From 27763b024648b848430481a929d716038d887952 Mon Sep 17 00:00:00 2001 From: "hwajeong.son" Date: Mon, 20 Aug 2018 13:20:53 +0900 Subject: [PATCH] Tizen_4.0 base Signed-off-by: hwajeong.son --- .gitignore | 12 + CMakeLists.txt | 16 + LICENSE.Apache-2.0 | 204 + README.md | 2 + include/adaptor_api_types.h | 66 + packaging/docker-adaptor.manifest | 5 + packaging/docker-adaptor.service | 14 + packaging/docker-adaptor.spec | 60 + src/CMakeLists.txt | 25 + src/adaptor.c | 49 + src/adaptor_interface.c | 247 + src/adaptor_interface.h | 30 + src/adaptor_setting.c | 224 + src/adaptor_setting.h | 40 + src/adaptor_util.c | 141 + src/adaptor_util.h | 50 + src/input_file.c | 451 ++ src/input_file.h | 52 + src/ipc_server.c | 119 + src/ipc_server.h | 38 + src/lib/CMakeLists.txt | 13 + src/lib/adaptor_api.c | 243 + src/lib/adaptor_api.h | 62 + src/lib/build.sh | 46 + src/lib/install/amd64/lib/libadaptor.a | Bin 0 -> 53230 bytes src/lib/install/amd64/lib/libjson-c.a | Bin 0 -> 251020 bytes src/lib/install/amd64/lib/libjson-c.la | 41 + src/lib/install/amd64/lib/libjson-c.so | 1 + src/lib/install/amd64/lib/libjson-c.so.2 | 1 + src/lib/install/amd64/lib/libjson-c.so.2.0.2 | Bin 0 -> 148648 bytes src/lib/install/arm/include/curl/curl.h | 2553 ++++++++ src/lib/install/arm/include/curl/curlbuild.h | 198 + src/lib/install/arm/include/curl/curlrules.h | 239 + src/lib/install/arm/include/curl/curlver.h | 77 + src/lib/install/arm/include/curl/easy.h | 102 + src/lib/install/arm/include/curl/mprintf.h | 50 + src/lib/install/arm/include/curl/multi.h | 439 ++ .../install/arm/include/curl/stdcheaders.h | 33 + src/lib/install/arm/include/curl/system.h | 484 ++ .../install/arm/include/curl/typecheck-gcc.h | 668 +++ src/lib/install/arm/lib/libadaptor.a | Bin 0 -> 40482 bytes src/lib/install/arm/lib/libjson-c.a | Bin 0 -> 164780 bytes src/lib/install/arm/lib/libjson-c.la | 41 + src/lib/install/arm/lib/libjson-c.so | 1 + src/lib/install/arm/lib/libjson-c.so.2 | 1 + src/lib/install/arm/lib/libjson-c.so.2.0.2 | Bin 0 -> 138296 bytes src/lib/install/include/adaptor/adaptor_api.h | 62 + .../include/adaptor/adaptor_api_types.h | 66 + src/lib/install/include/gmock/gmock-actions.h | 1205 ++++ .../include/gmock/gmock-cardinalities.h | 147 + .../include/gmock/gmock-generated-actions.h | 2377 ++++++++ .../gmock/gmock-generated-actions.h.pump | 794 +++ .../gmock/gmock-generated-function-mockers.h | 1095 ++++ .../gmock-generated-function-mockers.h.pump | 291 + .../include/gmock/gmock-generated-matchers.h | 2179 +++++++ .../gmock/gmock-generated-matchers.h.pump | 672 +++ .../gmock/gmock-generated-nice-strict.h | 397 ++ .../gmock/gmock-generated-nice-strict.h.pump | 161 + .../install/include/gmock/gmock-matchers.h | 4397 ++++++++++++++ .../include/gmock/gmock-more-actions.h | 246 + .../include/gmock/gmock-more-matchers.h | 58 + .../include/gmock/gmock-spec-builders.h | 1850 ++++++ src/lib/install/include/gmock/gmock.h | 94 + .../internal/custom/gmock-generated-actions.h | 8 + .../custom/gmock-generated-actions.h.pump | 10 + .../gmock/internal/custom/gmock-matchers.h | 39 + .../gmock/internal/custom/gmock-port.h | 46 + .../internal/gmock-generated-internal-utils.h | 279 + .../gmock-generated-internal-utils.h.pump | 136 + .../gmock/internal/gmock-internal-utils.h | 510 ++ .../include/gmock/internal/gmock-port.h | 91 + .../install/include/gtest/gtest-death-test.h | 294 + src/lib/install/include/gtest/gtest-message.h | 250 + .../install/include/gtest/gtest-param-test.h | 1444 +++++ .../include/gtest/gtest-param-test.h.pump | 510 ++ .../install/include/gtest/gtest-printers.h | 1006 ++++ src/lib/install/include/gtest/gtest-spi.h | 231 + .../install/include/gtest/gtest-test-part.h | 179 + .../install/include/gtest/gtest-typed-test.h | 264 + src/lib/install/include/gtest/gtest.h | 2240 +++++++ .../install/include/gtest/gtest_pred_impl.h | 358 ++ src/lib/install/include/gtest/gtest_prod.h | 58 + .../gtest/internal/custom/gtest-port.h | 72 + .../gtest/internal/custom/gtest-printers.h | 42 + .../include/gtest/internal/custom/gtest.h | 45 + .../internal/gtest-death-test-internal.h | 319 + .../include/gtest/internal/gtest-filepath.h | 206 + .../include/gtest/internal/gtest-internal.h | 1239 ++++ .../include/gtest/internal/gtest-linked_ptr.h | 243 + .../internal/gtest-param-util-generated.h | 5146 +++++++++++++++++ .../gtest-param-util-generated.h.pump | 286 + .../include/gtest/internal/gtest-param-util.h | 730 +++ .../include/gtest/internal/gtest-port-arch.h | 95 + .../include/gtest/internal/gtest-port.h | 2591 +++++++++ .../include/gtest/internal/gtest-string.h | 167 + .../include/gtest/internal/gtest-tuple.h | 1020 ++++ .../include/gtest/internal/gtest-tuple.h.pump | 347 ++ .../include/gtest/internal/gtest-type-util.h | 3331 +++++++++++ .../gtest/internal/gtest-type-util.h.pump | 297 + src/lib/install/include/json-c/arraylist.h | 56 + src/lib/install/include/json-c/bits.h | 28 + src/lib/install/include/json-c/debug.h | 71 + src/lib/install/include/json-c/json.h | 34 + .../install/include/json-c/json_c_version.h | 22 + src/lib/install/include/json-c/json_config.h | 4 + .../install/include/json-c/json_inttypes.h | 28 + src/lib/install/include/json-c/json_object.h | 612 ++ .../include/json-c/json_object_iterator.h | 239 + .../include/json-c/json_object_private.h | 47 + src/lib/install/include/json-c/json_tokener.h | 208 + src/lib/install/include/json-c/json_util.h | 41 + src/lib/install/include/json-c/linkhash.h | 292 + src/lib/install/include/json-c/printbuf.h | 77 + src/lib/install/include/json-c/random_seed.h | 25 + src/lib/ipc.c | 252 + src/lib/ipc.h | 192 + src/lib/ipc_client.c | 220 + src/lib/ipc_client.h | 33 + src/lib/ipc_config.h | 19 + src/lib/json_util.c | 222 + src/lib/json_util.h | 91 + src/lib/test/build.sh | 59 + src/lib/test/client.c | 164 + src/lib/test/server.c | 187 + src/lib/test/server_cb.c | 89 + src/lib/test/test_client | Bin 0 -> 1385272 bytes src/lib/test/test_client-arm | Bin 0 -> 1041992 bytes src/lib/test/test_server | Bin 0 -> 1109824 bytes src/lib/test/test_server-arm | Bin 0 -> 769884 bytes src/parse_file.c | 478 ++ src/parse_file.h | 52 + src/sa_common.h | 70 + src/sa_types.h | 240 + src/setup_system.c | 867 +++ src/setup_system.h | 92 + test/README.md | 14 + test/config.json | 4 + test/devconfig_system.json | 6 + test/sa_test.c | 0 unit-test.sh | 12 + unittest/CMakeLists.txt | 52 + unittest/beluga-adaptor_interface.cpp | 135 + unittest/beluga-adaptor_main.cpp | 13 + unittest/beluga-adaptor_setting.cpp | 145 + .../setup-adaptor/cert/SRnD+Web+Proxy.crt | 25 + .../beluga/setup-adaptor/config/config.json | 1 + .../setup-adaptor/config/set_eth_config.sh | 72 + .../setup-adaptor/config/set_wifi_config.sh | 79 + .../setup-adaptor/container/config-agent.yml | 15 + .../container/config-service.yml | 14 + .../beluga/system/docker/dockerd_start.json | 6 + unittest/pre/beluga/system/env/environment | 0 .../pre/beluga/system/env/factory_init.json | 1 + .../pre/beluga/system/release/beluga-release | 2 + .../pre/beluga/system/tools/agent_config.sh | 64 + .../pre/beluga/system/tools/agent_reset.sh | 31 + .../dockerd_start-default.json | 4 + .../beluga/system/tools/dockerd_start.json | Bin 0 -> 108 bytes .../system/tools/dockzen_agent-default.json | 10 + .../tools/dockzen_agent-headed-iiot.json | 10 + .../system/tools/dockzen_agent-headed.json | 10 + .../tools/dockzen_agent-headless-iiot.json | 10 + .../system/tools/dockzen_agent-headless.json | 10 + unittest/pre/test_condition.sh | 6 + 164 files changed, 53220 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE.Apache-2.0 create mode 100644 README.md create mode 100644 include/adaptor_api_types.h create mode 100644 packaging/docker-adaptor.manifest create mode 100755 packaging/docker-adaptor.service create mode 100644 packaging/docker-adaptor.spec create mode 100644 src/CMakeLists.txt create mode 100755 src/adaptor.c create mode 100644 src/adaptor_interface.c create mode 100644 src/adaptor_interface.h create mode 100644 src/adaptor_setting.c create mode 100755 src/adaptor_setting.h create mode 100644 src/adaptor_util.c create mode 100755 src/adaptor_util.h create mode 100644 src/input_file.c create mode 100644 src/input_file.h create mode 100644 src/ipc_server.c create mode 100644 src/ipc_server.h create mode 100755 src/lib/CMakeLists.txt create mode 100755 src/lib/adaptor_api.c create mode 100755 src/lib/adaptor_api.h create mode 100755 src/lib/build.sh create mode 100644 src/lib/install/amd64/lib/libadaptor.a create mode 100644 src/lib/install/amd64/lib/libjson-c.a create mode 100644 src/lib/install/amd64/lib/libjson-c.la create mode 120000 src/lib/install/amd64/lib/libjson-c.so create mode 120000 src/lib/install/amd64/lib/libjson-c.so.2 create mode 100644 src/lib/install/amd64/lib/libjson-c.so.2.0.2 create mode 100644 src/lib/install/arm/include/curl/curl.h create mode 100644 src/lib/install/arm/include/curl/curlbuild.h create mode 100644 src/lib/install/arm/include/curl/curlrules.h create mode 100644 src/lib/install/arm/include/curl/curlver.h create mode 100644 src/lib/install/arm/include/curl/easy.h create mode 100644 src/lib/install/arm/include/curl/mprintf.h create mode 100644 src/lib/install/arm/include/curl/multi.h create mode 100644 src/lib/install/arm/include/curl/stdcheaders.h create mode 100644 src/lib/install/arm/include/curl/system.h create mode 100644 src/lib/install/arm/include/curl/typecheck-gcc.h create mode 100644 src/lib/install/arm/lib/libadaptor.a create mode 100644 src/lib/install/arm/lib/libjson-c.a create mode 100755 src/lib/install/arm/lib/libjson-c.la create mode 120000 src/lib/install/arm/lib/libjson-c.so create mode 120000 src/lib/install/arm/lib/libjson-c.so.2 create mode 100755 src/lib/install/arm/lib/libjson-c.so.2.0.2 create mode 100755 src/lib/install/include/adaptor/adaptor_api.h create mode 100644 src/lib/install/include/adaptor/adaptor_api_types.h create mode 100644 src/lib/install/include/gmock/gmock-actions.h create mode 100644 src/lib/install/include/gmock/gmock-cardinalities.h create mode 100644 src/lib/install/include/gmock/gmock-generated-actions.h create mode 100644 src/lib/install/include/gmock/gmock-generated-actions.h.pump create mode 100644 src/lib/install/include/gmock/gmock-generated-function-mockers.h create mode 100644 src/lib/install/include/gmock/gmock-generated-function-mockers.h.pump create mode 100644 src/lib/install/include/gmock/gmock-generated-matchers.h create mode 100644 src/lib/install/include/gmock/gmock-generated-matchers.h.pump create mode 100644 src/lib/install/include/gmock/gmock-generated-nice-strict.h create mode 100644 src/lib/install/include/gmock/gmock-generated-nice-strict.h.pump create mode 100644 src/lib/install/include/gmock/gmock-matchers.h create mode 100644 src/lib/install/include/gmock/gmock-more-actions.h create mode 100644 src/lib/install/include/gmock/gmock-more-matchers.h create mode 100644 src/lib/install/include/gmock/gmock-spec-builders.h create mode 100644 src/lib/install/include/gmock/gmock.h create mode 100644 src/lib/install/include/gmock/internal/custom/gmock-generated-actions.h create mode 100644 src/lib/install/include/gmock/internal/custom/gmock-generated-actions.h.pump create mode 100644 src/lib/install/include/gmock/internal/custom/gmock-matchers.h create mode 100644 src/lib/install/include/gmock/internal/custom/gmock-port.h create mode 100644 src/lib/install/include/gmock/internal/gmock-generated-internal-utils.h create mode 100644 src/lib/install/include/gmock/internal/gmock-generated-internal-utils.h.pump create mode 100644 src/lib/install/include/gmock/internal/gmock-internal-utils.h create mode 100644 src/lib/install/include/gmock/internal/gmock-port.h create mode 100644 src/lib/install/include/gtest/gtest-death-test.h create mode 100644 src/lib/install/include/gtest/gtest-message.h create mode 100644 src/lib/install/include/gtest/gtest-param-test.h create mode 100644 src/lib/install/include/gtest/gtest-param-test.h.pump create mode 100644 src/lib/install/include/gtest/gtest-printers.h create mode 100644 src/lib/install/include/gtest/gtest-spi.h create mode 100644 src/lib/install/include/gtest/gtest-test-part.h create mode 100644 src/lib/install/include/gtest/gtest-typed-test.h create mode 100644 src/lib/install/include/gtest/gtest.h create mode 100644 src/lib/install/include/gtest/gtest_pred_impl.h create mode 100644 src/lib/install/include/gtest/gtest_prod.h create mode 100644 src/lib/install/include/gtest/internal/custom/gtest-port.h create mode 100644 src/lib/install/include/gtest/internal/custom/gtest-printers.h create mode 100644 src/lib/install/include/gtest/internal/custom/gtest.h create mode 100644 src/lib/install/include/gtest/internal/gtest-death-test-internal.h create mode 100644 src/lib/install/include/gtest/internal/gtest-filepath.h create mode 100644 src/lib/install/include/gtest/internal/gtest-internal.h create mode 100644 src/lib/install/include/gtest/internal/gtest-linked_ptr.h create mode 100644 src/lib/install/include/gtest/internal/gtest-param-util-generated.h create mode 100644 src/lib/install/include/gtest/internal/gtest-param-util-generated.h.pump create mode 100644 src/lib/install/include/gtest/internal/gtest-param-util.h create mode 100644 src/lib/install/include/gtest/internal/gtest-port-arch.h create mode 100644 src/lib/install/include/gtest/internal/gtest-port.h create mode 100644 src/lib/install/include/gtest/internal/gtest-string.h create mode 100644 src/lib/install/include/gtest/internal/gtest-tuple.h create mode 100644 src/lib/install/include/gtest/internal/gtest-tuple.h.pump create mode 100644 src/lib/install/include/gtest/internal/gtest-type-util.h create mode 100644 src/lib/install/include/gtest/internal/gtest-type-util.h.pump create mode 100644 src/lib/install/include/json-c/arraylist.h create mode 100644 src/lib/install/include/json-c/bits.h create mode 100644 src/lib/install/include/json-c/debug.h create mode 100644 src/lib/install/include/json-c/json.h create mode 100644 src/lib/install/include/json-c/json_c_version.h create mode 100644 src/lib/install/include/json-c/json_config.h create mode 100644 src/lib/install/include/json-c/json_inttypes.h create mode 100644 src/lib/install/include/json-c/json_object.h create mode 100644 src/lib/install/include/json-c/json_object_iterator.h create mode 100644 src/lib/install/include/json-c/json_object_private.h create mode 100644 src/lib/install/include/json-c/json_tokener.h create mode 100644 src/lib/install/include/json-c/json_util.h create mode 100644 src/lib/install/include/json-c/linkhash.h create mode 100644 src/lib/install/include/json-c/printbuf.h create mode 100644 src/lib/install/include/json-c/random_seed.h create mode 100755 src/lib/ipc.c create mode 100755 src/lib/ipc.h create mode 100755 src/lib/ipc_client.c create mode 100755 src/lib/ipc_client.h create mode 100755 src/lib/ipc_config.h create mode 100755 src/lib/json_util.c create mode 100755 src/lib/json_util.h create mode 100755 src/lib/test/build.sh create mode 100755 src/lib/test/client.c create mode 100755 src/lib/test/server.c create mode 100755 src/lib/test/server_cb.c create mode 100755 src/lib/test/test_client create mode 100755 src/lib/test/test_client-arm create mode 100755 src/lib/test/test_server create mode 100755 src/lib/test/test_server-arm create mode 100644 src/parse_file.c create mode 100755 src/parse_file.h create mode 100644 src/sa_common.h create mode 100755 src/sa_types.h create mode 100644 src/setup_system.c create mode 100755 src/setup_system.h create mode 100644 test/README.md create mode 100755 test/config.json create mode 100755 test/devconfig_system.json create mode 100644 test/sa_test.c create mode 100755 unit-test.sh create mode 100755 unittest/CMakeLists.txt create mode 100755 unittest/beluga-adaptor_interface.cpp create mode 100755 unittest/beluga-adaptor_main.cpp create mode 100755 unittest/beluga-adaptor_setting.cpp create mode 100755 unittest/pre/beluga/setup-adaptor/cert/SRnD+Web+Proxy.crt create mode 100755 unittest/pre/beluga/setup-adaptor/config/config.json create mode 100755 unittest/pre/beluga/setup-adaptor/config/set_eth_config.sh create mode 100755 unittest/pre/beluga/setup-adaptor/config/set_wifi_config.sh create mode 100755 unittest/pre/beluga/setup-adaptor/container/config-agent.yml create mode 100755 unittest/pre/beluga/setup-adaptor/container/config-service.yml create mode 100755 unittest/pre/beluga/system/docker/dockerd_start.json create mode 100755 unittest/pre/beluga/system/env/environment create mode 100755 unittest/pre/beluga/system/env/factory_init.json create mode 100755 unittest/pre/beluga/system/release/beluga-release create mode 100755 unittest/pre/beluga/system/tools/agent_config.sh create mode 100755 unittest/pre/beluga/system/tools/agent_reset.sh create mode 100755 unittest/pre/beluga/system/tools/availables-dockerd/dockerd_start-default.json create mode 100755 unittest/pre/beluga/system/tools/dockerd_start.json create mode 100755 unittest/pre/beluga/system/tools/dockzen_agent-default.json create mode 100755 unittest/pre/beluga/system/tools/dockzen_agent-headed-iiot.json create mode 100755 unittest/pre/beluga/system/tools/dockzen_agent-headed.json create mode 100755 unittest/pre/beluga/system/tools/dockzen_agent-headless-iiot.json create mode 100755 unittest/pre/beluga/system/tools/dockzen_agent-headless.json create mode 100755 unittest/pre/test_condition.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d700010 --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +# Compiled source # +################### +*.o +build/ +CMakeFiles/ +Makefile +*.cmake +CMakeCache.txt +*.pc +install_manifest.txt +src/docker-adaptor +src/lib/libadaptor.a diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..f5470cb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,16 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(docker-adaptor C CXX) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) + +INCLUDE(FindPkgConfig) + +SET(EXTRA_CFLAGS "-Wall -Werror-implicit-function-declaration -fvisibility=hidden") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") + +SET(DOCKER-ADAPTOR ${PROJECT_NAME}) + +ADD_SUBDIRECTORY(src) +ADD_SUBDIRECTORY(src/lib) +IF(BUILD_TESTS) + ADD_SUBDIRECTORY(unittest) +ENDIF(BUILD_TESTS) \ No newline at end of file diff --git a/LICENSE.Apache-2.0 b/LICENSE.Apache-2.0 new file mode 100644 index 0000000..a06208b --- /dev/null +++ b/LICENSE.Apache-2.0 @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..1e4cf17 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# docker-adaptor +Providing configuration with config diff --git a/include/adaptor_api_types.h b/include/adaptor_api_types.h new file mode 100644 index 0000000..e68cb1f --- /dev/null +++ b/include/adaptor_api_types.h @@ -0,0 +1,66 @@ +/** + * @file adaptor_api_types.h + * @brief Types of API for dockzen + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_API_TYPES_H__ +#define __ADAPTOR_API_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CONTAINER_NUM (10) +#define MAX_DISK_NUM (10) + +/** + * @brief This enum contains dockzen error information + * + * The adaptor_api_error_e indicates what error is happened + * + */ +typedef enum { + ADAPTOR_API_ERROR_NONE = 0, /**< Successful */ + ADAPTOR_API_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + ADAPTOR_API_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + ADAPTOR_API_ERROR_PERMISSION_DENIED, /**< Permission denied */ + ADAPTOR_API_ERROR_NOT_SUPPORTED, /**< Not supported */ +} ADAPTOR_API_error_e; + +/** + * @struct os_info_s + * @brief This struct contains os information + */ +typedef struct{ + char * platformVer; + char * baseOSVer; + char * dockerVer; +} os_info_s; + + +/** + * @struct disk_info_s + * @brief This struct contains disk information + */ +typedef struct{ + int count; /**< the counts of containers info */ + struct { + char * path; + int free; /* MB */ + int total; /* MB */ + int used; /* MB */ + int usedpercent; /* divide by 100 to get percentage. (float)disk_info.disk[index].usedpercent/(float)100 */ + }disk[MAX_DISK_NUM]; /**< Max Count constraint */ +} disk_info_s; + +#ifdef __cplusplus +} +#endif +#endif /* __ADAPTOR_API_TYPES_H__ */ diff --git a/packaging/docker-adaptor.manifest b/packaging/docker-adaptor.manifest new file mode 100644 index 0000000..a76fdba --- /dev/null +++ b/packaging/docker-adaptor.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/docker-adaptor.service b/packaging/docker-adaptor.service new file mode 100755 index 0000000..8d030d0 --- /dev/null +++ b/packaging/docker-adaptor.service @@ -0,0 +1,14 @@ +[Unit] +Description=Docker-Adaptor daemon +After=connman.service +Requires=connman.service + +[Service] +SmackProcessLabel=System +Type=simple +ExecStart=/usr/bin/docker-adaptor +Restart=always +RestartSec=0 + +[Install] +WantedBy=multi-user.target diff --git a/packaging/docker-adaptor.spec b/packaging/docker-adaptor.spec new file mode 100644 index 0000000..da73be9 --- /dev/null +++ b/packaging/docker-adaptor.spec @@ -0,0 +1,60 @@ +Name: docker-adaptor +Summary: Provide network and system data setting daemon +Version: 0.7.0 +Release: 0 +Group: System/Docker Framework +ExclusiveArch: armv7l +License: Apache-2.0 +Source0: %{name}-%{version}.tar.gz +Source1: %{name}.manifest +Source2: %{name}.service +BuildRequires: awk +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(libsystemd) +BuildRequires: pkgconfig(json-c) + + +Requires(post): /sbin/ldconfig +Requires(postun): /sbin/ldconfig + +%description +provide setting for network and system data based on config + +%prep +%setup -q +cp %{SOURCE1} ./ +cp %{SOURCE2} ./ + +%build +export LDFLAGS+="-Wl,--as-needed" +MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'` + +%cmake . \ + -DBUILD_TESTS=OFF\ + -DMAJORVER=${MAJORVER}\ + -DFULLVER=%{version}\ + -DBIN_INSTALL_DIR:PATH=%{_bindir} + +%install +%make_install +mkdir -p %{buildroot}%{_unitdir}/multi-user.target.wants +install -m 0644 %SOURCE2 %{buildroot}%{_unitdir}/%{name}.service +%install_service multi-user.target.wants %{name}.service + + +%post + +%preun + +%postun + +%files +%manifest %{name}.manifest +%defattr(-,root,root,-) +%license LICENSE.Apache-2.0 +%{_bindir}/%{name} +%{_unitdir}/%{name}.service +%{_unitdir}/multi-user.target.wants/%{name}.service + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..d90776e --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,25 @@ +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/lib) + +INCLUDE(FindPkgConfig) + +if(NONE_GBS_BUILD) +INCLUDE_DIRECTORIES(${LINK_LIB_INCLUDE}) +set(CMAKE_EXE_LINKER_FLAGS ${LINK_FLAG}) +else() +pkg_check_modules(pbus_pkgs REQUIRED dlog json-c) +endif() + +INCLUDE_DIRECTORIES(${pbus_pkgs_INCLUDE_DIRS}) +LINK_DIRECTORIES(${pbus_pkgs_LIBRARY_DIRS}) + +FILE(GLOB SRCS *.c + lib/ipc.c + lib/json_util.c) + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pbus_pkgs_LIBRARIES} pthread json-c) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BIN_INSTALL_DIR}) diff --git a/src/adaptor.c b/src/adaptor.c new file mode 100755 index 0000000..889ff54 --- /dev/null +++ b/src/adaptor.c @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "sa_common.h" +#include "adaptor_setting.h" +#include "adaptor_interface.h" + +int main(int argc, char *argv[]) +{ + pthread_t t_setting = pthread_self(); + pthread_t t_api = pthread_self(); + int status; + int ret; + + _D("pthread_create >>> SETTING_MAIN !!!"); + ret = pthread_create(&t_setting, NULL, &setting_main_thread, (void *)NULL); + if (ret < 0) { + _E("[SETTING_MAIN] thread create error (ret=%d)", ret); + return -1; + } + + _D("pthread_create >>> API_MAIN !!!"); + ret = pthread_create(&t_api, NULL, &api_main_thread, (void *)NULL); + if (ret < 0) { + _E("[API_MAIN] thread create error (ret=%d)", ret); + return -1; + } + + pthread_join(t_setting, (void **)&status); + pthread_join(t_api, (void **)&status); + + return 0; +} diff --git a/src/adaptor_interface.c b/src/adaptor_interface.c new file mode 100644 index 0000000..e3a7de9 --- /dev/null +++ b/src/adaptor_interface.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "sa_common.h" +#include "sa_types.h" +#include "ipc.h" +#include "ipc_config.h" +#include "ipc_server.h" +#include "json_util.h" +#include "setup_system.h" + +////////////////////////////////////////////////////////////////// +// callee function body +////////////////////////////////////////////////////////////////// + +char *__device_reboot(char *data) +{ + _D("[SERVER] __device_reboot"); + + int ret = 0; + char *buf = NULL; + char *ret_buf = NULL; + int buf_len = 0; + + ret = sa_device_reboot(); + _D("[SERVER] sa_create_device_reboot_json_string()"); + buf = sa_create_device_reboot_json_string(ret); + if (buf != NULL) { + buf_len = strlen(buf) + 1; + ret_buf = (char *)malloc(buf_len); + if (ret_buf != NULL) + snprintf(ret_buf, buf_len, "%s", buf); + free(buf); + } + //_D("ret_buf : %s", ret_buf); + return ret_buf; +} + +char *__get_os_info(void) +{ + _D("[SERVER] __get_os_info"); + + os_info_s *os_info_h = NULL; + char *ret_buf = NULL; + int ret = 0; + char *buf = NULL; + int buf_len = 0; + + os_info_h = (os_info_s *) malloc(sizeof(os_info_s)); + if (os_info_h != NULL) { + memset(os_info_h, 0x0, sizeof(os_info_s)); + ret = sa_get_os_info(os_info_h); + if (ret != -1) { + // make json string + buf = sa_create_os_info_json_string(os_info_h); + //_D("json_str : %s", buf); + if (buf != NULL) { + buf_len = strlen(buf) + 1; + ret_buf = (char *)malloc(buf_len); + if (ret_buf != NULL) + snprintf(ret_buf, buf_len, "%s", buf); + free(buf); + } + } + + if (os_info_h->platformVer) + free(os_info_h->platformVer); + if (os_info_h->baseOSVer) + free(os_info_h->baseOSVer); + if (os_info_h->dockerVer) + free(os_info_h->dockerVer); + free(os_info_h); + } + //_D("ret_buf : %s", ret_buf); + return ret_buf; +} + +char *__get_disk_info(void) +{ + _D("[SERVER] __get_disk_info"); + char *ret_buf = NULL; + int ret = 0; + disk_info_s *disk_info_h = NULL; + int index; + char *buf = NULL; + int buf_len = 0; + + disk_info_h = (disk_info_s *) malloc(sizeof(disk_info_s)); + if (disk_info_h != NULL) { + memset(disk_info_h, 0x0, sizeof(disk_info_s)); + ret = sa_get_disk_info(disk_info_h); + if (ret != -1) { + // make json string + buf = sa_create_disk_info_json_string(disk_info_h); + //_D("json_str : %s", buf); + if (buf != NULL) { + buf_len = strlen(buf) + 1; + ret_buf = (char *)malloc(buf_len); + if (ret_buf != NULL) + snprintf(ret_buf, buf_len, "%s", buf); + free(buf); + } + } + + for (index = 0; index < disk_info_h->count; index++) { + if (disk_info_h->disk[index].path) + free(disk_info_h->disk[index].path); + } + free(disk_info_h); + } + //_D("ret_buf : %s", ret_buf); + return ret_buf; +} + +char *__factory_restore(char *data) +{ + _D("[SERVER] __factory_restore"); + + int ret = 0; + char *buf = NULL; + char *ret_buf = NULL; + int buf_len = 0; + int fdevice_restart = 1; + + ret = sa_factory_restore(fdevice_restart); + _D("[SERVER] sa_create_factory_restore_json_string()"); + buf = sa_create_factory_restore_json_string(ret); + if (buf != NULL) { + buf_len = strlen(buf) + 1; + ret_buf = (char *)malloc(buf_len); + if (ret_buf != NULL) + snprintf(ret_buf, buf_len, "%s", buf); + free(buf); + } + //_D("ret_buf : %s", ret_buf); + return ret_buf; +} + +////////////////////////////////////////////////////////////////// +// callee function list structure & register +////////////////////////////////////////////////////////////////// + +typedef void *(*cmdFunctionPtr) (void *, ...); + +struct _cmd_table_s { + char cmd[50]; + cmdFunctionPtr func; +}; + +typedef struct _cmd_table_s cmd_mapping_tables; + +cmd_mapping_tables cmd_mapping_table[] = { + {"device_reboot", (cmdFunctionPtr) __device_reboot}, + {"get_os_info", (cmdFunctionPtr) __get_os_info}, + {"get_disk_info", (cmdFunctionPtr) __get_disk_info}, + {"factory_restore", (cmdFunctionPtr) __factory_restore}, + {"end", NULL} +}; + +char *__interface_parser(char *data, int size) +{ + char *func = NULL; + char *param = NULL; + char *ret_buf = NULL; + int i = 0; + + _D("interface_parser"); + + func = json_getString(data, "func"); + param = json_getObject(data, "param"); + + _D("func:%s", func); + _D("param:%s", param); + + while (1) { + if (!strncmp(cmd_mapping_table[i].cmd, "end", strlen("end"))) + break; + + if (func != NULL && !strncmp(cmd_mapping_table[i].cmd, func, strlen(func))) { + ret_buf = cmd_mapping_table[i].func(param); + break; + } + i++; + } + _D("SERVER ret_buf=%s", ret_buf); + if (func != NULL) + free(func); + if (param != NULL) + free(param); + return ret_buf; +} + +void *__server_init(void *pv) +{ + char *(*pFunc) (char *, int) = __interface_parser; + + _D("[SERVER] adaptor_api_init"); + + if (IPC_StartServer(pFunc) < 0) { + _E("[SERVER] IPC_StartServer Failed"); + return NULL; + } + return NULL; +} + +////////////////////////////////////////////////////////////////// +// main thread for device api +////////////////////////////////////////////////////////////////// +void *api_main_thread(void *pv) +{ + pthread_t t_server = pthread_self(); + int status; + int ret; + + _D("device api main_thread ~~~"); +/* + ret = callback_init_connection(); + if (0 != ret) + _E("[API_SERVER] callback_init_connection error (ret=%d)", ret); +*/ + ret = pthread_create(&t_server, NULL, &__server_init, (void *)NULL); + if (ret < 0) { + _E("[API_SERVER] thread create error (ret=%d)", ret); + return NULL; + } + pthread_join(t_server, (void **)&status); + + _D("device api main_thread exit~~~~~~~"); + + return NULL; +} diff --git a/src/adaptor_interface.h b/src/adaptor_interface.h new file mode 100644 index 0000000..fc31f9b --- /dev/null +++ b/src/adaptor_interface.h @@ -0,0 +1,30 @@ +/** + * @file adaptor_interface.h + * @brief API interface server + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_INTERFACE_H__ +#define __ADAPTOR_INTERFACE_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @fn void *api_main_thread(void *pv) + * @brief main function to run api thread + * @param void *pv + * @return void * + */ + void *api_main_thread(void *pv); + +#ifdef __cplusplus +} +#endif +#endif /* __ADAPTOR_INTERFACE_H__ */ diff --git a/src/adaptor_setting.c b/src/adaptor_setting.c new file mode 100644 index 0000000..93f6937 --- /dev/null +++ b/src/adaptor_setting.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "sa_common.h" +#include "sa_types.h" +#include "setup_system.h" +#include "input_file.h" +#include "parse_file.h" +#include "adaptor_util.h" + +#include +#include +#include +#include +#include +#include +#include + +#include "json_util.h" + +#define CONFIG_NUM 2 +#define ORIGIN_CONFIG_FILE "/opt/beluga/setup-adaptor/config/config.json" +#define ENVIRONMENT_DIR_PATH "/opt/beluga/system/env/" + +#define MAXLINE 1024 + +char sa_config_file_path[CONFIG_NUM][256] = { + "/opt/beluga/setup-adaptor/config/devconfig_system.json", + "/opt/beluga/setup-adaptor/config/devconfig_target.json" +}; + +char sa_applied_config_file_path[CONFIG_NUM][256] = { + "/opt/beluga/setup-adaptor/config/devconfig_system_applied.json", + "/opt/beluga/setup-adaptor/config/devconfig_target_applied.json" +}; + +int flagInitialized = 0; + +sa_error_e __prepare_config_file(void) +{ + sa_error_e ret = SA_ERROR_NONE; + + //exit if config file exists already + if ((SA_FILE_STATE_NOT_EXISTED == sa_inputfile_is_file_exist(sa_config_file_path[0])) + || (SA_FILE_STATE_NOT_EXISTED == sa_inputfile_is_file_exist(sa_config_file_path[1]))) { + _D("split into each config files"); + sa_split_files(ORIGIN_CONFIG_FILE, sa_config_file_path[0], sa_config_file_path[1]); + } else { + _D("skip split files."); + ret = SA_ERROR_NOT_AVAILABLE; + } + + return ret; +} + +sa_error_e sa_remove_config_file(void) +{ + int index; + sa_error_e ret = SA_ERROR_NONE; + + for (index = 0; index < CONFIG_NUM; index++) { + if (sa_inputfile_is_file_exist(sa_config_file_path[index]) == SA_FILE_STATE_EXIST) { + if (remove(sa_config_file_path[index]) != 0) { + _D("Error!!! remove [%s] file", sa_config_file_path[index]); + ret = SA_ERROR_UNKNOWN; + } + } + if (sa_inputfile_is_file_exist(sa_applied_config_file_path[index]) == SA_FILE_STATE_EXIST) { + if (remove(sa_applied_config_file_path[index]) != 0) { + _D("Error!!! remove [%s] file", sa_applied_config_file_path[index]); + ret = SA_ERROR_UNKNOWN; + } + } + } + return ret; +} + +int setup_cb(void *data) +{ + char *file_path = (char *)data; + + sa_error_e ret = SA_ERROR_NONE; + sa_config_s config = { 0, }; + sa_error_e file_read = SA_ERROR_NONE; + + _D("setup_cb called... >>>>>>>>>>>>>>>>>>>>>>>"); + _D("file_path : %s", file_path); + + // Apply the modified setting value. + file_read = sa_inputfile_get_config_info(&config, file_path); + + if (file_read == SA_ERROR_NONE) { + if (config.systemData != NULL) { + ret = sa_setup_system(config.systemData, flagInitialized); + if (ret != SA_ERROR_NONE) + _E("sa_setup_system return error(%d)", ret); + _D("sa_setup_system() completed !!! ret(%d)", ret); + } + } + _D("setup_cb completed <<<<<<<<<<<<<<<<<<<<<<<<"); + + return ret; +} + +// send notification to systemd when finished starting up +// it have to be sent once after starting service +// launcher use setting value from adaptor as EnvironmentFile +void completed_notify_cb(void) +{ + if (send_message_to_launcher(SA_START_LAUNCHER_SVC) < 0) + _E("send error : "); + + flagInitialized = 1; + _D("send notification to launcher to start itself..."); +} + +void __free_main_thread_param(sa_main_thread_s * param) +{ + int index = 0; + + if (param != NULL) { + // free parameter + for (index = 0; index < param->config_file_num; index++) { + if ((char *)param->config_file_path[index] != NULL) { + free((char *)param->config_file_path[index]); + param->config_file_path[index] = NULL; + } + } + if (param->config_file_path != NULL) { + free((char **)param->config_file_path); + param->config_file_path = NULL; + } + // free param structure + free(param); + param = NULL; + } +} + +sa_main_thread_s *__create_main_thread_param(void) +{ + int index = 0; + sa_main_thread_s *param = (sa_main_thread_s *) malloc(sizeof(sa_main_thread_s)); + + if (param != NULL) { + memset(param, 0x00, sizeof(sa_main_thread_s)); + param->config_file_num = CONFIG_NUM; + param->config_file_path = (char **)malloc(sizeof(char *) * param->config_file_num); + if (param->config_file_path != NULL) { + // set config file path as a parameter + for (index = 0; index < param->config_file_num; index++) { + param->config_file_path[index] = (char *)malloc(strlen(sa_config_file_path[index]) + 1); + if (param->config_file_path[index] != NULL) { + memcpy(param->config_file_path[index], sa_config_file_path[index], strlen(sa_config_file_path[index]) + 1); + _D("path [%d]: %s", index, param->config_file_path[index]); + } else { + _E("malloc failed for config_file_path"); + __free_main_thread_param(param); + return NULL; + } + } + param->setup_cb = (void *)&setup_cb; + param->completed_notify_cb = (void *)&completed_notify_cb; + } + } else { + _E("malloc failed for param->config_file_path"); + } + return param; +} + +// config for main thread & callback function +void *setting_main_thread(void *pv) +{ + sa_main_thread_s *param = NULL; + sa_error_e ret = SA_ERROR_UNKNOWN; + pthread_t thread = pthread_self(); + int status; + int rv; + + _D("setting_main_thread ~~~"); + // 1. if no processing json files, create from config.json in first booting time + ret = __prepare_config_file(); + if (ret == SA_ERROR_NONE) { + // add user ca-certificates files in first booting time + setup_user_certificates(); + } + // 2. create beluga folder usded for docker engine + sa_generate_folder(ENVIRONMENT_DIR_PATH); + + // 3. configure parameters + param = __create_main_thread_param(); + if (param != NULL) { + // create pthread + rv = pthread_create(&thread, NULL, &sa_inputfile_thread, (void *)param); + if (rv < 0) { + _E("[ADAPTOR_SETTING] thread create error (rv=%d)", rv); + return NULL; + } + pthread_join(thread, (void **)&status); + + // free allocated memory + __free_main_thread_param(param); + } else { + _E("param is NULL "); + return NULL; + } + _D("setting_main_thread exit~~~"); + return NULL; +} diff --git a/src/adaptor_setting.h b/src/adaptor_setting.h new file mode 100755 index 0000000..9bef62e --- /dev/null +++ b/src/adaptor_setting.h @@ -0,0 +1,40 @@ +/** + * @file adaptor_api.h + * @brief API interface server + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_SETTING_H__ +#define __ADAPTOR_SETTING_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sa_types.h" + +/** + * @fn void *setting_main_thread(void *pv) + * @brief main function to run configuration setting thread + * @param void *pv + * @return void * + */ + void *setting_main_thread(void *pv); + +/** + * @fn sa_error_e sa_remove_config_file(void) + * @brief function to remove split config files + * @return sa_error_e + */ + sa_error_e sa_remove_config_file(void); + +#ifdef __cplusplus +} +#endif +#endif /* __ADAPTOR_SETTING_H__ */ diff --git a/src/adaptor_util.c b/src/adaptor_util.c new file mode 100644 index 0000000..8b1e8fb --- /dev/null +++ b/src/adaptor_util.c @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include "sa_common.h" +#include "sa_types.h" +#include "adaptor_util.h" + +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 1024 +#define LOG_BUF_LEN 2048 +#define SERVER "/var/run/beluga_launcher_notify.sock" + +static int flagConnected = 0; + +int send_message_to_launcher(sa_interface_cmd_e cmd) +{ + int ret = 0; + int sockfd; + int clilen; + struct sockaddr_un serveraddr; + + if (!flagConnected && cmd != SA_START_LAUNCHER_SVC) { + // case of no-valid request to send.. + return -1; + } + + _D("send_message_to_launcher[%d]", cmd); + sockfd = socket(AF_UNIX, SOCK_DGRAM, 0); + if (sockfd < 0) { + _E("socket error : "); + ret = -1; + } else { + bzero(&serveraddr, sizeof(serveraddr)); + serveraddr.sun_family = AF_UNIX; + strncpy(serveraddr.sun_path, SERVER, sizeof(serveraddr.sun_path) - 1); + serveraddr.sun_path[sizeof(serveraddr.sun_path) - 1] = '\0'; + clilen = sizeof(serveraddr); + + _D("send mssage: (%d)", cmd); + do { + if (sendto(sockfd, (void *)&cmd, sizeof(sa_interface_cmd_e), 0, (struct sockaddr *)&serveraddr, clilen) < 0) { + _E("Error sending msg: (%d)", errno); + ret = -2; + sleep(1); + } else { + ret = 0; + } + } while (ret < 0); + + close(sockfd); + + if (cmd == SA_START_LAUNCHER_SVC) + flagConnected = 1; + } + return ret; +} + +/** + * @fn int CLI_command(char *cmd, int fgetOutput, char *ret_buf) + * @brief This function to run command for daemon + * @param *cmd [in] command to run + * @param fgetoutput [in] flag to get ouput of the command + * @param * ret_buf [in] output of the command + * @return int return of function + */ +int CLI_command(char *cmd, int get_output, char **ret_buf) +{ + FILE *stream = NULL; + int ret = 0; + int index = 0; + int ch = 0; + char *buf = NULL; + + if (strlen(cmd) > 0) { + stream = popen(cmd, "r"); + if (stream != NULL) { + switch (get_output) { + case 1: /* to get a specific string */ + _D("get a specific string"); + buf = (char *)malloc(MAXLINE * sizeof(char)); + if (buf != NULL) { + memset(buf, 0x0, MAXLINE * sizeof(char)); + while ((index < MAXLINE) && ((ch = getc(stream)) != EOF) + && (ch != '\n')) { + buf[index++] = ch; + } + //_D("buf:%s(%d)", buf, index); + } + break; + case 2: /* to get logs */ + _D("get logs"); + buf = (char *)malloc(LOG_BUF_LEN * sizeof(char)); + if (buf != NULL) { + memset(buf, 0x0, LOG_BUF_LEN * sizeof(char)); + while ((index < LOG_BUF_LEN) + && ((ch = getc(stream)) != EOF)) { + buf[index++] = ch; + } + //_D("buf:%s(%d)", buf, index); + } + break; + default: + _E("no output message !!"); + break; + } + pclose(stream); + } else { + _E("Error sending msg: (%d)", errno); + ret = -1; + } + } else + ret = -1; + + if (buf) + *ret_buf = buf; + + return ret; +} diff --git a/src/adaptor_util.h b/src/adaptor_util.h new file mode 100755 index 0000000..a763c3a --- /dev/null +++ b/src/adaptor_util.h @@ -0,0 +1,50 @@ +/** + * @file adaptor_api.h + * @brief API interface server + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_UTIL_H__ +#define __ADAPTOR_UTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sa_types.h" + + typedef enum { + SA_START_LAUNCHER_SVC = 0, /**< start launcher service */ + SA_RESTART_DOCKERD, /**< restart docker engine */ + SA_STOP_DOCKERD, /**< stop docker engine */ + SA_CMD_UNKNOWN + } sa_interface_cmd_e; + +/** + * @fn void *setting_main_thread(void *pv) + * @brief send message to launcher with predefined command + * @param sa_interface_cmd_e cmd - command + * @return return if connection is completed succefully ( 0:success, -1 : fail) + */ + int send_message_to_launcher(sa_interface_cmd_e cmd); + +/** + * @fn int CLI_command(char *cmd, int fgetOutput, char *ret_buf) + * @brief This function to run command for daemon + * @param *cmd [in] command to run + * @param fgetoutput [in] flag to get ouput of the command + * @param * ret_buf [in] output of the command + * @return int return of function + */ + int CLI_command(char *cmd, int fgetoutput, char **ret_buf); + +#ifdef __cplusplus +} +#endif +#endif /* __ADAPTOR_UTIL_H__ */ diff --git a/src/input_file.c b/src/input_file.c new file mode 100644 index 0000000..c86a1b5 --- /dev/null +++ b/src/input_file.c @@ -0,0 +1,451 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "sa_common.h" +#include "sa_types.h" +#include "input_file.h" +#include + +#define EVENT_NAME_MAX 256 +#define EVENT_SIZE (sizeof(struct inotify_event)) +#define EVENT_BUF_LEN (512 * (EVENT_SIZE + EVENT_NAME_MAX)) +#define MAXLINE 1024 + +static volatile int cond_cnt = 0; + +/* a global count of the number of threads finished working. It will + be protected by mutex and changes to it will be signalled to the + main thread via cond */ +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; + +static void get_applied_file_name(char *file_path, char *applied_file_path, int buf_len) +{ + char buf[256]; + char *ptr = NULL; + int len; + + // find the position of the file name before the extension('.') + if ((file_path != NULL) && (applied_file_path != NULL) && (buf_len > 0)) { + ptr = strchr(file_path, '.'); + len = strlen(file_path); + if ((ptr != NULL) && (len > 5)) { + strncpy(buf, file_path, len - 5); + buf[len - 5] = 0; + } else { + _E("fail to get file name"); + } + snprintf(applied_file_path, buf_len, "%s%s", buf, "_applied.json"); + //_D("applied_file_path : %s", applied_file_path); + } else { + _E("file path is NULL ~~"); + } +} + +static int compare_config_files(char *file_path, char *applied_file_path) +{ + FILE *fp1, *fp2; + int ch1, ch2, same; + int ret = -1; + unsigned long l; + + /* open first file */ + if ((fp1 = fopen(file_path, "rb")) == NULL) { + _E("Cannot open first file."); + return -1; + } + /* open second file */ + if ((fp2 = fopen(applied_file_path, "rb")) == NULL) { + _E("Cannot open second file."); + fclose(fp1); + return -1; + } + + if (fp1 != NULL && fp2 != NULL) { + l = 0; + same = 1; + /* compare the files */ + while (!feof(fp1)) { + ch1 = fgetc(fp1); + if (ferror(fp1)) { + _E("Error reading first file."); + exit(1); + } + ch2 = fgetc(fp2); + if (ferror(fp2)) { + _E("Error reading second file."); + exit(1); + } + if (ch1 != ch2) { + //_D("Files differ at byte number %lu, %c, %c", l, ch1, ch2); + same = 0; + break; + } + l++; + } + if (same) { + //_D("Files are identical."); + ret = 0; + } else { + //_D("Files are not identical."); + ret = 1; + } + + fclose(fp1); + fclose(fp2); + } + return ret; +} + +static int update_file(char *file_path) +{ + FILE *dst; + FILE *src; + int readlen; + unsigned char buf[MAXLINE]; + char applied_file_path[256]; + + /* open first file */ + if ((src = fopen(file_path, "rb")) == NULL) { + _E("Cannot open first file."); + return -1; + } + /* open second file */ + get_applied_file_name(file_path, applied_file_path, sizeof(applied_file_path)); + if ((dst = fopen(applied_file_path, "wb")) == NULL) { + _E("Cannot open second file."); + fclose(src); + return -1; + } + + while (1) { + readlen = fread(buf, 1, MAXLINE, src); + if (readlen != MAXLINE) { + if (ferror(src)) + _E("Error reading %s", file_path); + else if (feof(src)) { + _D("EOF found"); + if (readlen > 0) + fwrite(buf, 1, readlen, dst); + } + break; + } else + fwrite(buf, 1, readlen, dst); + } + + fclose(src); + fclose(dst); + return 1; +} + +static int call_config_setting_cb(char *file_path, int (*callbackFuntion) (void *)) +{ + int ret = 0; + + _D("call setup callback function ~~~"); + if (callbackFuntion != NULL) { + if (callbackFuntion((void *)file_path) == SA_ERROR_NONE) { + _D("complete update_file ~~~~~"); + ret = update_file(file_path); + } else { + ret = -1; + _E("setting error !!"); + } + } + return ret; +} + +static int file_check(char *file_path) +{ + // Here, check the condition if we need to configure the network or system setting. + // compare the contents of two configuration files (config.json and config_applied.json) + // and call callbackfunction if needed to be updated. + + _D("start to check config file ~~~ (%s)", file_path); + int flag_update = FALSE; + int ret; + char applied_file_path[256]; + + if (access(file_path, F_OK) == 0) { + // get allpied file name to be compared. + get_applied_file_name(file_path, applied_file_path, sizeof(applied_file_path)); + + // 1. if applied file is not exist, call callbackfunction to update; + if (access(applied_file_path, F_OK) == -1) { + //_D("1. if the applied file is not existed, call setup callback function"); + flag_update = TRUE; + } else { + //_D("2. else, the applied file exists, then compare two config files ~~~"); + ret = compare_config_files(file_path, applied_file_path); + + if (ret == 1) { + flag_update = TRUE; + } else if (ret == 0) { + //_D("file is the same !!!"); + flag_update = FALSE; + } else { + _E("there are some errors in compare_config_files function."); + flag_update = -1; + } + } + _D("flag_update (%d)", flag_update); + } else { + flag_update = FALSE; + _D("There's no config file(%s)", file_path); + } + return flag_update; +} + +static void *__config_main_loop(void *arg) +{ + int fd = 0; + int wd = 0; + int i = 0; + sa_file_check_thread_s *param = NULL; + char *buffer = NULL; + int flagUpdate = 0; + + _D("__config_main_loop start"); + param = (sa_file_check_thread_s *) arg; + if (param == NULL) { + _D("param or challback is null for event"); + return NULL; + } + _D("checking file : %s", param->config_file_path); + + // 1. first check the configuration file. + flagUpdate = file_check(param->config_file_path); + if (flagUpdate == 1) { + // Apply the modified setting value to system and update the applied json file. + call_config_setting_cb(param->config_file_path, param->file_state_cb); + } else if (flagUpdate == -1) { + _E("file checking error !!"); + //return NULL; + } + _D("thread [%d] is done. Send cond_signal", param->id); + pthread_mutex_lock(&mutex); + cond_cnt++; + pthread_cond_signal(&cond); + pthread_mutex_unlock(&mutex); + + // 2. start to monitoring the configuration file. + fd = inotify_init(); + if (fd < 0) { + _E("inotify_init error"); + return NULL; + } + + wd = inotify_add_watch(fd, param->config_file_path, IN_CLOSE_WRITE); + if (wd < 0) { + _E("inotify_add_watch fail"); + close(fd); + return NULL; + } + + buffer = (char *)malloc(EVENT_BUF_LEN); + if (buffer != NULL) { + memset(buffer, 0x00, EVENT_BUF_LEN); + // Start callack + _D("Registerd Callback Triggered"); + while (1) { + int length = 0; + _D("start listening ~~~"); + length = read(fd, buffer, EVENT_BUF_LEN); + _D("event buffer read done(%d)", length); + + if (length <= 0) { + _E("read error"); + break; + } + i = 0; + while (i < length && i < (EVENT_BUF_LEN - EVENT_SIZE)) { + struct inotify_event *event = (struct inotify_event *)&buffer[i]; + _D("event->len(%d), event->mask(%d)", event->len, event->mask); + if (event->mask & IN_CLOSE_WRITE) { + if (event->mask & IN_ISDIR) { + _D("The directory was created"); + } else { + _D("callback function is called !!!!"); + // Apply the modified setting value to system and update the applied json file. + call_config_setting_cb(param->config_file_path, param->file_state_cb); + break; + } + } + i += EVENT_SIZE + event->len; + } + //_D("event buffer parse done~~~"); + } + } else { + _E("buffer is NULL"); + } + + _D("__config_main_loop close"); + inotify_rm_watch(fd, wd); + close(fd); + + if (buffer != NULL) + free(buffer); + + return NULL; +} + +void *sa_inputfile_thread(void *user_data) +{ + sa_main_thread_s *main_param = (sa_main_thread_s *) user_data; + sa_file_check_thread_s **th_param = NULL; + sa_error_e ret = SA_ERROR_NONE; + int index; + pthread_t *p_thread = NULL; + + if (main_param == NULL) { + _E("parameter is NULL !!!"); + return FALSE; + } + + cond_cnt = 0; + + _D("sa_inputfile_thread>>> config_file_num[%d]", main_param->config_file_num); + if (main_param->config_file_num > 0) { + // alloc p_thread + p_thread = (pthread_t *) malloc(main_param->config_file_num * sizeof(pthread_t)); + if (p_thread != NULL) { + th_param = (sa_file_check_thread_s **) malloc(main_param->config_file_num * sizeof(sa_file_check_thread_s *)); + if (th_param != NULL) { + // 1. create a new thread to monitoring modification of setting file. + for (index = 0; index < main_param->config_file_num; index++) { + p_thread[index] = 0; + if (access(main_param->config_file_path[index], F_OK) == 0) { + th_param[index] = (sa_file_check_thread_s *) + malloc(sizeof(sa_file_check_thread_s)); + if (th_param[index] != NULL) { + th_param[index]->config_file_path = (char *) + malloc(strlen(main_param->config_file_path[index]) + 1); + if (th_param[index]->config_file_path != NULL) { + memcpy(th_param[index]->config_file_path, main_param->config_file_path[index], strlen(main_param->config_file_path[index]) + 1); + th_param[index]->file_state_cb = main_param->setup_cb; + + // ****************** Start thread to create in order to receive event *************** // + _D("Create monitoring thread"); + th_param[index]->id = index; + if (pthread_create(&p_thread[index], NULL, &__config_main_loop, (void *)th_param[index]) < 0) { + _E("thread create error for checking configuration"); + ret = SA_ERROR_NOT_AVAILABLE; + //break; + } else { + _D("thread created (%d)", index); + } + } else { + _E("memory alloc fail !!!"); + ret = SA_ERROR_NOT_AVAILABLE; + break; + } + } + } else { + _D("No Configuration file (%s)", main_param->config_file_path[index]); + ret = SA_ERROR_INVALID_PARAMETER; + } + } + + // we're going to test "done" so we need the mutex for safety + pthread_mutex_lock(&mutex); + do { + _D("[thread main] cond_cnt is %d which is < %d so waiting on cond", cond_cnt, main_param->config_file_num); + /* block this thread until another thread signals cond. While + blocked, the mutex is released, then re-aquired before this + thread is woken up and the call returns. */ + pthread_cond_wait(&cond, &mutex); + } while (cond_cnt < main_param->config_file_num); + + _D("[thread main] done == %d so everyone is done", main_param->config_file_num); + pthread_mutex_unlock(&mutex); + if (main_param->completed_notify_cb != NULL) + main_param->completed_notify_cb(); + else + _D("no sd_notify() call !!!"); + + for (index = 0; index < main_param->config_file_num; index++) { + if (p_thread[index]) { + //_D("pthread_join(%d) index); + pthread_join(p_thread[index], NULL); + } + } + // free the allocated memory.. + for (index = 0; index < main_param->config_file_num; index++) { + if (th_param[index] != NULL) { + if (th_param[index]->config_file_path != NULL) + free(th_param[index]->config_file_path); + } + free(th_param[index]); + } + free(th_param); + } + free(p_thread); + } else + _E("memory alloc faile !!!"); + } else + _D("There's no config file to update ~~~"); + + // if return value is "FALSE", function stop + // if return value is "TRUE", function restart + return FALSE; +} + +sa_file_state_e sa_inputfile_is_file_exist(char *file_name) +{ + sa_file_state_e ret = SA_FILE_STATE_NOT_EXISTED; + + if (file_name && access(file_name, F_OK) != -1) + ret = SA_FILE_STATE_EXIST; + else + ret = SA_FILE_STATE_NOT_EXISTED; + + return ret; +} + +int sa_generate_folder(char *folder_path) +{ + int ret = 0; + + // check folder exists or not + if (folder_path != NULL) { + if (access(folder_path, F_OK) != -1) { + _D("%s folder existes !!", folder_path); + ret = -1; + } else { + // create folder + _D("folder create (%s)", folder_path); + if (mkdir(folder_path, 0644) == -1) { + _E("directory create error !!!"); + ret = -1; + } + } + } else { + _E("folder path is NULL !!"); + ret = -1; + } + + return ret; +} diff --git a/src/input_file.h b/src/input_file.h new file mode 100644 index 0000000..312c531 --- /dev/null +++ b/src/input_file.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2016-2017 Samsung Electronics Co., Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef __INPUT_FILE_H__ +#define __INPUT_FILE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "sa_types.h" + +/** + * @fn int sa_inputfile_thread + * @brief This function to call callback at the condition of file + * @param GSource parameter + * @return gboolean FALSE + */ + void *sa_inputfile_thread(void *user_data); + +/** + * @fn sa_file_state_e sa_inputfile_is_file_exist + * @brief This function to check if file exists or not + * @param file name string + * @return SA_FILE_STATE_EXIST or SA_FILE_STATE_NOT_EXISTED + */ + sa_file_state_e sa_inputfile_is_file_exist(char *file_name); + +/** + * @fn int sa_generate_env_folder + * @brief This function to create a directory + * @param folder path + * @return int + */ + int sa_generate_folder(char *folder_path); + +#ifdef __cplusplus +} +#endif +#endif /* __INPUT_FILE_H__ */ diff --git a/src/ipc_server.c b/src/ipc_server.c new file mode 100644 index 0000000..a17deb8 --- /dev/null +++ b/src/ipc_server.c @@ -0,0 +1,119 @@ +/** + * @file interface.c + * @brief API interface server + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ +#include +#include +#include +#include +#include "sa_common.h" +#include "sa_types.h" +#include "ipc.h" +#include "ipc_config.h" + +#define MAXLINE 1024 + +int IPC_StartServer(char *(*pFunc) (char *, int)) +{ + SOCKET_HANDLE handle; + int ret = 0; + char *buf = NULL; + int msgSize = 0; + char *ret_buf = NULL; + + _D("adaptor_api_server start"); + + ret = IPC_OpenServerConnection(SERVER, &handle); + + _D("IPC_OpenServerConnection ret=%d", ret); + + if (ret >= 0) { + while (1) { + if (IPC_ClientAccept(&handle) != -1) { + ret = IPC_GetMessage(&handle, &msgSize); + _D("<> msgSize = %d", msgSize); + + if (msgSize > 0) { + buf = (char *)malloc(msgSize + 1); + if (buf == NULL) { + _D("adaptor_api_server buff is null!!"); + IPC_SocketOpenClientClose(&handle); + IPC_OpenServerClose(&handle); + return -1; + } + memset(buf, 0x00, msgSize + 1); + + IPC_RecvMessage(&handle, buf, msgSize); + //_D("<> recvData = %s", buf); + /* Server mainloop */ + ret_buf = pFunc(buf, strlen(buf)); + + //_D("<> sendData = %s", ret_buf); + if (ret_buf != NULL) { + IPC_SendMessage(&handle, ret_buf, strlen(ret_buf)); + free(ret_buf); + } + + if (buf != NULL) + free(buf); + } + IPC_SocketOpenClientClose(&handle); + } + } + ret = IPC_OpenServerClose(&handle); + } else { + _E("<> server open error !!"); + return -1; + } + + _D("<> close"); + return 0; + +} + +static SOCKET_HANDLE __cbhndl; +static SOCKET_HANDLE *__pcbhndl = NULL; + +static int __open_callback_connection(void) +{ + int ret = 0; + + _D("[SERVER-CB] adaptor_server start (%s)", EVENT_SERVER); + + ret = IPC_OpenServerConnection(EVENT_SERVER, &__cbhndl); + + _D("[SERVER-CB] IPC_OpenServerConnection (ret=%d)", ret); + + if (ret >= 0) { + __pcbhndl = &__cbhndl; + + ret = IPC_ClientAccept(__pcbhndl); + _D("[SERVER-CB] IPC_ClientAccept (ret=%d)", ret); + if (0 != ret) + _E("[SERVER-CB] error (%d)", ret); + } else { + _E("[SERVER-CB] servercallback_init_connection open error !!"); + } + + return ret; + +} + +int callback_init_connection(void) +{ + int ret = 0; + _D("[SERVER-CB] callback_thread"); + + ret = __open_callback_connection(); + if (0 != ret) + _E("[SERVER-CB] __open_callback_connection Failed"); + + return ret; +} diff --git a/src/ipc_server.h b/src/ipc_server.h new file mode 100644 index 0000000..534d9ff --- /dev/null +++ b/src/ipc_server.h @@ -0,0 +1,38 @@ +/** + * @file interface.h + * @brief API interface server + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __IPC_SERVER_H__ +#define __IPC_SERVER_H__ + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @fn int IPC_StartServer(char *(*pFunc)(char *, int)) + * @brief this function to start IPC Server + * @param char *(*pFunc)(char *, int) + * @return int + */ + int IPC_StartServer(char *(*pFunc) (char *, int)); + +/** + * @fn int callback_init_connection(void) + * @brief this function to initialize callback fuction + * @param void + * @return int + */ + int callback_init_connection(void); + +#ifdef __cplusplus +} +#endif +#endif /* __IPC_SERVER_H__ */ diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100755 index 0000000..0dd8a6e --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,13 @@ +SET(LIBADAPTOR "adaptor") +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/) +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/lib/install/include/json-c) +FILE(GLOB LIBADAPTOR_SRCS *.c ${CMAKE_SOURCE_DIR}/src/json_util.c) + +INCLUDE(FindPkgConfig) +PKG_SEARCH_MODULE(JSONC json-c json) +IF(JSONC_FOUND) + ADD_DEFINITIONS(-DJSONC) + INCLUDE_DIRECTORIES(${JSONC_INCLUDE_DIRS}) +ENDIF(JSONC_FOUND) + +ADD_LIBRARY(${LIBADAPTOR} STATIC ${LIBADAPTOR_SRCS}) diff --git a/src/lib/adaptor_api.c b/src/lib/adaptor_api.c new file mode 100755 index 0000000..788fcca --- /dev/null +++ b/src/lib/adaptor_api.c @@ -0,0 +1,243 @@ +/** + * @file adaptor_api.c + * @brief library for providing adaptor API + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#include +#include +#include +#include +#include "adaptor_api.h" +#include "ipc_client.h" +#include "json_util.h" + +/** + * @fn static char *__get_funcname_param_in(char *funcName) + * @brief This function to generate in params for container info api + * @param *funcName [in] function name to make json data + * @return *char whole json data + */ +static char *__get_funcname_param_in(const char *funcName) +{ + struct json_object *newObj; + const char *buf = NULL; + char *ret_buf = NULL; + + newObj = json_object_new_object(); + json_object_object_add(newObj, "func", json_object_new_string(funcName)); + buf = json_object_to_json_string_ext(newObj, JSON_C_TO_STRING_SPACED | JSON_C_TO_STRING_PRETTY); + + ret_buf = (char *)malloc(strlen(buf) + 1); + if (ret_buf != NULL) { + memset(ret_buf, 0x00, strlen(buf) + 1); + memcpy(ret_buf, buf, strlen(buf) + 1); + } + json_object_put(newObj); + + return ret_buf; +} + +/** + * @fn static int __get_device_reboot_param_out(char *rcvData, containers_info_s *containers_info_h) + * @brief This function to generate out params for container info api + * @param *revData [in] received data from response + * @return int result of function + */ +static int __get_device_reboot_param_out(char *rcvData) +{ + int ret = -1; + if (rcvData) + ret = json_getNumber(rcvData, "result"); + else + printf("{%s}(%d) ERROR!!! NULL pointer of rcvData\n", __FUNCTION__, __LINE__); + + return ret; +} + +/** + * @fn static int __get_device_reboot_param_out(char *rcvData, os_info_s *os_info) + * @brief This function to generate out params for container info api + * @param *revData [in] received data from response + * @param *os_info [inout] fill os info into structure + * @return int result of function + */ +static int __get_os_info_param_out(char *rcvData, os_info_s *os_info) +{ + if (os_info) { + os_info->platformVer = json_getString(rcvData, "platformVer"); + os_info->baseOSVer = json_getString(rcvData, "baseOSVer"); + os_info->dockerVer = json_getString(rcvData, "dockerVer"); + } else { + printf("{%s}(%d) ERROR!!! NULL pointer of os_info\n", __FUNCTION__, __LINE__); + return -1; + } + return 0; +} + +/** + * @fn static int __get_disk_info_param_out(char *rcvData, disk_info_s *disk_info) + * @brief This function to generate out params for disk info api + * @param *revData [in] received data from response + * @param *disk_info [inout] fill disk info into structure + * @return int result of function + */ +static int __get_disk_info_param_out(char *rcvData, disk_info_s *disk_info) +{ + int index; + int diskCnt = 0; + + diskCnt = json_getNumber(rcvData, "count"); + + if (disk_info) { + disk_info->count = diskCnt; + for (index = 0; index < diskCnt; index++) { + disk_info->disk[index].path = json_getStringFromArray(rcvData, "disk", index, "path"); + disk_info->disk[index].free = json_getIntFromArray(rcvData, "disk", index, "free"); + disk_info->disk[index].total = json_getIntFromArray(rcvData, "disk", index, "total"); + disk_info->disk[index].used = json_getIntFromArray(rcvData, "disk", index, "used"); + disk_info->disk[index].usedpercent = json_getIntFromArray(rcvData, "disk", index, "usedpercent"); + } + } else { + printf("{%s}(%d) ERROR!!! NULL pointer of disk_info\n", __FUNCTION__, __LINE__); + return -1; + } + return 0; +} + +/** + * @fn static int __get_factory_restore_param_out(char *rcvData) + * @brief This function to generate out params for factory restore + * @param *revData [in] received data from response + * @return int result of function + */ +static int __get_factory_restore_param_out(char *rcvData) +{ + int ret = -1; + if (rcvData) + ret = json_getNumber(rcvData, "result"); + else + printf("{%s}(%d) ERROR!!! NULL pointer of rcvData\n", __FUNCTION__, __LINE__); + + return ret; +} + + +API int device_reboot() +{ + int ret = ADAPTOR_API_ERROR_NONE; + char *send_data = NULL; + char *ret_buf = NULL; + + send_data = __get_funcname_param_in(__FUNCTION__); + printf("Client>> SendMessage = %s\n", send_data); + + if (send_data) { + ret = IPC_CallFunction(send_data, strlen(send_data), &ret_buf); + printf("Client>> IPC_CallFunction(%d), ret_buf(%p)\n", ret, ret_buf); + if (!ret && ret_buf) { + ret = __get_device_reboot_param_out(ret_buf); + printf("ret = %d\n", ret); + } + if (ret_buf) + free(ret_buf); + free(send_data); + } + + return ret; +} + +API int get_os_info(os_info_s * os_info) +{ + int ret = ADAPTOR_API_ERROR_NONE; + char *send_data = NULL; + char *ret_buf = NULL; + + send_data = __get_funcname_param_in(__FUNCTION__); + printf("Client>> SendMessage = %s\n", send_data); + + if (send_data) { + ret = IPC_CallFunction(send_data, strlen(send_data), &ret_buf); + printf("Client>> IPC_CallFunction(%d), ret_buf(%p)\n", ret, ret_buf); + if (!ret && ret_buf) { + ret = __get_os_info_param_out(ret_buf, os_info); + /* + if (!ret) { + printf("os_info.platformVer = %s\n", os_info->platformVer); + printf("os_info.baseOSVer = %s\n", os_info->baseOSVer); + printf("os_info.dockerVer = %s\n", os_info->dockerVer); + } + */ + } + if (ret_buf) + free(ret_buf); + free(send_data); + } + + return ret; +} + +API int get_disk_info(disk_info_s *disk_info) +{ + int ret = ADAPTOR_API_ERROR_NONE; + char *send_data = NULL; + char *ret_buf = NULL; + //int index; + + send_data = __get_funcname_param_in(__FUNCTION__); + printf("Client>> SendMessage = %s\n", send_data); + + if (send_data) { + ret = IPC_CallFunction(send_data, strlen(send_data), &ret_buf); + printf("Client>> IPC_CallFunction(%d), ret_buf(%p)\n", ret, ret_buf); + if (!ret && ret_buf) { + ret = __get_disk_info_param_out(ret_buf, disk_info); + /* + if (!ret) { + for (index = 0; index < disk_info->count; index++) { + printf("disk_info[%d] path = %s\n", index, disk_info->disk[index].path); + printf("disk_info[%d] free = %dM\n", index, disk_info->disk[index].free); + printf("disk_info[%d] total = %dM\n", index, disk_info->disk[index].total); + printf("disk_info[%d] used = %dM\n", index, disk_info->disk[index].used); + printf("disk_info[%d] usedpercent = %.2f%%\n", index, (float)disk_info->disk[index].usedpercent/(float)100); + } + } + */ + } + if (ret_buf) + free(ret_buf); + free(send_data); + } + + return ret; +} + +API int factory_restore() +{ + int ret = ADAPTOR_API_ERROR_NONE; + char *send_data = NULL; + char *ret_buf = NULL; + + send_data = __get_funcname_param_in(__FUNCTION__); + printf("Client>> SendMessage = %s\n", send_data); + + if (send_data) { + ret = IPC_CallFunction(send_data, strlen(send_data), &ret_buf); + printf("Client>> IPC_CallFunction(%d), ret_buf(%p)\n", ret, ret_buf); + if (!ret && ret_buf) { + ret = __get_factory_restore_param_out(ret_buf); + printf("ret = %d\n", ret); + } + if (ret_buf) + free(ret_buf); + free(send_data); + } + + return ret; +} diff --git a/src/lib/adaptor_api.h b/src/lib/adaptor_api.h new file mode 100755 index 0000000..0193811 --- /dev/null +++ b/src/lib/adaptor_api.h @@ -0,0 +1,62 @@ +/** + * @file adaptor_api.h + * @brief library for providing adaptor API + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_API_H__ +#define __ADAPTOR_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "adaptor_api_types.h" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +/** + * @fn int device_reboot(void) + * @brief this function to reboot target device + * @param void + * @return int return of function + */ +API int device_reboot(void); + +/** + * @fn int get_os_info(void) + * @brief this function to get os information + * @param *os_info [out] fill os information + * @return int return of function + */ +API int get_os_info(os_info_s * os_info); + +/** + * @fn int device_reboot(void) + * @brief this function to get disk information + * @param *disk_info [out] fill disk information + * @return int return of function + */ +API int get_disk_info(disk_info_s * disk_info); + +/** + * @fn int factory_restore(void) + * @brief this function to restore factory state + * @param void + * @return int return of function + */ +API int factory_restore(); + +#ifdef __cplusplus +} +#endif + +#endif /* __ADAPTOR_API_H__ */ diff --git a/src/lib/build.sh b/src/lib/build.sh new file mode 100755 index 0000000..67632c8 --- /dev/null +++ b/src/lib/build.sh @@ -0,0 +1,46 @@ +#! /bin/sh +set -e + +# NOTE +# build script for cli interface with cross-compile environment +# for arm : ./build.sh arm +# for amd64 : ./build.sh +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +LIBRARY_NAME="libadaptor.a" + +TYPES_INCLUDE="../../include" +ADAPTOR_LIB_INCLUDE="install/include/adaptor/" +JSON_LIB_INCLUDE="install/include/json-c/" +# build +#JSON_LIB_PATH=`whereis json-c | awk -F' ' '{print $2}'` +if [ "$1" = "arm" ]; then + echo "****************************" + echo "Target Binary arch is ARM" + echo "****************************" + + ADAPTOR_LIB="install/arm/lib/" + arm-linux-gnueabi-gcc -static -g -c *.c -I$JSON_LIB_INCLUDE -I$TYPES_INCLUDE +else + echo "****************************" + echo "Target Binary arch is amd64" + echo "****************************" + + ADAPTOR_LIB="install/amd64/lib/" + gcc -static -g -c *.c -I$JSON_LIB_INCLUDE -I$TYPES_INCLUDE +fi +ar rc $LIBRARY_NAME *.o +echo "\033[1;96mbuilt successfully... \033[0m" +file *.o + +echo "\033[1;96minstall successfully... \033[0m" +echo "OUTPUT library : $ADAPTOR_LIB" +echo "OUTPUT header : $ADAPTOR_LIB_INCLUDE" +ls -Al $ADAPTOR_LIB + + +# install to local directory +mkdir -p $ADAPTOR_LIB +mkdir -p $ADAPTOR_LIB_INCLUDE +mv $LIBRARY_NAME $ADAPTOR_LIB +cp $TYPES_INCLUDE/*.h $ADAPTOR_LIB_INCLUDE +cp adaptor_api.h $ADAPTOR_LIB_INCLUDE diff --git a/src/lib/install/amd64/lib/libadaptor.a b/src/lib/install/amd64/lib/libadaptor.a new file mode 100644 index 0000000000000000000000000000000000000000..f577f48d8cf7c08c368135498cacee49efa5b4cd GIT binary patch literal 53230 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 Le!~&yM7{q2pzCqq literal 0 HcmV?d00001 diff --git a/src/lib/install/amd64/lib/libjson-c.a b/src/lib/install/amd64/lib/libjson-c.a new file mode 100644 index 0000000000000000000000000000000000000000..dbd17ac50e4caa70424720f17c89c2cef8322c1b GIT binary patch literal 251020 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 GA5=XUrk6`w@n14XWW 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, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * If you have libcurl problems, all docs and details are found here: + * https://curl.haxx.se/libcurl/ + * + * curl-library mailing list subscription and unsubscription web interface: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + */ + +#ifdef CURL_NO_OLDIES +#define CURL_STRICTER +#endif + +#include "curlver.h" /* libcurl version defines */ +#include "system.h" /* determine things run-time */ +#include "curlbuild.h" /* libcurl build definitions */ +#include "curlrules.h" /* libcurl rules enforcement */ + +/* + * Define WIN32 when build target is Win32 API + */ + +#if (defined(_WIN32) || defined(__WIN32__)) && \ + !defined(WIN32) && !defined(__SYMBIAN32__) +#define WIN32 +#endif + +#include +#include + +#if defined(__FreeBSD__) && (__FreeBSD__ >= 2) +/* Needed for __FreeBSD_version symbol definition */ +#include +#endif + +/* The include stuff here below is mainly for time_t! */ +#include +#include + +#if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__CYGWIN__) +#if !(defined(_WINSOCKAPI_) || defined(_WINSOCK_H) || \ + defined(__LWIP_OPT_H__) || defined(LWIP_HDR_OPT_H)) +/* The check above prevents the winsock2 inclusion if winsock.h already was + included, since they can't co-exist without problems */ +#include +#include +#endif +#endif + +/* HP-UX systems version 9, 10 and 11 lack sys/select.h and so does oldish + libc5-based Linux systems. Only include it on systems that are known to + require it! */ +#if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ + defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + (defined(__FreeBSD_version) && (__FreeBSD_version < 800000)) +#include +#endif + +#if !defined(WIN32) && !defined(_WIN32_WCE) +#include +#endif + +#if !defined(WIN32) && !defined(__WATCOMC__) && !defined(__VXWORKS__) +#include +#endif + +#ifdef __BEOS__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_easy CURL; +typedef struct Curl_share CURLSH; +#else +typedef void CURL; +typedef void CURLSH; +#endif + +/* + * libcurl external API function linkage decorations. + */ + +#ifdef CURL_STATICLIB +# define CURL_EXTERN +#elif defined(WIN32) || defined(_WIN32) || defined(__SYMBIAN32__) +# if defined(BUILDING_LIBCURL) +# define CURL_EXTERN __declspec(dllexport) +# else +# define CURL_EXTERN __declspec(dllimport) +# endif +#elif defined(BUILDING_LIBCURL) && defined(CURL_HIDDEN_SYMBOLS) +# define CURL_EXTERN CURL_EXTERN_SYMBOL +#else +# define CURL_EXTERN +#endif + +#ifndef curl_socket_typedef +/* socket typedef */ +#if defined(WIN32) && !defined(__LWIP_OPT_H__) && !defined(LWIP_HDR_OPT_H) +typedef SOCKET curl_socket_t; +#define CURL_SOCKET_BAD INVALID_SOCKET +#else +typedef int curl_socket_t; +#define CURL_SOCKET_BAD -1 +#endif +#define curl_socket_typedef +#endif /* curl_socket_typedef */ + +struct curl_httppost { + struct curl_httppost *next; /* next entry in the list */ + char *name; /* pointer to allocated name */ + long namelength; /* length of name length */ + char *contents; /* pointer to allocated data contents */ + long contentslength; /* length of contents field, see also + CURL_HTTPPOST_LARGE */ + char *buffer; /* pointer to allocated buffer contents */ + long bufferlength; /* length of buffer field */ + char *contenttype; /* Content-Type */ + struct curl_slist *contentheader; /* list of extra headers for this form */ + struct curl_httppost *more; /* if one field name has more than one + file, this link should link to following + files */ + long flags; /* as defined below */ + +/* specified content is a file name */ +#define CURL_HTTPPOST_FILENAME (1<<0) +/* specified content is a file name */ +#define CURL_HTTPPOST_READFILE (1<<1) +/* name is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRNAME (1<<2) +/* contents is only stored pointer do not free in formfree */ +#define CURL_HTTPPOST_PTRCONTENTS (1<<3) +/* upload file from buffer */ +#define CURL_HTTPPOST_BUFFER (1<<4) +/* upload file from pointer contents */ +#define CURL_HTTPPOST_PTRBUFFER (1<<5) +/* upload file contents by using the regular read callback to get the data and + pass the given pointer as custom pointer */ +#define CURL_HTTPPOST_CALLBACK (1<<6) +/* use size in 'contentlen', added in 7.46.0 */ +#define CURL_HTTPPOST_LARGE (1<<7) + + char *showfilename; /* The file name to show. If not set, the + actual file name will be used (if this + is a file part) */ + void *userp; /* custom pointer used for + HTTPPOST_CALLBACK posts */ + curl_off_t contentlen; /* alternative length of contents + field. Used if CURL_HTTPPOST_LARGE is + set. Added in 7.46.0 */ +}; + +/* This is the CURLOPT_PROGRESSFUNCTION callback proto. It is now considered + deprecated but was the only choice up until 7.31.0 */ +typedef int (*curl_progress_callback)(void *clientp, + double dltotal, + double dlnow, + double ultotal, + double ulnow); + +/* This is the CURLOPT_XFERINFOFUNCTION callback proto. It was introduced in + 7.32.0, it avoids floating point and provides more detailed information. */ +typedef int (*curl_xferinfo_callback)(void *clientp, + curl_off_t dltotal, + curl_off_t dlnow, + curl_off_t ultotal, + curl_off_t ulnow); + +#ifndef CURL_MAX_READ_SIZE + /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */ +#define CURL_MAX_READ_SIZE 524288 +#endif + +#ifndef CURL_MAX_WRITE_SIZE + /* Tests have proven that 20K is a very bad buffer size for uploads on + Windows, while 16K for some odd reason performed a lot better. + We do the ifndef check to allow this value to easier be changed at build + time for those who feel adventurous. The practical minimum is about + 400 bytes since libcurl uses a buffer of this size as a scratch area + (unrelated to network send operations). */ +#define CURL_MAX_WRITE_SIZE 16384 +#endif + +#ifndef CURL_MAX_HTTP_HEADER +/* The only reason to have a max limit for this is to avoid the risk of a bad + server feeding libcurl with a never-ending header that will cause reallocs + infinitely */ +#define CURL_MAX_HTTP_HEADER (100*1024) +#endif + +/* This is a magic return code for the write callback that, when returned, + will signal libcurl to pause receiving on the current transfer. */ +#define CURL_WRITEFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_write_callback)(char *buffer, + size_t size, + size_t nitems, + void *outstream); + + + +/* enumeration of file types */ +typedef enum { + CURLFILETYPE_FILE = 0, + CURLFILETYPE_DIRECTORY, + CURLFILETYPE_SYMLINK, + CURLFILETYPE_DEVICE_BLOCK, + CURLFILETYPE_DEVICE_CHAR, + CURLFILETYPE_NAMEDPIPE, + CURLFILETYPE_SOCKET, + CURLFILETYPE_DOOR, /* is possible only on Sun Solaris now */ + + CURLFILETYPE_UNKNOWN /* should never occur */ +} curlfiletype; + +#define CURLFINFOFLAG_KNOWN_FILENAME (1<<0) +#define CURLFINFOFLAG_KNOWN_FILETYPE (1<<1) +#define CURLFINFOFLAG_KNOWN_TIME (1<<2) +#define CURLFINFOFLAG_KNOWN_PERM (1<<3) +#define CURLFINFOFLAG_KNOWN_UID (1<<4) +#define CURLFINFOFLAG_KNOWN_GID (1<<5) +#define CURLFINFOFLAG_KNOWN_SIZE (1<<6) +#define CURLFINFOFLAG_KNOWN_HLINKCOUNT (1<<7) + +/* Content of this structure depends on information which is known and is + achievable (e.g. by FTP LIST parsing). Please see the url_easy_setopt(3) man + page for callbacks returning this structure -- some fields are mandatory, + some others are optional. The FLAG field has special meaning. */ +struct curl_fileinfo { + char *filename; + curlfiletype filetype; + time_t time; + unsigned int perm; + int uid; + int gid; + curl_off_t size; + long int hardlinks; + + struct { + /* If some of these fields is not NULL, it is a pointer to b_data. */ + char *time; + char *perm; + char *user; + char *group; + char *target; /* pointer to the target filename of a symlink */ + } strings; + + unsigned int flags; + + /* used internally */ + char *b_data; + size_t b_size; + size_t b_used; +}; + +/* return codes for CURLOPT_CHUNK_BGN_FUNCTION */ +#define CURL_CHUNK_BGN_FUNC_OK 0 +#define CURL_CHUNK_BGN_FUNC_FAIL 1 /* tell the lib to end the task */ +#define CURL_CHUNK_BGN_FUNC_SKIP 2 /* skip this chunk over */ + +/* if splitting of data transfer is enabled, this callback is called before + download of an individual chunk started. Note that parameter "remains" works + only for FTP wildcard downloading (for now), otherwise is not used */ +typedef long (*curl_chunk_bgn_callback)(const void *transfer_info, + void *ptr, + int remains); + +/* return codes for CURLOPT_CHUNK_END_FUNCTION */ +#define CURL_CHUNK_END_FUNC_OK 0 +#define CURL_CHUNK_END_FUNC_FAIL 1 /* tell the lib to end the task */ + +/* If splitting of data transfer is enabled this callback is called after + download of an individual chunk finished. + Note! After this callback was set then it have to be called FOR ALL chunks. + Even if downloading of this chunk was skipped in CHUNK_BGN_FUNC. + This is the reason why we don't need "transfer_info" parameter in this + callback and we are not interested in "remains" parameter too. */ +typedef long (*curl_chunk_end_callback)(void *ptr); + +/* return codes for FNMATCHFUNCTION */ +#define CURL_FNMATCHFUNC_MATCH 0 /* string corresponds to the pattern */ +#define CURL_FNMATCHFUNC_NOMATCH 1 /* pattern doesn't match the string */ +#define CURL_FNMATCHFUNC_FAIL 2 /* an error occurred */ + +/* callback type for wildcard downloading pattern matching. If the + string matches the pattern, return CURL_FNMATCHFUNC_MATCH value, etc. */ +typedef int (*curl_fnmatch_callback)(void *ptr, + const char *pattern, + const char *string); + +/* These are the return codes for the seek callbacks */ +#define CURL_SEEKFUNC_OK 0 +#define CURL_SEEKFUNC_FAIL 1 /* fail the entire transfer */ +#define CURL_SEEKFUNC_CANTSEEK 2 /* tell libcurl seeking can't be done, so + libcurl might try other means instead */ +typedef int (*curl_seek_callback)(void *instream, + curl_off_t offset, + int origin); /* 'whence' */ + +/* This is a return code for the read callback that, when returned, will + signal libcurl to immediately abort the current transfer. */ +#define CURL_READFUNC_ABORT 0x10000000 +/* This is a return code for the read callback that, when returned, will + signal libcurl to pause sending data on the current transfer. */ +#define CURL_READFUNC_PAUSE 0x10000001 + +typedef size_t (*curl_read_callback)(char *buffer, + size_t size, + size_t nitems, + void *instream); + +typedef enum { + CURLSOCKTYPE_IPCXN, /* socket created for a specific IP connection */ + CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */ + CURLSOCKTYPE_LAST /* never use */ +} curlsocktype; + +/* The return code from the sockopt_callback can signal information back + to libcurl: */ +#define CURL_SOCKOPT_OK 0 +#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return + CURLE_ABORTED_BY_CALLBACK */ +#define CURL_SOCKOPT_ALREADY_CONNECTED 2 + +typedef int (*curl_sockopt_callback)(void *clientp, + curl_socket_t curlfd, + curlsocktype purpose); + +struct curl_sockaddr { + int family; + int socktype; + int protocol; + unsigned int addrlen; /* addrlen was a socklen_t type before 7.18.0 but it + turned really ugly and painful on the systems that + lack this type */ + struct sockaddr addr; +}; + +typedef curl_socket_t +(*curl_opensocket_callback)(void *clientp, + curlsocktype purpose, + struct curl_sockaddr *address); + +typedef int +(*curl_closesocket_callback)(void *clientp, curl_socket_t item); + +typedef enum { + CURLIOE_OK, /* I/O operation successful */ + CURLIOE_UNKNOWNCMD, /* command was unknown to callback */ + CURLIOE_FAILRESTART, /* failed to restart the read */ + CURLIOE_LAST /* never use */ +} curlioerr; + +typedef enum { + CURLIOCMD_NOP, /* no operation */ + CURLIOCMD_RESTARTREAD, /* restart the read stream from start */ + CURLIOCMD_LAST /* never use */ +} curliocmd; + +typedef curlioerr (*curl_ioctl_callback)(CURL *handle, + int cmd, + void *clientp); + +#ifndef CURL_DID_MEMORY_FUNC_TYPEDEFS +/* + * The following typedef's are signatures of malloc, free, realloc, strdup and + * calloc respectively. Function pointers of these types can be passed to the + * curl_global_init_mem() function to set user defined memory management + * callback routines. + */ +typedef void *(*curl_malloc_callback)(size_t size); +typedef void (*curl_free_callback)(void *ptr); +typedef void *(*curl_realloc_callback)(void *ptr, size_t size); +typedef char *(*curl_strdup_callback)(const char *str); +typedef void *(*curl_calloc_callback)(size_t nmemb, size_t size); + +#define CURL_DID_MEMORY_FUNC_TYPEDEFS +#endif + +/* the kind of data that is passed to information_callback*/ +typedef enum { + CURLINFO_TEXT = 0, + CURLINFO_HEADER_IN, /* 1 */ + CURLINFO_HEADER_OUT, /* 2 */ + CURLINFO_DATA_IN, /* 3 */ + CURLINFO_DATA_OUT, /* 4 */ + CURLINFO_SSL_DATA_IN, /* 5 */ + CURLINFO_SSL_DATA_OUT, /* 6 */ + CURLINFO_END +} curl_infotype; + +typedef int (*curl_debug_callback) + (CURL *handle, /* the handle/transfer this concerns */ + curl_infotype type, /* what kind of data */ + char *data, /* points to the data */ + size_t size, /* size of the data pointed to */ + void *userptr); /* whatever the user please */ + +/* All possible error codes from all sorts of curl functions. Future versions + may return other values, stay prepared. + + Always add new return codes last. Never *EVER* remove any. The return + codes must remain the same! + */ + +typedef enum { + CURLE_OK = 0, + CURLE_UNSUPPORTED_PROTOCOL, /* 1 */ + CURLE_FAILED_INIT, /* 2 */ + CURLE_URL_MALFORMAT, /* 3 */ + CURLE_NOT_BUILT_IN, /* 4 - [was obsoleted in August 2007 for + 7.17.0, reused in April 2011 for 7.21.5] */ + CURLE_COULDNT_RESOLVE_PROXY, /* 5 */ + CURLE_COULDNT_RESOLVE_HOST, /* 6 */ + CURLE_COULDNT_CONNECT, /* 7 */ + CURLE_WEIRD_SERVER_REPLY, /* 8 */ + CURLE_REMOTE_ACCESS_DENIED, /* 9 a service was denied by the server + due to lack of access - when login fails + this is not returned. */ + CURLE_FTP_ACCEPT_FAILED, /* 10 - [was obsoleted in April 2006 for + 7.15.4, reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASS_REPLY, /* 11 */ + CURLE_FTP_ACCEPT_TIMEOUT, /* 12 - timeout occurred accepting server + [was obsoleted in August 2007 for 7.17.0, + reused in Dec 2011 for 7.24.0]*/ + CURLE_FTP_WEIRD_PASV_REPLY, /* 13 */ + CURLE_FTP_WEIRD_227_FORMAT, /* 14 */ + CURLE_FTP_CANT_GET_HOST, /* 15 */ + CURLE_HTTP2, /* 16 - A problem in the http2 framing layer. + [was obsoleted in August 2007 for 7.17.0, + reused in July 2014 for 7.38.0] */ + CURLE_FTP_COULDNT_SET_TYPE, /* 17 */ + CURLE_PARTIAL_FILE, /* 18 */ + CURLE_FTP_COULDNT_RETR_FILE, /* 19 */ + CURLE_OBSOLETE20, /* 20 - NOT USED */ + CURLE_QUOTE_ERROR, /* 21 - quote command failure */ + CURLE_HTTP_RETURNED_ERROR, /* 22 */ + CURLE_WRITE_ERROR, /* 23 */ + CURLE_OBSOLETE24, /* 24 - NOT USED */ + CURLE_UPLOAD_FAILED, /* 25 - failed upload "command" */ + CURLE_READ_ERROR, /* 26 - couldn't open/read from file */ + CURLE_OUT_OF_MEMORY, /* 27 */ + /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error + instead of a memory allocation error if CURL_DOES_CONVERSIONS + is defined + */ + CURLE_OPERATION_TIMEDOUT, /* 28 - the timeout time was reached */ + CURLE_OBSOLETE29, /* 29 - NOT USED */ + CURLE_FTP_PORT_FAILED, /* 30 - FTP PORT operation failed */ + CURLE_FTP_COULDNT_USE_REST, /* 31 - the REST command failed */ + CURLE_OBSOLETE32, /* 32 - NOT USED */ + CURLE_RANGE_ERROR, /* 33 - RANGE "command" didn't work */ + CURLE_HTTP_POST_ERROR, /* 34 */ + CURLE_SSL_CONNECT_ERROR, /* 35 - wrong when connecting with SSL */ + CURLE_BAD_DOWNLOAD_RESUME, /* 36 - couldn't resume download */ + CURLE_FILE_COULDNT_READ_FILE, /* 37 */ + CURLE_LDAP_CANNOT_BIND, /* 38 */ + CURLE_LDAP_SEARCH_FAILED, /* 39 */ + CURLE_OBSOLETE40, /* 40 - NOT USED */ + CURLE_FUNCTION_NOT_FOUND, /* 41 - NOT USED starting with 7.53.0 */ + CURLE_ABORTED_BY_CALLBACK, /* 42 */ + CURLE_BAD_FUNCTION_ARGUMENT, /* 43 */ + CURLE_OBSOLETE44, /* 44 - NOT USED */ + CURLE_INTERFACE_FAILED, /* 45 - CURLOPT_INTERFACE failed */ + CURLE_OBSOLETE46, /* 46 - NOT USED */ + CURLE_TOO_MANY_REDIRECTS, /* 47 - catch endless re-direct loops */ + CURLE_UNKNOWN_OPTION, /* 48 - User specified an unknown option */ + CURLE_TELNET_OPTION_SYNTAX, /* 49 - Malformed telnet option */ + CURLE_OBSOLETE50, /* 50 - NOT USED */ + CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint + wasn't verified fine */ + CURLE_GOT_NOTHING, /* 52 - when this is a specific error */ + CURLE_SSL_ENGINE_NOTFOUND, /* 53 - SSL crypto engine not found */ + CURLE_SSL_ENGINE_SETFAILED, /* 54 - can not set SSL crypto engine as + default */ + CURLE_SEND_ERROR, /* 55 - failed sending network data */ + CURLE_RECV_ERROR, /* 56 - failure in receiving network data */ + CURLE_OBSOLETE57, /* 57 - NOT IN USE */ + CURLE_SSL_CERTPROBLEM, /* 58 - problem with the local certificate */ + CURLE_SSL_CIPHER, /* 59 - couldn't use specified cipher */ + CURLE_SSL_CACERT, /* 60 - problem with the CA cert (path?) */ + CURLE_BAD_CONTENT_ENCODING, /* 61 - Unrecognized/bad encoding */ + CURLE_LDAP_INVALID_URL, /* 62 - Invalid LDAP URL */ + CURLE_FILESIZE_EXCEEDED, /* 63 - Maximum file size exceeded */ + CURLE_USE_SSL_FAILED, /* 64 - Requested FTP SSL level failed */ + CURLE_SEND_FAIL_REWIND, /* 65 - Sending the data requires a rewind + that failed */ + CURLE_SSL_ENGINE_INITFAILED, /* 66 - failed to initialise ENGINE */ + CURLE_LOGIN_DENIED, /* 67 - user, password or similar was not + accepted and we failed to login */ + CURLE_TFTP_NOTFOUND, /* 68 - file not found on server */ + CURLE_TFTP_PERM, /* 69 - permission problem on server */ + CURLE_REMOTE_DISK_FULL, /* 70 - out of disk space on server */ + CURLE_TFTP_ILLEGAL, /* 71 - Illegal TFTP operation */ + CURLE_TFTP_UNKNOWNID, /* 72 - Unknown transfer ID */ + CURLE_REMOTE_FILE_EXISTS, /* 73 - File already exists */ + CURLE_TFTP_NOSUCHUSER, /* 74 - No such user */ + CURLE_CONV_FAILED, /* 75 - conversion failed */ + CURLE_CONV_REQD, /* 76 - caller must register conversion + callbacks using curl_easy_setopt options + CURLOPT_CONV_FROM_NETWORK_FUNCTION, + CURLOPT_CONV_TO_NETWORK_FUNCTION, and + CURLOPT_CONV_FROM_UTF8_FUNCTION */ + CURLE_SSL_CACERT_BADFILE, /* 77 - could not load CACERT file, missing + or wrong format */ + CURLE_REMOTE_FILE_NOT_FOUND, /* 78 - remote file not found */ + CURLE_SSH, /* 79 - error from the SSH layer, somewhat + generic so the error message will be of + interest when this has happened */ + + CURLE_SSL_SHUTDOWN_FAILED, /* 80 - Failed to shut down the SSL + connection */ + CURLE_AGAIN, /* 81 - socket is not ready for send/recv, + wait till it's ready and try again (Added + in 7.18.2) */ + CURLE_SSL_CRL_BADFILE, /* 82 - could not load CRL file, missing or + wrong format (Added in 7.19.0) */ + CURLE_SSL_ISSUER_ERROR, /* 83 - Issuer check failed. (Added in + 7.19.0) */ + CURLE_FTP_PRET_FAILED, /* 84 - a PRET command failed */ + CURLE_RTSP_CSEQ_ERROR, /* 85 - mismatch of RTSP CSeq numbers */ + CURLE_RTSP_SESSION_ERROR, /* 86 - mismatch of RTSP Session Ids */ + CURLE_FTP_BAD_FILE_LIST, /* 87 - unable to parse FTP file list */ + CURLE_CHUNK_FAILED, /* 88 - chunk callback reported error */ + CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the + session will be queued */ + CURLE_SSL_PINNEDPUBKEYNOTMATCH, /* 90 - specified pinned public key did not + match */ + CURLE_SSL_INVALIDCERTSTATUS, /* 91 - invalid certificate status */ + CURLE_HTTP2_STREAM, /* 92 - stream error in HTTP/2 framing layer + */ + CURL_LAST /* never use! */ +} CURLcode; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Previously obsolete error code re-used in 7.38.0 */ +#define CURLE_OBSOLETE16 CURLE_HTTP2 + +/* Previously obsolete error codes re-used in 7.24.0 */ +#define CURLE_OBSOLETE10 CURLE_FTP_ACCEPT_FAILED +#define CURLE_OBSOLETE12 CURLE_FTP_ACCEPT_TIMEOUT + +/* compatibility with older names */ +#define CURLOPT_ENCODING CURLOPT_ACCEPT_ENCODING +#define CURLE_FTP_WEIRD_SERVER_REPLY CURLE_WEIRD_SERVER_REPLY + +/* The following were added in 7.21.5, April 2011 */ +#define CURLE_UNKNOWN_TELNET_OPTION CURLE_UNKNOWN_OPTION + +/* The following were added in 7.17.1 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_SSL_PEER_CERTIFICATE CURLE_PEER_FAILED_VERIFICATION + +/* The following were added in 7.17.0 */ +/* These are scheduled to disappear by 2009 */ +#define CURLE_OBSOLETE CURLE_OBSOLETE50 /* no one should be using this! */ +#define CURLE_BAD_PASSWORD_ENTERED CURLE_OBSOLETE46 +#define CURLE_BAD_CALLING_ORDER CURLE_OBSOLETE44 +#define CURLE_FTP_USER_PASSWORD_INCORRECT CURLE_OBSOLETE10 +#define CURLE_FTP_CANT_RECONNECT CURLE_OBSOLETE16 +#define CURLE_FTP_COULDNT_GET_SIZE CURLE_OBSOLETE32 +#define CURLE_FTP_COULDNT_SET_ASCII CURLE_OBSOLETE29 +#define CURLE_FTP_WEIRD_USER_REPLY CURLE_OBSOLETE12 +#define CURLE_FTP_WRITE_ERROR CURLE_OBSOLETE20 +#define CURLE_LIBRARY_NOT_FOUND CURLE_OBSOLETE40 +#define CURLE_MALFORMAT_USER CURLE_OBSOLETE24 +#define CURLE_SHARE_IN_USE CURLE_OBSOLETE57 +#define CURLE_URL_MALFORMAT_USER CURLE_NOT_BUILT_IN + +#define CURLE_FTP_ACCESS_DENIED CURLE_REMOTE_ACCESS_DENIED +#define CURLE_FTP_COULDNT_SET_BINARY CURLE_FTP_COULDNT_SET_TYPE +#define CURLE_FTP_QUOTE_ERROR CURLE_QUOTE_ERROR +#define CURLE_TFTP_DISKFULL CURLE_REMOTE_DISK_FULL +#define CURLE_TFTP_EXISTS CURLE_REMOTE_FILE_EXISTS +#define CURLE_HTTP_RANGE_ERROR CURLE_RANGE_ERROR +#define CURLE_FTP_SSL_FAILED CURLE_USE_SSL_FAILED + +/* The following were added earlier */ + +#define CURLE_OPERATION_TIMEOUTED CURLE_OPERATION_TIMEDOUT + +#define CURLE_HTTP_NOT_FOUND CURLE_HTTP_RETURNED_ERROR +#define CURLE_HTTP_PORT_FAILED CURLE_INTERFACE_FAILED +#define CURLE_FTP_COULDNT_STOR_FILE CURLE_UPLOAD_FAILED + +#define CURLE_FTP_PARTIAL_FILE CURLE_PARTIAL_FILE +#define CURLE_FTP_BAD_DOWNLOAD_RESUME CURLE_BAD_DOWNLOAD_RESUME + +/* This was the error code 50 in 7.7.3 and a few earlier versions, this + is no longer used by libcurl but is instead #defined here only to not + make programs break */ +#define CURLE_ALREADY_COMPLETE 99999 + +/* Provide defines for really old option names */ +#define CURLOPT_FILE CURLOPT_WRITEDATA /* name changed in 7.9.7 */ +#define CURLOPT_INFILE CURLOPT_READDATA /* name changed in 7.9.7 */ +#define CURLOPT_WRITEHEADER CURLOPT_HEADERDATA + +/* Since long deprecated options with no code in the lib that does anything + with them. */ +#define CURLOPT_WRITEINFO CURLOPT_OBSOLETE40 +#define CURLOPT_CLOSEPOLICY CURLOPT_OBSOLETE72 + +#endif /*!CURL_NO_OLDIES*/ + +/* This prototype applies to all conversion callbacks */ +typedef CURLcode (*curl_conv_callback)(char *buffer, size_t length); + +typedef CURLcode (*curl_ssl_ctx_callback)(CURL *curl, /* easy handle */ + void *ssl_ctx, /* actually an + OpenSSL SSL_CTX */ + void *userptr); + +typedef enum { + CURLPROXY_HTTP = 0, /* added in 7.10, new in 7.19.4 default is to use + CONNECT HTTP/1.1 */ + CURLPROXY_HTTP_1_0 = 1, /* added in 7.19.4, force to use CONNECT + HTTP/1.0 */ + CURLPROXY_HTTPS = 2, /* added in 7.52.0 */ + CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already + in 7.10 */ + CURLPROXY_SOCKS5 = 5, /* added in 7.10 */ + CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */ + CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the + host name rather than the IP address. added + in 7.18.0 */ +} curl_proxytype; /* this enum was added in 7.10 */ + +/* + * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options: + * + * CURLAUTH_NONE - No HTTP authentication + * CURLAUTH_BASIC - HTTP Basic authentication (default) + * CURLAUTH_DIGEST - HTTP Digest authentication + * CURLAUTH_NEGOTIATE - HTTP Negotiate (SPNEGO) authentication + * CURLAUTH_GSSNEGOTIATE - Alias for CURLAUTH_NEGOTIATE (deprecated) + * CURLAUTH_NTLM - HTTP NTLM authentication + * CURLAUTH_DIGEST_IE - HTTP Digest authentication with IE flavour + * CURLAUTH_NTLM_WB - HTTP NTLM authentication delegated to winbind helper + * CURLAUTH_ONLY - Use together with a single other type to force no + * authentication or just that single type + * CURLAUTH_ANY - All fine types set + * CURLAUTH_ANYSAFE - All fine types except Basic + */ + +#define CURLAUTH_NONE ((unsigned long)0) +#define CURLAUTH_BASIC (((unsigned long)1)<<0) +#define CURLAUTH_DIGEST (((unsigned long)1)<<1) +#define CURLAUTH_NEGOTIATE (((unsigned long)1)<<2) +/* Deprecated since the advent of CURLAUTH_NEGOTIATE */ +#define CURLAUTH_GSSNEGOTIATE CURLAUTH_NEGOTIATE +#define CURLAUTH_NTLM (((unsigned long)1)<<3) +#define CURLAUTH_DIGEST_IE (((unsigned long)1)<<4) +#define CURLAUTH_NTLM_WB (((unsigned long)1)<<5) +#define CURLAUTH_ONLY (((unsigned long)1)<<31) +#define CURLAUTH_ANY (~CURLAUTH_DIGEST_IE) +#define CURLAUTH_ANYSAFE (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE)) + +#define CURLSSH_AUTH_ANY ~0 /* all types supported by the server */ +#define CURLSSH_AUTH_NONE 0 /* none allowed, silly but complete */ +#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */ +#define CURLSSH_AUTH_PASSWORD (1<<1) /* password */ +#define CURLSSH_AUTH_HOST (1<<2) /* host key files */ +#define CURLSSH_AUTH_KEYBOARD (1<<3) /* keyboard interactive */ +#define CURLSSH_AUTH_AGENT (1<<4) /* agent (ssh-agent, pageant...) */ +#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY + +#define CURLGSSAPI_DELEGATION_NONE 0 /* no delegation (default) */ +#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */ +#define CURLGSSAPI_DELEGATION_FLAG (1<<1) /* delegate always */ + +#define CURL_ERROR_SIZE 256 + +enum curl_khtype { + CURLKHTYPE_UNKNOWN, + CURLKHTYPE_RSA1, + CURLKHTYPE_RSA, + CURLKHTYPE_DSS +}; + +struct curl_khkey { + const char *key; /* points to a zero-terminated string encoded with base64 + if len is zero, otherwise to the "raw" data */ + size_t len; + enum curl_khtype keytype; +}; + +/* this is the set of return values expected from the curl_sshkeycallback + callback */ +enum curl_khstat { + CURLKHSTAT_FINE_ADD_TO_FILE, + CURLKHSTAT_FINE, + CURLKHSTAT_REJECT, /* reject the connection, return an error */ + CURLKHSTAT_DEFER, /* do not accept it, but we can't answer right now so + this causes a CURLE_DEFER error but otherwise the + connection will be left intact etc */ + CURLKHSTAT_LAST /* not for use, only a marker for last-in-list */ +}; + +/* this is the set of status codes pass in to the callback */ +enum curl_khmatch { + CURLKHMATCH_OK, /* match */ + CURLKHMATCH_MISMATCH, /* host found, key mismatch! */ + CURLKHMATCH_MISSING, /* no matching host/key found */ + CURLKHMATCH_LAST /* not for use, only a marker for last-in-list */ +}; + +typedef int + (*curl_sshkeycallback) (CURL *easy, /* easy handle */ + const struct curl_khkey *knownkey, /* known */ + const struct curl_khkey *foundkey, /* found */ + enum curl_khmatch, /* libcurl's view on the keys */ + void *clientp); /* custom pointer passed from app */ + +/* parameter for the CURLOPT_USE_SSL option */ +typedef enum { + CURLUSESSL_NONE, /* do not attempt to use SSL */ + CURLUSESSL_TRY, /* try using SSL, proceed anyway otherwise */ + CURLUSESSL_CONTROL, /* SSL for the control connection or fail */ + CURLUSESSL_ALL, /* SSL for all communication or fail */ + CURLUSESSL_LAST /* not an option, never use */ +} curl_usessl; + +/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */ + +/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the + name of improving interoperability with older servers. Some SSL libraries + have introduced work-arounds for this flaw but those work-arounds sometimes + make the SSL communication fail. To regain functionality with those broken + servers, a user can this way allow the vulnerability back. */ +#define CURLSSLOPT_ALLOW_BEAST (1<<0) + +/* - NO_REVOKE tells libcurl to disable certificate revocation checks for those + SSL backends where such behavior is present. */ +#define CURLSSLOPT_NO_REVOKE (1<<1) + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2009 */ + +#define CURLFTPSSL_NONE CURLUSESSL_NONE +#define CURLFTPSSL_TRY CURLUSESSL_TRY +#define CURLFTPSSL_CONTROL CURLUSESSL_CONTROL +#define CURLFTPSSL_ALL CURLUSESSL_ALL +#define CURLFTPSSL_LAST CURLUSESSL_LAST +#define curl_ftpssl curl_usessl +#endif /*!CURL_NO_OLDIES*/ + +/* parameter for the CURLOPT_FTP_SSL_CCC option */ +typedef enum { + CURLFTPSSL_CCC_NONE, /* do not send CCC */ + CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */ + CURLFTPSSL_CCC_ACTIVE, /* Initiate the shutdown */ + CURLFTPSSL_CCC_LAST /* not an option, never use */ +} curl_ftpccc; + +/* parameter for the CURLOPT_FTPSSLAUTH option */ +typedef enum { + CURLFTPAUTH_DEFAULT, /* let libcurl decide */ + CURLFTPAUTH_SSL, /* use "AUTH SSL" */ + CURLFTPAUTH_TLS, /* use "AUTH TLS" */ + CURLFTPAUTH_LAST /* not an option, never use */ +} curl_ftpauth; + +/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */ +typedef enum { + CURLFTP_CREATE_DIR_NONE, /* do NOT create missing dirs! */ + CURLFTP_CREATE_DIR, /* (FTP/SFTP) if CWD fails, try MKD and then CWD + again if MKD succeeded, for SFTP this does + similar magic */ + CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD + again even if MKD failed! */ + CURLFTP_CREATE_DIR_LAST /* not an option, never use */ +} curl_ftpcreatedir; + +/* parameter for the CURLOPT_FTP_FILEMETHOD option */ +typedef enum { + CURLFTPMETHOD_DEFAULT, /* let libcurl pick */ + CURLFTPMETHOD_MULTICWD, /* single CWD operation for each path part */ + CURLFTPMETHOD_NOCWD, /* no CWD at all */ + CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */ + CURLFTPMETHOD_LAST /* not an option, never use */ +} curl_ftpmethod; + +/* bitmask defines for CURLOPT_HEADEROPT */ +#define CURLHEADER_UNIFIED 0 +#define CURLHEADER_SEPARATE (1<<0) + +/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */ +#define CURLPROTO_HTTP (1<<0) +#define CURLPROTO_HTTPS (1<<1) +#define CURLPROTO_FTP (1<<2) +#define CURLPROTO_FTPS (1<<3) +#define CURLPROTO_SCP (1<<4) +#define CURLPROTO_SFTP (1<<5) +#define CURLPROTO_TELNET (1<<6) +#define CURLPROTO_LDAP (1<<7) +#define CURLPROTO_LDAPS (1<<8) +#define CURLPROTO_DICT (1<<9) +#define CURLPROTO_FILE (1<<10) +#define CURLPROTO_TFTP (1<<11) +#define CURLPROTO_IMAP (1<<12) +#define CURLPROTO_IMAPS (1<<13) +#define CURLPROTO_POP3 (1<<14) +#define CURLPROTO_POP3S (1<<15) +#define CURLPROTO_SMTP (1<<16) +#define CURLPROTO_SMTPS (1<<17) +#define CURLPROTO_RTSP (1<<18) +#define CURLPROTO_RTMP (1<<19) +#define CURLPROTO_RTMPT (1<<20) +#define CURLPROTO_RTMPE (1<<21) +#define CURLPROTO_RTMPTE (1<<22) +#define CURLPROTO_RTMPS (1<<23) +#define CURLPROTO_RTMPTS (1<<24) +#define CURLPROTO_GOPHER (1<<25) +#define CURLPROTO_SMB (1<<26) +#define CURLPROTO_SMBS (1<<27) +#define CURLPROTO_ALL (~0) /* enable everything */ + +/* long may be 32 or 64 bits, but we should never depend on anything else + but 32 */ +#define CURLOPTTYPE_LONG 0 +#define CURLOPTTYPE_OBJECTPOINT 10000 +#define CURLOPTTYPE_STRINGPOINT 10000 +#define CURLOPTTYPE_FUNCTIONPOINT 20000 +#define CURLOPTTYPE_OFF_T 30000 + +/* *STRINGPOINT is an alias for OBJECTPOINT to allow tools to extract the + string options from the header file */ + +/* name is uppercase CURLOPT_, + type is one of the defined CURLOPTTYPE_ + number is unique identifier */ +#ifdef CINIT +#undef CINIT +#endif + +#ifdef CURL_ISOCPP +#define CINIT(na,t,nu) CURLOPT_ ## na = CURLOPTTYPE_ ## t + nu +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define STRINGPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLOPT_/**/name = type + number +#endif + +/* + * This macro-mania below setups the CURLOPT_[what] enum, to be used with + * curl_easy_setopt(). The first argument in the CINIT() macro is the [what] + * word. + */ + +typedef enum { + /* This is the FILE * or void * the regular output should be written to. */ + CINIT(WRITEDATA, OBJECTPOINT, 1), + + /* The full URL to get/put */ + CINIT(URL, STRINGPOINT, 2), + + /* Port number to connect to, if other than default. */ + CINIT(PORT, LONG, 3), + + /* Name of proxy to use. */ + CINIT(PROXY, STRINGPOINT, 4), + + /* "user:password;options" to use when fetching. */ + CINIT(USERPWD, STRINGPOINT, 5), + + /* "user:password" to use with proxy. */ + CINIT(PROXYUSERPWD, STRINGPOINT, 6), + + /* Range to get, specified as an ASCII string. */ + CINIT(RANGE, STRINGPOINT, 7), + + /* not used */ + + /* Specified file stream to upload from (use as input): */ + CINIT(READDATA, OBJECTPOINT, 9), + + /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE + * bytes big. If this is not used, error messages go to stderr instead: */ + CINIT(ERRORBUFFER, OBJECTPOINT, 10), + + /* Function that will be called to store the output (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11), + + /* Function that will be called to read the input (instead of fread). The + * parameters will use fread() syntax, make sure to follow them. */ + CINIT(READFUNCTION, FUNCTIONPOINT, 12), + + /* Time-out the read operation after this amount of seconds */ + CINIT(TIMEOUT, LONG, 13), + + /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about + * how large the file being sent really is. That allows better error + * checking and better verifies that the upload was successful. -1 means + * unknown size. + * + * For large file support, there is also a _LARGE version of the key + * which takes an off_t type, allowing platforms with larger off_t + * sizes to handle larger files. See below for INFILESIZE_LARGE. + */ + CINIT(INFILESIZE, LONG, 14), + + /* POST static input fields. */ + CINIT(POSTFIELDS, OBJECTPOINT, 15), + + /* Set the referrer page (needed by some CGIs) */ + CINIT(REFERER, STRINGPOINT, 16), + + /* Set the FTP PORT string (interface name, named or numerical IP address) + Use i.e '-' to use default address. */ + CINIT(FTPPORT, STRINGPOINT, 17), + + /* Set the User-Agent string (examined by some CGIs) */ + CINIT(USERAGENT, STRINGPOINT, 18), + + /* If the download receives less than "low speed limit" bytes/second + * during "low speed time" seconds, the operations is aborted. + * You could i.e if you have a pretty high speed connection, abort if + * it is less than 2000 bytes/sec during 20 seconds. + */ + + /* Set the "low speed limit" */ + CINIT(LOW_SPEED_LIMIT, LONG, 19), + + /* Set the "low speed time" */ + CINIT(LOW_SPEED_TIME, LONG, 20), + + /* Set the continuation offset. + * + * Note there is also a _LARGE version of this key which uses + * off_t types, allowing for large file offsets on platforms which + * use larger-than-32-bit off_t's. Look below for RESUME_FROM_LARGE. + */ + CINIT(RESUME_FROM, LONG, 21), + + /* Set cookie in request: */ + CINIT(COOKIE, STRINGPOINT, 22), + + /* This points to a linked list of headers, struct curl_slist kind. This + list is also used for RTSP (in spite of its name) */ + CINIT(HTTPHEADER, OBJECTPOINT, 23), + + /* This points to a linked list of post entries, struct curl_httppost */ + CINIT(HTTPPOST, OBJECTPOINT, 24), + + /* name of the file keeping your private SSL-certificate */ + CINIT(SSLCERT, STRINGPOINT, 25), + + /* password for the SSL or SSH private key */ + CINIT(KEYPASSWD, STRINGPOINT, 26), + + /* send TYPE parameter? */ + CINIT(CRLF, LONG, 27), + + /* send linked-list of QUOTE commands */ + CINIT(QUOTE, OBJECTPOINT, 28), + + /* send FILE * or void * to store headers to, if you use a callback it + is simply passed to the callback unmodified */ + CINIT(HEADERDATA, OBJECTPOINT, 29), + + /* point to a file to read the initial cookies from, also enables + "cookie awareness" */ + CINIT(COOKIEFILE, STRINGPOINT, 31), + + /* What version to specifically try to use. + See CURL_SSLVERSION defines below. */ + CINIT(SSLVERSION, LONG, 32), + + /* What kind of HTTP time condition to use, see defines */ + CINIT(TIMECONDITION, LONG, 33), + + /* Time to use with the above condition. Specified in number of seconds + since 1 Jan 1970 */ + CINIT(TIMEVALUE, LONG, 34), + + /* 35 = OBSOLETE */ + + /* Custom request, for customizing the get command like + HTTP: DELETE, TRACE and others + FTP: to use a different list command + */ + CINIT(CUSTOMREQUEST, STRINGPOINT, 36), + + /* FILE handle to use instead of stderr */ + CINIT(STDERR, OBJECTPOINT, 37), + + /* 38 is not used */ + + /* send linked-list of post-transfer QUOTE commands */ + CINIT(POSTQUOTE, OBJECTPOINT, 39), + + CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */ + + CINIT(VERBOSE, LONG, 41), /* talk a lot */ + CINIT(HEADER, LONG, 42), /* throw the header out too */ + CINIT(NOPROGRESS, LONG, 43), /* shut off the progress meter */ + CINIT(NOBODY, LONG, 44), /* use HEAD to get http document */ + CINIT(FAILONERROR, LONG, 45), /* no output on http error codes >= 400 */ + CINIT(UPLOAD, LONG, 46), /* this is an upload */ + CINIT(POST, LONG, 47), /* HTTP POST method */ + CINIT(DIRLISTONLY, LONG, 48), /* bare names when listing directories */ + + CINIT(APPEND, LONG, 50), /* Append instead of overwrite on upload! */ + + /* Specify whether to read the user+password from the .netrc or the URL. + * This must be one of the CURL_NETRC_* enums below. */ + CINIT(NETRC, LONG, 51), + + CINIT(FOLLOWLOCATION, LONG, 52), /* use Location: Luke! */ + + CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */ + CINIT(PUT, LONG, 54), /* HTTP PUT */ + + /* 55 = OBSOLETE */ + + /* DEPRECATED + * Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_progress_callback + * prototype defines. */ + CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56), + + /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION + callbacks */ + CINIT(PROGRESSDATA, OBJECTPOINT, 57), +#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA + + /* We want the referrer field set automatically when following locations */ + CINIT(AUTOREFERER, LONG, 58), + + /* Port of the proxy, can be set in the proxy string as well with: + "[host]:[port]" */ + CINIT(PROXYPORT, LONG, 59), + + /* size of the POST input data, if strlen() is not good to use */ + CINIT(POSTFIELDSIZE, LONG, 60), + + /* tunnel non-http operations through a HTTP proxy */ + CINIT(HTTPPROXYTUNNEL, LONG, 61), + + /* Set the interface string to use as outgoing network interface */ + CINIT(INTERFACE, STRINGPOINT, 62), + + /* Set the krb4/5 security level, this also enables krb4/5 awareness. This + * is a string, 'clear', 'safe', 'confidential' or 'private'. If the string + * is set but doesn't match one of these, 'private' will be used. */ + CINIT(KRBLEVEL, STRINGPOINT, 63), + + /* Set if we should verify the peer in ssl handshake, set 1 to verify. */ + CINIT(SSL_VERIFYPEER, LONG, 64), + + /* The CApath or CAfile used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAINFO, STRINGPOINT, 65), + + /* 66 = OBSOLETE */ + /* 67 = OBSOLETE */ + + /* Maximum number of http redirects to follow */ + CINIT(MAXREDIRS, LONG, 68), + + /* Pass a long set to 1 to get the date of the requested document (if + possible)! Pass a zero to shut it off. */ + CINIT(FILETIME, LONG, 69), + + /* This points to a linked list of telnet options */ + CINIT(TELNETOPTIONS, OBJECTPOINT, 70), + + /* Max amount of cached alive connections */ + CINIT(MAXCONNECTS, LONG, 71), + + CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */ + + /* 73 = OBSOLETE */ + + /* Set to explicitly use a new connection for the upcoming transfer. + Do not use this unless you're absolutely sure of this, as it makes the + operation slower and is less friendly for the network. */ + CINIT(FRESH_CONNECT, LONG, 74), + + /* Set to explicitly forbid the upcoming transfer's connection to be re-used + when done. Do not use this unless you're absolutely sure of this, as it + makes the operation slower and is less friendly for the network. */ + CINIT(FORBID_REUSE, LONG, 75), + + /* Set to a file name that contains random data for libcurl to use to + seed the random engine when doing SSL connects. */ + CINIT(RANDOM_FILE, STRINGPOINT, 76), + + /* Set to the Entropy Gathering Daemon socket pathname */ + CINIT(EGDSOCKET, STRINGPOINT, 77), + + /* Time-out connect operations after this amount of seconds, if connects are + OK within this time, then fine... This only aborts the connect phase. */ + CINIT(CONNECTTIMEOUT, LONG, 78), + + /* Function that will be called to store headers (instead of fwrite). The + * parameters will use fwrite() syntax, make sure to follow them. */ + CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79), + + /* Set this to force the HTTP request to get back to GET. Only really usable + if POST, PUT or a custom request have been used first. + */ + CINIT(HTTPGET, LONG, 80), + + /* Set if we should verify the Common name from the peer certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches the + * provided hostname. */ + CINIT(SSL_VERIFYHOST, LONG, 81), + + /* Specify which file name to write all known cookies in after completed + operation. Set file name to "-" (dash) to make it go to stdout. */ + CINIT(COOKIEJAR, STRINGPOINT, 82), + + /* Specify which SSL ciphers to use */ + CINIT(SSL_CIPHER_LIST, STRINGPOINT, 83), + + /* Specify which HTTP version to use! This must be set to one of the + CURL_HTTP_VERSION* enums set below. */ + CINIT(HTTP_VERSION, LONG, 84), + + /* Specifically switch on or off the FTP engine's use of the EPSV command. By + default, that one will always be attempted before the more traditional + PASV command. */ + CINIT(FTP_USE_EPSV, LONG, 85), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */ + CINIT(SSLCERTTYPE, STRINGPOINT, 86), + + /* name of the file keeping your private SSL-key */ + CINIT(SSLKEY, STRINGPOINT, 87), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */ + CINIT(SSLKEYTYPE, STRINGPOINT, 88), + + /* crypto engine for the SSL-sub system */ + CINIT(SSLENGINE, STRINGPOINT, 89), + + /* set the crypto engine for the SSL-sub system as default + the param has no meaning... + */ + CINIT(SSLENGINE_DEFAULT, LONG, 90), + + /* Non-zero value means to use the global dns cache */ + CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */ + + /* DNS cache timeout */ + CINIT(DNS_CACHE_TIMEOUT, LONG, 92), + + /* send linked-list of pre-transfer QUOTE commands */ + CINIT(PREQUOTE, OBJECTPOINT, 93), + + /* set the debug function */ + CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94), + + /* set the data for the debug function */ + CINIT(DEBUGDATA, OBJECTPOINT, 95), + + /* mark this as start of a cookie session */ + CINIT(COOKIESESSION, LONG, 96), + + /* The CApath directory used to validate the peer certificate + this option is used only if SSL_VERIFYPEER is true */ + CINIT(CAPATH, STRINGPOINT, 97), + + /* Instruct libcurl to use a smaller receive buffer */ + CINIT(BUFFERSIZE, LONG, 98), + + /* Instruct libcurl to not use any signal/alarm handlers, even when using + timeouts. This option is useful for multi-threaded applications. + See libcurl-the-guide for more background information. */ + CINIT(NOSIGNAL, LONG, 99), + + /* Provide a CURLShare for mutexing non-ts data */ + CINIT(SHARE, OBJECTPOINT, 100), + + /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default), + CURLPROXY_HTTPS, CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and + CURLPROXY_SOCKS5. */ + CINIT(PROXYTYPE, LONG, 101), + + /* Set the Accept-Encoding string. Use this to tell a server you would like + the response to be compressed. Before 7.21.6, this was known as + CURLOPT_ENCODING */ + CINIT(ACCEPT_ENCODING, STRINGPOINT, 102), + + /* Set pointer to private data */ + CINIT(PRIVATE, OBJECTPOINT, 103), + + /* Set aliases for HTTP 200 in the HTTP Response header */ + CINIT(HTTP200ALIASES, OBJECTPOINT, 104), + + /* Continue to send authentication (user+password) when following locations, + even when hostname changed. This can potentially send off the name + and password to whatever host the server decides. */ + CINIT(UNRESTRICTED_AUTH, LONG, 105), + + /* Specifically switch on or off the FTP engine's use of the EPRT command ( + it also disables the LPRT attempt). By default, those ones will always be + attempted before the good old traditional PORT command. */ + CINIT(FTP_USE_EPRT, LONG, 106), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_USERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(HTTPAUTH, LONG, 107), + + /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx + in second argument. The function must be matching the + curl_ssl_ctx_callback proto. */ + CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108), + + /* Set the userdata for the ssl context callback function's third + argument */ + CINIT(SSL_CTX_DATA, OBJECTPOINT, 109), + + /* FTP Option that causes missing dirs to be created on the remote server. + In 7.19.4 we introduced the convenience enums for this option using the + CURLFTP_CREATE_DIR prefix. + */ + CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110), + + /* Set this to a bitmask value to enable the particular authentications + methods you like. Use this in combination with CURLOPT_PROXYUSERPWD. + Note that setting multiple bits may cause extra network round-trips. */ + CINIT(PROXYAUTH, LONG, 111), + + /* FTP option that changes the timeout, in seconds, associated with + getting a response. This is different from transfer timeout time and + essentially places a demand on the FTP server to acknowledge commands + in a timely manner. */ + CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112), +#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT + + /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to + tell libcurl to resolve names to those IP versions only. This only has + affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */ + CINIT(IPRESOLVE, LONG, 113), + + /* Set this option to limit the size of a file that will be downloaded from + an HTTP or FTP server. + + Note there is also _LARGE version which adds large file support for + platforms which have larger off_t sizes. See MAXFILESIZE_LARGE below. */ + CINIT(MAXFILESIZE, LONG, 114), + + /* See the comment for INFILESIZE above, but in short, specifies + * the size of the file being uploaded. -1 means unknown. + */ + CINIT(INFILESIZE_LARGE, OFF_T, 115), + + /* Sets the continuation offset. There is also a LONG version of this; + * look above for RESUME_FROM. + */ + CINIT(RESUME_FROM_LARGE, OFF_T, 116), + + /* Sets the maximum size of data that will be downloaded from + * an HTTP or FTP server. See MAXFILESIZE above for the LONG version. + */ + CINIT(MAXFILESIZE_LARGE, OFF_T, 117), + + /* Set this option to the file name of your .netrc file you want libcurl + to parse (using the CURLOPT_NETRC option). If not set, libcurl will do + a poor attempt to find the user's home directory and check for a .netrc + file in there. */ + CINIT(NETRC_FILE, STRINGPOINT, 118), + + /* Enable SSL/TLS for FTP, pick one of: + CURLUSESSL_TRY - try using SSL, proceed anyway otherwise + CURLUSESSL_CONTROL - SSL for the control connection or fail + CURLUSESSL_ALL - SSL for all communication or fail + */ + CINIT(USE_SSL, LONG, 119), + + /* The _LARGE version of the standard POSTFIELDSIZE option */ + CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120), + + /* Enable/disable the TCP Nagle algorithm */ + CINIT(TCP_NODELAY, LONG, 121), + + /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 123 OBSOLETE. Gone in 7.16.0 */ + /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */ + /* 127 OBSOLETE. Gone in 7.16.0 */ + /* 128 OBSOLETE. Gone in 7.16.0 */ + + /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option + can be used to change libcurl's default action which is to first try + "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK + response has been received. + + Available parameters are: + CURLFTPAUTH_DEFAULT - let libcurl decide + CURLFTPAUTH_SSL - try "AUTH SSL" first, then TLS + CURLFTPAUTH_TLS - try "AUTH TLS" first, then SSL + */ + CINIT(FTPSSLAUTH, LONG, 129), + + CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130), + CINIT(IOCTLDATA, OBJECTPOINT, 131), + + /* 132 OBSOLETE. Gone in 7.16.0 */ + /* 133 OBSOLETE. Gone in 7.16.0 */ + + /* zero terminated string for pass on to the FTP server when asked for + "account" info */ + CINIT(FTP_ACCOUNT, STRINGPOINT, 134), + + /* feed cookie into cookie engine */ + CINIT(COOKIELIST, STRINGPOINT, 135), + + /* ignore Content-Length */ + CINIT(IGNORE_CONTENT_LENGTH, LONG, 136), + + /* Set to non-zero to skip the IP address received in a 227 PASV FTP server + response. Typically used for FTP-SSL purposes but is not restricted to + that. libcurl will then instead use the same IP address it used for the + control connection. */ + CINIT(FTP_SKIP_PASV_IP, LONG, 137), + + /* Select "file method" to use when doing FTP, see the curl_ftpmethod + above. */ + CINIT(FTP_FILEMETHOD, LONG, 138), + + /* Local port number to bind the socket to */ + CINIT(LOCALPORT, LONG, 139), + + /* Number of ports to try, including the first one set with LOCALPORT. + Thus, setting it to 1 will make no additional attempts but the first. + */ + CINIT(LOCALPORTRANGE, LONG, 140), + + /* no transfer, set up connection and let application use the socket by + extracting it with CURLINFO_LASTSOCKET */ + CINIT(CONNECT_ONLY, LONG, 141), + + /* Function that will be called to convert from the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142), + + /* Function that will be called to convert to the + network encoding (instead of using the iconv calls in libcurl) */ + CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143), + + /* Function that will be called to convert from UTF8 + (instead of using the iconv calls in libcurl) + Note that this is used only for SSL certificate processing */ + CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144), + + /* if the connection proceeds too quickly then need to slow it down */ + /* limit-rate: maximum number of bytes per second to send or receive */ + CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145), + CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146), + + /* Pointer to command string to send if USER/PASS fails. */ + CINIT(FTP_ALTERNATIVE_TO_USER, STRINGPOINT, 147), + + /* callback function for setting socket options */ + CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148), + CINIT(SOCKOPTDATA, OBJECTPOINT, 149), + + /* set to 0 to disable session ID re-use for this transfer, default is + enabled (== 1) */ + CINIT(SSL_SESSIONID_CACHE, LONG, 150), + + /* allowed SSH authentication methods */ + CINIT(SSH_AUTH_TYPES, LONG, 151), + + /* Used by scp/sftp to do public/private key authentication */ + CINIT(SSH_PUBLIC_KEYFILE, STRINGPOINT, 152), + CINIT(SSH_PRIVATE_KEYFILE, STRINGPOINT, 153), + + /* Send CCC (Clear Command Channel) after authentication */ + CINIT(FTP_SSL_CCC, LONG, 154), + + /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */ + CINIT(TIMEOUT_MS, LONG, 155), + CINIT(CONNECTTIMEOUT_MS, LONG, 156), + + /* set to zero to disable the libcurl's decoding and thus pass the raw body + data to the application even when it is encoded/compressed */ + CINIT(HTTP_TRANSFER_DECODING, LONG, 157), + CINIT(HTTP_CONTENT_DECODING, LONG, 158), + + /* Permission used when creating new files and directories on the remote + server for protocols that support it, SFTP/SCP/FILE */ + CINIT(NEW_FILE_PERMS, LONG, 159), + CINIT(NEW_DIRECTORY_PERMS, LONG, 160), + + /* Set the behaviour of POST when redirecting. Values must be set to one + of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */ + CINIT(POSTREDIR, LONG, 161), + + /* used by scp/sftp to verify the host's public key */ + CINIT(SSH_HOST_PUBLIC_KEY_MD5, STRINGPOINT, 162), + + /* Callback function for opening socket (instead of socket(2)). Optionally, + callback is able change the address or refuse to connect returning + CURL_SOCKET_BAD. The callback should have type + curl_opensocket_callback */ + CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163), + CINIT(OPENSOCKETDATA, OBJECTPOINT, 164), + + /* POST volatile input fields. */ + CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165), + + /* set transfer mode (;type=) when doing FTP via an HTTP proxy */ + CINIT(PROXY_TRANSFER_MODE, LONG, 166), + + /* Callback function for seeking in the input stream */ + CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167), + CINIT(SEEKDATA, OBJECTPOINT, 168), + + /* CRL file */ + CINIT(CRLFILE, STRINGPOINT, 169), + + /* Issuer certificate */ + CINIT(ISSUERCERT, STRINGPOINT, 170), + + /* (IPv6) Address scope */ + CINIT(ADDRESS_SCOPE, LONG, 171), + + /* Collect certificate chain info and allow it to get retrievable with + CURLINFO_CERTINFO after the transfer is complete. */ + CINIT(CERTINFO, LONG, 172), + + /* "name" and "pwd" to use when fetching. */ + CINIT(USERNAME, STRINGPOINT, 173), + CINIT(PASSWORD, STRINGPOINT, 174), + + /* "name" and "pwd" to use with Proxy when fetching. */ + CINIT(PROXYUSERNAME, STRINGPOINT, 175), + CINIT(PROXYPASSWORD, STRINGPOINT, 176), + + /* Comma separated list of hostnames defining no-proxy zones. These should + match both hostnames directly, and hostnames within a domain. For + example, local.com will match local.com and www.local.com, but NOT + notlocal.com or www.notlocal.com. For compatibility with other + implementations of this, .local.com will be considered to be the same as + local.com. A single * is the only valid wildcard, and effectively + disables the use of proxy. */ + CINIT(NOPROXY, STRINGPOINT, 177), + + /* block size for TFTP transfers */ + CINIT(TFTP_BLKSIZE, LONG, 178), + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_SERVICE, STRINGPOINT, 179), /* DEPRECATED, do not use! */ + + /* Socks Service */ + CINIT(SOCKS5_GSSAPI_NEC, LONG, 180), + + /* set the bitmask for the protocols that are allowed to be used for the + transfer, which thus helps the app which takes URLs from users or other + external inputs and want to restrict what protocol(s) to deal + with. Defaults to CURLPROTO_ALL. */ + CINIT(PROTOCOLS, LONG, 181), + + /* set the bitmask for the protocols that libcurl is allowed to follow to, + as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs + to be set in both bitmasks to be allowed to get redirected to. Defaults + to all protocols except FILE and SCP. */ + CINIT(REDIR_PROTOCOLS, LONG, 182), + + /* set the SSH knownhost file name to use */ + CINIT(SSH_KNOWNHOSTS, STRINGPOINT, 183), + + /* set the SSH host key callback, must point to a curl_sshkeycallback + function */ + CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184), + + /* set the SSH host key callback custom pointer */ + CINIT(SSH_KEYDATA, OBJECTPOINT, 185), + + /* set the SMTP mail originator */ + CINIT(MAIL_FROM, STRINGPOINT, 186), + + /* set the list of SMTP mail receiver(s) */ + CINIT(MAIL_RCPT, OBJECTPOINT, 187), + + /* FTP: send PRET before PASV */ + CINIT(FTP_USE_PRET, LONG, 188), + + /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */ + CINIT(RTSP_REQUEST, LONG, 189), + + /* The RTSP session identifier */ + CINIT(RTSP_SESSION_ID, STRINGPOINT, 190), + + /* The RTSP stream URI */ + CINIT(RTSP_STREAM_URI, STRINGPOINT, 191), + + /* The Transport: header to use in RTSP requests */ + CINIT(RTSP_TRANSPORT, STRINGPOINT, 192), + + /* Manually initialize the client RTSP CSeq for this handle */ + CINIT(RTSP_CLIENT_CSEQ, LONG, 193), + + /* Manually initialize the server RTSP CSeq for this handle */ + CINIT(RTSP_SERVER_CSEQ, LONG, 194), + + /* The stream to pass to INTERLEAVEFUNCTION. */ + CINIT(INTERLEAVEDATA, OBJECTPOINT, 195), + + /* Let the application define a custom write method for RTP data */ + CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196), + + /* Turn on wildcard matching */ + CINIT(WILDCARDMATCH, LONG, 197), + + /* Directory matching callback called before downloading of an + individual file (chunk) started */ + CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198), + + /* Directory matching callback called after the file (chunk) + was downloaded, or skipped */ + CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199), + + /* Change match (fnmatch-like) callback for wildcard matching */ + CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200), + + /* Let the application define custom chunk data pointer */ + CINIT(CHUNK_DATA, OBJECTPOINT, 201), + + /* FNMATCH_FUNCTION user pointer */ + CINIT(FNMATCH_DATA, OBJECTPOINT, 202), + + /* send linked-list of name:port:address sets */ + CINIT(RESOLVE, OBJECTPOINT, 203), + + /* Set a username for authenticated TLS */ + CINIT(TLSAUTH_USERNAME, STRINGPOINT, 204), + + /* Set a password for authenticated TLS */ + CINIT(TLSAUTH_PASSWORD, STRINGPOINT, 205), + + /* Set authentication type for authenticated TLS */ + CINIT(TLSAUTH_TYPE, STRINGPOINT, 206), + + /* Set to 1 to enable the "TE:" header in HTTP requests to ask for + compressed transfer-encoded responses. Set to 0 to disable the use of TE: + in outgoing requests. The current default is 0, but it might change in a + future libcurl release. + + libcurl will ask for the compressed methods it knows of, and if that + isn't any, it will not ask for transfer-encoding at all even if this + option is set to 1. + + */ + CINIT(TRANSFER_ENCODING, LONG, 207), + + /* Callback function for closing socket (instead of close(2)). The callback + should have type curl_closesocket_callback */ + CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208), + CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209), + + /* allow GSSAPI credential delegation */ + CINIT(GSSAPI_DELEGATION, LONG, 210), + + /* Set the name servers to use for DNS resolution */ + CINIT(DNS_SERVERS, STRINGPOINT, 211), + + /* Time-out accept operations (currently for FTP only) after this amount + of milliseconds. */ + CINIT(ACCEPTTIMEOUT_MS, LONG, 212), + + /* Set TCP keepalive */ + CINIT(TCP_KEEPALIVE, LONG, 213), + + /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */ + CINIT(TCP_KEEPIDLE, LONG, 214), + CINIT(TCP_KEEPINTVL, LONG, 215), + + /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */ + CINIT(SSL_OPTIONS, LONG, 216), + + /* Set the SMTP auth originator */ + CINIT(MAIL_AUTH, STRINGPOINT, 217), + + /* Enable/disable SASL initial response */ + CINIT(SASL_IR, LONG, 218), + + /* Function that will be called instead of the internal progress display + * function. This function should be defined as the curl_xferinfo_callback + * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */ + CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219), + + /* The XOAUTH2 bearer token */ + CINIT(XOAUTH2_BEARER, STRINGPOINT, 220), + + /* Set the interface string to use as outgoing network + * interface for DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_INTERFACE, STRINGPOINT, 221), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP4, STRINGPOINT, 222), + + /* Set the local IPv4 address to use for outgoing DNS requests. + * Only supported by the c-ares DNS backend */ + CINIT(DNS_LOCAL_IP6, STRINGPOINT, 223), + + /* Set authentication options directly */ + CINIT(LOGIN_OPTIONS, STRINGPOINT, 224), + + /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_NPN, LONG, 225), + + /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */ + CINIT(SSL_ENABLE_ALPN, LONG, 226), + + /* Time to wait for a response to a HTTP request containing an + * Expect: 100-continue header before sending the data anyway. */ + CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227), + + /* This points to a linked list of headers used for proxy requests only, + struct curl_slist kind */ + CINIT(PROXYHEADER, OBJECTPOINT, 228), + + /* Pass in a bitmask of "header options" */ + CINIT(HEADEROPT, LONG, 229), + + /* The public key in DER form used to validate the peer public key + this option is used only if SSL_VERIFYPEER is true */ + CINIT(PINNEDPUBLICKEY, STRINGPOINT, 230), + + /* Path to Unix domain socket */ + CINIT(UNIX_SOCKET_PATH, STRINGPOINT, 231), + + /* Set if we should verify the certificate status. */ + CINIT(SSL_VERIFYSTATUS, LONG, 232), + + /* Set if we should enable TLS false start. */ + CINIT(SSL_FALSESTART, LONG, 233), + + /* Do not squash dot-dot sequences */ + CINIT(PATH_AS_IS, LONG, 234), + + /* Proxy Service Name */ + CINIT(PROXY_SERVICE_NAME, STRINGPOINT, 235), + + /* Service Name */ + CINIT(SERVICE_NAME, STRINGPOINT, 236), + + /* Wait/don't wait for pipe/mutex to clarify */ + CINIT(PIPEWAIT, LONG, 237), + + /* Set the protocol used when curl is given a URL without a protocol */ + CINIT(DEFAULT_PROTOCOL, STRINGPOINT, 238), + + /* Set stream weight, 1 - 256 (default is 16) */ + CINIT(STREAM_WEIGHT, LONG, 239), + + /* Set stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS, OBJECTPOINT, 240), + + /* Set E-xclusive stream dependency on another CURL handle */ + CINIT(STREAM_DEPENDS_E, OBJECTPOINT, 241), + + /* Do not send any tftp option requests to the server */ + CINIT(TFTP_NO_OPTIONS, LONG, 242), + + /* Linked-list of host:port:connect-to-host:connect-to-port, + overrides the URL's host:port (only for the network layer) */ + CINIT(CONNECT_TO, OBJECTPOINT, 243), + + /* Set TCP Fast Open */ + CINIT(TCP_FASTOPEN, LONG, 244), + + /* Continue to send data if the server responds early with an + * HTTP status code >= 300 */ + CINIT(KEEP_SENDING_ON_ERROR, LONG, 245), + + /* The CApath or CAfile used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAINFO, STRINGPOINT, 246), + + /* The CApath directory used to validate the proxy certificate + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_CAPATH, STRINGPOINT, 247), + + /* Set if we should verify the proxy in ssl handshake, + set 1 to verify. */ + CINIT(PROXY_SSL_VERIFYPEER, LONG, 248), + + /* Set if we should verify the Common name from the proxy certificate in ssl + * handshake, set 1 to check existence, 2 to ensure that it matches + * the provided hostname. */ + CINIT(PROXY_SSL_VERIFYHOST, LONG, 249), + + /* What version to specifically try to use for proxy. + See CURL_SSLVERSION defines below. */ + CINIT(PROXY_SSLVERSION, LONG, 250), + + /* Set a username for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_USERNAME, STRINGPOINT, 251), + + /* Set a password for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_PASSWORD, STRINGPOINT, 252), + + /* Set authentication type for authenticated TLS for proxy */ + CINIT(PROXY_TLSAUTH_TYPE, STRINGPOINT, 253), + + /* name of the file keeping your private SSL-certificate for proxy */ + CINIT(PROXY_SSLCERT, STRINGPOINT, 254), + + /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLCERTTYPE, STRINGPOINT, 255), + + /* name of the file keeping your private SSL-key for proxy */ + CINIT(PROXY_SSLKEY, STRINGPOINT, 256), + + /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") for + proxy */ + CINIT(PROXY_SSLKEYTYPE, STRINGPOINT, 257), + + /* password for the SSL private key for proxy */ + CINIT(PROXY_KEYPASSWD, STRINGPOINT, 258), + + /* Specify which SSL ciphers to use for proxy */ + CINIT(PROXY_SSL_CIPHER_LIST, STRINGPOINT, 259), + + /* CRL file for proxy */ + CINIT(PROXY_CRLFILE, STRINGPOINT, 260), + + /* Enable/disable specific SSL features with a bitmask for proxy, see + CURLSSLOPT_* */ + CINIT(PROXY_SSL_OPTIONS, LONG, 261), + + /* Name of pre proxy to use. */ + CINIT(PRE_PROXY, STRINGPOINT, 262), + + /* The public key in DER form used to validate the proxy public key + this option is used only if PROXY_SSL_VERIFYPEER is true */ + CINIT(PROXY_PINNEDPUBLICKEY, STRINGPOINT, 263), + + /* Path to an abstract Unix domain socket */ + CINIT(ABSTRACT_UNIX_SOCKET, STRINGPOINT, 264), + + /* Suppress proxy CONNECT response headers from user callbacks */ + CINIT(SUPPRESS_CONNECT_HEADERS, LONG, 265), + + CURLOPT_LASTENTRY /* the last unused */ +} CURLoption; + +#ifndef CURL_NO_OLDIES /* define this to test if your app builds with all + the obsolete stuff removed! */ + +/* Backwards compatibility with older names */ +/* These are scheduled to disappear by 2011 */ + +/* This was added in version 7.19.1 */ +#define CURLOPT_POST301 CURLOPT_POSTREDIR + +/* These are scheduled to disappear by 2009 */ + +/* The following were added in 7.17.0 */ +#define CURLOPT_SSLKEYPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_FTPAPPEND CURLOPT_APPEND +#define CURLOPT_FTPLISTONLY CURLOPT_DIRLISTONLY +#define CURLOPT_FTP_SSL CURLOPT_USE_SSL + +/* The following were added earlier */ + +#define CURLOPT_SSLCERTPASSWD CURLOPT_KEYPASSWD +#define CURLOPT_KRB4LEVEL CURLOPT_KRBLEVEL + +#else +/* This is set if CURL_NO_OLDIES is defined at compile-time */ +#undef CURLOPT_DNS_USE_GLOBAL_CACHE /* soon obsolete */ +#endif + + + /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host + name resolves addresses using more than one IP protocol version, this + option might be handy to force libcurl to use a specific IP version. */ +#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP + versions that your system allows */ +#define CURL_IPRESOLVE_V4 1 /* resolve to IPv4 addresses */ +#define CURL_IPRESOLVE_V6 2 /* resolve to IPv6 addresses */ + + /* three convenient "aliases" that follow the name scheme better */ +#define CURLOPT_RTSPHEADER CURLOPT_HTTPHEADER + + /* These enums are for use with the CURLOPT_HTTP_VERSION option. */ +enum { + CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd + like the library to choose the best possible + for us! */ + CURL_HTTP_VERSION_1_0, /* please use HTTP 1.0 in the request */ + CURL_HTTP_VERSION_1_1, /* please use HTTP 1.1 in the request */ + CURL_HTTP_VERSION_2_0, /* please use HTTP 2 in the request */ + CURL_HTTP_VERSION_2TLS, /* use version 2 for HTTPS, version 1.1 for HTTP */ + CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE, /* please use HTTP 2 without HTTP/1.1 + Upgrade */ + + CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */ +}; + +/* Convenience definition simple because the name of the version is HTTP/2 and + not 2.0. The 2_0 version of the enum name was set while the version was + still planned to be 2.0 and we stick to it for compatibility. */ +#define CURL_HTTP_VERSION_2 CURL_HTTP_VERSION_2_0 + +/* + * Public API enums for RTSP requests + */ +enum { + CURL_RTSPREQ_NONE, /* first in list */ + CURL_RTSPREQ_OPTIONS, + CURL_RTSPREQ_DESCRIBE, + CURL_RTSPREQ_ANNOUNCE, + CURL_RTSPREQ_SETUP, + CURL_RTSPREQ_PLAY, + CURL_RTSPREQ_PAUSE, + CURL_RTSPREQ_TEARDOWN, + CURL_RTSPREQ_GET_PARAMETER, + CURL_RTSPREQ_SET_PARAMETER, + CURL_RTSPREQ_RECORD, + CURL_RTSPREQ_RECEIVE, + CURL_RTSPREQ_LAST /* last in list */ +}; + + /* These enums are for use with the CURLOPT_NETRC option. */ +enum CURL_NETRC_OPTION { + CURL_NETRC_IGNORED, /* The .netrc will never be read. + * This is the default. */ + CURL_NETRC_OPTIONAL, /* A user:password in the URL will be preferred + * to one in the .netrc. */ + CURL_NETRC_REQUIRED, /* A user:password in the URL will be ignored. + * Unless one is set programmatically, the .netrc + * will be queried. */ + CURL_NETRC_LAST +}; + +enum { + CURL_SSLVERSION_DEFAULT, + CURL_SSLVERSION_TLSv1, /* TLS 1.x */ + CURL_SSLVERSION_SSLv2, + CURL_SSLVERSION_SSLv3, + CURL_SSLVERSION_TLSv1_0, + CURL_SSLVERSION_TLSv1_1, + CURL_SSLVERSION_TLSv1_2, + CURL_SSLVERSION_TLSv1_3, + + CURL_SSLVERSION_LAST /* never use, keep last */ +}; + +enum { + CURL_SSLVERSION_MAX_NONE = 0, + CURL_SSLVERSION_MAX_DEFAULT = (CURL_SSLVERSION_TLSv1 << 16), + CURL_SSLVERSION_MAX_TLSv1_0 = (CURL_SSLVERSION_TLSv1_0 << 16), + CURL_SSLVERSION_MAX_TLSv1_1 = (CURL_SSLVERSION_TLSv1_1 << 16), + CURL_SSLVERSION_MAX_TLSv1_2 = (CURL_SSLVERSION_TLSv1_2 << 16), + CURL_SSLVERSION_MAX_TLSv1_3 = (CURL_SSLVERSION_TLSv1_3 << 16), + + /* never use, keep last */ + CURL_SSLVERSION_MAX_LAST = (CURL_SSLVERSION_LAST << 16) +}; + +enum CURL_TLSAUTH { + CURL_TLSAUTH_NONE, + CURL_TLSAUTH_SRP, + CURL_TLSAUTH_LAST /* never use, keep last */ +}; + +/* symbols to use with CURLOPT_POSTREDIR. + CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303 + can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302 + | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */ + +#define CURL_REDIR_GET_ALL 0 +#define CURL_REDIR_POST_301 1 +#define CURL_REDIR_POST_302 2 +#define CURL_REDIR_POST_303 4 +#define CURL_REDIR_POST_ALL \ + (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303) + +typedef enum { + CURL_TIMECOND_NONE, + + CURL_TIMECOND_IFMODSINCE, + CURL_TIMECOND_IFUNMODSINCE, + CURL_TIMECOND_LASTMOD, + + CURL_TIMECOND_LAST +} curl_TimeCond; + + +/* curl_strequal() and curl_strnequal() are subject for removal in a future + libcurl, see lib/README.curlx for details + + !checksrc! disable SPACEBEFOREPAREN 2 +*/ +CURL_EXTERN int (curl_strequal)(const char *s1, const char *s2); +CURL_EXTERN int (curl_strnequal)(const char *s1, const char *s2, size_t n); + +/* name is uppercase CURLFORM_ */ +#ifdef CFINIT +#undef CFINIT +#endif + +#ifdef CURL_ISOCPP +#define CFINIT(name) CURLFORM_ ## name +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define CFINIT(name) CURLFORM_/**/name +#endif + +typedef enum { + CFINIT(NOTHING), /********* the first one is unused ************/ + + /* */ + CFINIT(COPYNAME), + CFINIT(PTRNAME), + CFINIT(NAMELENGTH), + CFINIT(COPYCONTENTS), + CFINIT(PTRCONTENTS), + CFINIT(CONTENTSLENGTH), + CFINIT(FILECONTENT), + CFINIT(ARRAY), + CFINIT(OBSOLETE), + CFINIT(FILE), + + CFINIT(BUFFER), + CFINIT(BUFFERPTR), + CFINIT(BUFFERLENGTH), + + CFINIT(CONTENTTYPE), + CFINIT(CONTENTHEADER), + CFINIT(FILENAME), + CFINIT(END), + CFINIT(OBSOLETE2), + + CFINIT(STREAM), + CFINIT(CONTENTLEN), /* added in 7.46.0, provide a curl_off_t length */ + + CURLFORM_LASTENTRY /* the last unused */ +} CURLformoption; + +#undef CFINIT /* done */ + +/* structure to be used as parameter for CURLFORM_ARRAY */ +struct curl_forms { + CURLformoption option; + const char *value; +}; + +/* use this for multipart formpost building */ +/* Returns code for curl_formadd() + * + * Returns: + * CURL_FORMADD_OK on success + * CURL_FORMADD_MEMORY if the FormInfo allocation fails + * CURL_FORMADD_OPTION_TWICE if one option is given twice for one Form + * CURL_FORMADD_NULL if a null pointer was given for a char + * CURL_FORMADD_MEMORY if the allocation of a FormInfo struct failed + * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used + * CURL_FORMADD_INCOMPLETE if the some FormInfo is not complete (or error) + * CURL_FORMADD_MEMORY if a curl_httppost struct cannot be allocated + * CURL_FORMADD_MEMORY if some allocation for string copying failed. + * CURL_FORMADD_ILLEGAL_ARRAY if an illegal option is used in an array + * + ***************************************************************************/ +typedef enum { + CURL_FORMADD_OK, /* first, no error */ + + CURL_FORMADD_MEMORY, + CURL_FORMADD_OPTION_TWICE, + CURL_FORMADD_NULL, + CURL_FORMADD_UNKNOWN_OPTION, + CURL_FORMADD_INCOMPLETE, + CURL_FORMADD_ILLEGAL_ARRAY, + CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */ + + CURL_FORMADD_LAST /* last */ +} CURLFORMcode; + +/* + * NAME curl_formadd() + * + * DESCRIPTION + * + * Pretty advanced function for building multi-part formposts. Each invoke + * adds one part that together construct a full post. Then use + * CURLOPT_HTTPPOST to send it off to libcurl. + */ +CURL_EXTERN CURLFORMcode curl_formadd(struct curl_httppost **httppost, + struct curl_httppost **last_post, + ...); + +/* + * callback function for curl_formget() + * The void *arg pointer will be the one passed as second argument to + * curl_formget(). + * The character buffer passed to it must not be freed. + * Should return the buffer length passed to it as the argument "len" on + * success. + */ +typedef size_t (*curl_formget_callback)(void *arg, const char *buf, + size_t len); + +/* + * NAME curl_formget() + * + * DESCRIPTION + * + * Serialize a curl_httppost struct built with curl_formadd(). + * Accepts a void pointer as second argument which will be passed to + * the curl_formget_callback function. + * Returns 0 on success. + */ +CURL_EXTERN int curl_formget(struct curl_httppost *form, void *arg, + curl_formget_callback append); +/* + * NAME curl_formfree() + * + * DESCRIPTION + * + * Free a multipart formpost previously built with curl_formadd(). + */ +CURL_EXTERN void curl_formfree(struct curl_httppost *form); + +/* + * NAME curl_getenv() + * + * DESCRIPTION + * + * Returns a malloc()'ed string that MUST be curl_free()ed after usage is + * complete. DEPRECATED - see lib/README.curlx + */ +CURL_EXTERN char *curl_getenv(const char *variable); + +/* + * NAME curl_version() + * + * DESCRIPTION + * + * Returns a static ascii string of the libcurl version. + */ +CURL_EXTERN char *curl_version(void); + +/* + * NAME curl_easy_escape() + * + * DESCRIPTION + * + * Escapes URL strings (converts all letters consider illegal in URLs to their + * %XX versions). This function returns a new allocated string or NULL if an + * error occurred. + */ +CURL_EXTERN char *curl_easy_escape(CURL *handle, + const char *string, + int length); + +/* the previous version: */ +CURL_EXTERN char *curl_escape(const char *string, + int length); + + +/* + * NAME curl_easy_unescape() + * + * DESCRIPTION + * + * Unescapes URL encoding in strings (converts all %XX codes to their 8bit + * versions). This function returns a new allocated string or NULL if an error + * occurred. + * Conversion Note: On non-ASCII platforms the ASCII %XX codes are + * converted into the host encoding. + */ +CURL_EXTERN char *curl_easy_unescape(CURL *handle, + const char *string, + int length, + int *outlength); + +/* the previous version */ +CURL_EXTERN char *curl_unescape(const char *string, + int length); + +/* + * NAME curl_free() + * + * DESCRIPTION + * + * Provided for de-allocation in the same translation unit that did the + * allocation. Added in libcurl 7.10 + */ +CURL_EXTERN void curl_free(void *p); + +/* + * NAME curl_global_init() + * + * DESCRIPTION + * + * curl_global_init() should be invoked exactly once for each application that + * uses libcurl and before any call of other libcurl functions. + * + * This function is not thread-safe! + */ +CURL_EXTERN CURLcode curl_global_init(long flags); + +/* + * NAME curl_global_init_mem() + * + * DESCRIPTION + * + * curl_global_init() or curl_global_init_mem() should be invoked exactly once + * for each application that uses libcurl. This function can be used to + * initialize libcurl and set user defined memory management callback + * functions. Users can implement memory management routines to check for + * memory leaks, check for mis-use of the curl library etc. User registered + * callback routines with be invoked by this library instead of the system + * memory management routines like malloc, free etc. + */ +CURL_EXTERN CURLcode curl_global_init_mem(long flags, + curl_malloc_callback m, + curl_free_callback f, + curl_realloc_callback r, + curl_strdup_callback s, + curl_calloc_callback c); + +/* + * NAME curl_global_cleanup() + * + * DESCRIPTION + * + * curl_global_cleanup() should be invoked exactly once for each application + * that uses libcurl + */ +CURL_EXTERN void curl_global_cleanup(void); + +/* linked-list structure for the CURLOPT_QUOTE option (and other) */ +struct curl_slist { + char *data; + struct curl_slist *next; +}; + +/* + * NAME curl_slist_append() + * + * DESCRIPTION + * + * Appends a string to a linked list. If no list exists, it will be created + * first. Returns the new list, after appending. + */ +CURL_EXTERN struct curl_slist *curl_slist_append(struct curl_slist *, + const char *); + +/* + * NAME curl_slist_free_all() + * + * DESCRIPTION + * + * free a previously built curl_slist. + */ +CURL_EXTERN void curl_slist_free_all(struct curl_slist *); + +/* + * NAME curl_getdate() + * + * DESCRIPTION + * + * Returns the time, in seconds since 1 Jan 1970 of the time string given in + * the first argument. The time argument in the second parameter is unused + * and should be set to NULL. + */ +CURL_EXTERN time_t curl_getdate(const char *p, const time_t *unused); + +/* info about the certificate chain, only for OpenSSL builds. Asked + for with CURLOPT_CERTINFO / CURLINFO_CERTINFO */ +struct curl_certinfo { + int num_of_certs; /* number of certificates with information */ + struct curl_slist **certinfo; /* for each index in this array, there's a + linked list with textual information in the + format "name: value" */ +}; + +/* enum for the different supported SSL backends */ +typedef enum { + CURLSSLBACKEND_NONE = 0, + CURLSSLBACKEND_OPENSSL = 1, + CURLSSLBACKEND_GNUTLS = 2, + CURLSSLBACKEND_NSS = 3, + CURLSSLBACKEND_OBSOLETE4 = 4, /* Was QSOSSL. */ + CURLSSLBACKEND_GSKIT = 5, + CURLSSLBACKEND_POLARSSL = 6, + CURLSSLBACKEND_CYASSL = 7, + CURLSSLBACKEND_SCHANNEL = 8, + CURLSSLBACKEND_DARWINSSL = 9, + CURLSSLBACKEND_AXTLS = 10, + CURLSSLBACKEND_MBEDTLS = 11 +} curl_sslbackend; + +/* aliases for library clones and renames */ +#define CURLSSLBACKEND_LIBRESSL 1 +#define CURLSSLBACKEND_BORINGSSL 1 +#define CURLSSLBACKEND_WOLFSSL 6 + +/* Information about the SSL library used and the respective internal SSL + handle, which can be used to obtain further information regarding the + connection. Asked for with CURLINFO_TLS_SSL_PTR or CURLINFO_TLS_SESSION. */ +struct curl_tlssessioninfo { + curl_sslbackend backend; + void *internals; +}; + +#define CURLINFO_STRING 0x100000 +#define CURLINFO_LONG 0x200000 +#define CURLINFO_DOUBLE 0x300000 +#define CURLINFO_SLIST 0x400000 +#define CURLINFO_PTR 0x400000 /* same as SLIST */ +#define CURLINFO_SOCKET 0x500000 +#define CURLINFO_MASK 0x0fffff +#define CURLINFO_TYPEMASK 0xf00000 + +typedef enum { + CURLINFO_NONE, /* first, never use this */ + CURLINFO_EFFECTIVE_URL = CURLINFO_STRING + 1, + CURLINFO_RESPONSE_CODE = CURLINFO_LONG + 2, + CURLINFO_TOTAL_TIME = CURLINFO_DOUBLE + 3, + CURLINFO_NAMELOOKUP_TIME = CURLINFO_DOUBLE + 4, + CURLINFO_CONNECT_TIME = CURLINFO_DOUBLE + 5, + CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6, + CURLINFO_SIZE_UPLOAD = CURLINFO_DOUBLE + 7, + CURLINFO_SIZE_DOWNLOAD = CURLINFO_DOUBLE + 8, + CURLINFO_SPEED_DOWNLOAD = CURLINFO_DOUBLE + 9, + CURLINFO_SPEED_UPLOAD = CURLINFO_DOUBLE + 10, + CURLINFO_HEADER_SIZE = CURLINFO_LONG + 11, + CURLINFO_REQUEST_SIZE = CURLINFO_LONG + 12, + CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG + 13, + CURLINFO_FILETIME = CURLINFO_LONG + 14, + CURLINFO_CONTENT_LENGTH_DOWNLOAD = CURLINFO_DOUBLE + 15, + CURLINFO_CONTENT_LENGTH_UPLOAD = CURLINFO_DOUBLE + 16, + CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17, + CURLINFO_CONTENT_TYPE = CURLINFO_STRING + 18, + CURLINFO_REDIRECT_TIME = CURLINFO_DOUBLE + 19, + CURLINFO_REDIRECT_COUNT = CURLINFO_LONG + 20, + CURLINFO_PRIVATE = CURLINFO_STRING + 21, + CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG + 22, + CURLINFO_HTTPAUTH_AVAIL = CURLINFO_LONG + 23, + CURLINFO_PROXYAUTH_AVAIL = CURLINFO_LONG + 24, + CURLINFO_OS_ERRNO = CURLINFO_LONG + 25, + CURLINFO_NUM_CONNECTS = CURLINFO_LONG + 26, + CURLINFO_SSL_ENGINES = CURLINFO_SLIST + 27, + CURLINFO_COOKIELIST = CURLINFO_SLIST + 28, + CURLINFO_LASTSOCKET = CURLINFO_LONG + 29, + CURLINFO_FTP_ENTRY_PATH = CURLINFO_STRING + 30, + CURLINFO_REDIRECT_URL = CURLINFO_STRING + 31, + CURLINFO_PRIMARY_IP = CURLINFO_STRING + 32, + CURLINFO_APPCONNECT_TIME = CURLINFO_DOUBLE + 33, + CURLINFO_CERTINFO = CURLINFO_PTR + 34, + CURLINFO_CONDITION_UNMET = CURLINFO_LONG + 35, + CURLINFO_RTSP_SESSION_ID = CURLINFO_STRING + 36, + CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG + 37, + CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG + 38, + CURLINFO_RTSP_CSEQ_RECV = CURLINFO_LONG + 39, + CURLINFO_PRIMARY_PORT = CURLINFO_LONG + 40, + CURLINFO_LOCAL_IP = CURLINFO_STRING + 41, + CURLINFO_LOCAL_PORT = CURLINFO_LONG + 42, + CURLINFO_TLS_SESSION = CURLINFO_PTR + 43, + CURLINFO_ACTIVESOCKET = CURLINFO_SOCKET + 44, + CURLINFO_TLS_SSL_PTR = CURLINFO_PTR + 45, + CURLINFO_HTTP_VERSION = CURLINFO_LONG + 46, + CURLINFO_PROXY_SSL_VERIFYRESULT = CURLINFO_LONG + 47, + CURLINFO_PROTOCOL = CURLINFO_LONG + 48, + CURLINFO_SCHEME = CURLINFO_STRING + 49, + /* Fill in new entries below here! */ + + CURLINFO_LASTONE = 49 +} CURLINFO; + +/* CURLINFO_RESPONSE_CODE is the new name for the option previously known as + CURLINFO_HTTP_CODE */ +#define CURLINFO_HTTP_CODE CURLINFO_RESPONSE_CODE + +typedef enum { + CURLCLOSEPOLICY_NONE, /* first, never use this */ + + CURLCLOSEPOLICY_OLDEST, + CURLCLOSEPOLICY_LEAST_RECENTLY_USED, + CURLCLOSEPOLICY_LEAST_TRAFFIC, + CURLCLOSEPOLICY_SLOWEST, + CURLCLOSEPOLICY_CALLBACK, + + CURLCLOSEPOLICY_LAST /* last, never use this */ +} curl_closepolicy; + +#define CURL_GLOBAL_SSL (1<<0) +#define CURL_GLOBAL_WIN32 (1<<1) +#define CURL_GLOBAL_ALL (CURL_GLOBAL_SSL|CURL_GLOBAL_WIN32) +#define CURL_GLOBAL_NOTHING 0 +#define CURL_GLOBAL_DEFAULT CURL_GLOBAL_ALL +#define CURL_GLOBAL_ACK_EINTR (1<<2) + + +/***************************************************************************** + * Setup defines, protos etc for the sharing stuff. + */ + +/* Different data locks for a single share */ +typedef enum { + CURL_LOCK_DATA_NONE = 0, + /* CURL_LOCK_DATA_SHARE is used internally to say that + * the locking is just made to change the internal state of the share + * itself. + */ + CURL_LOCK_DATA_SHARE, + CURL_LOCK_DATA_COOKIE, + CURL_LOCK_DATA_DNS, + CURL_LOCK_DATA_SSL_SESSION, + CURL_LOCK_DATA_CONNECT, + CURL_LOCK_DATA_LAST +} curl_lock_data; + +/* Different lock access types */ +typedef enum { + CURL_LOCK_ACCESS_NONE = 0, /* unspecified action */ + CURL_LOCK_ACCESS_SHARED = 1, /* for read perhaps */ + CURL_LOCK_ACCESS_SINGLE = 2, /* for write perhaps */ + CURL_LOCK_ACCESS_LAST /* never use */ +} curl_lock_access; + +typedef void (*curl_lock_function)(CURL *handle, + curl_lock_data data, + curl_lock_access locktype, + void *userptr); +typedef void (*curl_unlock_function)(CURL *handle, + curl_lock_data data, + void *userptr); + + +typedef enum { + CURLSHE_OK, /* all is fine */ + CURLSHE_BAD_OPTION, /* 1 */ + CURLSHE_IN_USE, /* 2 */ + CURLSHE_INVALID, /* 3 */ + CURLSHE_NOMEM, /* 4 out of memory */ + CURLSHE_NOT_BUILT_IN, /* 5 feature not present in lib */ + CURLSHE_LAST /* never use */ +} CURLSHcode; + +typedef enum { + CURLSHOPT_NONE, /* don't use */ + CURLSHOPT_SHARE, /* specify a data type to share */ + CURLSHOPT_UNSHARE, /* specify which data type to stop sharing */ + CURLSHOPT_LOCKFUNC, /* pass in a 'curl_lock_function' pointer */ + CURLSHOPT_UNLOCKFUNC, /* pass in a 'curl_unlock_function' pointer */ + CURLSHOPT_USERDATA, /* pass in a user data pointer used in the lock/unlock + callback functions */ + CURLSHOPT_LAST /* never use */ +} CURLSHoption; + +CURL_EXTERN CURLSH *curl_share_init(void); +CURL_EXTERN CURLSHcode curl_share_setopt(CURLSH *, CURLSHoption option, ...); +CURL_EXTERN CURLSHcode curl_share_cleanup(CURLSH *); + +/**************************************************************************** + * Structures for querying information about the curl library at runtime. + */ + +typedef enum { + CURLVERSION_FIRST, + CURLVERSION_SECOND, + CURLVERSION_THIRD, + CURLVERSION_FOURTH, + CURLVERSION_LAST /* never actually use this */ +} CURLversion; + +/* The 'CURLVERSION_NOW' is the symbolic name meant to be used by + basically all programs ever that want to get version information. It is + meant to be a built-in version number for what kind of struct the caller + expects. If the struct ever changes, we redefine the NOW to another enum + from above. */ +#define CURLVERSION_NOW CURLVERSION_FOURTH + +typedef struct { + CURLversion age; /* age of the returned struct */ + const char *version; /* LIBCURL_VERSION */ + unsigned int version_num; /* LIBCURL_VERSION_NUM */ + const char *host; /* OS/host/cpu/machine when configured */ + int features; /* bitmask, see defines below */ + const char *ssl_version; /* human readable string */ + long ssl_version_num; /* not used anymore, always 0 */ + const char *libz_version; /* human readable string */ + /* protocols is terminated by an entry with a NULL protoname */ + const char * const *protocols; + + /* The fields below this were added in CURLVERSION_SECOND */ + const char *ares; + int ares_num; + + /* This field was added in CURLVERSION_THIRD */ + const char *libidn; + + /* These field were added in CURLVERSION_FOURTH */ + + /* Same as '_libiconv_version' if built with HAVE_ICONV */ + int iconv_ver_num; + + const char *libssh_version; /* human readable string */ + +} curl_version_info_data; + +#define CURL_VERSION_IPV6 (1<<0) /* IPv6-enabled */ +#define CURL_VERSION_KERBEROS4 (1<<1) /* Kerberos V4 auth is supported + (deprecated) */ +#define CURL_VERSION_SSL (1<<2) /* SSL options are present */ +#define CURL_VERSION_LIBZ (1<<3) /* libz features are present */ +#define CURL_VERSION_NTLM (1<<4) /* NTLM auth is supported */ +#define CURL_VERSION_GSSNEGOTIATE (1<<5) /* Negotiate auth is supported + (deprecated) */ +#define CURL_VERSION_DEBUG (1<<6) /* Built with debug capabilities */ +#define CURL_VERSION_ASYNCHDNS (1<<7) /* Asynchronous DNS resolves */ +#define CURL_VERSION_SPNEGO (1<<8) /* SPNEGO auth is supported */ +#define CURL_VERSION_LARGEFILE (1<<9) /* Supports files larger than 2GB */ +#define CURL_VERSION_IDN (1<<10) /* Internationized Domain Names are + supported */ +#define CURL_VERSION_SSPI (1<<11) /* Built against Windows SSPI */ +#define CURL_VERSION_CONV (1<<12) /* Character conversions supported */ +#define CURL_VERSION_CURLDEBUG (1<<13) /* Debug memory tracking supported */ +#define CURL_VERSION_TLSAUTH_SRP (1<<14) /* TLS-SRP auth is supported */ +#define CURL_VERSION_NTLM_WB (1<<15) /* NTLM delegation to winbind helper + is supported */ +#define CURL_VERSION_HTTP2 (1<<16) /* HTTP2 support built-in */ +#define CURL_VERSION_GSSAPI (1<<17) /* Built against a GSS-API library */ +#define CURL_VERSION_KERBEROS5 (1<<18) /* Kerberos V5 auth is supported */ +#define CURL_VERSION_UNIX_SOCKETS (1<<19) /* Unix domain sockets support */ +#define CURL_VERSION_PSL (1<<20) /* Mozilla's Public Suffix List, used + for cookie domain verification */ +#define CURL_VERSION_HTTPS_PROXY (1<<21) /* HTTPS-proxy support built-in */ + + /* + * NAME curl_version_info() + * + * DESCRIPTION + * + * This function returns a pointer to a static copy of the version info + * struct. See above. + */ +CURL_EXTERN curl_version_info_data *curl_version_info(CURLversion); + +/* + * NAME curl_easy_strerror() + * + * DESCRIPTION + * + * The curl_easy_strerror function may be used to turn a CURLcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_easy_strerror(CURLcode); + +/* + * NAME curl_share_strerror() + * + * DESCRIPTION + * + * The curl_share_strerror function may be used to turn a CURLSHcode value + * into the equivalent human readable error string. This is useful + * for printing meaningful error messages. + */ +CURL_EXTERN const char *curl_share_strerror(CURLSHcode); + +/* + * NAME curl_easy_pause() + * + * DESCRIPTION + * + * The curl_easy_pause function pauses or unpauses transfers. Select the new + * state by setting the bitmask, use the convenience defines below. + * + */ +CURL_EXTERN CURLcode curl_easy_pause(CURL *handle, int bitmask); + +#define CURLPAUSE_RECV (1<<0) +#define CURLPAUSE_RECV_CONT (0) + +#define CURLPAUSE_SEND (1<<2) +#define CURLPAUSE_SEND_CONT (0) + +#define CURLPAUSE_ALL (CURLPAUSE_RECV|CURLPAUSE_SEND) +#define CURLPAUSE_CONT (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT) + +#ifdef __cplusplus +} +#endif + +/* unfortunately, the easy.h and multi.h include files need options and info + stuff before they can be included! */ +#include "easy.h" /* nothing in curl is fun without the easy stuff */ +#include "multi.h" + +/* the typechecker doesn't work in C++ (yet) */ +#if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ + ((__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) && \ + !defined(__cplusplus) && !defined(CURL_DISABLE_TYPECHECK) +#include "typecheck-gcc.h" +#else +#if defined(__STDC__) && (__STDC__ >= 1) +/* This preprocessor magic that replaces a call with the exact same call is + only done to make sure application authors pass exactly three arguments + to these functions. */ +#define curl_easy_setopt(handle,opt,param) curl_easy_setopt(handle,opt,param) +#define curl_easy_getinfo(handle,info,arg) curl_easy_getinfo(handle,info,arg) +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) +#endif /* __STDC__ >= 1 */ +#endif /* gcc >= 4.3 && !__cplusplus */ + +#endif /* __CURL_CURL_H */ diff --git a/src/lib/install/arm/include/curl/curlbuild.h b/src/lib/install/arm/include/curl/curlbuild.h new file mode 100644 index 0000000..8228e44 --- /dev/null +++ b/src/lib/install/arm/include/curl/curlbuild.h @@ -0,0 +1,198 @@ +/* include/curl/curlbuild.h. Generated from curlbuild.h.in by configure. */ +#ifndef __CURL_CURLBUILD_H +#define __CURL_CURLBUILD_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2012, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * If you think that something actually needs to be changed, adjusted + * or fixed in this file, then, report it on the libcurl development + * mailing list: https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * This header file shall only export symbols which are 'curl' or 'CURL' + * prefixed, otherwise public name space would be polluted. + * + * NOTE 2: + * ------- + * + * Right now you might be staring at file include/curl/curlbuild.h.in or + * at file include/curl/curlbuild.h, this is due to the following reason: + * + * On systems capable of running the configure script, the configure process + * will overwrite the distributed include/curl/curlbuild.h file with one that + * is suitable and specific to the library being configured and built, which + * is generated from the include/curl/curlbuild.h.in template file. + * + */ + +/* ================================================================ */ +/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */ +/* ================================================================ */ + +#ifdef CURL_SIZEOF_LONG +#error "CURL_SIZEOF_LONG shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_LONG_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_SOCKLEN_T +#error "CURL_TYPEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_SOCKLEN_T +#error "CURL_SIZEOF_CURL_SOCKLEN_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_already_defined +#endif + +#ifdef CURL_TYPEOF_CURL_OFF_T +#error "CURL_TYPEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_T +#error "CURL_FORMAT_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_FORMAT_CURL_OFF_TU +#error "CURL_FORMAT_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_already_defined +#endif + +#ifdef CURL_FORMAT_OFF_T +#error "CURL_FORMAT_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_FORMAT_OFF_T_already_defined +#endif + +#ifdef CURL_SIZEOF_CURL_OFF_T +#error "CURL_SIZEOF_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_T +#error "CURL_SUFFIX_CURL_OFF_T shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_already_defined +#endif + +#ifdef CURL_SUFFIX_CURL_OFF_TU +#error "CURL_SUFFIX_CURL_OFF_TU shall not be defined except in curlbuild.h" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_already_defined +#endif + +/* ================================================================ */ +/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */ +/* ================================================================ */ + +/* Configure process defines this to 1 when it finds out that system */ +/* header file ws2tcpip.h must be included by the external interface. */ +/* #undef CURL_PULL_WS2TCPIP_H */ +#ifdef CURL_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/types.h must be included by the external interface. */ +#define CURL_PULL_SYS_TYPES_H 1 +#ifdef CURL_PULL_SYS_TYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file stdint.h must be included by the external interface. */ +#define CURL_PULL_STDINT_H 1 +#ifdef CURL_PULL_STDINT_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file inttypes.h must be included by the external interface. */ +#define CURL_PULL_INTTYPES_H 1 +#ifdef CURL_PULL_INTTYPES_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/socket.h must be included by the external interface. */ +#define CURL_PULL_SYS_SOCKET_H 1 +#ifdef CURL_PULL_SYS_SOCKET_H +# include +#endif + +/* Configure process defines this to 1 when it finds out that system */ +/* header file sys/poll.h must be included by the external interface. */ +/* #undef CURL_PULL_SYS_POLL_H */ +#ifdef CURL_PULL_SYS_POLL_H +# include +#endif + +/* The size of `long', as computed by sizeof. */ +#define CURL_SIZEOF_LONG 4 + +/* Integral data type used for curl_socklen_t. */ +#define CURL_TYPEOF_CURL_SOCKLEN_T socklen_t + +/* The size of `curl_socklen_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_SOCKLEN_T 4 + +/* Data type definition of curl_socklen_t. */ +typedef CURL_TYPEOF_CURL_SOCKLEN_T curl_socklen_t; + +/* Signed integral data type used for curl_off_t. */ +#define CURL_TYPEOF_CURL_OFF_T int64_t + +/* Data type definition of curl_off_t. */ +typedef CURL_TYPEOF_CURL_OFF_T curl_off_t; + +/* curl_off_t formatting string directive without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_T "lld" + +/* unsigned curl_off_t formatting string without "%" conversion specifier. */ +#define CURL_FORMAT_CURL_OFF_TU "llu" + +/* curl_off_t formatting string directive with "%" conversion specifier. */ +#define CURL_FORMAT_OFF_T "%lld" + +/* The size of `curl_off_t', as computed by sizeof. */ +#define CURL_SIZEOF_CURL_OFF_T 8 + +/* curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_T LL + +/* unsigned curl_off_t constant suffix. */ +#define CURL_SUFFIX_CURL_OFF_TU ULL + +#endif /* __CURL_CURLBUILD_H */ diff --git a/src/lib/install/arm/include/curl/curlrules.h b/src/lib/install/arm/include/curl/curlrules.h new file mode 100644 index 0000000..0abd9f7 --- /dev/null +++ b/src/lib/install/arm/include/curl/curlrules.h @@ -0,0 +1,239 @@ +#ifndef __CURL_CURLRULES_H +#define __CURL_CURLRULES_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* ================================================================ */ +/* COMPILE TIME SANITY CHECKS */ +/* ================================================================ */ + +/* + * NOTE 1: + * ------- + * + * All checks done in this file are intentionally placed in a public + * header file which is pulled by curl/curl.h when an application is + * being built using an already built libcurl library. Additionally + * this file is also included and used when building the library. + * + * If compilation fails on this file it is certainly sure that the + * problem is elsewhere. It could be a problem in the curlbuild.h + * header file, or simply that you are using different compilation + * settings than those used to build the library. + * + * Nothing in this file is intended to be modified or adjusted by the + * curl library user nor by the curl library builder. + * + * Do not deactivate any check, these are done to make sure that the + * library is properly built and used. + * + * You can find further help on the libcurl development mailing list: + * https://cool.haxx.se/mailman/listinfo/curl-library/ + * + * NOTE 2 + * ------ + * + * Some of the following compile time checks are based on the fact + * that the dimension of a constant array can not be a negative one. + * In this way if the compile time verification fails, the compilation + * will fail issuing an error. The error description wording is compiler + * dependent but it will be quite similar to one of the following: + * + * "negative subscript or subscript is too large" + * "array must have at least one element" + * "-1 is an illegal array size" + * "size of array is negative" + * + * If you are building an application which tries to use an already + * built libcurl library and you are getting this kind of errors on + * this file, it is a clear indication that there is a mismatch between + * how the library was built and how you are trying to use it for your + * application. Your already compiled or binary library provider is the + * only one who can give you the details you need to properly use it. + */ + +/* + * Verify that some macros are actually defined. + */ + +#ifndef CURL_SIZEOF_LONG +# error "CURL_SIZEOF_LONG definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_LONG_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_SOCKLEN_T +# error "CURL_TYPEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_SOCKLEN_T +# error "CURL_SIZEOF_CURL_SOCKLEN_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_SOCKLEN_T_is_missing +#endif + +#ifndef CURL_TYPEOF_CURL_OFF_T +# error "CURL_TYPEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_TYPEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_T +# error "CURL_FORMAT_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_FORMAT_CURL_OFF_TU +# error "CURL_FORMAT_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_FORMAT_CURL_OFF_TU_is_missing +#endif + +#ifndef CURL_SIZEOF_CURL_OFF_T +# error "CURL_SIZEOF_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SIZEOF_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_T +# error "CURL_SUFFIX_CURL_OFF_T definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_T_is_missing +#endif + +#ifndef CURL_SUFFIX_CURL_OFF_TU +# error "CURL_SUFFIX_CURL_OFF_TU definition is missing!" + Error Compilation_aborted_CURL_SUFFIX_CURL_OFF_TU_is_missing +#endif + +/* + * Macros private to this header file. + */ + +#define CurlchkszEQ(t, s) sizeof(t) == s ? 1 : -1 + +#define CurlchkszGE(t1, t2) sizeof(t1) >= sizeof(t2) ? 1 : -1 + +/* + * Verify that the size previously defined and expected for long + * is the same as the one reported by sizeof() at compile time. + */ + +typedef char + __curl_rule_01__ + [CurlchkszEQ(long, CURL_SIZEOF_LONG)]; + +/* + * Verify that the size previously defined and expected for + * curl_off_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_02__ + [CurlchkszEQ(curl_off_t, CURL_SIZEOF_CURL_OFF_T)]; + +/* + * Verify at compile time that the size of curl_off_t as reported + * by sizeof() is greater or equal than the one reported for long + * for the current compilation. + */ + +typedef char + __curl_rule_03__ + [CurlchkszGE(curl_off_t, long)]; + +/* + * Verify that the size previously defined and expected for + * curl_socklen_t is actually the the same as the one reported + * by sizeof() at compile time. + */ + +typedef char + __curl_rule_04__ + [CurlchkszEQ(curl_socklen_t, CURL_SIZEOF_CURL_SOCKLEN_T)]; + +/* + * Verify at compile time that the size of curl_socklen_t as reported + * by sizeof() is greater or equal than the one reported for int for + * the current compilation. + */ + +typedef char + __curl_rule_05__ + [CurlchkszGE(curl_socklen_t, int)]; + +/* ================================================================ */ +/* EXTERNALLY AND INTERNALLY VISIBLE DEFINITIONS */ +/* ================================================================ */ + +/* + * CURL_ISOCPP and CURL_OFF_T_C definitions are done here in order to allow + * these to be visible and exported by the external libcurl interface API, + * while also making them visible to the library internals, simply including + * curl_setup.h, without actually needing to include curl.h internally. + * If some day this section would grow big enough, all this should be moved + * to its own header file. + */ + +/* + * Figure out if we can use the ## preprocessor operator, which is supported + * by ISO/ANSI C and C++. Some compilers support it without setting __STDC__ + * or __cplusplus so we need to carefully check for them too. + */ + +#if defined(__STDC__) || defined(_MSC_VER) || defined(__cplusplus) || \ + defined(__HP_aCC) || defined(__BORLANDC__) || defined(__LCC__) || \ + defined(__POCC__) || defined(__SALFORDC__) || defined(__HIGHC__) || \ + defined(__ILEC400__) + /* This compiler is believed to have an ISO compatible preprocessor */ +#define CURL_ISOCPP +#else + /* This compiler is believed NOT to have an ISO compatible preprocessor */ +#undef CURL_ISOCPP +#endif + +/* + * Macros for minimum-width signed and unsigned curl_off_t integer constants. + */ + +#if defined(__BORLANDC__) && (__BORLANDC__ == 0x0551) +# define __CURL_OFF_T_C_HLPR2(x) x +# define __CURL_OFF_T_C_HLPR1(x) __CURL_OFF_T_C_HLPR2(x) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val) ## \ + __CURL_OFF_T_C_HLPR1(CURL_SUFFIX_CURL_OFF_TU) +#else +# ifdef CURL_ISOCPP +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val ## Suffix +# else +# define __CURL_OFF_T_C_HLPR2(Val,Suffix) Val/**/Suffix +# endif +# define __CURL_OFF_T_C_HLPR1(Val,Suffix) __CURL_OFF_T_C_HLPR2(Val,Suffix) +# define CURL_OFF_T_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_T) +# define CURL_OFF_TU_C(Val) __CURL_OFF_T_C_HLPR1(Val,CURL_SUFFIX_CURL_OFF_TU) +#endif + +/* + * Get rid of macros private to this header file. + */ + +#undef CurlchkszEQ +#undef CurlchkszGE + +#endif /* __CURL_CURLRULES_H */ diff --git a/src/lib/install/arm/include/curl/curlver.h b/src/lib/install/arm/include/curl/curlver.h new file mode 100644 index 0000000..227571c --- /dev/null +++ b/src/lib/install/arm/include/curl/curlver.h @@ -0,0 +1,77 @@ +#ifndef __CURL_CURLVER_H +#define __CURL_CURLVER_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* This header file contains nothing but libcurl version info, generated by + a script at release-time. This was made its own header file in 7.11.2 */ + +/* This is the global package copyright */ +#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, ." + +/* This is the version number of the libcurl package from which this header + file origins: */ +#define LIBCURL_VERSION "7.54.1-DEV" + +/* The numeric version number is also available "in parts" by using these + defines: */ +#define LIBCURL_VERSION_MAJOR 7 +#define LIBCURL_VERSION_MINOR 54 +#define LIBCURL_VERSION_PATCH 1 + +/* This is the numeric version of the libcurl version number, meant for easier + parsing and comparions by programs. The LIBCURL_VERSION_NUM define will + always follow this syntax: + + 0xXXYYZZ + + Where XX, YY and ZZ are the main version, release and patch numbers in + hexadecimal (using 8 bits each). All three numbers are always represented + using two digits. 1.2 would appear as "0x010200" while version 9.11.7 + appears as "0x090b07". + + This 6-digit (24 bits) hexadecimal number does not show pre-release number, + and it is always a greater number in a more recent release. It makes + comparisons with greater than and less than work. + + Note: This define is the full hex number and _does not_ use the + CURL_VERSION_BITS() macro since curl's own configure script greps for it + and needs it to contain the full number. +*/ +#define LIBCURL_VERSION_NUM 0x073601 + +/* + * This is the date and time when the full source package was created. The + * timestamp is not stored in git, as the timestamp is properly set in the + * tarballs by the maketgz script. + * + * The format of the date follows this template: + * + * "2007-11-23" + */ +#define LIBCURL_TIMESTAMP "[unreleased]" + +#define CURL_VERSION_BITS(x,y,z) ((x)<<16|(y)<<8|z) +#define CURL_AT_LEAST_VERSION(x,y,z) \ + (LIBCURL_VERSION_NUM >= CURL_VERSION_BITS(x, y, z)) + +#endif /* __CURL_CURLVER_H */ diff --git a/src/lib/install/arm/include/curl/easy.h b/src/lib/install/arm/include/curl/easy.h new file mode 100644 index 0000000..752c504 --- /dev/null +++ b/src/lib/install/arm/include/curl/easy.h @@ -0,0 +1,102 @@ +#ifndef __CURL_EASY_H +#define __CURL_EASY_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN CURL *curl_easy_init(void); +CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); +CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); +CURL_EXTERN void curl_easy_cleanup(CURL *curl); + +/* + * NAME curl_easy_getinfo() + * + * DESCRIPTION + * + * Request internal information from the curl session with this function. The + * third argument MUST be a pointer to a long, a pointer to a char * or a + * pointer to a double (as the documentation describes elsewhere). The data + * pointed to will be filled in accordingly and can be relied upon only if the + * function returns CURLE_OK. This function is intended to get used *AFTER* a + * performed transfer, all results from this function are undefined until the + * transfer is completed. + */ +CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...); + + +/* + * NAME curl_easy_duphandle() + * + * DESCRIPTION + * + * Creates a new curl session handle with the same options set for the handle + * passed in. Duplicating a handle could only be a matter of cloning data and + * options, internal state info and things like persistent connections cannot + * be transferred. It is useful in multithreaded applications when you can run + * curl_easy_duphandle() for each new thread to avoid a series of identical + * curl_easy_setopt() invokes in every thread. + */ +CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl); + +/* + * NAME curl_easy_reset() + * + * DESCRIPTION + * + * Re-initializes a CURL handle to the default values. This puts back the + * handle to the same state as it was in when it was just created. + * + * It does keep: live connections, the Session ID cache, the DNS cache and the + * cookies. + */ +CURL_EXTERN void curl_easy_reset(CURL *curl); + +/* + * NAME curl_easy_recv() + * + * DESCRIPTION + * + * Receives data from the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, + size_t *n); + +/* + * NAME curl_easy_send() + * + * DESCRIPTION + * + * Sends data over the connected socket. Use after successful + * curl_easy_perform() with CURLOPT_CONNECT_ONLY option. + */ +CURL_EXTERN CURLcode curl_easy_send(CURL *curl, const void *buffer, + size_t buflen, size_t *n); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/lib/install/arm/include/curl/mprintf.h b/src/lib/install/arm/include/curl/mprintf.h new file mode 100644 index 0000000..e20f546 --- /dev/null +++ b/src/lib/install/arm/include/curl/mprintf.h @@ -0,0 +1,50 @@ +#ifndef __CURL_MPRINTF_H +#define __CURL_MPRINTF_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include +#include /* needed for FILE */ +#include "curl.h" /* for CURL_EXTERN */ + +#ifdef __cplusplus +extern "C" { +#endif + +CURL_EXTERN int curl_mprintf(const char *format, ...); +CURL_EXTERN int curl_mfprintf(FILE *fd, const char *format, ...); +CURL_EXTERN int curl_msprintf(char *buffer, const char *format, ...); +CURL_EXTERN int curl_msnprintf(char *buffer, size_t maxlength, + const char *format, ...); +CURL_EXTERN int curl_mvprintf(const char *format, va_list args); +CURL_EXTERN int curl_mvfprintf(FILE *fd, const char *format, va_list args); +CURL_EXTERN int curl_mvsprintf(char *buffer, const char *format, va_list args); +CURL_EXTERN int curl_mvsnprintf(char *buffer, size_t maxlength, + const char *format, va_list args); +CURL_EXTERN char *curl_maprintf(const char *format, ...); +CURL_EXTERN char *curl_mvaprintf(const char *format, va_list args); + +#ifdef __cplusplus +} +#endif + +#endif /* __CURL_MPRINTF_H */ diff --git a/src/lib/install/arm/include/curl/multi.h b/src/lib/install/arm/include/curl/multi.h new file mode 100644 index 0000000..f93e511 --- /dev/null +++ b/src/lib/install/arm/include/curl/multi.h @@ -0,0 +1,439 @@ +#ifndef __CURL_MULTI_H +#define __CURL_MULTI_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ +/* + This is an "external" header file. Don't give away any internals here! + + GOALS + + o Enable a "pull" interface. The application that uses libcurl decides where + and when to ask libcurl to get/send data. + + o Enable multiple simultaneous transfers in the same thread without making it + complicated for the application. + + o Enable the application to select() on its own file descriptors and curl's + file descriptors simultaneous easily. + +*/ + +/* + * This header file should not really need to include "curl.h" since curl.h + * itself includes this file and we expect user applications to do #include + * without the need for especially including multi.h. + * + * For some reason we added this include here at one point, and rather than to + * break existing (wrongly written) libcurl applications, we leave it as-is + * but with this warning attached. + */ +#include "curl.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER) +typedef struct Curl_multi CURLM; +#else +typedef void CURLM; +#endif + +typedef enum { + CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or + curl_multi_socket*() soon */ + CURLM_OK, + CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */ + CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */ + CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */ + CURLM_INTERNAL_ERROR, /* this is a libcurl bug */ + CURLM_BAD_SOCKET, /* the passed in socket argument did not match */ + CURLM_UNKNOWN_OPTION, /* curl_multi_setopt() with unsupported option */ + CURLM_ADDED_ALREADY, /* an easy handle already added to a multi handle was + attempted to get added - again */ + CURLM_LAST +} CURLMcode; + +/* just to make code nicer when using curl_multi_socket() you can now check + for CURLM_CALL_MULTI_SOCKET too in the same style it works for + curl_multi_perform() and CURLM_CALL_MULTI_PERFORM */ +#define CURLM_CALL_MULTI_SOCKET CURLM_CALL_MULTI_PERFORM + +/* bitmask bits for CURLMOPT_PIPELINING */ +#define CURLPIPE_NOTHING 0L +#define CURLPIPE_HTTP1 1L +#define CURLPIPE_MULTIPLEX 2L + +typedef enum { + CURLMSG_NONE, /* first, not used */ + CURLMSG_DONE, /* This easy handle has completed. 'result' contains + the CURLcode of the transfer */ + CURLMSG_LAST /* last, not used */ +} CURLMSG; + +struct CURLMsg { + CURLMSG msg; /* what this message means */ + CURL *easy_handle; /* the handle it concerns */ + union { + void *whatever; /* message-specific data */ + CURLcode result; /* return code for transfer */ + } data; +}; +typedef struct CURLMsg CURLMsg; + +/* Based on poll(2) structure and values. + * We don't use pollfd and POLL* constants explicitly + * to cover platforms without poll(). */ +#define CURL_WAIT_POLLIN 0x0001 +#define CURL_WAIT_POLLPRI 0x0002 +#define CURL_WAIT_POLLOUT 0x0004 + +struct curl_waitfd { + curl_socket_t fd; + short events; + short revents; /* not supported yet */ +}; + +/* + * Name: curl_multi_init() + * + * Desc: inititalize multi-style curl usage + * + * Returns: a new CURLM handle to use in all 'curl_multi' functions. + */ +CURL_EXTERN CURLM *curl_multi_init(void); + +/* + * Name: curl_multi_add_handle() + * + * Desc: add a standard curl handle to the multi stack + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_add_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_remove_handle() + * + * Desc: removes a curl handle from the multi stack again + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_remove_handle(CURLM *multi_handle, + CURL *curl_handle); + + /* + * Name: curl_multi_fdset() + * + * Desc: Ask curl for its fd_set sets. The app can use these to select() or + * poll() on. We want curl_multi_perform() called as soon as one of + * them are ready. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_fdset(CURLM *multi_handle, + fd_set *read_fd_set, + fd_set *write_fd_set, + fd_set *exc_fd_set, + int *max_fd); + +/* + * Name: curl_multi_wait() + * + * Desc: Poll on all fds within a CURLM set as well as any + * additional fds passed to the function. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_wait(CURLM *multi_handle, + struct curl_waitfd extra_fds[], + unsigned int extra_nfds, + int timeout_ms, + int *ret); + + /* + * Name: curl_multi_perform() + * + * Desc: When the app thinks there's data available for curl it calls this + * function to read/write whatever there is right now. This returns + * as soon as the reads and writes are done. This function does not + * require that there actually is data available for reading or that + * data can be written, it can be called just in case. It returns + * the number of handles that still transfer data in the second + * argument's integer-pointer. + * + * Returns: CURLMcode type, general multi error code. *NOTE* that this only + * returns errors etc regarding the whole multi stack. There might + * still have occurred problems on invidual transfers even when this + * returns OK. + */ +CURL_EXTERN CURLMcode curl_multi_perform(CURLM *multi_handle, + int *running_handles); + + /* + * Name: curl_multi_cleanup() + * + * Desc: Cleans up and removes a whole multi stack. It does not free or + * touch any individual easy handles in any way. We need to define + * in what state those handles will be if this function is called + * in the middle of a transfer. + * + * Returns: CURLMcode type, general multi error code. + */ +CURL_EXTERN CURLMcode curl_multi_cleanup(CURLM *multi_handle); + +/* + * Name: curl_multi_info_read() + * + * Desc: Ask the multi handle if there's any messages/informationals from + * the individual transfers. Messages include informationals such as + * error code from the transfer or just the fact that a transfer is + * completed. More details on these should be written down as well. + * + * Repeated calls to this function will return a new struct each + * time, until a special "end of msgs" struct is returned as a signal + * that there is no more to get at this point. + * + * The data the returned pointer points to will not survive calling + * curl_multi_cleanup(). + * + * The 'CURLMsg' struct is meant to be very simple and only contain + * very basic information. If more involved information is wanted, + * we will provide the particular "transfer handle" in that struct + * and that should/could/would be used in subsequent + * curl_easy_getinfo() calls (or similar). The point being that we + * must never expose complex structs to applications, as then we'll + * undoubtably get backwards compatibility problems in the future. + * + * Returns: A pointer to a filled-in struct, or NULL if it failed or ran out + * of structs. It also writes the number of messages left in the + * queue (after this read) in the integer the second argument points + * to. + */ +CURL_EXTERN CURLMsg *curl_multi_info_read(CURLM *multi_handle, + int *msgs_in_queue); + +/* + * Name: curl_multi_strerror() + * + * Desc: The curl_multi_strerror function may be used to turn a CURLMcode + * value into the equivalent human readable error string. This is + * useful for printing meaningful error messages. + * + * Returns: A pointer to a zero-terminated error message. + */ +CURL_EXTERN const char *curl_multi_strerror(CURLMcode); + +/* + * Name: curl_multi_socket() and + * curl_multi_socket_all() + * + * Desc: An alternative version of curl_multi_perform() that allows the + * application to pass in one of the file descriptors that have been + * detected to have "action" on them and let libcurl perform. + * See man page for details. + */ +#define CURL_POLL_NONE 0 +#define CURL_POLL_IN 1 +#define CURL_POLL_OUT 2 +#define CURL_POLL_INOUT 3 +#define CURL_POLL_REMOVE 4 + +#define CURL_SOCKET_TIMEOUT CURL_SOCKET_BAD + +#define CURL_CSELECT_IN 0x01 +#define CURL_CSELECT_OUT 0x02 +#define CURL_CSELECT_ERR 0x04 + +typedef int (*curl_socket_callback)(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* see above */ + void *userp, /* private callback + pointer */ + void *socketp); /* private socket + pointer */ +/* + * Name: curl_multi_timer_callback + * + * Desc: Called by libcurl whenever the library detects a change in the + * maximum number of milliseconds the app is allowed to wait before + * curl_multi_socket() or curl_multi_perform() must be called + * (to allow libcurl's timed events to take place). + * + * Returns: The callback should return zero. + */ +typedef int (*curl_multi_timer_callback)(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp); /* private callback + pointer */ + +CURL_EXTERN CURLMcode curl_multi_socket(CURLM *multi_handle, curl_socket_t s, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_action(CURLM *multi_handle, + curl_socket_t s, + int ev_bitmask, + int *running_handles); + +CURL_EXTERN CURLMcode curl_multi_socket_all(CURLM *multi_handle, + int *running_handles); + +#ifndef CURL_ALLOW_OLD_MULTI_SOCKET +/* This macro below was added in 7.16.3 to push users who recompile to use + the new curl_multi_socket_action() instead of the old curl_multi_socket() +*/ +#define curl_multi_socket(x,y,z) curl_multi_socket_action(x,y,0,z) +#endif + +/* + * Name: curl_multi_timeout() + * + * Desc: Returns the maximum number of milliseconds the app is allowed to + * wait before curl_multi_socket() or curl_multi_perform() must be + * called (to allow libcurl's timed events to take place). + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_timeout(CURLM *multi_handle, + long *milliseconds); + +#undef CINIT /* re-using the same name as in curl.h */ + +#ifdef CURL_ISOCPP +#define CINIT(name,type,num) CURLMOPT_ ## name = CURLOPTTYPE_ ## type + num +#else +/* The macro "##" is ISO C, we assume pre-ISO C doesn't support it. */ +#define LONG CURLOPTTYPE_LONG +#define OBJECTPOINT CURLOPTTYPE_OBJECTPOINT +#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT +#define OFF_T CURLOPTTYPE_OFF_T +#define CINIT(name,type,number) CURLMOPT_/**/name = type + number +#endif + +typedef enum { + /* This is the socket callback function pointer */ + CINIT(SOCKETFUNCTION, FUNCTIONPOINT, 1), + + /* This is the argument passed to the socket callback */ + CINIT(SOCKETDATA, OBJECTPOINT, 2), + + /* set to 1 to enable pipelining for this multi handle */ + CINIT(PIPELINING, LONG, 3), + + /* This is the timer callback function pointer */ + CINIT(TIMERFUNCTION, FUNCTIONPOINT, 4), + + /* This is the argument passed to the timer callback */ + CINIT(TIMERDATA, OBJECTPOINT, 5), + + /* maximum number of entries in the connection cache */ + CINIT(MAXCONNECTS, LONG, 6), + + /* maximum number of (pipelining) connections to one host */ + CINIT(MAX_HOST_CONNECTIONS, LONG, 7), + + /* maximum number of requests in a pipeline */ + CINIT(MAX_PIPELINE_LENGTH, LONG, 8), + + /* a connection with a content-length longer than this + will not be considered for pipelining */ + CINIT(CONTENT_LENGTH_PENALTY_SIZE, OFF_T, 9), + + /* a connection with a chunk length longer than this + will not be considered for pipelining */ + CINIT(CHUNK_LENGTH_PENALTY_SIZE, OFF_T, 10), + + /* a list of site names(+port) that are blacklisted from + pipelining */ + CINIT(PIPELINING_SITE_BL, OBJECTPOINT, 11), + + /* a list of server types that are blacklisted from + pipelining */ + CINIT(PIPELINING_SERVER_BL, OBJECTPOINT, 12), + + /* maximum number of open connections in total */ + CINIT(MAX_TOTAL_CONNECTIONS, LONG, 13), + + /* This is the server push callback function pointer */ + CINIT(PUSHFUNCTION, FUNCTIONPOINT, 14), + + /* This is the argument passed to the server push callback */ + CINIT(PUSHDATA, OBJECTPOINT, 15), + + CURLMOPT_LASTENTRY /* the last unused */ +} CURLMoption; + + +/* + * Name: curl_multi_setopt() + * + * Desc: Sets options for the multi handle. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_setopt(CURLM *multi_handle, + CURLMoption option, ...); + + +/* + * Name: curl_multi_assign() + * + * Desc: This function sets an association in the multi handle between the + * given socket and a private pointer of the application. This is + * (only) useful for curl_multi_socket uses. + * + * Returns: CURLM error code. + */ +CURL_EXTERN CURLMcode curl_multi_assign(CURLM *multi_handle, + curl_socket_t sockfd, void *sockp); + + +/* + * Name: curl_push_callback + * + * Desc: This callback gets called when a new stream is being pushed by the + * server. It approves or denies the new stream. + * + * Returns: CURL_PUSH_OK or CURL_PUSH_DENY. + */ +#define CURL_PUSH_OK 0 +#define CURL_PUSH_DENY 1 + +struct curl_pushheaders; /* forward declaration only */ + +CURL_EXTERN char *curl_pushheader_bynum(struct curl_pushheaders *h, + size_t num); +CURL_EXTERN char *curl_pushheader_byname(struct curl_pushheaders *h, + const char *name); + +typedef int (*curl_push_callback)(CURL *parent, + CURL *easy, + size_t num_headers, + struct curl_pushheaders *headers, + void *userp); + +#ifdef __cplusplus +} /* end of extern "C" */ +#endif + +#endif diff --git a/src/lib/install/arm/include/curl/stdcheaders.h b/src/lib/install/arm/include/curl/stdcheaders.h new file mode 100644 index 0000000..027b6f4 --- /dev/null +++ b/src/lib/install/arm/include/curl/stdcheaders.h @@ -0,0 +1,33 @@ +#ifndef __STDC_HEADERS_H +#define __STDC_HEADERS_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2016, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +#include + +size_t fread(void *, size_t, size_t, FILE *); +size_t fwrite(const void *, size_t, size_t, FILE *); + +int strcasecmp(const char *, const char *); +int strncasecmp(const char *, const char *, size_t); + +#endif /* __STDC_HEADERS_H */ diff --git a/src/lib/install/arm/include/curl/system.h b/src/lib/install/arm/include/curl/system.h new file mode 100644 index 0000000..ed3a55c --- /dev/null +++ b/src/lib/install/arm/include/curl/system.h @@ -0,0 +1,484 @@ +#ifndef __CURL_SYSTEM_H +#define __CURL_SYSTEM_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* + * This header is supposed to eventually replace curlbuild.h. This little one + * is still learning. During the experimental phase, this header files + * defines symbols using the prefixes CURLSYS_ or curlsys_. When we feel + * confident enough, we replace curlbuild.h with this file and rename all + * prefixes to CURL_ and curl_. + */ + +/* + * Try to keep one section per platform, compiler and architecture, otherwise, + * if an existing section is reused for a different one and later on the + * original is adjusted, probably the piggybacking one can be adversely + * changed. + * + * In order to differentiate between platforms/compilers/architectures use + * only compiler built in predefined preprocessor symbols. + * + * curl_off_t + * ---------- + * + * For any given platform/compiler curl_off_t must be typedef'ed to a 64-bit + * wide signed integral data type. The width of this data type must remain + * constant and independent of any possible large file support settings. + * + * As an exception to the above, curl_off_t shall be typedef'ed to a 32-bit + * wide signed integral data type if there is no 64-bit type. + * + * As a general rule, curl_off_t shall not be mapped to off_t. This rule shall + * only be violated if off_t is the only 64-bit data type available and the + * size of off_t is independent of large file support settings. Keep your + * build on the safe side avoiding an off_t gating. If you have a 64-bit + * off_t then take for sure that another 64-bit data type exists, dig deeper + * and you will find it. + * + */ + +#if defined(__DJGPP__) || defined(__GO32__) +# if defined(__DJGPP__) && (__DJGPP__ > 1) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SALFORDC__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__BORLANDC__) +# if (__BORLANDC__ < 0x520) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T i64 +# define CURLSYS_SUFFIX_CURL_OFF_TU ui64 +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TURBOC__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__WATCOMC__) +# if defined(__386__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T i64 +# define CURLSYS_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__POCC__) +# if (__POCC__ < 280) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# elif defined(_MSC_VER) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T i64 +# define CURLSYS_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__LCC__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__SYMBIAN32__) +# if defined(__EABI__) /* Treat all ARM compilers equally */ +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# elif defined(__CW32__) +# pragma longlong on +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# elif defined(__VC32__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MWERKS__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(_WIN32_WCE) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T i64 +# define CURLSYS_SUFFIX_CURL_OFF_TU ui64 +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__MINGW32__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_WS2TCPIP_H 1 + +#elif defined(__VMS) +# if defined(__VAX) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T unsigned int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__OS400__) +# if defined(__ILEC400__) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__MVS__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURLSYS_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURLSYS_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# else +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(__370__) +# if defined(__IBMC__) || defined(__IBMCPP__) +# if defined(_ILP32) +# define CURLSYS_SIZEOF_LONG 4 +# elif defined(_LP64) +# define CURLSYS_SIZEOF_LONG 8 +# endif +# if defined(_LONG_LONG) +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# elif defined(_LP64) +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# else +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_SYS_SOCKET_H 1 +# endif + +#elif defined(TPF) +# define CURLSYS_SIZEOF_LONG 8 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +#elif defined(__TINYC__) /* also known as tcc */ + +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_SYS_SOCKET_H 1 + +/* ===================================== */ +/* KEEP MSVC THE PENULTIMATE ENTRY */ +/* ===================================== */ + +#elif defined(_MSC_VER) +# if (_MSC_VER >= 900) && (_INTEGRAL_MAX_BITS >= 64) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T __int64 +# define CURLSYS_FORMAT_CURL_OFF_T "I64d" +# define CURLSYS_FORMAT_CURL_OFF_TU "I64u" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T i64 +# define CURLSYS_SUFFIX_CURL_OFF_TU ui64 +# else +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 + +/* ===================================== */ +/* KEEP GENERIC GCC THE LAST ENTRY */ +/* ===================================== */ + +#elif defined(__GNUC__) +# if !defined(__LP64__) && (defined(__ILP32__) || \ + defined(__i386__) || defined(__ppc__) || defined(__arm__) || \ + defined(__sparc__) || defined(__mips__) || defined(__sh__)) +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long long +# define CURLSYS_FORMAT_CURL_OFF_T "lld" +# define CURLSYS_FORMAT_CURL_OFF_TU "llu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T LL +# define CURLSYS_SUFFIX_CURL_OFF_TU ULL +# elif defined(__LP64__) || \ + defined(__x86_64__) || defined(__ppc64__) || defined(__sparc64__) +# define CURLSYS_SIZEOF_LONG 8 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SIZEOF_CURL_OFF_T 8 +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# endif +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T socklen_t +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_PULL_SYS_TYPES_H 1 +# define CURLSYS_PULL_SYS_SOCKET_H 1 + +#else +/* generic "safe guess" on old 32 bit style */ +# define CURLSYS_SIZEOF_LONG 4 +# define CURLSYS_SIZEOF_CURL_SOCKLEN_T 4 +# define CURLSYS_SIZEOF_CURL_OFF_T 4 +# define CURLSYS_TYPEOF_CURL_OFF_T long +# define CURLSYS_FORMAT_CURL_OFF_T "ld" +# define CURLSYS_FORMAT_CURL_OFF_TU "lu" +# define CURLSYS_SUFFIX_CURL_OFF_T L +# define CURLSYS_SUFFIX_CURL_OFF_TU UL +# define CURLSYS_TYPEOF_CURL_SOCKLEN_T int +#endif + +/* CURLSYS_PULL_WS2TCPIP_H is defined above when inclusion of header file */ +/* ws2tcpip.h is required here to properly make type definitions below. */ +#ifdef CURLSYS_PULL_WS2TCPIP_H +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +# endif +# include +# include +# include +#endif + +/* CURLSYS_PULL_SYS_TYPES_H is defined above when inclusion of header file */ +/* sys/types.h is required here to properly make type definitions below. */ +#ifdef CURLSYS_PULL_SYS_TYPES_H +# include +#endif + +/* CURLSYS_PULL_SYS_SOCKET_H is defined above when inclusion of header file */ +/* sys/socket.h is required here to properly make type definitions below. */ +#ifdef CURLSYS_PULL_SYS_SOCKET_H +# include +#endif + +/* Data type definition of curl_socklen_t. */ +#ifdef CURLSYS_TYPEOF_CURL_SOCKLEN_T + typedef CURLSYS_TYPEOF_CURL_SOCKLEN_T curlsys_socklen_t; +#endif + +/* Data type definition of curl_off_t. */ + +#ifdef CURLSYS_TYPEOF_CURL_OFF_T + typedef CURLSYS_TYPEOF_CURL_OFF_T curlsys_off_t; +#endif + +#endif /* __CURL_SYSTEM_H */ + diff --git a/src/lib/install/arm/include/curl/typecheck-gcc.h b/src/lib/install/arm/include/curl/typecheck-gcc.h new file mode 100644 index 0000000..10b5de2 --- /dev/null +++ b/src/lib/install/arm/include/curl/typecheck-gcc.h @@ -0,0 +1,668 @@ +#ifndef __CURL_TYPECHECK_GCC_H +#define __CURL_TYPECHECK_GCC_H +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2017, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* wraps curl_easy_setopt() with typechecking */ + +/* To add a new kind of warning, add an + * if(_curl_is_sometype_option(_curl_opt)) + * if(!_curl_is_sometype(value)) + * _curl_easy_setopt_err_sometype(); + * block and define _curl_is_sometype_option, _curl_is_sometype and + * _curl_easy_setopt_err_sometype below + * + * NOTE: We use two nested 'if' statements here instead of the && operator, in + * order to work around gcc bug #32061. It affects only gcc 4.3.x/4.4.x + * when compiling with -Wlogical-op. + * + * To add an option that uses the same type as an existing option, you'll just + * need to extend the appropriate _curl_*_option macro + */ +#define curl_easy_setopt(handle, option, value) \ +__extension__ ({ \ + __typeof__(option) _curl_opt = option; \ + if(__builtin_constant_p(_curl_opt)) { \ + if(_curl_is_long_option(_curl_opt)) \ + if(!_curl_is_long(value)) \ + _curl_easy_setopt_err_long(); \ + if(_curl_is_off_t_option(_curl_opt)) \ + if(!_curl_is_off_t(value)) \ + _curl_easy_setopt_err_curl_off_t(); \ + if(_curl_is_string_option(_curl_opt)) \ + if(!_curl_is_string(value)) \ + _curl_easy_setopt_err_string(); \ + if(_curl_is_write_cb_option(_curl_opt)) \ + if(!_curl_is_write_cb(value)) \ + _curl_easy_setopt_err_write_callback(); \ + if((_curl_opt) == CURLOPT_READFUNCTION) \ + if(!_curl_is_read_cb(value)) \ + _curl_easy_setopt_err_read_cb(); \ + if((_curl_opt) == CURLOPT_IOCTLFUNCTION) \ + if(!_curl_is_ioctl_cb(value)) \ + _curl_easy_setopt_err_ioctl_cb(); \ + if((_curl_opt) == CURLOPT_SOCKOPTFUNCTION) \ + if(!_curl_is_sockopt_cb(value)) \ + _curl_easy_setopt_err_sockopt_cb(); \ + if((_curl_opt) == CURLOPT_OPENSOCKETFUNCTION) \ + if(!_curl_is_opensocket_cb(value)) \ + _curl_easy_setopt_err_opensocket_cb(); \ + if((_curl_opt) == CURLOPT_PROGRESSFUNCTION) \ + if(!_curl_is_progress_cb(value)) \ + _curl_easy_setopt_err_progress_cb(); \ + if((_curl_opt) == CURLOPT_DEBUGFUNCTION) \ + if(!_curl_is_debug_cb(value)) \ + _curl_easy_setopt_err_debug_cb(); \ + if((_curl_opt) == CURLOPT_SSL_CTX_FUNCTION) \ + if(!_curl_is_ssl_ctx_cb(value)) \ + _curl_easy_setopt_err_ssl_ctx_cb(); \ + if(_curl_is_conv_cb_option(_curl_opt)) \ + if(!_curl_is_conv_cb(value)) \ + _curl_easy_setopt_err_conv_cb(); \ + if((_curl_opt) == CURLOPT_SEEKFUNCTION) \ + if(!_curl_is_seek_cb(value)) \ + _curl_easy_setopt_err_seek_cb(); \ + if(_curl_is_cb_data_option(_curl_opt)) \ + if(!_curl_is_cb_data(value)) \ + _curl_easy_setopt_err_cb_data(); \ + if((_curl_opt) == CURLOPT_ERRORBUFFER) \ + if(!_curl_is_error_buffer(value)) \ + _curl_easy_setopt_err_error_buffer(); \ + if((_curl_opt) == CURLOPT_STDERR) \ + if(!_curl_is_FILE(value)) \ + _curl_easy_setopt_err_FILE(); \ + if(_curl_is_postfields_option(_curl_opt)) \ + if(!_curl_is_postfields(value)) \ + _curl_easy_setopt_err_postfields(); \ + if((_curl_opt) == CURLOPT_HTTPPOST) \ + if(!_curl_is_arr((value), struct curl_httppost)) \ + _curl_easy_setopt_err_curl_httpost(); \ + if(_curl_is_slist_option(_curl_opt)) \ + if(!_curl_is_arr((value), struct curl_slist)) \ + _curl_easy_setopt_err_curl_slist(); \ + if((_curl_opt) == CURLOPT_SHARE) \ + if(!_curl_is_ptr((value), CURLSH)) \ + _curl_easy_setopt_err_CURLSH(); \ + } \ + curl_easy_setopt(handle, _curl_opt, value); \ +}) + +/* wraps curl_easy_getinfo() with typechecking */ +/* FIXME: don't allow const pointers */ +#define curl_easy_getinfo(handle, info, arg) \ +__extension__ ({ \ + __typeof__(info) _curl_info = info; \ + if(__builtin_constant_p(_curl_info)) { \ + if(_curl_is_string_info(_curl_info)) \ + if(!_curl_is_arr((arg), char *)) \ + _curl_easy_getinfo_err_string(); \ + if(_curl_is_long_info(_curl_info)) \ + if(!_curl_is_arr((arg), long)) \ + _curl_easy_getinfo_err_long(); \ + if(_curl_is_double_info(_curl_info)) \ + if(!_curl_is_arr((arg), double)) \ + _curl_easy_getinfo_err_double(); \ + if(_curl_is_slist_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_slist *)) \ + _curl_easy_getinfo_err_curl_slist(); \ + if(_curl_is_tlssessioninfo_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_tlssessioninfo *)) \ + _curl_easy_getinfo_err_curl_tlssesssioninfo(); \ + if(_curl_is_certinfo_info(_curl_info)) \ + if(!_curl_is_arr((arg), struct curl_certinfo *)) \ + _curl_easy_getinfo_err_curl_certinfo(); \ + if(_curl_is_socket_info(_curl_info)) \ + if(!_curl_is_arr((arg), curl_socket_t)) \ + _curl_easy_getinfo_err_curl_socket(); \ + } \ + curl_easy_getinfo(handle, _curl_info, arg); \ +}) + +/* TODO: typechecking for curl_share_setopt() and curl_multi_setopt(), + * for now just make sure that the functions are called with three + * arguments + */ +#define curl_share_setopt(share,opt,param) curl_share_setopt(share,opt,param) +#define curl_multi_setopt(handle,opt,param) curl_multi_setopt(handle,opt,param) + + +/* the actual warnings, triggered by calling the _curl_easy_setopt_err* + * functions */ + +/* To define a new warning, use _CURL_WARNING(identifier, "message") */ +#define _CURL_WARNING(id, message) \ + static void __attribute__((__warning__(message))) \ + __attribute__((__unused__)) __attribute__((__noinline__)) \ + id(void) { __asm__(""); } + +_CURL_WARNING(_curl_easy_setopt_err_long, + "curl_easy_setopt expects a long argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_off_t, + "curl_easy_setopt expects a curl_off_t argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_string, + "curl_easy_setopt expects a " + "string ('char *' or char[]) argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_write_callback, + "curl_easy_setopt expects a curl_write_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_read_cb, + "curl_easy_setopt expects a curl_read_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ioctl_cb, + "curl_easy_setopt expects a curl_ioctl_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_sockopt_cb, + "curl_easy_setopt expects a curl_sockopt_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_opensocket_cb, + "curl_easy_setopt expects a " + "curl_opensocket_callback argument for this option" + ) +_CURL_WARNING(_curl_easy_setopt_err_progress_cb, + "curl_easy_setopt expects a curl_progress_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_debug_cb, + "curl_easy_setopt expects a curl_debug_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_ssl_ctx_cb, + "curl_easy_setopt expects a curl_ssl_ctx_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_conv_cb, + "curl_easy_setopt expects a curl_conv_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_seek_cb, + "curl_easy_setopt expects a curl_seek_callback argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_cb_data, + "curl_easy_setopt expects a " + "private data pointer as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_error_buffer, + "curl_easy_setopt expects a " + "char buffer of CURL_ERROR_SIZE as argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_FILE, + "curl_easy_setopt expects a 'FILE *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_postfields, + "curl_easy_setopt expects a 'void *' or 'char *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_httpost, + "curl_easy_setopt expects a 'struct curl_httppost *' " + "argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_curl_slist, + "curl_easy_setopt expects a 'struct curl_slist *' argument for this option") +_CURL_WARNING(_curl_easy_setopt_err_CURLSH, + "curl_easy_setopt expects a CURLSH* argument for this option") + +_CURL_WARNING(_curl_easy_getinfo_err_string, + "curl_easy_getinfo expects a pointer to 'char *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_long, + "curl_easy_getinfo expects a pointer to long for this info") +_CURL_WARNING(_curl_easy_getinfo_err_double, + "curl_easy_getinfo expects a pointer to double for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_slist, + "curl_easy_getinfo expects a pointer to 'struct curl_slist *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_tlssesssioninfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_tlssessioninfo *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_certinfo, + "curl_easy_getinfo expects a pointer to " + "'struct curl_certinfo *' for this info") +_CURL_WARNING(_curl_easy_getinfo_err_curl_socket, + "curl_easy_getinfo expects a pointer to curl_socket_t for this info") + +/* groups of curl_easy_setops options that take the same type of argument */ + +/* To add a new option to one of the groups, just add + * (option) == CURLOPT_SOMETHING + * to the or-expression. If the option takes a long or curl_off_t, you don't + * have to do anything + */ + +/* evaluates to true if option takes a long argument */ +#define _curl_is_long_option(option) \ + (0 < (option) && (option) < CURLOPTTYPE_OBJECTPOINT) + +#define _curl_is_off_t_option(option) \ + ((option) > CURLOPTTYPE_OFF_T) + +/* evaluates to true if option takes a char* argument */ +#define _curl_is_string_option(option) \ + ((option) == CURLOPT_ABSTRACT_UNIX_SOCKET || \ + (option) == CURLOPT_ACCEPT_ENCODING || \ + (option) == CURLOPT_CAINFO || \ + (option) == CURLOPT_CAPATH || \ + (option) == CURLOPT_COOKIE || \ + (option) == CURLOPT_COOKIEFILE || \ + (option) == CURLOPT_COOKIEJAR || \ + (option) == CURLOPT_COOKIELIST || \ + (option) == CURLOPT_CRLFILE || \ + (option) == CURLOPT_CUSTOMREQUEST || \ + (option) == CURLOPT_DEFAULT_PROTOCOL || \ + (option) == CURLOPT_DNS_INTERFACE || \ + (option) == CURLOPT_DNS_LOCAL_IP4 || \ + (option) == CURLOPT_DNS_LOCAL_IP6 || \ + (option) == CURLOPT_DNS_SERVERS || \ + (option) == CURLOPT_EGDSOCKET || \ + (option) == CURLOPT_FTPPORT || \ + (option) == CURLOPT_FTP_ACCOUNT || \ + (option) == CURLOPT_FTP_ALTERNATIVE_TO_USER || \ + (option) == CURLOPT_INTERFACE || \ + (option) == CURLOPT_ISSUERCERT || \ + (option) == CURLOPT_KEYPASSWD || \ + (option) == CURLOPT_KRBLEVEL || \ + (option) == CURLOPT_LOGIN_OPTIONS || \ + (option) == CURLOPT_MAIL_AUTH || \ + (option) == CURLOPT_MAIL_FROM || \ + (option) == CURLOPT_NETRC_FILE || \ + (option) == CURLOPT_NOPROXY || \ + (option) == CURLOPT_PASSWORD || \ + (option) == CURLOPT_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PRE_PROXY || \ + (option) == CURLOPT_PROXY || \ + (option) == CURLOPT_PROXYPASSWORD || \ + (option) == CURLOPT_PROXYUSERNAME || \ + (option) == CURLOPT_PROXYUSERPWD || \ + (option) == CURLOPT_PROXY_CAINFO || \ + (option) == CURLOPT_PROXY_CAPATH || \ + (option) == CURLOPT_PROXY_CRLFILE || \ + (option) == CURLOPT_PROXY_KEYPASSWD || \ + (option) == CURLOPT_PROXY_PINNEDPUBLICKEY || \ + (option) == CURLOPT_PROXY_SERVICE_NAME || \ + (option) == CURLOPT_PROXY_SSLCERT || \ + (option) == CURLOPT_PROXY_SSLCERTTYPE || \ + (option) == CURLOPT_PROXY_SSLKEY || \ + (option) == CURLOPT_PROXY_SSLKEYTYPE || \ + (option) == CURLOPT_PROXY_SSL_CIPHER_LIST || \ + (option) == CURLOPT_PROXY_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_PROXY_TLSAUTH_USERNAME || \ + (option) == CURLOPT_PROXY_TLSAUTH_TYPE || \ + (option) == CURLOPT_RANDOM_FILE || \ + (option) == CURLOPT_RANGE || \ + (option) == CURLOPT_REFERER || \ + (option) == CURLOPT_RTSP_SESSION_ID || \ + (option) == CURLOPT_RTSP_STREAM_URI || \ + (option) == CURLOPT_RTSP_TRANSPORT || \ + (option) == CURLOPT_SERVICE_NAME || \ + (option) == CURLOPT_SOCKS5_GSSAPI_SERVICE || \ + (option) == CURLOPT_SSH_HOST_PUBLIC_KEY_MD5 || \ + (option) == CURLOPT_SSH_KNOWNHOSTS || \ + (option) == CURLOPT_SSH_PRIVATE_KEYFILE || \ + (option) == CURLOPT_SSH_PUBLIC_KEYFILE || \ + (option) == CURLOPT_SSLCERT || \ + (option) == CURLOPT_SSLCERTTYPE || \ + (option) == CURLOPT_SSLENGINE || \ + (option) == CURLOPT_SSLKEY || \ + (option) == CURLOPT_SSLKEYTYPE || \ + (option) == CURLOPT_SSL_CIPHER_LIST || \ + (option) == CURLOPT_TLSAUTH_PASSWORD || \ + (option) == CURLOPT_TLSAUTH_TYPE || \ + (option) == CURLOPT_TLSAUTH_USERNAME || \ + (option) == CURLOPT_UNIX_SOCKET_PATH || \ + (option) == CURLOPT_URL || \ + (option) == CURLOPT_USERAGENT || \ + (option) == CURLOPT_USERNAME || \ + (option) == CURLOPT_USERPWD || \ + (option) == CURLOPT_XOAUTH2_BEARER || \ + 0) + +/* evaluates to true if option takes a curl_write_callback argument */ +#define _curl_is_write_cb_option(option) \ + ((option) == CURLOPT_HEADERFUNCTION || \ + (option) == CURLOPT_WRITEFUNCTION) + +/* evaluates to true if option takes a curl_conv_callback argument */ +#define _curl_is_conv_cb_option(option) \ + ((option) == CURLOPT_CONV_TO_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_NETWORK_FUNCTION || \ + (option) == CURLOPT_CONV_FROM_UTF8_FUNCTION) + +/* evaluates to true if option takes a data argument to pass to a callback */ +#define _curl_is_cb_data_option(option) \ + ((option) == CURLOPT_CHUNK_DATA || \ + (option) == CURLOPT_CLOSESOCKETDATA || \ + (option) == CURLOPT_DEBUGDATA || \ + (option) == CURLOPT_FNMATCH_DATA || \ + (option) == CURLOPT_HEADERDATA || \ + (option) == CURLOPT_INTERLEAVEDATA || \ + (option) == CURLOPT_IOCTLDATA || \ + (option) == CURLOPT_OPENSOCKETDATA || \ + (option) == CURLOPT_PRIVATE || \ + (option) == CURLOPT_PROGRESSDATA || \ + (option) == CURLOPT_READDATA || \ + (option) == CURLOPT_SEEKDATA || \ + (option) == CURLOPT_SOCKOPTDATA || \ + (option) == CURLOPT_SSH_KEYDATA || \ + (option) == CURLOPT_SSL_CTX_DATA || \ + (option) == CURLOPT_WRITEDATA || \ + 0) + +/* evaluates to true if option takes a POST data argument (void* or char*) */ +#define _curl_is_postfields_option(option) \ + ((option) == CURLOPT_POSTFIELDS || \ + (option) == CURLOPT_COPYPOSTFIELDS || \ + 0) + +/* evaluates to true if option takes a struct curl_slist * argument */ +#define _curl_is_slist_option(option) \ + ((option) == CURLOPT_HTTP200ALIASES || \ + (option) == CURLOPT_HTTPHEADER || \ + (option) == CURLOPT_MAIL_RCPT || \ + (option) == CURLOPT_POSTQUOTE || \ + (option) == CURLOPT_PREQUOTE || \ + (option) == CURLOPT_PROXYHEADER || \ + (option) == CURLOPT_QUOTE || \ + (option) == CURLOPT_RESOLVE || \ + (option) == CURLOPT_TELNETOPTIONS || \ + 0) + +/* groups of curl_easy_getinfo infos that take the same type of argument */ + +/* evaluates to true if info expects a pointer to char * argument */ +#define _curl_is_string_info(info) \ + (CURLINFO_STRING < (info) && (info) < CURLINFO_LONG) + +/* evaluates to true if info expects a pointer to long argument */ +#define _curl_is_long_info(info) \ + (CURLINFO_LONG < (info) && (info) < CURLINFO_DOUBLE) + +/* evaluates to true if info expects a pointer to double argument */ +#define _curl_is_double_info(info) \ + (CURLINFO_DOUBLE < (info) && (info) < CURLINFO_SLIST) + +/* true if info expects a pointer to struct curl_slist * argument */ +#define _curl_is_slist_info(info) \ + (((info) == CURLINFO_SSL_ENGINES) || ((info) == CURLINFO_COOKIELIST)) + +/* true if info expects a pointer to struct curl_tlssessioninfo * argument */ +#define _curl_is_tlssessioninfo_info(info) \ + (((info) == CURLINFO_TLS_SSL_PTR) || ((info) == CURLINFO_TLS_SESSION)) + +/* true if info expects a pointer to struct curl_certinfo * argument */ +#define _curl_is_certinfo_info(info) ((info) == CURLINFO_CERTINFO) + +/* true if info expects a pointer to struct curl_socket_t argument */ +#define _curl_is_socket_info(info) \ + (CURLINFO_SOCKET < (info)) + + +/* typecheck helpers -- check whether given expression has requested type*/ + +/* For pointers, you can use the _curl_is_ptr/_curl_is_arr macros, + * otherwise define a new macro. Search for __builtin_types_compatible_p + * in the GCC manual. + * NOTE: these macros MUST NOT EVALUATE their arguments! The argument is + * the actual expression passed to the curl_easy_setopt macro. This + * means that you can only apply the sizeof and __typeof__ operators, no + * == or whatsoever. + */ + +/* XXX: should evaluate to true iff expr is a pointer */ +#define _curl_is_any_ptr(expr) \ + (sizeof(expr) == sizeof(void *)) + +/* evaluates to true if expr is NULL */ +/* XXX: must not evaluate expr, so this check is not accurate */ +#define _curl_is_NULL(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), __typeof__(NULL))) + +/* evaluates to true if expr is type*, const type* or NULL */ +#define _curl_is_ptr(expr, type) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), type *) || \ + __builtin_types_compatible_p(__typeof__(expr), const type *)) + +/* evaluates to true if expr is one of type[], type*, NULL or const type* */ +#define _curl_is_arr(expr, type) \ + (_curl_is_ptr((expr), type) || \ + __builtin_types_compatible_p(__typeof__(expr), type [])) + +/* evaluates to true if expr is a string */ +#define _curl_is_string(expr) \ + (_curl_is_arr((expr), char) || \ + _curl_is_arr((expr), signed char) || \ + _curl_is_arr((expr), unsigned char)) + +/* evaluates to true if expr is a long (no matter the signedness) + * XXX: for now, int is also accepted (and therefore short and char, which + * are promoted to int when passed to a variadic function) */ +#define _curl_is_long(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), long) || \ + __builtin_types_compatible_p(__typeof__(expr), signed long) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned long) || \ + __builtin_types_compatible_p(__typeof__(expr), int) || \ + __builtin_types_compatible_p(__typeof__(expr), signed int) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned int) || \ + __builtin_types_compatible_p(__typeof__(expr), short) || \ + __builtin_types_compatible_p(__typeof__(expr), signed short) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned short) || \ + __builtin_types_compatible_p(__typeof__(expr), char) || \ + __builtin_types_compatible_p(__typeof__(expr), signed char) || \ + __builtin_types_compatible_p(__typeof__(expr), unsigned char)) + +/* evaluates to true if expr is of type curl_off_t */ +#define _curl_is_off_t(expr) \ + (__builtin_types_compatible_p(__typeof__(expr), curl_off_t)) + +/* evaluates to true if expr is abuffer suitable for CURLOPT_ERRORBUFFER */ +/* XXX: also check size of an char[] array? */ +#define _curl_is_error_buffer(expr) \ + (_curl_is_NULL(expr) || \ + __builtin_types_compatible_p(__typeof__(expr), char *) || \ + __builtin_types_compatible_p(__typeof__(expr), char[])) + +/* evaluates to true if expr is of type (const) void* or (const) FILE* */ +#if 0 +#define _curl_is_cb_data(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_ptr((expr), FILE)) +#else /* be less strict */ +#define _curl_is_cb_data(expr) \ + _curl_is_any_ptr(expr) +#endif + +/* evaluates to true if expr is of type FILE* */ +#define _curl_is_FILE(expr) \ + (_curl_is_NULL(expr) || \ + (__builtin_types_compatible_p(__typeof__(expr), FILE *))) + +/* evaluates to true if expr can be passed as POST data (void* or char*) */ +#define _curl_is_postfields(expr) \ + (_curl_is_ptr((expr), void) || \ + _curl_is_arr((expr), char)) + +/* FIXME: the whole callback checking is messy... + * The idea is to tolerate char vs. void and const vs. not const + * pointers in arguments at least + */ +/* helper: __builtin_types_compatible_p distinguishes between functions and + * function pointers, hide it */ +#define _curl_callback_compatible(func, type) \ + (__builtin_types_compatible_p(__typeof__(func), type) || \ + __builtin_types_compatible_p(__typeof__(func) *, type)) + +/* evaluates to true if expr is of type curl_read_callback or "similar" */ +#define _curl_is_read_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), __typeof__(fread) *) || \ + _curl_callback_compatible((expr), curl_read_callback) || \ + _curl_callback_compatible((expr), _curl_read_callback1) || \ + _curl_callback_compatible((expr), _curl_read_callback2) || \ + _curl_callback_compatible((expr), _curl_read_callback3) || \ + _curl_callback_compatible((expr), _curl_read_callback4) || \ + _curl_callback_compatible((expr), _curl_read_callback5) || \ + _curl_callback_compatible((expr), _curl_read_callback6)) +typedef size_t (*_curl_read_callback1)(char *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback2)(char *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback3)(char *, size_t, size_t, FILE *); +typedef size_t (*_curl_read_callback4)(void *, size_t, size_t, void *); +typedef size_t (*_curl_read_callback5)(void *, size_t, size_t, const void *); +typedef size_t (*_curl_read_callback6)(void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_write_callback or "similar" */ +#define _curl_is_write_cb(expr) \ + (_curl_is_read_cb(expr) || \ + _curl_callback_compatible((expr), __typeof__(fwrite) *) || \ + _curl_callback_compatible((expr), curl_write_callback) || \ + _curl_callback_compatible((expr), _curl_write_callback1) || \ + _curl_callback_compatible((expr), _curl_write_callback2) || \ + _curl_callback_compatible((expr), _curl_write_callback3) || \ + _curl_callback_compatible((expr), _curl_write_callback4) || \ + _curl_callback_compatible((expr), _curl_write_callback5) || \ + _curl_callback_compatible((expr), _curl_write_callback6)) +typedef size_t (*_curl_write_callback1)(const char *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback2)(const char *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback3)(const char *, size_t, size_t, FILE *); +typedef size_t (*_curl_write_callback4)(const void *, size_t, size_t, void *); +typedef size_t (*_curl_write_callback5)(const void *, size_t, size_t, + const void *); +typedef size_t (*_curl_write_callback6)(const void *, size_t, size_t, FILE *); + +/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */ +#define _curl_is_ioctl_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_ioctl_callback) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback1) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback2) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback3) || \ + _curl_callback_compatible((expr), _curl_ioctl_callback4)) +typedef curlioerr (*_curl_ioctl_callback1)(CURL *, int, void *); +typedef curlioerr (*_curl_ioctl_callback2)(CURL *, int, const void *); +typedef curlioerr (*_curl_ioctl_callback3)(CURL *, curliocmd, void *); +typedef curlioerr (*_curl_ioctl_callback4)(CURL *, curliocmd, const void *); + +/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */ +#define _curl_is_sockopt_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_sockopt_callback) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback1) || \ + _curl_callback_compatible((expr), _curl_sockopt_callback2)) +typedef int (*_curl_sockopt_callback1)(void *, curl_socket_t, curlsocktype); +typedef int (*_curl_sockopt_callback2)(const void *, curl_socket_t, + curlsocktype); + +/* evaluates to true if expr is of type curl_opensocket_callback or + "similar" */ +#define _curl_is_opensocket_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_opensocket_callback) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback1) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback2) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback3) || \ + _curl_callback_compatible((expr), _curl_opensocket_callback4)) +typedef curl_socket_t (*_curl_opensocket_callback1) + (void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback2) + (void *, curlsocktype, const struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback3) + (const void *, curlsocktype, struct curl_sockaddr *); +typedef curl_socket_t (*_curl_opensocket_callback4) + (const void *, curlsocktype, const struct curl_sockaddr *); + +/* evaluates to true if expr is of type curl_progress_callback or "similar" */ +#define _curl_is_progress_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_progress_callback) || \ + _curl_callback_compatible((expr), _curl_progress_callback1) || \ + _curl_callback_compatible((expr), _curl_progress_callback2)) +typedef int (*_curl_progress_callback1)(void *, + double, double, double, double); +typedef int (*_curl_progress_callback2)(const void *, + double, double, double, double); + +/* evaluates to true if expr is of type curl_debug_callback or "similar" */ +#define _curl_is_debug_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_debug_callback) || \ + _curl_callback_compatible((expr), _curl_debug_callback1) || \ + _curl_callback_compatible((expr), _curl_debug_callback2) || \ + _curl_callback_compatible((expr), _curl_debug_callback3) || \ + _curl_callback_compatible((expr), _curl_debug_callback4) || \ + _curl_callback_compatible((expr), _curl_debug_callback5) || \ + _curl_callback_compatible((expr), _curl_debug_callback6) || \ + _curl_callback_compatible((expr), _curl_debug_callback7) || \ + _curl_callback_compatible((expr), _curl_debug_callback8)) +typedef int (*_curl_debug_callback1) (CURL *, + curl_infotype, char *, size_t, void *); +typedef int (*_curl_debug_callback2) (CURL *, + curl_infotype, char *, size_t, const void *); +typedef int (*_curl_debug_callback3) (CURL *, + curl_infotype, const char *, size_t, void *); +typedef int (*_curl_debug_callback4) (CURL *, + curl_infotype, const char *, size_t, const void *); +typedef int (*_curl_debug_callback5) (CURL *, + curl_infotype, unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback6) (CURL *, + curl_infotype, unsigned char *, size_t, const void *); +typedef int (*_curl_debug_callback7) (CURL *, + curl_infotype, const unsigned char *, size_t, void *); +typedef int (*_curl_debug_callback8) (CURL *, + curl_infotype, const unsigned char *, size_t, const void *); + +/* evaluates to true if expr is of type curl_ssl_ctx_callback or "similar" */ +/* this is getting even messier... */ +#define _curl_is_ssl_ctx_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_ssl_ctx_callback) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback1) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback2) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback3) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback4) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback5) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback6) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback7) || \ + _curl_callback_compatible((expr), _curl_ssl_ctx_callback8)) +typedef CURLcode (*_curl_ssl_ctx_callback1)(CURL *, void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback2)(CURL *, void *, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback3)(CURL *, const void *, void *); +typedef CURLcode (*_curl_ssl_ctx_callback4)(CURL *, const void *, + const void *); +#ifdef HEADER_SSL_H +/* hack: if we included OpenSSL's ssl.h, we know about SSL_CTX + * this will of course break if we're included before OpenSSL headers... + */ +typedef CURLcode (*_curl_ssl_ctx_callback5)(CURL *, SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback6)(CURL *, SSL_CTX, const void *); +typedef CURLcode (*_curl_ssl_ctx_callback7)(CURL *, const SSL_CTX, void *); +typedef CURLcode (*_curl_ssl_ctx_callback8)(CURL *, const SSL_CTX, + const void *); +#else +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback5; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback6; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback7; +typedef _curl_ssl_ctx_callback1 _curl_ssl_ctx_callback8; +#endif + +/* evaluates to true if expr is of type curl_conv_callback or "similar" */ +#define _curl_is_conv_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_conv_callback) || \ + _curl_callback_compatible((expr), _curl_conv_callback1) || \ + _curl_callback_compatible((expr), _curl_conv_callback2) || \ + _curl_callback_compatible((expr), _curl_conv_callback3) || \ + _curl_callback_compatible((expr), _curl_conv_callback4)) +typedef CURLcode (*_curl_conv_callback1)(char *, size_t length); +typedef CURLcode (*_curl_conv_callback2)(const char *, size_t length); +typedef CURLcode (*_curl_conv_callback3)(void *, size_t length); +typedef CURLcode (*_curl_conv_callback4)(const void *, size_t length); + +/* evaluates to true if expr is of type curl_seek_callback or "similar" */ +#define _curl_is_seek_cb(expr) \ + (_curl_is_NULL(expr) || \ + _curl_callback_compatible((expr), curl_seek_callback) || \ + _curl_callback_compatible((expr), _curl_seek_callback1) || \ + _curl_callback_compatible((expr), _curl_seek_callback2)) +typedef CURLcode (*_curl_seek_callback1)(void *, curl_off_t, int); +typedef CURLcode (*_curl_seek_callback2)(const void *, curl_off_t, int); + + +#endif /* __CURL_TYPECHECK_GCC_H */ diff --git a/src/lib/install/arm/lib/libadaptor.a b/src/lib/install/arm/lib/libadaptor.a new file mode 100644 index 0000000000000000000000000000000000000000..51a77a1307cc7d602f1d940064834b08c9cb6b1e GIT binary patch literal 40482 zcmd^o4S1E+mG1t|IY~}_fIy-Kh2?{0<2BOBl3HdoBk#LepP7tgW zD(MtkZAqmaW^O96V_T=Cqchjup@I&*wR624+cN5{wqvJ&GUK4_V=L{o)(-c5_g?!u z`+P|xI@jKL?(8RD)?Rz9z4qE`|DJEJvroyAwt7mL&P2Bw-i!H8NBpmB= zlv3v?70yh5F8Q@m|K8`u?<%$BU7ybQ=AMpt>p;A{uP>>(;>p&&!PcI{hCUtd>>1o> zunlb;$-aTDU>pRDtKMW^n_9VMS!+{&Jh3i5usJ@ktS^y>cO-lI5}L5CuVZ68IVss8 z^!5$LC(e?h#1oyX;)8>2T`uRk2~*d`J2tz#LHwF{(j^-`1BuIed*X>?T}MZ}Kk2A8 zE}6A3iIdiTLb8)DRY%`olEtSiYwPX3dMIIRd)r`Nq7@CbE;-PX=u#G4J+!GkKH#HG z?YE&Ve6((0plxe9))-H8CAZ0zWs{JqDck`~S%d)dbG z!JF^!dR04)h1J+m%3)s0%&VGvT&Z<0&rm9794}-m$jcKM6VdbY=N`9oTP|g?oXFvZ zV`}FUuj(pF-SSa4>ZPiVyc|XO`BHua<a4G&oJ8bX~1BcPPK2}HHE%C7UL_%)8k<7@u#JpcD$d5K4r%(@*KsyakQ|i;TY!=o6d2{e#bP9^PM8Y zj@fLb=GZ=pWnTAD+AfUwMbACR(;|5+U&!I(Jmi<9+h^=(5$dMyu5DUdQc@CIeO+T?tiP`(k&F+-`ZmM{IyTq0CEKvi z@9%9(Zs;4>bUk)z?QMhcrge-d)yb{jfQg@8p6t*eucL1$0Ton#8+LM(gZ(<;hJkpT zFxi)E>jfMdjCT?z?2iw0U~fAGz5U%kN>a*fO0T>!=Ipv-OJnl}LG@|;MBwgLX_)!3 z0eq}zAKFkhum7SP*e%IyofO*2jcjY$XOPzZwt==yt$jnRm!V629g5_$pH3W#%@g>% z;&7yuhBBzZ#GiR!$H1qaTr7x~pAaJ6XYoJpTKqeUIKrJ#14EIlD=N#2Y;e*=Ow41jE-m6TMb>i>W>&&MF1Ng?KW;+)=AsHVbiGhqF}%1x)8;;a$Tl zj6DSCjs6h`M)EaAa&iVf=7Ws{=%Xcn0`ZJ6_ra+BG5pu^nX2WVr7~_ueEJXY&%2rO zUjgg$EN%2>NHg+p7R_fwU^nk(5<(;0`TvudZZ-Aj&!59gf9TdK4DO6D_iHGd&7#X@ zsxEuB%3w=R=cM9oVaEL+8LO>A%#^()&1!eJ^4Zri!ef-LB@@?@&s7-|P|!)0hMA=p zBdwU&=r=$xE%3)iR&V|s*5ebVoPN`$I}O&YZTKBs&LO`X;<}t^Dudz*-lBj}imSn( z<_5_dy#yti_RtN5o@7dWAg$EBX{C<2rCtF68DZ`&Oznv4Qgc-Xg%>=@avrC+M(hJk zsSmPL-Aa#}R+3T=rj`0cTB%RErBXmfm_y#wt?(I^@)KrXkGa9v@Hb#GwfSk9+#_jn zkGgWRVVI2Y>wayB>)Omv85F0ynclqV1-aqrbEnVrW@YAMCJdFT+}taXg!xCJm=+^5 zkh&6|EHf@p1ep}g0Pva+BCw45`26xQ{;l?BY2 zR|0{RAWtg*dC6?_%?i(CyKwf(0;*M8^!cl1lXpgjFCkQf$*DRGoe4B*iX(LvsVfVr zXA>!?@IE|y5~+nLTA(~t3>%@FA<$YT*j0kqB`|GBtwb#3{dW2^h1Vc7He0Wvq7r{S ziH_c(&bU(U3ziOMbrM>WTl?dK72V7S3+n>IbG_k)#)cP$-|TwxWMgGG`|ceLU1P(Q z;he|!b{#nIx7X}g5YGAKSmSV47gn0E{uli^qZ9o93evsI4VhowK}pf15%uJTu7-xj zuI{dA$zEaT+R@$BwW>1u$lc>f;p_)A?S9f$rDqFI6WXLAL&Y#oU47k}=BBl+b!%3( z>djW`>ZaApRb_YIrg&vHUxZcO-Z!wZa&VxdvOV5A)YT@ST&$%jy*=%&^(s2JBjNTW zZFgjL7=iWQ*+rP0*EOrJi!EEQAa-d*bwyQdVby{~Rg0=Fiw-0QAx+Z0#h zO}}#W^>vLa>s!~8N*lcE>huXEnZnHOtqoTDflB%BIz= z^~+bUTwb5Hd-g?lbhiztLA(fV?Zh4%7P$Jl)ytZhtJT?J`|LEJ)@{6kcAGgUW@P0P zsJyg#PeLW)x8uF48tl0v&M{}U*(qt1J-!}I*EP2`UER8B`KqS1H!7`ePoguv#Wt2T ziPO1E3saolxVt-4zpZ3%uV4T6nU}r#Q-D^dQ@^x@qPmCZGRG^nx~aK!-F0i$G_7rh zah;DK*DPChd93WZc6_!Ns%-2@v<>u`9$vm^NGC41Yr&$5s_Kf%E(-K~PC$8hP9b;@S51$8D)edZs=VAtXhYt#C?`nVYmF}*zmK8GH<%E@mx zK`#AShi*424n0l2-EKJa&|OY`yG?NEcRF;tpif4(OR-C*{JM)!skS&~2W(3b&A7B# zWrm|(wl^zM=$+x66)y5-dvikPV8aj$dd8Q;i2B7TmmW6jfu9ss*!DOf>?}%54yz0` z!=XbHH7gDG)ER=atwNAb{ug~7PxF&zf~U$6vF&R4t9_+C)c`to&^Z2rG*cei*#uAB ziU@JGyUnk6SDL|7Lx9{TV~O_jvmcn?sZStc`-RQF+c$%!9t3?D{BrQn4qa_v?)m_Ja{%Y3LL10G z62SKaaDL{qf&5<%;9n2mPXzF10{C+Q{8#{gJAlu?=FQGSv(O@Eo86;UiTYFo@DBy> z`T%}Ca64~NUOR9*PZ942Zs#T9fsIjVrz+)=$^~frYIwTMMrt9hxU}ZdDv@JX+0<(u zcgZH_rSGyb26z`)-pMy=fgFpeN1A4f7X?#lJ`_y3Y+SC(7MYV%v-GxNXV5CEu(KlT zWNhR7b6VjR(AL?RCM4O{sxzA$t?@0`>m>(z;|aA12f%$DYEyjEAl^d&bo9$oT1eO(iG6{U|oM!B1W1r~xK}rcQ8e=9TWTZu(|0_-@Z^e_C7hzO}WZdt>W{ww_*? zE|t(V)HcxhE^pWZ&8A}Ljdcs zi7!^_DZ(1FMujlFMbX8JFHL1aV{qCb%CW=bC|w`5c0W3QO+KLqXNeSJ|ysAf%^nL zD)2FZuK=?AcL*VuYZv7f3M>-19+31TA?$ZA;fG;QNq>6HS} z^)(;5kcRaFxxZrm8wIWx*d;I_@FN2MMBo<${<*-v5cr6|Ck1|2;1319ERgRsS#HQP zaJoRgZ)Exf0B7`0OOz?*VJ|&RrE#?1&5PaO*5a&1~oJELs zC>MM&A)c!RZx+}tu$K`0_X++dgm}IzIL9&N{&#_g1^$!3R|%0n8{?0B1%yaDPw*=R zt{?ATe+fUwJImqLo^ZNA?kR|0K!|ec1aBZjIX4Nu zS>Uk1&k7tRM82;G{#S&^_kF=%5_m%3NkZ`Jetm)2Uy}cN_6xv5LVP&jzMVLRmc}tv zYrI)-&iAAz1>Yk0Zo&5m{+QtV1%F=f7X?2l_*;VW#j7q~`iZI-+`1{*)()5)FtFRk z2I9RHNv_2e`UOKp`{1Ce80a$yiJkHGp)TVkC-JuS_JR0jaQRf6X(hVi%;+ce_9Wtv zsWYQ2RngJ6X%i3TDiU}DRDoAZcmsqtLT;W7I2uEyy0xn++LBn%+lP`6I`wcaSW#u& zF3eSp$9*A*X47FV{&ROVd_%z@DNA0)8SDjI)OBXOYo3%IzBA@ zS{{nhf%4w5LXcwh!&0jG3>Vgs9Q}6JqCTw#DQ-O?C0G-r9_*X89xD)cictsf!8Yb3 z*yv3GzJJ7~JccwIEFb&1TkcEen=w!*>9*WWz-=DN_$}mBItez~Bl&8{gz!4#(VmpY zPhD2tR>YZyc4W91AK<&J(Sei3XIP-+8^J_P8K+=*r zwE2*?9!jw~v;p;F`P9vocP|FQb|<5i*VEsj{TyQwPV4WuVA0}*n)menj%B8z6Z$*W z!l$VQzD7&(bC1`?a*x-;f9Va!ho=mFNiq0J(HD`vGxP^K2Yyaf;{P-s5Vk&11OJ*@ z@vk9|N53ZcE$%BfRxmPj17%`q}|9HV^7ratwMH6J`xvAxHaSeej$D*jEjUs)fXG=E0OwSJb` zZwoSg->889S#-BF7%&!+~LuEWGZ$p zf*@;S`UF{@(R|n1^wX=n=%Jf0eRnPY1^WNfc8;{kKaSC2@$(f1MS;)yM2zXbSgKfqXg zdH>>uqf8H}9mjSe@1qzSz2Kod%`fe}UG%sUW!woqPYu3|ZP%P(DZ|oP7Us7T8IWPq zf_a)J$OC;(+zYwe(Z<%FmU>R5&)D^(1zkr^SfjzCV}oMLBoEPV|Rn zT(`%L3nztaW?jI#`S_zU4yYgNjP?1%m`zh=u3uCxu~ zA?W<-sZ&3`r|M>;pMUIBRrna&j%$0jXj=WL*BdPYU;bve4tqLdXrzATS>W^L827N+nKe2C1%*crZkzc% zL=0>TeE|nUp0&Mn_w}NF1 zLtG7@H(Cl7qst1>#T2o^)T-ZFnNKJEix6+M;c|9C?lOc4O3&cbRPM%oZMb0aER z?|=$X-Ug0^@W}8sRd55v-b3XZX<8R1=s zsVs66*CX>xmB|7M=zQ&coq6~sZVbR1y&g=aCSNxt-@DDU_18ZGdU#}~468@T7#`WR z&5ZgDR(6LfsH39aq}VZtU9ZLN_r-qGRJ_;p!f%=u?>4xU&X1Zr9eODdoyLzvtJHejedc98QziO9j7*GwOF++;h z9_PPWIW#y>2?xk>yyhO-QVu6adN^5!*2?ytdluLoojz*mz*on+>aWG#orY&(}O3k{9Y^B}aLs-f}V-iEG*?j8!P%zQiqFAWbT?5H*T0$P)*zq>8b*&BzW zKwA?3wQDFH2aVl)PsP;6%=zBEzw?{y8}8P)twRabszo#{Ygpdgx}t7%edBU?i<*64 zD_s=Uxg=-2|#agv7;@Xo|ntf;7V6&`GB-O#qFr*|uw!1pcHewMoU zwe_p~8c(QusvIGk8u-o1>bttRo}4L%Q@>uZtQk1e&f(w+@Z77FI%=o zsehNVFLz#(`TBB4@A|q9JHE1Zx9`x`g6#YH+8w<^U+vQEPTrx1Twh$f3wP+(yZP-7 z+o7kGZ}-v;J*|9hO}Vjj=xO=wZrP!y<+r|-~$4n0l2-Ple>w;NiA9{NK^ zzTI}Z^c4=>?jIfcZLa;4>;@hBO)lN;^c;HV$6%s<98kmzVnIo5Is#Oqz->FMSbgpqxsJ01~(72edhTQ|kis6#@JY z0(g4>PXebbj$6v(*|r^r#PF-XVShxDC|z7eru`S^(0oB`$&V zER=1>73pUKxAPQn`Zn8niTD!WcAOIb1K@UEBHj+%j&tH$f!leB_-BFJaY+2HfZKVA z_;-NYd4%{+f!jcR|2csFEP$U3;J*prd?{xGF z-|K~0*cfw%t~YFY@8oXKQmO8Klc_=6+3BP*1rpPCb1ANI$y0HA^5jr zjmx4bZ5&J z2VV?q>r}T7^x%_~_*}~e8um-RJ~!yN9`fRr1m=Dd3fW4{$G5)SwrxxSXBg^ zK5@kYIlhZ8z?Y{9@oH@!VTsb;4cuZ+u;^K?pe?=Sz#vDh)IX;T#!fKNHVXT>g?;)&({RBTkh;q2bvYa;v@thR+mO#GGV!HMzFkfJyK&Y=mXP|t- zBD{|ih$M~ACPZIB6;ueDk}^r>I!%6b6%C<+hEQF@27xyUTraRop!PXN{*MU0UEr4m z{*}OQ3H%=dzbEiHfj<)XQ-Q|?z9#Ubz;^_4{ng*)7I>~ejzgxe5XiGd;yhp>{HVZt z1b$xNg95)o2s>#XWbpGk3g$a1a5iYfxn7ZPq2RRwuM?;*-atGd_(uiu-UsH>SA;;0 z_BjUpw$PsycvRqPgm~T-{LHW^f1bcfLeRADG2}E#`pp94LQe|5L*RXquD^?bd|#FH zZwmaj(4Q3?2k^SyuSxpbf@eoedXc~j1uhbJwLs1v)U#FagupG5{t3Z9FK|rK9})aX zf!`CTeUzd1Yl8oZ5aWdN3fpH6AjI$az-qp9}n* zz%0%mpr1*Ia_0%G7Pw5{T7mrnM+5?>5Kd0GC!(Cc5r`xenj7$`23{ldW}&wTo)mnG z;JXFiBlu&2?-%@e!Cw^oq~LD}UdaB=@?|_!3tl6*9#^2Z2%Z%B7QuH5zDMxK1m7?C z^Mb!9_({Rv61)($(B%{2`Ooar?Y^W(H`f8C*B=jS4XU0l!CDDB6#|C|75T7~sCj~8 zxa!b|^}-G0Wx&#?`A^5ktp@Y3Nf;=PbEXYeKYreGlGU3znDf}#C0JSwaH>=*={rl! z9)=c)B-m&VXl^~$KpyQ+dAWG3ysd~c5ADcs6&M;xlt3DvVS$$K(?zMz&}6lI_eq>- z4BrKx8_37-ARZeh{tWo4Y$F1vCB>b+dgGQMD6$^rcQcY#ni8(%PYYaExnrRV)=u-2At9*eoZ6HGy2O}Un=^_<%{2#>nn$$VeXTpKP3FSmWb~a?@hFR zhw~*3bw5!W!(EY(6_Ygj&87LrL9bFgEAaH9hJ--FVMlnaIh99QuF3oc^7- zR!>*{K}X(XK7zdOafQe&61f-;Ifd{QW103YUo9WFtqa-@caa{^b_>?)b(CAg1{U8_ zd+%j&K79KE{(tuVVBQJJy7E5MVwCfe=u|8^T|k}STSvPWOWWx713e7?N$R>!@~}N< zA2k1u8Ta5zN4wCE7iH*sh5dBorT?bA=acD_N8f6<9Nt&UG8!FQF^xW())uS_+lFOL z#kY=o;3S@h99zZEFJthPd?{e3BC(IPleJs1V>esxX7tlB@nwvPPa*3~8Mcj4uZzv?-LTlw1T>I=eQ_9{TzGd*s(&pPPGqkfAtQY z7zXnSJbaIEFP>36d@uP19vx&Xv48OHZH}c_4E7216OJF2@Aeb750Gx{X!^jBmoe3! zpq-yWJ^!1%*Aw>T7{XjW$Env*_Ib7$)BYvEi#Z?jW5Y4Z(rqYo&V{{VL(UoOySA^Q zdU~#ju{_w7vw04@?{rO?N-qw?Z6F@~p1+-4no3gJNFFTfU3r?@+w2#E00lMftL;+-B{- zbq($K>Sk-QTfah7le9-GzUkSsVXJ8tTSp_SzoUJU4loJdxK5DHha>QK&*r!^sIMR{ z?04;C%66$}Psc9lblmG|gv!mgu~dUOwtsiqoVLH20pPkR`<~Erhs6wu5b>_V|GXj0 zBlZ&mU-vP744P2wvAUgiamf!kPL11;rN{3JP}S$7jeGI&q{Dc=AV ziDX3X&>5r80L}ak;^BFhGbI|~m6Tb(LUJ@zv>!>)tC`<;-bVR$Hzc07nKeX8?gvjc zzk%+ZL*F!pF+AQV-&EyfWnX4VzV$4J@y^IJ;%jTZj__>Y& zU4zFPT}DZWfnf6Xn!MFEZ}y)u*D|7S;JK5mqjay$ImGBPdgrnHA85?v>NXOW8Ht@n z;&NYN9a(Q6+6y`JDSwn!F%oZJ6rP4g#tlZsdL!dTBcnI(ADHPTDJ@q!=H6^9(U00P zmfb{_tyFIhEXXy>T&_B;f3u{AMsCUbCUyCUD4KT}u{#YWM*OH0X$rZ^6tX_=5IMI= zk<;(R?A?tNHRH!DbwBg)Z8e+G8~rKDHg(%?GISbiX|~YF`kVqPx8KzJmOQ@x^9~p# z`c1J1O+HcS2~kPqJx?tLK8F7p(16H$x^ENN?6sSjuH#}>y3b)W-RCfS((5zf#%i4t z`Q9ow-N`U7-H~uwx`X2MTt)vyn9y};oXUNfb{w<*bomaccEsM7zadZj>_@x~%Jba> z`^`k{_!z=?XebnUj<>h5VMo{AgTs|??`Z7m>cSnGcOO7x?=Ww}eBc3d)#YAXtNFx% z;g2INC%TJwT=H^EWNd^(;NA!Q8#3?N+XX+su5jYoaA8GPS7TRI)gO1m!w)kI{rfVb zk38OuoIAS0IoIy!db8^wq=2hY=%GCL|LJA_{akw~iwe#%Wwl7Hp}!YTC9|d}eRYDE z9R73KrOID(WXT-w#5I8nnpqoC)d_A%QeJSrYo71DnDWu`tr65A&4(s(En1)q8O|QoF+9s!R3$KN~Fvb+;x6% zK44=QL9P!_t?Oe18doWYzTWjAvg?sUPr7uwx;XUEPDj377hL*Dhi+$Zm%a=1I(!KE zkK&^=9jc^4hCZW9;huiSMtlqp?&|LYE&XMnW337)zJ z5!()ypXb$WUlWWwPYm`hF2xR;aGse7Pv>?sK7&j%*S14 z@rA~Zh57jYl<90+`l-|l&Ut`z{pkvDpQJxch&l9#;C!b<|A%6XYx-0041xX+^@Na1 zKNb30aGnTNn0HQEU*eFvTOfVkSl^R`kjFc-nEw`mdjx8~l}d9aMEXliuM)o%z&y+s z#AAe@*9crM>DvjR59b-`vx|^=2;3uZRN$CE`n8bnVS)PuJ}OZAxgh=)9_r8YW%}RT zNmvSf38B}Egeaf$7|VZ^5Rdj_0nB83;e~P@Ar3k?2NG((4ZzvNVWSd4yy!%eX*x`z zq4wJV-%`Qr1vUu0QQ&%kT>=vVKPvEUfu9km`xWGl3BFGtKZ8-frv!eV5c>T@@Ye+D zJL15{{zm$RguvO~2v1%(mPb#NB%I7QvSe zMAn0<+Ip;T@*t|ZFku{FM1qyaJ)4b_bj>uSVvIjyE8@&UJ2E7uW33C=h4f)OF5iZlLfXA&zHR`b*X{-lD+j{&Z;%N4M03Dve#EoUZ54J4M z=T7%fyCLsMpDU#k`5iN;w~&#(oLmP=@vvN$Pu*O3WngHug@IM)W1rGb8D&$R7Xw|kbERxgyzK83v%be+5|^8$5Y z9objmilWc8-M*;%a#~+Z_Zjfdz>$9j6VW*~E#2CXGN;@Z13oDzTc1Z;nQlL@J~gZ_=KMLfO|6dv%M9LiRfBo83T;!3 zwyD9~vIKR0G|-aO1#g_+zq%Eea-x?arAJ*v3&a*=}4q4>|D-0gq?@VV$?PF z_|vCZliqE<#zzCa_LRXswodHZc8=n{BG|XNUb%CWU9TqU1DxY*A9zpmuGCu}xWjcJ z(HGN)Dc7!RS`7yTenB0_0Q42%ud*tY;!DOh;J0Es%jONjo#HIC7t}?Fc+L2q_bmQl zJ=S3fH;f24^8Omy4+rP^6M87Cj94UVlTOUkUrz{S@KbZ@;9Td6X6@IU8TylGB2wFGoryC=vcJX!bq$=gs1wFax#lM){f`=bwNY0xqP=-5B5MV{7z9UEUd=0S6Ac z^M)wmEQ7V=T|#X3=QOQ9uZ~jmkB{PPd73_!K6{&{b>o^Y@7yLGUq9_OKi;Xbd4rAD zL=yEm1n7_{Y>hv-N>U*8w7@)HMkfjY#=oYBX zS0~=+HHewgG{G-TFezrLk-C|(|3WNmtp7DrHtc#W>-KyT%2w#jE!1T63}|7>eqQ*DC0{V5 z^&9y=GV+tt^sPbvND;iKDEod&{5dnWK;jW?yXSm~nt&_JavInt1Y41_O=mJP>P;&O zt=5$N3sbiAtTzqToX4%X_bY?7bZNI(0n)6ag_q&3$4OyZqtI`7Bx z%Do|s>zXVKX{|o78M^bAdq!U446VOKSIp2ADEExa`g}b$EVXuKGb>x^iJmj{=%^BO z%}ia11%fuu)U{YB=q)pK*Zh#y2yPG@q~C(#vwlF$uGR(et8QZ3-|7{EqJOI>4>Tp{K58YNc>y51;xt)QJo$p%6DjgpO0{cfo8o?I;4pER|bgoEup9nfvq`O|=7f(fQ#-zV_nz6EgP8;~LlfD^BQ2ypAe_~b8 zS(6At6BV=1;lb3a|MQ<+DHxBSRYUqa@8euEdJ?#tsJGX@`-v|a$~%<#Wg`8;0f?aH z=ZpeZHO=xKNHjLC>h9@2Id-!9&Am@X2e1%@F2O(kENOV!FV{47S4FozkkC9|T+>(? zz4d|aM&v=3gUEC8?bVgh+6Q`#kl}77g>!!izS^D4v$68FABJ-_u#l4vPFBe3+cs84 zZ~x)OVW{xt!N%^MhUoo2+}KEL3|J-X>v`#?`|tCT87?jH-Z*~^0w+Pg7uO8mlR&%& z^xGi)BbTZ7LLJ6)gS(8x(58TMg=XuDC+h|V+T^#Xn7y?vfSVSc=toSg1o{0ci)w+5 z@kAHyU$SX(KBkpU^U~0zt<*oSsiQQX&9qM650(1KtF(-%c1ugPc~`nWi=`8F^8D5WPt)0M7H9r`GyNlG=xiGkOn%-IU~#@D zWZPJr`QPyu4wIj4Lp0a`RMl1qId`|%98HNp{f88R0#2*Xb z-wEI^0Jk4+Sf76m(BB4b$1>@3ZnlB)>AP&lGU>c&*^XV}3j_QO!0p&2y(2*9clPZr znDoyD=&mlN7;)Qx0DIz&%TZEM0|k1)I1nBdCY9Ae<4%P=Q^7tIyC&;vrC!k zFFk5U6*nUi)YPw=v2}1)R7WXJ{FbH3c$~ODEt$TUTg+XFMV4NucnPGtL*fb zy`NcRUPh<6gA z9=(DO6IQ~Hg%IWKBSd+er&-<`#8J*WgpePL0HQqY4+Fe~`1z1a2>D4ult+IU;`DQ2 zdGv1~{xl)VJ4}f3-XKJIocCE?G3v(h_#2TdualEelw;(CMRv>@tk@9yDLjFEN$bU-kmk7%t zpOEqi%OD@?8s(P~LO$0y%C9Db{2GC%t_tDBCAKCiG+X?F0M8H{QSHA1(<^=yglNr& zCesjA({QQ4dVviBZxpy*V3)vzz>f(0l)%pm{IbA(0{>dzet|sOroK-J{H{QK&kNEy zK1n}D7&7;)5ufIn^tl2r61Z3($1(Xf6C&To1%FVW_74L63BmtfAiv|md>qfrr+;_= zIDea&>1PYPOd!82$@H~^c-jR2sK8GN)c!)?(|$sLPf7as3Gw_y@Ye+XMxegG1^gWM zhtPorI8kzu;dKsDCpOa(^KBKMDMqKs`@@o{K)s@^ybk=jHx@@@^1VNQlihy0A{i z5Yl*!;LU=!2%Z#ti{QHj-y`^Ag6|jndBI;4{4K%X5&S>1Usc*0AJ~H-=vOrie-&(k zwf_r-kbYl;scf8IRX^q}H;|VBQ(Kx})nt5C;A0+i4IRk$VTluGLd?>9*WWh}%4fst^W7)Jd?>9?)EQoiU>~<>lhB^0p$*JhUT24*ZAy#u^hi zX?%tSTE1`L!wYR{gXOyq35?tDJNqF=5-jaO;5M#FP^{2NpneQrz~k1VH>T8fq_G~T zx?hjKL>%3%A3%pf%o$iF{a{50{iW7V@^E008_-j47ApQ#U00;ZTuM-?D`v H)kgmhj;Z!- literal 0 HcmV?d00001 diff --git a/src/lib/install/arm/lib/libjson-c.a b/src/lib/install/arm/lib/libjson-c.a new file mode 100644 index 0000000000000000000000000000000000000000..476a0508ec4d7c5d1ec53f811d12e59bc9f808e7 GIT binary patch literal 164780 zcmd?S3wTwxr`md2Piw2So|cPIYwfA6w$j$h_xru`&faTp@U%YP z|NouudAZI_ny>Z(XiIld^mKOj2J!ahj7A8KywO|UG9zMkgpriR{zG>#)CdOH)Mv!}Patz&JP46IATQS3ClttZjD zv8y?a#uA-Cl#(@fw>7l4UDMp1CZC>tqIpAl7U}G?l&H3ZEoK^-2AqVf4q-J(aTQmf z)pHUK)irN8S(;4msH&#s_B3glxu&zTy}3baOXaBeWOT~6b)GhUkt#4@WI|;A(s=kKwRwzl@I@&ngv^4a!Yy0Z$yt26i zmdY3dR!^fXrlYg$cKngjJ92k3dUU#^jGAdetV!2%Ttd*&lXbzB%_oRiD#o}qojqDS zr$JchIykztv^T6xZ^JF!o$C@UZ5d4-;|Xae8)s6oHv3=)uoQGb*ReRnap;t~X>Uz* z^>!y(8+uwjjoTUk!p4$F$DCZl8r~!z)7yZaDYqdYS4xU>61AsMEFwNnrf=)OI3Li5 zO2TNH(%;_Md1YT$qPe5Dd*g}J4Vk1AjuEZ77cNUrXsIbF9YVWs7wKKo*CNG9BI}yh zHFR~c;Ri`;@H;Z=yDIU6>jgB-3=X0sM?<9<|eNqb6OUdm7OeFRq3epdD2*u zchd6C3QGxe;D+ALZqj9h;8Xz!)4$u?Z)TO9^3AF|d#25&KJSK$Yc4UyUe?fiNan>zj}IIzsNFgk ziEbSX#}S;2S1V~eZ|flPz=U()@a+CaUm>K9tm=Woe>r~qRq8MBw!h+e%dLF%z+;%m zJs&oAzHF+u9`T?jg!BdRy9cKquQ*)b-3=Yf5C8f2@gIboF6yp+^cCoRH5}iL{FWc~ z;@iJx%w6C2yn&ydhIA3oU!Pm{8&iMd5#PJ)u!sB&$`tA!I2`r7&w25kgIQM%9L_R# zy_^%@a)|l*lJ8E*mweL0v7Lin|CYg!xAJhI=RF**-#Umqj=p~5qpxg<4;-fM?5=@N z`CS8F${9Xz*z>jziqD{rK8rvPeUcMvJmj1HL!t4IfgdRo>DoH@0?Od@dEOz>YhnY3 z!%@-mszDy%*Z^$XZp#b(EZ>hXqlcexh0Ss}+BdtH)7t8zyFGmoBRXTLm=dZ5==Yl+lc3zA5!Ex{P7BYj6cz=(NS=R+=O`6sf>mu zdP9D|1Y@W%G%-A6F?nMx78&wY@`_Ip$pU0ST{+2kx3r($==8c@Kbh;PxP$Wi1l{ab?7*`+x&`>YpIbr(a6qAF$rqt8}>__M$dIqX- zv}9Py4DSYQM4M;ISpxdCXfOUy*{MuooLZ(GV`@p7DV`wr353vfp7~%>=S=GS3CLri zb0&3~I3TfHW^==ufj)5;MQ8 zNc09t9q3@TAd9JJB*JJu-I&EpI3MWnYRWC9%4>m+r2O>id&L{@98lfG*T>L)dI`Lve&jN2^1tPVKoP)@9h>W6Cw^T))fx=M> zfZt{D@YP;r3G*If*3*KOQYMyXI|BXqSh7efS)?6MXv?sYW%x4CQz z902ulrrAu^2Mi?!5U6kja<)GD02Tg<3fYRx2iV7sQz1pom&C&5R^c)?!-v;ejM;CU%lcvenS> z<6zY?vod>C{`*i*6SBN%BSXk-qD0__l6)}Hd#lJm>~Nmy!mEb_E#nt`k^q<56V^AY!~)f@+DbB&bISd+5@85Rr?w z1N2DB5-gDD3UqmIwTSVv&fB+HRXvn-Wn71QvZV7z4nHq9zA41bD?>~aDpn^H!~UJO;bcl!h7;{H36@5M3742lCcP4&+w_@|8U>|(DxBsS7tc6n=h zc`HlY)7yk)7sOE^h@2FfbJ zA%9eP*!b<6{rp9j__>QrMaA&xrlKZVRTv7RlDKA&NL#v=Rffif_V&(3FTpjUG_G4W z<0@RDrNfhj=Bs2)PL>~}h<2UbEu{6dLN?ad(bKlJqq!-@2c3Xaav|N5bww^=Bt^M2 z;$ba;3kU6;9cxdbL~EeC*&3WuoYKM!CH09a5?HVCXtyk3+w~RZBa%!9fzEYU4MI`j zC9x-!MdnU|E{V)vx-xcA4DGqRDp*izr^l>2ta7fO2J~g_A~bL4!r}*)f}6WLu)>!# zE2+!6RP55+D_T3(HCKG7t-1B;hK`D^_J)mXyF2?jnkt$)8?S8cZn?T*ZCh^z7emU> zaOYoi(K)fnE7$aO^!8QMv~@IecUsHKruPYPTICci3Z`yow8wE_+O%nC!4NNb(*nI7 z;liQOE#a;HO`$tXl1F-N29J7p@n%UK9J+XM$aw@|-q510**9g~9KOZBmAaff2Vce= z&haxEz&S=nfX|(RKMfpJJaamtSu<96*?z?2Vy0hcMw!umkvY|j37uxgOGuKs58}Bg1To*kY%Xy5Nl#d! z?_r)ExO{kr{$a4!a2FBidztvK4E{(DlR>%a@plBuKf$8%mwKx*aJs%8p%#JiX9Mm> zU_BGB0d)0DJOSKY)VJ0lfW$ixT)k7Ck9e-$iQf*~U6j8IVL;mf`GGOF(JN{2O47FN zxIV2zU7#DvI1s?yKo%gmVbF~`I!Fa1lH-~k45e$^aWWvJeHJ#;_F_1j{v=#MSctMH zd=PLP@OdawF`U^-c&eR@jKgy!ClKS%kuaP0LTFa(BO&}@4HJ%1h$LPJ?S7oX@q}nr zXDENV!gCbPRk%Rmr3x=oC^Kp3zf$pTg&P%aR(OlTuPA&<;d2UKQuwCA5XwWlPg59I zc&@@r6mlJoavvl_xz;FbA;e(NrTl9Y|FA*~DbqMyA?h_i12xZUnGS5V+wzw@L59WKdktxgb4pd zh-W+wNlceT2z;pGqZP&oAzPwwy3*$;yjbBP<-cEH7a{V!R`DAY-b0A|KB4^k75|*_ zzo+!46n|Rb%Y;bxn)3gw_}`RYh*>Q2JDm{rPE>dfA=1rNenMfd!n+kdq)_?;{;+>h z&n&G^bR{o@;f~`H>2bxY6t7XdR`Jz}*DJnB@qWd(DZX9t-HHz=?v?j!T!(EOz}{{P zTV1TXxxKuX`+?;$n<`(^)8mzsDDMQ=_W(5Bux3qn^LhyKje-QHXaT_nY?Z8SMq0~t zSV|LS+|7=Q%)N3}@W`#HFmKx1sUMpwgCZZbz2SUACmWp%?EAtm*4T z7XS3c`!8HB;}R3mzrn{6RFhm|@t1eIYQa2jHY#WV;vBb_o^q&mkLy~*(M;refk@zT z=vkmq{vXNF9+!q{sP8Avr~r@cBWPbg?2AGxFFSiFdW}A=y_XYe~es<-<5`k1N>oL*>CER zCVZ%D(2LzQSn%|cBc8X6`+#E#p1%D^_|PX`i~@4MEew8P{C44oczl;8#VhpiuBy6rnMVs^SXSKGPCaw8U4ZZL79Sh-4>=&L1CiWdq zg)FuaD+x?Cr%u>+ypZzAeMip2unN|AnZD{FteSA?xh;*FniS4fw8{KXC6TaxDpeZ`7?j4K8a{od}&sel1 zcNbBk=;YiorVJ@sn)@-LVIxzniSb-+Fy&;M=Kw+zt8#Ntz8t&d8k#semmM>wKsJCv z6X)b|ew{Paa99jYtj;}7bc8uy(0REpQq@SqstQfKB$w-MIfaHBPN9kO@d72#A|q3| zi3@T$<;WRtwux|U?kg0YVmR=HCa%i;J<+L(uFm~4(X$k-&;2{mQbn6`!_2qbOp>&% zx!)vOp*FYY-b>+W=1no9%M1Msk;r6j{N=oa6yaQNC*pbB7`C}%l*^w+H{6rc24X?Z zZu%<1xpK}Yt=qgv5wZKM*TRu}VxP9vAMvuopFo1_Fk49h8xPAognlQLxd}ClJcN2C zsCht!Qa1EaN?poUHOz3F4V4++ECxIJW6(ln%q3bXQEG_N@K71$v0rlz{`%cgcHi`o zO-a8yDd~5sWD_MfsU+vK(ee1>Z<44ax-OOII!Tlr{#PU#VIIX_Q-W-f2!T6-&m!%} zH;|Pnp?%nlEHqyrI!SV%SWHDnm}ijGoM}jiD{*uf>3;ykoT=$YnFB;i4Mp}M@G}1n zxl`8ltObMCg?4m}E^6q));0TOXh+kjV*tA#xs}q>?}hl73qTrMg+H@F8#@INw$S2! z{Mnw3XGOC-w4-Jmwo-R2$R3BS_G#m=qdp4{XLLIC>_sp$$Fu=G{e$=u+OeQ`7ibSj z>Qp+AMwuBb+_{En!id%bn%lCR)#s*JeV((LHT5(kU!e57MGzlzA4p^G!XM@|_Eto` zhDb3bY`&RR!(bNvH3%?cGdET6pMw@-!TsW6h}u%8>}GlSWIW15nQ(z&`X+=wfoSHV zl-A`7(u`jeG@cKzbC|d;2jVH?`AUZvUxP?7CH`CEDaDM<(vnB2u(JI zrb=_Re^~kw=?Ig|H(`mtO4_z5VVB7i`QO}pcKgj3PJ{c&k@WrKTt%@*&F$qpqKsA* zU`yKVbYrwJ#%@^;8ILXN3ap0=Jwx`chb8wcu|?~4qob)!W{fC7iPVnuh#)y_2X$mB zH6PFm%e~-^cTyCM?F1EWm;02|9x+vnE<)uLrM8MmJ2i7lcMLaw(bU`?aB*tOdt6{A z{Ip;?^k%nr9Al&yjv1fYg=RhzQs@QP=f#71&}zH!TVme>m=xr2>ljvZ=;9+7w?hf% z*m#t1o{bk0aXyb*1?B_wFID~Nh z3u*~CRs@YAd$!Q75@rp zF5L#4Xv`LK)5x3SrTFLPE%G;RW-J^!EA0FK=G}*Vy!n4zI<*qS(#lHE&gItL{1$BT zwQWXh%)>!uIhiZST)i19X~rZHcul+s+gSGP=}K?C{`w@*+1`}sY-!;(oBKsdV&SEU zo`&^&4YlKUkKYc5Xh8`|B+MtvdPwFlkBv|Db;y~5;{rI>(X+Cssd-29~e z;I3fGIpT>#Uk84k(^Q%AfcQ+E#R^CyoMW+Jc_mQH=$v_c9o|)>{Hh?4=xS)11|b0G zB$#eNl?5{ZwC+XSNj7K`iI#OI+jC7>Zp}ignOTJ<^`3Se6KpMPhbRJmFd?l1tB!bC zUEG0c1vTy0Qi*k)P0cCySg$3})KC(`G)r?^64LY zSw3%54ktgR80DF^G=P&&AKJ_EcRN(|(|`7|{I?ydeEKfPU!8$FE^nJ>E5aM70bT*f zxWkn#;Q#x*;2}ZvSSuVR{z&;R6{8^chJ)9Md&eW7!CsW)UMhXhxWlI)9t+@jB22bf z%2xw-7t?Uf+g-%Dw(TzBO$d7t>JgZJ9iY3&XJ2q_S@w3_m~8iTF=B8mOx`cJZJR^_ zqa@^XTu2)QGsajQ10ZaF5T!R8;PSgnwl%y!BR(NyyCd8LSUl15b`qA@_X9~EARiB4 zoHdgECL!e5-pEIBz0jF<0!RJ|;N-KtkzcQTJaBm-EJ{oMSZtE@4?wO{hXCoV7g^w%b z-V*7>3i&Wje1^hmg-aAB6n;qI)e1kXaHqmO3csxI8-&R7QH4KH`Y#l|sPtD9{!!_F zQT*=;`D=IDcdEh|A@r6goJ@EMR{9mcOyP%=-lK4X((hCFX@y@^_+vuk^K-?YSNJPJ z=#OOCd6qYOfQiaPEHY&eE@oj|2=Pt!RrtlMl$me^CKdJCPmHv{#-zvQT z9hQEOSL*>|#F73ir7s{vJ}U@OhW9DntoVl%zgpo|g?B3aib4P{RA|R$=J!FiUqFz& z5C(285lDR~K3VZ9#b+x%PjML!kiJ#%cI9tVe7oZRNB6b=M|ZNZ7=kjxt!aDN!AE3N zpIl?{mvfJ5!EkTD;Jg8G)&C%u#xo6oh z^m4p7@SuHrVP6rH&^|QVq;2ao`OF5kNRLjQXlW# zOhf10puQJL@!sr z1Hgmjcn0OD2aV;Rf1F>wggDHmd*pf(`ldPr(B(yQ0>$&H#(3U$P9jJ7K(%`@Y)o$l zfpZS_3FgcEXKO8rCg^aY`e32jl>1AKX56?p^ zybyn~Or)Juvj~5&Q_u!LF&TTY1(a=fTTi<1UH)#Xz`k4P4%-#!tkh4kvQt0Fvhz^n zWottslCO>7my(EtJWMc8T)uNZw$^WqlsDQmx+s-z3fl_tBOznn(=&d?udN%?)<4pj zsjrwMf1Pa?H{Q!bH~su>&)noO@N)6FQ-J&rJ@@jxj?`tOAEm}~gJ++Vz3i>*XYAwl za=pl6e2yePb=eN!a6fssvXuA!jxh$oz{TfE=EweSuT+fqKl5Da`V{Me&v9&(u3qH1 zF1>xALD~nrbaF-oYQmI!H!wx|A9x$^Cj8U4ZP*Y%{JLmm=4DjP>Eo4Xv3HV5_X zg929{!8uev!`@x8TM!(QMlw-NRf`GXUi!Ijz==*2pP)|d__go@CXA@!2^j;ubtKfLV zz(P=qImz20`D#?%M9Qf9((xC->X5rnQ4!J|N4C7Svzp_ksYvW0O|Vi z4U#T=i==+;kt}@MBM09V$%+je#u$@ls{cG_YHvC+#9MI`bJ^Pp04JiVBhh(Bu-$ny z=6N4K9W>Z+*>Yn$bw;hVWChd@ zC-Xac{P>uxfDX!1kM$+KZ*t3{uT&r}RC(TNK-6{K1i)V*-Mi%-0Ux)MygWd(BfQ|S z;wZ+`yj(z*kL5WHkb1@gQf~<$^LZ9}X~S;#H59XT`V;t%v~2;}zbkE1fcAva+5@!5 zl(srR`=^ZBBr8Kxupj)7kPx&{)@#5n!|Q%K||56ZTi$H?Xwf#SpsC&Z=rr z-_@w^diXnvZ@8cw^lee}p26bSJ%hxr22M!6^LrQCYL)6Jsl~T#m|oMe?NS!+W*!d5 zY#OF#ns;lzb76Opd?N?8;F~+B$1xF<3;DeoR#=VvW+U8)wh@Exz33tKsaIdWwCpzr zKecDDc>ngnqWK6Jah2a8`^9gWn3)-`bW z{m3sg_lHL*8-}bGJ9M;bnr)Ai!<bV|a1;WyXr5@|p z-#>7e?;=ZkMg9i5w`0r*!%n6R4U9dq5@qtdl`Xgt!&lVzh;9GB{ki&czv8s_O_do?+UqK_Q}JLvgKQs2!}deH9EVu0aFp!~_b9}f zFXNcMjadOc-{*e)QvHS%=(9D={m6&$AfLMN4*8hhf!B(9z<0cGuOAbWZ&k?{kyjG6 z-@&5IVbJ+4F0_lI_Fifs%J`}qcd!a$%k1qOboW%+5SBW?I2Nxxgw?nszPJAnZ86?e z$a`QqA|k;gRE!PFVf@wv2`$p5UJfd zs-%AFs94ulPGRzn@tzO6vr+&4ANG69e3WS(xN$1)UVL$RWQ5h$su27#xzwmeaO*gc~ zycouq80?RNUf^y0jR#r&hJkvEpp*6Q=1-}j)E-5>8GLgMe2fF$b~OEgk*rIpJCuua zA=aBgy@`z|uk9bUtk5N8<@eO+bB+N;)ptw2*)fa*Q9BMCtG0ba=T;a?mhnC?(u;3K zJ=aQ~b9UIa7UX06flV$ge|I6j@n9Xr@cWMV1Z}gQl>X+y4kzo{HQW3e`U`nQ;(JCF zRrimIpg*O20y^q5g1IN{V4up;Hitg->I)cwUPK6^a-RWYcpRY^{y}TRYw80dkrwp@ zn>2rc(SG!m9j~zN*{0}2<8?`&5q@m@U@`LZ<9DJj4ERouv)hNhD%u^dJwm^*P9Hy= zKHf4|9NmI@(w0HUB=@hr+w?HV=#vRv#Fsj_WPD;vH`C}jhbc@};882tQ4 z;#!9+%YOxM{vODcBc$bc@}DRN(}YlF@hkch#)3S~IfxfV@p~ckn<#w1K1&**9Sc|v z&wHKY4%(9RfqJwH%t0oIKki9uw^)aI^-V0bMR21iM0f#lhD`{PH*|RLuh)e>8om8U zk#~+heUtuH^ydmrb2TVbQy2b&5Awta&fI4e>uOmHHg3H&m2ejd$nwig@_{^`icFW8{40| zr@Aqk{TJg6lG!nuV+6`@v{Y@Qz9QIF1pA6S%sm2SrTe=#?OBQ zW!|}6=bi8qeTFgY@a*8cv;Wj17oyE*n>rfqg3SKhBW7UB5jUkeH8e^Nn+$w}J zuwL@u%coE-H!qa-0G~l9FLLm%LAHgw80L#{J745CM{$qBebtRuD-L6q=5u&Ind6P< z+!uB2b=A?sO52sBeSpuzB6q9OFu#12w(uF1`D1kP#VjZ9y zjQgPT*)%x!tIohFSFC!!uK5%w{u|)iQAKV($hl!Z!Y+iJ2wX}zfH0}Oy$Qfuy#}EJ zp&J3ht6LBzAgo5f!`JG*czjahq(;hu?DclzgU`5H8rpjpS=iCS&pK};tt@~{DxWrM zEoj#wpun=076Y7cP7DFx(dcV$2kOPH!zUO4KfpK^3Gv^HPph0>HDl(i*=IMbX~Y}N zb1%GT-o=*$>E&mYHDB!g*F?956*lc~oH+pRehD)~UbDHvjw=)i{}4B`P$Y-1hWOV( zB>XeJ=Nt;-Cw2fPayJYNg>tT?SU4w6%w#tc3uTSM4N8BN7>Z;K!SLnp!=J2KolxN~ zhEUd)ZK5r!8lwI@bn>jN>#hDXp^868{8yp|KQqJH?NZQoW&hzyG}g!>0C^{$iLK-;K+$bfh&Yex0Mwl8w=jG01K}X6DbNCxX zbW$(7(0oNS&(9stv_G>XcS+jX++VQ>Q_TH>uFB=FX0xX%x;pnYqGu^u zpZf;UQbn6`|4Ou6enu6V*qWO~pH`^N?YT>7aF4k#p$1Pg{TR=Y`!!kR4{n%V%R?aSHB3gj6;Kq5jfQ`SZfVK!#8@ zJ4`ix0{U|vm*`Gpobx?4!0d1Y84VSy$00T>`3J0tAVfpq@CLw~U()c%=rxEB=j-2* zq6d(k&F*egR^(J`YB=&Ryb>AX4A1#IgbH%!-OFTGHgEKDFVSSf@#%LjcfNcUV`4aR z8?4J+@BtVWni%nNF#Yf*=Zzva@+s)g8~qF19hlp4VnwGS7kte((ur1;ck1baMIxLd z=V{&r!xLR=yu7hLm2}bJo%n3$w@`-A#G(lIEb`7|^9@amMOdV~$+iiUpxCrEhn+u~ ze?AQwex;Xxp=Eo+*L(Sw&_~RC7&6aaq&7!Bz*<;pu>z*KtdqRRUg*oe!a0yHMCGqh2SzSOk@DACtRRw4tleVKh)?V)ixo!x2L1W# zEmjoyGqG#gAVL$1BXzX2-`W<7{F>=*vRFx^fs(gaY;xpbxHo^>5^+>%1VfIOfBSO5 z;*sx?cZa;tHL(i6^F;xp1*12!K<|TK!Kv#-(2FdD$^xwi+ae0aTEileK|%2*ku30h zR&;J1UG6^$TJ9>o?=ZrA7Jr8^gJJi>cb?x0JokzN_-orLYt`~4M&-l!2Y%x-TDfr_R?gPaX-ho~jDlCIr{KDy|n{eR{FtZ9r!TxN!Pmw=uEE0?`XX5WL zy2bN%<8S_qN)Uz`?u%VW7F&Vm=OSVL+3ZBwVdj<{X1eS!Mf_hN&w^2W<86eYZ){<* z!z@#FI6;v|5X~ETyNKLN5f<7T70H{x#yXrIHOZU!07z*2!})c!yb_iZ&Cfff8xoPc zV%}3mUxlpl#x)@E=-)huJ{0!<#|M4zn7v!?)va(FY-JzG`HoFzbMviX9tLXz;1%YUXQ(buk9_eb0Pd zs>f4?r)X z9f(dx^t2hsICLIc`|0>}^cvW1?vYf6WA-?)^d9l-cr%IItBj#5%t$!M7UU`^2=crG zp7bkal=sa7@K0NU68e?*Gov5Eb$%tQ{xtqt*RN#u-h?wCW)4^lz_||2%X|#g_FA=6v*crsnOM70$A6ViSYy%>DI|B8+ znAG=zIPh)IOW8X9Q(DJ33|-~YrhX+gx{$cEt6vNLA>dQDF}o*Y;>Rr1i#WpOd)7jF zVuEj&--8GrK>{-c^=LgY!KWua58{*oa9@r=9mUc-G2vd+o~f4%$s9mSdy;zm0@MnP zt!LZ+4M>yOWljA9kjjD7WcFE8-wJdR&^UjmWn^@p4RjiR6=~5=lH2H+#)~1!PYzTT zgZH->CZw>HRRX6~&IXO;{E^V=vi!-AcFcNB!1W17E&PkJq1SF!cka}0ANx&P)oJ&;V`ZS4XK!P5ij)63Z!hl4LO7PB;va~25 zQLhp&rb!g1BqniVnz^LX194V*)4#)-{c=dEb^xL;B5*i2_oFbjiF{ew`D75KT|N|I zU0(v!w#x${)@~E==MllollV=*D<6TfCu5#>4RpcDp+3nM9klW(aM%cWL(={>={c27 zlk}?0AK-X%l{Jy(@mnbWf?(!hEybF6m6-T%Ac~3IV&cm{t%==YQWhGzHPPZ{0H5&& z%ik;f`M@iWA%k(_F$h674eLY0Er23*Ax4*!c^s$Cx*ZA7H4LqaBQ!&c`Eb&*dg;_R zfjFfE+?h~4m11fAYvx%PKS*7Lz(HX=R*Yty2jXXtaMnUZ9%p0)BDpYlRy`sYAu^i@ ztB{BnZbn&1cQ(cGl!zF`&Ss*sscUL2^JRTVgP#ovTvHdMQL8~hx$WRFlQ%lr)QUj6 z`e@g+AU4s8n-RGQk+bilcFLGVDBl@oc^1aJX(ecKIIV&H$~|s%*5U`xpFy>o>9#tV zrUn}R1;KoOn5)j|Qk`sOQk_*&oo@oQ)j30|YXk;1Tb(lnpAH;9#BK4+>=0G?JD$1z zJbWl)cIW|=iIceVu5#EOU^6&XH)l)QF9ScH_vHuS<`)snC80LxnDqo`e*kmVqln}p z%=$9^oQ5#z1&Cc`iyMmcvwPtVhT|y^nTm_=Ceu^r|tX_i-lC>}1Ad(D2J*285o9%P~8Sr3;BUIKi^1N2T@@C%7gz{q2! z89qha3H*G{I5r?tE@$D;jBbp0v$DY$3ZuO9*`W4=^EkP4%{|~s>p7ck>1?(vud)lg zC*hKZz?7ES3aaxL6S8;wyJf;hj`Or8d(|bY3M6|DOm^#cgjpN98u`2e8pog_JnXPi zu1>0YTUC_`N2U}P6r&X^6?}QdW#m&?QyYEAv*z>xlftDcFbVP17Oluf3-}1M@_amtNLlMWGE;?lMp9w3ut{o zwa#$NfYzz6yQGrrRwVPhxn?bU^&Qfx*xY6#$bbP27s{0D4m;)ZF5+B?>{}7eV@v%3 zWM;h#>$X3Fn%b>^eU(#Ggj07c}MP zlPQ11lnao^TWCJYf;?*|bPzeVQPogP7Hl5RGWucACSF3nJ;x=12Z+kd^cO5X7g#2) zr?JoT(Vsg{7l(m5C*q+8hE$oMbY-3~e4JoTak_(+-iR#h=#eM&JRU?lJmg8~R|21M z2q~UIN4ww{B3B~??glcbEi-Y=X-X6t4{_vLWX@$~#Wpi$G#i25`+hR7V##YKbWbJI z6pBv!xL_-=%5WBBT5u1ByC~F;@D-YT<|xlQPnut=Fn3n#0J_;^4Eb*&6tY466++fqnQYSSkmXHz z3N+Sovza@ zKAEN!T9EK4Z}XophR@oh^D{h5xGkCR6Os@|255OdA>~~FynF=`Au(m!fX`=Qb0ZaJ zhgo@5W+K(^)T#t`HNtHWHOG_scZ&Y6CiU+W{m%lgd4Z|#5q_w9)1+D?W`S7v9qkye zIIV#XY`ZBlO(>lCf-%gb34!IP!OpC$w=amEW66BJAo-k%0d*>c&0cY<=%nRbEHK}; zmXp5?;T#B?k5MC@k-jZHdp}5Xq)C29^y4YG7m{p{Y;V&%Z;AO9{r!aXG1c%pJsYU% z`$^-Tki@${MAmPzt-olqrtAuYahMR8LOd&!;;ZQ|n%6>}cOFQ#H@qaNKLC7EDP&#d z)0z1ps5HMbl7fofM%YMYJya%^|4x$M4`R&@v^?{B!!?%Bj@B9Su>ZOYX~nqJPI?fD zzia&j=hD^)eO?$64OATm&eLGbx760c5S4X-WZiU%Oa|emC?wM?J(nII7n01W=5d5w zR5cWDEm=#)N#e&robfFC*6E^rA#RA1ZiRHZX+NjiS6kDl>li{CM9urCuZg@#D8q+A zvZj5|nf4qcooSUUC4a7LTC6InnT=NTC8|26s#-+Ve}Gilgh%3*5XXeS0M+42G>^vp zt}=|IEYNol&d9F4D_nP1IO`4nPu?W2vJgCW`Ja)ePb-r_<1K{KaC8So@OWz@w)ZbF z6+q4PA;aR(v|6+y-t0~N80Wd`#exP9XLL}yUkv^{@S4k5xEp0!9on&aNd<6JxE|5Ki^sDHCpM_eXVb&bbJ`3ioX^1?+$Qg+I7?DXYK=hP}G{(*3*CSyi zKaR_yT#MwkD3hpkmPq0m6aHL;N0OR?(+GMZY*4#^ub z)Y;K&ky*pR^(FgY#l+RB;O(S>mqbAYlEF<6gdjfImySr$euP@E%rYz=SVv5i#i1?` zD{H`I5zYsbMVNt`CKK2q*!IOze4FDzrEj>rN{zb_Sc)5w&X%H5l-@xj%1i<(&3V3| z*j^R=QBw3g5&a@W%YVx0&v||bb^A2%sT4M?lDm$;i_CwrL>Kxp86p2cRhTo*<$a+j z`~wusC)3;r1u*(Mv|_$ZNcsUyxGI@&z9byMd%E1SEj}IiR0^AW(=CZ$U^6vVA^DG} z!h=bLHKK3@70U5_HGV5h=}Ts?MELhG112_Kl?-_J-7>w8(eO9f6PMXKq}bz{&+yY+ ziI<6J8vM ziIR;IK1Rtd$TA_B+mv~ZW3~sF1IoPIF?&<(oS`;IWFd$8IUDFrNY| zGFN)Od6{$y4`WWJQw{Phz}MLRMh-_Ne2(R6s-A39@cxlXVRzE%%u2`&yUoZBx8cH_ z=!3eo=q35TGP2k;jQc21_vr}Kop04~RmiGqrHbSqZ>6~&mPEa~AZ$gsv@`4hN}Zn+ zm6$bsrFjcxM!k=7JfWE3ijUY~t-Q?CvdbE*K3$K(M&=pACoAi#%MHIW5jjm3cgzZN zZ2|0l!tVU=DZ*ODoQ8476Q%f-fyC?bykU5wmD1U*zB=;})b#Lo!qyHxQ&@kjFuUM_ z{FiNk_>^E%u|{3eqo|GivG!?0=KI!db!Gw?Av@ER33V#RVcasr2MRw$n@-iVoUo-t zVDVQ7h_phBz!x;0j!<(dVGFV2WjO{I*PKW+L%Eb2HVR zVat%>qWmX0A2jv*bKiYHm8X1$Q$I#`=YzUmuD`cWv^u4zMfX+K0{2zcA@(=$LsMsr z;$%?f9z6pk9geTN>H(d6P#oco936=dAqI{dEu4&xz!qcfIclUy9YlJ{=rp0xsqe^Q z#ZQmvlp`-=azf^*`UzG!{1o3-m6JII8JiNeqB!I;_=Q*Z71{KIK2?Jpp?W%=Y`lyE zKCPH!HSf=jKfspf$~6b zTIy4@OjqfON1fA8P~v=46|_S$aJ(6+QB9s%uE(TSyW?DExv%NY4jj3f#SG6T2M_f2 zq}6jz%wErGoug%77HG5Q1yGdX{J__EMePN)P|Tq^;C142lLe8}WYb)FVW94i%SFk8 zxRTBb*pH#)Vyhbqr76SH6wZeLYG12-fz}wC2GlPMT9VcV79}~-e$!Mg4)W4c)dZ>m z>X!rsU5%+bm(t(##-*ADCfV;2<5XB_RYIVZb?IvCr;3*)iEyGNEl-kQvn8!alEl@P zxH3h&rFv-UaNNu6r#;Rr;5oRszodWZgQQh9W$>)r_ob9sO&rN_;b!FFlfVLJ+c<7$ zsS9&84~Lf$kR3QAmgpP=rY2lrfCj#9;_@Ip^-9i3t1h|8M?0`Fn?nhv1!U4?!blL*uiIDwRLr10f< zI*@Rajh7H|bKUo@djf6RUKHMj0B;hIpPn5Bwu?X=0R@crzF_j5!d*t-lBdect@y=H71T1H?E-%%4Z+_INDwvpd@ zB#X5lsdy(KEQS7%H*L=xK=}YA;u{d>TLPrJB2u2)_%^rHap^mugL<;CLb39$FrzVu z<$9Oj6~64QFi1qJ5LANE*$5Fzhybx$5dvw5GG|Rge=uW3T}k=Q$VuzP$){Ha-yoQS zz}hF|#y{f8agBVw-hvt@=$GgUf~}THz(j$%SOxUNG|oT@e?$`067X$-bdyNgjzE(L z`8Gh%B=Wgb0+R^H4rEUBfaMZAj$qX@_Jm~+@J)gAd`WrE3J~xOfph^cy%7a?B&KsU*tKoOLY;5kbr zc)?PgY1DDdatYo>NG~}lrFe{kQUd;p%nC48Wf=rq2|6+5ED@+9a001YI8|GLWkG?| zZIwypAV{SGR@-=(knaY7o@|tqy%Yg<5|Ev4PD-FID3CITN$RZz0=_Gdu7LuLB2Y)* z1X3DEX+@yDgnUN;@nj<;zY7625|ABeghY2DFf}3H7zm~&{|N-7CU^$H+Q-;)mO=1B zlEK&^%OH3$$zbd?%OKzn_^m3&`2IEWAfO59J|HEAKqCqHCPL6i@+Tue0Rh>8BJ!n% z8p|cH+~uw<5?zHr-Gucv9wvO-#*@`e*)9aS5@4r9mk|sgSeqI9yk!u)m}D^avSkpw zmSiyYrezQ?)AZuEf@1Spp3=TNrEhskL$X-Z!tW!pScH5f0`X)~$miP^*`9rgfN{!X zdwiRqG&%Dkjc+Sa4CQMpfEoip47S>kXbP9>YFK^5ZZMDkJ)(AG2}mu;2gs^WvpW+ zB^^WB+X!?FA>W(`I)i*4G^dAg%A8COd3YjsB7s4i?|VdrTT4I%ftF2l4gzf;CCjzwueA6O53sUx50fGZ36?jMl>Ij@b zDhpD+E&{a#k07LHL4j|IKplY-NY`KmmIVb;lLaO@C>m-B9!E&ef&!0;KplY-NM%9F z69}v*!l!M#gphAsfF5_XPT3a_P-z5Y2U<0`hlE>4@Ulc}30^?IK-VJptwd`H#)6ymcK55>{Cnvr5zSlDd93@^raM$bb*P95~3|A}MzD*Af5D{#tQ#oETkvc~Sto}P+^?saAOv~k~tGMo(7+_0vtqN;pW zMR|GZ|A`W99gXdMP0bZJN6oX}mDW$IHqx&=kSulPUw2!_+Ud!Y{!VrPVBpk0cPt

Ky${_SD-laYsSC?8od+#kHYeB_ql{&z!*EcuaZ%BT6o<$gnXbKDDsO?>TQ|CFCE zUfWtx>Nnr#pH}X#S>#VBU)$=mDu$QEqy9_Rx17=%_3sRo*ZCV4m9N9GiZccxPvT(2 zm$lHQ! z3omK~^2cjipy9aR;*VYA|LnS-w=BJ+vckV$(c+r8|E(L!{c9ffdlvbp-?#Rg6*$$g zVu^p{!!!L2<;X2m!#|}Go3YrxW;5J1WV64ng?xYXq9u=3lufHx=qJkk(>G6>?{6&k zzk7XT`^bv6X%#h#%PQdBTgv>ug%=eL_aE7$Rr6caNzInhD@VpFW)|Ye$gS~9&syxq z$}1}T`tl|IsK~0tQv?6}*w5j@X>IX8!3^VXXxTE~&o94}wfm%pT3uWL_D!D}iPFR? z%coDdwBk~<0RNgr-=R5q(hTzPw`R$eDB3lPs{Ct=-&wwRZQMVlg<7Iw7YeduWLZT; zq<(AMUthlTb^nxyMSJtKw#uoM@roK8eVJeG4}Cc9U%BYJ1538n_!}1a!%(eAwYXy8 zv?XYd6@Ff1Rm~-|H2c2n1^xa0*)1YaLje?V>B5S#Hb1&KUW(H)k=d5E`A9a?AKId6 zS}*ml*!*#v#)*nM?P3442pnU}xVZHus|qc?0*7oKzJ?8BPu8Mj{8L%wYvVVKT-+Wl zoj)Tk9>GzZn!LukXc~%KsbM-Gga7Fp%3GGqpH?9r9xCnJ?_dKk{)mT9*LZjG>Q-q9ZZ^dbuz1 z+LU(krksD-)7#M9>kcGs-hiR}+P#m~~Em>qrV z)->bb(AEYXQ3_89)w(N9T}SiP3F{wxb0K-CDeA+XNU8pLPlsqE6SsGE@_0azs$>6Rv%H}qPz)D7ME?!q1$6Yf{d>(hi-KnfO$Wu!WR7tku@2nwqSXi4@6 zSmCucZ_w(+E!3U+nLPV8fumWwdE`Rc2_`M=oej`|(`<2&Z(BzK-`VJpmfj*Ks;;yC zNw9Hwjh%fN?xqXgr3Gm}WI8ytul=N6Wlw0{5IFcYtrMgi;5E7mlTx@ont9-=>njNe z^z`Cj-gbO*ETPAw2HnSe0|vT7fP1@pJ9$PeSWSIh9vYXN35(Xtc?&ypD^B%oY;9|A z>PEQ&8gaA-jgeD-<#1LU;V2UnnRDT2Sn1G#1i{1{3^F@ps_d>`pU{Ukz)~J=8_;Sy z5Y0Y;s^$cRGkO+^7syoxDc2R7dm0-s5<*9sURM8_&d&DchBRk5*QV>|h;By^9jIJ; zv~3H+5(XQ0Ie6p=f7>ipl7bJP#PqRVa6c{nX+t+4;5!O?K9QCfeh(%L#Od~l@Dv$x$a;j#0iWx$#d zCwa;I|A~{FT@OPmX+{?9^jxZhCuzMh(x#u19CSciPl64{R#%#RwgRP)G|<(7B<{k^ zv6=l5Jt$)+bk&$x*SwB5iR2C04l}{LZ4M1hm}sy9lkHQc9;!Vk@BEZmC-yw+WE;>y z-)hh7Tx>Fwbh7|-LL5cSK|ImY(AMrr*GpCByWLST)oPzjbD*;WZauaRT9+JB8qJ=lMre|U++6^)?)wCp;X|Q=^6vwvsy}dy9Dg3L*hwa2N?e&{JzGa+ zLsweH&5Q#?@<{_MfS;a13n61`>vUN|(eHG~6w9i23;&t=lN$`_<#n?Qm&^miIqX}*H~BXQ zd3+@=p22f@7GmWln5VOiZ>mj38i#XDk;{Cf@#33ZFN#eiTXS!U+?;bu_N`eT4&UZ~ z1UWAlDzBK8SW$Vc>bZB5oi{Y@@+iUjBkgjw%?4fz-1*nZah;N@p-zr3s+_D0`#=wt zfiIp=2W5HjZI2fL=M62|lD#$Srtr=FEkVEW-Ha~q;nOYQt^Q5qIUD%m1=vX&W&>X! zvbK#lxqi@@pUZPM@Kqw0o~M)Ndk56(aJ~yL2e>OMckAib3x|g9Ffh!?aSuLd54Y4O zi(Gn}Q(Hi>%Jj=X}O}!6Iotg{fMaH#Fwba+j_qBdz1@2Cv@olKlc%$;It1`pDrWSl4Er zt{m0CtAS^>zkZc->2?FB?;XB31LrnTkk37xAkGaK;;z4NPonp~=`VAqK=^;;?8qz+ zrUfp0RwN0t5kgqGodC!>wwJ+={w-@L`6BrS1lFI^w+(T7+4O9` z4&R6fahLv1#2-Z9czKrRSHj>}BocJC_ch26^HfPo4bRctg?gnIFed zhcAbm8!su(GvC~J>C(?;byT%Kc>@AY{)!Af z-xP8B$bU0{Gk=a<_Oj{Y7_S^oKF2SIGksG4Cx24_C%-1S-)8OS_+~Gwe`f$^dX8~H z{+j`ue2#NLelLk~S^XT(9M1fUllzM{KgZ=8*};ovyHY-NB^#oUd@tD$6;D>Q;>n6r zJn2ZqlZGpvG*t1Vp^A?bd)T+^JKs7jb@c)XmSB{;UlBl^J+-240(iCo=Gk4E(wbd}{`N zR|dW}1OF;;H&3Iz{|4O6(}@2ZxSMwoe-*f!cM(4h+|9d);~*6oKj=f^X9t=X{lk52 zcM<1j>fPLn@?F5)+>7`v8S)JnoprW7 zj0f)KY~-Jt!Cwm8&Ed%B=QrKljW~bq;4YST8*n$5BcH!xa2NRx0e5pc@_z{2&E<&m zqxJ5h{AB7 z?##eH1>DW|nEvY-{3kQ;r-8fqALU;L?&f^N`Ab}PF~8glJPO>+11ZnXfxCGi@e6@h zW7w%iTH>oR(ys;1@sslp@~;E#=7Yp{X2|aa?&gQ&^DFA^qJ8`!hMO;vj{{$l7x`}j zck@T`hX#gN^2Y;r^GWj0&EPLpoXui5#`7zHGw$%<)4e_TI{5g_hwPHf^@|ht-}EUx zeX%sC2TKN-i)KN#U3>_xgS^X1w&swro)c7+S};iN4l3zg7F6xhSUFY{d&{Q(U?C)EYx)vNkYkf&=*`>&J7H~57H-@kWnd>XV{PYTt7*Z^orcUBgY&sf z1gq`-faIUK+?q(pgG!>Qaa~s**LqSYHgbdL+FrM2m9c`$jh(bL(I8=MUqg3hgG^s9 zoDt;14TEp!?*AQHm=^Mf+)6)vAWL?oq z+p7*{Mc=sP>0qmAzA8=If47Rwb;@MY%C>7xNSIv63~nc68UZ2MWYBh8*?v+z8H=B^ zUY8^@_34r{w(PZQv{!O3)2eR^#My%~wqsdZw``lad5wzZu4ra+n!uA3E?4P9$+yRL}~%Y;T6|< z;()!1-%5y=Ot%4sF2-Dg{8e^+tQbGct-_S982r_Qz;`O-a|rQc3JWj~CmvH+rI6>$ zlfGJEmqMHLrqwFCA=8(KZWxYwgb}srxZRz2)mCdUW0j>)Puq= z*N9lID&XTjgl8PmJMG#~XcX1}fm7cm!tu~gemCAjCqy}3AjHeEuLF)l=ira@#;u1w zEGdk`0%8qd@zv-*#IHsB1f(5YJ7RhED?Fg^>k1!Hcu?V+fW`QI64#Viu6+o_oAJy} z*pG5x$%1sQ8By;lg{u|TD{NBOs&FeH_3S6yYS)zLFAr-$#W&+wj1c83A#B4l7hnjB zqg90X4F}hdm|v^Hc7Bm$qif5v6>tH9JjqXOh0*1ibK#2CTi7@8L zFEqyOf?t7;`#AhTh(V3Nh8Ty>mmMS=fWHCRUrO?lRpD-h4=Q{G zkp1hJ!Z4PMC|{_MYh7%IF@+@xCoAM9^~sMbtWt=Yvi(vax~msjVD|t*OZaRB91u-e z;HiYDFEnX^XwqJ&#_m5*u0rMHJ^*~K;!r8+FI9-D7yJr^7@`D6*ARHMLNqPGKdNx2 z!cQsOukb4hzoYQS3jb5#Zx#MUVUDqSM=6}Bkn7Sc#{~+PD&$8MNpDwptwOFNlYXzl zeG0#(@ZS{vOd;=Ilz&4ZeMx+{!kEGeh4Kpo@Rumg`_i^97V@&Fdfe@WrD75=-zUn=~K!nYJ=W!ZEi6^>U}q40c#T<@WNezk(IMPaYP zEeh{Y_&J5oD||`eYYP9UkoQgMdq-gy9g29K!r=-hE4)Zyy}~UDzpe0x3V*H;2mOjZ z-e0NrErlW8AAy%DT&b`@VTZz76yBxqQwpC{_^iS|DdY)t)O)7FN`>bsT&R$HEpp#b zxSDVw{Hpve#WyQ|m(uqr{uzZ25F*_-6>?98dY@GIOG4OlRPmP;{+1Bwyj%;j2$7D* zpAe2GM7k-8mnpoMa3Q|wO9=i-#oteebnBG9QSs{(-c7g=^ACleB}DoIiho1##}$8) z5c-}ayci$uRz6S7BmEBw|3tVD?S=Pkz+r^o7b%=dhxD1N8H&!`-KIm~olQTQ!|-zP+VKO|g?`KQ9ymHrMP z>Lr`=AIKFF0zX6XsS3{}g#LL7mnwZd;S!uKsQAqaZzF{K9)({}_z)rFzoqzNivLJ) z{{ENg{;Ke}^7DpSI)C3wJ4Y)#Q|WPqXDd8k`TvW!cY%+xINQdbXP@0%k$^sPekum$pe zPv|Fv{)N!52z^lKW}&|l?1s5D<@O^&&Tyf}3O!Ni=|q&hXc#$KwAtBIJH1{)xRb|5-%v_Y&+&1YedQHzj5G zIKj(_NN0x7a|A1ihh$^$5pS^2=L!xdLjEO!6N%uvTIktC=zEReGQl-O@ZBTyeS$wCLf&qn z-ynkTJ)!>~_#qK|Cj~zj|70vUm|kDvAe6h%VZjMR#G6cn+ye3E&i;%yU&5CP-YU3J z@LnR~JtFjDLO&(+(?rO5P4I2OHo;Rw#P?$@PQHNPP$Kj?Pw4ZB;F}=yB*ANl;9DwK zO9bDoLa!!5?iTTn2)#paClT>q5PVDUT_WVP5E0+*tLY>n=x&1N5E1`;!Exe$6%p~j zE%bK<7ZJhVAh=%qA0mSPaiO0Se2NJEmj&M-g6};E|AXL%5`IFEFHA9>j|hGH5D{;% z(B}#cCxY)1!HGoh%@X{s_%9|xPJ{Tb68bj5JBX08P4Fk;zmEucZwh@t@E{TVe-`|N z2)-|c{+fvNf>zoD*oRgg1=no>jbNb;9o7cS@2Q8Cy0>$vf%rI zZN#~FPEN%AmVXi%4u2refg{u&9tOZ@K<{DFk;lJH*$y;s5yi2q@sn+3lhLhiqWPQr~Grr(Sb z=tDxE5c)Hr{kGOGK!kpL@0|Lk3!N!+me8|>o-g!rp&NzXAoM1ocL=TScS8QNLhq6A zH-$bR^kJc!g+4Cy38DEMkNWX|Z|a*Vbe7P0LXQ`k?+cQDw$MdFmk8Y`w0f=ww|b5T z{w)$7k#N2j$n^FIy;tbhg?>}$W}!b8THQ~Dyi-C49jy=FsaE<6t?sjehtK_}FW&=X z_(GwJgkB~zw>M_^7NNHat?s)b{vM&#eOJ&2g+4C)Cxqs6LZ-(Tq9`vw1RWH5sL+{0 zj}bag=!rs47Mi;fGyZ&`ON3q`H1|4Y_%fl_3cX%vE2r+JrFbg>hzI%#ml#)VX=P45 zKdjH8OMMudv#72PWHkxK7@0FhLQ5All;cyavT7@*M7fI>E#epUIaFsG^-yT@E{)tqeg=8juvSuMXE%$YFr%ADeQ zd}_U@p&m(m^B=l%3#M&eEUtFlyFdg}d;o(mA@Pj)4Oc%F2W9inz?Ut7XMMCg1KND6154XIJAYb_p83Ys>UlCv1v`d_NODmp!vL^+vS@SE zFNlk}x#ewZz<%O1Q2Cj3b4TWd+`q7k&~E*A?3ghsWNh9jiBOcha?4__O~L? z=UoRPfj)_c82l<$xj2jC9Q>uRCdK}M^=Wt{r|=lMOi%9|$PB3GpM5`pAkPphpq|pE z6`)c*L%e~D!QkmPS5f}J5%Tn>SkI6^w?Z7c=sEkSiWlrwZF$c91X4Xi(gG*xH*BGb z6$-pa8JV>z)=+5h3|uMw5g2qX=6R#tuCts=b+Fa#2Ftme>N4@(;Blss#WTbo_>x6* zm8Jp^!`Gn_e*sqCmDH$v6o2d#esq=R%((^{1UOM}7HD;?z$2ut(Udok0tRQ1ru@89 zWjW=V3Ix7S&Pq)M1No$`*HmiYhvd9LQ)vNyLgL)A3Vxm;>49d3HEIn*fiX{uTZvvEq|h=2qfI47=tH_-cz` zh3atSqQoTrL6P4M)*v6FdwnJ6KsL|z#NXTDw0m$k^YnNLf1MtsVD$D_47abxJK#^S z688a|k?gO|vd80Z63fC$|1}c$w-qUagYLR;4aBWy{^#SSW^@58124k~4te$?) zV483@&UidS>fwbJ(GBk#TArc0WW83er{V4Qq+bN%OdX17o&kLEA@yx?XDHu?=p48K ze^b@F5+TkUQ`K~O&{R5^n&%uQjP~v2`)ochR}(%j?G|lR`LLpVURHc>`?v71FH@)e zA(HBDi8kK>=!5rc5lEpS`1O5}yptZp-w7nM$#*$bD1j@DBScU1SpCdtz5VUmk%T=@ z31>gf@r38(o{GtyN9T?3K3mCNK-u1K(|um(=kcK;*rd6Pf}C=j@iTEz1`b@a2B=8o zblL@o!Px!nPsm(vuM%d~CnNA9lMEH1p3bfCMwD_m6Lh>fc;H-m=9Y2taWURQv3RQ( z@0ajKB153JeYedDA|u-pnSW2_XIM;kllhPE9`H+&_mH$_ASPd~w701;VXPvFX`|$H zA#9Hq!a#ocWM9+`VO9cdEM$KTX}-^Gmb$Ht>%Tkj5Ow0j&p!0>a6?2lXB;NzlL-^e z>4iL$&>ughFi9U%n0zi0PU+R|q`^S^q`^E4*xlM6V%WVGjxFOu;j_$XhC%EW=Q_=> zhdIr#r~5R+UhPja#8X>y_!$hf{n=vej#}&EIw%e$)i-`<8b9Po)5pT`8B#yjiGlsQ z5NJ-wJKH4zxodY8V!PwtcpPH)aVZzd8FCpe5-AUii{aN*9S%oi`KTXi60;zEJQ`aG z+-yp*A16B48JED|_WSUXlY+cfP3S&8uU9+{cRz<){R|6a7%$36#RV?{+f{q9neYi~ z1_Ikddj|T9*9?SwTAkfs?Go-@@)~);%;7^fp0QDJL$Km?l-W0au2C9YJ zexko0O`zyyF|7y29gWEn!+{oT^NmS1fzX z`7@j(dqy88X?366nSFAdq^W(T-RY#*9xuKK?I%f93QK4$<7PXmH&Fo@sf#`bK z-0aU1XOwRO;ygOzN{I4oR}d_s!kW_3>k9RjNb&897R#nb+>A$k9-}|Ws?(crsr2|w zhD$o9ud!`{)Ta{Iy+`e7Xg-KJL(*zXA@%h~>^l-VV!PAC_q~a2(I&6>cl<0Vw&z?I z+i|H9&|jQ%(t}o_x3ps>I@L)nBx}Oo1iNRlEPWl)>hG zdJ{j{%Bb@eQn4MV;v4?`TiaZ^nuJo?d}pM#NYfiXna!>UEUqTKF165<1m7KPSl<-lsDl#{81k`S$r&H`OcqhB{+UN$?oY*wR_uroiw|j-QSa; z#}shHf0%K_eqQU-(=h@L2P2gG=fKDPb1-aCpZKpMKPGmrU+4V`sD1qBsJj_%8dC$; z&#}6>DC&2X#ru*hL;Z`pNIR|&P2;64*U!Nh#%eJIKgQ(uz302a={H@%s42sXfu`O_ zbAoQ_jr6^sO}&x+G3b0;j6?cWps6>~oh(rX*P+E7KMX#D`MXTKW2-ro@k({Wous&ivQA;D2kevw40Eo|9ae&gVoyxdfqXxh_RDWPcrT3DTafp*Jg`wb zdQ~`xh)E{z0h156Rux_(I8kt#;7q{naJb*?1}24 z9wEW=1s4dG3#w;U;9Dp3M!|;!e<1iX!B+&|5#-GQrt??9uLP4&HuUc+c#hy`!3ly_ z3w~GdTES(4TzXQDdIkmjzR)iU{!Q>JK^x7U{E33y1bIJ;{`~|83Z5%?k>Gs620`^K z3GsFa%|#*Q{7vvHLG=zl{CmKF7@jUTOmLK7zF>)9H4(bk3EoIV1HMae6A|*hCv=n0 zPYV5GBI3U!{%;C>K=23=@{UV57K2J&kcfDxf`i0=tl$LkpCmX_{1*}-uS)2fB>Yyv zJH>ws5qu8|{e*<8Zvv3+FU0>P;d@Q!_XL}X;QLtcQ}O3gkmZposM;z1u>T|fmx3JM z_{|afGWur;9Tu9a9fs!%&AyX#fzS(uE)u#@=o+Dy3*9L6H+xp+eon{7c4vGrr$f&4 zQ11WjV>qj;=Ws!8VVqZW;JX3J ze#Hp#Gkn*8Hf{!84<$l$$j^jvY;fy$0)tNwe$fHIga)2D96M&Yy;BCw4P`I&Up45hyMx>D?-l2e@<`k$V2jlSUg^GB&C zUjOrRuE`Im#A466&PGp|iRW2%k5$bzc;01Ch_rY^Ynts~q|GYARRFqZ%@J>Kbu?hz z8|Cw`%<%nDZ+J~}plD4rh-Y0fzx*}L!J@U%8aylOZWXlo!%g>F_I(d}t)|=bb1$9I zbUaTZormp5>Q(&DosEq4CI)(?=LZPmAZdHQsJD;#MH zgl~(c<3gOHLB`LIv@m_IwFU7DSe(g9pANJa@`Cv<97WhM<}=LvA#XOG#gX62FKC51 zCo|ntgegDDD~hyaT5F@wOUWH%t;J_@Ce26-^J?gX{74J*JQmV2kDa(W`_FIwtto0l zZ)@N7=$Hdnwo+dkG9AdUkd6mBWbNA+?Hhhem7`Tt(CV$(=z}e&^t{%_D0N&vut|qQ zmTfh(rG?j`9M(pwP+k?_4eUn#5tdoAC7SYRq{ScJ7*gzs$b8+t41 zjC}A&O5>f){#EOm)2vx-&ZkWe_H?XcdtjU)6u=j--8>lU1{f;mDq+lZkK;NBH@{0e zih^iFKQ|G42XJje2XO$GKY-H5#cz<;<9ZX6pshGUG4=h^6m{jqVnzyKY}`*h5TE|EI-y!dYJV-i}l3M zSNaD)XNI;QpKF?(k*k{nVxNHm@S)uCRazUe@SG1e#(J|0CbeFyY^*`qSb9cNG%JL3 z!ke+p66S`rZKj8`QlO-m3f#oIaiG z6}J4or>C->#E@c7T+CD;f-{6PQ;ns{cUpV4e;q^XLLvk+YzR)27 zyzqQ=OA==IVO z+KIA}Rd+QrEoBGb#n%>Xc6d!I?FxBIrVUk5pU{WV1eDcqq>->MVxtR8PE-6dWBm5M z+gl49*2$cf_kn>>gr8O(qdc}r%Jl4uv|z5Nc;*5v>s{qH9O2aO?|rXcF~4b zlfQ(T;%4SC5%qvM>~9hwo8{-uMlONW@Q0rinx_hjGmM0Ue=4Ok&uHS3zaHEW`YQjY=HbLKwSH0shbXmzt^^9B{q zT?TCXECbf32kwA%2W(_LY~apTmdkA@lgZCFK|XA#@!=@jTOhPC>Vf|Lnn+8c6=_L= zPR2GdPft#TUKgM}CR$0WLqVk9xVSZJO}RJ8YFzDKh5mH?s%Dmt7i}QaxHg)Kdj7M= zl<|VNeFSfByjKaLHI|F_a#kM#YR`vk15 zYW@@J?=d!~gzjwi^jOz?7WyW(b+5H5>Oud%PU`C#v{48BPZrRJ{;UuCeeki3dPD1B z1M8z4$Ju{#e6Evtw}Kz=*+2XRa@=Dt?l-Bi z_qV{V<_(u3E%tw}1KndU-repr_Kp?ay+AYea(w?LWAC4x|AVnNxFzbIPx4(pXR{s$ zVs(N3&-AtI`+A~Gf*r=*C!}o0p-dZ5p1r!Li-*xS`_XRg(50;@m@CwxPqug8)tU-< ztg96C^MT!KQ4f)pdr!IMKePqR?K!XaBb{JytFjkA=CG>1P{;21uvxFg^f&QgOPm|@ zhCR`if}vGWXVAJMm`k*rJf-^p+C~-1o;HO&NBZ~eA|DmV2kn4%wgmcgHMak!=bMe~ z9IrXPTQ&D#E)-W9BClkluTtZB%{q_033KI5kzO3*aqppjiKhv3Cyb-$ z@pFvvtW&NtOu6LsZ1Um4ay>rIcPyWPg*JoyIw&U(`A{~h&7pjLDCNUB zbV6gqei`lV_@JgJ+$~n*-Y9fy!*b}@B;n37}t3+&yG^(JlX%dg@#X78TX%Jl&4j5bJHTZ%k)Rk!8eux`z~?PAON4d!mG ziJKxVxc8duo~vPEjjZ1nO+r2Hu$rRDs8dr8e?@(Au68NwbGNK%I@mJniFFik+43dO z+t|i<$Tae9#F|IRK^sgNc^BFf)`vmVbK~k}&Xt|;y+_i6Yol`!9}8J)HvixUo$))d z5|?`Jcp7Wv$?z#q{$H#l-$Lcq&&=p9!c~H62`(>e!>Nh1?PI-Rea3y#Sh z>lJI@w!YZLoNJc@!GTzZG&VbE3oJXfQO?O7v&M|PbR>i}yApMCj$?f;xaP!dg=9y@FAr#rBR_+mz3Ff?(1?2~SYL208H!+Sg3GFTIJ&=a#Trn}=|4nU?5g}MDZgOPxO`K7?04FgA=c^l zz#dr7tZ(w&CH7(NozzSF{rOj?`LL z`f1kZF6d_R?9Sh7ObhL>*)veJMRz+KfOf<7c?w}}|GsQbj`lO_6W$B(p?=6mzbu5C z_J`+e{kd+t3iZtX+4RjUn}S{_GpxV1VqL+t+d|4keD~UI)2Y+R^jn57xBs2+UoUt8SPORtpTS49r!d#2}QHb}0X14KukWD*8nWn>D zl|A6zj34uKJGiJh33h&y*c!m_-+_K$HQLWhM^aD+dfb|& z(q;KrVT>(O$KKGrDs6Nrm^Wz~Sco_sZ7~V$tr&eS(~YHx^5*voR_H)98~U%om=jcb z%xt?BZia<|8(U3X{Yc8j3m$b}0{7Z1q)#5l+I-Y0mirUd?P|Sf?n#Z#C%U9ukN@y$k0`w6W zw>dwVfcAkkxvC%5-^c$v-9HFF>IFM$3t>*o`x%U5VZJ;XZDbMnHlsYMfKLHyf%sN4 zxgPjmz%n47Ypb=BiidgIFvv7z9YB2q`^5A3fU+a3-B1_oQ`^^v?h`yA*nr%-+roDE zZ{9z`I3A0`G?b08zJp!gZ^{I}=}-Rh_38e8ln3XZtOv$5<;pVT+MoI4yq9Z)K}IChoO% zsc*+LQ<3I)$VdY}EPdbA z=f39}+^5Fj)W%5L!+w7=+XDM&e|X&yyXcNqKkj)mPme$suD!2kzR1hK$Ai_q;W&nRl&e=KaG@ znHJ_iXS(0DT>4D**{03>PxkEAFNx(Y_ei;Rb>APoh~@d;q>VoF-@bQyrnK3n+-YYZ z?T-B%=OlQpqtcw%|C`MjUPAe%x%z47jCs~Z%#$!bYrYq^RM9uVzOCS9T<=7~=&$hp zPjX-%`tfGWJ73zswM~nI{wPpS>inUdjb#vFhPXFfc*}5-( z0Csy++_c9+l$W~=eFt<9X)~R}tOK~ugI~uwXMYl5ovXP5%0=$~b3Sm!@eO^jxxZTk znWjFtu4EafqFt%Bk3N&_at+F%t8{-P>0)lycBXssyM?D4c<@~I7}pC0nCIF4`E8ib z49^@AX}JWpaY@+U+8A2h))-#X#AX~{W@!fHe2IKBST-FuiUgnC+F^+TGSic};=P~OO%%wg@eNnH|`~0!zOqu)M zikfF>m6A`EyR+}*BmXJ<9sB+o;ln(#?LO$N?!}^x`~T~7{{vr~KGp~B!Ek3FK6T<; zkaf@snsW@&AHkgv!F_@nlsoFrxU1L>#Q%Ah{}t$eyQ;rAq6_Y!wbeiumLt<-IXsUv zFta6g+dFlxq##gIo?)b|;L^+0{U`}OJJnSJnVoOK?w zTVwSeT-DaD?lCqEM;(oD*Wr1(4o{#Cy;6sGF0A@G>diXjJfdSAdR=vRJM@@6Fs|b` z$+OXU1;W)>ZuMw;?d#LYiDBrE`P>EQPu9EQWg*@c7o90`%sjLba(27IP5a__$GT+O zTMZuSZFDXKt@uLmehz(Br+W#P!A6+Jj=Xp_-HA63yzV~b&q#ysF{pPKisZfs-eJI_ z`((s#u|mzN{M7UD0?^^x@xFlWgD|haoF30zflMDVP!C#$52)U0K%B2o7T)IUXaMgm zc#%J)>w%4}7T$Tt3hHm4|Mubw7TSwCi=Yv>1=lWI`*9t_brjbZxcHIZL|iqv_=(&u zT>EfMsVd`(w&*_a?qEYDMOjxBUuD(THk8s`R$N&}$DFF`s;Y0S3YFH@R@Y|Xcx-%^ zQc)6ezbeDiE~;xo>VuU~O>tdaX-TNQx(gP3GEuiU^E?avhI-Elg`wWc=KDDTTy+hL z7nfqsjK$Se^%YfGkE+r-xXU51I#g0xil&df5AYgt4Zc!9I(SPtR9zNQ@A0|)`H@30 zIBLny{Dn*u(DF@z+Y3BP7nRn=z0`LIlBc>-974i(t3$)GhQ(Q|>l?7O2GUobOoVD` zt7~xh_Dvza3GL#-H}zdHxP*>#2^C&lm@Xc7!ln}R2OXh0yhvSIwYbzWSqz!IKbY5s zvNGh0pHGCUZz!!TtE|4!dZWL2ams7|2kunZA)jTv1*_n1{9uh9uUCCO?)RRD%5n7P z@Lq2|LOr(sYQ*p@!OX^aPrW+rP0U1m1l)&O^>`AwC%?y=m_^D?c!QM3w-HatJboWu zjsPUiMtktB#(g{Qw=l!Be0#v;T@#^vukVLo^}UCLy=(7OK8ZnyO7JF51#Iibet0sk{l!1qs01^qm-()X37QvLlY z^OUC2{70dI?_Ziq_ZLF8?`utklKx34maWO5Nxx=xY#}p~ehmeE9wD=m_EW6a-UnaL zkZ{uFl$&6`rpPf#W2v6s);Y;bn#<6DkmHjsrh?t=`&G{Jlen#~ucuw4$cag8O1@rp zl_D=sx)A6~wbhY`3mhTZ=LY99IGre6Gkk|hZ7<`ZE^6_Ikg*!ldz0X64 zlFaNW$@FD1%J-!49R^=+cGN8&5xiaph0v`C&TbUwTZwcNUZn|oy%`AVewMdK?k#Wx zuS6yqJ;7`+Ggtrhu^;|b#c>zG+t^k1(SFOtSXS$_g#4PK;yL%)3kwE{;we*v7asj zuOAOPti=ANM0#@Xc-!k`G~Wq`@L#F&MsNQN<@**A^3OUAhD18UNmo6Cz#jZ`KB+*` z=z$#~l4j5!+d24`LHnecl7ye9ofsV^p3q(1Dg zg85*yf)C)29h}2R!M*Tyf*vI04W`flga1UcO9;M<(8S<7s0M#9fr!CKn#KGY+>Cyca^f!A)#m!B@bO z5aheciNTfN@dv+;gp-09;7Jbdf`F9ZyD*&q7TVwD88X=7fK8Z>ayagDBY+PfD9z8r=Fy_qA)oyT9QFdrB#F4i zOr+2z1LG~j#kk4v*7_9E*$8hW_ZgB)$4(81a<5I+J-8mlW%D>j&3`ZTe+hmADlB^o zQ~C&3Mg)IYJ_GF;o_c$rUEpbePrChG6tdlDQ_u-qy(#-wF=34qhULE%+K<2>{J)2b zvFlL~oVyK8gX3d3SR#Wc!lp}DtikplSOC|m0%m9dgw0|i9P@M$UrQzH;5R^3Kqb?} zEmSMy#h*L~>jhTo?GHn&J<U78InS$ zva7O>(j+zAkO{(zV=^f=-f`@>_(=b z$O}LYQ6=oyL#uH*AvW3A0O99w{0tyg73}cb+EN6RI@DMhK#3Pnb|Y3oyxqsc;bT9X!%oF-*`pESgF^U)LcMg@#xBBAQ+1}F>>`X?XR||r}BLq11Lp^otfo?NV!c|Zgi);P^HZ+0V!qYnOVYMp?W;|0_Eb}ymMuOm66q77conQ z^BCbzYw+1ZwE}0#Sq#i{nWQ1uw9vCa4+jFO6n*|$_b*RxQDB~SS^!A zY(y7smne51Br)P3!|hWMQmZHPyD#7*4Il9ArE zwfK?PSI}q#7ZUawrNs@@;vs6aR?&BW?w1PD4bURA8{ABb$GtHvHq{xbQ9&JafMCfJ ztLI4{XJFyZIFz#e%q&Yp%1gqctAe>lLIoRD;*N6tS ziEVGEhvuxLOlM?{LWM?3Ev1mHvy>1|-+ z&odr=Z2bg8k9Y=C2>V%27Rru?1%|Q^|8A5|DwtKrop1G<55J$Xo)2Q|cpHvUI?&m? zXQkCI9d>;Zp1N$dU@X~+%l3FG!KHGgnkaL{BivQl&~mJ7PISn-lXm8Kwi*6xgsM`Q zKnKfm0r^$ghcUqBaV++F-ZcERhW~cMzdgpEkMV0VF5BlhW%z$#_FutMDDEd_08A{bFtwwW+*gFkzP`O067Ss~tCC2zgv)uRk5 zjT3CKObi43#s{uXM2I7G*m12;pH#>%h_jEeK6i4=MdVgD*Ac=SQA7mkp)C zK?&bde0p(`g#e20x5PNM!tn%sUWemZIu4tlp(q=rO90+9)^$3?cw-EWmykz0g%rVH z80Yy;A)$~C`M?$8bLOL_u%ME#zqbopsKQQ3*jZ?+$hXqM=M<^1z#uJiM7yvO6_zDo zSF{UT!mxgg2zv#2$aq$mj9@(?d%axk54Ia<`A?`d4%av7gHeYlUAs40oLFOl0fTKcVTQh+_cFNDZ8NWx!>uvxaleO;9(%e`#OVFVkA0yZ8hDfQ5%V(>!*Atm zVc2*dN>^1w+TT~1hVmBU2Gx|Zwxr{M<$t=umCPsHFho>yslX&)w zUOaT$0B6pPjIo4wCAIIER;ZP{llMn$d(88Iz(1u8`}FeG!`NTK&&soTk0S93+vZ(?vAic}U0~-yT*^UP-5j!c zS77WF@K=AVarVC;CNaY%FJj+>iuT{A49VuWrW3nR-CxoIY&LO~+}JcIGWKaEe7@Ze z5%D-dRXrDsD)F(*!&v%3ja+d1ukdKuACe^=I^LdwIt^ImEU|H5w>jN#F`RGDgKxKc zbOM}S>p&%f*+ByQ>wn4C32+WJ7B6)(AO}*r_4eqv?EX8)y#d+p{@btqZfiBz^{X1!)t+Y;vsNeCHU}SVPT#Vpu|&GV?l^{MZdD7) zEXUb{XuO~5O1Q`_Bz3Fg;9`3?G~mwCb`SfU?!8i+?q_%BCX!rGdg6O?I^skDsckyB z7pKp?F=v9_yfd-=Mx6fmCYgEA8!Je)A*F9hFOtc&J*AfoNhyP@DZO}XBsL`0J66Iv z^zNVC&xL+xdF_-GZe&U3pxK?X2c-G+_Lh{^(`@V6tNm`C*md@jfR;KeFr`;0WlVr# zddGLe#EsV+Yye78!vgL0?(Exs@6NP%9B$as4|{i7J#6mX`AzrhM6AyHbtXJ`sZwbG zcI1={QG7;xYtVtNtwBS^o4FXIiTf`NP>aFsv)V2zLz1QJabpxtrsL~@)^JV=YQCpU zVdqNvs2-+2EXAIaK>tkHDHQ&gSPnpj8DoCR0v|(%`>c_Qe?**((X(76swbQAW2HV!0co^Ee^5R1@70T^SXEYfG z@)zMkbV3cT_WPmIryds=2+KM#&}TU=DoEU;-7y6jz6lou5E$%Ikp18`g^^vbSx^XekAweVw%Jg+RZGgAH!e4g)|8awpHfg(Bx-8#wPMUySqrq4t~Za zFxaIrp8y1PC?QWdXXgW^YbRs#$NTXMaWNTUrFIV`avtkgw;s}*!n_OtNRz;Dm&O#e zT!qdc@D96e&CS99g#8QXtOTsrP6Btq(Dh8$VI4q#FVekXWfL7kInS`>5+*9=3<6Jg zv8{!CH=$BH32T*eCb!eDFiSx+LaK5u%mRe9lQ3C1XB-8Tpg#aFp;0+!5cmifzJyBU zT(}(2sGWqZ$~lu8cuYs7f|tO3Je2Zu9N=WrnoBr=3;uQ!9ehOyFMSeDaBgbNC47NP zMWtgR+7bK--1u@M9H9IA{OtI4Jg2+ zWy3LF`xCgOi1Mdn30BSECveLV+nP^U&jo`um#{%OXAquO&V^q9_F$C`2Eyygx$p#F zAbMp~9U&hV60w`;C{V<5yJ;&N5nN!}3D~8aGYEUMFPFn#DCb;)H&s-nqZckjBn;L5 zb`u?Auu6e0gq_Mc|1cmGs{`a_J>a-<&L!~kaFusDLYSB%B7vWVD}OrXYkxwK@u#Cw z`OjYt*rlEPayuUvq!9RFvywu`F6~d)WBln@j#(Y}3G0<}0bvg=RbF%)QvNduN0oCf z;RG%vosQ|4a6t-TJ}%`?N0IWMUkTWtoO9RWcF>!+z&$h_wT}zsQVH0koOAa9_ABQM z!ckmG6FN?5f5Jp8>6JenCAc7P8Q^2>B%HvdHH70(NU@v%ELXkBTrRhD$1)e~ME%&Y z@SF|2!b{K{%Nznb7j_{to9NQr%p5{xEP$>p$|mO!XqP$$U0anE%^}d#bO2p@bO7N{ zEPyVpK}Tk{BP9EzU~ zHWBy}Xx7S~4jMQ731MXjkVBKv1BQA~p>?BX5nRk4Q5bftG^%fa=fk*=Pr?D^oM(y! zX&A=isO`_xh*CfZps-+C?og-)uQ>$1`-1_Rz^Ap2)nGT#p<~T4v6`X3S2e&`GW7Zz zF2r_o@fmI+<{b%j*5D=*$8jaVgEZYbPJxM2iBSccygb1*)OOB-3lYZo6(SKFf_sCXt8BNT!=7k-8*%W%xra?^?;mQLjyB z*Gf8;DASoAx0d;F15y1a_vKJg;|3DzV6;CBgq?{Z*qyM8Py}xR55$m?*hzfeSQkY$B%DPkfVvkhU%Z#|^)(XhuF-Q@P$1V6-@+(d_Zb{wy3#^EF7 zSh<3$KH%ZB(SWl&8z=9!GrD@}RD?4DkHco>sR;tO0xGTmR{a!K9^gFJxCHOHmb zA>|d5OfNoxiAg502bYmdx1OQIN_7`Tz=LWOjOk3T!+Kye*`OC6GR7p6*o(_Zru#)) zE}c1b+J}q1ACXUGJl4o2Vo=Sa7Muve^q~_bgF!?N;Uc$5_1PHbJaR5qoG~@m!fOLA zS3Qz^U3;-NryU@aqsC5LE=F!K$N3ynBSy47djNWhw;(=MS`eStEHIia!VsT-#HLEE7JVg&wYXSnr0Kp3m#fq`s?hd0KbBwID<+v5aS0SC2k?czmt&HA%vZ_ zTZr+4kR@&*#=nyg*2G?1YOM_9Lkah4m*Kz0h1w*1tekTQso>-+te}amG+gK+2o#|M zpn>|uh0LH3GPwFXK4CDLO{tVF-H1(#Vy zFb$6NOk+0Miy7g~;2sX?aor5*W;EwOUV_W~s1N5Q)Q2+=GyO1gk8i3EryBo%^kA8A zXf@+1`{^*QgOGb17j@%{!Hfak)T3uRNrdyp@d9qWi?#=2ph>~_@) zM-q-0W)LuAg^|lJ_UPPP)bKD3GX`)mXd#VF(2)ay`7sW=d(+pmj=3f-Vx8hL9WNJ+ ztmC23jW%R{Bz7Wlm(Z2heFT;m-(^J+=eS4U7zt^i5ndri;qM9x6dhBR8e1N za3EV~>ZBNZ>I$i-nZ1-Dg2Ym zKiSi#Ib~CGa!J?;WeG9N&34LiMvfRcZCZKuv{BQiJ2y?8h6AE{<@RunTRGFSrWQCi zPn|w0cf?2)GbdqM#aL%qPVV`dRDWmk?@IjfBuq`Xjf7|XSpY9c=YaQp`q0^ZDz#$r zS32FMI(0eWUkx7xAI~)YaVblIjwXHd?16o!9%0ofC_$C;e^sZGl7Ih|sH^ZVr{$)}vvAAC?gWlHW6XZwn& z&g-7l&Q(*J{1;_UbAE5BgcF!G2gMUuEebz(i^;@m-l;J^Bk?tF4pVc~pEY!`_?+zU zA)@WPvf_QMO}l*TK$s`txr8O3jTDKk%S|fV9g|9HOz-VZPE$B5oHfeHc+UCsR?pM6 z?F`nH5X-rpFy*o9rj2%f>v(=;+vU&07)Mr2%bk+zd}QS~KU}%mNh&MPo#q7mp>JGr zPuy(s`A1)@y_DcigH#tf#;f>WKSku2iW3h?)P=(6P)kG3hqCBtDUtg{I8c+O2OO{tLaaj z?Jr(=?NX*g%dxYkl`DeQVWXiF#^8^mTAGt^JKed?4P_$fWXv+}_CELd8u2|I^WE#E zad^-w*|t27IC*8$v#)d>U8$5+Wu5K3VNFGCD!$b#RFckXE7;WSM|9yQD?3{?ebrT( zjw)#;G)Y3Ar#O$(hbf__VSJ|ITdhjaPKY(edv7r|@QHV|iu3qN9Z6|LFCY4tW{V`- zNQINUy(;3L@O-vTq6H0iwz0D3V}<#uW9s+$ShM-U$#E{+?)+e-KjggZndO%22ThO^{+@OREs=U&^tYcFEi&hZsS`KMzXZ^!!F zpVH5H)I0Uc>F73cvvPB6#8~hi!){-hGd)-5Fn0vzEtiiPj(?)k zyD`K6vGgGk)krqL%cQQdpb*)L!_8vi(_@Ri!r;nzQ)y$N$(U zpb&GmLVku-2v_mq>k1byxvsFRxT4Z3R7Vu@`_;lJR~KUXb{)>11UH!hRg0I_s1R_( zPa2c?BW2Z>7U~l-i%Uu%UCsFl7g3O&dm7f*RsrocB+vqkx@DEc<#p|%wId4gaerND zVd*lfwzQ-gStzb;AFie0j)Z3_zV>AzLKv_?;SwHVQWHK9*9ENq`Ek)r3(h1hDLxTe%9Tv}XvU1=>A zI7_ORmgZhtQM%;D;;P)5%Ho^KYpWZoN^(n3IoKEA#@zCX`dk)cc84-n+dD`pnKD&= zoz&7AT9~VMswlS*tzoCw?xP>|AuN(8wk=pxT~}&x69XI%2b-#?maH!+U8ZVGNbdB2 zVyK0Up@?8{h@mR0uJ{IBSBOrlyyB`kq08hjMr?^tEQgF5vr<(KyQ8_bvn+Quq&}`I zy{WL%;diVgsR+ubsFNzwhnjXiHnUwK?F>%s1kqjz9j@C4?WBvyvIB%NPa5kYw9bYa z0E)4?vP8_Pu)3^_CfS96E-J&F_xKhZC?#y`0kfVm3tLNI!wobMWVyO4p{2$3H=3F% zu3`bH5?1xf?m^Wn`;yv{h8oKpS&OYX#*SeTR+W|)*H_#ihEP?EerL+8WhE6bTvf@n zrNt#Wi;I!Z&XuRjEmkzul{6Ea2&&Kcy%zc78M|6>F=gF|5z;<8swmod<#cE?IxX(8 zQny5z;V6CZD!Z31i(PdN(D{Z^^qxzrafhLcTG1w@GOOFQ-h)JUTC8VP1T|;??IOEt zuC%(WeIQL0ou7&zCS8N36YIwi-adko)@9eD`<%jts*1&(Ga#G0bfH*DX-)kSt6_0n zSDkNdDbHp_y|CG~i`>3CLDgzA&>gcf^>+O3QqbGIxLRYZ;@QKg0#;pylA`s4tu4mM zy5@vs>7ld|I`K26=ISZfULi>vZMz6Oj8ogy(&A-kQ!JCh!s{Dg)2emV)f6ulqd+I7 zdbvV$kR>C*1sJ7aw1zPn&etVoy2Ud!3AF)`Qbv!3a)55(4eAi+cIK)XRMV8&ka>U} z*3s@bw71KcE+W-$PnlKIP_@|AT6xMSjC%1B^cx6dJzEX+WqB}U3{i_qm*OyEZ58p8 zu$6GNKT)g)Q5`DdqF!-qDT=YMqP(ga1G>d(ECC~?6z$b=n?o19oz_}vPL2AVCn|0c z!l}AzHF_&G(MhSAQiQMwaAw1vZ=_aBeB-0LRbE|RxTK=6t^wOCq2ueIzShs|^n=1H zuPv@YSHpQ&`;2yx6L_JqXbsiIM>2@2nOghUI*;7BNomWQZ?X1RxU_U>aZL>?vGb5t zh;hc44!fqyr%a#3Et=H4q@)nF9G4?AqbakBD{Gb%w<{1d3kzeEj99U$Ru|JWv>!dS zDy&lz&%(Oe#i}Li4xv-8sLMrq0#z36hJQKyS=FUtrG*w(g1>zMovC;Wi(?bH!a{Y| zvqISdZM|J;U3ajBYVM*KrMaJ}^|rG-JzvJSt~-rImBm%pq2kJ`uu+vNGjQukte&)V zag;bJb#cv2)*?=_7Q^_^1lud@Hha}|NPnS}HP&5QTYOWY(gw+LkexEC0j9$F0q5hR z+KcQwS#~F4tlXUd8;b6R3ZY~n4r^~%DwDNX-_Sk{)pem?MB$7b!{TYEYQSD)=r}n+ z!a_uK_G;>&+sD6iqBox2v^&q+^`uR`xO;i`;9Bo(&g~u?EI?lVX5-=$6GPX)jW)gh;cxtbHd+;|87tRS^OMesR1pJDWf9Lf0A~59-#l_!z&_yB2 z7`is;HvjF3>k`)c?(p8}+y#k~yU#Z=`EaxZ{Lmwo2crj{Q2z0( zd!xz{LFwIYnb&G_R5^93ggP8OUlSRgoCaK7L|!6HHSv6Q<57xTA=h?i*c46c-4DOe*|FStx_ zxnQH#8w58AZV}unxJ@u3xI=KK;4Z=4g3k(aM+EA(S8$);e!Oncx?Krvy0}q#UoHUoapT6y#Qz(P!P$cI1s4hy z36=;h5v&yCCbdkjUT~SgGmS9+Lj9{MNc)@(ZiGq^_rwbMc&K8_6xKOZ2utac)V5MM&kQ*e*q^Z`12q2R#`(2#c+uP`%SdPw6|BK-FWeL(OFLH{7lmnN7g zI9-shSf^iwd4vFfa$@O}yGtKiUcJi4ZYtDuj6}gn24NH7Z1L zDn#}ah6INSW(sBrh6SO5;?EPrG{^FwEL1u}u$KyHAk0BwKO*`Y6q`b*Z+W1zk`F%K z`yu~jf-oIL&k)eCgfA9)jo_Vv4+wIeOLaS%TjY zTr5~2SS{EfxJ~fqg8K!3FZhw*F~NTb($J~TFv0T$FB6<0SSWal;2nYw3O+8#of9eV zHNiIp-xWM0_$R@S1#y^;iidNq75GmTce1PB}2|r)(Qo$=EypV`^ zWkO#oSVe?fo+mp#$+l14gTiND2l2&nF=tcSNEdDT1kj+zXE3V+8XACrkJY!EXx|O85M7Wp2>p0A1MxiZ=RV=&yHL=~`{xRuny)*S zRV%cbhl9RbXwJ7ekNu(0`-FZ?=)*$e(0Y~bKLmN~1>^M~LZ9J+mkBNuK0v&I-YG zf*U0K2ZBEmd|tx$3%(`zu7v+p@KZq>>mbTc7VIUMMueWZf_Z}69GCvz5#%no)c+PD z^j{}>1-n8jTM|l zgxm!}-yrmIp&t^uN$9;ozby1eLPv$>dXRefAd`CZ5KJc`{d0&&|2)A9#Q##kX@Y8< z2)^rtuUc@Wgs&IeEck$gKPC8*;2|RPX(2+N<3#B3snDl{wy}PsUcCh~1V;-_5S%19 zhX^^}6)YFLUcwuQNcT4JzgzG@!AFTm?{UGOiT|$ze=Ycqguf>k75`5JKNsYNc$DW8 z>`jDz8G^$Evn70z-~z#GiC8~12)#-03Bl(CUlII+V5{IM!Jb%XQIE3)`I#zd?krB6 zAUIWUmf%9cQo$<0^@5KHa(zxY?-HRexAG_biO`=3os5MT!-GVGpDQ%i@1!pkda}?n z1gnX#lbeNJA-I}|@_az>VIue*7y4PjR|H=tBAs^xKNZB@mCAnr5%GE7fPCE1n;0e{ zor!`|h~O)c@LPqxP3SuWcZmNhf^QRH+kX)HAA&aSJJ3Ic2)TU)hlqc+&=&|!6921( zzE1E)@n0qMBZ5zg|1&~!7ZHv}`-Of-@K1t&5&TlH2Nvkm>s-Ncf_#~U{$+wI1e*k3 z68uOoDrjLL&Uk|bFBJT);EjTt1fLOnNANSjZvC~K;ewY5&J%19yhCuO;LinL6-;D* z4ZEB!xLNRh!L!+aA{^6g%Y&N-AeCL1=Rq)U%X2RJckvGkJx1t!p(hGmAoOgZD}}BR zdacmwg^mclL+IT?KP&Vhp$`lFnb2Pd9k8{2d>4ZDY~|G5v=pzQ0_$rvE-|j!(#o9r z(q;8ljynG_XA#bh%%Nv(wf4}+m?N=irwS@5UDQy{j|i#}OSy{|EvhZO!5zwv7hKFZ z`?0FL6rwf1p_q{N!AIhyCKPE|Ip%$}oGKg;nS*Z)vejc&x6ra$oDyl}Oqh9PPH}yG zZN;L7dL;49e`w;owW8{ou~>iZ?H{m=RzH{mmjqV6qHurhCfoyr2h38%Cm)s$);U6> zsi|MhV7`+R{~38B;6;8DRtG-!k2>*3eduNt@>dVOMcS$U8hNxow|;xp=yztQAC|o8 zz8upVkBjm~;o|QQ4t(z~wn%-pI6}HsnCSSkH@GcJeN%J!@D&XNxcgYrgPmlS<6h4;ja=1+#IIZhv zTULk;`I)d~pxyE|K_0T9>K9Yvn7q5-HgVvzHbdS%Q#r1%M_g|5&6sCd+#}umjEsli z;Z8S#bXi`^2h%s@_axkm!+PfLAdP^E$&X>Yo)wJoRqJQ+!lro0_k!>lfAzvujELv) zoi6y&C_sMHkH5EYx%06T`PdCV<^w}+EFXV@8`WL|P`|Y6v9>Y<(1>Q0yUfFye?R6H zUGS0LRs7aO$P2;XX{zVpqJBYK)Xgog%?oQ+QS!=3(=X>v+U95DE_0m1Gn9)|h;NL7OzUin9w%@Ha%yo?)c)g@t*JPt z*a|-o^$g$GYT*oJoT=UN*(IK+I^!5;BZqLNn?CQjpcSh3M;#yIdB*`c+t?ni&p|e{ z6)I@`uhXZ0!?TgSp^Zw8H^j5%XSQJ)f+D(KWJg*khq686Hnx72+Y9H)KM-X+$C}xa z4&GFpn{5AaW9tc=ovd`QHmSIY>a6BS%WSL3$ZGp5&Ry<`XN>Tew5?F6Y>HOo>hrd(qJq{zC?}@jg>FiZ znu1o?f}9my(28_>!Djkns*JSfa7pq#Z*X0+FI3W;fOuN>f;KCEZ8OU6hsMvHC%@#o z$mH8^K5f*8ao5uBU{kcGn^E=~U{5FRdEuxPelKcmdN7)eG`!)hQM&+d57tENl$r>t zWmemTh&$L?(1toqCT|#iu>EAnJVrP8TUnPj<$(SY`fRbAq9tfQY2l5yy>j1C%i0+A z!~O%vt7F}ZJRlz^!;q!&>#*!X;SZG#gBmw_LX8`H`jHQNcf>*7dNDl3nujyU*-oH` zHLne)N;#g9%?|3KmuF<87y7tkv0#KYecutGOVwADDq2*OSZ#|HTkPew_;pJwt=^WZx5d`B z-Zp@_($@OXa;t4^egFS8YtG&Yc&)$ZzVH1#@AC}o{AbNtv*vTpp0oGNn#9PKNx0CM z9~LLMIuHx}5?mwK*pU8Vva&2R!CiwNp}%#N=E$zdODu0maOEho(M@+!&T2kw&ckKx zAiIr#f^f3=3o3Je#F42=2M6mhf1}3bEmEA9s5~LC% z8(19d7v@p&GQCe+U0OJ@;Tn`q_P0QMX^aA zQ-dGi&zI1~bQQP}>2M7CYXCnFe^Oqa$dG8-Kt#h4>OX}%j!?giR5VS#NSf3?P$ZJ_ z9(YlE7CVkmzndynLUroIk@Vv7Qa5hGU)X9Gj&T1!a5JQ~V=_fmgCUR-^`#H*t*31C zadJ%Tvk*(W0qmV=@2o<)F@Cp7`vYb0>o>-)lxgoiDpWMaHI8ZTSt=Ie7reATTPh<~ zfFGV|f3Z|n>}E>-)l%89OR4jHOXb8q18r%4vs7;EHKy=)OC{p_k%ctRSTaBUWkxhg z7R3L~6eCI&#=pa;QNt5~c(giy@ua2V^fQtbasHr8iy2#z$~f0#r)4NPIZh+PX_*Ei zJA|v^SCi~xE)sHTd^i*8Yc3OVT6_XEXPYNP^TqKKRFz}?Rmkaa-rZ@#%~lbvj^{DY zqhUsanis@JlN_Vu!gwjku}ap(Cz32wvLSvR$zoF|ahJva#Dq#T&rR`0a?8w%k}i%` zU&->{ofZR~k+zG~5bI>d@3%GL#nv)?b7_u_YZMOO2^8$^qU*@cR5x8UNl$2_1k?9IM`^glC#% z-HigYMY3KcM6+Im1ddgo2yq;%{uSiBEs=F40}py~#y5{u$6HE|$EyDrm29#efKVjs z1Nfs^HTWCz(iTElM*4t9pwu@@lHMIfT* zs{Y#$X#iHKBZS3-cO|@(>^B4T7(JJ%_V;qka-f-N9*0u8Qe)BF1gU{j5Nf7UbP|FG zH81kav~MA70V$00p1GJ2*%=0NN2Qt0X#V!sY6mZA@XQS6*UTF%rz2aUCYSY=gK#=C zi=*9;KFF*$G!1|M8J=MU_;Y;*pQboVFJTXR^@g*?W`na3mzjSH;tidSpr3#odM-Tg z(lZX8OHhPil)6WB)cEOM7F7A$U#+FGR&eq-;r=$*BdGC5@O%mSLPBf6;xD_Q9Fx14ZluOQh$p{kZ~s1<>%*wCw{+*atp~u#wX0OW5k)208Fql;13=hbFE= zA4M^yhll+pgQ#R8^=<+pgQ#uJyPIC~DYC5;zGFH{o0u zrkV@I_Kdz9lMf+tmuRNwLR>PF8HU#pBV{PKi>ki}v4Klb7IPOl&w?Dr4Ff+$?xEQ# z#TnTAQJ2)78XXDQNGy6iLPsxPO1q7@4q;=aP}PH}2pWSjct)O5V}1;c>TN?WQSbf9 zP;~Jb4Bs#LWnQ_6=q*v)%jI`J^Gln!HoyCKgL56oQIh62nI@Msje46|_!fm}Aa@j( zbD0D6$js{`e@X5WB>SN5$8wq=g2$~j8V;qYJS03 zoB@rR29NnANm}{Oe23ViYVu;6yA!~ky~;nJUppp#H;Wy z)?KGfgr&(l0mU*xrbgM=GOPJ#h|64Ou~%ZcP`xJ47`8n-5T9KypadoxH(lvDNE_T| z5cN$2mVK7e`O@P^56cJ5o0csy(cVziQa+AT=pmoPA5&G2zbQVHdxgAr%mp?8wAYL2 zPD4_Xp;R0+&lCoj1qiawlrtv4TizF9u|1s3;h??uNjzeS3iD0Ghz#aLMDk_$gd9(` z_r+4^apbOA+ry|homsabHXvc5P!T0<|oKt`cT8EfSG9Kpm^y8RwKus@eB{t z;sB{C#Ol>xtO%cyU0g985*8A!hvr&BVF>X7Jnk?0xY%zv_A zm1YvRi15LM|I+;M8l>Ob^USf*)_4#~m~8b32Ql@RUaPP60Ms-7nuI;E%~cj#e;JM{4X+mjAC*bdMm z^m?%%Il-ZHJdv*3p@9SSa6Jg}NWVd$Gx|Ud4v{ExZs>$RIjM07PX^4z;4su35jf19 zU5Gn8bfn?%(3ye~GY@ilvf>CAg-a{)rOwdp@jytP7KohiWQBN*BO_AL3fd$=8 zOdK5?{FsoG#{`=2WO64U76zeQVOPX(jLsE$@?l9bJvqOxTNUCbs$@+MRV-6YN{$PW zP#ikF&>mM(U}cIqH* zAiRgU$s=OiqMt*#d{)8PbvqJSAWAWwfY_6OKk3eb4=<$&Dtj4w@nGF>V?3*$A!YLdWi^4aWNG<0UnLr<3Dkh@k&RTjqX4BL*bH3ZGSCL0 zEjG?hz#i*$+-8uJ;BhN~}<12$Mw-GaE#`eRN3`Ll2#1p?XK54fPf zbPEIqDGtoQ-y}v?bJHDryR`3G$e(D z2us{5=~NS_6ocG}o0HO(a^gF*aip60tK*bv=J}y~XBf&YgV-c}z5k4kJUPjk+91}9GvsD{DLF_x_++?}Cyz+dFa^03ehA7UJ1Y_Ta%cm(A189Uqd^XNW&L0s#15)lV zGvV*NnI(D9EP?;mu%zDI|F9{(#9v+P_bDFjw-)=oi^n7F@hG?y^*T8#;QrY&mf`G# znV%`~cdehfyJW^C9kXLY%EsY95`Wba|5Y#6>JNG{yRfu;)|icv7=Brc&Ai%H7|0eA zr7-TBv^PnsFtF~YCVXqH0owYe<@GHg8{mtZXug>y_Fx=TjN#B^DearixXhY0ZE-e$ zVI302O=0YJ(P~;)4Sloa7uRl<`o!eqsdguAzv5S3`F0!bX4alGQ$5AbWDirYVT*|@ zJxmsQ*Na6)XWlqzZ8vHCk{JvV*AK<3YQ3pL4JqbP<<9f2U91LZ*;1&1TCq}#h76l+RlCEy z+gIX#){0`;vGg@*FI(;Q=+}K1W@vJct*) zU=vl8bhC@ZwGUp4bZAd(VspiBvfI!csbvPey%uYLZ70VPWLnIpwAf7z+bgFv(Iv^d z$(pJ>t)_-mSeI;VYC9|Nl1m-=lZ}U4nC5q_5lpqnD>kZn*xU^o)zuirXldIXmVyI& zr|9u3cNzX67Mt%nra}KlT4Ht; zAvJC9XV$fQKnCVWC5fP}*>#|Q<)Rz7LfnogVy7I%4O>*TEf})%j`E-f*4n|?TE=yW zS^H@$B4VlC_Ml|CIwrW8)QnluB72Wk#jPW&eL^J@Q>swyjI*n0XWT{ChD?hG=F>io zsa1KI!)Y?kXSp#m;|!URa&|#iipj&2%KR!{nVM6@{7~y z;1s?xq~ijKkGrC=t2Jlw7X|no<5;2!u*!?peuXO=Ye+jG~;v0&}8(_ z1mcqBJ3Z&9kEq1K#M0&|56t8spPVJ0^6U-=gse$+f0W65 zp~oXmNF?B<6Yz2-X{TE~WaV)vVcjNMww`S5be~{^&kj2E!4=rzl<9(d^vN?NHy`~D z{ULXxeXE{3%DzO;#Y_4ohT}odM#Nao*ZH)2#lD|A)~Hd$Ny9sd2!C6{ z-yJ4W+9v7*o$wBH}Mons10$FMOWxYwsIG)X&>Q zq<2#BJw?9uV*dGjiJXb{Btnjk2rzNk;A#&JX*_$+wqcV~E zh9W2X6xFHoGWI7jhv#cLE-C^jo{AtK{%QM_I8Ud0C$*&iwQ zgyQ!Uf1-F)@h!!_DfTip-ay5(6vr!GsK~LD`s)>&71t|bx+MJj71<9d|CHhn6o0PB z{zv}1im9ke()|=U4 zcLK$J6L6~XXDjk;C*$*tCvlPDGDR-ZWw_XH0)9^E`xW;p{)-~lj8pz4MOhOLn)eCA zk13u|d{gmHiZS+o$n{kmu2`;ko+4LHQSNfZn-#YzioGY)(S4+WyNT%Jk0}42l>Uz5 zONxf~8RS!lgYgBPhuU!nAJBI>DCX=ndvlZJnei2RD( zBj7_S_pI_?Q2NJ;KP5u$w~B8Oq5scH|DA|@_K5?LuL2_YMT(OYFH#iyv*2H?^b*Au z#hZ!Hw?T0;5$WHnxSNRhk0>qnk3b(#`WfXvr}SZ^f2#B^mF`mdw?y18f7EcXiv)cc zSY*L;dlNwqRyv{d7^TaJ$nQiV^i0$6If@GuxwnOK8;Pi=+mwDl@qprw6#tC~ePV|d zDE5(%pEnr}d{>d1m`TSKGl@uNBoXNpD?0nA=PF<9o`Qd+^6NGHlZq{hw<-T_rN2c) zeLSo5bBaGCA|Ed+zfI0*g`xR@^Mk$DU2t1I!me{xE|b6(h(S%J?X%ZjaehmW-HFs`(G{DcJEN85Ke zGz$sgcH}+HU#dB*nQ?WU{vJJECSGh|;UY3_&S zes1G6A46%&x$pVyi;I4fGavh-t2!WmSC{cxj^ihNdQ|t6dx^WSx4z@(d(qw4-=2LO zv#d_vYwPr|2i(J6>Z?#)8Q9Z}wz{{@+wq%>gF7%yZtKiASl4N?wszJH9p0Ie*w7iN zuJ5eBW@KlCaSt|jHXbfS-frpivYI-Za)x($)tew!-+6RYUT4a|t(_UA7aq&Vx}}r4 zGY&55T$EYZX`lyt*Kaf6^+LG+&h9UqjcMjSGys2dWuU?MTdNJoJqlbBG#ytJu1Z|F zxK4tvb#VNB?1Q)E=scc{@-h4%_LTQ3J<{c8v~{KvQJ-;Qw5>BnME=u=g&R6ki3J-v zQ;7K+I-^A7(I@8K(itJ<+|p@?*(fU!W%5e%Iv1UNA?jyD=kY-obVd@xJCBZ-f_Mn8 zwBd_~+VJ|(2=@>kt?GRH)@Sh3JNr1sU#as1>io%$BS#Ok9Xa~Vx+6#TS06e0jpidq zpFVh`Gkwbz)bEzgwC7QmXp7VZo09DjNo@LWYmZ;`Xpfgsf37`_psx9jmG66U@T}mv zC;s+)9@j2hJ8gck*@f`BVCcYBVDn!Be2(Sq$_<7`dRalu8fCo>+H4d zNLMQOsmoxSqT{yCl!ncnKIBp$msYpAGrsq>&M0M{M;s6QLt8szO`AK@z)!8K>r6wx zN;$k0^{`p`WhAlnzoi~Bs@jjSZ@$o@Ec;Pb6`x)O`x>nGD<)yqC^ldZoB8;NK7VeUSeqEn<2lc zGXwIxk4l*)Wl`>ZD#I~`ywTvf`;j`B=6>jq_)H6N5|H7&;_~)nC@tPA$^7A-cWL%T z91rfTe|hXzXL?1yiFOus<-?vt25g;VAG{so=$%~#_CPW)MrOedN%Ww#&0%0ugX0O~ za*Xw=Ve?}fE`(P?KGFeO9&H^*6V3OlZJX+2nA)d%bsfjO>h`YOZS7srx^`@Mf?mi| z7i?M_E%4gAFsDdQg>9L_j`pt7w)U=y=Ju{s&-+EncRP-zA|D>@XC&HQ&nn#r8zq+= z{VQx`M4^Y{2i^{;?GQZQP?qe2wk%n+k)e6dcnRgAtqgVls9YtUFNvycT`Vj1%N>o6t-g05YD`KRj@^* z{DQ>YsBgZuxEpPH%Q54%;hM+ioFDTxcbUlNUpL>yvrNLPkDtW-o}euw#AEsLOYiQ7 zao|{+*?J0oTZT+Jx=qDU2 ztln6at#{h7DL@&SRtB&j>#nW@p7Z(g{BJ{_*^GLCj^@qaZ3b^Mc$<+n?CONti1uJg z(N5^oM@^g7XWbXNQjss}&VsENytO>eHZ)b}$ECM+VQ%${0)(3{BF?xwU*~)Sm5`1+ zW1RASOI{SbsPgc$Aw2>aA8F7A4rJ0RAR}!@8!w!$Ax(oZI2CP0n?0Dz_$l7yM=`ej zz}0Vo_XWHTY3pQNXQ56b$dB|B=wLm${u;IAfjye`t}M9+<{@qJEse4sXE^(nAnqZy z32a~;qrRwjztj`&AKniI?8ivUBo=p0$=i3d7-qa9kvm_H)O27xWdEu;o>IE8a}=I` zQEx|AA#C;-uL|Qz4eFyE<09cG6~ts zj-Cn3NZg6%1g{N(8Hroa7PNb_u`7nF68WQSexf}kfh!~HPV~)N`sHV}_d~zNGvQ8* z^|y2-vf8_7XUBsLDjUZl>yYJ=I?Sp*7D1X)CspnT+~GHAT+mu+NUGXUKEWkaxXak%a|;9el%?meK6xJi_z%s`CDe=iM!#&6`x|4w3W1c;0|-eQ3-8WUYmsFG0#g5gIWg>5c(HSlMC!X8LPcZapeFS_ zOT}XR#*+GHOJ&50Dft&mWyPwYG4-#O%8p&>fqLIkIk6ZzYwF)Dl^eT+yuVv25vMJY zRL@v4KYk^XFiIB0|C6#2B@5$UAsIE?xJ`>JFEhM6%g7!7Dg`5`09q*-Pn_r3Mi{tN*n`3C>B{E`qoaddU z1{PT;l^R%N=^`0eWO;*RV3FmIBm;{qe<4|HMoPNN;(YU!TB3PwihsaNmYI_Xjf`ma zBA-RVX$7AGnf5xe6phK}&-5Q6-~rL#8LwA9^L}?47qVxh?qXfV4l={{+iLS-GpY3f zTWitSZz%pnTWK`gavvgCvn?6yJS_7WUx0_9{Mag?SmJC$X|^RDL?&e;8^BMQL*p)I zQel=9qyp^T$v=>vgn&MgzL4_omUL_3jh9ZOhSA`~%cNCq039#qZIi|y$64v;?E$mz z3NL+%7PjwNFMS#{(*R2=WYT9+Br+lv`*%{8S}Fr+E@k*bNT=5&Ofu~z(3R=)Z$nkY zevaVuD{T#Uu_Dw}`Zbn{#+H(|$WpOb1;o>rS}H@#DWx}ADl7JFXiUG(QrR(XK2Be2 zshrq1NPU`>78#K%28z<#Y~B*FPf+J3OXbIwQ}R|z6~vw*Z|igT8yQg;GvwX=BcV!T z&ysfsw^XC=+fgXJ>@JYm=0W`JO&wn3L6&CxUIb*BixBWMS*$WI5~sSehv9E(l=YAr zWxUiVMf#b=_#0U*4d@#@nY{kLf~v@B7NS2pTx2!d*&AT)!(Wpx+TrsOxL_;56eCW~ z3UDMfat4^8P-@1AQi`!{DY`^N%fO=SaD)zAF-|En7q;w%A!+j^BM}*CDy}KG3{No` zyaF-5WEgc3!Ui*{B{zcP8BMZ4ZpcY0`HI|XL*^js>K|GOfou%q!>qN6Va{5Gmxxj7 zgyE-Gvn3TdThVv}0+>?&8U~&iiMajCsrUq?^6IhwT|6*(V?B%2Ga_n!M;k2pT%T)x zM;-ag;h_dEZw-87!5vwLKY6INKQKLS6v%ROr}!#8Q(+z;>nsK@vVJt$9SF;0 z%Bj(N=$$Lxhv}ULZ-IG$Rlm(hGqL)bQF9Li%>m4K2Se93slh`C8ZEn&K5sZCrr^R0 zE7mjLz|)y8nl{84n*!yuUNH7AU|vekTkw1Zbyk>wSP^%v#}K`UCLOLt@P z_SwT=sbu@~RP-x@m*+zt2J;S^3DSei9aQsGV>0lrj+v-J!Ty;UVZcO=O5n0IFC%aw z#}LrW*&j)BY%q@+4i5Z=I+3G;*=smFlz^_}_+TCrn+uWc-r4ADUl(PUfO&SSXZA@l z^`IslM&b`4XFLN2xsAjsQBla_B(@P5Jp7ZzsA2`KL0KjvtL!+SZ4Y6`djdHaWcneF zIcQ785-r2E9`OxN!nCD2C>ePafwoi!rBpn*)RyWyQmWsB9=ZUr*)FJ2n-DAYkEW*k z%{okslc1*H2ALbs?&kY82TYxx)H9K|>5mzi&B6C22mEGhbMSr10l(GS96TpE;8~wT z+dg&<&N19dW;%^w%CF$MpQ*1y>Vr}7ol^1qetR|shhv5VHNVzQJ^)F6KGj}Yb{O<` zQ2Xang`rQYAGh5XMm5hfMI^m|m)W+r=PMD&tfiJHzsTr)hwR@9jh-fmM6#ELpIB2@#5 zRnt3i5z5G_=_5WKURlZsg6SLKjrk4GlXpNX_y0487^%+Zt9RZ-9JK}+erqxX5%V?V zgK4+p;u$+;yQW_t>A#O4re7fG4$v-Ez?+a$ zqe12=R_^eKv@=uez_kexWeqmF$8bsYaRf2d;gTwk;u$UWXhuY2hPAzEC~sQU6xtxN zy{Tt%gUl{gZ+S$Tm5JPlruicix&kkJm{7SS)Rz>BP%cHd7!)gYe1zstT0ouuHsYcJ zY1xVSf0Tn)wN*=%598uVpyo$Z1hv(o_B~R_f3@VlKkg9LQ;j4t5!9qDh{t+*3W7oA z`3yK$`YAtkvE4X%tTL~$t*)@CGDZG^~G%{*dc1dyAfHxrRR-o+Rv z!95NmH@(^9NW8Zhnc26OpE)>_Ry+6*k2qT`G>+n{0T?6@{qM2`LrXC;`c|e_pyTv% ziJ?B6VVEZGKO_PvoMrK zPB4Y+g*+6TF5h=gk*XOTBvlnf?zUPv9ZpKqBML&B=mbdc*m7ia~b!&p-`QqyQHL2>i{} zU4S9{Wkt&Y#HrSgN1=7(^9MZ?5Xe4Nffbk=76?plFv@gXOo7O$I{XQE#gV@d7g8W> z6Yo3%e-zln+|L8N5a+K1{sOcN@p0_-#4OA6@LC3ae9Hy~fr)m{cM}q5leB8^R~&eBrK~k9_G{Mr24J3)s-`Ykz~ueU0`8Kc zR0n;e`Vd0ime7R+Tfk}-@M-BT)r2?1dl?~LN>v>+b~PKjO+ptE5|YE}pt-8qTw5e` zA)#7wSWS!7wh5|{t~lm!8!q3QcW0Cy<|Y-^uBvz68Fh8;Xjkzf%-+k|bxc>&!gM2~ zV@g{1vjrD#9}J=dI|{b8$|z{-VcrSkw?Ha)UL}A-2BaY@j#=V@3pbZVkb5<@W>GjBB}<1>6NTCO)et#e5Opv;J%%U*LrENZFIPm`7!Y@<=W|k%2px zATNi!WFB)7lrP+Bg5@Twkz^Y#=7PvqH{q1Y---(<6UYu(b0qgp;m#%S^(k!N5k9b? z1REz=EBg?1#BvFin`|w|r9n2bPl)9FT%?;XX(w~eh?8+K=S05#fgkeLk$)jB#X-iK%4ctj4)+6^&1%_ZpDR+Mu~it1b=cA zpzNKvkZA(h-7_5s%nb_!nP!xSaj{y6e5({rf&8a&Aq7G!*eDc%ZyOOxV5Cq{8RspD zGnc?aYnZFKyXmvC$yv}o2<*p|;;r^7M(w8e5H5`Mgu}RE-gRCJzE_RfO^OQR2x%=y zWe_zoGoc`oHj(6$hh!Tr7Lv%9Snwy?p8Q*Jp*RGxL&XWWa~;L}$Le_e6Xz&XL&xa3z7o+-|K6rXdS zc3fLy$5h{hQR58bDT}MFc*hUcIWsszY$kEt{u4e^xlQbIoVk0?Shv7 zBh1Np$%W*LSp#CU?Y}nh7P9Nsw0zNW8fZiHBeZ@s4YZ*-x*K7m{K{4vO_vKzddW?nmi+e!j_m>XK~#&yfu!CI0dyWn;_y%q9Ne zn>Un=ojYyZB}Ju$Wz$PzYl=pf*Zcj8{jDbU+A@F91G55G?GK3U^*^`1c+RCWX3U;G zt28N}QS9g89HNYwMX;Gxfy<8<`)i9Ql#L!U-oL)MtaJ4w_ilgu1G8c6t+0fDE`?b+`By#b zp4l@>X85aTmXKxt`!C-_i*-NuXz1-L>x)Z4{LG`Jw@22KVf}m87yGySONuX@_Q{f2 zh+4L^sASyO5>(4dn17=IxkzepYCF*QYi9aqEfnr$lI0~uW6MfPVrxofFir{o%vd(7Xw2Mce%6v=$TK9>+P4#K z(Iqw{b^0YG{&mH(XQM%pjk4KK;ctHff()Q>oqWJjWS-H#<<_*k|21~GP2yJV&30z#JQXxm9`ZK=@->7dE-j;-rSJkZ5?EhA`&O`l=WKI*ECX)M zJhRv?bF(JCaNCKUvaqqLo>s$_H{ozK8gqgfKIVajziJy{ZLY~%ylM@yzkKC#F+sPw zv1Lt@nru7O!k(B43mckJGjz^09yG6D@sbPjV7>~LDi_zTt*>o@c}Zt25OS;mHVst< z7Pn*wQL9{HjRcZbS<|XjE7ml_h6q&BlvKcIT)C761#4T%#K54nX?E?ZhDMKRG%as! zg&8g6s$uz(C2CnsP1#|^pa$4RT~y!F!%kb{y5+P0*D_92YyGj6D-m(=swNZ)HpN-u)f1CyHlzi8k;-9xuy*YdF=k^;$XPWlxYMqOjY3p1_}Z5^x?0#Zr&o*33VA#<1BQZc2-1dlwLN9Of*4m7D-9`$gfXWP; zkUWjqLR6yMeli9mYt$CrV->QslFbHz`bB6DPwj0=W|M{r7q3}ei*C5)THHuX9mWtL zxn|{>md1v0$)QX7H59Fobc37of64Y*1|QYx5PyQ!^7u8NU12 zDKe+(ae3eyh60g^(k@(<3+GS$aCi=6==ckMIuPk@jJErm!g=D)?hH&Ck?)PM_Owl@ zn^SI$Zn631RGE%HY;B%G_UNW(CKAHMv^0j_GVq^Hhszs(#LX6&SUb~q;q3@#I#V)H z7G%)nnZI>jmGB_XE)IV<*m7E3uB|xtM^?NGM&r-_kWD(57vuoWcvxpHHj#t`O+J4X zIGX&O_V);Umd~F7*4g+ECx0ebe(cNVqnSVUFGn+f zbs?I3_A~3O{w*PzeD=36|5fxKN0ZO~=|T7IK@aUgbG4Ln zj8B_+Zj7UTE*y2^8R<`ecHd3}`nFkq-Y( z%@>n-p=WIIgo^QJa}L2LxO;#GPjfKj5oe$6I$gu`?S_?{f;Qn%c`Z!DHP+%6XKl;% z_06>v)D=99|Lb1@5Y@eDX4g*$!lr5!DEvjK;Og$6?M^ zYyAz^uAzx&B`}d+$|;Z~*DP;Xz7})dV0xu9w4_>{m?r7dPs&{AxqY1&W1=rHU1bd{*RQP~dkT z+PmYkg6Zs1>`;7IagX9&#eItV6%Qyrt$0xJkRqQo)W1hj?0JFSr}Tcs1By>89#lM} z_`Kp_#g`QMtct+T*H^Uj*FhYIdxqiVcm+m!Jib&aR$@rcEycSTU}O+Ji;_ko@R<}D z1Ec!HBHV)-&Sy~s&;PANOcI`F_}O^X1{?x>pY$ZO7oI`H93pI66cRDm&L*A!Io`~XOOYv`tT;s*`#oiw9ETzTX9%!+*2NZjIz*dc@uy z=)Fpdy*n7J4nfBIqT(}(zf}CaBA3-rE`|3k zFpC(mD{P27Cpojl~b7sfM&bKGNik>Yto=$WbXrHVB~ z$S+hr4`U|Xr1bSlbB@LMw<^uAn54g;G{;fW`<4E#;&a3ZR=FvPeLT>q7-#uB$R;9Q zf{5^ZMX{HMe2i26xkS)Yl)gmi8l|sMdJz$NRuS=Bxr2!3%-uw!^F`%>R{RAK>Hk)ddnTwagNX1f#cU$Co6ri z(pM1?-`T;tRq1Vt4-pan>q`HVqS(hnIzJ!{d___0-+>nUcZkQIaO9^Dk&f8G1CAgK zeu;*cD^4Urex@RisU^Kcu~kv*;Xx12qNScM5kWtq_?XHaRD414Cq&4@V1UR+&aiYQ z5%K#d_9r6U(TWolFH)RIg#496=xbDZx#G1%#BWo)LvfelgG9uCTJc39^!!rkUn~A6 z5qkcr{1_JAQ;wS*h`EZ~?m&8`;$p>ZieFNERuRLdNBhD2O(ylm=XJ!sON)%O%Y#Yh zlMfoVgz!1vCS9rYY^AG}mU#{MtxE4uKHpbS-vOncR{ABSk0^aY={J;)GGEXa)BMT& z9JHICPgnkI`quhl{MIYO zaj3%_R`bTGjA$HGr}C-)lU!j3xW zN^#MTpDyAk$GN+6)JOh>iZ0w>-1-Ub3Fn+X{M6`Hj;E_^0L#I9$CZQgd>02^?+AW4 zbh*ric-MsdlzRf1+j^RGn|jDyROopLMo{O{S_V2?&ri>=_cHUxDsuVb?+X_PUat}Q zcn><~c()_K`N9T#8E{3RNy7$0OeQX!Hci|~Wv3~v~kJrPB zPHxx)+}j9q&dEK70Q#Mq1-Yp?v=57GqkJ3I2Y`YxKQ2S0^RrN8n ze|iF8u(=1@Hn0H&J2cKtjkW934*M|H)(Y*hL}43-{1n(?fnA^9z6YJOVME(25!eBW zcpE!ov?+6tc71A&n!1jo$N;ArPhznRZm+gZ+UrS4SUnlA7X-UP$NkbxolM)$`tIwr z1@s=$io@>F2FOKVhYGfT9*i`1Jf4QQ)Z_9PYi`HS{`P*+(jEO?$Fh8{y7Ty($d~c1 zJ5IY!wAB=?-j?Dw!=4ZFnO3){(}%4d$!}Z7(G27bzl^$4kT2T%Nz;5mAM$!R()NBq zyI6SYh}|TI8%t>uZZm#DUUk&(=y*IGajD1Ui+PH5v|~qgThcK#-hkSX>w|7OWZ|}Nj39+p8~R{q?XXWJ)(aEB3CcI*y_*rn3ww(38cu(COl_y}hc=f5NT&WXz+TFW3)* zEOlnVju3GNY>IibF$KPl_Cx;|w2O9_E_mhy?J<&==5` zywdNYFSUs+9&5X&`WWod#W!J$rG(*!wDKHp7Fh#@LsIi_U$}iHrgfb*6au zN&}{N_@)4+c-|%zP2;{!nBw_71pP<~O{N5vm0qQAq@6+8UQhL3oo$0gTi@%{he=;danb2Y1CvKq6YSN zULf@s%gc)W4EYJ{?_2}Lf&HDS)bckgnH&2PslQt)5%($S8B6BJ@1atoWI>#7OG5T{ zxUCrWcb)^#{to8^u)p&oAuHk!kPPha44`mee`hQ+7}(#TxulT&onsUZ?C;>=9)XV)nU#k;c&~MxR$DbR+^0>9dSO_a#kfCHHaPp{ zT}0}OFDeM>fF!&t;iY6BT0HP)vfzDK-~LP%6N&PLt^cCNFN}hHkn9)5E0JCdBE2Y) zQllM+lx;F0Xz~nfn2DQb!IOY~F#M5EP6DC*`9!`4x8@oI41ghw$pgedMt{y!zJ>75 zNO*N5mhf_BBkU!FK_t=&e`>Tp(ivEY?3zh-Blj;L-WLf>Vgh~m3fD|x%?!fM_Q@Ua z4CdY+b1uV>&wpn==SWoMkzEh762Y!ko@SESOE`D%u3Y3GZmg3O86L;2VhJ78qu&8At=z78TD!@5DUZKXiIUK`!Tc5 zZHDcft68F35j2E0v(42~1d^E)6Ou2Qb9tJRCC@;a^JxLhi0vkG`AGKK1Of^fxQqs7 z5|1KiECdrB@XVm+E_jy0lS3)Kt72ZSm%Oe+&PK7yW`kAA95N1y0g>6Et;nNXZ zzzTZ^l&!L>a+X2fRoSN?z!DEu#HEnX@P z`yGPL>ck&&Md8bUw!{zccN(so=OH;$3V&H7)`luDWo&PHtNrc!Zypf2DasavF$C!Z zLwTQ`K%^~H{|Mh{4ojc_iGKLg23{f^o;#_UkH__@ntecPmkB`izMFA#Qn}m6lOq)A%t3ByJiFQc{$zs9gHTOP;h@-Hy@1RB@CueHx2#EP-etrWYF7+ZtX=aHqD_f^)L z^e(nvd504yPl}eamzIkKiize~@cjpE1hzyu2Vg5JVlwhpn)eU|W%}R4&IG56S%Dda zO8l_yo!m?>o9>+zi9Tv>0GseP6 zj+|-_Vo;z3PmaLK0D5nb5$YcjWRm32o|Y7Fh7ye%B%E1?;nu7JOiYxCjf)YCzyd7j z#p6`+gQRGfVPu#~Qv{>J`Z4y1S_l?6GZFYEy$X|vFiU?$fHUN>^EE?}TL#sKGMe5yweM8!qI9vNj277RS7(UJa34+Mr}cD76Jw zD&Ez!V1GCLcj7`(@mC!6p2Wr4A@WHKe*#`{ZnAd%>vD2Z!$_gH5xnGQ`fWDY<&YWX(~z}H+-m(9#2wb3Pvir^_ij1} zuXT)g02h)VkdIxHj++H?x`cDUz4454sQ z`O7~PaqdQV*rVO;@KNDxyjEOn57wh|9~RyLnLW7n;(8hv>+X46ow#1Z<=hGQ-^0b~ z&$WQ^?RI=*7-s<)b?{CvhaLLq`+0;(6 zVJ**;E#;o1l83NMDSsw5UERVRTG+<5mfO4XHq4k+>Mx)9aC^y0KR&bH*y3?xDvC<5 z`Kr1CGOHidta=Z>($*d*rr`_;c;e3J1CY#8(X zFRyyJ1`*7eZN6%?V>ey+Y!zomVFniRxVAPW@|=m%j(6l@1e&Qnea9W zx53EOd#&nB?jDleSy|3)iCNRV{Wa)Jkm1;kF!PL-!=v9Z=o2mL&^~HJsSL zg50;Pw9O*LJhe()gyO}b*=}xPd)CT!7O9idY)oM;f}KcqPfc>CiEOCSMXpXiPjr?I zLvG_ukKJCuP910t_RZDSHZ)={7?aZ-c=XD~mecQB>sjJt`RxX{iXCmN$=W5{*&}h2B}5T)J6f>6#%+2-rh}bp=#Yz>Z;(Ps z9oh~lo42@Kt@figZ6&wuXy0C}8ALLRLVNC#S(Amrj$#66VC2V^3Xwv4+ME<`oBHNv z=IwuJ?@w~NiqVg=!0?J1k0oBdnE`)D|eA|HEsPT5COfN(lK zC_8~uGBe!npZxatrr74RTT{2B+!39cdC+7~5RQ|EY#=W>KK>Ix>^qYEGZ%~oA*-c5 z!}sDT-2+mWOvmm)Vg4Q8`H0-Z5q7?ZS1cjt%h%l?;M6@E_;D6;r|#JZedLCmkFT3& z0<)5F_~kTk+`|!er|$9So7~mGKEO5otZ(P2mp|K`BYnsbK+^oW;Q9~aSAlkp{EHm{ zB+YO9u0K&eIVV+qEztEP@|S~lj`8`v+&R*paRiX`y*=o?pk05XKEAwl{f)HeZa9p< z`Lc(>1=Mmt(K}m5pd>4}Idw2`cXL>RPk_*)sK>K_Pqy$Q@RZRl9I$jv{pyBfRxy@Q zcQP#*UQjOf-CVrG=RKL*-|mac9e}T(qzA$>25}JhD0VJx{stoGL&TwWVw#H%kc0l6 zi-99SM0~zLC(U09xe3p%CmxPpCd%Id90EDK2Z1Skn~w;(DtjN1pB0G6g2#1BLlmLH zg+ztWE?KB1U`;gWI#6w4IPSDd3*uh^t` zy<)rK-HHz??p1t3@u=b(ihow@6}9R2R~)Wbp?E$KdA(5aVj^CAU8%_9A;@2=$dejK zKS)HmXa=76qT;KHuM;8nJH@w%&}%T<6J>okkmlMMAMgGooNII#k9%h$xH+pd{34|n zD1W8mYQ>v~(6?FfbBZ*LLVdC>9O)cT`f0_3D)$q`SBQ{1rZg6E2>p)IykVIRPamLM ze*^08B8~j_8-lK?W z@*>c|=O6RU7Z*g%uOb+PF?0)Es&s|Y)k^dEP5D-(*D2kh^utQ;Q+mJBAAddP|34OR za*l*5mggNn_RWP~IAM4YHyD4>L|&CpnAhML+Xg?Mhm21-G}|fbHxHvN!j7_ZV{uU) z!=bnjlVkh3I25EDZDu*=c0LlDS!SCY0>)nWZ@C=uU5bx5EpK_nU z~ny z-zAC8-3qy|bG&aL(D}*V0=YvWLDmc1*Kmc)u><9(Lm11!xf$hHu5aT)wwnRsW~1Yd zaRkt%#Wzmu`4hF^^U* z#fnSktl$2fP*EYlXP1?#$Vacse3&;gx;yU~&YTA#ms}sW3~K?8Wbw>nocE_^`*}F$ z4qbXsqV)c*NP6Gn=nLulJUwp`Yx&Uap3Jc8@Z>DUDAod^=!3Ynj_dI%5GZaH%lPZn7h zSg2=SaxE#-Nt`B*!Ma1rXCN-u2TF1AhwV^+tE8cEZOIy2)8sX-UcG8{VijIM;O%T; zWXmL6K{#KgxWG7?(YAKfY=g(pTH9x|T~9I&Tx22sq`K9DOCW~Tf^kA5?E=VRwcu3* zlX{^9rm)ims|8nr!fHVtH5G}V`=m{*r&3Nt(<+zI`x?DB^3IK%M}eDovqip4@6F;J zLxJ@dG4wM0NxMZtAA#bu4dUe*z_g7&1`kUQI}je>s=G9|^pK^Gv{B}>lu3z3o+0}l z5)rOhN_#-O+o*BxRSf+u{-k}Kp{Y^+MnI8YWeFM~9V?wo!4fcc#^3oPf@4p?A5R`0 zxDP?`ck`JKoX9o@7=O=Fu~=^?i2vDA8L?fI{EMZsVvkYFUoDj#Ta66I-?vmw>==1} zvs7;ECC2-^r4n)ec!+z(lKFAYz2jK=An6yxr!i(k$-;O#vlBJ)0|1K`pQCW9nFzoE zYVmK93>GhP*oX&<7yrh%ndUi!Mn+V{|A}O9c;K5PgT;$CGgsN>T+w`SoX0=La}1YF z@$f)?*@+J~KNnTiaW4Oek2Zf2azXq(l4F!y80XTy_*fG* zBOWYX98a>$Tqfx@d+GO)zB{c2kuu`DSPik?QNjJTM!eW3De!=;kZ9~MvmH7YP);h0 zvIF#DzhH4PUPG?gQP>qEbg>KNy2Rxm&XC`k`Oq9&l8I=MN<>JX^*j7c;{uUb`nt!M zlk*w;DF*Wp%5$JE{nN5#c|_Dpy9|O0dX3sc`Cme$SHUI~l*Kcn&l4&Z8_sNu{jyLQ zG5*r;Rr0t{S+Tc(y-J@JDmyj_Y4$4HCR9#rHWc?7cb`zXvG*uhZc|9a*dV~fyg0y+>_6>QfD4vs)r0K{7fz|ho9ky!TQWH!$A0> zWjT&-dZpmu$r%1-^DF-3Oxo1}ddiMRA&j*Si^!Q)_@N-(1HCd!QoG(?L%^{wy~SGDWXHU&)xCiK+o6mvN7hpmRgF;aajB zW)06SFCUkAy&69`20C)kE#UdvJJt{W8p_Jh917i@`y-HiKRDz&@bG@aPr#w%aU-sr z=(ck`P7>m41=7`~oSp>B7PfjOPQ@8?`x%ZpM zSMDDX#Hn8H-{D~o9!h4hq?tToEoU-fPe%B3T;@T8RB{^;^nH-ISHbfi^vr>01Zrg{ zrK)YNO$ARs+P(u>w~JD9*d;n3uosuvbrw}|i#Wd*=MIIZ0Uj?wDN68RV;IS5bwL3n-+PluH< zW!}ic2ofRoS_)xh6Z=LTJngv58$*`?-UNq@!2I>Q0aa(V{2EHmV1FI;KK{h^a6B_+ z6ivRy9#LW`3K#pTCC)NpvH(XTN{?cd7tmKg9R+evjW&F{ zc+r8pGvvN7tPiV)w?e^4{PD&Zp01TL-|Aq!6!0DklIsKW4AY<}qd{}SDiF4;+rUUL z&TteoXPLgxbjD8mursVYD^_T*JI6bdXF#!TY~UEfw_@oB%?+%JRLp$}_y_kh1O7*r z;svKX;b0?H2%2Q@?<&><+O2}b9XX+9*Ilw3@DbZ~$9u9+&lYnF`ULW4O zechrtcZ5=Qu*wV_Cs+-J(WN*UInfKRZ-ONBI3Ks7ET`vkw}I|hC#=V_>*WTAMQ~ra zb#+*WX9Yg&%%||eIj*GZwh#})#R#T=8^e-WZ-sFfO;IwKsqN! zo9a%6e#^BZZ5@b+SF!sbkUHoGh~r3Hg$o(qv3@sw7vsVrBSIZ6%Qy(176W1+#4)lJ zuXf^CRdx`e&*KU$FzW!h7Z-A$1xPAz;UUpn@NuKVvC^$$%FeOC3vs!^epEP_^0KD7O!MY%jy!Wpeb3pcyZC<)vH=sO6pf%TZB!}Yt|LP{A*+V zqU9wO#S=?lDLDE6REgy)7dNeGXe?Q@9JW9IVVxT5ACHjC0X!d?3B3LdS*2dgcEBPlMXJq{ijY|-Y9!{I2Eg=zj(fn@75xlL-uWht} znn+kN_;xjumB3Hvm0W~m)3A23r8A`<1UKDLW3YVaHN*8o&)u})5-}R>`!C$gfd9av zp{T!oJ^g?3mekDhCl~vzuo@jp_+Lk8iht1qU_I+SIRpNGS^q#J3ybyWp#@=gasq9Yr(fGQ9>&txSoWoYV3j{m~z9SkhQh$T>*o| zl&f1`gOw#H>tgvxxq5A5Lj@K*bPpMi5X?)tlq9s^#oA%USI-+-7Gr5dZ3|b+a0L_A zW3(<~o{_9X;xZsHl!~yGwA)MOYH~vhNu0%Iw1~XRu$IkFV>BB1ZmM6(EXfB|Yr&RF zqOg1jIh1uHvUH}kc2Uy`yCSEx0Xlmuf?^f3VnW>!N?Wwr>>8b5d6UgJix*nUgoP`3 z;Zj@Qw7ecRb-DCN^8`if*x^{v#b_+gT035AjncVQE}_Lv-PhLy3t|v|`N~zn+83!t z7LjcaW4?>KnZ%Xsp1No$sa#gmU=0xN3>!iPt38h9PIHz*^P=dv$9q?v!hZu*|0& zsCxme5o<1q>lVIJsx9cmb{P?i1+^b*k(paEhaGy0ZlEa%EODw|u6BZ}Ac6IyL#m!l;Y!Py2#_F$=V_Abx$NanPqnYVk=2r;Vwnin^%YH4JREM<+b+tu3J zz;;Y)*Vvj{rlIo2`fI&V$6vC%iEHt2uVCHHsSgj&Xb&@-U>$mNuS+= z=G!6X$e-#6An6%BX!o{)!Q{&XKxIf@r+xzIwLRz_HN0$s;<<`^^~Ufk6lDz$=oY1KQT&|Z{fdt&KB4%W;!hR1VV!zU zD*C8n(tQ;9-jy`JOA^mlyi}3a2pHa^D7G9y%NicwJsQ48@mq@DSA1FVHN}&Pe^pGw zESUPa<()V}ah2ky6gMeuSKO`mHN__t#a1fx@S_m*@jDHX--U^sUlTJGd15N*F^W9V zkThTA5a%f_QsnDZhTp8XRqBjZ4U5N(ipaXtKn}d{#o&Fif7`6WxT$MLy3qdYjkj5 zmuUEfM9}kq8GZNufE4_>e`bNb~ieeiQ;SVbPRmCS1pHV!d zC~JPuK3$}Ne^8XQKcLURs}qKoDo#+WQCy%%+qjgIwLCzv=?MI;hW}FWZN<-U{6Sjx zD9U&O8r9@+tz;Gv<@giF10bIV5j=$Xs*Uu=Ut{xeY^H_mpso7f({9>HRFQMIg~j19 z*lpcI2P$(N!tA>+`$h-NbIQ6Ku8R#jM~+1xg5 zq6=Syz%%#~S)EJwe9#Q8((oKSl$T*VU^&=-sE_%YgUiK%*IShi8^r88>Kv~gwDXho z9X$N64+S{yHQ}eAe)t)O?ML?}GRIF@ z&XLD!kD`;?g~?K(6H*@K9#_9(J?|#P8bBGk@8NQO(v%D9b6NNfc;RyF3)LTIo6keCUC{c@rvwn^Yv*h5;N@{kYj5$2$ZxFAYKt+APAg&{sm^$*N43^X5NM)-kdz*Y$Pz*pg=7gRfQ0kN|eKB$Qv-M_z+vYSJlsqY%h&aYgbeQiWr$~`0US`6r zk!S11CL>j`;1S=d8i`EdC23!bSl*=T%7?=fI z3S0)%0{SP}>)#yUa$r92IbZ>BC9n{<3RnVM16&JS2k74oUSPgJ_(kAGpbcmTRsuHz zw*sqx)xhmQ2e1ZM2doF~05$;ncefYVzXxA+)b(#X+4TDjkKQzW(B1d{`i%F-?L1@M z1r|!Mym>)Rb9JlNHUtM(E=xP79^TfAr4E=b^OAju7?6?VA zes*Qz;4>~w-81^)Lx0dP{%coUx^d|lXa4-{e<}UTfBbsf559g`+Z!juUj0F0&62f` z+&FJY`^9s=F#Mw5-*w$f^)v36yK?hG2OM+WgzndVKk)mj-x=6(e*N^-f4%ru+lM~8 z(>>_%vCRXH{rqok`}C6aho1KK=Q2O~#v517ta$SEWowGRGG@SUq8o~TkXd`f^xynu z@>O%E|LEc5lb?TJ;)?e#yME0b?_N1%?c85Jd&L){$Dh9E?t_;?!2*J@cZvwb;<5O{q2;d=U<+>`NB(nUi^!- z=6mlpte81v+&eG*`SG8fv*V=)zjFPt>wfs=XAe2++)q~@I%e0ouWcRV-gLq0_b;Ec zJUb)y#yK|*>Nqui{Y9I49{A#u&;NS$XU3-fc1raTzkKW0H^KJaTr%Rh7HuMYq1 z-%dH=FMrzeV!@{2-wB*Iq5b=pozph?_CxcAuQz&ag%=H)A{*I;ozlOcDKX1z%=8?mgx}P! z{Peu~Du2pidViFj*AM?Pud5b8?TyJx3%|Z!dlUQdKd~QvUedVKKeiwK!-Zt}|3v?H z{mKjb@n799eNaDszT1!9%zph_Eu-%LQ+p%&(Hq&1UR^(amh_`{eqIM9uRHs-U!QA? z&;_pVM{ieNx%kQ1U1hsKvLC&Z`qe+KAOC+OJ?{$EGwKdD1I$z4udl;4(=Vk@fL_~&{uyL=>+sOFH~;e^Z7CG=+_?wfAjMA`xo$PDvgQy z_-BDXjsR8S}nhegJe=Qa|RWU!wlxJo?w5ALHj6^Mqgi z0Q~j!cc{4n`m0!EC-~)u)4v$~%gJvM={s>( z)Yv|K+=={J7~dIw`NR9j_dxT2@EOl3e)%HO8%dA!(5D-aD&Lp4%CZGRC99r++x|t~sVpUN^$e z^XT8he))aS*#bY1vGlsZe{X)D{LX>iO!P6we{wm z-#RMR)b;8AmuYVn{O0K0&3L_tzUIbfAn7UaGuh|wyYSPHH-4L_*aW?tJWJ`{vw8GF z(4UNcp z{=)e!rgkoYsXb@Ld9@9V&5f7OU)<8zJmb7G7A#uWIHP{{f<~`w|0T6^uB{h=`UUf^ z2l3Na*G}^(oUx#O@#4nCroOqk{<_))P_13qc#WA;zhJ?lIr+JBn;RSR)0a24)Xs0X zHb1LriI>&f_<`E>4GsC2ix)Mwn5*pHyoMJvF1);Dp1E>P?P7>GG|pafxe{urH=&Zn z*DYSK$QF6owY67!S+#TU14zwnYM#HaWv)#wZfRJwq(yWZo0}Ik8`4CSp1*MJBJ;V$ zNP14~)s4-I=Pz2=FIl^A$(6>^n!RLht(AbqUo`u3jdNOTM(vWtjm-`9E%jz`4zaJs zm5o={H#IdbZ1CvLYrGbg>YEpPNuNrNKyAyST1$O#3*280qs<7!ESOi@qT%(L&$Uqt zX+$BUIrEz7^WueheJ0sbKj#Ydzjki@`~@oS&A5C?eY4My&jAA7ha<*upY;62wJp~* zHSUwALHR(Y9h}DI`Bu%E_rc${bG41vw)Baqxlvu|?V9v2U(EYf-KPlDTCWq5(-jh~ zFRlJW#IKK;PurJ()U#L63l=T9Vo6hN#XFO8;PpNg-)eS|!H z-cNhtrt#W7nz<&g-KTdx+5W@hXE!u1=p#U)v1Q*8l5A!#TC||C-dF2Ba{J8}KC@;Y z4#a0~UK5(zsN@Ob_CfM1_RICF_RAG6^HJt1Uo3suwfjyEQStF>HGvl{s>LqVw`i`S z`z?$1)nw7}r%!+KUUsdf)RmrjVhYV^x^5pn)ZBjR_hsAq{YhIB_5nH{%=Jv2wR-s^ zd<*zNW$_B6n;%5a+1d}5SixhMZ3zZ!c4PB?tj>H^kJ{NR0{be5&F(c=zQ)+hg_^SY zt=ZhB#>OjZ7uH|7?{M}NU0uIm$$rWjuUb;S;Dgk(&|&K5)-PG$x7D)fipGU-YHc?~ zi|2T?a{214XV)!jxopp(?32}Jy>m!X7AE07Smf=S;VC_6m?&u;ii?6QoO5LpreTgO zVC`(Fq?cR2xKSmRq*pUv*>eqhB`i6!7cKUMvro~!9LT87T~L4dz7u0^^P($R(P3v1 z3yfjOZ7_2dh#u_aNyHyQY^ac}-Myxn@$uT&x6~|NJg0u)T)%mBjcRsqF=BXUhv{ycXw%8r~u&`IERp zE$oxyB^XyZFumxW-Rw(yX0X?EU)^t2yt>|7q&?4|w)R?9#TL^tAN8%R&377_>*piM z1@mXm8NGPX=o8F>hEWUVFI;l1QpcIvM!VqG*3MqMSPLt?$cxKkvn5O;8}~wpNfe_j z#j)n>Dd(JiM(xe8O=f9ZS}*){O}1s z?DWHD{qT7|e9;eI@x$$Y__`my<%cOh+~J42{P1l*+~bGu`QctaeBTcZ&xpid$PXia z81=(s(ktKQhmZMTryoA=hui(|EkD$mmgw&A!;OSPZ)WeSkUi1E3fX&YQOJI4tHNUT z$_hCMd{*Is?5z~CIeSIn5$vrM9>so(@IdxTF@@}*N)@tqD^m#l3WaQ%T!oBHmBIn+ za}}~#t5(R!#uW}^kE(DG`%Hxl{se^_C?*sRVLz{sP1R(DL)qgggufbvbaaNoGWL!N z4`z?3u$+Cm!b8{tDrD0?Pa&t~3l#DUut_2N`4)vPXG;p%zulm47-vZeha0m@;RyD< z3XkLrP2ouP-U>NCSg(+M;|7J*>=zTGesh&EyCbbn?h2(wWkab=*@3CsQ;|JC%r0nW zllbG?yUJcz)wST=C$hPCLtcDVUVKJgd`ez?QeJ#QUVL0$ygDyll^3tbiAYK~Zlr42PWrOkCQvr9~PM(Zp4(mDAd7`JM`{6dnJj-0u zn2!fVRq&s0&S`sl=l3TOr5qBA{1I&xgkv1#c_(^AJQ0OmpS zVV`CKdI{=!^hC2Rb;g)vIu4C5O>9p+6W^K+xR!3jjcv+0?pn*A=mulS^jM#E1$4`R z7_?u9_7v)iXVo?Ct9~2PGCq%G`SHGkbb=KLb>dcHE@JH|{f8@&Bx3 z(dwAZ&|gMeFb@9Jj`%ljM^M{>5wdk}bj&R1y+XlwXvAX4 z43j?Xm}F)YJeWjH7iO#2Ren5~iPkL3MqG7JEgvU@` zkVvNgL|dXCH66P&CTauY^Gw8;H$%?aolas|m*_|i(fA!%@fbCCKx2CPzj}IJ2tcb$ zv_u=;he9tD@1VWuX%p{w&T-cLgputL#SANJ{pEa%R*?_qqjcI&5RJRPdCNq25p4`)9ofJA&69^@7J-grQs~Y}1)bJZpb{M9ID&penwDkXq7ONG zoN8OTj+;z}VjbC+D065dr13{)N2|Zk_xhL9|8|>hVGKjQ?x?(ubVO-8{vJ*Zd4tTT z-!zdgd#N%LTbFG>2aTDUiN11Pm-G}llt*7#-4#mRwEw$ssZcm8@I#MnjH?cL$yEWt|Gmk>IKc7LLr!P_VN7{Ut_BMXOvCnG$8ExLV zpEkpOn=AY_$I<3Uzs-<%W==|mE9cR1(uzB*&oSnLl@q!-5*pK}FFlN5Q)CAj`;4_4 ziPmh$ZOumGty#);$!}9#>2wTzxM#50t$7w>PSpIZr#n|xM%ff-=E^ia%<1&m;FQH% zyP{^@E~P^nGvs{sVAK8f<$bhOe=vHQtDmO+p3jW>P1V><*$Q+;`olP7%Se~4^>i&p zI!2ngZEa6fx)$f?!!HYlSdzK3Apts=@540O((W8 zg`TFLEit=S((a(n5PaXWQ+X!7E?Y#KRl{D}8I8ZTvk*DjHpx@F^tZeqkCy6)-nXEo zIa|Tp*mL`nyN;z@*^XI+vVFq{|Bbr)Yy*Q)REVeO!FwGJaF0z8R3S&HEt@? zif%vcvXoVR!q+nkdD%qxa8NFEOFxhi9MX2 z`7?T~ww?If*=S8eO8qDRuL$~YFb2}^jo5t?Uz61s2F#(i+>tj((GPBivCaw9QdZVFP?e~*;SNvo0 zuXMr z<%7HoPa(5Dt2H4*nRp1%mdc!X4fb(ySI}&=>yl%xqV42y;!AkoSRUQZj_h8oGiFw% z*MF*GESlsSn&K*alnJ)Z1=PV0#LsboNX@dLRdvgTx=qX2MVjKh;uF5*p9kN$y@Rpu z#-?|(mF#BQ*^Lak=`%7nbfc%c0U2v;h#(8qo!KuvrC(Zpdp`cSerfAd=h2hi-$!%cekg?m{SS*5J(=<#WjR-%|`}mw~LK6=7J1+@ZvJ& zs?$24%jsC!)rk#}jKx!oy4y%AUO{||AD7MB?8igIH~MkS-}QbxN}Tl&-M!fE3DhsG z*AL03!9FNm4qsZcCZg|!lrau=&TqH#c4me(YA9=0fp7=eakwzU5k>KUxW?~Jbkeh- zMby*yMQZM_ewX^CHQDY{n(oMk>h8b}8M0<(-ozG&o@~^g2bta225T?0_Wc)W@%x^S zQ$gN4%m$P*3mIthJ@0vf zb%mF)hSy^y1jMfetevP~e};Vt)X~SLWctVGqvjBDLtfteK^=>Kr17is=C;PJEOAHn z*MI5R9d;Q%#!x)(O+2~lyn(V29obXiOa2@>HN?c1VpD4Dx{}jn&#vW{C#CC_m+jEd zK0|v9JMUfXD~4sIzaeuU`Rr+!D{7~lc5*h9d5}5KxBbkeNHmU*iy!XU8P5;j#RfyX zXy2`K0P!O`Uf|m~jT;Kojm_xB-|I#Wy*93b_K;o|?F`YLUN%9Y_^@HD75ltq7y4}1 z=x^hjI;P3mXar4R&p|KO_yXPJ7?l+vt_ZRmJe&Y&FWnd^5t)H99SGAq<_WizcUO9QO*W> z<+(O{0AraL;MqPzRUS0=?Fv__KPl#OO*+{5vlKFVJY1QwePoQ&PUmZ>fRlRkZFF!W zeb%~G#y)ZvVZfnJgr04dPk{e`&TUaY83*iWB<7D(MNQvW$-b7p>-P^l^-p~FA1{p$ z$D?+v=ns1(>7D5g+7Q06vwi*Ru>Fhp{o{PX_K(o|jFRg!$ooH)_Q$fF{`@X4y*sZj z0lzQTeT=?r{Xdt5^Mt(vY-f;E$V$)*)EpL9;;A`f&3o3nmrFus1L z>_&w7r?3gRG%a+@HafW-*rPQMyKU!69rW;{hFLk?xsP6J?Iyqb2w)_@QLtUhwRYp! zp>rDJ)~xn*q1fuKGIMA4ZSu?HyT|eA5}rS&vGc~^HRi(fOrh*6zU(r1E=E=wQ|*sT z{4V&gzEC-Jb#7$sntXqa#~wRx?#wpGzC&Ad?Ksq|=!$cG#LzPaE36)0pNI2X@?~p8 zN9{T%q%yyI6VzC+=Sk0OmpqXPGawR+mY=%{V(FJBRk0t zPw_+a+2#ibt-pfIBtM5Xmf^41^N0@Vx#x3~vi1a85ALc#r{=N$k={s_(&<^GLrv%) zX`Nrxkao5fb$Pa(^9yv;Nw#-QAm7R#9NBMUF3GsQ4-h~G8ei?B+R%xdAMtbMqhv1M zA=0@nE8Qw~@mu1af1xu@)<%3p&Lo6uW~A|fA2H^$R_8=hzRivUr2jKBoI%)jD1Yp^PJPQJ1 z7vYP}^v>`vW^Hx-wNC4X)j`&?2xl^~9l5l8=v+LM7uOk}iBC`E?_+XwMrs`{X-jF2 zIj12{w>{;=up4#OcBDgf?K?xUrP(O!%0}cdlC$OzXT8z7cKqpe*&F}l=Ox-xG5i$G zr-A4#>%c8~Mj@RroEwX;2>PEp-|M{GF&i$>y;tvy*0UQmU0Ro-_&AI;a_0;gov^Y@ zOzL_K9dJxbhOLL)4@cw6S=X0)`v%#FL^915@?G=!T_TACcec37hivGk|M>_A{X|`emI#*{+=SJ&mI33o<%S?>F zlno@4=^2zQ6fevf&ISuubBiw_9Wkr3k;9=wThh5ki$mO8pDByqii~c}UX3iZ_tTUVL8v}}G^4kC=Z};7Vza<<- zI31j8fVtFZ25tm8fbGCr0Ph`iJCrX3t|cBNlx~cMAIVL93)QVih2c3|voaNqZ`e7p z?pNr~g%(HtSA9r+7d|8N`Y_2W&bmsz(=STZd@l@2A zbmXg)^}}~MZ|+(U)R(oi7 z@adU{oXgujgcI}O*B>MLkmLWi8YAqc`XHGGO>1g6x}dR=-!0oOAI2n>r9$jqLb0dq zI7VH@tn=P%pmJ#{$an^(u1bA{wWW6~$1F=3mvOILxie~(XM@b`05S=oD^ACXF3Djz zG7-+^ld&P#FBcmTjNk9gxx_mBoYmP?l&!knv;8AUFC!gb&dBanlfIU8sMSlyNiQI+ zvT?+97Av3aU|+Yti|k72*GbIhLK9x<#+Z|dIryq)tt~RGOGB(#u}N(y$yaAJZsJyK z)~(q;1af0^VXryb58k4#==ojZ9buVS*zxJ24!`QtMLe|KBVoWv#+4!>T zKOahKkSpgPPGb41p}OSHm~U?eNfXbo7B~fod zZvbBhwg6uP9s#}zJPdpV;Qfy7hXCGl?EVt)An*WyRqfsc+z;FbYy|EFMEh=F18^6> z`zYOa0PBHuz*=Ap&;i^I+y;oY*2`OgTY#H^mB3BF3Sc>~3}^?I0&PGma3kP%mHQt z69CaZ85j$U_+!uRiSb`$i<)G^IA=i@Wc$jnH+G$kFSYAI%C~t6o!B4c_oUm=nQyxt z>B0`qTZ#wknPmB~%;SmZ+jqdz+NZTD!#*rGmKXVBseY>;{rfH6_t$U9F4ynBCp-Bh zqLJV4deZ85EpQodDKHDT1h^Qu2$0M^3tR}y1ZDv8ai#%N0gcyZfb)U#0FA}Dfa;zD zXe`bK&H~N^CIK3o(}B}~1TYae75EgOu{Z_LSeyi??uoz&z<6LBa2%jEgN9I zU*nJ0rOZ*@fhw*h9ECkQ(Dm@-Q-s{*c5LMb$bM^mpX1m20{Hln#lr}XG}DF*pl+4> zQ@gHjF5cJ1l=PeT(vyFKPX5~cJ8Xp3VjTAUuHC$MZ0+A`g!yatW71XYfAp>0r~9}+ zAXOfl!dBUJ zJ+Um{G$n(kDLF)I{6p*^HaPe>$V+=(t@GXVSAOjMltrNP3hTV&qVtU0USnR#rUHN? zRd20-O0r|E%k9e~Bl&pNKdW3Rc}X^m^HOV1@0N_LuQD~mGg{~S%)JWEW}^5Qr18Nz zcEV%E)UC^M-L?Bn_~*=nXHtE(T6ae@7q|I-!}ElNu{U<=K9lV7a%8VF8O~O{{!lLa z?=;=iH5z)2X8I7$pv#>U&s$TsW_S8yAzLtr`4>T#o!DvU*VJ^GuV31~%mq*Tsv>Y? zYd()Z6a}}G{jK!vHGlslS!lndy@li-Na69lkaKl*?m_2My_w;NemO6tw78i0i>@=R)B#fy8jKJ)@v1OWLD$a9Elo!M6 z&gIS$us@wT?PKax&R?wN`!x8BT{>esnsKnYZNp2x;fjYc@g_HOAB2HVNZhG=|q1s!J4Hh?WuWw zva=#~YxYQJz;7m);GENrt+(HbYQN&|w{m-x>+ys8?^X7`_jl}_^gWM<{PrWX?P62( zjEl3t;)$n(x=tLxeF=21|9G(H&J;La`{P)@g6xxmZZh+_-@bhKU~W%a^VCk4c5g)g zSX=KY|>I-*>^9f{(Z`qZ*^Y(lKbml-BUZozqN^Z>lx>x>@_|}m-Cr7ONSf|-#Q!MY~7dL z&AG8dxAu`AX96AQLT(>$T*T~N4WUBp08|vzlU|-D-+HpzwCbUU9+-FdD_=}-p|K`6jy}~_x5Yd9hJGJwQG%Eo-@>Nd!oH+o89Xw##beaxQS)1KT|Cz2@fc!W+CESwoU8pZ?#>pM z!lUxU$Fw{iJK<6Jn%^obg~xe*IsRa|_NMXu@c3To;nugPgGX;|nyxz<#(gC_3L5KKPhz4^oa=6! z>8#66=2_UgLGQWNw|zcC;Ee3_&g2a33n$2P-{5JhQU#pr@$AR$3wzf}-#3*V%=xAT z9qcpkPyhALJ>7B58FXkRJZbLt&}ZQlljpMj=^Q~iXYf-mK;LG=-^=i~kns0}&4foY z_ge@*ML3u6azgD{Y(0FhlhEm2ndF_bJu17@@0_jwnL@8!mn~-R9CAIn@`p5!hd~=( zH6xoW***8?p7M9-*R}&0L;9e3JC(jYqJA-tb7w^whr8bOZ7{M?y8-tm=zC{-ciMTn z@A=ZLIegmN-}#b*eahK+*@_$g4!#TTIU9f;mq(C$?o4tEJm>nZerj(odFuQ?dw?DE zQR|ZW-3hN{d3Ep0tDEx=46=}aP>LO%N?q==Wb~{#npf}kkEj=;-Wk*rofviSy>_Mg z`QGx!#H0AtSpC4qKfuS|%e+^coZ)78j=}RF`9LLIXT9&+-xz26@L+WXz06-nbq+N@ z=T{i$8}B@?ApcA@)@jdVOKXyu^#uhfI|pd1Ag;5Qo4N`(8y9bPz?Xcu`QneYPVu1T zvwy~{Gw9>~+|xU!<34^E9kS=D3aN9mpT3DOU(S+&^z&x)VIuR>L1tUSX7|(Dd-&-s zq>su=KTP^&^dVQine@@5RabdQ(m8#|*9G;b-uC0OnG`ydvn#vdDR4?MJ^TdD<;Qa_ zcrN#r&uvfXY*76u?8IK0eb>Awc8b@stgoUovfNw=b#kZlKfSpU>eM|d|7dY)00 zC*rH^efwZ+t?pwLYwydu48YH_ar~-du)R^%fsv_uv(cwkrLgbmpyYVkZK=~ai_$u9 z1M+m(SIt8&q$mIG2D;8+9yO5em5YCVA^VYA7tVp7{<; zHh9qZYW@9v0Xoc_$fb9aJ{Y-MUg%%W-;P2jSksmY#@FnuFt=u>z)!Buuc^bcp5FAE zq&JgxTjdYWw9l^l)63D~nWSCMJzRfHmt46s+`FbD;{fu_U(b&{94Zc1@-(zvD>C-b$YYd5Vm*xYsWZS+j{o;&05~J__`MUAt`C-qTa%aiIp_v;` z?OP>B`OMZ1q3as^ne_b$c+IVetKjd*58>r@pBL^b=)HvQJ$d!cp^qoB7kE@YPh>_0 z+@q_8@cba=VE02^t+BRDtGkrBcyD$pHgXzsDrEcBk*$&~ip@@?;_aCrGOmfgl>L#~ zVqLC5{{yUrnRG-J^`_z}8{J=Z?*Y&<E(M_+kLu^i>@F4 z9`S%5-$s0YGPu^~SN_zc@N35eo*i^$BXy*k;&(G~$w~1Ch*u2exx4W2wf-w)c3(i< zXkOks6Qiq(rz>PwzpVSh4*^wWz_Zr{tkjr;x|kV$TDIjLk5^7ZzBPcaUX zi~9Qm`gI}oMpB;Z|98n7N?*gYW#^>ZXV=(^VAu9NM;OX@iJs==SEzeB^pqCAUm|_# zhwxQN|F&_TCdb#k@YTP)g8j7jr$6>|w^A?1?=7^EvmNp)q?@uU18G-xeZ-f>wH3TW z$g_8S{JhVTr{_z$>yyK~n!FP5a(+xR>AOjn9nXE96S*@#nKPtuaD6tn1dcN%PN;7! zMhNX4w;IM0oxh4T%y7Srch`#PhrMsNkh}`rUjxU)S8%6;IC_tNQLMeJL%0o}n{xDk zJ1F265b8coh&o(v@6O%r)jh*5?keQ&XI96&J4Ac93scQmVKsNk^*lCEw{EBN=6PME z_CD~P*}&1OyX0$dewco5Vj#PDkH@FW-I8JSRrf08?~LVKQEf+QXAJqy(H>7qH>r+W z)5V>`7sRLTvp+{($UoEJ8D=?O1kUQNk4boUf4&Zlz{#t--aB>(>y`IT6Z)Ax9Nf}Z z(8o7d+k1_-i#EEt#I})4&*Q$4_V3yQe;u8KUPgCim-~2E_;{1@@V*3|c<0>P;(O19 zdAA5$7rX*^61}^@djneMl3#PCcjma4j>j3#w+QtuA9+5ayk_#wv-us_;}p8+0DNP=EZJJGK1qdphC8jl)%M=< z*TBiq4mdocF+6#Vao0bV95Rf%sPx-$wzdt?y;ReAm)?;sZi#zqfgK~xKIY}64Qbt5 z(p(9Yq!|0@%pV>C#G%POtYPS0kb6u{XFD`!Ww@VSuKVg|!^g8cAk_P9kDbAgb5Sis z*utW`p2=Mo=i47Z-Dzk&5Jr}ICjz^9i|z=E7u}cCT!4Sh?XY2ttH%BYJHNblA6`7w zF&)R!$k@76a4hf33&wE1J%%vSnsNjFUFG=HRQ|nBwN(UB(IVoLxxjj04RAMbC$Jn?3UEiYdogeipmAoJ+*6#~o-OL!o(KMwO zU6qO~Sdl8EJX}|oDnz#mUR;G7R#@E(xSS{a6Ld4GyX%bm%l%}r7CE#5Uj#l6Tnp&A zNHeeq&>6a(UF%us9H0)!>CD#n_Ox_mF?o7NRPiR_k(%|a@9TFJXr4*e$k$#{I6dQ@ z!G~>6iCzw`XVP={h<&)Vls$%?=pBy;a>15i_t)>r(fX{P?s@jbOfGL4dD}X-vwp14 z=JL)XFT_~n=S?OrH)pn?hg;Ff@6y({srwlH(Ydo^U%;G+GA}fjPEmVt<^}O>;BN*0 zyWoG@;;#UIc`6FN=22X23YUIw^>JipRCW|)x%ns>YI7SjY<;yw9TyzUl^k!6=e4D| z(#s!nKG)_D>P${JrV9A|55NBF@e{pog~-3I?&MiJz6on(m)`r(d+d6iqj%X^i?Au) zcRv30x3a;>%o~J}lfCbJ>^)OHBepjw`^$T;;0Ib+dz*O1RCizY4sf+ED6_r;w0MW5 zBI$iwMr*OYMYBpctSP#uKG?477i6kimu2Hk%d+F@__hjrr;)siTQHdU5Qhfu@&w&g zJ7YW()EdV=f#-p|Q@C93*Li*(&(wCaUtmspX?<%)=R((FXy*aycNP7vN_qVqnBu*C z)-uT<7~i@B7tBgsqO#re!{d%7j}(l~UI_=(7&RPSTe>5P~=x2=o? z@-Ne~sD$oBl4gubNk8lIo*@0?&em?@k{?$c{H0hjoz(t;aj3#B$MF>l$=AE+Cc*xN z@-sQ_9El%WfUS!d-WlWGufsDshv&|$`@x7=k#z!VcREkAR@(d;y(fE%tNjo4)W53u zokMj#*6OU<#XT(i;^dI3&J_hN5b10m8jY_S8gW-CEQkP<;nF2D8rxgoAq-Cez6tgV z#`5sxyQe;OSazcJfa?1=+R(ch8bkG8eSojD!OvD-Xe)ya*zG3BuaUg%`x@K}ksV5= zze-so;mKV->`40f-rMK^;YjWVxjf6N(sMHU7NxJMW13b_wt})1l&zp`{A$MNKi>An zNIqbkadN3f>}T<75JE9L zV*|PGMp=lmkY6^CvH&V2eM$B=0Nez*^Bb%HU+-}dxX&w1!i#>AIp_5PRggSOmDt4#UQD;xUn=dy3^ zVh-}WsPDa8%?G{DWBoUGPU`ewThq9opAH1rJ57`CCjHVo0qvA4N0zNA&b`tFZZds})&2GI=`+Fj za@GW7%~`kfelN1&E_>Hf@B-W;M9&`x=o?wo6`kXK9{C0qs=I6`-?bR3J(a0RWwhtu zn-m$@FxjP0O-Dhn3EhRy!n)$D;72^AY(8((OXpJ0IHmPKNN1>6^K4c1dqF zehS;;@~!kv=*8(^GWjjeZsDsVJILotJVlbrhC(-nPBP_Ew%$N9>Nh$Ed7ZW4b*%@i zg&Vad)NS0kt%*Hj>dx$A?B80Ei9;I(9!(S9K&s)rBlfY5%dblc z;EjwKw)z=s=M%}a?!K!(1<;A9E;LmyCLS4klSn+cz4OjkJ_^2_%joUa-QN3Wk<&J1=OGvEf3-GXd-zV+>aNGZ-BY8z2=ArW+|C_a zed~m885Iv0tcy)Zy{PUG4Gqn6+2$+#aL9>9#>N@b_S z{J2BBZJ?h&kbFPx5N|uc&p&{CKkg83i~9Ld^8L6&ylsG=KY)Bc?htP)_VbI$_u~%n zwjw{jh{kTKCjd8JZHst$phj@T7(ELF+SYEvM zq%~fLyR*CExpNBHV3Qis#yft7=NNqVrZ|YbZDpQ?nJa5ekbTW*_8UBblFBYrqdPEW zcvl>pwgm4H)aaaQ95yWOn9lVjfzCTho_%3Y$#cMU=*Z?z^DUH%TT-T`@!MhSTmfgM z0oP3hYsB$^%!yzt(NeO=9V;fHNc$^ z6a0L)xy!^eUE<-h;OTyZFWr_ z0#2ZF)$r-yJ#+ZCQh}+C*0_sJ=MD6Ak8RTlPtD+;oE#ve{>cx-wx;XM*7Sl-c*GxB zb~Ir@bLIk`Ck32YnPlfySl-$dDt{nV5Nk`*r(LT$x2DOXzYnCGF#UticdgAHlQFR* z_{m@i^U0032L^Di;=0qj@T(t*x@)`eh2AXfT-p_7+)ARHX|sor4^@f}>UPe4wS;uM zqU~p~0PjB~W~4&pZAsdFfOa3|s3LuMVutQNJ`zo=mt0;bg=g1o=!%Du>5@QedQ9nZ z%VRXr;N_zmC81X9PmA|4;K{dEoGE$n){oggPGD*bJ*Ycfcl+Lu1&=LM#gpqKi|NKfB$yjK2ntG*{!9Aur@ z@)R<2mk#a?E0?C+`0TFOGmMeOF36ao69MMhXK1sDKKFDcGleg%%2a;3A~pQtidfW) zD~X!pOBNY3Kyxx!SD9K>{#1I^$}!)UYH3^c~*1i=-X0T`9|J%QsKHUr&bJIntrIfExo)T znf^v`Yx=fqGX2-i8C`|ZS?#Q^w*;KaGRaimylGrzAwFTXd*0gk@ z-%nBgy!bOId>Hh5CVG7W@2I06uLVk+S1EtpNS`S~C#~+|A9}i9)6f+=9$88M3tH2G zN^g9=G^isrru4y7d+Pr5mj-n@;=#@d;g16!-Zd|v-z8kxm3&-Rc-h<1ad1nHZ%=F9 z2zN}V6MC)t(A7M`FDMVxJ6)dc_u7SkY;YL6Va)OR=0HiHK8TOXn8&|_?HIzdiZeZ& zc)PXljAeTG#Zk^^k1s)=ireZs((QF?OE{w~m)yjI=8gKJGR;NJN#WQ%1ohFma%XNw z8X0k(dAyyI!MQv~V18+yVK;hd-B{YzI~PS$=~EACv-Ceo*LWu#U7M5&rYcj+(X?#* zx$rA{?o3N&hL2sI9yXyp9jHpCE2k|_yR(+3O@m}O5Fhvgc)8H|YhrU(a0+L9=+~F{ z-tlag^12IC!J6k%xwI2z&iw>Pk)Qf`Do}TpJFq5M8O5u~;q))t@)2d#&PUXvES$O{ zjeRXHV6S(?Wy{my*{qA);eYVd_Vm)qWV-t4t?7SbEM)f?pK?CD%-F);Q^}0ZXq9h2 z#>^U!n-ibr%pur$K`PLBp~+uQB=10aU{~dVx23lv)_>@HI2pR()bjLrLQglwu@5=k z!G`gU$GEikkgdEOzBJx95i-`Ysq)V`b2?sYOu5GCO6ugwWW#d$#kpg7TcRV)S!#KE z&Du2QrseqO-KH~@Vg7eJo!D1D40Vpmwy|Emh}~}Y!V>NIL-@RHo#<<)wb|J7I792% zYHVOe>jnGYsqD|3X9guJpBa=IAV8)7lROf4nxWZ{)C7-@!ae z8`@Prbng$|Y+t#H%I8ZM18n4W?QyL?)O3b}oFnY{_mY?MpCWti+o3$xZRH&YpTl!` z><5*%j=c6P+-1KJ;%a{d)X3*ark|i6l2w6`Ou5I3-soIUeo3HYne0F1-WsO!1la`xjT-hR zhWZY4X7Y`v-|7snE}0&xZ^2Qn?;_f747=bkHrlhv_o(N6d5nO?F^Q$=F!fcYeZJ-d zz8bG&>^V(m1tXhigK`JDCc!uHpylB%OPy$CP?KR?z4KP;b`I+4`KWrK*xY}x-iq`; z)?WA@Z10GVtXI81xx~Wwq$w+(9IraBmArI5BH7qylr^SnN@7!X`Be7eXC~8=I(UYg zWDYfTWFHMK)OzMP2&TDzLP%<=>GVw@?=OXEoe7SSxR345b(+NP&(Db#X zf3%Ho>~sI?ZP1VO|8_r$8H4}*Hjem*+NjAJ^T~gA%spM&UthG>`KWQ1UiBoB8R=Hy z@3!+1y2bt|0Z6y<_3FPv|0DJ4pFsa3b?To&|0DG2pF;m5bm?Qz|NFM%@90s#Ha=jx zdDbMGA5OH|bG@8h`@1&ZuV)f-|G|1I(pm@q`|XAQ!S;^$yY=?5`Mv$4y#zKtkJtU$ z{DkS6QL`z#>@?Qr8OijNym?uWXY&hW^BZnS9oSId+55T`c3sZ5`2{uM)bW#8A3n_X z|F_!u-2Y))x1|5?`c?dY*sr7i$8F8b(~X*s)Q#d)xGwdfa@5-Jar8ra*uxowbTNM| z`iFI~pB=G&4tn_U+xeJ!_&;vvW9s1lxSfxwfB)llKBn${jCMZSCjB?`u76uRKO5J| zKBCUss|1>~m(aZdop;aZeXm)2pYgtL%UxjWH|uwI?4E-Aw81*lRmVJ8QI8G1Fqt0w z<${zmIhnTerPcGF3$~`xRpjM-=z>m@n!uTei492UcZG`apS2gyx2JlZwwLeO1;;1T zXRJ)7IWy|c`OWN0XUzqM0URpMIu=+GkB^u$VvcahHZ9Fd8Wo>gzhJQ<=PcAut+((<%9v4k zi4mj6oOn5T3zsb5k)|=92dV)V7xe zJ%?YnJ?-=}CY^bf$;%&o%&5jQ_h~oRhJJ6OKYtf2ykg;^YZkipS6-{#`3w1x-T4jf zKEGpY%Ut{GyKa+y;l06aS+pM%`;)pOk1}V#FXLc1n>3se8P1B#;w5wDG%j9j<}6y+ z!jGR?87*vFO#E_)Epi(g8=F8gOZaKvCVmf{Hu$MichOwe{yb`azJ4RN9t=jrlb@Tb zLfZe4>ijHZtlur}%d$U(?DuDJBR`;9-?FILJ+k`9J`{7+l11Xd`%PQ7shJplukrT&wC~B@5WD(?UkP2m;OmZ9d@{fs`mj3rzoYKz z*WVi(ia!k3QxpAo@ZX{D|9`Fz&#y+%r@jS}==N(CkHzc0qVdMF zFJFV<53({p`S*zgK9RsD68J;{pGe>n349`fPbBb(1U`|#CldHX0-s0#2`u9S8x?^5 zMOGUV11f+xFd3)=nt)}%df+i21w?NH2bc`Z0^C)+=hs0#Pzsa*E-(_{?9JTFp^(CL zgaZkGL8vpLYb(4nqla%b=3vrW?sv=~gq%U^z|L$X4T??w;cq>Q${@o1K+_5l?k^b* zt#x7B{0Vvk2xCAH;M$=H5V+u%5^`DA90bgSxZ)ztyOU-nRE0#8y+C&s<*6aRfK4{QUKP*y@Ku+cI2# z`Q8U|tzoR^0l)vzlaf`>*=L+_vODsE*-I9-EID?{{Dt++i`;RePaHjN)NxB}=9sZZ zc^T%kBcV~>SU-EdaSkO~aQqAt4n~|JXK<+08R{GqEOQQa$^#m54S_fC#=MA%KHMi& zs}ce8DuXXY;Ru%T`C$21(Fm`+0`^5S_s^rxZA8C(Jmq_(5B@)|{7?>iz54MJmqYEd2At5El)l#L)Mp{6D8ldm1=W|NRSei{sr!45(Ix9CmIYDZd2eybod+$ z6i)LpziBhWH`>gCV;~R;73eH07%BKyWkw1gv6uzhZBY1Qf`SlqRuBpQia()jU@bvm zXaj#E4uUXW2a0RglH9p)X9O)A21ey^Bvn&XDTRzWEukJ zD`U`8HYzfMj#usTM-VkJXE%SHL!5slPeQDAl}(m1O4OQjh+1>W8_WqG`mK^FB!{HH zpU8+jL`EqMCQ6+eXN(yV0$KS#^zs7{R|VtD&?*WprGR9h1qy{B$wTC6rrJ^4HvkO3 zagJb|53&tbtHC?S8_et)tsY3OWlgR}>|j-Ka%5Gv+?mK<=L9PWm97T@Uog&Py);h{ z%~!!X1ezy^rZd%4oJ*!N!H%WFD_Z7I+x`UM9(rZ{wUi0-uomN-Dw!UxJ~$JVhe19} ziF0jbwO3PV%)83sXG;8zoGU^+rZWf4Z-Cgjs(3cZlF_-hg5$rWgtV?81$ zROefk!|5KuX{Z!D{#kglEsw&H6%db7K#$~Xkvs;LF(onnhPFFaGpx=OX&Tr+<|t=1 zOKvFRIF2OaP1B?8tn%<33CLy_Y3Pcs<_|RQ;%_MB(-emuiU^xyoRd`ge!y}1a=kWX zNsM_d47-M(jx!<8qSXay-oHoOTC~tV!=eS&L9XD$dRh(~jz|jHmlF+!tep!C zRnD?SHpe%4;n0_r^bB8M8q9^`kC9V&KG6+@??@{nkCl?~pOOjYD{==}g?~)iR4DRi z8Z6xFr6Li2N5&NX$xB5e(!|0)d#PCD7sC9Dmnw}E3iEw0RTkNyvcGz%ipYbi_ct%) z7PSl0I9{@Z&Wu?G)`O$c22d)NkuKHJH(M?3=BW3Xt7F59jS6)_}N9H zl`M09XOokQwu)4xv&tgZ6uqL-qn!I~a%Ryll|0%{&MFd(!ejhoT~SuaYCqXf^tO_t z9jRMj_`IT<%Sj&V^Sq#Fl}g7r?-2xsH<>^qTt-I9q!d>1CsbtC6BIwmAFp-em;ql^ zSMDsFM`pBeqhuA?5+&P#Zf8DU!x+6EtWu=BL=j&zi<#m_tlqcP-PY`$NA zs8gt9wIh^q!&q=d?j`UJymIm76o|XPnx=!w>YG>;2ia7^!F(Iv?4?GO8qRTdgI>bkw?YLiv1> zhhN5@z?#VwRpdQtYxmWo<3pX#20%W=QJsf@E#N!16y&%*Wgo6TmE&3?)dcnpfHUdS zpqJlI)*hK%^}3I5_4hc- zd?G-_$&TvF@}5RL=WKfEiG1=t%zrwc`5n~Q12|I)LGNS!Iw)A?H;8#*d?fRRM%A!$ zejoGS%P}9Wh*Gpa=JC-@$z5z;brqykyN>ipkin$U-_{Idx`^(xk zu(YhHf7+FNfpoxmoxjciYeH2}4QM_ELzAc8K9Y5)8+vRh~xFdTSLQ9Kk2QZ;ek$@ z?U}cRh6nqLrniQMhgikRt)byk=R20Nw}ytxoab!PTSLQ@&N@rVTSLP~IS<*Sw}ys~ z_LJTk8a~EPdTVI7+E03GXn3?W1GzOce5}v2w}yttI6t-RHko2Ak70j#3~!Ve?D81C z&y$F^JcjT01mZ1^;Rii=XnAa=LfCHE253c5ccNN*l`B=Sx&M~S)$*7oae#2cA(06l zT88pGYoj9yi9RO<42L4{HPCW>D6v7ke<&JGMl28tUBRR-oXsqWMh==yUI`a(Or*>k zcN6Jhc0>;LSPezA^Nf_|7%#j+)rux*p)9$g@j6p{80vutxp>cSVyg zv8jkDoCSv?i-)R|>4&dz&>L8IDfu~M6_*`MxvHIx^Id%K;WibCtbvnazwKyAZPRR1 ze8_9IUW^y6i;wsr9SICCi~N?b_((}1Fx-tC#YU=lq^AN^bX&X@?p5ChoGOM&t}p{m z_lix))n>q1l93w!I*bkYw9j+oOEfg#d@mJ+3|CT3@NW^ib)KYAxD8gv54hk{pjjae zxX2TdiQEa>11|Map~%Bj88F*RMItAu>~b#^jSN?6ftQL!4pHhVFI5^DqSV!1sx0!r zP*R_lLIj3aM0UW-fL4z;H?m5Y%e_=p)9|un(qK9~lMQj7niW@9u)C4uq zMN=j6;LFr1nz;dTgPpJPcaTPZ&_lFhf zYKYNH=@jUi(g6&XQ+g|Z1EtqfJ6IZ_JE794G*VD{JMpjy?xgO3F^5oVuyZ7T2T3d@ zI7(tTek>USo#|wpt|DoH3ARfnCutIeLuxG?QoV3UD4gFRhoPS%I@pnHyv~F}>QgvW zE0h~(pm@k?i*mP6)M+y`Qant`TEev`Q#|}DWTE>d3mO;lYfS1V>Sqqr2|%Q{;sCfi z=y!Cu_|SSPA5^U9VI#mg=m<@Z!~cjD9K=^i`5KhP-6(|0A*wc=KgA=|FbplAb~q#j z4TqMJ6%J__!lBjtEjy0JobNi;QaD#q?O?8+DMt(+%v5u}=V&a-hjFCrJZACAzt0}e z`M!;tL$B|+!sR6De`b}>0$fnTBviOLH* z%=-49lC~etp~|fcxO1ni<-Ds(meV_}WGkG#^gcM&TJfMW64b+V;1wMEkO-}?g&Nw! zj%VEPRn;9w-pFMXev8^i3CnrT((w+#j@|*f^JKtL z$rfOmX!MYIjHU5pKt!5FBuS~N9wju(vG~v_RJC)k`gL8vQPDO)&e0U|JR;XwA{`JJ zrFWe{e27}#B7KyQa}4QVh422(L(>WPLMw8MK$-P*MG0MqnjmwVL?aDybaWY$M2-%cpny&0NThLnWA*B z1R%711W=h3&vmvP6;3|Fm`$SdC~9z|c&w93zev`Rnu$)G6t7!JO+}|}9?1waj%`}B znDZnh4n(ZD z$Np{}c6@|K;f1`sRzI)X=1p_PqH)1BQ^L6xHu&X1dN#tbulLjE|N9S|bN1S6?X}lld+oKa&wfhTv}ccWmA6hBX(J*Fj|00D zY>G&h)Nrb1LAi`gpJANFSCGDXJ|cUNu(}oj_Ndis5qO?~bqHiYEoU*|D@eEwqM-Bm z6w=j@eD*Fx)R3%(iE7AePGAOzSRat#1Z7Ba0afgUC_pYg^jxE{4_bW%BIC%Z`f3Ck z5vaKVfg;kV4@9YxH96ij{`JyS0#1xL&8#b)dK$&@H~#2RgFzn`oQx$=3^D6#=aM&W8<5DnG1CS zs^mCY&6c!R0A9dObD$8L!1$;o_DPoYS;QR$vii#ie4ByKA@EBC3XXtm$Q0KO?_x_r z_p?fZ#`%|>n1PiAP>h8%f+}`xeJ#?`e5wVrT3W#>F{DO#Cadff;F+?~O&N1i76zcL z=YcWPkxPM>Ny<*^Y;_K#QrC-dQKyyou+DA-%|hw2t~Xt#bq@P^qW9nvhE=OygQohI zh%E%Pi0HLI9Y!|l-zENH#GlKXd0!TZq=1VD06TJ7)_H{?P*2i|O!wi#yr*LcvP8B~ zCh5DuZ5!AW5h+6r&n9Lrr4a8|im1ErxrJ~m63^m;2*7ZZ_$VR^ZvvKm?HrN`7nJ-n zDF}Z}92TRG;ltbyfr07pzs8b(59ycuic0z#hZ5*g&sNV7{FWljR4+Lxzv-p?7E@-S z4Pi^@p)iPFR3v(SCNzjx6~kD};N&V1gF*;Wp*}$IQkCLxi#aWu1@S6q4m8#>wU3$Qn#`C{BRteP7gZN;Bf9S#2puSjeP|uSIaob z^-Sp8%B&KT|LcaIJE&mx5eF5@mRfYjBSaNAs3|VW44a6maZpu)GDCrNPF$@oj<365 z!7uT}ZATnccbOAM)!l?Rs_r_8!>GrMYzFY4+#^6q2X{w;$DCtsq*bTBO#9ic6z%3> zd_IkORqMvMwzFMq=Q%{q;zA23*+73om`g3{O2Mb0byS{ALCUMdI}{Oql*Te7Zfq^! zvRrVVG6f02oLvK|s<0AqbiHNE5Lf`@GC|59vWViS3lYgm+3Z##TF5uZ`6I^WNz{rD zTgb;fu|FbW?L)S6h*Xz@3lq{0-J%p{w2VLOBz((Dc#9;w4+%|qZ;|r;3~))1nz}`i zHh>D4!^G+aG7bgkF)P%0WPi{&1Y)1YXBtRV+gR`uhj38%uR^5Ze^B`M0j__FssCN@ zcHj1bN068WV&M;TLt&hvpaB{0Q>>cPLH?jp%;Xq8RKVxFd>#}&ANBHiQ1W>ga1n{s z=S8i;lal`db)X(Mk`sRtpYMWL{e>JcWqDk5_6J1GlX5&M{4p1O8I*KubZKSS98y1^ znw~W}CY$Tx=uFUZR0(FpMhVYK;tE6}>q#uft0rsGK8w#Iq~At*oQZfZs@ z3rYP)zy-I0*3GGbjWVERi6Jc1s`kt5hZzTCbMAlzGi~X(QN``%)vr?wq zZ%W7bMW73!Nc^3>zx z*Gk+pl%W7oMzjyQqBVlj6|J15w54A&tjOkBd>Y8A0i#EulwP}^<#go6N` zPER<~7Rz=aDGM|MDW`=RKN?u|(LnI``VZDLcrD=AK-0e2`4{lgC< znniieD@p;GE)z=BiJ}|*3~l!Zwzw3E{4_pvKT~k@(^Sb1M6N55QPIOd${-G!F}`b= z`ZLS@3o{>L;#V97jUIzv2!n5c0qW*88f2lCW=GQEN;Es5)UBX5ikK-YGik7ivNu4% zBHREZYop34%tnG{6alhtWScM7Dhp*GpJn(^_HTMwmkX;Ru) z=rlI&r6wWc*EtFA^b#(WgbyI0>6Z=sElNUS^~q#OKA(oT2E&l}PKROYB)4b{!tl3b zC`ZH^bSFv}p_fAn^3@GlwAZI2Y~G+mA4*7T(^U} z%HZ5(Iihwss9Rl>StSFiV84T69XX3*h=wzU{LJZDNg~d-jOF35@~4K4$Yn6|fMF~6 zqeBhXQT7>!Iul%kyBUOnd+l+cWDq)CaKdBGt8Qf3+Xyl5#R+Ud7!}JnY6&c?6+AOA z@(4FFm0H0w10(MsM%yrYgM@G^J;k7AfTmNha63ZEklSaJ1Nh(|G}$zX$YR{B(> z(xbr8!B}h5DzYv#Dd_wYDa_VVqnZKvM_sFA%U3NW3HgED9!QY(BP9z=qc|G`yEovE z!V3($A&(uKrm!8AtU-)br-~pSP#-IkW4+#1VkE+ z=PTZ40A;LFk3&7-#Y+8-6r!sO)Gctg;XIjFsx@jWMoDSU%KTMvz;7fIX50cqDQ1C3 z+M6;pQ0yh8bY}0XQRSkfnSTu!IXL_``dFhbLD|!OX$r&vy-CFyb(3=WHEp7q7|77v zsI5_51D}iXkf$;F#|M z^;a;+Do3}5EY_$o$T8zC8Mde?`A#85F@ywE@rANyWDHWVe-#@uTjhsE%kg4Kct`?2nM(&rD#B5lC0yT4x*Mi%qfU z!A&Bn6p7Hdt@I*;q#HI!u{EK%NDeorPd8;qV6j~VacpZPOvX8LvjuL1M_}l$d6GX2 zl`mg=}4p%m{6Ct*H^h}1MW z9AJ-$QH7id*yGFzNh_U)1MHkeeoqag^KgJY{sMu*={y`@PnZS{_SE!|JRD$8e9a~l z8QE*u)Bg+l$Kil<9uBZ)Tr8=g=|!+6yRc7E6+nWA5K5E70eS(4SR*%BdXYg}BR5-m z3B_gRJRG3wNMcV7r}J=tUSXhgu&G4+2p$dyE~i8pJYAvE@ipWgyyWYMH5S7PHFyb;qa2)u%CAPMh@1-uwoU`@%m(naGUZ%A zrko4Nlyd=@axNfK&IM$ea{(iGEL%EFu?%J6b$f8aN3(NpTLNs&mo*X6-{!) zOk-FG@yLLk^<_!@b*831tkGdRpC&w#8;j|NfR!aj2JGDVV3Exu z1NJ07Jdn*J19qOo^2mTa`8p)e=8*wAx|p;)GGI@sV{i=$ZBJvymNrM@f`RM6Bp9IG zqKyI*46vet0apANwGQ&DbJfRypjTOlPbP*W>T$3ei;G}@WD&{`H%`_q&m-w-f}evL z)Dns?2r#DxNk>Df@$Lj=f|^C<7YcJSUWN}R2`4??7c#gHsV55W_mMYlGQ+X_V1V=I z5Sw(ax|KO~D5k&2;SmFNk|gS25GQnl0j8dyzDwc(Igm!;RwqF-sPZJi0E71-QzYp? zFl5qwiRrNLhSD<4CMVs;y>wSG-8YzSg1Vk1yI!$^NVv}-W=EdKm3(zQiC+itr1um2 z2tiC=Ca566TSX^KMK?~JC}_?o;ZQ;elNXYB{z%}g(Ea#|%CdIw9Yw7xV_epS7?s<2 z>zUV0JddeAy9x5<16?y{Am*r;b6^tB2k_yjKwu%5I)@j7<|(VyjCs$eC!J%H&H>CI zPfrHU+71>$o}LWsJ}lhiVT9lq#_YM)@P7tBp@2Cs8T=hj(8+Iul`9+(V<)H4E_1Czn9bNJ94m<*;npgAxZ%uqK<$;^St z;Api@KyzR+n5B9IG!GpFv(+)-Yz|BYbJWWMngf%;Db6uYb6_%9q`o9+&4J0_Ob0Xv zCUN4`V9kNaV6g+51Czm+S}JMHLkGdQBeOX$87z~x0P&%N)P*1$f)Ht+LqJ>UJU|(A z4p0VfrCQ_wW$-qmA#;E-c*rQo9H0!|X=*wQEBp`=1OktOmvCnBgfnBAjl{m?#?C>H0MIfM&_sDe!jwHh%$0?z&(gXv6JfJd01v2ATAP_l*K6RHJDMstq6^PuJjh}F2 z-)Q_qB3Cgo8u=WdC#=YVEd1_LkvSwnn(L8NMYv&LN2-7eMBV`=Y^A;r`LLG|anT3~ z-{QjBIhi?P+_w=WCo@On7y~mWGe?X!Ixy$(MochJ*c#1IlnMlxEXa{acsWr)Mu%5P z?8FQN*Zd6xBN!}AS@95Df}BZ9X>{_)#5gKt72|m#@(83)S?y#IemOG%rH6NpNI4IL2zXi?6$m0+? zBXS?YqawA4k3^P%CNuH?1R5Rr5aP2UmqL{6$oGI96S)G|u@MU~<05&W$+1Sf4%XQz zi>a;fK18J~p;G7vhkQ^VlRa|EQl7HM$TfTqSfng7P;7PEfrlHwFT1!ekgZ3wfc_`ym+RJO*v6 z3u#dsz+~b>1m8!V1d;Xt>#9kSfa!9aw5ezdMxG`H?|>B-$40)fw)OnnL5av0+^%aEd(X?Gnwm3YO=FplB>Q8wW?i;jP~O*2ej%d9noEnX@LCiYEywlb6Vqv0DB zUrHfwLfj;&fNtjb1?G7dXrBSIERa&}a4Fbg11b85gD5r#wb&`o_+vo4iWJe85TLlV zLLuVjy@oiyY!g%|3x9>kM!8Pl!;1S55=|i>njr6R6noREkc$7MJOx5*&ik>8&Z7JQ z^=~Tcmy|snYd+)T(B5k_iJ1gtVg5B1^g~loP#Jpunx;L!03c53y}l5*`v6S*Ia-wZ z4GsO=X#fu~Qvq86PF+Ays{-72XkjSYIUCDgCqO#_gXigTa%Z>nYg<4(eJibPkHFUg z9$&e{vfdg8^(mXuY;i}UqVa5?u z_iOlEl!on#zBZUZo2K=>i-H$&DY{)#FXN}<^91Pr4UF?%K_I#5UjdqFhoR7~fKSoP zu~6U_#C^@oh5f#=0_R%sQD0UM06&X6)+@nr)*J-ZGZ05$5P>|BeFAw<&+rIV-u}6s z+!8VE3FPwebT^kDCvs_+hqDCusGq9wz)LRokvVgDi~;8I90GYHOXR}Zyc~IntP58o zKYY|{s>$V|XE z5HJN?3))uFm)U2dBNjD1;?f^;>Hma49?6^ns&dMHU>Wk-S8HN9Q9}V#1u%gF_p=>z z))~}b66!9ZE`q(X5%OeKBGqA{Zdz_oJV2R19U*D}=D<|k5D=6VeSVF}<9{Wh_MLC2 zUQI+je4&Z@ixcIFAKiYDNj?_pB*#jpT+w4dFsrzOpr>Ggqq*-h2o6$Q@dQ!qAex7> zdc;8txGB(NoG4QWc*FVF;XrP5#>_}OrM(qOf7;QZLpd!9pB{w=H?8Wc346bP1B zbxfrIFBMr*h^WWIuf0)c)DS%h)1p3j$_(mH=p?W4 z^bK|^H1!Q?Y8ncnTBKi`-i-*=D&ZTE{q%Xnb;?}$MZi&OiRl?W?&M;+lL26Ef@at! za7@SiJxpHswBCE#P00Tq42Mij-DbnGQapl>`hv_fPVzm(>G-Se%LOCRJ>+AT8i|!s7D@`k~X^# zw{IZsY{W%#QKgq4puh=8ec+Lu*7#OL?n0y~RW7_o6dz^Vb3rA#iGs0MQY8b_O#|~Q zVJjf*2?(RKy}_k#bLlU4=?{=zw00}J=v{QU0s9u0{*x~KS6uoRJo-05dxG>q`a@*0mJ_=T-_0TRLFkUrLQCz`@Ll@Jx}^!m{x<%6D8--D5yg@| z?Q{s@LLeiVJ+n=kI+G@FVAswN>W;(an}Ff~c%7jZlojQC`U_w-U}EW1#=o=>T`%II zPcK4EA@EU`8%HPOmz@jwCjfmMjgmu)FBr5m!A6{rw4x_~83U4If>~{bHRB`a841Rh zE;WOb=t2a@;Vmb3q#a+l(y$-j>IQCg1IG}k1l#c^5m>}Pw9%0z2R2N1un3(ly|FiT zjMg}qi%-G4<~WMYr(j-jdZZ7z7%Td=6Lo7M>XnO3o}c!j#=nNBRn*P?_Zi$bJzVsd z6ZIo6D(_7vDoJ8Y^?n7D%~z?TP`G>$DhE3{ISZMR`RK=Q}%)j!rD)Z)}u<2+O1?x(;~GdT$WC z?6c=}BaRbJhX&Ge`kJrCjfDhIfoLzgA?-m0!-)7J_$~%p3bP3#%H-xflbo3bY`s zNvFb;twvDEB38hP#i-Lc&4>x=J=bA{gDfhZMO##J`7~ufQVh8%!dC22;^uu+Qfy_4 zKBjmdG@|A+ML6~@OS9nfLUEl?pqv#e=nBs!g^mSCvG7Hq*ze_f_ejK^lgRZ1@FHi> ziiHtYi&CKbpuUMIUPDC1CFFB1Qv_3`rw3kAWLU8saH;CNxsu`$+}JmA0)nxnOwq|T z!k~Wbu(B$7N+R_LS1XmO^ zoPbE<2?#C(RDTI^R*f8$7=fb_oV-_ah0dBShbz)>xPl~#bM$JoeDh_^k;4Ha@)T*+ zY{hem;S~421+?kvV$kAUwqJz4(m!IP;Ow-T;+ZdULpGyP+VnBDA)z}MPEsYOEk+a? z3eLPlLPJ(znDC@)_(>&}tT>0N{t-)CC6AJXx0rbLmqrV7%`Ux^OmQwDdZ^Apn(EIP zjy%K{Uh0&HU8*m?d2+B~q&ZkI2lR@*-A6E6jyq)FxPxHXdkPi;y#>=8m21i}+l{Yg z2(6Mzn=L0b!%-(|cCMmKmjTZ#jGAZ|Z1Wf}1P1KHXUl=s@GFis*d0|f9+@9PLyK%T zLa_&_ruq!y*>Ykf9Vb>;FN%GMLCjGvqYg7ysvjZ>i@<+D1J0851;2Y1O7q_LkDOcj+zULoe-t_kQ*}#o|0pDv zS>c4k^NivCQAjSc@^0VId(h%T_csF_3VfD1`!C{1y3C3+?!MB9cRnSMdzqDi+{>&C zJkw=X7*2qdcbU~10lmwtz9gKz%dEIpZ%_SaTxP|FW+yJQGBSIYSv@ED zIu~&y?x~_0oO`N_M%;UxF(2^tWLxH`Gr2aJblv2J*vkV2sAr^Z|qvJdZ@Xy#&GPil8j{6k& z%brncjxi6jXOueLl-KMTrA}~5Z}yBr0VWH{IR$gkLZp>z;t@Ge5s?EG5jjv1kpmSG zIZzRi0~HZ-pdwrGp?kYXk+W8l(cz5wAe3VlQFCK9OOUv+*j?a>P@S)S4UAT6Ng6_8 zolpFjS_vLv@aqzkJ}O&o4hYP5_+N`e<9KsGU_Oh9U=M<%9K#9-%xA7+tsM2A$XG2_ zpG73S&ubsR+6%`{m!RVqKNI}bVv>FXaTBodrIvgVl&=wzvC~o}oDs)*u{`OyjLGzY zSDPlb<0yVDUQO+F6n+i4gha^?}m zcyJ5QQ>d}GfeAoDb^cXIm$wX2El459IIdx!95Fv64^oXyCy&)S)rx?XKJaoAnGJwh z{>xxA59q1nSckyf;O8S61S$tCx`FzVpd?{_G2-?zT@3=aA@G8OM1uTvi2E$!@;ecD zoK)KpcnN`%hC2(Azt5%G?^506P~}5+kbzWF??)W@S4*4>f2Tf%I0{tf#Gxel$K15f zBk&s_O>67{Nx{be{cRNLnBzk{3&`4F{hqiO<6J07&A|BE)NwoOcw#9A=~AohtksnO z$IF3^9UQa>E2yaA2b`3M%kM;-RO==Lq+0hN zz-s-DlQYDbdeBM9hjtxq`G?(n(~cgU5>c%*R$?!BxVi3$=RS?2~DzT;n@L?X(;eANSvcEMHLkNcBKk2 z&YLM~Gk1g_+{`L6lg?%4n~C5@No`_(=EcHtIZDJWBs4LK7+GgoJ1OQgxCbNV!xZy= zPt1pj;i%HA2YrEgRuR01Y`;k2R)U$#@DcLeLhxo{zeJGdCuSAG76&mjEPjAwFYyGn zKJey_=_?6-?^7WAJX7r^_JwGs?i`MlW%LP~yYdRBf7Fl;81FLp=_8rsNjMb()Wgus(XJ@paChIm-hWg}we zzlzl2$3g+tos2E!f=WglEmmCdc_Wpt6st0_&Wx9DhG>eXT}$OLxqQW=f=3Zq_H9xZ zhyf9vybvkabgAI8OtWZ2J-4yy7P9Js+PXto#g{PMIVR%dVchk}?4EMv2wCNaNH9)) z7g0g|HYdHjL8XFo-0%^Oq%f)A95;NQ0V>rGk;0zHQGke}*gaK|Z56W_YgMYVA%z~# z&R@EI#U4tKRfj-PRg5pITBfY2d5Zn8I!h*%sfC6koktbp6KpXl=F@R$t;&$F^AeVr zLUY+9{YvTj75f@Vg-H?3Jr%QPR++FvraV7BvRwUv1*=gfQHYG2lnlQW)oEDHmU}HR zEmW*QVK)|YZ0B_TS@IZt8bB=}- zZO^DAlW9qeB2EQK__IzC*@}z;s9fsxGWfwv^S}XBt=M3yK7~-#S^Q$037G_E$#g&C zBSvGi*91Ga5;&P0y;41gAKb0@E;6$2%|QKH&yV(Ibx-D)SzY5gG`bB~uSdoH<1Ss7 zD~bbWQFytcI3Tk+{}si7|EDX8gT5<@Ly0SjLrGT@hu%5NEO69`R}_a%7|6X|(LnC? ziUxA8S2U1&y`q8K>lF>;Uax2%Gpob(iU#zqS2Un^y`llV>lMEZ-Mh0oT(8LMIdKqM zt|-R!iWuGj^sZMlpm)9EHo>(c)&`QC?MN+}zr z{W61P3mD90umWRF%iL3#y5I;BW^J%i7a8qYS(~lYCFD#~eIOk!td1l+(8Wg)Qdby= z_Y`(8o(BNamNQFpPhsl$oHNNig{ki|8Zh@1re0zob5CLFdIOnz3R61_WbP?Ur&O^jwL{Vjy z&BObtvt@NCKs|&4Ocx4}WQ^j4(YAYGw1zgvauR9Fh0$Zb%ywZej2@@TQBUY^$(?R* z6FwZV@-TT04!IRDx4)qyw#KPQr@kYv>9;|nbd$o0CV?%b{{^Iwvfra^2p7k!-;Snk-Wr(n}8VH zdYb?^I7F(~)WzVe_Mtw!3^T0#w9r5s1A6LOyCyasgsKI1lBDoj_DOqqZaJc19IPz_+9g;CBI* z^dc~JKH_mA;~@G%4(abjf>N#vV}ip*cQ){4HvuscJv8>5*TJk1a(9u+)fm!FRMbLl zJ7!s+$CeBXPwo((C{6Xirix15AwJ2u(7Nh-5bX`5D1|&~@+^>7zk{f=-oO{medMKs z(`?CxcW`5ii#MNeGnI4PY#`f>41_1BY1Hy3l}bfBqzupFb0g(oM2(!U`=k`+^N6gu zV~kK!uK|3O#^^`sQ)XMpogf&*)Xs>Flb!&@lc!a*HA zW3ppb4fq7kM%;gS**zoKl_Jt)_l#t>im+t&HOa0Ia9#~k|DEjS$rG^Z6{VQXL3}>S zta$y}L}>IC(da{nnuA9FQ$+{-zW~i20A&@39P2CF2l(UA_X4s|3^{s5Gvza-yfB1D zO!VPS%lb2O`M#6OZzPuq3r(Z_jlAoihR|lFqg%NE(DY7TByt{@%)t$gCNzNf`4;#+ z>BzDLMLr0atf5*wuUJ+Cdt3MK!y5XJlpCI75N zfKX9|HmNEB&1pkFXVX+x1In|&g*qN?>7l?O$@LhOJH?iIW{wx*a|II0jEuQXkzDU( zKFD>7gUV|Hw01}%%o-m*8iAM96cp7 zs*sFQ&IN=bR7er#1ERfE*>h2#E;3A+z9keVO=Q)axVPl>ug<+1InQ@51 zO*v+Ip=8<&#?~Uv=7Y|=02XmJA9UUYaIRVaorJAr)C|?4*tcZTcgdHvSOtL^nI$;( zHWk)+-qz$aCYbFeu$IV+0&M3+0qYnqUrcLQa+d{O^#Ob@Rkwg~#$;P5y6H?3fprAm zyh4CgDvcwPnaCGzy6~2xk z(>1Tq30r(1?KH2@Nz6~FD`$Rc)aK4ljn+<`pYp`BX&3Uc9F}?H$Hc@#^7xy?{>hEy z*5uy+BwnGDvXWL63UCvAl)FW^96*F?;Hf!>9Yf=V|Ec4R*|}SU1`1o5?!!QATUrev z_2_X-SI&sh=3yX?8b_Olf!HvS=nrgzE2P0{S_;lT2P$JlaAlZ-R^i0>W;G;P`({(H+GRo%Z^xg1UdE~ z;=hRa4@tZ{+>-M!;&|yVNW?#f0%IZi_MndwK8mO)-&{5Xf+_0|mH$;hsxhB0TvQk4)F88;OKD^m4-4J2r8mIk zBtGi==w^V2kvO^mfrl7ahrlxk<3t)lqD#_XW_!t2c!rDS5sF4egI&uJPRb?M*tRFOsuSJs0*giYWIQjL3~sv zCty)-c|QQc=wSrD$-s>W{0e~_QWZF|ZV_3xLb~Zx*~36>4T4GQ45~|AAPO6?6bjpq z=t3%N8X%*x_vai3y{ocqV8SYFX2P4K#4PR08?onrBq|KmvI=ivf%hS%NG51Eu?p=2 z12boFf_5`IVSV7(jxn&0TMmQaJ)kU*+T{*6Hl$}s&EH0Lyp%YPOXk_gMD9$zW8(-^ z_3Mb5@e01wg~i{+&#ve<@ck?}<;(+RofIBBHM>wLbDSHzac?p9jG`$i}>3EC*@CY3{UQa^wjcZdCc3 z_;6q}ANV3D_F-xrHv+_EgFqcsB;a778ltP6pkmz|CDjFpDG2~Yc}hv6{EfVf;q*_gz-Sbr6V zU4jaaw1QSzAtSl76c5VjJ4^!BLeJ^K>{BqV9#Pcha|}3X(R4`KVwIb z;M0r^1!ltgIalo1tD)?0={&@k;bY40e$SXkvSDjU+Z!qG6oAOx-bguNAhW%Z@+SkC z?TwT_8^~;Lq`Ye&v%QgW(m-Z=Bjqm!GTR#|e>ITV-bg`DDH)pWjTGg8W_tr?PYu>= zZ=?iN8C2#DA5%i=ECJ2%F(r9>BPIC_j42uFYt)eQ2F8@+H!!9ozkx9&8`lGp*bE<2 zauho*_t09(6!kq}Wwtj`iqszkG}{{~Gab-uZ=}p}K(oD(QtW_cdjpqiusyqn)>4wU zH&V*f8p+o=w3gyrevoo2)gU9ol-rC(%*Zh1kWq*k8K&GRHZheu7k@@|hXOQ!G};A= zlm04lW-LuXVq4r;jtsj1j3ljnHS8k3i|+YY4?ZD^MgH zB~<#DK-u9J36<>^C?}i^LDI@^5hypzD?rmKOb*fTi_D?YlpH0d+ zCnQ~I_>+Wic_f9d4D(9Ov}JoxHtd##A1736poQU0gz5~mEX=1e(k_%nKD9CY2SOJa z2=DR^ydT^%6g6N!Z5FOHd#h1$)a_|Sg^xOHu#86v>N6sT<8+ZYM6J?-7^^acE@FaA z9*)yRWIYp}YBYG4fixng=>qxkf?=&LV*;M03*?hw zCQs7^@@dbRJWUtKpN627^&ON;T}ukZcL8O~h~YZQYGu_yekGe#>M`PY)a_=HW@9n` zFau+LM3OsrDU>z#0kV3L(Ks)_RRQ%A0%jOe! z)=eL{Y3D?~V}%4Yh*clX<>n8cn!Y{vNrXbW5e9Pmq*4&X&Fd0 zLtGjCPN5|{4T4w5>ektiHopi_2go50f&0jTNX|F%Flu5^vBXXWSev$lfrSn-7a#Qr zUizL(1|hwb%E~1Vb^at`&%j~oR&aj|+&_Y}j$8$gA?~|~E1+yYLtyG_2%JRVVMB!l z^MVsD5%VX}qyhv;#M;2Bzcr2KvkPQ*;iKM|v=2W#azi}(%P|wt($zj2Nk-D7r<>Cy zba_fm=eQ|+p94%nyAOZT05eo4%+JRDju;*5hL7D?h2&8v&8|pJqiAy)MW|Q>hJfH` zyycmvQ3B>P3JqCNL52@oOW`zpSu<7H1T;AF>T5+c6|xy7vKx(4Y&?LHjsqx?57j1U zyz}|5Ak8RObd-40D-V^7#Gw*)fQo7|WW}=JHHr&f)QyRpsXl^yQ=d?mQ!?IISI93k zc}8GOS53>vO4At=GcpxkMGF(O$67jLPTJhG+AOrD0xKw1S>9VgKQkI>1fL8&IaS?Ds ze(r|%zZ>4;z}v?x2WhZUP=-Q`H_2~Ylul@ZpF?ey@JMy!!&0ut1Nr90pbW}q3QL7d zN>ISS6Y^s+1i-7A=xH(uIf71^1gTc5^FtS6Htg5e(p&HDD*Hv$~;fBUgVE7Q8P^xX)4oA)U0Hx|JUZ{S{z=I?YF3KvPGph zAgq)ImP(Mp%5)f|YwIverHs*zoC2ebLv0z;#d=41QlpYwdyFK^44%kOk+9j({^%qf zW+hUyTC!u7-{w71nB^%fTst3|uoAKuhu+f4Nf-;`#t*O539Nps0=ZU@n=txGzP6C( zPY0`WttZL=-$pbgVTa5oKLMVNnueMAr8ZSxU_8MzKZeG01{*k|LbO}w0aH1_gntSp z{L^XOT7pu$wNB@B8n@==@!zv6mnp2uHKladltvn9GZL;54vo1-rb7dnFiFR+&_YMM zo-zxMfcQLRb|EY`cOh|h*Wh(i%zVuIL^ z!Z-QN(lz~L|CF#~SPG4Bm|rriruf~Q*tcuP@J+5yqa(t_psp%tS_KIUo#wO9=?Qj8 z%w{-+Lq9}jg$V~;l;oh{n@qW9q$j1H<)nu`n7-Ik02Ju8O1j4qM{0*Kmf$zc-N$|9 z0Y@BZ_LsKIEgpH6pTfk|QH5U)Cj%E(>2P!;sfsy{e4*RnV3c8e{8_$EA;=7Ch{2f$ z(-+J!%5u7}xu*)_^eyw85-~&6(0m_=0xt0R4$0(fPj>0zlC-$cS6yIrjwicYxJ5pZ z;djn8>Z0t6O%NM;2|<&1FL7#!rU2ec{bD55`7#e9tt5#_t;t1n!d&b8v`Jj*ebs>M z8vKNAjX4TjPJNTx3MUOjG=6iXKY~&>CbKcFbd?tgjhd*{UKGk;qSkm(qIVOyHW7Kv z!i+@seZKLxGt${pV^K2M{W9u8lhWUtUzA{GIGw?lC)~1sFi9Wl3?%6XL&ialaGfaQ z&NPrr?(NeP4v)^0!%3en&B#K7V*y6FPBoJ3R5M+tI@<44vyz=^b|Q~qeX?7(&gjnH zE2A}xOH?TR2?vZa`b6LC^Jaf{xai}6(j~d%BvYkVcE*OZ98A|d5IOrsj_kmP`RFrt z!@e#vQHue$dkp$3D`YD4zt?5D{bZWkPo}#pQISrUIUQy-D&XtzB5sWh?>6149^P#x z+o{`)jY()o#{5QI!#afFBmP7h)+a~(&II7S)*(`zT8FN?n}o{t%`fs2<}%r5E>Sm{ zK4gjk9Iu_9T+}2FH8s^(1ZI*22r{2wCMJ;6Tz53xF*T2S{SaGo2j@uECuJKKwr4#RMmbE?Zk7s{OcE_0rjG%d;h z&i7I~EYXoByX1e_5$*p>^W?zN*A``D>#xQnOXm>Rb%khe6JQa(RyENF(xdv!QU=Iy zq-K@_7itW7vfJR`IDPF)V%?xs1GON)nKZi92cq$&5X zVI)VgXpT-Z$86j6R%UoTGhy^tG;|xZ+W?&gR$|6^Xm+MpanBgV=#o@e>T6Vxw9Mh} zIDm2=2o?I8oEgVddYqHZyvj7QYR}r8p^3lc`9>>=w&!bTiPq;eNT=<&qnFb*6}Mku zGxrZe65X1+rsei-|Gl1!1BCz9qC%CK{v{@aSh%8aquHRck_R!_?${-1IUupnz)^>{ zE;KHoe7YW~R(CFtlWc(QT+lI)L?3plLAc9Sjs@hJ&H;;62~)tJ!?k)0ID8ESqYc+w zDYJB22|>*Ifzv=S0UYP+>I)KjkdBH;*=ij3k7cSf^kBnQq>LdugKb}5#bJ^3R?fnh zbV7;V%CwFWw{^taRuoV4gYN9jQ37XgPJ74PE#Z!mT2cjF7keSs1wo3c;XX&^XlMoE zaX^5XnP|+(Xtoaoc1}VAbR%#>e&`2;@!1E%-H;VP5-&Xi}X2w#H0-p7`mj{+8M{K|8lLJ zjXIJrW=>Sjv}owmHQFTnfWMh!C#xu_a>w`#3??zwZxZ8tP0>FCIki>#dP=MkCaM^{ zWI_;{oPV+bP!eu>pO|Q5$2er>C&XO<93Xw zEz=GXjzAiXG1>~_+7sQPXU@)O)IUb7P6(CMk`jYcUkj;u52M6?c4Kh)|GjljuS}v9 z(+9X)I&gBQZ0Wd@G~aFxx<*!OmTR_dSCXBmXUxqLmc&V&=cJ;jcwfgjY}TIRw=Wvp zcw?_<55`_6`U#{pnD|L(U@6c ztmredLStr$y_n?Dm$M<`ZZ;XyoOSA0ENRu#P+1S5o3*iriEs68#z<_cDugY3RD7_% zFW%j?KHkyNQqt1b+ut8=?%P<>-PJR=wWOnGu&sH0SG+QIRy-C<{6CeVtEZ)Vu(d6| zzH6Z0de1zaRPQ~(dlCXqME3PHU*6r-KM-p{F)dsb-__Gm5yLYu1X^3$+7ZS^GQuc2 z!q`hqr0HZDEN~N~=^8W7L4zI?#ddt1AS9=4OZ))rJqPu!c zJ)%P0AgZ^yk4#Y2^VSb`bq|zu_3+4$)b79()Gpo=dAr)1b!TaD>9W$|SgB5p>C1x%njB7{zbqygj;RQc3M&w!|FCMZpP>Xnu z4Fb&I_wdGN;myfCO)X8E+xq&udV5UKX?eL*AzPZt-kXj7TB*hGHMX??#W;n;OYrav5jkuY#{XDln8seisBmUVlk{tvs(L_fAI zrpLu}7r$$(_10Le?uo(i)#~n;&c@Hin9hm;h}Y{$@PIKy(BqYL)a$V?)OU2oOG?1K zZAjo;_su$U$+x9U;6Pt_|-T##yfU*>PL3A zGqgwl`btOK7p+*O z2>L#^Q0kF1B2c318GPGw~0Y7f`~ouF^kHI=!`h_fm8mD_K)tx1e*>T)h6vcVyK! zl$Pqx?~Gl#BvwANJl^m}y*UQI)^KU(hF1N-AwBs}$D?t0xcG9t;V7#S?Cb`96-%h9 zUT+&hm5m(I8;6M3%XC@RT z4c`sRH-P=Nx=OuG>E2jE2M_1L3M32Mu_Aa!XR z{VcoDjH9J`L*0KIUcRS6Z>`g#P`5}|AFo}$9Q|@!r-md2we;&PNZyl!{bQlzZb8SPH8&XxL-p_|c5paS!b>bx*&z$mk$bFY&f zGz-W7lWlbFw+HJaOk=qt80#qAn^oT(DPCGtYE(a0l4HD3-)SnN3*6nrrm-y=vAqo) z^U)}Htuclg2frso|^dl2xK=B3~!9Tkn8SZnNx(3?%ng@FOOdscSlz-1Jx{elN z`%;|NXZrAoyu6WIX*ImwQ3?Xy+1=aH+|Aw^y=@C+H9_{Fe6g9{ zhrPAhcs+VFxFdMW+M(=*s~Wnpby*$WzyM#;!LM3=v4z_u4fVPm-pfoK+C$zidc=16 zf%^K6lKS$726RyMuuJ-gH>_Cup5lFaTdZ60!E8_zG z==@&0qmBse!h5bX_^VH$6F)edZWa>TnBnXt6C3aBz#BjT>f?bI7{g#j9gC>M)tAUm388 z(tEEw8o(h>gxes8;fn-#eY*&z|8s{a=R+!H#0x(Qyk=H9RJ#v9cId58 z{Y!dEY+s|^7M|D0;^h}`6i*xxu6NoWyEnoEX zn#$BAr7y{lL_f9T1tVKhsqO-e9XcB7e7nry_|xrfE{C+6%TK*h9MZAd(K8m8v%mY@ zmGmOS&{mGp}D02q}dgq}`J%GhRyOEqZ^d^P$KxgJr;e!S&`f^Qh&4kt z+8XBW9eP%~PHo2k?y4*6>M@$De^F1jYw!XS&?x;GPqyQpY@hLDJ8nyjqM495B-P2b zpQugD0 z86uR_cL+e^P#B8w2UljHkftr%$#7h6##B`(-tr9d`oN(d>~><`@M0g6Mr)&qvZ2|x z>6-S2lI8l2og%F0x&#B!I@BidddP7=^Te>ila2CI1iGr>_r{+8a;3Cd7n|x}zqEoi zW9tVcuYl3r5Tb(c9d{wbrGh}k9uw5gpTRChxENW!%@z7gx`rPrEIWx*A73-(LQiW|2{x@l)h_+Q%(9; z9#VwZ1eV4+uGwAOp;M*4 zFiYy_aCqE{j7-+wQ|-5hr(uPO0*G#cLm~a2N<5*hKfRM$v~@Fuu=Q^&^Ls>@-_P$D z((fp&Xy|u#wCk%By|PO9x*NO_{ui!a0fX>ld^=UZ9D~9p)Sj zCXesxcFV$S*} zmiaw$M2^i1T;S=k|Vhl5rzQM*wU0fbU-gk1fZ0{^gg=2cj(OG3x zMHNdp+Hr^CtKos;C3q?NPj?I<^TVng;a7IBFn37!$M6Bk;ky);s`|JLSj3%=%vcpN zuR__Sw3kVTep^Fr=T#`;vV^e=y8(S&!lEt|D! zN%?Y&&C8aRh6hWEDw_4!n7&ShU+vWEk2=e~{AtwV!uRWs?2N5kQCr)vtR5RO4t;t| z=Z9Z~{glA8D!I^@62q!tby?BODone|N@p@+TdcGKxZ;YLrSZ!1Dv*|DnGtI!=5KaP zuM59guOCJ4wza+VZoPHr#d-|FZr4?Z*f(){5HDWAHB|mH)=eeni-SCqv|mX^<45&lNUoe-$DM5i3WVkU}N60a^= z9*@slDJ>U^3i<;_S75F8(UQ{oj^Y(7QT}-SOmwqlwYmb!t+nxZSG)uZjq&hcoC^|4 z)*fm*>q};?S^|HAMG5KQo%y(6OSp!?Y5ub1*sqLXSt5h$>tzj(;@jEIjD_}M|De8M zRR^wy1hunRX}IUqFR9mC>Xzy8T=bw`mz!P9Vs@og@BcL|+uI^?T6XeQlWz|yu`lg* zXwcDnZrjfGru{!ndwsqU(~Yfrof z>ri86VHcqiBXD#tm7wV(&8T)P=wC3jZ*K{{6xIF%_6CSGa z5Z_0$(fXd99HyD@EYe>vgxHx3T^Q@!-58#9M^{$I3ar4F7TY#@f)25lU;Pi*3s*4z zKiRqXow#F#&Fl)GQ*ST^EqlWyguNcfgw3Wq`efHMT@rA?u*RcE@in0sI||;*tgY zF3!l=6WSZRI&h8NM_w*{;}j!<3ttR40(uwj1{`)^znsJ$!H0($aP^PS6W-@bPxvMW zA4Qn({ebu37vCODe%PUN`5hmY zuE0t62I4PSW*psq1eD#QHLi>Ur3S6uI4bm*mSjc)N|7FwhK^QvS6WFV-c5Q{Y z{lM|Y3qQ`y_X*(q<#6SD*-7KV={QS5n<#Yh%LR-%@ag4Rk?}0D^~xG8GWOx-Sqa$K zuF;*F#~#G9CAxI`0H02_yAV$~+;qnPGfY~R_a(q55r)0*4($o<4P33S@$2LHnVxNV z?aJk~Y?i4fR|dY0do6gm_3YB!g?Q%Y*3%P!7oSNVbs5WC*#a?KUnKmJWpnvn47}e? zS^>`ky(`aQz|3<|M&Npd3U$*x?WA+*jsZ4xo@}2d5x*bl7iWZb`|bI<`04HZS;QZ4 z^IM$3`|3rp2p=j0Nh%`&$C}wXU_tcgL;JnNYo}A zft&V~axbk{pDwPl!m>Jt@pW}}D{y{0dKxhEbj$Gy;08&XY^QigM(A8V%K-c9tZ^93 zcTxHA>xRLd4(!^}CcsZfc~8^k>oOKHU%zk523#7#2U~;@Bd^pg=@`Ed@oxTvmpODU z{vyB(yKw6;coSgi)5Y%t?DF%=L7GRvpIen{5nkf+MNCWFtH2dIya-3mGQ8ZhIe-@e z57YMQlI0`qMZnbv&eVsSW25dC43VyZ3JBuVHe&6 zn07}##P0&kFnp%iVbqB~i1@{LrVUMZPk8T$t3%fW_XR$rucaSyXUU z7j>ds%cXg#CT7zYLVK zCJnaOgR)C~d1Il)8C#vx)=fO3-PGRK)@HRdcjLf?)zsA5)<0m*VjJwH!GWf()~!~5 zZy!i|tjiei6LhpW1f4)c2YdRvI(ph#qgd$_6n6}C zT1!`)A3ZmUGxm74Gm)|Ag(dEnf*HQN+1N)iTo-LyH(|N13AAl}JTl~_l zw$3fhJ@HN5&6jud^$zy5##?(^HnjD%Z;5ww4aB)JUP9epHrU(>ft%X9n>+f;t<9JZ z;}Evh)Z5+K)Z5J+0PeS!`&xHn%$gVz>0+s8>+(uPkXP`)XxhGnbVTmhVvMWl)ZhHdz73QlQT%ENSEA*X+#_B8SHOsEl-H%m!1WM zBu)`g>ky;~_b)pVyEaKx;O_S4-q;GozRo1}eM{q90oQX-y0 zOo{*%4`n-C*xZuyfNw!#$4UmgkJAL&w!&*sLMd4iy(5~_t~+7n7R<2`Z9%v~LF?OK z!tgr%N$KdBOc8O(Jyc}s$tjr!clY+v0#41=cm&rG`U?Pc3h3yxZL3p@q9~T^%)~g_ z-nKajPbp0ay<_h%IeG;@7e@#FYH^~N-c(K#TWL=(n|1R59(+h*;P^M=8~vOOB4JNS zshm8Z1QXraw$)K|dv|X$Ta-Ki($&)h3-2-hN*dxuVxsMJy&! zt6e=1GTB6_5z`3iiqYeDd!mXMr>R)#!DnhsUHwfYO^P!bmGOv>V)WDBMvH^(xSqIa zW7|f03(tXWZtfmD9UBhTSQMDF;o#5RtNLLk;-@jv3?pE(LLbUT-_+jR)tyk2j6nVA zok|GJ$gAFSU{eZap{)GBOOn4ob zT(UJHmjo4*+`MTMhZFu1IlarU5E!F^)0Z-nJ!PTH>-55y1Wx^<0I+M-ZsMsBy z`?F%16ZRpY7EcL~u4U8Z*7{Ao{Z{WVGLOj5jhdnzjf$M4Bcxo~}3UMm0uAVNA z=h~auvGi_gzHG3q=~OD#?S_@|DBF2Gt+kNw0?D3PmRbBRKQ+<%whjy=hZoIxB4c>8 zaSVofpbtX80L0bex2I*}CI@4V`LkJJ1Z50@?Eq6FQRjO0@5!Vsy*(H@xsBdAjpHy# zY9|gVIkj;r=vn*PT6?8;PsSTToZ4>hYU_5|fSZqRu;NA~$==S&?r+;<4Q$-Rp^01F z$;8G(Hkp1cSpb=PVC+xdce>)3$%#W?_#`thN%1)7`d-YL*wSJA?S_V(8!G}1qMfrC zsk9`~lB4{>I6A?bT${uk;llmKp2WrJF#R^2j5jq+J)J57T*$_aXohHttrq5uXI7)} zF-aW!5)Y!$ZNkHvZLp`>HQl{i+-^2mmbT`BEsitnY3}jaX%jsR2HbEGC~Qw#2L_s( z9hHKTOt-dnVfu@u2h>(#9Fb(yUTN4>Lpg!#_M+91NivaNiEX{Z%!J+)?I($=Bye;%Ou1(0hHc@N z-d4wlc@%>!Ep7e7l9{|)+csfUW3Z+FG}86=wVhTouA)&ycfjK2iN4Id@X?%3{J)hl2pPjOtQ5$HgAPPW_du_zp1&!Q3Kkbv_(ngw#+kGQDRtX+ILdZ zbKENj|2;ItGq_i}0f?{(vtmxl*T|sC8XRb^LC=kqot8Ffb_siEZ|;U&gR4jd#lab( zOifrG>xKWcxQf#XJbd?Q?7{I-r)i|d2>ni0+Io`y{8i>qN)IW{)u_xgR&jA)+T6@ted+x zbv9cVrJmMt!7OBL>~y(0rkSLNBzYWjYwiZ+=@=xbRK#v-_Ijiwwuw=T(AOEs>0}3de{MsCk9}j))w{|rd>dz$c8+zRNN#kB6-Y>ku+D#;7yaqrtN(= zElCW!9htpg{c)=ga7SV6$(x$+N)=iEvwHiG4`%u7sxb89YJf;@$+{eeki$#UG{B{D z4$|Ab!W%uEma?_C$7xs2No;uH&Nj@4+)O>~I-^G!!^vpDQLU*R$9SCbBmbWDmqQX~ zG%p<_)Qkc&nc6Xy%Y`{45q2oK7_8xE7BPJ%l&nFht)d(Yj_!mDI@v-1%d)Z%B8A3n z9$3r)FFH&hr8|`gEe1$kQlA{`GmTkJBNJ44nOF$dQ@Xnb22f9+Xzh~KR`!lEJ*8Uv z%Y~4_)c9pF6EOdIT~ACiV-xwys{Lu4H36BPxCJqyx`I<4Vw%@;dt-C6S-ylz@|LZf z$uk$l9VCjp!P-bAV4Nt!2{R25qwc|hU3htS?v3$?8>Go{be3Svm1+Nym09 zPZM?;u%ybRRx;sF4^JsG(8mZg6)6B3IZBP#_1zmp3<}3={T2kHWMZ&uYT8OC%mghs zna1BPG;GL@SvJ>~MS3~323m)wq+>EREy)TC;Mlon8g#cvn2zk4$jwNN@ujdI?7~hH zy%Uf;3kR%EG}Ht4xHcn}$bJlQ$+wI9E@0Y$#J<9a9}%%I+yMntDwNn z8FL&T=FVRpEq51`AoA=2v_mPr18p; zNb|pII~(Y_uB*;pS!$v*E+|E5P3urKRjEr|$4S)IU3jKyuR@$})YFdB2tEfq9ue3rru+i!lC& z#I{*(2F+sy_JnAKp2FKJzTdOMJFkALTh?P}z3#_C%Y$__QET>eHl3}0sB-~?yQZus zHKLYQnLN}vnccq-b>3w;_3V!OiwT2A>SH9s0hRu=NG*gN6g3VX2J>c6g}H4{YFjOw zQJO#ekTcj(QKPfcpo+nQ*=~h}ZRw1hV`fl+9Tzn^+n_dV6fv>jJnlwQMczA#)|^$|IT8NhOd$Nj^9kJ!?^0yS?~rKewm$E)zn<0i(bq&O4MUxj2F|(`wpY|R$uRhs8B}3mP)<{F=FFf1J1lDS zfWf>ORAJAVSb>FYqq75M&;tvDo?=eo%sp&PJ!~xuC~`zZcfe1%TyzKeVlbD4>53H@4;dK`wjDSI^4uCc5t%(V@^A24kX3@wwZ zoDVp6gRQASIUgv}FS6w!KId`~9r_WGqJyDsoW2S#sEu$t*Jp7 z;G`VRn$rr*{TCeooEH&3{FuwdbVh$jr0`*=lj#gR;ab@9qQ=HyaM}#2uwOT^0y`_h zwz`1y+pd6xlXB7G#7p+1C3}*RJ!#2u^eB1UTyKSi>#}pm`7<-9z^;lK8-T$TGpNGC zpbU z>y%)ZS#5*y3Q)BZH(qwzd5OR6xv*;{7RN{Id29R~S@SCGVf-_aDh=E0xiAVPK35AaEfdYh_`_D90;`A` z$CjL45iPr~vBs$=J*TUvRjqb^r7vUa$)a6e21wDMqZWC2mah|eOU9fW| zZiB6rsXIp6EYkN;7(SNPc*IIpVZUr*1vX~IdSUxatibkrF6=qah2b}8C(UqAJutNC zmxWTjHPlU6v5lc!a~CDnFTjtP{NTbV@e8?pLwv1yeQ*KZYqGvyi+gS5H#9l~KQGIk zYu)x-3*uqXUD;#LwLJPSVD2FNi1&@70s*l8e&ldD32`VJk)6LL~llOA1(fp+H*Y z3fSsGfz;^=7_YH#S4b6CzzCtS7s=@p5hVPe%SDjr2SthnhB|3tO>oY&FxPI4?g1VW z;TwL$(Ri#c*SLLZo_N7ftMeT^4!FNPq4MSchD=0_hDRozGxv3I)=7SHP&W zvH8d3$Lrc!df!_5+gf@knuV8*BANxCbh&5>`c0xcvdVKU)#qA}vAHArM)O~1Ym2iK zd36zf;Co$efwz2DWA|WtLPYn7ox#NJnIfHa1?*CxK)T`z*tJ4|bi);}TZIBCQ@yGK zMhK0abxH=*r%T4jMRBS?j`5~MtB3}{H@aMO4Ei=vbPO^!-Z5`1I)=P%5q{tYT`v5f zf4?aFAY-$fA9R`)VUm2q+bm7LX)7=sBwIZ2kcb%IM_g`)AOCL4?}&C|`-dWR9Bhl! zss~mvu>u?PTv*+6VYo_SY7y)b-I4X$_3c1z5;$t4*a;EQ!Ed`<^bq<}B1Hs4owV(= z;3e0>Tw8oI1@Z@5_=eY9E_|bJ6_Rfl>ZAo|zuU5^FxM8R(l%wSH*E#x+M?!eW%Zi2 zC{Sh<7f`YuF{?^+2Yx>0S+Kn#pSei;T>(2_;#Sz4=fdVaH=F^Fx)yd^)VK`DIU%yn z7r*Ipv1OhTJ}*)S!B8h#Cb0D$?>@0MQKNfu+T8%QYFUF0v_)krB8jlaOf0UFEGKSu(D`spd*ou3 z2xffcQ)w9L#^J?MS7+r;c0AXDgiSLSRdGvUA|H{3O}j{0Fb?#MZr3Phy&J%~mKcz; z(G6hTqDBwoY!;~s7`J{K4U}P#({$qQ6-g$vBCVAq2Qbvh?u-cy(|t)8THKe@nw$|c zsKCZ@gUSNZq$^qxBo`cH95b z3bfm~MSMggksG#aG{+^vwuqXuXZ9^1OnN@-povx3F%$c_5qR1~*hLe2I&{Zvi%9NZ zgC_QK+itImutO$RyL2PzhTT)z4qNHBW?)xM+zz{CVt=bfXr)NEGGU!2_RNZ1GI2ZX zipYXT=(n%B+hKb}&DqmU3kdU;{}_z>1PT;(!gFDJS6VLYfXEyo_{n{Hd`qx=j`6KJ zn92)mwTb;*VjEn9RZOgM{^g*GtysIrd>~x(eAwm4N4Vg3zom_lGsfXx5MUNYvEpAt%-1-iLgNvx9=A_=HfZA^Cnhd*F~zaX#pYo zJ_=T0TSS(R&~N$MC&ezi2)ib-U=ccAN73!D^&%^ZF!FlK-!ImCzlnWfy|$-phxzvM zSibkz4}!d0O??CN?d5S8TMXNM&qBG`JkFlOhT{sPLpC`dhcQ82VN=!S(BsTDrkX2| zHd@a;4%;Gf1(FB+IE{G#AE>Bk_apKajh>? zAaEepehZ^I%a582L|w;KS550mnP1sACSl&z+M_U*p5-G{thtZEd@0GkTuP6|QZjqi z6bnixMi`60@)1}H%7y0endC!`?Hq>XUu69LbWciO`+ru+iXGDc(0KcP!=j1oFD04zH{&`UnGg+4{ ztME+LNm1b$a7GlKk$+v3jPk+!TCBNqcppn~txwd$`w-S>bW~?KH+#$J*vsDD=F{=; zzH&PD#^z@(nT{Jo@)8@J<+IiKKBjuvq;893#3pq^^g=aur6rPd&_*3-88tsY|QR11bKFca%CTp#z@C?`>3eU(t zC`w}HT*hrUc2sz;$qz2TkBanE&rR)=8x)hoF&zT-im;9`=q@aKv1~WXqHCX*mII%a z5Z@q@Bc28GGvH(8!Q!!SSssm+$ts$Q)pb$PT)<6HG#B~XqNKTP+BLZBCJ!r>S%qh^ z+C_zDK!+$iBfm+Mc;=#fy4hy_>3x?Z-L+ux(P9jfEZl{q%{t_qsaxk*U zN#w~%_LE5@k-x;rO6`wqm}w-DM{`mqk-x+VBQY0plAY zS^~f6atpkr)AEZ}Vf$^7S_MPh7%^4q`>#2JYnw!FhijA25Pkem2f~&n1IIfg7wKV1 zat%YDEU0d>Tnjs5;}8BG;&5&~9xiqNazq zWx}}GtrKk)lIdwn=>6&L3T%zkO<5m|e|K9w0pnjWRc>0QCSyeoJ80rIm|WXX>wcId zceV}ouz9G$+*vWP2!OjT`bq>lWMVHYoawG};jFiG)>AqwTDxDxK4Ts#Fv@9qY!vG@ zu>$h|=yOZl1@c=yl~WSWdGXNB3u3`lq_pfkqpTZdS=1et>N5;gLUk9-98?yuYeu|# z#R3r#hNGwpo26qBw#ficbf-vF!D{9y{UeRipqd(#w<#$yDPmf{=Ui@$P|!auQVlTF zjY}AVF*B&b+_opREi0q+yok!+CtdD@*L7^yaz9CrS;F|YM5-Bf#l-EfYbI{HF1DuG zI=5S_*Tq@wBl|@v2IJo0Pii&5r6UPjls)1T4BGTa7UY^SFXYlV@4)Z%w7@(PSF zwU=G{L}BeH%rEAHW8Hj8K`rTKGOt>+MGMaeG9=%V{dLP5Z@w|+@cuWqzVMo2m%J{c z8&<9#)-L-M`V$xU29fUD!Ei%%Bud>9$@L0c^G_Bk?K9UXD1Wb><^N{u5;dwktfgh6 zg1U^j#mmxwpK>|cVC|n*o+bh8pvc!D(qUJ?e$m7#3>S@SmCD%g3JP)!ZWJ%S=!$*2K7r&dVrkZ1}0phz{q@@q3} zleP}849PDgy|5NdCRZS}i*$*Ealg$KNLO3|qteE>XH~(xNLMF)S|V$&NRhyheTEw;fUwM2+;~7%-K@f3Ogz?dxYbj z54-01O$)K`t#C_=eh&~CVDWbZSSz6`0Q*3HfDs8}0rpBb5P+XG4hP`(jpG3>Nw^%K zMcvsdvPwH7bOvBu^ar5lNObJ7Z#4y}0k3opE;yR)vrMY^AgP;PRArwW65Vz5QZ znuybt7*}UaH5fBMx#gs-Flo7Q_h$X(b*M@E-Gw#S}(T?NZ zg?8Yh@3gvL^qrat>+@XLUK6*$yaRd`bpS1Top#FTfIEt2w|KL;yA;=7RW&I41J>+q zuyfYd9-4jA#oJ;vYgNx=(ZFK;)4=1_lu9{AD$J4FmfH{W23D9O7i_vzV7E=&3hS~~ zRm#DxFxUqzw;#6NBCM3dRbjXeTW&vW&?2mi6%kfcuca7*W*$^JqAa4(^H=&Z`CLm( z+rZKBW=z-9yP=GpHf8LPq0DQuFCWJQw7bH@wc_h_+XcNJdfAIMSm*Y##js__Ivfzv zS&_1+kY7C{!j6i}7Xp9Bk(62~Qx=o5V24CzihvvCQ{uXpqDr5sMYV_jzJ{9>Tc5>O zf$cQ0oDUiRuFYJz;u3HTYs)4t_xQk<%+4`pY7%2pH<*Y>D=Y zX{#{T7H3zqe`VSpm}~penq9lK)IJv4^{Qx-#ZumByCEmH%wGlOe~{4&8?>-0Ft4TP zULb#lLBGI{y4(Uk>vCJviS3s}YAXzN<8`<+sHO(x`JpuENe#*;mhgE_L^$xvF1NsM zyIh2W?VpPj4h(f;IHf@~H7LU=4SG_8G8}yB>SN)+H@RGdfWA$63IT>X8T}T)4$JC= zy}`r^%nge{0B#o1YIvp9Z zYR#VH-&K$jgu}a(Q(tojS$HIvBn#-36c-%ebrD?(Z}UH6D8?TBH$-X<40Y0+QdV9O3#J4)1uwLcGtpIi5f=^=eh!0%y6cBI`qte)gr|V+h}6% zCb5c(`m{trRuhef^Sw**DltpwM?`W2^KWOx0z)`p+A8d%iI2k0doIk&JSxc&WyVAr zMA&f?x4|e!GkfgGxofU~;lULWEbZ0jevt-(QeH(77O~`hC0Q!7ia^Mk6U9$K$j^z? zRDD{)?@bZC13#dnisTN7me8;ElMHN&iM_Cz=fWtIOc=`C7U_%+b8WGOqV2E(Juvs! z2ixtrFfUVVf|O}7?N*p;i_1#s=CN66_nP4{+P+d-c&6-ItU#sI7QOS*?c@|nA$4bz zeUX1bg@ETo^fG+j<(2RwE_cG~b|n4yS&5z~cuu4$VCa*(x~m0yt;lCjequy|mlufg z7ggwMULMvj8{I!U^@#-}zaeb*dnxFODA}r<^`hkRMb_PxRe_;ZnUkL=Zkch@bY4U= z;m2KW4WH;aL#s6~)XB8LszpR;_)3@C;A<4TZu;Jm=xIc3Ql$HS^ZO1-I1)hI(nft^ zp<9rZgSsV&0d4}Dkv_uC?$_rw$f4gN0Y5xUbE(jGHRvnKS69sMTR>v!Y3{=)=!z)n zNZFQf?&g&+*GVO8lS9iX8IrB&2M;E{Mn-;e)H^S;3!>*m6uBz8CR(e;*F~%k=2fJB zs6F?LPKeHm&gb;Jc%<*7U#){`w`h}Sizrf8n+8MFE!rfCG;)u&Q_-YouV}xBU+-7G zQWIJfiC$ z!@l%|mYCM&ee{F%fJ0wCIe8b$&r~Q50#GGMcOHB5uz{deM9t zY|`2s$=4@qi5o1DX1{}ePWpqQL%AKdh`31;3BTt>m*kiGIFVSdkr!psdXFfEqoU)Y zGf6yq<=}wmr09A$6MwOM4hzfeuP>H=LiVRbr$xlgwfcF{brE}6B=#TrD)zI;r|Fu; zcAe}H?-Vi4Yenfe|DW2)jirtH91|T8tx4i~v3x7Ep#+d9>P~@&Rp?qzEYc+a!Mz^*O>JAB}A);)SPK~EA?q5k@VxD@!8eJg!M&HiPc1E z&iMACRj-vpYUV49((%t26V|q%bh5zOB9!Ktib~D=ajnvcFL;BRGc9walLc-we5$~@ z{3x9+u(lheHvV-vrDpwfXz6I+c7vA-e6Qgf1=iM(q-On)kfvt)A+OA7&hn1SvzoKK z;|iR2T!HhBDzLV`BsKGNe3F`VXFW~LSw}wNp4*cB&let-82!yR$A6OG6~Z4Ct`%O}vI1V{PFM1Pm22IJ2RY06$@{T1^~Gs)Ig;3i@G z^YE;vyR&zxVBqk7Hqq1nF`xDKzu6DVK5&yT`j~$i^%F>*qW^hL)|0o_R{=TqWlt?* z&wHgkx&46z6aQR-ssB)d(evJEPhS3bg3Qukx{t~0_N-+M9BpChi1fy?zgFY;I zeK$28o?eyxzLq4Ios01~uO)sf!IVFpThkw(h@#4i{^Q-%p4|VM1QQP@tyJH&2*-Yv zWv}q{RMc^w{o|NXI_l%y*WvHyWE=0oj`=Z}=)Wv|U6>_?o_N5X?zXGh!9@S3vOkqz z+J7Ojr~JhPH?43S{$C@^BZ7Qsjd)gne_mZ)Kkvl$ba(axvWs_Qhy8q_r#{}39rjyf zAMeJ-ewT2(6FbVcys5OOJnzW%ba(dSvX6IWWB+;KcxQG|{>`O5<#|uGr@OOXlYP7o z8~Z;Hj`v|l`7=LI+TW0VQkVF%>R0slG)sPqPFKnYiP7^8 zX-}>{lVJ0oVB)*{P-%~z_egv4@@pS1F?!x5?aB3r5{#brNvHab;>hLwzc#_tzw+&k z_E)qYc)HitCyz~e^7VQs)Y=~&*7!z>^~(F7J$ZcHcLcsK`=Mp*c~5iLZ?_iPH=6#HroWc-H~-2ZSWM-;|BuR_ zC--+g>CZpGFi+9{yxZB6x9|Cnlo%E7boS)>YyBlg&pVwxxxRx#kR|Uw-sK#a_FWw) zG3DC^ON@T=B78GHU(z3csrbR{r%l4x*MCYMmb|^Ui~f0)eJcdV_3Kp#KVM>t=gz#i z<|oeuMvDHa3`UN(@BDCyiJx~rdvbmIt`ei?z0aOpe<8u>dFOMgZ`oa9>z@P@Z+C*x z^A2cF?*H&eiP7_pXHTxbUi8ns*+XhC*!#!l&-#O5@BMk)zji3|zU+}@`iFNfdvgEJ z7l&9Mf8K|j>JPj;@O{~bmhs1XkW>54iAKylP){D;=DP#m*YNE>#&1JXez)pN@xG+~ zOy}oMB{<4&dNTaqoqcW@{q1_G|Ch_?$DS$mzq*Y6@Ux}{8=zI6;!;<^&+n+<#hyGN8DStY_=-dCP zJ}i0pRS8C4PcY?Y6O8^+g3(`2F#5Jn>cf)zZ%;7#%?YObmIR~UpJ4O{5{&+Ig3+Hz zF!~z_Mt?KG=-2+JJ}l+qlVJ3R5={9c2}WK2}XY^!IVFfVDue7W`*_PU9J;CV55^V7&82yC=qraG7^fwZW{$_&Fw-x8{y#55EU!P#gcO@8o zCBdyPQ%0WR`qG=|e>0Tg=qVrf7x_2*UZe7Xn}pHF{i;m&tJX*#nEO|0!e5v4>>nGX z;Jp9C!tBSj91jU|eF^>3!u`)`56ksGCLGs)${!NmtLrmU0{nBrtdEf#pAx1&I&%D< zggX*{|5bRiuK(S+{_Dcbzu6qO+~NE6V2)oa%>EhpA>sA1-<0bs!WEr2POR{FwhOc0 zMSCWM*+0f|`%ejTKIqT!PYb8*`8?(2?_}=pm@xZGl>axv?3dyH_l1wBJrUm@3$q_? z%>92;nEhok$KQ3QUoXP`jly;HCr32;^R2?1e-7vPZNkU3K00#DKlM=mi8B5PVdhhB zuK&0&*Yl|Vp9yn)jPd!haEIbuliUBAFz1=j|CTW4qqbcCpM}{!qy5)~xgJFOn_D#& z`FW4{?-Axa6Z$p6oDXWbzjq0<--o|Ph12oaDLkk6^uP7Tq%haF@b_t9<|Dt9P~T^T z<9;gN=e{7^x4#^ZQ^K6*Hs${QoiOLmu@zqatBdd-3a8_LMRe=omF zax&jLgxOCza{b$d)A4yknDb2Z$K%56Po25_r0~eoTBCV<&j=q#*3X>9B%H3N zEyD5pMw9lVZNlmJ?iA+w7yh0V?$mth$o+jrnCn~2mtPd-{2%fEif}rAe_c2o@Bb*w z`7-*8N94F3h5r|X`-Ru$^?l#nemx5R?-b_xGnngpg*mTD6i=Y+YQM|;04+?Dk28DY+&QQy~uIbVeRe-}>oyKf0kCgtx~srfx!&ZqW8`1QhR z|E(3?oRt4Tu+~Sn;%9w*Ksepswh8lnBl>4dIGwMLt6coPmg)Dkj|v}Jtq)5txBHWa z6a0+IN8;D8&j|08lU0&msrtVl%>8ioBk-3O+5cPNt4IC&_&w@>{spng!P5SZ7TNz* zg725lyI!G>Jave_QFu=G%UUH<-y^~?zHPdnUlrzEW}*LRQl9vq73Th4i)7;Yap4PZ z=9j0uJ;GzJFUy}?RQ{|m_a`>z_Fomg^04x9d{vnHC!2Eom%`l7jd)tWOZ&~3Uq6U{ zm2jkcB)m|2FFTx^N`w`=;;g>R0Q zPYCn-$3f}9pI&7DGm9|)m@L1i^yT*dUYOrAW4>J!zNP-{&}N0duM2a3KGyr+2}eTw z-tP&7z2=JW2F=gt|MxA@4=uto!WGpY<9A?@{&T{6JIeiez20u_y4&*67RW1 z<^Nz2{&V3$t%qpOw}kf(mhFF;IwJM|3OXiFwD0>9%+PKSF87~TWt)UAX+GVSj(7%y zCpF*W`tp=;+hDoh%n5INuv~u&!h>C9e7`0fiTb}Pyg~8DeEnnLTC$%0R`}e*<$AkU zk8tq&0Z#@I&s+SF4s+R|&vzvl|5f2b+OJpU_CvxqlJTDs?$$+iwQTYCNnw6}3Vc{N z68^p@d{pzTQ!@5vh5J?ha*qE%nBOnj^7{UV@FB$;ew#;YqF6*dPCuFwYwd z=H<@{ukFwr&hbTIe*d4#@qZDHM1Nct=J!5@Xz|?nYW0Wg+j9JB;duV!mHO4{KH*4| zUnhKhOfgHQJsX6(G~c5B&BENz*EBHwW5O5If9rERAfa`^uZVV+lr{`?)`&0S^xWe?0uPd%V_=RUA|=gzn8oSK-Peqd;7&s+6M z+nL$7?jD~R9@;VbK-ao=Jg{zE`TtT2JjepJbE-bNZX)X(((APKvfZbLhn^VNHJ)|W z{{Pf9uDVp^bbV&mu64ZN_Jk@9G_`H<((nF$JR_Yr{Kcc8lBls&@`NH9R#vIx!v@{?_Y8WUr+* z^ZcFIyNAbzr$%?`{k}xq@Vachr+QTHH(o}g_e=9;Z1dw*4F$brX*qvmJ#W5lFwARs z30HZPsjob1$Hc_g@X+|;I7Y{7>e6+34|{#xgAJ9{CT4c%<>xO^Su!FTgW<;B(2K5Z ztd?rL*h~1$BYp{sQBAEO&7l~q{PpvTpuLv5u2+0NH9Y1`8`Z1gi%uP%;hogc#pCLm z0@SBw^d{_3y~w-k?FHx4*-U-c2GukDn$szQJki_KfZfmto*u2Hw~6?hn3q;JqK(q@BdKm5`^O8Q)33 z14HArfnCG(og)Lhaon;UqL`Q(cxc&NY=_ub2Wo25*l+>$ZthWDKkhA!vW*q7H(5nv zdQrH>TZ?IWcz|4YxpR@vT@Uega4Vr#whyq+4NVPOS`&8k-oZ*G6l+(capv zC6yK}hH6oM;j(Np1!?kF-J{w)?A+Y4lP&GfqK9mJ>ce`|I$oyr>UdOnyB?YueKx`? ztFwTL@D}Bly)tS;T6h}6lOtBl`tZwmQMLOiTGyCuL*{dFD(UR9Ze=bvxydeE0vcclYiSf~AS%X$r!>TF_8*&M^+$y4A86+LNe8~+m_B~BP-UzMr-SwqTh`4al=(`*; zwu@r8mtB#?Y%E>i85d*uT(;#h?aReuvMprz$q1@p8kKW+XKgBWuW@&^Y5RxX{lO1B zqH^YQW;|Vl%#U)8lx}R#+cQyYQi~R4X~@1dGmi6OA9uix9N%_()t&-oNF;?|Ju@fe*j$eOuq#JJ9>?_iTADSDD@UMq~9h zuGGe!D2J!4hgF4@6>eN&Nnwq@Y?9f>+|LKBVH(W%J`)$(hC*X?!Qt8Z@OW){SGr>- zi@Xesai`1jO1a4K-C$y8clZ0ZeBeEg3_P^1%TFr#0ct?ksOkJ1SDcS^ycnGxUQ%Ry zX3q{C@OO@=NT$=?WPM6kk(r^fOa~{;nY4f|t+PX#K;uJWTJsH>5A=ReN9OpxppoL+ zLhq1{o(-o_PJDj2uMO`Snz4S^F+HtAnoh1dD5Pg}KVXgxkMFLJWK+XKwX{Mr92uU? z15eBC*0rMk%;a#EJJ6Q~tyc5G@iz6M_ST7U>FIWS_-X(CL7xomn3$?J#J1>AJE^Y> z^&K<22KEf^(WOdbr3UGIv2)~!f!#AhQw^cZ;S=<-*Q|;fJX5iHUSC1v<*Dg$bG-{s zY2d17=j1bKPTB+I*N1FixHeQDYN%mmdU%S=m-8w7wr=i!Zs+ek1!!$Up zo&NW-4cRvIn(!Pd$447flqlNFbdcGylL5og+H6B%A7x*bWv}lV8XZf!XU|SML)cfx zhT^o;`-_qGF&Uefcw%N!3$(#9@6~)Nr7gCmjcYv@r+FsA(Bve|)y#d#wOW4ViY~Qp zBw9_=`B&V$Vyk6`zLAf|Ivp9B9?>kBRkQ19W2fs{ic@J$8ZDiew>Zr<_mjiJPYl@C z8&lanqV-yTdlz*+!7h=^TPEl;(_<667f(+s9L=GJqbrNuXh8c;xaqz< zfV2wjpKMG6I|deQ-ovw_4FhQXw{rkb$(O<!b>^6{kd1!jMZsx!z zPqmqbt5CA7TMKN%w_I7mAiuu$}^1@bvjwS$Xzo{!-iUSO-=04e$SVYA9`w_C%>Ke z$k@>IwC*MPjgn=1dURa9^FtGaac36C#QA6PW>)3`(<5v^A_i~B~xSd zFyWV*PXxnI?HU`}J>3vOJ_bY*3n$NFn;(cvZ#KYrY1z|KG1qiq<%?B;X}wmfuRWV+ z95~9WM_x}Ja6?r2cBUOESsM6DpgEF%ze3vjZ9M#?y@JDJ#1l7kd}b%SOgD@h&zru+ z6?H>!nv&&ZbLnYdz#QQa2PQ8iMi`S!1$w z)6eYDxjvWrc-Hw^jvD#ZlYndUt#;mJ7Gp>@EaovM7O@6Ps0Sri| z8&TM~FsWnlI_`jH>*`$e*4cq+-PD8~<<q1Z#E%+bf;WmY<{P715v(* zbgNGFPRO78(H4}g(+w@|c4q6|-Sfe9Lv^j<9W(l_CL3 zP&Wh>kQd6MbD*w@eC;?P=5FJ+neW73D}y^l`WfB+aiyE${Du>$B^UHlQ1;CiUYNj+ zXB;5@#RdIu2|I}2yY3cYcSRY{(YsuSEjIin)GY#I$KTOIJmVEf?k#QBr~YwjtCzp8 zhq|PUdMOWW6aBB;j=#Hy_-%{&(8EbJ5!H}qe^&k){idDx!;atZ^i!DGy+@qC(}y~8 zJAT6oyQd@*>m4F~e}ni4E$KRhrg9MYO@b^jKu;aNB zh`1w#-JCM8qrE3(1MzPeM+)(vGQy7Mc%jf?8}iRe)=*jh^Y_*#zEJ8?yMG~|pWMxk zzwW@W=CfZ43UJXXxSd)9;9) zUV9GisQvg=MVLVTHokg@yGU(ko1--{HwdluWhzA1Z? z=4zy{d)*?tU;0N)S^4+hWnKOcmqlqkQ#069D^+Jy< zs`uGXH)Ur&5LRWqA6jJh_TOvD_A@c^gf9}$VlZZrHr~6!-ozR>?BJ}SNT>g>DLeW` e{VS!);0<}SqfNx#lKSiWyQb`_e%p=|{{A=2l!PS! literal 0 HcmV?d00001 diff --git a/src/lib/install/include/adaptor/adaptor_api.h b/src/lib/install/include/adaptor/adaptor_api.h new file mode 100755 index 0000000..6a67da9 --- /dev/null +++ b/src/lib/install/include/adaptor/adaptor_api.h @@ -0,0 +1,62 @@ +/** + * @file adaptor_api.h + * @brief library for providing adaptor API + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_API_H__ +#define __ADAPTOR_API_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "adaptor_api_types.h" + +#ifndef API +#define API __attribute__ ((visibility("default"))) +#endif + +/** + * @fn int device_reboot(void) + * @brief this function to reboot target device + * @param void + * @return int return of function + */ +API int device_reboot(void); + +/** + * @fn int get_os_info(void) + * @brief this function to get os information + * @param *os_info [out] fill os information + * @return int return of function + */ +API int get_os_info(os_info_s * os_info); + +/** + * @fn int device_reboot(void) + * @brief this function to get disk information + * @param *disk_info [out] fill disk information + * @return int return of function + */ +API int get_disk_info(disk_info_s * disk_info); + +/** + * @fn int factory_restore(void) + * @brief this function to restore factory state + * @param void + * @return int return of function + */ +API int factory_restore(); + +#ifdef __cplusplus +} +#endif + +#endif /* __ADAPTOR_API_H__ */ diff --git a/src/lib/install/include/adaptor/adaptor_api_types.h b/src/lib/install/include/adaptor/adaptor_api_types.h new file mode 100644 index 0000000..e68cb1f --- /dev/null +++ b/src/lib/install/include/adaptor/adaptor_api_types.h @@ -0,0 +1,66 @@ +/** + * @file adaptor_api_types.h + * @brief Types of API for dockzen + + * Copyright (c) 2017 Samsung Electronics Co., Ltd. + * This software is the confidential and proprietary information + * of Samsung Electronics, Inc. ("Confidential Information"). You + * shall not disclose such Confidential Information and shall use + * it only in accordance with the terms of the license agreement + * you entered into with Samsung. + */ + +#ifndef __ADAPTOR_API_TYPES_H__ +#define __ADAPTOR_API_TYPES_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_CONTAINER_NUM (10) +#define MAX_DISK_NUM (10) + +/** + * @brief This enum contains dockzen error information + * + * The adaptor_api_error_e indicates what error is happened + * + */ +typedef enum { + ADAPTOR_API_ERROR_NONE = 0, /**< Successful */ + ADAPTOR_API_ERROR_INVALID_PARAMETER, /**< Invalid parameter */ + ADAPTOR_API_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + ADAPTOR_API_ERROR_PERMISSION_DENIED, /**< Permission denied */ + ADAPTOR_API_ERROR_NOT_SUPPORTED, /**< Not supported */ +} ADAPTOR_API_error_e; + +/** + * @struct os_info_s + * @brief This struct contains os information + */ +typedef struct{ + char * platformVer; + char * baseOSVer; + char * dockerVer; +} os_info_s; + + +/** + * @struct disk_info_s + * @brief This struct contains disk information + */ +typedef struct{ + int count; /**< the counts of containers info */ + struct { + char * path; + int free; /* MB */ + int total; /* MB */ + int used; /* MB */ + int usedpercent; /* divide by 100 to get percentage. (float)disk_info.disk[index].usedpercent/(float)100 */ + }disk[MAX_DISK_NUM]; /**< Max Count constraint */ +} disk_info_s; + +#ifdef __cplusplus +} +#endif +#endif /* __ADAPTOR_API_TYPES_H__ */ diff --git a/src/lib/install/include/gmock/gmock-actions.h b/src/lib/install/include/gmock/gmock-actions.h new file mode 100644 index 0000000..b3f654a --- /dev/null +++ b/src/lib/install/include/gmock/gmock-actions.h @@ -0,0 +1,1205 @@ +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used actions. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ + +#ifndef _WIN32_WCE +# include +#endif + +#include +#include + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" + +#if GTEST_HAS_STD_TYPE_TRAITS_ // Defined by gtest-port.h via gmock-port.h. +#include +#endif + +namespace testing { + +// To implement an action Foo, define: +// 1. a class FooAction that implements the ActionInterface interface, and +// 2. a factory function that creates an Action object from a +// const FooAction*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Action objects can now be copied like plain values. + +namespace internal { + +template +class ActionAdaptor; + +// BuiltInDefaultValueGetter::Get() returns a +// default-constructed T value. BuiltInDefaultValueGetter::Get() crashes with an error. +// +// This primary template is used when kDefaultConstructible is true. +template +struct BuiltInDefaultValueGetter { + static T Get() { return T(); } +}; +template +struct BuiltInDefaultValueGetter { + static T Get() { + Assert(false, __FILE__, __LINE__, + "Default action undefined for the function return type."); + return internal::Invalid(); + // The above statement will never be reached, but is required in + // order for this function to compile. + } +}; + +// BuiltInDefaultValue::Get() returns the "built-in" default value +// for type T, which is NULL when T is a raw pointer type, 0 when T is +// a numeric type, false when T is bool, or "" when T is string or +// std::string. In addition, in C++11 and above, it turns a +// default-constructed T value if T is default constructible. For any +// other type T, the built-in default T value is undefined, and the +// function will abort the process. +template +class BuiltInDefaultValue { + public: +#if GTEST_HAS_STD_TYPE_TRAITS_ + // This function returns true iff type T has a built-in default value. + static bool Exists() { + return ::std::is_default_constructible::value; + } + + static T Get() { + return BuiltInDefaultValueGetter< + T, ::std::is_default_constructible::value>::Get(); + } + +#else // GTEST_HAS_STD_TYPE_TRAITS_ + // This function returns true iff type T has a built-in default value. + static bool Exists() { + return false; + } + + static T Get() { + return BuiltInDefaultValueGetter::Get(); + } + +#endif // GTEST_HAS_STD_TYPE_TRAITS_ +}; + +// This partial specialization says that we use the same built-in +// default value for T and const T. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return BuiltInDefaultValue::Exists(); } + static T Get() { return BuiltInDefaultValue::Get(); } +}; + +// This partial specialization defines the default values for pointer +// types. +template +class BuiltInDefaultValue { + public: + static bool Exists() { return true; } + static T* Get() { return NULL; } +}; + +// The following specializations define the default values for +// specific types we care about. +#define GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(type, value) \ + template <> \ + class BuiltInDefaultValue { \ + public: \ + static bool Exists() { return true; } \ + static type Get() { return value; } \ + } + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(void, ); // NOLINT +#if GTEST_HAS_GLOBAL_STRING +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::string, ""); +#endif // GTEST_HAS_GLOBAL_STRING +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(::std::string, ""); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(bool, false); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed char, '\0'); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(char, '\0'); + +// There's no need for a default action for signed wchar_t, as that +// type is the same as wchar_t for gcc, and invalid for MSVC. +// +// There's also no need for a default action for unsigned wchar_t, as +// that type is the same as unsigned int for gcc, and invalid for +// MSVC. +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(wchar_t, 0U); // NOLINT +#endif + +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned short, 0U); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed short, 0); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned int, 0U); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed int, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(unsigned long, 0UL); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(signed long, 0L); // NOLINT +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(UInt64, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(Int64, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(float, 0); +GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_(double, 0); + +#undef GMOCK_DEFINE_DEFAULT_ACTION_FOR_RETURN_TYPE_ + +} // namespace internal + +// When an unexpected function call is encountered, Google Mock will +// let it return a default value if the user has specified one for its +// return type, or if the return type has a built-in default value; +// otherwise Google Mock won't know what value to return and will have +// to abort the process. +// +// The DefaultValue class allows a user to specify the +// default value for a type T that is both copyable and publicly +// destructible (i.e. anything that can be used as a function return +// type). The usage is: +// +// // Sets the default value for type T to be foo. +// DefaultValue::Set(foo); +template +class DefaultValue { + public: + // Sets the default value for type T; requires T to be + // copy-constructable and have a public destructor. + static void Set(T x) { + delete producer_; + producer_ = new FixedValueProducer(x); + } + + // Provides a factory function to be called to generate the default value. + // This method can be used even if T is only move-constructible, but it is not + // limited to that case. + typedef T (*FactoryFunction)(); + static void SetFactory(FactoryFunction factory) { + delete producer_; + producer_ = new FactoryValueProducer(factory); + } + + // Unsets the default value for type T. + static void Clear() { + delete producer_; + producer_ = NULL; + } + + // Returns true iff the user has set the default value for type T. + static bool IsSet() { return producer_ != NULL; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T if the user has set one; + // otherwise returns the built-in default value. Requires that Exists() + // is true, which ensures that the return value is well-defined. + static T Get() { + return producer_ == NULL ? + internal::BuiltInDefaultValue::Get() : producer_->Produce(); + } + + private: + class ValueProducer { + public: + virtual ~ValueProducer() {} + virtual T Produce() = 0; + }; + + class FixedValueProducer : public ValueProducer { + public: + explicit FixedValueProducer(T value) : value_(value) {} + virtual T Produce() { return value_; } + + private: + const T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FixedValueProducer); + }; + + class FactoryValueProducer : public ValueProducer { + public: + explicit FactoryValueProducer(FactoryFunction factory) + : factory_(factory) {} + virtual T Produce() { return factory_(); } + + private: + const FactoryFunction factory_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(FactoryValueProducer); + }; + + static ValueProducer* producer_; +}; + +// This partial specialization allows a user to set default values for +// reference types. +template +class DefaultValue { + public: + // Sets the default value for type T&. + static void Set(T& x) { // NOLINT + address_ = &x; + } + + // Unsets the default value for type T&. + static void Clear() { + address_ = NULL; + } + + // Returns true iff the user has set the default value for type T&. + static bool IsSet() { return address_ != NULL; } + + // Returns true if T has a default return value set by the user or there + // exists a built-in default value. + static bool Exists() { + return IsSet() || internal::BuiltInDefaultValue::Exists(); + } + + // Returns the default value for type T& if the user has set one; + // otherwise returns the built-in default value if there is one; + // otherwise aborts the process. + static T& Get() { + return address_ == NULL ? + internal::BuiltInDefaultValue::Get() : *address_; + } + + private: + static T* address_; +}; + +// This specialization allows DefaultValue::Get() to +// compile. +template <> +class DefaultValue { + public: + static bool Exists() { return true; } + static void Get() {} +}; + +// Points to the user-set default value for type T. +template +typename DefaultValue::ValueProducer* DefaultValue::producer_ = NULL; + +// Points to the user-set default value for type T&. +template +T* DefaultValue::address_ = NULL; + +// Implement this interface to define an action for function type F. +template +class ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + ActionInterface() {} + virtual ~ActionInterface() {} + + // Performs the action. This method is not const, as in general an + // action can have side effects and be stateful. For example, a + // get-the-next-element-from-the-collection action will need to + // remember the current element. + virtual Result Perform(const ArgumentTuple& args) = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ActionInterface); +}; + +// An Action is a copyable and IMMUTABLE (except by assignment) +// object that represents an action to be taken when a mock function +// of type F is called. The implementation of Action is just a +// linked_ptr to const ActionInterface, so copying is fairly cheap. +// Don't inherit from Action! +// +// You can view an object implementing ActionInterface as a +// concrete action (including its current state), and an Action +// object as a handle to it. +template +class Action { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + // Constructs a null Action. Needed for storing Action objects in + // STL containers. + Action() : impl_(NULL) {} + + // Constructs an Action from its implementation. A NULL impl is + // used to represent the "do-default" action. + explicit Action(ActionInterface* impl) : impl_(impl) {} + + // Copy constructor. + Action(const Action& action) : impl_(action.impl_) {} + + // This constructor allows us to turn an Action object into an + // Action, as long as F's arguments can be implicitly converted + // to Func's and Func's return type can be implicitly converted to + // F's. + template + explicit Action(const Action& action); + + // Returns true iff this is the DoDefault() action. + bool IsDoDefault() const { return impl_.get() == NULL; } + + // Performs the action. Note that this method is const even though + // the corresponding method in ActionInterface is not. The reason + // is that a const Action means that it cannot be re-bound to + // another concrete action, not that the concrete action it binds to + // cannot change state. (Think of the difference between a const + // pointer and a pointer to const.) + Result Perform(const ArgumentTuple& args) const { + internal::Assert( + !IsDoDefault(), __FILE__, __LINE__, + "You are using DoDefault() inside a composite action like " + "DoAll() or WithArgs(). This is not supported for technical " + "reasons. Please instead spell out the default action, or " + "assign the default action to an Action variable and use " + "the variable in various places."); + return impl_->Perform(args); + } + + private: + template + friend class internal::ActionAdaptor; + + internal::linked_ptr > impl_; +}; + +// The PolymorphicAction class template makes it easy to implement a +// polymorphic action (i.e. an action that can be used in mock +// functions of than one type, e.g. Return()). +// +// To define a polymorphic action, a user first provides a COPYABLE +// implementation class that has a Perform() method template: +// +// class FooAction { +// public: +// template +// Result Perform(const ArgumentTuple& args) const { +// // Processes the arguments and returns a result, using +// // tr1::get(args) to get the N-th (0-based) argument in the tuple. +// } +// ... +// }; +// +// Then the user creates the polymorphic action using +// MakePolymorphicAction(object) where object has type FooAction. See +// the definition of Return(void) and SetArgumentPointee(value) for +// complete examples. +template +class PolymorphicAction { + public: + explicit PolymorphicAction(const Impl& impl) : impl_(impl) {} + + template + operator Action() const { + return Action(new MonomorphicImpl(impl_)); + } + + private: + template + class MonomorphicImpl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + virtual Result Perform(const ArgumentTuple& args) { + return impl_.template Perform(args); + } + + private: + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); + }; + + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(PolymorphicAction); +}; + +// Creates an Action from its implementation and returns it. The +// created Action object owns the implementation. +template +Action MakeAction(ActionInterface* impl) { + return Action(impl); +} + +// Creates a polymorphic action from its implementation. This is +// easier to use than the PolymorphicAction constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicAction(foo); +// vs +// PolymorphicAction(foo); +template +inline PolymorphicAction MakePolymorphicAction(const Impl& impl) { + return PolymorphicAction(impl); +} + +namespace internal { + +// Allows an Action object to pose as an Action, as long as F2 +// and F1 are compatible. +template +class ActionAdaptor : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit ActionAdaptor(const Action& from) : impl_(from.impl_) {} + + virtual Result Perform(const ArgumentTuple& args) { + return impl_->Perform(args); + } + + private: + const internal::linked_ptr > impl_; + + GTEST_DISALLOW_ASSIGN_(ActionAdaptor); +}; + +// Helper struct to specialize ReturnAction to execute a move instead of a copy +// on return. Useful for move-only types, but could be used on any type. +template +struct ByMoveWrapper { + explicit ByMoveWrapper(T value) : payload(internal::move(value)) {} + T payload; +}; + +// Implements the polymorphic Return(x) action, which can be used in +// any function that returns the type of x, regardless of the argument +// types. +// +// Note: The value passed into Return must be converted into +// Function::Result when this action is cast to Action rather than +// when that action is performed. This is important in scenarios like +// +// MOCK_METHOD1(Method, T(U)); +// ... +// { +// Foo foo; +// X x(&foo); +// EXPECT_CALL(mock, Method(_)).WillOnce(Return(x)); +// } +// +// In the example above the variable x holds reference to foo which leaves +// scope and gets destroyed. If copying X just copies a reference to foo, +// that copy will be left with a hanging reference. If conversion to T +// makes a copy of foo, the above code is safe. To support that scenario, we +// need to make sure that the type conversion happens inside the EXPECT_CALL +// statement, and conversion of the result of Return to Action is a +// good place for that. +// +template +class ReturnAction { + public: + // Constructs a ReturnAction object from the value to be returned. + // 'value' is passed by value instead of by const reference in order + // to allow Return("string literal") to compile. + explicit ReturnAction(R value) : value_(new R(internal::move(value))) {} + + // This template type conversion operator allows Return(x) to be + // used in ANY function that returns x's type. + template + operator Action() const { + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename Function::Result Result; + GTEST_COMPILE_ASSERT_( + !is_reference::value, + use_ReturnRef_instead_of_Return_to_return_a_reference); + return Action(new Impl(value_)); + } + + private: + // Implements the Return(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + // The implicit cast is necessary when Result has more than one + // single-argument constructor (e.g. Result is std::vector) and R + // has a type conversion operator template. In that case, value_(value) + // won't compile as the compiler doesn't known which constructor of + // Result to call. ImplicitCast_ forces the compiler to convert R to + // Result without considering explicit constructors, thus resolving the + // ambiguity. value_ is then initialized using its copy constructor. + explicit Impl(const linked_ptr& value) + : value_before_cast_(*value), + value_(ImplicitCast_(value_before_cast_)) {} + + virtual Result Perform(const ArgumentTuple&) { return value_; } + + private: + GTEST_COMPILE_ASSERT_(!is_reference::value, + Result_cannot_be_a_reference_type); + // We save the value before casting just in case it is being cast to a + // wrapper type. + R value_before_cast_; + Result value_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Impl); + }; + + // Partially specialize for ByMoveWrapper. This version of ReturnAction will + // move its contents instead. + template + class Impl, F> : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const linked_ptr& wrapper) + : performed_(false), wrapper_(wrapper) {} + + virtual Result Perform(const ArgumentTuple&) { + GTEST_CHECK_(!performed_) + << "A ByMove() action should only be performed once."; + performed_ = true; + return internal::move(wrapper_->payload); + } + + private: + bool performed_; + const linked_ptr wrapper_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const linked_ptr value_; + + GTEST_DISALLOW_ASSIGN_(ReturnAction); +}; + +// Implements the ReturnNull() action. +class ReturnNullAction { + public: + // Allows ReturnNull() to be used in any pointer-returning function. In C++11 + // this is enforced by returning nullptr, and in non-C++11 by asserting a + // pointer type on compile time. + template + static Result Perform(const ArgumentTuple&) { +#if GTEST_LANG_CXX11 + return nullptr; +#else + GTEST_COMPILE_ASSERT_(internal::is_pointer::value, + ReturnNull_can_be_used_to_return_a_pointer_only); + return NULL; +#endif // GTEST_LANG_CXX11 + } +}; + +// Implements the Return() action. +class ReturnVoidAction { + public: + // Allows Return() to be used in any void-returning function. + template + static void Perform(const ArgumentTuple&) { + CompileAssertTypesEqual(); + } +}; + +// Implements the polymorphic ReturnRef(x) action, which can be used +// in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefAction { + public: + // Constructs a ReturnRefAction object from the reference to be returned. + explicit ReturnRefAction(T& ref) : ref_(ref) {} // NOLINT + + // This template type conversion operator allows ReturnRef(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRef(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_(internal::is_reference::value, + use_Return_instead_of_ReturnRef_to_return_a_value); + return Action(new Impl(ref_)); + } + + private: + // Implements the ReturnRef(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(T& ref) : ref_(ref) {} // NOLINT + + virtual Result Perform(const ArgumentTuple&) { + return ref_; + } + + private: + T& ref_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& ref_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefAction); +}; + +// Implements the polymorphic ReturnRefOfCopy(x) action, which can be +// used in any function that returns a reference to the type of x, +// regardless of the argument types. +template +class ReturnRefOfCopyAction { + public: + // Constructs a ReturnRefOfCopyAction object from the reference to + // be returned. + explicit ReturnRefOfCopyAction(const T& value) : value_(value) {} // NOLINT + + // This template type conversion operator allows ReturnRefOfCopy(x) to be + // used in ANY function that returns a reference to x's type. + template + operator Action() const { + typedef typename Function::Result Result; + // Asserts that the function return type is a reference. This + // catches the user error of using ReturnRefOfCopy(x) when Return(x) + // should be used, and generates some helpful error message. + GTEST_COMPILE_ASSERT_( + internal::is_reference::value, + use_Return_instead_of_ReturnRefOfCopy_to_return_a_value); + return Action(new Impl(value_)); + } + + private: + // Implements the ReturnRefOfCopy(x) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const T& value) : value_(value) {} // NOLINT + + virtual Result Perform(const ArgumentTuple&) { + return value_; + } + + private: + T value_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const T value_; + + GTEST_DISALLOW_ASSIGN_(ReturnRefOfCopyAction); +}; + +// Implements the polymorphic DoDefault() action. +class DoDefaultAction { + public: + // This template type conversion operator allows DoDefault() to be + // used in any function. + template + operator Action() const { return Action(NULL); } +}; + +// Implements the Assign action to set a given pointer referent to a +// particular value. +template +class AssignAction { + public: + AssignAction(T1* ptr, T2 value) : ptr_(ptr), value_(value) {} + + template + void Perform(const ArgumentTuple& /* args */) const { + *ptr_ = value_; + } + + private: + T1* const ptr_; + const T2 value_; + + GTEST_DISALLOW_ASSIGN_(AssignAction); +}; + +#if !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetErrnoAndReturn action to simulate return from +// various system calls and libc functions. +template +class SetErrnoAndReturnAction { + public: + SetErrnoAndReturnAction(int errno_value, T result) + : errno_(errno_value), + result_(result) {} + template + Result Perform(const ArgumentTuple& /* args */) const { + errno = errno_; + return result_; + } + + private: + const int errno_; + const T result_; + + GTEST_DISALLOW_ASSIGN_(SetErrnoAndReturnAction); +}; + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Implements the SetArgumentPointee(x) action for any function +// whose N-th argument (0-based) is a pointer to x's type. The +// template parameter kIsProto is true iff type A is ProtocolMessage, +// proto2::Message, or a sub-class of those. +template +class SetArgumentPointeeAction { + public: + // Constructs an action that sets the variable pointed to by the + // N-th function argument to 'value'. + explicit SetArgumentPointeeAction(const A& value) : value_(value) {} + + template + void Perform(const ArgumentTuple& args) const { + CompileAssertTypesEqual(); + *::testing::get(args) = value_; + } + + private: + const A value_; + + GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); +}; + +template +class SetArgumentPointeeAction { + public: + // Constructs an action that sets the variable pointed to by the + // N-th function argument to 'proto'. Both ProtocolMessage and + // proto2::Message have the CopyFrom() method, so the same + // implementation works for both. + explicit SetArgumentPointeeAction(const Proto& proto) : proto_(new Proto) { + proto_->CopyFrom(proto); + } + + template + void Perform(const ArgumentTuple& args) const { + CompileAssertTypesEqual(); + ::testing::get(args)->CopyFrom(*proto_); + } + + private: + const internal::linked_ptr proto_; + + GTEST_DISALLOW_ASSIGN_(SetArgumentPointeeAction); +}; + +// Implements the InvokeWithoutArgs(f) action. The template argument +// FunctionImpl is the implementation type of f, which can be either a +// function pointer or a functor. InvokeWithoutArgs(f) can be used as an +// Action as long as f's type is compatible with F (i.e. f can be +// assigned to a tr1::function). +template +class InvokeWithoutArgsAction { + public: + // The c'tor makes a copy of function_impl (either a function + // pointer or a functor). + explicit InvokeWithoutArgsAction(FunctionImpl function_impl) + : function_impl_(function_impl) {} + + // Allows InvokeWithoutArgs(f) to be used as any action whose type is + // compatible with f. + template + Result Perform(const ArgumentTuple&) { return function_impl_(); } + + private: + FunctionImpl function_impl_; + + GTEST_DISALLOW_ASSIGN_(InvokeWithoutArgsAction); +}; + +// Implements the InvokeWithoutArgs(object_ptr, &Class::Method) action. +template +class InvokeMethodWithoutArgsAction { + public: + InvokeMethodWithoutArgsAction(Class* obj_ptr, MethodPtr method_ptr) + : obj_ptr_(obj_ptr), method_ptr_(method_ptr) {} + + template + Result Perform(const ArgumentTuple&) const { + return (obj_ptr_->*method_ptr_)(); + } + + private: + Class* const obj_ptr_; + const MethodPtr method_ptr_; + + GTEST_DISALLOW_ASSIGN_(InvokeMethodWithoutArgsAction); +}; + +// Implements the IgnoreResult(action) action. +template +class IgnoreResultAction { + public: + explicit IgnoreResultAction(const A& action) : action_(action) {} + + template + operator Action() const { + // Assert statement belongs here because this is the best place to verify + // conditions on F. It produces the clearest error messages + // in most compilers. + // Impl really belongs in this scope as a local class but can't + // because MSVC produces duplicate symbols in different translation units + // in this case. Until MS fixes that bug we put Impl into the class scope + // and put the typedef both here (for use in assert statement) and + // in the Impl class. But both definitions must be the same. + typedef typename internal::Function::Result Result; + + // Asserts at compile time that F returns void. + CompileAssertTypesEqual(); + + return Action(new Impl(action_)); + } + + private: + template + class Impl : public ActionInterface { + public: + typedef typename internal::Function::Result Result; + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const A& action) : action_(action) {} + + virtual void Perform(const ArgumentTuple& args) { + // Performs the action and ignores its result. + action_.Perform(args); + } + + private: + // Type OriginalFunction is the same as F except that its return + // type is IgnoredValue. + typedef typename internal::Function::MakeResultIgnoredValue + OriginalFunction; + + const Action action_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + const A action_; + + GTEST_DISALLOW_ASSIGN_(IgnoreResultAction); +}; + +// A ReferenceWrapper object represents a reference to type T, +// which can be either const or not. It can be explicitly converted +// from, and implicitly converted to, a T&. Unlike a reference, +// ReferenceWrapper can be copied and can survive template type +// inference. This is used to support by-reference arguments in the +// InvokeArgument(...) action. The idea was from "reference +// wrappers" in tr1, which we don't have in our source tree yet. +template +class ReferenceWrapper { + public: + // Constructs a ReferenceWrapper object from a T&. + explicit ReferenceWrapper(T& l_value) : pointer_(&l_value) {} // NOLINT + + // Allows a ReferenceWrapper object to be implicitly converted to + // a T&. + operator T&() const { return *pointer_; } + private: + T* pointer_; +}; + +// Allows the expression ByRef(x) to be printed as a reference to x. +template +void PrintTo(const ReferenceWrapper& ref, ::std::ostream* os) { + T& value = ref; + UniversalPrinter::Print(value, os); +} + +// Does two actions sequentially. Used for implementing the DoAll(a1, +// a2, ...) action. +template +class DoBothAction { + public: + DoBothAction(Action1 action1, Action2 action2) + : action1_(action1), action2_(action2) {} + + // This template type conversion operator allows DoAll(a1, ..., a_n) + // to be used in ANY function of compatible type. + template + operator Action() const { + return Action(new Impl(action1_, action2_)); + } + + private: + // Implements the DoAll(...) action for a particular function type F. + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + typedef typename Function::MakeResultVoid VoidResult; + + Impl(const Action& action1, const Action& action2) + : action1_(action1), action2_(action2) {} + + virtual Result Perform(const ArgumentTuple& args) { + action1_.Perform(args); + return action2_.Perform(args); + } + + private: + const Action action1_; + const Action action2_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + Action1 action1_; + Action2 action2_; + + GTEST_DISALLOW_ASSIGN_(DoBothAction); +}; + +} // namespace internal + +// An Unused object can be implicitly constructed from ANY value. +// This is handy when defining actions that ignore some or all of the +// mock function arguments. For example, given +// +// MOCK_METHOD3(Foo, double(const string& label, double x, double y)); +// MOCK_METHOD3(Bar, double(int index, double x, double y)); +// +// instead of +// +// double DistanceToOriginWithLabel(const string& label, double x, double y) { +// return sqrt(x*x + y*y); +// } +// double DistanceToOriginWithIndex(int index, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXEPCT_CALL(mock, Foo("abc", _, _)) +// .WillOnce(Invoke(DistanceToOriginWithLabel)); +// EXEPCT_CALL(mock, Bar(5, _, _)) +// .WillOnce(Invoke(DistanceToOriginWithIndex)); +// +// you could write +// +// // We can declare any uninteresting argument as Unused. +// double DistanceToOrigin(Unused, double x, double y) { +// return sqrt(x*x + y*y); +// } +// ... +// EXEPCT_CALL(mock, Foo("abc", _, _)).WillOnce(Invoke(DistanceToOrigin)); +// EXEPCT_CALL(mock, Bar(5, _, _)).WillOnce(Invoke(DistanceToOrigin)); +typedef internal::IgnoredValue Unused; + +// This constructor allows us to turn an Action object into an +// Action, as long as To's arguments can be implicitly converted +// to From's and From's return type cann be implicitly converted to +// To's. +template +template +Action::Action(const Action& from) + : impl_(new internal::ActionAdaptor(from)) {} + +// Creates an action that returns 'value'. 'value' is passed by value +// instead of const reference - otherwise Return("string literal") +// will trigger a compiler error about using array as initializer. +template +internal::ReturnAction Return(R value) { + return internal::ReturnAction(internal::move(value)); +} + +// Creates an action that returns NULL. +inline PolymorphicAction ReturnNull() { + return MakePolymorphicAction(internal::ReturnNullAction()); +} + +// Creates an action that returns from a void function. +inline PolymorphicAction Return() { + return MakePolymorphicAction(internal::ReturnVoidAction()); +} + +// Creates an action that returns the reference to a variable. +template +inline internal::ReturnRefAction ReturnRef(R& x) { // NOLINT + return internal::ReturnRefAction(x); +} + +// Creates an action that returns the reference to a copy of the +// argument. The copy is created when the action is constructed and +// lives as long as the action. +template +inline internal::ReturnRefOfCopyAction ReturnRefOfCopy(const R& x) { + return internal::ReturnRefOfCopyAction(x); +} + +// Modifies the parent action (a Return() action) to perform a move of the +// argument instead of a copy. +// Return(ByMove()) actions can only be executed once and will assert this +// invariant. +template +internal::ByMoveWrapper ByMove(R x) { + return internal::ByMoveWrapper(internal::move(x)); +} + +// Creates an action that does the default action for the give mock function. +inline internal::DoDefaultAction DoDefault() { + return internal::DoDefaultAction(); +} + +// Creates an action that sets the variable pointed by the N-th +// (0-based) function argument to 'value'. +template +PolymorphicAction< + internal::SetArgumentPointeeAction< + N, T, internal::IsAProtocolMessage::value> > +SetArgPointee(const T& x) { + return MakePolymorphicAction(internal::SetArgumentPointeeAction< + N, T, internal::IsAProtocolMessage::value>(x)); +} + +#if !((GTEST_GCC_VER_ && GTEST_GCC_VER_ < 40000) || GTEST_OS_SYMBIAN) +// This overload allows SetArgPointee() to accept a string literal. +// GCC prior to the version 4.0 and Symbian C++ compiler cannot distinguish +// this overload from the templated version and emit a compile error. +template +PolymorphicAction< + internal::SetArgumentPointeeAction > +SetArgPointee(const char* p) { + return MakePolymorphicAction(internal::SetArgumentPointeeAction< + N, const char*, false>(p)); +} + +template +PolymorphicAction< + internal::SetArgumentPointeeAction > +SetArgPointee(const wchar_t* p) { + return MakePolymorphicAction(internal::SetArgumentPointeeAction< + N, const wchar_t*, false>(p)); +} +#endif + +// The following version is DEPRECATED. +template +PolymorphicAction< + internal::SetArgumentPointeeAction< + N, T, internal::IsAProtocolMessage::value> > +SetArgumentPointee(const T& x) { + return MakePolymorphicAction(internal::SetArgumentPointeeAction< + N, T, internal::IsAProtocolMessage::value>(x)); +} + +// Creates an action that sets a pointer referent to a given value. +template +PolymorphicAction > Assign(T1* ptr, T2 val) { + return MakePolymorphicAction(internal::AssignAction(ptr, val)); +} + +#if !GTEST_OS_WINDOWS_MOBILE + +// Creates an action that sets errno and returns the appropriate error. +template +PolymorphicAction > +SetErrnoAndReturn(int errval, T result) { + return MakePolymorphicAction( + internal::SetErrnoAndReturnAction(errval, result)); +} + +#endif // !GTEST_OS_WINDOWS_MOBILE + +// Various overloads for InvokeWithoutArgs(). + +// Creates an action that invokes 'function_impl' with no argument. +template +PolymorphicAction > +InvokeWithoutArgs(FunctionImpl function_impl) { + return MakePolymorphicAction( + internal::InvokeWithoutArgsAction(function_impl)); +} + +// Creates an action that invokes the given method on the given object +// with no argument. +template +PolymorphicAction > +InvokeWithoutArgs(Class* obj_ptr, MethodPtr method_ptr) { + return MakePolymorphicAction( + internal::InvokeMethodWithoutArgsAction( + obj_ptr, method_ptr)); +} + +// Creates an action that performs an_action and throws away its +// result. In other words, it changes the return type of an_action to +// void. an_action MUST NOT return void, or the code won't compile. +template +inline internal::IgnoreResultAction IgnoreResult(const A& an_action) { + return internal::IgnoreResultAction(an_action); +} + +// Creates a reference wrapper for the given L-value. If necessary, +// you can explicitly specify the type of the reference. For example, +// suppose 'derived' is an object of type Derived, ByRef(derived) +// would wrap a Derived&. If you want to wrap a const Base& instead, +// where Base is a base class of Derived, just write: +// +// ByRef(derived) +template +inline internal::ReferenceWrapper ByRef(T& l_value) { // NOLINT + return internal::ReferenceWrapper(l_value); +} + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_ACTIONS_H_ diff --git a/src/lib/install/include/gmock/gmock-cardinalities.h b/src/lib/install/include/gmock/gmock-cardinalities.h new file mode 100644 index 0000000..fc315f9 --- /dev/null +++ b/src/lib/install/include/gmock/gmock-cardinalities.h @@ -0,0 +1,147 @@ +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used cardinalities. More +// cardinalities can be defined by the user implementing the +// CardinalityInterface interface if necessary. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ + +#include +#include // NOLINT +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +namespace testing { + +// To implement a cardinality Foo, define: +// 1. a class FooCardinality that implements the +// CardinalityInterface interface, and +// 2. a factory function that creates a Cardinality object from a +// const FooCardinality*. +// +// The two-level delegation design follows that of Matcher, providing +// consistency for extension developers. It also eases ownership +// management as Cardinality objects can now be copied like plain values. + +// The implementation of a cardinality. +class CardinalityInterface { + public: + virtual ~CardinalityInterface() {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + virtual int ConservativeLowerBound() const { return 0; } + virtual int ConservativeUpperBound() const { return INT_MAX; } + + // Returns true iff call_count calls will satisfy this cardinality. + virtual bool IsSatisfiedByCallCount(int call_count) const = 0; + + // Returns true iff call_count calls will saturate this cardinality. + virtual bool IsSaturatedByCallCount(int call_count) const = 0; + + // Describes self to an ostream. + virtual void DescribeTo(::std::ostream* os) const = 0; +}; + +// A Cardinality is a copyable and IMMUTABLE (except by assignment) +// object that specifies how many times a mock function is expected to +// be called. The implementation of Cardinality is just a linked_ptr +// to const CardinalityInterface, so copying is fairly cheap. +// Don't inherit from Cardinality! +class GTEST_API_ Cardinality { + public: + // Constructs a null cardinality. Needed for storing Cardinality + // objects in STL containers. + Cardinality() {} + + // Constructs a Cardinality from its implementation. + explicit Cardinality(const CardinalityInterface* impl) : impl_(impl) {} + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + int ConservativeLowerBound() const { return impl_->ConservativeLowerBound(); } + int ConservativeUpperBound() const { return impl_->ConservativeUpperBound(); } + + // Returns true iff call_count calls will satisfy this cardinality. + bool IsSatisfiedByCallCount(int call_count) const { + return impl_->IsSatisfiedByCallCount(call_count); + } + + // Returns true iff call_count calls will saturate this cardinality. + bool IsSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count); + } + + // Returns true iff call_count calls will over-saturate this + // cardinality, i.e. exceed the maximum number of allowed calls. + bool IsOverSaturatedByCallCount(int call_count) const { + return impl_->IsSaturatedByCallCount(call_count) && + !impl_->IsSatisfiedByCallCount(call_count); + } + + // Describes self to an ostream + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the given actual call count to an ostream. + static void DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os); + + private: + internal::linked_ptr impl_; +}; + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n); + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n); + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber(); + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max); + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n); + +// Creates a cardinality from its implementation. +inline Cardinality MakeCardinality(const CardinalityInterface* c) { + return Cardinality(c); +} + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_CARDINALITIES_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-actions.h b/src/lib/install/include/gmock/gmock-generated-actions.h new file mode 100644 index 0000000..b5a889c --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-actions.h @@ -0,0 +1,2377 @@ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { +namespace internal { + +// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary +// function or method with the unpacked values, where F is a function +// type that takes N arguments. +template +class InvokeHelper; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple<>&) { + return function(); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple<>&) { + return (obj_ptr->*method_ptr)(); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args), get<8>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args), get<8>(args)); + } +}; + +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple& args) { + return function(get<0>(args), get<1>(args), get<2>(args), + get<3>(args), get<4>(args), get<5>(args), get<6>(args), + get<7>(args), get<8>(args), get<9>(args)); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple& args) { + return (obj_ptr->*method_ptr)(get<0>(args), get<1>(args), + get<2>(args), get<3>(args), get<4>(args), get<5>(args), + get<6>(args), get<7>(args), get<8>(args), get<9>(args)); + } +}; + +// An INTERNAL macro for extracting the type of a tuple field. It's +// subject to change without notice - DO NOT USE IN USER CODE! +#define GMOCK_FIELD_(Tuple, N) \ + typename ::testing::tuple_element::type + +// SelectArgs::type is the +// type of an n-ary function whose i-th (1-based) argument type is the +// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple +// type, and whose return type is Result. For example, +// SelectArgs, 0, 3>::type +// is int(bool, long). +// +// SelectArgs::Select(args) +// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. +// For example, +// SelectArgs, 2, 0>::Select( +// ::testing::make_tuple(true, 'a', 2.5)) +// returns tuple (2.5, true). +// +// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be +// in the range [0, 10]. Duplicates are allowed and they don't have +// to be in an ascending or descending order. + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), + GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), + GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9), + GMOCK_FIELD_(ArgumentTuple, k10)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args), get(args), get(args), + get(args), get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& /* args */) { + return SelectedArgs(); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), + GMOCK_FIELD_(ArgumentTuple, k6)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), + GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args), get(args), get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), + GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), + GMOCK_FIELD_(ArgumentTuple, k8)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args), get(args), get(args), + get(args)); + } +}; + +template +class SelectArgs { + public: + typedef Result type(GMOCK_FIELD_(ArgumentTuple, k1), + GMOCK_FIELD_(ArgumentTuple, k2), GMOCK_FIELD_(ArgumentTuple, k3), + GMOCK_FIELD_(ArgumentTuple, k4), GMOCK_FIELD_(ArgumentTuple, k5), + GMOCK_FIELD_(ArgumentTuple, k6), GMOCK_FIELD_(ArgumentTuple, k7), + GMOCK_FIELD_(ArgumentTuple, k8), GMOCK_FIELD_(ArgumentTuple, k9)); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs(get(args), get(args), get(args), + get(args), get(args), get(args), get(args), + get(args), get(args)); + } +}; + +#undef GMOCK_FIELD_ + +// Implements the WithArgs action. +template +class WithArgsAction { + public: + explicit WithArgsAction(const InnerAction& action) : action_(action) {} + + template + operator Action() const { return MakeAction(new Impl(action_)); } + + private: + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const InnerAction& action) : action_(action) {} + + virtual Result Perform(const ArgumentTuple& args) { + return action_.Perform(SelectArgs::Select(args)); + } + + private: + typedef typename SelectArgs::type InnerFunctionType; + + Action action_; + }; + + const InnerAction action_; + + GTEST_DISALLOW_ASSIGN_(WithArgsAction); +}; + +// A macro from the ACTION* family (defined later in this file) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template +class ActionHelper { + public: + static Result Perform(Impl* impl, const ::testing::tuple<>& args) { + return impl->template gmock_PerformImpl<>(args, ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), + get<1>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), + get<1>(args), get<2>(args), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), + get<1>(args), get<2>(args), get<3>(args), ExcessiveArg(), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, + get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), + ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, + get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), + get<5>(args), ExcessiveArg(), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, + get<0>(args), get<1>(args), get<2>(args), get<3>(args), get<4>(args), + get<5>(args), get<6>(args), ExcessiveArg(), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), + get<4>(args), get<5>(args), get<6>(args), get<7>(args), ExcessiveArg(), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), + get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), + ExcessiveArg()); + } + + template + static Result Perform(Impl* impl, const ::testing::tuple& args) { + return impl->template gmock_PerformImpl(args, get<0>(args), get<1>(args), get<2>(args), get<3>(args), + get<4>(args), get<5>(args), get<6>(args), get<7>(args), get<8>(args), + get<9>(args)); + } +}; + +} // namespace internal + +// Various overloads for Invoke(). + +// WithArgs(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. C++ doesn't support default arguments for +// function templates, so we have to overload it. +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +template +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. +template +inline internal::DoBothAction +DoAll(Action1 a1, Action2 a2) { + return internal::DoBothAction(a1, a2); +} + +template +inline internal::DoBothAction > +DoAll(Action1 a1, Action2 a2, Action3 a3) { + return DoAll(a1, DoAll(a2, a3)); +} + +template +inline internal::DoBothAction > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4) { + return DoAll(a1, DoAll(a2, a3, a4)); +} + +template +inline internal::DoBothAction > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5) { + return DoAll(a1, DoAll(a2, a3, a4, a5)); +} + +template +inline internal::DoBothAction > > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6) { + return DoAll(a1, DoAll(a2, a3, a4, a5, a6)); +} + +template +inline internal::DoBothAction > > > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, + Action7 a7) { + return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7)); +} + +template +inline internal::DoBothAction > > > > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, + Action7 a7, Action8 a8) { + return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8)); +} + +template +inline internal::DoBothAction > > > > > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, + Action7 a7, Action8 a8, Action9 a9) { + return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9)); +} + +template +inline internal::DoBothAction > > > > > > > > +DoAll(Action1 a1, Action2 a2, Action3 a3, Action4 a4, Action5 a5, Action6 a6, + Action7 a7, Action8 a8, Action9 a9, Action10 a10) { + return DoAll(a1, DoAll(a2, a3, a4, a5, a6, a7, a8, a9, a10)); +} + +} // namespace testing + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P10 to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope. The reason is +// that C++ doesn't yet allow function-local types to be used to +// instantiate templates. The up-coming C++0x standard will fix this. +// Once that's done, we'll consider supporting using ACTION*() inside +// a function. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' +// on http://code.google.com/p/googlemock/wiki/CookBook. + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_, \ + arg0_type arg0 GTEST_ATTRIBUTE_UNUSED_, \ + arg1_type arg1 GTEST_ATTRIBUTE_UNUSED_, \ + arg2_type arg2 GTEST_ATTRIBUTE_UNUSED_, \ + arg3_type arg3 GTEST_ATTRIBUTE_UNUSED_, \ + arg4_type arg4 GTEST_ATTRIBUTE_UNUSED_, \ + arg5_type arg5 GTEST_ATTRIBUTE_UNUSED_, \ + arg6_type arg6 GTEST_ATTRIBUTE_UNUSED_, \ + arg7_type arg7 GTEST_ATTRIBUTE_UNUSED_, \ + arg8_type arg8 GTEST_ATTRIBUTE_UNUSED_, \ + arg9_type arg9 GTEST_ATTRIBUTE_UNUSED_ + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::testing::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. +#define GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(kind0, name0) kind0 name0 +#define GMOCK_INTERNAL_DECL_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) kind0 name0, kind1 name1 +#define GMOCK_INTERNAL_DECL_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) kind0 name0, kind1 name1, kind2 name2 +#define GMOCK_INTERNAL_DECL_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3 +#define GMOCK_INTERNAL_DECL_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) kind0 name0, kind1 name1, \ + kind2 name2, kind3 name3, kind4 name4 +#define GMOCK_INTERNAL_DECL_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5 +#define GMOCK_INTERNAL_DECL_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) kind0 name0, kind1 name1, kind2 name2, kind3 name3, kind4 name4, \ + kind5 name5, kind6 name6 +#define GMOCK_INTERNAL_DECL_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) kind0 name0, kind1 name1, kind2 name2, kind3 name3, \ + kind4 name4, kind5 name5, kind6 name6, kind7 name7 +#define GMOCK_INTERNAL_DECL_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) kind0 name0, kind1 name1, kind2 name2, \ + kind3 name3, kind4 name4, kind5 name5, kind6 name6, kind7 name7, \ + kind8 name8 +#define GMOCK_INTERNAL_DECL_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) kind0 name0, \ + kind1 name1, kind2 name2, kind3 name3, kind4 name4, kind5 name5, \ + kind6 name6, kind7 name7, kind8 name8, kind9 name9 + +// Lists the template parameters. +#define GMOCK_INTERNAL_LIST_HAS_1_TEMPLATE_PARAMS(kind0, name0) name0 +#define GMOCK_INTERNAL_LIST_HAS_2_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1) name0, name1 +#define GMOCK_INTERNAL_LIST_HAS_3_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2) name0, name1, name2 +#define GMOCK_INTERNAL_LIST_HAS_4_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3) name0, name1, name2, name3 +#define GMOCK_INTERNAL_LIST_HAS_5_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4) name0, name1, name2, name3, \ + name4 +#define GMOCK_INTERNAL_LIST_HAS_6_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5) name0, name1, \ + name2, name3, name4, name5 +#define GMOCK_INTERNAL_LIST_HAS_7_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6) name0, name1, name2, name3, name4, name5, name6 +#define GMOCK_INTERNAL_LIST_HAS_8_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7) name0, name1, name2, name3, name4, name5, name6, name7 +#define GMOCK_INTERNAL_LIST_HAS_9_TEMPLATE_PARAMS(kind0, name0, kind1, name1, \ + kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, name6, \ + kind7, name7, kind8, name8) name0, name1, name2, name3, name4, name5, \ + name6, name7, name8 +#define GMOCK_INTERNAL_LIST_HAS_10_TEMPLATE_PARAMS(kind0, name0, kind1, \ + name1, kind2, name2, kind3, name3, kind4, name4, kind5, name5, kind6, \ + name6, kind7, name7, kind8, name8, kind9, name9) name0, name1, name2, \ + name3, name4, name5, name6, name7, name8, name9 + +// Declares the types of value parameters. +#define GMOCK_INTERNAL_DECL_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_TYPE_AND_1_VALUE_PARAMS(p0) , typename p0##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_2_VALUE_PARAMS(p0, p1) , \ + typename p0##_type, typename p1##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , \ + typename p0##_type, typename p1##_type, typename p2##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , typename p0##_type, typename p1##_type, typename p2##_type, \ + typename p3##_type, typename p4##_type, typename p5##_type, \ + typename p6##_type, typename p7##_type, typename p8##_type +#define GMOCK_INTERNAL_DECL_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , typename p0##_type, typename p1##_type, \ + typename p2##_type, typename p3##_type, typename p4##_type, \ + typename p5##_type, typename p6##_type, typename p7##_type, \ + typename p8##_type, typename p9##_type + +// Initializes the value parameters. +#define GMOCK_INTERNAL_INIT_AND_0_VALUE_PARAMS()\ + () +#define GMOCK_INTERNAL_INIT_AND_1_VALUE_PARAMS(p0)\ + (p0##_type gmock_p0) : p0(gmock_p0) +#define GMOCK_INTERNAL_INIT_AND_2_VALUE_PARAMS(p0, p1)\ + (p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), p1(gmock_p1) +#define GMOCK_INTERNAL_INIT_AND_3_VALUE_PARAMS(p0, p1, p2)\ + (p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) +#define GMOCK_INTERNAL_INIT_AND_4_VALUE_PARAMS(p0, p1, p2, p3)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3) +#define GMOCK_INTERNAL_INIT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) +#define GMOCK_INTERNAL_INIT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) +#define GMOCK_INTERNAL_INIT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) +#define GMOCK_INTERNAL_INIT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7) +#define GMOCK_INTERNAL_INIT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8) +#define GMOCK_INTERNAL_INIT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9)\ + (p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8), p9(gmock_p9) + +// Declares the fields for storing the value parameters. +#define GMOCK_INTERNAL_DEFN_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DEFN_AND_1_VALUE_PARAMS(p0) p0##_type p0; +#define GMOCK_INTERNAL_DEFN_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0; \ + p1##_type p1; +#define GMOCK_INTERNAL_DEFN_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0; \ + p1##_type p1; p2##_type p2; +#define GMOCK_INTERNAL_DEFN_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0; \ + p1##_type p1; p2##_type p2; p3##_type p3; +#define GMOCK_INTERNAL_DEFN_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; +#define GMOCK_INTERNAL_DEFN_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; +#define GMOCK_INTERNAL_DEFN_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; +#define GMOCK_INTERNAL_DEFN_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; p4##_type p4; \ + p5##_type p5; p6##_type p6; p7##_type p7; +#define GMOCK_INTERNAL_DEFN_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; +#define GMOCK_INTERNAL_DEFN_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0; p1##_type p1; p2##_type p2; p3##_type p3; \ + p4##_type p4; p5##_type p5; p6##_type p6; p7##_type p7; p8##_type p8; \ + p9##_type p9; + +// Lists the value parameters. +#define GMOCK_INTERNAL_LIST_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_AND_1_VALUE_PARAMS(p0) p0 +#define GMOCK_INTERNAL_LIST_AND_2_VALUE_PARAMS(p0, p1) p0, p1 +#define GMOCK_INTERNAL_LIST_AND_3_VALUE_PARAMS(p0, p1, p2) p0, p1, p2 +#define GMOCK_INTERNAL_LIST_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0, p1, p2, p3 +#define GMOCK_INTERNAL_LIST_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) p0, p1, \ + p2, p3, p4 +#define GMOCK_INTERNAL_LIST_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) p0, \ + p1, p2, p3, p4, p5 +#define GMOCK_INTERNAL_LIST_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0, p1, p2, p3, p4, p5, p6 +#define GMOCK_INTERNAL_LIST_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0, p1, p2, p3, p4, p5, p6, p7 +#define GMOCK_INTERNAL_LIST_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0, p1, p2, p3, p4, p5, p6, p7, p8 +#define GMOCK_INTERNAL_LIST_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0, p1, p2, p3, p4, p5, p6, p7, p8, p9 + +// Lists the value parameter types. +#define GMOCK_INTERNAL_LIST_TYPE_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_LIST_TYPE_AND_1_VALUE_PARAMS(p0) , p0##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_2_VALUE_PARAMS(p0, p1) , p0##_type, \ + p1##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_3_VALUE_PARAMS(p0, p1, p2) , p0##_type, \ + p1##_type, p2##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_4_VALUE_PARAMS(p0, p1, p2, p3) , \ + p0##_type, p1##_type, p2##_type, p3##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) , \ + p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, p5##_type, \ + p6##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type +#define GMOCK_INTERNAL_LIST_TYPE_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9) , p0##_type, p1##_type, p2##_type, p3##_type, p4##_type, \ + p5##_type, p6##_type, p7##_type, p8##_type, p9##_type + +// Declares the value parameters. +#define GMOCK_INTERNAL_DECL_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_DECL_AND_1_VALUE_PARAMS(p0) p0##_type p0 +#define GMOCK_INTERNAL_DECL_AND_2_VALUE_PARAMS(p0, p1) p0##_type p0, \ + p1##_type p1 +#define GMOCK_INTERNAL_DECL_AND_3_VALUE_PARAMS(p0, p1, p2) p0##_type p0, \ + p1##_type p1, p2##_type p2 +#define GMOCK_INTERNAL_DECL_AND_4_VALUE_PARAMS(p0, p1, p2, p3) p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3 +#define GMOCK_INTERNAL_DECL_AND_5_VALUE_PARAMS(p0, p1, p2, p3, \ + p4) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4 +#define GMOCK_INTERNAL_DECL_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, \ + p5) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5 +#define GMOCK_INTERNAL_DECL_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, \ + p6) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6 +#define GMOCK_INTERNAL_DECL_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, \ + p5##_type p5, p6##_type p6, p7##_type p7 +#define GMOCK_INTERNAL_DECL_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8 +#define GMOCK_INTERNAL_DECL_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9 + +// The suffix of the class template implementing the action template. +#define GMOCK_INTERNAL_COUNT_AND_0_VALUE_PARAMS() +#define GMOCK_INTERNAL_COUNT_AND_1_VALUE_PARAMS(p0) P +#define GMOCK_INTERNAL_COUNT_AND_2_VALUE_PARAMS(p0, p1) P2 +#define GMOCK_INTERNAL_COUNT_AND_3_VALUE_PARAMS(p0, p1, p2) P3 +#define GMOCK_INTERNAL_COUNT_AND_4_VALUE_PARAMS(p0, p1, p2, p3) P4 +#define GMOCK_INTERNAL_COUNT_AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4) P5 +#define GMOCK_INTERNAL_COUNT_AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5) P6 +#define GMOCK_INTERNAL_COUNT_AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6) P7 +#define GMOCK_INTERNAL_COUNT_AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7) P8 +#define GMOCK_INTERNAL_COUNT_AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8) P9 +#define GMOCK_INTERNAL_COUNT_AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, \ + p7, p8, p9) P10 + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION(name)\ + class name##Action {\ + public:\ + name##Action() {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl() {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl());\ + }\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##Action);\ + };\ + inline name##Action name() {\ + return name##Action();\ + }\ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##Action::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P(name, p0)\ + template \ + class name##ActionP {\ + public:\ + explicit name##ActionP(p0##_type gmock_p0) : p0(gmock_p0) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl(p0##_type gmock_p0) : p0(gmock_p0) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0));\ + }\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP);\ + };\ + template \ + inline name##ActionP name(p0##_type p0) {\ + return name##ActionP(p0);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P2(name, p0, p1)\ + template \ + class name##ActionP2 {\ + public:\ + name##ActionP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ + p1(gmock_p1) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ + p1(gmock_p1) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP2);\ + };\ + template \ + inline name##ActionP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##ActionP2(p0, p1);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP2::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P3(name, p0, p1, p2)\ + template \ + class name##ActionP3 {\ + public:\ + name##ActionP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP3);\ + };\ + template \ + inline name##ActionP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##ActionP3(p0, p1, p2);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP3::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P4(name, p0, p1, p2, p3)\ + template \ + class name##ActionP4 {\ + public:\ + name##ActionP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP4);\ + };\ + template \ + inline name##ActionP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##ActionP4(p0, p1, \ + p2, p3);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP4::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P5(name, p0, p1, p2, p3, p4)\ + template \ + class name##ActionP5 {\ + public:\ + name##ActionP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4) : p0(gmock_p0), \ + p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP5);\ + };\ + template \ + inline name##ActionP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##ActionP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP5::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P6(name, p0, p1, p2, p3, p4, p5)\ + template \ + class name##ActionP6 {\ + public:\ + name##ActionP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP6);\ + };\ + template \ + inline name##ActionP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##ActionP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP6::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P7(name, p0, p1, p2, p3, p4, p5, p6)\ + template \ + class name##ActionP7 {\ + public:\ + name##ActionP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ + p6(gmock_p6) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP7);\ + };\ + template \ + inline name##ActionP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##ActionP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP7::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P8(name, p0, p1, p2, p3, p4, p5, p6, p7)\ + template \ + class name##ActionP8 {\ + public:\ + name##ActionP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7) : p0(gmock_p0), \ + p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), \ + p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP8);\ + };\ + template \ + inline name##ActionP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##ActionP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP8::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8)\ + template \ + class name##ActionP9 {\ + public:\ + name##ActionP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7), p8(gmock_p8) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP9);\ + };\ + template \ + inline name##ActionP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##ActionP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP9::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +#define ACTION_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)\ + template \ + class name##ActionP10 {\ + public:\ + name##ActionP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template \ + return_type gmock_PerformImpl(const args_type& args, arg0_type arg0, \ + arg1_type arg1, arg2_type arg2, arg3_type arg3, arg4_type arg4, \ + arg5_type arg5, arg6_type arg6, arg7_type arg7, arg8_type arg8, \ + arg9_type arg9) const;\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl(p0, p1, p2, p3, p4, p5, \ + p6, p7, p8, p9));\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##ActionP10);\ + };\ + template \ + inline name##ActionP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##ActionP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + name##ActionP10::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/callback-actions.h header. + +template +R InvokeArgumentAdl(AdlTag, F f) { + return f(); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1) { + return f(a1); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2) { + return f(a1, a2); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3) { + return f(a1, a2, a3); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4) { + return f(a1, a2, a3, a4); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + return f(a1, a2, a3, a4, a5); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + return f(a1, a2, a3, a4, a5, a6); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7) { + return f(a1, a2, a3, a4, a5, a6, a7); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8) { + return f(a1, a2, a3, a4, a5, a6, a7, a8); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9); +} +template +R InvokeArgumentAdl(AdlTag, F f, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, + A7 a7, A8 a8, A9 a9, A10 a10) { + return f(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); +} +} // namespace invoke_argument +} // namespace internal + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_0_VALUE_PARAMS()) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args)); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_1_VALUE_PARAMS(p0)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_2_VALUE_PARAMS(p0, p1)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args), p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_0_VALUE_PARAMS()) { + return new T(); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_1_VALUE_PARAMS(p0)) { + return new T(p0); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_2_VALUE_PARAMS(p0, p1)) { + return new T(p0, p1); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_3_VALUE_PARAMS(p0, p1, p2)) { + return new T(p0, p1, p2); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_4_VALUE_PARAMS(p0, p1, p2, p3)) { + return new T(p0, p1, p2, p3); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_5_VALUE_PARAMS(p0, p1, p2, p3, p4)) { + return new T(p0, p1, p2, p3, p4); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_6_VALUE_PARAMS(p0, p1, p2, p3, p4, p5)) { + return new T(p0, p1, p2, p3, p4, p5); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_7_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6)) { + return new T(p0, p1, p2, p3, p4, p5, p6); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_8_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_9_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8); +} + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_10_VALUE_PARAMS(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)) { + return new T(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-actions.h.pump b/src/lib/install/include/gmock/gmock-generated-actions.h.pump new file mode 100644 index 0000000..66d9f9d --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-actions.h.pump @@ -0,0 +1,794 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-actions.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$}} This meta comment fixes auto-indentation in editors. +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic actions. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ + +#include "gmock/gmock-actions.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { +namespace internal { + +// InvokeHelper knows how to unpack an N-tuple and invoke an N-ary +// function or method with the unpacked values, where F is a function +// type that takes N arguments. +template +class InvokeHelper; + + +$range i 0..n +$for i [[ +$range j 1..i +$var types = [[$for j [[, typename A$j]]]] +$var as = [[$for j, [[A$j]]]] +$var args = [[$if i==0 [[]] $else [[ args]]]] +$var gets = [[$for j, [[get<$(j - 1)>(args)]]]] +template +class InvokeHelper > { + public: + template + static R Invoke(Function function, const ::testing::tuple<$as>&$args) { + return function($gets); + } + + template + static R InvokeMethod(Class* obj_ptr, + MethodPtr method_ptr, + const ::testing::tuple<$as>&$args) { + return (obj_ptr->*method_ptr)($gets); + } +}; + + +]] +// An INTERNAL macro for extracting the type of a tuple field. It's +// subject to change without notice - DO NOT USE IN USER CODE! +#define GMOCK_FIELD_(Tuple, N) \ + typename ::testing::tuple_element::type + +$range i 1..n + +// SelectArgs::type is the +// type of an n-ary function whose i-th (1-based) argument type is the +// k{i}-th (0-based) field of ArgumentTuple, which must be a tuple +// type, and whose return type is Result. For example, +// SelectArgs, 0, 3>::type +// is int(bool, long). +// +// SelectArgs::Select(args) +// returns the selected fields (k1, k2, ..., k_n) of args as a tuple. +// For example, +// SelectArgs, 2, 0>::Select( +// ::testing::make_tuple(true, 'a', 2.5)) +// returns tuple (2.5, true). +// +// The numbers in list k1, k2, ..., k_n must be >= 0, where n can be +// in the range [0, $n]. Duplicates are allowed and they don't have +// to be in an ascending or descending order. + +template +class SelectArgs { + public: + typedef Result type($for i, [[GMOCK_FIELD_(ArgumentTuple, k$i)]]); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& args) { + return SelectedArgs($for i, [[get(args)]]); + } +}; + + +$for i [[ +$range j 1..n +$range j1 1..i-1 +template +class SelectArgs { + public: + typedef Result type($for j1, [[GMOCK_FIELD_(ArgumentTuple, k$j1)]]); + typedef typename Function::ArgumentTuple SelectedArgs; + static SelectedArgs Select(const ArgumentTuple& [[]] +$if i == 1 [[/* args */]] $else [[args]]) { + return SelectedArgs($for j1, [[get(args)]]); + } +}; + + +]] +#undef GMOCK_FIELD_ + +$var ks = [[$for i, [[k$i]]]] + +// Implements the WithArgs action. +template +class WithArgsAction { + public: + explicit WithArgsAction(const InnerAction& action) : action_(action) {} + + template + operator Action() const { return MakeAction(new Impl(action_)); } + + private: + template + class Impl : public ActionInterface { + public: + typedef typename Function::Result Result; + typedef typename Function::ArgumentTuple ArgumentTuple; + + explicit Impl(const InnerAction& action) : action_(action) {} + + virtual Result Perform(const ArgumentTuple& args) { + return action_.Perform(SelectArgs::Select(args)); + } + + private: + typedef typename SelectArgs::type InnerFunctionType; + + Action action_; + }; + + const InnerAction action_; + + GTEST_DISALLOW_ASSIGN_(WithArgsAction); +}; + +// A macro from the ACTION* family (defined later in this file) +// defines an action that can be used in a mock function. Typically, +// these actions only care about a subset of the arguments of the mock +// function. For example, if such an action only uses the second +// argument, it can be used in any mock function that takes >= 2 +// arguments where the type of the second argument is compatible. +// +// Therefore, the action implementation must be prepared to take more +// arguments than it needs. The ExcessiveArg type is used to +// represent those excessive arguments. In order to keep the compiler +// error messages tractable, we define it in the testing namespace +// instead of testing::internal. However, this is an INTERNAL TYPE +// and subject to change without notice, so a user MUST NOT USE THIS +// TYPE DIRECTLY. +struct ExcessiveArg {}; + +// A helper class needed for implementing the ACTION* macros. +template +class ActionHelper { + public: +$range i 0..n +$for i + +[[ +$var template = [[$if i==0 [[]] $else [[ +$range j 0..i-1 + template <$for j, [[typename A$j]]> +]]]] +$range j 0..i-1 +$var As = [[$for j, [[A$j]]]] +$var as = [[$for j, [[get<$j>(args)]]]] +$range k 1..n-i +$var eas = [[$for k, [[ExcessiveArg()]]]] +$var arg_list = [[$if (i==0) | (i==n) [[$as$eas]] $else [[$as, $eas]]]] +$template + static Result Perform(Impl* impl, const ::testing::tuple<$As>& args) { + return impl->template gmock_PerformImpl<$As>(args, $arg_list); + } + +]] +}; + +} // namespace internal + +// Various overloads for Invoke(). + +// WithArgs(an_action) creates an action that passes +// the selected arguments of the mock function to an_action and +// performs it. It serves as an adaptor between actions with +// different argument lists. C++ doesn't support default arguments for +// function templates, so we have to overload it. + +$range i 1..n +$for i [[ +$range j 1..i +template <$for j [[int k$j, ]]typename InnerAction> +inline internal::WithArgsAction +WithArgs(const InnerAction& action) { + return internal::WithArgsAction(action); +} + + +]] +// Creates an action that does actions a1, a2, ..., sequentially in +// each invocation. +$range i 2..n +$for i [[ +$range j 2..i +$var types = [[$for j, [[typename Action$j]]]] +$var Aas = [[$for j [[, Action$j a$j]]]] + +template +$range k 1..i-1 + +inline $for k [[internal::DoBothAction]] + +DoAll(Action1 a1$Aas) { +$if i==2 [[ + + return internal::DoBothAction(a1, a2); +]] $else [[ +$range j2 2..i + + return DoAll(a1, DoAll($for j2, [[a$j2]])); +]] + +} + +]] + +} // namespace testing + +// The ACTION* family of macros can be used in a namespace scope to +// define custom actions easily. The syntax: +// +// ACTION(name) { statements; } +// +// will define an action with the given name that executes the +// statements. The value returned by the statements will be used as +// the return value of the action. Inside the statements, you can +// refer to the K-th (0-based) argument of the mock function by +// 'argK', and refer to its type by 'argK_type'. For example: +// +// ACTION(IncrementArg1) { +// arg1_type temp = arg1; +// return ++(*temp); +// } +// +// allows you to write +// +// ...WillOnce(IncrementArg1()); +// +// You can also refer to the entire argument tuple and its type by +// 'args' and 'args_type', and refer to the mock function type and its +// return type by 'function_type' and 'return_type'. +// +// Note that you don't need to specify the types of the mock function +// arguments. However rest assured that your code is still type-safe: +// you'll get a compiler error if *arg1 doesn't support the ++ +// operator, or if the type of ++(*arg1) isn't compatible with the +// mock function's return type, for example. +// +// Sometimes you'll want to parameterize the action. For that you can use +// another macro: +// +// ACTION_P(name, param_name) { statements; } +// +// For example: +// +// ACTION_P(Add, n) { return arg0 + n; } +// +// will allow you to write: +// +// ...WillOnce(Add(5)); +// +// Note that you don't need to provide the type of the parameter +// either. If you need to reference the type of a parameter named +// 'foo', you can write 'foo_type'. For example, in the body of +// ACTION_P(Add, n) above, you can write 'n_type' to refer to the type +// of 'n'. +// +// We also provide ACTION_P2, ACTION_P3, ..., up to ACTION_P$n to support +// multi-parameter actions. +// +// For the purpose of typing, you can view +// +// ACTION_Pk(Foo, p1, ..., pk) { ... } +// +// as shorthand for +// +// template +// FooActionPk Foo(p1_type p1, ..., pk_type pk) { ... } +// +// In particular, you can provide the template type arguments +// explicitly when invoking Foo(), as in Foo(5, false); +// although usually you can rely on the compiler to infer the types +// for you automatically. You can assign the result of expression +// Foo(p1, ..., pk) to a variable of type FooActionPk. This can be useful when composing actions. +// +// You can also overload actions with different numbers of parameters: +// +// ACTION_P(Plus, a) { ... } +// ACTION_P2(Plus, a, b) { ... } +// +// While it's tempting to always use the ACTION* macros when defining +// a new action, you should also consider implementing ActionInterface +// or using MakePolymorphicAction() instead, especially if you need to +// use the action a lot. While these approaches require more work, +// they give you more control on the types of the mock function +// arguments and the action parameters, which in general leads to +// better compiler error messages that pay off in the long run. They +// also allow overloading actions based on parameter types (as opposed +// to just based on the number of parameters). +// +// CAVEAT: +// +// ACTION*() can only be used in a namespace scope. The reason is +// that C++ doesn't yet allow function-local types to be used to +// instantiate templates. The up-coming C++0x standard will fix this. +// Once that's done, we'll consider supporting using ACTION*() inside +// a function. +// +// MORE INFORMATION: +// +// To learn more about using these macros, please search for 'ACTION' +// on http://code.google.com/p/googlemock/wiki/CookBook. + +$range i 0..n +$range k 0..n-1 + +// An internal macro needed for implementing ACTION*(). +#define GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_\ + const args_type& args GTEST_ATTRIBUTE_UNUSED_ +$for k [[, \ + arg$k[[]]_type arg$k GTEST_ATTRIBUTE_UNUSED_]] + + +// Sometimes you want to give an action explicit template parameters +// that cannot be inferred from its value parameters. ACTION() and +// ACTION_P*() don't support that. ACTION_TEMPLATE() remedies that +// and can be viewed as an extension to ACTION() and ACTION_P*(). +// +// The syntax: +// +// ACTION_TEMPLATE(ActionName, +// HAS_m_TEMPLATE_PARAMS(kind1, name1, ..., kind_m, name_m), +// AND_n_VALUE_PARAMS(p1, ..., p_n)) { statements; } +// +// defines an action template that takes m explicit template +// parameters and n value parameters. name_i is the name of the i-th +// template parameter, and kind_i specifies whether it's a typename, +// an integral constant, or a template. p_i is the name of the i-th +// value parameter. +// +// Example: +// +// // DuplicateArg(output) converts the k-th argument of the mock +// // function to type T and copies it to *output. +// ACTION_TEMPLATE(DuplicateArg, +// HAS_2_TEMPLATE_PARAMS(int, k, typename, T), +// AND_1_VALUE_PARAMS(output)) { +// *output = T(::testing::get(args)); +// } +// ... +// int n; +// EXPECT_CALL(mock, Foo(_, _)) +// .WillOnce(DuplicateArg<1, unsigned char>(&n)); +// +// To create an instance of an action template, write: +// +// ActionName(v1, ..., v_n) +// +// where the ts are the template arguments and the vs are the value +// arguments. The value argument types are inferred by the compiler. +// If you want to explicitly specify the value argument types, you can +// provide additional template arguments: +// +// ActionName(v1, ..., v_n) +// +// where u_i is the desired type of v_i. +// +// ACTION_TEMPLATE and ACTION/ACTION_P* can be overloaded on the +// number of value parameters, but not on the number of template +// parameters. Without the restriction, the meaning of the following +// is unclear: +// +// OverloadedAction(x); +// +// Are we using a single-template-parameter action where 'bool' refers +// to the type of x, or are we using a two-template-parameter action +// where the compiler is asked to infer the type of x? +// +// Implementation notes: +// +// GMOCK_INTERNAL_*_HAS_m_TEMPLATE_PARAMS and +// GMOCK_INTERNAL_*_AND_n_VALUE_PARAMS are internal macros for +// implementing ACTION_TEMPLATE. The main trick we use is to create +// new macro invocations when expanding a macro. For example, we have +// +// #define ACTION_TEMPLATE(name, template_params, value_params) +// ... GMOCK_INTERNAL_DECL_##template_params ... +// +// which causes ACTION_TEMPLATE(..., HAS_1_TEMPLATE_PARAMS(typename, T), ...) +// to expand to +// +// ... GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS(typename, T) ... +// +// Since GMOCK_INTERNAL_DECL_HAS_1_TEMPLATE_PARAMS is a macro, the +// preprocessor will continue to expand it to +// +// ... typename T ... +// +// This technique conforms to the C++ standard and is portable. It +// allows us to implement action templates using O(N) code, where N is +// the maximum number of template/value parameters supported. Without +// using it, we'd have to devote O(N^2) amount of code to implement all +// combinations of m and n. + +// Declares the template parameters. + +$range j 1..n +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_DECL_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[kind$m name$m]] + + +]] + +// Lists the template parameters. + +$for j [[ +$range m 0..j-1 +#define GMOCK_INTERNAL_LIST_HAS_$j[[]] +_TEMPLATE_PARAMS($for m, [[kind$m, name$m]]) $for m, [[name$m]] + + +]] + +// Declares the types of value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, typename p$j##_type]] + + +]] + +// Initializes the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_INIT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])\ + ($for j, [[p$j##_type gmock_p$j]])$if i>0 [[ : ]]$for j, [[p$j(gmock_p$j)]] + + +]] + +// Declares the fields for storing the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DEFN_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[p$j##_type p$j; ]] + + +]] + +// Lists the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j, [[p$j]] + + +]] + +// Lists the value parameter types. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_LIST_TYPE_AND_$i[[]] +_VALUE_PARAMS($for j, [[p$j]]) $for j [[, p$j##_type]] + + +]] + +// Declares the value parameters. + +$for i [[ +$range j 0..i-1 +#define GMOCK_INTERNAL_DECL_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$for j, [[p$j##_type p$j]] + + +]] + +// The suffix of the class template implementing the action template. +$for i [[ + + +$range j 0..i-1 +#define GMOCK_INTERNAL_COUNT_AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]]) [[]] +$if i==1 [[P]] $elif i>=2 [[P$i]] +]] + + +// The name of the class template implementing the action template. +#define GMOCK_ACTION_CLASS_(name, value_params)\ + GTEST_CONCAT_TOKEN_(name##Action, GMOCK_INTERNAL_COUNT_##value_params) + +$range k 0..n-1 + +#define ACTION_TEMPLATE(name, template_params, value_params)\ + template \ + class GMOCK_ACTION_CLASS_(name, value_params) {\ + public:\ + explicit GMOCK_ACTION_CLASS_(name, value_params)\ + GMOCK_INTERNAL_INIT_##value_params {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + explicit gmock_Impl GMOCK_INTERNAL_INIT_##value_params {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$for k, [[typename arg$k[[]]_type]]>\ + return_type gmock_PerformImpl(const args_type& args[[]] +$for k [[, arg$k[[]]_type arg$k]]) const;\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(\ + new gmock_Impl(GMOCK_INTERNAL_LIST_##value_params));\ + }\ + GMOCK_INTERNAL_DEFN_##value_params\ + private:\ + GTEST_DISALLOW_ASSIGN_(GMOCK_ACTION_CLASS_(name, value_params));\ + };\ + template \ + inline GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params> name(\ + GMOCK_INTERNAL_DECL_##value_params) {\ + return GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>(\ + GMOCK_INTERNAL_LIST_##value_params);\ + }\ + template \ + template \ + template \ + typename ::testing::internal::Function::Result\ + GMOCK_ACTION_CLASS_(name, value_params)<\ + GMOCK_INTERNAL_LIST_##template_params\ + GMOCK_INTERNAL_LIST_TYPE_##value_params>::gmock_Impl::\ + gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const + +$for i + +[[ +$var template = [[$if i==0 [[]] $else [[ +$range j 0..i-1 + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var class_name = [[name##Action[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var typename_arg_types = [[$for k, [[typename arg$k[[]]_type]]]] +$var arg_types_and_names = [[$for k, [[arg$k[[]]_type arg$k]]]] +$var macro_name = [[$if i==0 [[ACTION]] $elif i==1 [[ACTION_P]] + $else [[ACTION_P$i]]]] + +#define $macro_name(name$for j [[, p$j]])\$template + class $class_name {\ + public:\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {}\ + template \ + class gmock_Impl : public ::testing::ActionInterface {\ + public:\ + typedef F function_type;\ + typedef typename ::testing::internal::Function::Result return_type;\ + typedef typename ::testing::internal::Function::ArgumentTuple\ + args_type;\ + [[$if i==1 [[explicit ]]]]gmock_Impl($ctor_param_list)$inits {}\ + virtual return_type Perform(const args_type& args) {\ + return ::testing::internal::ActionHelper::\ + Perform(this, args);\ + }\ + template <$typename_arg_types>\ + return_type gmock_PerformImpl(const args_type& args, [[]] +$arg_types_and_names) const;\$param_field_decls + private:\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template operator ::testing::Action() const {\ + return ::testing::Action(new gmock_Impl($params));\ + }\$param_field_decls2 + private:\ + GTEST_DISALLOW_ASSIGN_($class_name);\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + template <$typename_arg_types>\ + typename ::testing::internal::Function::Result\ + $class_name$param_types::gmock_Impl::gmock_PerformImpl(\ + GMOCK_ACTION_ARG_TYPES_AND_NAMES_UNUSED_) const +]] +$$ } // This meta comment fixes auto-indentation in Emacs. It won't +$$ // show up in the generated code. + + +namespace testing { + + +// The ACTION*() macros trigger warning C4100 (unreferenced formal +// parameter) in MSVC with -W4. Unfortunately they cannot be fixed in +// the macro definition, as the warnings are generated when the macro +// is expanded and macro expansion cannot contain #pragma. Therefore +// we suppress them here. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4100) +#endif + +// Various overloads for InvokeArgument(). +// +// The InvokeArgument(a1, a2, ..., a_k) action invokes the N-th +// (0-based) argument, which must be a k-ary callable, of the mock +// function, with arguments a1, a2, ..., a_k. +// +// Notes: +// +// 1. The arguments are passed by value by default. If you need to +// pass an argument by reference, wrap it inside ByRef(). For +// example, +// +// InvokeArgument<1>(5, string("Hello"), ByRef(foo)) +// +// passes 5 and string("Hello") by value, and passes foo by +// reference. +// +// 2. If the callable takes an argument by reference but ByRef() is +// not used, it will receive the reference to a copy of the value, +// instead of the original value. For example, when the 0-th +// argument of the mock function takes a const string&, the action +// +// InvokeArgument<0>(string("Hello")) +// +// makes a copy of the temporary string("Hello") object and passes a +// reference of the copy, instead of the original temporary object, +// to the callable. This makes it easy for a user to define an +// InvokeArgument action from temporary values and have it performed +// later. + +namespace internal { +namespace invoke_argument { + +// Appears in InvokeArgumentAdl's argument list to help avoid +// accidental calls to user functions of the same name. +struct AdlTag {}; + +// InvokeArgumentAdl - a helper for InvokeArgument. +// The basic overloads are provided here for generic functors. +// Overloads for other custom-callables are provided in the +// internal/custom/callback-actions.h header. + +$range i 0..n +$for i +[[ +$range j 1..i + +template +R InvokeArgumentAdl(AdlTag, F f[[$for j [[, A$j a$j]]]]) { + return f([[$for j, [[a$j]]]]); +} +]] + +} // namespace invoke_argument +} // namespace internal + +$range i 0..n +$for i [[ +$range j 0..i-1 + +ACTION_TEMPLATE(InvokeArgument, + HAS_1_TEMPLATE_PARAMS(int, k), + AND_$i[[]]_VALUE_PARAMS($for j, [[p$j]])) { + using internal::invoke_argument::InvokeArgumentAdl; + return InvokeArgumentAdl( + internal::invoke_argument::AdlTag(), + ::testing::get(args)$for j [[, p$j]]); +} + +]] + +// Various overloads for ReturnNew(). +// +// The ReturnNew(a1, a2, ..., a_k) action returns a pointer to a new +// instance of type T, constructed on the heap with constructor arguments +// a1, a2, ..., and a_k. The caller assumes ownership of the returned value. +$range i 0..n +$for i [[ +$range j 0..i-1 +$var ps = [[$for j, [[p$j]]]] + +ACTION_TEMPLATE(ReturnNew, + HAS_1_TEMPLATE_PARAMS(typename, T), + AND_$i[[]]_VALUE_PARAMS($ps)) { + return new T($ps); +} + +]] + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +} // namespace testing + +// Include any custom callback actions added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gmock/internal/custom/gmock-generated-actions.h" + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-function-mockers.h b/src/lib/install/include/gmock/gmock-generated-function-mockers.h new file mode 100644 index 0000000..4fa5ca9 --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-function-mockers.h @@ -0,0 +1,1095 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-function-mockers.h.pump +// DO NOT EDIT BY HAND!!! + +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +#if GTEST_HAS_STD_FUNCTION_ +# include +#endif + +namespace testing { +namespace internal { + +template +class FunctionMockerBase; + +// Note: class FunctionMocker really belongs to the ::testing +// namespace. However if we define it in ::testing, MSVC will +// complain when classes in ::testing::internal declare it as a +// friend class template. To workaround this compiler bug, we define +// FunctionMocker in ::testing::internal and import it into ::testing. +template +class FunctionMocker; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With() { + return this->current_spec(); + } + + R Invoke() { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple()); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1) { + this->current_spec().SetMatchers(::testing::make_tuple(m1)); + return this->current_spec(); + } + + R Invoke(A1 a1) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5, A6); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5, + const Matcher& m6) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, + m6)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5, A6, A7); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5, + const Matcher& m6, const Matcher& m7) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, + m6, m7)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5, A6, A7, A8); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5, + const Matcher& m6, const Matcher& m7, const Matcher& m8) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, + m6, m7, m8)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5, + const Matcher& m6, const Matcher& m7, const Matcher& m8, + const Matcher& m9) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, + m6, m7, m8, m9)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9)); + } +}; + +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With(const Matcher& m1, const Matcher& m2, + const Matcher& m3, const Matcher& m4, const Matcher& m5, + const Matcher& m6, const Matcher& m7, const Matcher& m8, + const Matcher& m9, const Matcher& m10) { + this->current_spec().SetMatchers(::testing::make_tuple(m1, m2, m3, m4, m5, + m6, m7, m8, m9, m10)); + return this->current_spec(); + } + + R Invoke(A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, + A10 a10) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple(a1, a2, a3, a4, a5, a6, a7, a8, a9, + a10)); + } +}; + +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Argument##N + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD0_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + ) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 0), \ + this_method_does_not_take_0_arguments); \ + GMOCK_MOCKER_(0, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(0, constness, Method).Invoke(); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method() constness { \ + GMOCK_MOCKER_(0, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(0, constness, Method).With(); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(0, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD1_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 1), \ + this_method_does_not_take_1_argument); \ + GMOCK_MOCKER_(1, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(1, constness, Method).Invoke(gmock_a1); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1) constness { \ + GMOCK_MOCKER_(1, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(1, constness, Method).With(gmock_a1); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(1, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD2_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 2), \ + this_method_does_not_take_2_arguments); \ + GMOCK_MOCKER_(2, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(2, constness, Method).Invoke(gmock_a1, gmock_a2); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2) constness { \ + GMOCK_MOCKER_(2, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(2, constness, Method).With(gmock_a1, gmock_a2); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(2, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD3_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 3), \ + this_method_does_not_take_3_arguments); \ + GMOCK_MOCKER_(3, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(3, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3) constness { \ + GMOCK_MOCKER_(3, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(3, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(3, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD4_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 4), \ + this_method_does_not_take_4_arguments); \ + GMOCK_MOCKER_(4, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(4, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4) constness { \ + GMOCK_MOCKER_(4, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(4, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(4, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD5_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 5), \ + this_method_does_not_take_5_arguments); \ + GMOCK_MOCKER_(5, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(5, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5) constness { \ + GMOCK_MOCKER_(5, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(5, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(5, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD6_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 6), \ + this_method_does_not_take_6_arguments); \ + GMOCK_MOCKER_(6, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(6, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6) constness { \ + GMOCK_MOCKER_(6, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(6, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(6, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD7_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 7), \ + this_method_does_not_take_7_arguments); \ + GMOCK_MOCKER_(7, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(7, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7) constness { \ + GMOCK_MOCKER_(7, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(7, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(7, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD8_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 8), \ + this_method_does_not_take_8_arguments); \ + GMOCK_MOCKER_(8, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(8, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8) constness { \ + GMOCK_MOCKER_(8, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(8, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(8, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD9_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 9), \ + this_method_does_not_take_9_arguments); \ + GMOCK_MOCKER_(9, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(9, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ + gmock_a9); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9) constness { \ + GMOCK_MOCKER_(9, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(9, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, \ + gmock_a9); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(9, constness, \ + Method) + +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD10_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + GMOCK_ARG_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_ARG_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_ARG_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_ARG_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_ARG_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_ARG_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_ARG_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_ARG_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_ARG_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_ARG_(tn, 10, __VA_ARGS__) gmock_a10) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value \ + == 10), \ + this_method_does_not_take_10_arguments); \ + GMOCK_MOCKER_(10, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_(10, constness, Method).Invoke(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ + gmock_a10); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method(GMOCK_MATCHER_(tn, 1, __VA_ARGS__) gmock_a1, \ + GMOCK_MATCHER_(tn, 2, __VA_ARGS__) gmock_a2, \ + GMOCK_MATCHER_(tn, 3, __VA_ARGS__) gmock_a3, \ + GMOCK_MATCHER_(tn, 4, __VA_ARGS__) gmock_a4, \ + GMOCK_MATCHER_(tn, 5, __VA_ARGS__) gmock_a5, \ + GMOCK_MATCHER_(tn, 6, __VA_ARGS__) gmock_a6, \ + GMOCK_MATCHER_(tn, 7, __VA_ARGS__) gmock_a7, \ + GMOCK_MATCHER_(tn, 8, __VA_ARGS__) gmock_a8, \ + GMOCK_MATCHER_(tn, 9, __VA_ARGS__) gmock_a9, \ + GMOCK_MATCHER_(tn, 10, \ + __VA_ARGS__) gmock_a10) constness { \ + GMOCK_MOCKER_(10, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_(10, constness, Method).With(gmock_a1, gmock_a2, \ + gmock_a3, gmock_a4, gmock_a5, gmock_a6, gmock_a7, gmock_a8, gmock_a9, \ + gmock_a10); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_(10, constness, \ + Method) + +#define MOCK_METHOD0(m, ...) GMOCK_METHOD0_(, , , m, __VA_ARGS__) +#define MOCK_METHOD1(m, ...) GMOCK_METHOD1_(, , , m, __VA_ARGS__) +#define MOCK_METHOD2(m, ...) GMOCK_METHOD2_(, , , m, __VA_ARGS__) +#define MOCK_METHOD3(m, ...) GMOCK_METHOD3_(, , , m, __VA_ARGS__) +#define MOCK_METHOD4(m, ...) GMOCK_METHOD4_(, , , m, __VA_ARGS__) +#define MOCK_METHOD5(m, ...) GMOCK_METHOD5_(, , , m, __VA_ARGS__) +#define MOCK_METHOD6(m, ...) GMOCK_METHOD6_(, , , m, __VA_ARGS__) +#define MOCK_METHOD7(m, ...) GMOCK_METHOD7_(, , , m, __VA_ARGS__) +#define MOCK_METHOD8(m, ...) GMOCK_METHOD8_(, , , m, __VA_ARGS__) +#define MOCK_METHOD9(m, ...) GMOCK_METHOD9_(, , , m, __VA_ARGS__) +#define MOCK_METHOD10(m, ...) GMOCK_METHOD10_(, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0(m, ...) GMOCK_METHOD0_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1(m, ...) GMOCK_METHOD1_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2(m, ...) GMOCK_METHOD2_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3(m, ...) GMOCK_METHOD3_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4(m, ...) GMOCK_METHOD4_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5(m, ...) GMOCK_METHOD5_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6(m, ...) GMOCK_METHOD6_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7(m, ...) GMOCK_METHOD7_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8(m, ...) GMOCK_METHOD8_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9(m, ...) GMOCK_METHOD9_(, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10(m, ...) GMOCK_METHOD10_(, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_T(m, ...) GMOCK_METHOD0_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD1_T(m, ...) GMOCK_METHOD1_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD2_T(m, ...) GMOCK_METHOD2_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD3_T(m, ...) GMOCK_METHOD3_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD4_T(m, ...) GMOCK_METHOD4_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD5_T(m, ...) GMOCK_METHOD5_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD6_T(m, ...) GMOCK_METHOD6_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD7_T(m, ...) GMOCK_METHOD7_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD8_T(m, ...) GMOCK_METHOD8_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD9_T(m, ...) GMOCK_METHOD9_(typename, , , m, __VA_ARGS__) +#define MOCK_METHOD10_T(m, ...) GMOCK_METHOD10_(typename, , , m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T(m, ...) \ + GMOCK_METHOD0_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T(m, ...) \ + GMOCK_METHOD1_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T(m, ...) \ + GMOCK_METHOD2_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T(m, ...) \ + GMOCK_METHOD3_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T(m, ...) \ + GMOCK_METHOD4_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T(m, ...) \ + GMOCK_METHOD5_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T(m, ...) \ + GMOCK_METHOD6_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T(m, ...) \ + GMOCK_METHOD7_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T(m, ...) \ + GMOCK_METHOD8_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T(m, ...) \ + GMOCK_METHOD9_(typename, const, , m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T(m, ...) \ + GMOCK_METHOD10_(typename, const, , m, __VA_ARGS__) + +#define MOCK_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(, const, ct, m, __VA_ARGS__) + +#define MOCK_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, , ct, m, __VA_ARGS__) +#define MOCK_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, , ct, m, __VA_ARGS__) + +#define MOCK_CONST_METHOD0_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD0_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD1_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD1_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD2_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD2_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD3_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD3_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD4_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD4_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD5_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD5_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD6_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD6_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD7_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD7_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD8_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD8_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD9_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD9_(typename, const, ct, m, __VA_ARGS__) +#define MOCK_CONST_METHOD10_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD10_(typename, const, ct, m, __VA_ARGS__) + +// A MockFunction class has one mock method whose type is F. It is +// useful when you just want your test code to emit some messages and +// have Google Mock verify the right messages are sent (and perhaps at +// the right times). For example, if you are exercising code: +// +// Foo(1); +// Foo(2); +// Foo(3); +// +// and want to verify that Foo(1) and Foo(3) both invoke +// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: +// +// TEST(FooTest, InvokesBarCorrectly) { +// MyMock mock; +// MockFunction check; +// { +// InSequence s; +// +// EXPECT_CALL(mock, Bar("a")); +// EXPECT_CALL(check, Call("1")); +// EXPECT_CALL(check, Call("2")); +// EXPECT_CALL(mock, Bar("a")); +// } +// Foo(1); +// check.Call("1"); +// Foo(2); +// check.Call("2"); +// Foo(3); +// } +// +// The expectation spec says that the first Bar("a") must happen +// before check point "1", the second Bar("a") must happen after check +// point "2", and nothing should happen between the two check +// points. The explicit check points make it easy to tell which +// Bar("a") is called by which call to Foo(). +// +// MockFunction can also be used to exercise code that accepts +// std::function callbacks. To do so, use AsStdFunction() method +// to create std::function proxy forwarding to original object's Call. +// Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } +template +class MockFunction; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD0_T(Call, R()); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this]() -> R { + return this->Call(); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD1_T(Call, R(A0)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0) -> R { + return this->Call(a0); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD2_T(Call, R(A0, A1)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1) -> R { + return this->Call(a0, a1); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD3_T(Call, R(A0, A1, A2)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2) -> R { + return this->Call(a0, a1, a2); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD4_T(Call, R(A0, A1, A2, A3)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3) -> R { + return this->Call(a0, a1, a2, a3); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD5_T(Call, R(A0, A1, A2, A3, A4)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) -> R { + return this->Call(a0, a1, a2, a3, a4); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD6_T(Call, R(A0, A1, A2, A3, A4, A5)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5) -> R { + return this->Call(a0, a1, a2, a3, a4, a5); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD7_T(Call, R(A0, A1, A2, A3, A4, A5, A6)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD8_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD9_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD10_T(Call, R(A0, A1, A2, A3, A4, A5, A6, A7, A8, A9)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this](A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, + A8 a8, A9 a9) -> R { + return this->Call(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-function-mockers.h.pump b/src/lib/install/include/gmock/gmock-generated-function-mockers.h.pump new file mode 100644 index 0000000..811502d --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-function-mockers.h.pump @@ -0,0 +1,291 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-function-mockers.h. +$$ +$var n = 10 $$ The maximum arity we support. +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements function mockers of various arities. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-internal-utils.h" + +#if GTEST_HAS_STD_FUNCTION_ +# include +#endif + +namespace testing { +namespace internal { + +template +class FunctionMockerBase; + +// Note: class FunctionMocker really belongs to the ::testing +// namespace. However if we define it in ::testing, MSVC will +// complain when classes in ::testing::internal declare it as a +// friend class template. To workaround this compiler bug, we define +// FunctionMocker in ::testing::internal and import it into ::testing. +template +class FunctionMocker; + + +$range i 0..n +$for i [[ +$range j 1..i +$var typename_As = [[$for j [[, typename A$j]]]] +$var As = [[$for j, [[A$j]]]] +$var as = [[$for j, [[a$j]]]] +$var Aas = [[$for j, [[A$j a$j]]]] +$var ms = [[$for j, [[m$j]]]] +$var matchers = [[$for j, [[const Matcher& m$j]]]] +template +class FunctionMocker : public + internal::FunctionMockerBase { + public: + typedef R F($As); + typedef typename internal::Function::ArgumentTuple ArgumentTuple; + + MockSpec& With($matchers) { + +$if i >= 1 [[ + this->current_spec().SetMatchers(::testing::make_tuple($ms)); + +]] + return this->current_spec(); + } + + R Invoke($Aas) { + // Even though gcc and MSVC don't enforce it, 'this->' is required + // by the C++ standard [14.6.4] here, as the base class type is + // dependent on the template argument (and thus shouldn't be + // looked into when resolving InvokeWith). + return this->InvokeWith(ArgumentTuple($as)); + } +}; + + +]] +} // namespace internal + +// The style guide prohibits "using" statements in a namespace scope +// inside a header file. However, the FunctionMocker class template +// is meant to be defined in the ::testing namespace. The following +// line is just a trick for working around a bug in MSVC 8.0, which +// cannot handle it if we define FunctionMocker in ::testing. +using internal::FunctionMocker; + +// GMOCK_RESULT_(tn, F) expands to the result type of function type F. +// We define this as a variadic macro in case F contains unprotected +// commas (the same reason that we use variadic macros in other places +// in this file). +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_RESULT_(tn, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Result + +// The type of argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_ARG_(tn, N, ...) \ + tn ::testing::internal::Function<__VA_ARGS__>::Argument##N + +// The matcher type for argument N of the given function type. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MATCHER_(tn, N, ...) \ + const ::testing::Matcher& + +// The variable for mocking the given method. +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_MOCKER_(arity, constness, Method) \ + GTEST_CONCAT_TOKEN_(gmock##constness##arity##_##Method##_, __LINE__) + + +$for i [[ +$range j 1..i +$var arg_as = [[$for j, \ + [[GMOCK_ARG_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +$var as = [[$for j, [[gmock_a$j]]]] +$var matcher_as = [[$for j, \ + [[GMOCK_MATCHER_(tn, $j, __VA_ARGS__) gmock_a$j]]]] +// INTERNAL IMPLEMENTATION - DON'T USE IN USER CODE!!! +#define GMOCK_METHOD$i[[]]_(tn, constness, ct, Method, ...) \ + GMOCK_RESULT_(tn, __VA_ARGS__) ct Method( \ + $arg_as) constness { \ + GTEST_COMPILE_ASSERT_((::testing::tuple_size< \ + tn ::testing::internal::Function<__VA_ARGS__>::ArgumentTuple>::value == $i), \ + this_method_does_not_take_$i[[]]_argument[[$if i != 1 [[s]]]]); \ + GMOCK_MOCKER_($i, constness, Method).SetOwnerAndName(this, #Method); \ + return GMOCK_MOCKER_($i, constness, Method).Invoke($as); \ + } \ + ::testing::MockSpec<__VA_ARGS__>& \ + gmock_##Method($matcher_as) constness { \ + GMOCK_MOCKER_($i, constness, Method).RegisterOwner(this); \ + return GMOCK_MOCKER_($i, constness, Method).With($as); \ + } \ + mutable ::testing::FunctionMocker<__VA_ARGS__> GMOCK_MOCKER_($i, constness, Method) + + +]] +$for i [[ +#define MOCK_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i(m, ...) GMOCK_METHOD$i[[]]_(, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T(m, ...) GMOCK_METHOD$i[[]]_(typename, , , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T(m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, , m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(, const, ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, , ct, m, __VA_ARGS__) + +]] + + +$for i [[ +#define MOCK_CONST_METHOD$i[[]]_T_WITH_CALLTYPE(ct, m, ...) \ + GMOCK_METHOD$i[[]]_(typename, const, ct, m, __VA_ARGS__) + +]] + +// A MockFunction class has one mock method whose type is F. It is +// useful when you just want your test code to emit some messages and +// have Google Mock verify the right messages are sent (and perhaps at +// the right times). For example, if you are exercising code: +// +// Foo(1); +// Foo(2); +// Foo(3); +// +// and want to verify that Foo(1) and Foo(3) both invoke +// mock.Bar("a"), but Foo(2) doesn't invoke anything, you can write: +// +// TEST(FooTest, InvokesBarCorrectly) { +// MyMock mock; +// MockFunction check; +// { +// InSequence s; +// +// EXPECT_CALL(mock, Bar("a")); +// EXPECT_CALL(check, Call("1")); +// EXPECT_CALL(check, Call("2")); +// EXPECT_CALL(mock, Bar("a")); +// } +// Foo(1); +// check.Call("1"); +// Foo(2); +// check.Call("2"); +// Foo(3); +// } +// +// The expectation spec says that the first Bar("a") must happen +// before check point "1", the second Bar("a") must happen after check +// point "2", and nothing should happen between the two check +// points. The explicit check points make it easy to tell which +// Bar("a") is called by which call to Foo(). +// +// MockFunction can also be used to exercise code that accepts +// std::function callbacks. To do so, use AsStdFunction() method +// to create std::function proxy forwarding to original object's Call. +// Example: +// +// TEST(FooTest, RunsCallbackWithBarArgument) { +// MockFunction callback; +// EXPECT_CALL(callback, Call("bar")).WillOnce(Return(1)); +// Foo(callback.AsStdFunction()); +// } +template +class MockFunction; + + +$for i [[ +$range j 0..i-1 +$var ArgTypes = [[$for j, [[A$j]]]] +$var ArgNames = [[$for j, [[a$j]]]] +$var ArgDecls = [[$for j, [[A$j a$j]]]] +template +class MockFunction { + public: + MockFunction() {} + + MOCK_METHOD$i[[]]_T(Call, R($ArgTypes)); + +#if GTEST_HAS_STD_FUNCTION_ + std::function AsStdFunction() { + return [this]($ArgDecls) -> R { + return this->Call($ArgNames); + }; + } +#endif // GTEST_HAS_STD_FUNCTION_ + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFunction); +}; + + +]] +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_FUNCTION_MOCKERS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-matchers.h b/src/lib/install/include/gmock/gmock-generated-matchers.h new file mode 100644 index 0000000..57056fd --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-matchers.h @@ -0,0 +1,2179 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-matchers.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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +namespace testing { +namespace internal { + +// The type of the i-th (0-based) field of Tuple. +#define GMOCK_FIELD_TYPE_(Tuple, i) \ + typename ::testing::tuple_element::type + +// TupleFields is for selecting fields from a +// tuple of type Tuple. It has two members: +// +// type: a tuple type whose i-th field is the ki-th field of Tuple. +// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. +// +// For example, in class TupleFields, 2, 0>, we have: +// +// type is tuple, and +// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). + +template +class TupleFields; + +// This generic version is used when there are 10 selectors. +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t), + get(t), get(t), get(t), get(t), get(t)); + } +}; + +// The following specialization is used for 0 ~ 9 selectors. + +template +class TupleFields { + public: + typedef ::testing::tuple<> type; + static type GetSelectedFields(const Tuple& /* t */) { + return type(); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t), + get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t), + get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t), + get(t), get(t), get(t)); + } +}; + +template +class TupleFields { + public: + typedef ::testing::tuple type; + static type GetSelectedFields(const Tuple& t) { + return type(get(t), get(t), get(t), get(t), get(t), + get(t), get(t), get(t), get(t)); + } +}; + +#undef GMOCK_FIELD_TYPE_ + +// Implements the Args() matcher. +template +class ArgsMatcherImpl : public MatcherInterface { + public: + // ArgsTuple may have top-level const or reference modifiers. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; + typedef typename internal::TupleFields::type SelectedArgs; + typedef Matcher MonomorphicInnerMatcher; + + template + explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) + : inner_matcher_(SafeMatcherCast(inner_matcher)) {} + + virtual bool MatchAndExplain(ArgsTuple args, + MatchResultListener* listener) const { + const SelectedArgs& selected_args = GetSelectedArgs(args); + if (!listener->IsInterested()) + return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = inner_matcher_.MatchAndExplain(selected_args, + &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; + } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeNegationTo(os); + } + + private: + static SelectedArgs GetSelectedArgs(ArgsTuple args) { + return TupleFields::GetSelectedFields(args); + } + + // Prints the indices of the selected fields. + static void PrintIndices(::std::ostream* os) { + *os << "whose fields ("; + const int indices[10] = { k0, k1, k2, k3, k4, k5, k6, k7, k8, k9 }; + for (int i = 0; i < 10; i++) { + if (indices[i] < 0) + break; + + if (i >= 1) + *os << ", "; + + *os << "#" << indices[i]; + } + *os << ") "; + } + + const MonomorphicInnerMatcher inner_matcher_; + + GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); +}; + +template +class ArgsMatcher { + public: + explicit ArgsMatcher(const InnerMatcher& inner_matcher) + : inner_matcher_(inner_matcher) {} + + template + operator Matcher() const { + return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); + } + + private: + const InnerMatcher inner_matcher_; + + GTEST_DISALLOW_ASSIGN_(ArgsMatcher); +}; + +// A set of metafunctions for computing the result type of AllOf. +// AllOf(m1, ..., mN) returns +// AllOfResultN::type. + +// Although AllOf isn't defined for one argument, AllOfResult1 is defined +// to simplify the implementation. +template +struct AllOfResult1 { + typedef M1 type; +}; + +template +struct AllOfResult2 { + typedef BothOfMatcher< + typename AllOfResult1::type, + typename AllOfResult1::type + > type; +}; + +template +struct AllOfResult3 { + typedef BothOfMatcher< + typename AllOfResult1::type, + typename AllOfResult2::type + > type; +}; + +template +struct AllOfResult4 { + typedef BothOfMatcher< + typename AllOfResult2::type, + typename AllOfResult2::type + > type; +}; + +template +struct AllOfResult5 { + typedef BothOfMatcher< + typename AllOfResult2::type, + typename AllOfResult3::type + > type; +}; + +template +struct AllOfResult6 { + typedef BothOfMatcher< + typename AllOfResult3::type, + typename AllOfResult3::type + > type; +}; + +template +struct AllOfResult7 { + typedef BothOfMatcher< + typename AllOfResult3::type, + typename AllOfResult4::type + > type; +}; + +template +struct AllOfResult8 { + typedef BothOfMatcher< + typename AllOfResult4::type, + typename AllOfResult4::type + > type; +}; + +template +struct AllOfResult9 { + typedef BothOfMatcher< + typename AllOfResult4::type, + typename AllOfResult5::type + > type; +}; + +template +struct AllOfResult10 { + typedef BothOfMatcher< + typename AllOfResult5::type, + typename AllOfResult5::type + > type; +}; + +// A set of metafunctions for computing the result type of AnyOf. +// AnyOf(m1, ..., mN) returns +// AnyOfResultN::type. + +// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined +// to simplify the implementation. +template +struct AnyOfResult1 { + typedef M1 type; +}; + +template +struct AnyOfResult2 { + typedef EitherOfMatcher< + typename AnyOfResult1::type, + typename AnyOfResult1::type + > type; +}; + +template +struct AnyOfResult3 { + typedef EitherOfMatcher< + typename AnyOfResult1::type, + typename AnyOfResult2::type + > type; +}; + +template +struct AnyOfResult4 { + typedef EitherOfMatcher< + typename AnyOfResult2::type, + typename AnyOfResult2::type + > type; +}; + +template +struct AnyOfResult5 { + typedef EitherOfMatcher< + typename AnyOfResult2::type, + typename AnyOfResult3::type + > type; +}; + +template +struct AnyOfResult6 { + typedef EitherOfMatcher< + typename AnyOfResult3::type, + typename AnyOfResult3::type + > type; +}; + +template +struct AnyOfResult7 { + typedef EitherOfMatcher< + typename AnyOfResult3::type, + typename AnyOfResult4::type + > type; +}; + +template +struct AnyOfResult8 { + typedef EitherOfMatcher< + typename AnyOfResult4::type, + typename AnyOfResult4::type + > type; +}; + +template +struct AnyOfResult9 { + typedef EitherOfMatcher< + typename AnyOfResult4::type, + typename AnyOfResult5::type + > type; +}; + +template +struct AnyOfResult10 { + typedef EitherOfMatcher< + typename AnyOfResult5::type, + typename AnyOfResult5::type + > type; +}; + +} // namespace internal + +// Args(a_matcher) matches a tuple if the selected +// fields of it matches a_matcher. C++ doesn't support default +// arguments for function templates, so we have to overload it. +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +template +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + +// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with +// n elements, where the i-th element in the container must +// match the i-th argument in the list. Each argument of +// ElementsAre() can be either a value or a matcher. We support up to +// 10 arguments. +// +// The use of DecayArray in the implementation allows ElementsAre() +// to accept string literals, whose type is const char[N], but we +// want to treat them as const char*. +// +// NOTE: Since ElementsAre() cares about the order of the elements, it +// must not be used with containers whose elements's order is +// undefined (e.g. hash_map). + +inline internal::ElementsAreMatcher< + ::testing::tuple<> > +ElementsAre() { + typedef ::testing::tuple<> Args; + return internal::ElementsAreMatcher(Args()); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type> > +ElementsAre(const T1& e1) { + typedef ::testing::tuple< + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, + e8)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, + e8, e9)); +} + +template +inline internal::ElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +ElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, + const T10& e10) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::ElementsAreMatcher(Args(e1, e2, e3, e4, e5, e6, e7, + e8, e9, e10)); +} + +// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension +// that matches n elements in any order. We support up to n=10 arguments. + +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple<> > +UnorderedElementsAre() { + typedef ::testing::tuple<> Args; + return internal::UnorderedElementsAreMatcher(Args()); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1) { + typedef ::testing::tuple< + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, + e6)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, + e6, e7)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, + e6, e7, e8)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, + e6, e7, e8, e9)); +} + +template +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> > +UnorderedElementsAre(const T1& e1, const T2& e2, const T3& e3, const T4& e4, + const T5& e5, const T6& e6, const T7& e7, const T8& e8, const T9& e9, + const T10& e10) { + typedef ::testing::tuple< + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type, + typename internal::DecayArray::type> Args; + return internal::UnorderedElementsAreMatcher(Args(e1, e2, e3, e4, e5, + e6, e7, e8, e9, e10)); +} + +// AllOf(m1, m2, ..., mk) matches any value that matches all of the given +// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. + +template +inline typename internal::AllOfResult2::type +AllOf(M1 m1, M2 m2) { + return typename internal::AllOfResult2::type( + m1, + m2); +} + +template +inline typename internal::AllOfResult3::type +AllOf(M1 m1, M2 m2, M3 m3) { + return typename internal::AllOfResult3::type( + m1, + ::testing::AllOf(m2, m3)); +} + +template +inline typename internal::AllOfResult4::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4) { + return typename internal::AllOfResult4::type( + ::testing::AllOf(m1, m2), + ::testing::AllOf(m3, m4)); +} + +template +inline typename internal::AllOfResult5::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { + return typename internal::AllOfResult5::type( + ::testing::AllOf(m1, m2), + ::testing::AllOf(m3, m4, m5)); +} + +template +inline typename internal::AllOfResult6::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { + return typename internal::AllOfResult6::type( + ::testing::AllOf(m1, m2, m3), + ::testing::AllOf(m4, m5, m6)); +} + +template +inline typename internal::AllOfResult7::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { + return typename internal::AllOfResult7::type( + ::testing::AllOf(m1, m2, m3), + ::testing::AllOf(m4, m5, m6, m7)); +} + +template +inline typename internal::AllOfResult8::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { + return typename internal::AllOfResult8::type( + ::testing::AllOf(m1, m2, m3, m4), + ::testing::AllOf(m5, m6, m7, m8)); +} + +template +inline typename internal::AllOfResult9::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { + return typename internal::AllOfResult9::type( + ::testing::AllOf(m1, m2, m3, m4), + ::testing::AllOf(m5, m6, m7, m8, m9)); +} + +template +inline typename internal::AllOfResult10::type +AllOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { + return typename internal::AllOfResult10::type( + ::testing::AllOf(m1, m2, m3, m4, m5), + ::testing::AllOf(m6, m7, m8, m9, m10)); +} + +// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given +// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. + +template +inline typename internal::AnyOfResult2::type +AnyOf(M1 m1, M2 m2) { + return typename internal::AnyOfResult2::type( + m1, + m2); +} + +template +inline typename internal::AnyOfResult3::type +AnyOf(M1 m1, M2 m2, M3 m3) { + return typename internal::AnyOfResult3::type( + m1, + ::testing::AnyOf(m2, m3)); +} + +template +inline typename internal::AnyOfResult4::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4) { + return typename internal::AnyOfResult4::type( + ::testing::AnyOf(m1, m2), + ::testing::AnyOf(m3, m4)); +} + +template +inline typename internal::AnyOfResult5::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5) { + return typename internal::AnyOfResult5::type( + ::testing::AnyOf(m1, m2), + ::testing::AnyOf(m3, m4, m5)); +} + +template +inline typename internal::AnyOfResult6::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6) { + return typename internal::AnyOfResult6::type( + ::testing::AnyOf(m1, m2, m3), + ::testing::AnyOf(m4, m5, m6)); +} + +template +inline typename internal::AnyOfResult7::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7) { + return typename internal::AnyOfResult7::type( + ::testing::AnyOf(m1, m2, m3), + ::testing::AnyOf(m4, m5, m6, m7)); +} + +template +inline typename internal::AnyOfResult8::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8) { + return typename internal::AnyOfResult8::type( + ::testing::AnyOf(m1, m2, m3, m4), + ::testing::AnyOf(m5, m6, m7, m8)); +} + +template +inline typename internal::AnyOfResult9::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9) { + return typename internal::AnyOfResult9::type( + ::testing::AnyOf(m1, m2, m3, m4), + ::testing::AnyOf(m5, m6, m7, m8, m9)); +} + +template +inline typename internal::AnyOfResult10::type +AnyOf(M1 m1, M2 m2, M3 m3, M4 m4, M5 m5, M6 m6, M7 m7, M8 m8, M9 m9, M10 m10) { + return typename internal::AnyOfResult10::type( + ::testing::AnyOf(m1, m2, m3, m4, m5), + ::testing::AnyOf(m6, m7, m8, m9, m10)); +} + +} // namespace testing + + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P10 to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope. The reason is +// that C++ doesn't yet allow function-local types to be used to +// instantiate templates. The up-coming C++0x standard will fix this. +// Once that's done, we'll consider supporting using MATCHER*() inside +// a function. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on http://code.google.com/p/googlemock/wiki/CookBook. + +#define MATCHER(name, description)\ + class name##Matcher {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl()\ + {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple<>()));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl());\ + }\ + name##Matcher() {\ + }\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##Matcher);\ + };\ + inline name##Matcher name() {\ + return name##Matcher();\ + }\ + template \ + bool name##Matcher::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P(name, p0, description)\ + template \ + class name##MatcherP {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + explicit gmock_Impl(p0##_type gmock_p0)\ + : p0(gmock_p0) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0));\ + }\ + explicit name##MatcherP(p0##_type gmock_p0) : p0(gmock_p0) {\ + }\ + p0##_type p0;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP);\ + };\ + template \ + inline name##MatcherP name(p0##_type p0) {\ + return name##MatcherP(p0);\ + }\ + template \ + template \ + bool name##MatcherP::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P2(name, p0, p1, description)\ + template \ + class name##MatcherP2 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1)\ + : p0(gmock_p0), p1(gmock_p1) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1));\ + }\ + name##MatcherP2(p0##_type gmock_p0, p1##_type gmock_p1) : p0(gmock_p0), \ + p1(gmock_p1) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP2);\ + };\ + template \ + inline name##MatcherP2 name(p0##_type p0, \ + p1##_type p1) {\ + return name##MatcherP2(p0, p1);\ + }\ + template \ + template \ + bool name##MatcherP2::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P3(name, p0, p1, p2, description)\ + template \ + class name##MatcherP3 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, \ + p2)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2));\ + }\ + name##MatcherP3(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP3);\ + };\ + template \ + inline name##MatcherP3 name(p0##_type p0, \ + p1##_type p1, p2##_type p2) {\ + return name##MatcherP3(p0, p1, p2);\ + }\ + template \ + template \ + bool name##MatcherP3::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P4(name, p0, p1, p2, p3, description)\ + template \ + class name##MatcherP4 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3));\ + }\ + name##MatcherP4(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP4);\ + };\ + template \ + inline name##MatcherP4 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3) {\ + return name##MatcherP4(p0, \ + p1, p2, p3);\ + }\ + template \ + template \ + bool name##MatcherP4::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P5(name, p0, p1, p2, p3, p4, description)\ + template \ + class name##MatcherP5 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3, p4)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4));\ + }\ + name##MatcherP5(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, \ + p4##_type gmock_p4) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP5);\ + };\ + template \ + inline name##MatcherP5 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4) {\ + return name##MatcherP5(p0, p1, p2, p3, p4);\ + }\ + template \ + template \ + bool name##MatcherP5::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P6(name, p0, p1, p2, p3, p4, p5, description)\ + template \ + class name##MatcherP6 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4), p5(gmock_p5) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3, p4, p5)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5));\ + }\ + name##MatcherP6(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP6);\ + };\ + template \ + inline name##MatcherP6 name(p0##_type p0, p1##_type p1, p2##_type p2, \ + p3##_type p3, p4##_type p4, p5##_type p5) {\ + return name##MatcherP6(p0, p1, p2, p3, p4, p5);\ + }\ + template \ + template \ + bool name##MatcherP6::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P7(name, p0, p1, p2, p3, p4, p5, p6, description)\ + template \ + class name##MatcherP7 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4), p5(gmock_p5), p6(gmock_p6) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3, p4, p5, \ + p6)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6));\ + }\ + name##MatcherP7(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), \ + p6(gmock_p6) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP7);\ + };\ + template \ + inline name##MatcherP7 name(p0##_type p0, p1##_type p1, \ + p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6) {\ + return name##MatcherP7(p0, p1, p2, p3, p4, p5, p6);\ + }\ + template \ + template \ + bool name##MatcherP7::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P8(name, p0, p1, p2, p3, p4, p5, p6, p7, description)\ + template \ + class name##MatcherP8 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, \ + p3, p4, p5, p6, p7)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7));\ + }\ + name##MatcherP8(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, \ + p7##_type gmock_p7) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP8);\ + };\ + template \ + inline name##MatcherP8 name(p0##_type p0, \ + p1##_type p1, p2##_type p2, p3##_type p3, p4##_type p4, p5##_type p5, \ + p6##_type p6, p7##_type p7) {\ + return name##MatcherP8(p0, p1, p2, p3, p4, p5, \ + p6, p7);\ + }\ + template \ + template \ + bool name##MatcherP8::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P9(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, description)\ + template \ + class name##MatcherP9 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8));\ + }\ + name##MatcherP9(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8) : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), \ + p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP9);\ + };\ + template \ + inline name##MatcherP9 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, \ + p8##_type p8) {\ + return name##MatcherP9(p0, p1, p2, \ + p3, p4, p5, p6, p7, p8);\ + }\ + template \ + template \ + bool name##MatcherP9::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#define MATCHER_P10(name, p0, p1, p2, p3, p4, p5, p6, p7, p8, p9, description)\ + template \ + class name##MatcherP10 {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + gmock_Impl(p0##_type gmock_p0, p1##_type gmock_p1, p2##_type gmock_p2, \ + p3##_type gmock_p3, p4##_type gmock_p4, p5##_type gmock_p5, \ + p6##_type gmock_p6, p7##_type gmock_p7, p8##_type gmock_p8, \ + p9##_type gmock_p9)\ + : p0(gmock_p0), p1(gmock_p1), p2(gmock_p2), p3(gmock_p3), \ + p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), p7(gmock_p7), \ + p8(gmock_p8), p9(gmock_p9) {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9)));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl(p0, p1, p2, p3, p4, p5, p6, p7, p8, p9));\ + }\ + name##MatcherP10(p0##_type gmock_p0, p1##_type gmock_p1, \ + p2##_type gmock_p2, p3##_type gmock_p3, p4##_type gmock_p4, \ + p5##_type gmock_p5, p6##_type gmock_p6, p7##_type gmock_p7, \ + p8##_type gmock_p8, p9##_type gmock_p9) : p0(gmock_p0), p1(gmock_p1), \ + p2(gmock_p2), p3(gmock_p3), p4(gmock_p4), p5(gmock_p5), p6(gmock_p6), \ + p7(gmock_p7), p8(gmock_p8), p9(gmock_p9) {\ + }\ + p0##_type p0;\ + p1##_type p1;\ + p2##_type p2;\ + p3##_type p3;\ + p4##_type p4;\ + p5##_type p5;\ + p6##_type p6;\ + p7##_type p7;\ + p8##_type p8;\ + p9##_type p9;\ + private:\ + GTEST_DISALLOW_ASSIGN_(name##MatcherP10);\ + };\ + template \ + inline name##MatcherP10 name(p0##_type p0, p1##_type p1, p2##_type p2, p3##_type p3, \ + p4##_type p4, p5##_type p5, p6##_type p6, p7##_type p7, p8##_type p8, \ + p9##_type p9) {\ + return name##MatcherP10(p0, \ + p1, p2, p3, p4, p5, p6, p7, p8, p9);\ + }\ + template \ + template \ + bool name##MatcherP10::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-matchers.h.pump b/src/lib/install/include/gmock/gmock-generated-matchers.h.pump new file mode 100644 index 0000000..de30c2c --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-matchers.h.pump @@ -0,0 +1,672 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-actions.h. +$$ +$var n = 10 $$ The maximum arity we support. +$$ }} This line fixes auto-indentation of the following code in Emacs. +// 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. + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used variadic matchers. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ + +#include +#include +#include +#include +#include "gmock/gmock-matchers.h" + +namespace testing { +namespace internal { + +$range i 0..n-1 + +// The type of the i-th (0-based) field of Tuple. +#define GMOCK_FIELD_TYPE_(Tuple, i) \ + typename ::testing::tuple_element::type + +// TupleFields is for selecting fields from a +// tuple of type Tuple. It has two members: +// +// type: a tuple type whose i-th field is the ki-th field of Tuple. +// GetSelectedFields(t): returns fields k0, ..., and kn of t as a tuple. +// +// For example, in class TupleFields, 2, 0>, we have: +// +// type is tuple, and +// GetSelectedFields(make_tuple(true, 'a', 42)) is (42, true). + +template +class TupleFields; + +// This generic version is used when there are $n selectors. +template +class TupleFields { + public: + typedef ::testing::tuple<$for i, [[GMOCK_FIELD_TYPE_(Tuple, k$i)]]> type; + static type GetSelectedFields(const Tuple& t) { + return type($for i, [[get(t)]]); + } +}; + +// The following specialization is used for 0 ~ $(n-1) selectors. + +$for i [[ +$$ }}} +$range j 0..i-1 +$range k 0..n-1 + +template +class TupleFields { + public: + typedef ::testing::tuple<$for j, [[GMOCK_FIELD_TYPE_(Tuple, k$j)]]> type; + static type GetSelectedFields(const Tuple& $if i==0 [[/* t */]] $else [[t]]) { + return type($for j, [[get(t)]]); + } +}; + +]] + +#undef GMOCK_FIELD_TYPE_ + +// Implements the Args() matcher. + +$var ks = [[$for i, [[k$i]]]] +template +class ArgsMatcherImpl : public MatcherInterface { + public: + // ArgsTuple may have top-level const or reference modifiers. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(ArgsTuple) RawArgsTuple; + typedef typename internal::TupleFields::type SelectedArgs; + typedef Matcher MonomorphicInnerMatcher; + + template + explicit ArgsMatcherImpl(const InnerMatcher& inner_matcher) + : inner_matcher_(SafeMatcherCast(inner_matcher)) {} + + virtual bool MatchAndExplain(ArgsTuple args, + MatchResultListener* listener) const { + const SelectedArgs& selected_args = GetSelectedArgs(args); + if (!listener->IsInterested()) + return inner_matcher_.Matches(selected_args); + + PrintIndices(listener->stream()); + *listener << "are " << PrintToString(selected_args); + + StringMatchResultListener inner_listener; + const bool match = inner_matcher_.MatchAndExplain(selected_args, + &inner_listener); + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + return match; + } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "are a tuple "; + PrintIndices(os); + inner_matcher_.DescribeNegationTo(os); + } + + private: + static SelectedArgs GetSelectedArgs(ArgsTuple args) { + return TupleFields::GetSelectedFields(args); + } + + // Prints the indices of the selected fields. + static void PrintIndices(::std::ostream* os) { + *os << "whose fields ("; + const int indices[$n] = { $ks }; + for (int i = 0; i < $n; i++) { + if (indices[i] < 0) + break; + + if (i >= 1) + *os << ", "; + + *os << "#" << indices[i]; + } + *os << ") "; + } + + const MonomorphicInnerMatcher inner_matcher_; + + GTEST_DISALLOW_ASSIGN_(ArgsMatcherImpl); +}; + +template +class ArgsMatcher { + public: + explicit ArgsMatcher(const InnerMatcher& inner_matcher) + : inner_matcher_(inner_matcher) {} + + template + operator Matcher() const { + return MakeMatcher(new ArgsMatcherImpl(inner_matcher_)); + } + + private: + const InnerMatcher inner_matcher_; + + GTEST_DISALLOW_ASSIGN_(ArgsMatcher); +}; + +// A set of metafunctions for computing the result type of AllOf. +// AllOf(m1, ..., mN) returns +// AllOfResultN::type. + +// Although AllOf isn't defined for one argument, AllOfResult1 is defined +// to simplify the implementation. +template +struct AllOfResult1 { + typedef M1 type; +}; + +$range i 1..n + +$range i 2..n +$for i [[ +$range j 2..i +$var m = i/2 +$range k 1..m +$range t m+1..i + +template +struct AllOfResult$i { + typedef BothOfMatcher< + typename AllOfResult$m<$for k, [[M$k]]>::type, + typename AllOfResult$(i-m)<$for t, [[M$t]]>::type + > type; +}; + +]] + +// A set of metafunctions for computing the result type of AnyOf. +// AnyOf(m1, ..., mN) returns +// AnyOfResultN::type. + +// Although AnyOf isn't defined for one argument, AnyOfResult1 is defined +// to simplify the implementation. +template +struct AnyOfResult1 { + typedef M1 type; +}; + +$range i 1..n + +$range i 2..n +$for i [[ +$range j 2..i +$var m = i/2 +$range k 1..m +$range t m+1..i + +template +struct AnyOfResult$i { + typedef EitherOfMatcher< + typename AnyOfResult$m<$for k, [[M$k]]>::type, + typename AnyOfResult$(i-m)<$for t, [[M$t]]>::type + > type; +}; + +]] + +} // namespace internal + +// Args(a_matcher) matches a tuple if the selected +// fields of it matches a_matcher. C++ doesn't support default +// arguments for function templates, so we have to overload it. + +$range i 0..n +$for i [[ +$range j 1..i +template <$for j [[int k$j, ]]typename InnerMatcher> +inline internal::ArgsMatcher +Args(const InnerMatcher& matcher) { + return internal::ArgsMatcher(matcher); +} + + +]] +// ElementsAre(e_1, e_2, ... e_n) matches an STL-style container with +// n elements, where the i-th element in the container must +// match the i-th argument in the list. Each argument of +// ElementsAre() can be either a value or a matcher. We support up to +// $n arguments. +// +// The use of DecayArray in the implementation allows ElementsAre() +// to accept string literals, whose type is const char[N], but we +// want to treat them as const char*. +// +// NOTE: Since ElementsAre() cares about the order of the elements, it +// must not be used with containers whose elements's order is +// undefined (e.g. hash_map). + +$range i 0..n +$for i [[ + +$range j 1..i + +$if i>0 [[ + +template <$for j, [[typename T$j]]> +]] + +inline internal::ElementsAreMatcher< + ::testing::tuple< +$for j, [[ + + typename internal::DecayArray::type]]> > +ElementsAre($for j, [[const T$j& e$j]]) { + typedef ::testing::tuple< +$for j, [[ + + typename internal::DecayArray::type]]> Args; + return internal::ElementsAreMatcher(Args($for j, [[e$j]])); +} + +]] + +// UnorderedElementsAre(e_1, e_2, ..., e_n) is an ElementsAre extension +// that matches n elements in any order. We support up to n=$n arguments. + +$range i 0..n +$for i [[ + +$range j 1..i + +$if i>0 [[ + +template <$for j, [[typename T$j]]> +]] + +inline internal::UnorderedElementsAreMatcher< + ::testing::tuple< +$for j, [[ + + typename internal::DecayArray::type]]> > +UnorderedElementsAre($for j, [[const T$j& e$j]]) { + typedef ::testing::tuple< +$for j, [[ + + typename internal::DecayArray::type]]> Args; + return internal::UnorderedElementsAreMatcher(Args($for j, [[e$j]])); +} + +]] + +// AllOf(m1, m2, ..., mk) matches any value that matches all of the given +// sub-matchers. AllOf is called fully qualified to prevent ADL from firing. + +$range i 2..n +$for i [[ +$range j 1..i +$var m = i/2 +$range k 1..m +$range t m+1..i + +template <$for j, [[typename M$j]]> +inline typename internal::AllOfResult$i<$for j, [[M$j]]>::type +AllOf($for j, [[M$j m$j]]) { + return typename internal::AllOfResult$i<$for j, [[M$j]]>::type( + $if m == 1 [[m1]] $else [[::testing::AllOf($for k, [[m$k]])]], + $if m+1 == i [[m$i]] $else [[::testing::AllOf($for t, [[m$t]])]]); +} + +]] + +// AnyOf(m1, m2, ..., mk) matches any value that matches any of the given +// sub-matchers. AnyOf is called fully qualified to prevent ADL from firing. + +$range i 2..n +$for i [[ +$range j 1..i +$var m = i/2 +$range k 1..m +$range t m+1..i + +template <$for j, [[typename M$j]]> +inline typename internal::AnyOfResult$i<$for j, [[M$j]]>::type +AnyOf($for j, [[M$j m$j]]) { + return typename internal::AnyOfResult$i<$for j, [[M$j]]>::type( + $if m == 1 [[m1]] $else [[::testing::AnyOf($for k, [[m$k]])]], + $if m+1 == i [[m$i]] $else [[::testing::AnyOf($for t, [[m$t]])]]); +} + +]] + +} // namespace testing +$$ } // This Pump meta comment fixes auto-indentation in Emacs. It will not +$$ // show up in the generated code. + + +// The MATCHER* family of macros can be used in a namespace scope to +// define custom matchers easily. +// +// Basic Usage +// =========== +// +// The syntax +// +// MATCHER(name, description_string) { statements; } +// +// defines a matcher with the given name that executes the statements, +// which must return a bool to indicate if the match succeeds. Inside +// the statements, you can refer to the value being matched by 'arg', +// and refer to its type by 'arg_type'. +// +// The description string documents what the matcher does, and is used +// to generate the failure message when the match fails. Since a +// MATCHER() is usually defined in a header file shared by multiple +// C++ source files, we require the description to be a C-string +// literal to avoid possible side effects. It can be empty, in which +// case we'll use the sequence of words in the matcher name as the +// description. +// +// For example: +// +// MATCHER(IsEven, "") { return (arg % 2) == 0; } +// +// allows you to write +// +// // Expects mock_foo.Bar(n) to be called where n is even. +// EXPECT_CALL(mock_foo, Bar(IsEven())); +// +// or, +// +// // Verifies that the value of some_expression is even. +// EXPECT_THAT(some_expression, IsEven()); +// +// If the above assertion fails, it will print something like: +// +// Value of: some_expression +// Expected: is even +// Actual: 7 +// +// where the description "is even" is automatically calculated from the +// matcher name IsEven. +// +// Argument Type +// ============= +// +// Note that the type of the value being matched (arg_type) is +// determined by the context in which you use the matcher and is +// supplied to you by the compiler, so you don't need to worry about +// declaring it (nor can you). This allows the matcher to be +// polymorphic. For example, IsEven() can be used to match any type +// where the value of "(arg % 2) == 0" can be implicitly converted to +// a bool. In the "Bar(IsEven())" example above, if method Bar() +// takes an int, 'arg_type' will be int; if it takes an unsigned long, +// 'arg_type' will be unsigned long; and so on. +// +// Parameterizing Matchers +// ======================= +// +// Sometimes you'll want to parameterize the matcher. For that you +// can use another macro: +// +// MATCHER_P(name, param_name, description_string) { statements; } +// +// For example: +// +// MATCHER_P(HasAbsoluteValue, value, "") { return abs(arg) == value; } +// +// will allow you to write: +// +// EXPECT_THAT(Blah("a"), HasAbsoluteValue(n)); +// +// which may lead to this message (assuming n is 10): +// +// Value of: Blah("a") +// Expected: has absolute value 10 +// Actual: -9 +// +// Note that both the matcher description and its parameter are +// printed, making the message human-friendly. +// +// In the matcher definition body, you can write 'foo_type' to +// reference the type of a parameter named 'foo'. For example, in the +// body of MATCHER_P(HasAbsoluteValue, value) above, you can write +// 'value_type' to refer to the type of 'value'. +// +// We also provide MATCHER_P2, MATCHER_P3, ..., up to MATCHER_P$n to +// support multi-parameter matchers. +// +// Describing Parameterized Matchers +// ================================= +// +// The last argument to MATCHER*() is a string-typed expression. The +// expression can reference all of the matcher's parameters and a +// special bool-typed variable named 'negation'. When 'negation' is +// false, the expression should evaluate to the matcher's description; +// otherwise it should evaluate to the description of the negation of +// the matcher. For example, +// +// using testing::PrintToString; +// +// MATCHER_P2(InClosedRange, low, hi, +// string(negation ? "is not" : "is") + " in range [" + +// PrintToString(low) + ", " + PrintToString(hi) + "]") { +// return low <= arg && arg <= hi; +// } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: is in range [4, 6] +// ... +// Expected: is not in range [2, 4] +// +// If you specify "" as the description, the failure message will +// contain the sequence of words in the matcher name followed by the +// parameter values printed as a tuple. For example, +// +// MATCHER_P2(InClosedRange, low, hi, "") { ... } +// ... +// EXPECT_THAT(3, InClosedRange(4, 6)); +// EXPECT_THAT(3, Not(InClosedRange(2, 4))); +// +// would generate two failures that contain the text: +// +// Expected: in closed range (4, 6) +// ... +// Expected: not (in closed range (2, 4)) +// +// Types of Matcher Parameters +// =========================== +// +// For the purpose of typing, you can view +// +// MATCHER_Pk(Foo, p1, ..., pk, description_string) { ... } +// +// as shorthand for +// +// template +// FooMatcherPk +// Foo(p1_type p1, ..., pk_type pk) { ... } +// +// When you write Foo(v1, ..., vk), the compiler infers the types of +// the parameters v1, ..., and vk for you. If you are not happy with +// the result of the type inference, you can specify the types by +// explicitly instantiating the template, as in Foo(5, +// false). As said earlier, you don't get to (or need to) specify +// 'arg_type' as that's determined by the context in which the matcher +// is used. You can assign the result of expression Foo(p1, ..., pk) +// to a variable of type FooMatcherPk. This +// can be useful when composing matchers. +// +// While you can instantiate a matcher template with reference types, +// passing the parameters by pointer usually makes your code more +// readable. If, however, you still want to pass a parameter by +// reference, be aware that in the failure message generated by the +// matcher you will see the value of the referenced object but not its +// address. +// +// Explaining Match Results +// ======================== +// +// Sometimes the matcher description alone isn't enough to explain why +// the match has failed or succeeded. For example, when expecting a +// long string, it can be very helpful to also print the diff between +// the expected string and the actual one. To achieve that, you can +// optionally stream additional information to a special variable +// named result_listener, whose type is a pointer to class +// MatchResultListener: +// +// MATCHER_P(EqualsLongString, str, "") { +// if (arg == str) return true; +// +// *result_listener << "the difference: " +/// << DiffStrings(str, arg); +// return false; +// } +// +// Overloading Matchers +// ==================== +// +// You can overload matchers with different numbers of parameters: +// +// MATCHER_P(Blah, a, description_string1) { ... } +// MATCHER_P2(Blah, a, b, description_string2) { ... } +// +// Caveats +// ======= +// +// When defining a new matcher, you should also consider implementing +// MatcherInterface or using MakePolymorphicMatcher(). These +// approaches require more work than the MATCHER* macros, but also +// give you more control on the types of the value being matched and +// the matcher parameters, which may leads to better compiler error +// messages when the matcher is used wrong. They also allow +// overloading matchers based on parameter types (as opposed to just +// based on the number of parameters). +// +// MATCHER*() can only be used in a namespace scope. The reason is +// that C++ doesn't yet allow function-local types to be used to +// instantiate templates. The up-coming C++0x standard will fix this. +// Once that's done, we'll consider supporting using MATCHER*() inside +// a function. +// +// More Information +// ================ +// +// To learn more about using these macros, please search for 'MATCHER' +// on http://code.google.com/p/googlemock/wiki/CookBook. + +$range i 0..n +$for i + +[[ +$var macro_name = [[$if i==0 [[MATCHER]] $elif i==1 [[MATCHER_P]] + $else [[MATCHER_P$i]]]] +$var class_name = [[name##Matcher[[$if i==0 [[]] $elif i==1 [[P]] + $else [[P$i]]]]]] +$range j 0..i-1 +$var template = [[$if i==0 [[]] $else [[ + + template <$for j, [[typename p$j##_type]]>\ +]]]] +$var ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_ctor_param_list = [[$for j, [[p$j##_type gmock_p$j]]]] +$var impl_inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] +$var inits = [[$if i==0 [[]] $else [[ : $for j, [[p$j(gmock_p$j)]]]]]] +$var params = [[$for j, [[p$j]]]] +$var param_types = [[$if i==0 [[]] $else [[<$for j, [[p$j##_type]]>]]]] +$var param_types_and_names = [[$for j, [[p$j##_type p$j]]]] +$var param_field_decls = [[$for j +[[ + + p$j##_type p$j;\ +]]]] +$var param_field_decls2 = [[$for j +[[ + + p$j##_type p$j;\ +]]]] + +#define $macro_name(name$for j [[, p$j]], description)\$template + class $class_name {\ + public:\ + template \ + class gmock_Impl : public ::testing::MatcherInterface {\ + public:\ + [[$if i==1 [[explicit ]]]]gmock_Impl($impl_ctor_param_list)\ + $impl_inits {}\ + virtual bool MatchAndExplain(\ + arg_type arg, ::testing::MatchResultListener* result_listener) const;\ + virtual void DescribeTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(false);\ + }\ + virtual void DescribeNegationTo(::std::ostream* gmock_os) const {\ + *gmock_os << FormatDescription(true);\ + }\$param_field_decls + private:\ + ::testing::internal::string FormatDescription(bool negation) const {\ + const ::testing::internal::string gmock_description = (description);\ + if (!gmock_description.empty())\ + return gmock_description;\ + return ::testing::internal::FormatMatcherDescription(\ + negation, #name, \ + ::testing::internal::UniversalTersePrintTupleFieldsToStrings(\ + ::testing::tuple<$for j, [[p$j##_type]]>($for j, [[p$j]])));\ + }\ + GTEST_DISALLOW_ASSIGN_(gmock_Impl);\ + };\ + template \ + operator ::testing::Matcher() const {\ + return ::testing::Matcher(\ + new gmock_Impl($params));\ + }\ + [[$if i==1 [[explicit ]]]]$class_name($ctor_param_list)$inits {\ + }\$param_field_decls2 + private:\ + GTEST_DISALLOW_ASSIGN_($class_name);\ + };\$template + inline $class_name$param_types name($param_types_and_names) {\ + return $class_name$param_types($params);\ + }\$template + template \ + bool $class_name$param_types::gmock_Impl::MatchAndExplain(\ + arg_type arg, \ + ::testing::MatchResultListener* result_listener GTEST_ATTRIBUTE_UNUSED_)\ + const +]] + + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_MATCHERS_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-nice-strict.h b/src/lib/install/include/gmock/gmock-generated-nice-strict.h new file mode 100644 index 0000000..4095f4d --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-nice-strict.h @@ -0,0 +1,397 @@ +// This file was GENERATED by command: +// pump.py gmock-generated-nice-strict.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) + +// Implements class templates NiceMock, NaggyMock, and StrictMock. +// +// Given a mock class MockFoo that is created using Google Mock, +// NiceMock is a subclass of MockFoo that allows +// uninteresting calls (i.e. calls to mock methods that have no +// EXPECT_CALL specs), NaggyMock is a subclass of MockFoo +// that prints a warning when an uninteresting call occurs, and +// StrictMock is a subclass of MockFoo that treats all +// uninteresting calls as errors. +// +// Currently a mock is naggy by default, so MockFoo and +// NaggyMock behave like the same. However, we will soon +// switch the default behavior of mocks to be nice, as that in general +// leads to more maintainable tests. When that happens, MockFoo will +// stop behaving like NaggyMock and start behaving like +// NiceMock. +// +// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of +// their respective base class, with up-to 10 arguments. Therefore +// you can write NiceMock(5, "a") to construct a nice mock +// where MockFoo has a constructor that accepts (int, const char*), +// for example. +// +// A known limitation is that NiceMock, NaggyMock, +// and StrictMock only works for mock methods defined using +// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. +// If a mock method is defined in a base class of MockFoo, the "nice" +// or "strict" modifier may not affect it, depending on the compiler. +// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT +// supported. +// +// Another known limitation is that the constructors of the base mock +// cannot have arguments passed by non-const reference, which are +// banned by the Google C++ style guide anyway. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { + +template +class NiceMock : public MockClass { + public: + // We don't factor out the constructor body to a common method, as + // we have to avoid a possible clash with members of MockClass. + NiceMock() { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + // C++ doesn't (yet) allow inheritance of constructors, so we have + // to define it for each arity. + template + explicit NiceMock(const A1& a1) : MockClass(a1) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + template + NiceMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, + const A4& a4) : MockClass(a1, a2, a3, a4) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5) : MockClass(a1, a2, a3, a4, a5) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, + a6, a7) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, + a2, a3, a4, a5, a6, a7, a8) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, + const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NiceMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, + const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { + ::testing::Mock::AllowUninterestingCalls( + internal::ImplicitCast_(this)); + } + + virtual ~NiceMock() { + ::testing::Mock::UnregisterCallReaction( + internal::ImplicitCast_(this)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NiceMock); +}; + +template +class NaggyMock : public MockClass { + public: + // We don't factor out the constructor body to a common method, as + // we have to avoid a possible clash with members of MockClass. + NaggyMock() { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + // C++ doesn't (yet) allow inheritance of constructors, so we have + // to define it for each arity. + template + explicit NaggyMock(const A1& a1) : MockClass(a1) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + template + NaggyMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, + const A4& a4) : MockClass(a1, a2, a3, a4) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5) : MockClass(a1, a2, a3, a4, a5) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, + a6, a7) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, + a2, a3, a4, a5, a6, a7, a8) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, + const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + NaggyMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, + const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { + ::testing::Mock::WarnUninterestingCalls( + internal::ImplicitCast_(this)); + } + + virtual ~NaggyMock() { + ::testing::Mock::UnregisterCallReaction( + internal::ImplicitCast_(this)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(NaggyMock); +}; + +template +class StrictMock : public MockClass { + public: + // We don't factor out the constructor body to a common method, as + // we have to avoid a possible clash with members of MockClass. + StrictMock() { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + // C++ doesn't (yet) allow inheritance of constructors, so we have + // to define it for each arity. + template + explicit StrictMock(const A1& a1) : MockClass(a1) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + template + StrictMock(const A1& a1, const A2& a2) : MockClass(a1, a2) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3) : MockClass(a1, a2, a3) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, + const A4& a4) : MockClass(a1, a2, a3, a4) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5) : MockClass(a1, a2, a3, a4, a5) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6) : MockClass(a1, a2, a3, a4, a5, a6) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7) : MockClass(a1, a2, a3, a4, a5, + a6, a7) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8) : MockClass(a1, + a2, a3, a4, a5, a6, a7, a8) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, + const A9& a9) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + template + StrictMock(const A1& a1, const A2& a2, const A3& a3, const A4& a4, + const A5& a5, const A6& a6, const A7& a7, const A8& a8, const A9& a9, + const A10& a10) : MockClass(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) { + ::testing::Mock::FailUninterestingCalls( + internal::ImplicitCast_(this)); + } + + virtual ~StrictMock() { + ::testing::Mock::UnregisterCallReaction( + internal::ImplicitCast_(this)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(StrictMock); +}; + +// The following specializations catch some (relatively more common) +// user errors of nesting nice and strict mocks. They do NOT catch +// all possible errors. + +// These specializations are declared but not defined, as NiceMock, +// NaggyMock, and StrictMock cannot be nested. + +template +class NiceMock >; +template +class NiceMock >; +template +class NiceMock >; + +template +class NaggyMock >; +template +class NaggyMock >; +template +class NaggyMock >; + +template +class StrictMock >; +template +class StrictMock >; +template +class StrictMock >; + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/src/lib/install/include/gmock/gmock-generated-nice-strict.h.pump b/src/lib/install/include/gmock/gmock-generated-nice-strict.h.pump new file mode 100644 index 0000000..3ee1ce7 --- /dev/null +++ b/src/lib/install/include/gmock/gmock-generated-nice-strict.h.pump @@ -0,0 +1,161 @@ +$$ -*- mode: c++; -*- +$$ This is a Pump source file. Please use Pump to convert it to +$$ gmock-generated-nice-strict.h. +$$ +$var n = 10 $$ The maximum arity we 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) + +// Implements class templates NiceMock, NaggyMock, and StrictMock. +// +// Given a mock class MockFoo that is created using Google Mock, +// NiceMock is a subclass of MockFoo that allows +// uninteresting calls (i.e. calls to mock methods that have no +// EXPECT_CALL specs), NaggyMock is a subclass of MockFoo +// that prints a warning when an uninteresting call occurs, and +// StrictMock is a subclass of MockFoo that treats all +// uninteresting calls as errors. +// +// Currently a mock is naggy by default, so MockFoo and +// NaggyMock behave like the same. However, we will soon +// switch the default behavior of mocks to be nice, as that in general +// leads to more maintainable tests. When that happens, MockFoo will +// stop behaving like NaggyMock and start behaving like +// NiceMock. +// +// NiceMock, NaggyMock, and StrictMock "inherit" the constructors of +// their respective base class, with up-to $n arguments. Therefore +// you can write NiceMock(5, "a") to construct a nice mock +// where MockFoo has a constructor that accepts (int, const char*), +// for example. +// +// A known limitation is that NiceMock, NaggyMock, +// and StrictMock only works for mock methods defined using +// the MOCK_METHOD* family of macros DIRECTLY in the MockFoo class. +// If a mock method is defined in a base class of MockFoo, the "nice" +// or "strict" modifier may not affect it, depending on the compiler. +// In particular, nesting NiceMock, NaggyMock, and StrictMock is NOT +// supported. +// +// Another known limitation is that the constructors of the base mock +// cannot have arguments passed by non-const reference, which are +// banned by the Google C++ style guide anyway. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ + +#include "gmock/gmock-spec-builders.h" +#include "gmock/internal/gmock-port.h" + +namespace testing { + +$range kind 0..2 +$for kind [[ + +$var clazz=[[$if kind==0 [[NiceMock]] + $elif kind==1 [[NaggyMock]] + $else [[StrictMock]]]] + +$var method=[[$if kind==0 [[AllowUninterestingCalls]] + $elif kind==1 [[WarnUninterestingCalls]] + $else [[FailUninterestingCalls]]]] + +template +class $clazz : public MockClass { + public: + // We don't factor out the constructor body to a common method, as + // we have to avoid a possible clash with members of MockClass. + $clazz() { + ::testing::Mock::$method( + internal::ImplicitCast_(this)); + } + + // C++ doesn't (yet) allow inheritance of constructors, so we have + // to define it for each arity. + template + explicit $clazz(const A1& a1) : MockClass(a1) { + ::testing::Mock::$method( + internal::ImplicitCast_(this)); + } + +$range i 2..n +$for i [[ +$range j 1..i + template <$for j, [[typename A$j]]> + $clazz($for j, [[const A$j& a$j]]) : MockClass($for j, [[a$j]]) { + ::testing::Mock::$method( + internal::ImplicitCast_(this)); + } + + +]] + virtual ~$clazz() { + ::testing::Mock::UnregisterCallReaction( + internal::ImplicitCast_(this)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_($clazz); +}; + +]] + +// The following specializations catch some (relatively more common) +// user errors of nesting nice and strict mocks. They do NOT catch +// all possible errors. + +// These specializations are declared but not defined, as NiceMock, +// NaggyMock, and StrictMock cannot be nested. + +template +class NiceMock >; +template +class NiceMock >; +template +class NiceMock >; + +template +class NaggyMock >; +template +class NaggyMock >; +template +class NaggyMock >; + +template +class StrictMock >; +template +class StrictMock >; +template +class StrictMock >; + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_NICE_STRICT_H_ diff --git a/src/lib/install/include/gmock/gmock-matchers.h b/src/lib/install/include/gmock/gmock-matchers.h new file mode 100644 index 0000000..9ade5b6 --- /dev/null +++ b/src/lib/install/include/gmock/gmock-matchers.h @@ -0,0 +1,4397 @@ +// 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 Mock - a framework for writing C++ mock classes. +// +// This file implements some commonly used argument matchers. More +// matchers can be defined by the user implementing the +// MatcherInterface interface if necessary. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_MATCHERS_H_ + +#include +#include +#include +#include +#include // NOLINT +#include +#include +#include +#include + +#include "gmock/internal/gmock-internal-utils.h" +#include "gmock/internal/gmock-port.h" +#include "gtest/gtest.h" + +#if GTEST_HAS_STD_INITIALIZER_LIST_ +# include // NOLINT -- must be after gtest.h +#endif + +namespace testing { + +// To implement a matcher Foo for type T, define: +// 1. a class FooMatcherImpl that implements the +// MatcherInterface interface, and +// 2. a factory function that creates a Matcher object from a +// FooMatcherImpl*. +// +// The two-level delegation design makes it possible to allow a user +// to write "v" instead of "Eq(v)" where a Matcher is expected, which +// is impossible if we pass matchers by pointers. It also eases +// ownership management as Matcher objects can now be copied like +// plain values. + +// MatchResultListener is an abstract class. Its << operator can be +// used by a matcher to explain why a value matches or doesn't match. +// +// TODO(wan@google.com): add method +// bool InterestedInWhy(bool result) const; +// to indicate whether the listener is interested in why the match +// result is 'result'. +class MatchResultListener { + public: + // Creates a listener object with the given underlying ostream. The + // listener does not own the ostream, and does not dereference it + // in the constructor or destructor. + explicit MatchResultListener(::std::ostream* os) : stream_(os) {} + virtual ~MatchResultListener() = 0; // Makes this class abstract. + + // Streams x to the underlying ostream; does nothing if the ostream + // is NULL. + template + MatchResultListener& operator<<(const T& x) { + if (stream_ != NULL) + *stream_ << x; + return *this; + } + + // Returns the underlying ostream. + ::std::ostream* stream() { return stream_; } + + // Returns true iff the listener is interested in an explanation of + // the match result. A matcher's MatchAndExplain() method can use + // this information to avoid generating the explanation when no one + // intends to hear it. + bool IsInterested() const { return stream_ != NULL; } + + private: + ::std::ostream* const stream_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(MatchResultListener); +}; + +inline MatchResultListener::~MatchResultListener() { +} + +// An instance of a subclass of this knows how to describe itself as a +// matcher. +class MatcherDescriberInterface { + public: + virtual ~MatcherDescriberInterface() {} + + // Describes this matcher to an ostream. The function should print + // a verb phrase that describes the property a value matching this + // matcher should have. The subject of the verb phrase is the value + // being matched. For example, the DescribeTo() method of the Gt(7) + // matcher prints "is greater than 7". + virtual void DescribeTo(::std::ostream* os) const = 0; + + // Describes the negation of this matcher to an ostream. For + // example, if the description of this matcher is "is greater than + // 7", the negated description could be "is not greater than 7". + // You are not required to override this when implementing + // MatcherInterface, but it is highly advised so that your matcher + // can produce good error messages. + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "not ("; + DescribeTo(os); + *os << ")"; + } +}; + +// The implementation of a matcher. +template +class MatcherInterface : public MatcherDescriberInterface { + public: + // Returns true iff the matcher matches x; also explains the match + // result to 'listener' if necessary (see the next paragraph), in + // the form of a non-restrictive relative clause ("which ...", + // "whose ...", etc) that describes x. For example, the + // MatchAndExplain() method of the Pointee(...) matcher should + // generate an explanation like "which points to ...". + // + // Implementations of MatchAndExplain() should add an explanation of + // the match result *if and only if* they can provide additional + // information that's not already present (or not obvious) in the + // print-out of x and the matcher's description. Whether the match + // succeeds is not a factor in deciding whether an explanation is + // needed, as sometimes the caller needs to print a failure message + // when the match succeeds (e.g. when the matcher is used inside + // Not()). + // + // For example, a "has at least 10 elements" matcher should explain + // what the actual element count is, regardless of the match result, + // as it is useful information to the reader; on the other hand, an + // "is empty" matcher probably only needs to explain what the actual + // size is when the match fails, as it's redundant to say that the + // size is 0 when the value is already known to be empty. + // + // You should override this method when defining a new matcher. + // + // It's the responsibility of the caller (Google Mock) to guarantee + // that 'listener' is not NULL. This helps to simplify a matcher's + // implementation when it doesn't care about the performance, as it + // can talk to 'listener' without checking its validity first. + // However, in order to implement dummy listeners efficiently, + // listener->stream() may be NULL. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const = 0; + + // Inherits these methods from MatcherDescriberInterface: + // virtual void DescribeTo(::std::ostream* os) const = 0; + // virtual void DescribeNegationTo(::std::ostream* os) const; +}; + +// A match result listener that stores the explanation in a string. +class StringMatchResultListener : public MatchResultListener { + public: + StringMatchResultListener() : MatchResultListener(&ss_) {} + + // Returns the explanation accumulated so far. + std::string str() const { return ss_.str(); } + + // Clears the explanation accumulated so far. + void Clear() { ss_.str(""); } + + private: + ::std::stringstream ss_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StringMatchResultListener); +}; + +namespace internal { + +struct AnyEq { + template + bool operator()(const A& a, const B& b) const { return a == b; } +}; +struct AnyNe { + template + bool operator()(const A& a, const B& b) const { return a != b; } +}; +struct AnyLt { + template + bool operator()(const A& a, const B& b) const { return a < b; } +}; +struct AnyGt { + template + bool operator()(const A& a, const B& b) const { return a > b; } +}; +struct AnyLe { + template + bool operator()(const A& a, const B& b) const { return a <= b; } +}; +struct AnyGe { + template + bool operator()(const A& a, const B& b) const { return a >= b; } +}; + +// A match result listener that ignores the explanation. +class DummyMatchResultListener : public MatchResultListener { + public: + DummyMatchResultListener() : MatchResultListener(NULL) {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DummyMatchResultListener); +}; + +// A match result listener that forwards the explanation to a given +// ostream. The difference between this and MatchResultListener is +// that the former is concrete. +class StreamMatchResultListener : public MatchResultListener { + public: + explicit StreamMatchResultListener(::std::ostream* os) + : MatchResultListener(os) {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamMatchResultListener); +}; + +// An internal class for implementing Matcher, which will derive +// from it. We put functionalities common to all Matcher +// specializations here to avoid code duplication. +template +class MatcherBase { + public: + // Returns true iff the matcher matches x; also explains the match + // result to 'listener'. + bool MatchAndExplain(T x, MatchResultListener* listener) const { + return impl_->MatchAndExplain(x, listener); + } + + // Returns true iff this matcher matches x. + bool Matches(T x) const { + DummyMatchResultListener dummy; + return MatchAndExplain(x, &dummy); + } + + // Describes this matcher to an ostream. + void DescribeTo(::std::ostream* os) const { impl_->DescribeTo(os); } + + // Describes the negation of this matcher to an ostream. + void DescribeNegationTo(::std::ostream* os) const { + impl_->DescribeNegationTo(os); + } + + // Explains why x matches, or doesn't match, the matcher. + void ExplainMatchResultTo(T x, ::std::ostream* os) const { + StreamMatchResultListener listener(os); + MatchAndExplain(x, &listener); + } + + // Returns the describer for this matcher object; retains ownership + // of the describer, which is only guaranteed to be alive when + // this matcher object is alive. + const MatcherDescriberInterface* GetDescriber() const { + return impl_.get(); + } + + protected: + MatcherBase() {} + + // Constructs a matcher from its implementation. + explicit MatcherBase(const MatcherInterface* impl) + : impl_(impl) {} + + virtual ~MatcherBase() {} + + private: + // shared_ptr (util/gtl/shared_ptr.h) and linked_ptr have similar + // interfaces. The former dynamically allocates a chunk of memory + // to hold the reference count, while the latter tracks all + // references using a circular linked list without allocating + // memory. It has been observed that linked_ptr performs better in + // typical scenarios. However, shared_ptr can out-perform + // linked_ptr when there are many more uses of the copy constructor + // than the default constructor. + // + // If performance becomes a problem, we should see if using + // shared_ptr helps. + ::testing::internal::linked_ptr > impl_; +}; + +} // namespace internal + +// A Matcher is a copyable and IMMUTABLE (except by assignment) +// object that can check whether a value of type T matches. The +// implementation of Matcher is just a linked_ptr to const +// MatcherInterface, so copying is fairly cheap. Don't inherit +// from Matcher! +template +class Matcher : public internal::MatcherBase { + public: + // Constructs a null matcher. Needed for storing Matcher objects in STL + // containers. A default-constructed matcher is not yet initialized. You + // cannot use it until a valid value has been assigned to it. + explicit Matcher() {} // NOLINT + + // Constructs a matcher from its implementation. + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Implicit constructor here allows people to write + // EXPECT_CALL(foo, Bar(5)) instead of EXPECT_CALL(foo, Bar(Eq(5))) sometimes + Matcher(T value); // NOLINT +}; + +// The following two specializations allow the user to write str +// instead of Eq(str) and "foo" instead of Eq("foo") when a string +// matcher is expected. +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a string object. + Matcher(const internal::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT +}; + +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a string object. + Matcher(const internal::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT +}; + +#if GTEST_HAS_STRING_PIECE_ +// The following two specializations allow the user to write str +// instead of Eq(str) and "foo" instead of Eq("foo") when a StringPiece +// matcher is expected. +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a string object. + Matcher(const internal::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT + + // Allows the user to pass StringPieces directly. + Matcher(StringPiece s); // NOLINT +}; + +template <> +class GTEST_API_ Matcher + : public internal::MatcherBase { + public: + Matcher() {} + + explicit Matcher(const MatcherInterface* impl) + : internal::MatcherBase(impl) {} + + // Allows the user to write str instead of Eq(str) sometimes, where + // str is a string object. + Matcher(const internal::string& s); // NOLINT + + // Allows the user to write "foo" instead of Eq("foo") sometimes. + Matcher(const char* s); // NOLINT + + // Allows the user to pass StringPieces directly. + Matcher(StringPiece s); // NOLINT +}; +#endif // GTEST_HAS_STRING_PIECE_ + +// The PolymorphicMatcher class template makes it easy to implement a +// polymorphic matcher (i.e. a matcher that can match values of more +// than one type, e.g. Eq(n) and NotNull()). +// +// To define a polymorphic matcher, a user should provide an Impl +// class that has a DescribeTo() method and a DescribeNegationTo() +// method, and define a member function (or member function template) +// +// bool MatchAndExplain(const Value& value, +// MatchResultListener* listener) const; +// +// See the definition of NotNull() for a complete example. +template +class PolymorphicMatcher { + public: + explicit PolymorphicMatcher(const Impl& an_impl) : impl_(an_impl) {} + + // Returns a mutable reference to the underlying matcher + // implementation object. + Impl& mutable_impl() { return impl_; } + + // Returns an immutable reference to the underlying matcher + // implementation object. + const Impl& impl() const { return impl_; } + + template + operator Matcher() const { + return Matcher(new MonomorphicImpl(impl_)); + } + + private: + template + class MonomorphicImpl : public MatcherInterface { + public: + explicit MonomorphicImpl(const Impl& impl) : impl_(impl) {} + + virtual void DescribeTo(::std::ostream* os) const { + impl_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + impl_.DescribeNegationTo(os); + } + + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + return impl_.MatchAndExplain(x, listener); + } + + private: + const Impl impl_; + + GTEST_DISALLOW_ASSIGN_(MonomorphicImpl); + }; + + Impl impl_; + + GTEST_DISALLOW_ASSIGN_(PolymorphicMatcher); +}; + +// Creates a matcher from its implementation. This is easier to use +// than the Matcher constructor as it doesn't require you to +// explicitly write the template argument, e.g. +// +// MakeMatcher(foo); +// vs +// Matcher(foo); +template +inline Matcher MakeMatcher(const MatcherInterface* impl) { + return Matcher(impl); +} + +// Creates a polymorphic matcher from its implementation. This is +// easier to use than the PolymorphicMatcher constructor as it +// doesn't require you to explicitly write the template argument, e.g. +// +// MakePolymorphicMatcher(foo); +// vs +// PolymorphicMatcher(foo); +template +inline PolymorphicMatcher MakePolymorphicMatcher(const Impl& impl) { + return PolymorphicMatcher(impl); +} + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// The MatcherCastImpl class template is a helper for implementing +// MatcherCast(). We need this helper in order to partially +// specialize the implementation of MatcherCast() (C++ allows +// class/struct templates to be partially specialized, but not +// function templates.). + +// This general version is used when MatcherCast()'s argument is a +// polymorphic matcher (i.e. something that can be converted to a +// Matcher but is not one yet; for example, Eq(value)) or a value (for +// example, "hello"). +template +class MatcherCastImpl { + public: + static Matcher Cast(const M& polymorphic_matcher_or_value) { + // M can be a polymorhic matcher, in which case we want to use + // its conversion operator to create Matcher. Or it can be a value + // that should be passed to the Matcher's constructor. + // + // We can't call Matcher(polymorphic_matcher_or_value) when M is a + // polymorphic matcher because it'll be ambiguous if T has an implicit + // constructor from M (this usually happens when T has an implicit + // constructor from any type). + // + // It won't work to unconditionally implict_cast + // polymorphic_matcher_or_value to Matcher because it won't trigger + // a user-defined conversion from M to T if one exists (assuming M is + // a value). + return CastImpl( + polymorphic_matcher_or_value, + BooleanConstant< + internal::ImplicitlyConvertible >::value>()); + } + + private: + static Matcher CastImpl(const M& value, BooleanConstant) { + // M can't be implicitly converted to Matcher, so M isn't a polymorphic + // matcher. It must be a value then. Use direct initialization to create + // a matcher. + return Matcher(ImplicitCast_(value)); + } + + static Matcher CastImpl(const M& polymorphic_matcher_or_value, + BooleanConstant) { + // M is implicitly convertible to Matcher, which means that either + // M is a polymorhpic matcher or Matcher has an implicit constructor + // from M. In both cases using the implicit conversion will produce a + // matcher. + // + // Even if T has an implicit constructor from M, it won't be called because + // creating Matcher would require a chain of two user-defined conversions + // (first to create T from M and then to create Matcher from T). + return polymorphic_matcher_or_value; + } +}; + +// This more specialized version is used when MatcherCast()'s argument +// is already a Matcher. This only compiles when type T can be +// statically converted to type U. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& source_matcher) { + return Matcher(new Impl(source_matcher)); + } + + private: + class Impl : public MatcherInterface { + public: + explicit Impl(const Matcher& source_matcher) + : source_matcher_(source_matcher) {} + + // We delegate the matching logic to the source matcher. + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + return source_matcher_.MatchAndExplain(static_cast(x), listener); + } + + virtual void DescribeTo(::std::ostream* os) const { + source_matcher_.DescribeTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + source_matcher_.DescribeNegationTo(os); + } + + private: + const Matcher source_matcher_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; +}; + +// This even more specialized version is used for efficiently casting +// a matcher to its own type. +template +class MatcherCastImpl > { + public: + static Matcher Cast(const Matcher& matcher) { return matcher; } +}; + +} // namespace internal + +// In order to be safe and clear, casting between different matcher +// types is done explicitly via MatcherCast(m), which takes a +// matcher m and returns a Matcher. It compiles only when T can be +// statically converted to the argument type of m. +template +inline Matcher MatcherCast(const M& matcher) { + return internal::MatcherCastImpl::Cast(matcher); +} + +// Implements SafeMatcherCast(). +// +// We use an intermediate class to do the actual safe casting as Nokia's +// Symbian compiler cannot decide between +// template ... (M) and +// template ... (const Matcher&) +// for function templates but can for member function templates. +template +class SafeMatcherCastImpl { + public: + // This overload handles polymorphic matchers and values only since + // monomorphic matchers are handled by the next one. + template + static inline Matcher Cast(const M& polymorphic_matcher_or_value) { + return internal::MatcherCastImpl::Cast(polymorphic_matcher_or_value); + } + + // This overload handles monomorphic matchers. + // + // In general, if type T can be implicitly converted to type U, we can + // safely convert a Matcher to a Matcher (i.e. Matcher is + // contravariant): just keep a copy of the original Matcher, convert the + // argument from type T to U, and then pass it to the underlying Matcher. + // The only exception is when U is a reference and T is not, as the + // underlying Matcher may be interested in the argument's address, which + // is not preserved in the conversion from T to U. + template + static inline Matcher Cast(const Matcher& matcher) { + // Enforce that T can be implicitly converted to U. + GTEST_COMPILE_ASSERT_((internal::ImplicitlyConvertible::value), + T_must_be_implicitly_convertible_to_U); + // Enforce that we are not converting a non-reference type T to a reference + // type U. + GTEST_COMPILE_ASSERT_( + internal::is_reference::value || !internal::is_reference::value, + cannot_convert_non_referentce_arg_to_reference); + // In case both T and U are arithmetic types, enforce that the + // conversion is not lossy. + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(T) RawT; + typedef GTEST_REMOVE_REFERENCE_AND_CONST_(U) RawU; + const bool kTIsOther = GMOCK_KIND_OF_(RawT) == internal::kOther; + const bool kUIsOther = GMOCK_KIND_OF_(RawU) == internal::kOther; + GTEST_COMPILE_ASSERT_( + kTIsOther || kUIsOther || + (internal::LosslessArithmeticConvertible::value), + conversion_of_arithmetic_types_must_be_lossless); + return MatcherCast(matcher); + } +}; + +template +inline Matcher SafeMatcherCast(const M& polymorphic_matcher) { + return SafeMatcherCastImpl::Cast(polymorphic_matcher); +} + +// A() returns a matcher that matches any value of type T. +template +Matcher A(); + +// Anything inside the 'internal' namespace IS INTERNAL IMPLEMENTATION +// and MUST NOT BE USED IN USER CODE!!! +namespace internal { + +// If the explanation is not empty, prints it to the ostream. +inline void PrintIfNotEmpty(const std::string& explanation, + ::std::ostream* os) { + if (explanation != "" && os != NULL) { + *os << ", " << explanation; + } +} + +// Returns true if the given type name is easy to read by a human. +// This is used to decide whether printing the type of a value might +// be helpful. +inline bool IsReadableTypeName(const std::string& type_name) { + // We consider a type name readable if it's short or doesn't contain + // a template or function type. + return (type_name.length() <= 20 || + type_name.find_first_of("<(") == std::string::npos); +} + +// Matches the value against the given matcher, prints the value and explains +// the match result to the listener. Returns the match result. +// 'listener' must not be NULL. +// Value cannot be passed by const reference, because some matchers take a +// non-const argument. +template +bool MatchPrintAndExplain(Value& value, const Matcher& matcher, + MatchResultListener* listener) { + if (!listener->IsInterested()) { + // If the listener is not interested, we do not need to construct the + // inner explanation. + return matcher.Matches(value); + } + + StringMatchResultListener inner_listener; + const bool match = matcher.MatchAndExplain(value, &inner_listener); + + UniversalPrint(value, listener->stream()); +#if GTEST_HAS_RTTI + const std::string& type_name = GetTypeName(); + if (IsReadableTypeName(type_name)) + *listener->stream() << " (of type " << type_name << ")"; +#endif + PrintIfNotEmpty(inner_listener.str(), listener->stream()); + + return match; +} + +// An internal helper class for doing compile-time loop on a tuple's +// fields. +template +class TuplePrefix { + public: + // TuplePrefix::Matches(matcher_tuple, value_tuple) returns true + // iff the first N fields of matcher_tuple matches the first N + // fields of value_tuple, respectively. + template + static bool Matches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + return TuplePrefix::Matches(matcher_tuple, value_tuple) + && get(matcher_tuple).Matches(get(value_tuple)); + } + + // TuplePrefix::ExplainMatchFailuresTo(matchers, values, os) + // describes failures in matching the first N fields of matchers + // against the first N fields of values. If there is no failure, + // nothing will be streamed to os. + template + static void ExplainMatchFailuresTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + // First, describes failures in the first N - 1 fields. + TuplePrefix::ExplainMatchFailuresTo(matchers, values, os); + + // Then describes the failure (if any) in the (N - 1)-th (0-based) + // field. + typename tuple_element::type matcher = + get(matchers); + typedef typename tuple_element::type Value; + Value value = get(values); + StringMatchResultListener listener; + if (!matcher.MatchAndExplain(value, &listener)) { + // TODO(wan): include in the message the name of the parameter + // as used in MOCK_METHOD*() when possible. + *os << " Expected arg #" << N - 1 << ": "; + get(matchers).DescribeTo(os); + *os << "\n Actual: "; + // We remove the reference in type Value to prevent the + // universal printer from printing the address of value, which + // isn't interesting to the user most of the time. The + // matcher's MatchAndExplain() method handles the case when + // the address is interesting. + internal::UniversalPrint(value, os); + PrintIfNotEmpty(listener.str(), os); + *os << "\n"; + } + } +}; + +// The base case. +template <> +class TuplePrefix<0> { + public: + template + static bool Matches(const MatcherTuple& /* matcher_tuple */, + const ValueTuple& /* value_tuple */) { + return true; + } + + template + static void ExplainMatchFailuresTo(const MatcherTuple& /* matchers */, + const ValueTuple& /* values */, + ::std::ostream* /* os */) {} +}; + +// TupleMatches(matcher_tuple, value_tuple) returns true iff all +// matchers in matcher_tuple match the corresponding fields in +// value_tuple. It is a compiler error if matcher_tuple and +// value_tuple have different number of fields or incompatible field +// types. +template +bool TupleMatches(const MatcherTuple& matcher_tuple, + const ValueTuple& value_tuple) { + // Makes sure that matcher_tuple and value_tuple have the same + // number of fields. + GTEST_COMPILE_ASSERT_(tuple_size::value == + tuple_size::value, + matcher_and_value_have_different_numbers_of_fields); + return TuplePrefix::value>:: + Matches(matcher_tuple, value_tuple); +} + +// Describes failures in matching matchers against values. If there +// is no failure, nothing will be streamed to os. +template +void ExplainMatchFailureTupleTo(const MatcherTuple& matchers, + const ValueTuple& values, + ::std::ostream* os) { + TuplePrefix::value>::ExplainMatchFailuresTo( + matchers, values, os); +} + +// TransformTupleValues and its helper. +// +// TransformTupleValuesHelper hides the internal machinery that +// TransformTupleValues uses to implement a tuple traversal. +template +class TransformTupleValuesHelper { + private: + typedef ::testing::tuple_size TupleSize; + + public: + // For each member of tuple 't', taken in order, evaluates '*out++ = f(t)'. + // Returns the final value of 'out' in case the caller needs it. + static OutIter Run(Func f, const Tuple& t, OutIter out) { + return IterateOverTuple()(f, t, out); + } + + private: + template + struct IterateOverTuple { + OutIter operator() (Func f, const Tup& t, OutIter out) const { + *out++ = f(::testing::get(t)); + return IterateOverTuple()(f, t, out); + } + }; + template + struct IterateOverTuple { + OutIter operator() (Func /* f */, const Tup& /* t */, OutIter out) const { + return out; + } + }; +}; + +// Successively invokes 'f(element)' on each element of the tuple 't', +// appending each result to the 'out' iterator. Returns the final value +// of 'out'. +template +OutIter TransformTupleValues(Func f, const Tuple& t, OutIter out) { + return TransformTupleValuesHelper::Run(f, t, out); +} + +// Implements A(). +template +class AnyMatcherImpl : public MatcherInterface { + public: + virtual bool MatchAndExplain( + T /* x */, MatchResultListener* /* listener */) const { return true; } + virtual void DescribeTo(::std::ostream* os) const { *os << "is anything"; } + virtual void DescribeNegationTo(::std::ostream* os) const { + // This is mostly for completeness' safe, as it's not very useful + // to write Not(A()). However we cannot completely rule out + // such a possibility, and it doesn't hurt to be prepared. + *os << "never matches"; + } +}; + +// Implements _, a matcher that matches any value of any +// type. This is a polymorphic matcher, so we need a template type +// conversion operator to make it appearing as a Matcher for any +// type T. +class AnythingMatcher { + public: + template + operator Matcher() const { return A(); } +}; + +// Implements a matcher that compares a given value with a +// pre-supplied value using one of the ==, <=, <, etc, operators. The +// two values being compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq(5) can be +// used to match an int, a short, a double, etc). Therefore we use +// a template type conversion operator in the implementation. +// +// The following template definition assumes that the Rhs parameter is +// a "bare" type (i.e. neither 'const T' nor 'T&'). +template +class ComparisonBase { + public: + explicit ComparisonBase(const Rhs& rhs) : rhs_(rhs) {} + template + operator Matcher() const { + return MakeMatcher(new Impl(rhs_)); + } + + private: + template + class Impl : public MatcherInterface { + public: + explicit Impl(const Rhs& rhs) : rhs_(rhs) {} + virtual bool MatchAndExplain( + Lhs lhs, MatchResultListener* /* listener */) const { + return Op()(lhs, rhs_); + } + virtual void DescribeTo(::std::ostream* os) const { + *os << D::Desc() << " "; + UniversalPrint(rhs_, os); + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << D::NegatedDesc() << " "; + UniversalPrint(rhs_, os); + } + private: + Rhs rhs_; + GTEST_DISALLOW_ASSIGN_(Impl); + }; + Rhs rhs_; + GTEST_DISALLOW_ASSIGN_(ComparisonBase); +}; + +template +class EqMatcher : public ComparisonBase, Rhs, AnyEq> { + public: + explicit EqMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyEq>(rhs) { } + static const char* Desc() { return "is equal to"; } + static const char* NegatedDesc() { return "isn't equal to"; } +}; +template +class NeMatcher : public ComparisonBase, Rhs, AnyNe> { + public: + explicit NeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyNe>(rhs) { } + static const char* Desc() { return "isn't equal to"; } + static const char* NegatedDesc() { return "is equal to"; } +}; +template +class LtMatcher : public ComparisonBase, Rhs, AnyLt> { + public: + explicit LtMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyLt>(rhs) { } + static const char* Desc() { return "is <"; } + static const char* NegatedDesc() { return "isn't <"; } +}; +template +class GtMatcher : public ComparisonBase, Rhs, AnyGt> { + public: + explicit GtMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyGt>(rhs) { } + static const char* Desc() { return "is >"; } + static const char* NegatedDesc() { return "isn't >"; } +}; +template +class LeMatcher : public ComparisonBase, Rhs, AnyLe> { + public: + explicit LeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyLe>(rhs) { } + static const char* Desc() { return "is <="; } + static const char* NegatedDesc() { return "isn't <="; } +}; +template +class GeMatcher : public ComparisonBase, Rhs, AnyGe> { + public: + explicit GeMatcher(const Rhs& rhs) + : ComparisonBase, Rhs, AnyGe>(rhs) { } + static const char* Desc() { return "is >="; } + static const char* NegatedDesc() { return "isn't >="; } +}; + +// Implements the polymorphic IsNull() matcher, which matches any raw or smart +// pointer that is NULL. +class IsNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { +#if GTEST_LANG_CXX11 + return p == nullptr; +#else // GTEST_LANG_CXX11 + return GetRawPointer(p) == NULL; +#endif // GTEST_LANG_CXX11 + } + + void DescribeTo(::std::ostream* os) const { *os << "is NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "isn't NULL"; + } +}; + +// Implements the polymorphic NotNull() matcher, which matches any raw or smart +// pointer that is not NULL. +class NotNullMatcher { + public: + template + bool MatchAndExplain(const Pointer& p, + MatchResultListener* /* listener */) const { +#if GTEST_LANG_CXX11 + return p != nullptr; +#else // GTEST_LANG_CXX11 + return GetRawPointer(p) != NULL; +#endif // GTEST_LANG_CXX11 + } + + void DescribeTo(::std::ostream* os) const { *os << "isn't NULL"; } + void DescribeNegationTo(::std::ostream* os) const { + *os << "is NULL"; + } +}; + +// Ref(variable) matches any argument that is a reference to +// 'variable'. This matcher is polymorphic as it can match any +// super type of the type of 'variable'. +// +// The RefMatcher template class implements Ref(variable). It can +// only be instantiated with a reference type. This prevents a user +// from mistakenly using Ref(x) to match a non-reference function +// argument. For example, the following will righteously cause a +// compiler error: +// +// int n; +// Matcher m1 = Ref(n); // This won't compile. +// Matcher m2 = Ref(n); // This will compile. +template +class RefMatcher; + +template +class RefMatcher { + // Google Mock is a generic framework and thus needs to support + // mocking any function types, including those that take non-const + // reference arguments. Therefore the template parameter T (and + // Super below) can be instantiated to either a const type or a + // non-const type. + public: + // RefMatcher() takes a T& instead of const T&, as we want the + // compiler to catch using Ref(const_value) as a matcher for a + // non-const reference. + explicit RefMatcher(T& x) : object_(x) {} // NOLINT + + template + operator Matcher() const { + // By passing object_ (type T&) to Impl(), which expects a Super&, + // we make sure that Super is a super type of T. In particular, + // this catches using Ref(const_value) as a matcher for a + // non-const reference, as you cannot implicitly convert a const + // reference to a non-const reference. + return MakeMatcher(new Impl(object_)); + } + + private: + template + class Impl : public MatcherInterface { + public: + explicit Impl(Super& x) : object_(x) {} // NOLINT + + // MatchAndExplain() takes a Super& (as opposed to const Super&) + // in order to match the interface MatcherInterface. + virtual bool MatchAndExplain( + Super& x, MatchResultListener* listener) const { + *listener << "which is located @" << static_cast(&x); + return &x == &object_; + } + + virtual void DescribeTo(::std::ostream* os) const { + *os << "references the variable "; + UniversalPrinter::Print(object_, os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "does not reference the variable "; + UniversalPrinter::Print(object_, os); + } + + private: + const Super& object_; + + GTEST_DISALLOW_ASSIGN_(Impl); + }; + + T& object_; + + GTEST_DISALLOW_ASSIGN_(RefMatcher); +}; + +// Polymorphic helper functions for narrow and wide string matchers. +inline bool CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) { + return String::CaseInsensitiveCStringEquals(lhs, rhs); +} + +inline bool CaseInsensitiveCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + return String::CaseInsensitiveWideCStringEquals(lhs, rhs); +} + +// String comparison for narrow or wide strings that can have embedded NUL +// characters. +template +bool CaseInsensitiveStringEquals(const StringType& s1, + const StringType& s2) { + // Are the heads equal? + if (!CaseInsensitiveCStringEquals(s1.c_str(), s2.c_str())) { + return false; + } + + // Skip the equal heads. + const typename StringType::value_type nul = 0; + const size_t i1 = s1.find(nul), i2 = s2.find(nul); + + // Are we at the end of either s1 or s2? + if (i1 == StringType::npos || i2 == StringType::npos) { + return i1 == i2; + } + + // Are the tails equal? + return CaseInsensitiveStringEquals(s1.substr(i1 + 1), s2.substr(i2 + 1)); +} + +// String matchers. + +// Implements equality-based string matchers like StrEq, StrCaseNe, and etc. +template +class StrEqualityMatcher { + public: + StrEqualityMatcher(const StringType& str, bool expect_eq, + bool case_sensitive) + : string_(str), expect_eq_(expect_eq), case_sensitive_(case_sensitive) {} + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + if (s == NULL) { + return !expect_eq_; + } + return MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + const bool eq = case_sensitive_ ? s2 == string_ : + CaseInsensitiveStringEquals(s2, string_); + return expect_eq_ == eq; + } + + void DescribeTo(::std::ostream* os) const { + DescribeToHelper(expect_eq_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + DescribeToHelper(!expect_eq_, os); + } + + private: + void DescribeToHelper(bool expect_eq, ::std::ostream* os) const { + *os << (expect_eq ? "is " : "isn't "); + *os << "equal to "; + if (!case_sensitive_) { + *os << "(ignoring case) "; + } + UniversalPrint(string_, os); + } + + const StringType string_; + const bool expect_eq_; + const bool case_sensitive_; + + GTEST_DISALLOW_ASSIGN_(StrEqualityMatcher); +}; + +// Implements the polymorphic HasSubstr(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class HasSubstrMatcher { + public: + explicit HasSubstrMatcher(const StringType& substring) + : substring_(substring) {} + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.find(substring_) != StringType::npos; + } + + // Describes what this matcher matches. + void DescribeTo(::std::ostream* os) const { + *os << "has substring "; + UniversalPrint(substring_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "has no substring "; + UniversalPrint(substring_, os); + } + + private: + const StringType substring_; + + GTEST_DISALLOW_ASSIGN_(HasSubstrMatcher); +}; + +// Implements the polymorphic StartsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class StartsWithMatcher { + public: + explicit StartsWithMatcher(const StringType& prefix) : prefix_(prefix) { + } + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= prefix_.length() && + s2.substr(0, prefix_.length()) == prefix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "starts with "; + UniversalPrint(prefix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't start with "; + UniversalPrint(prefix_, os); + } + + private: + const StringType prefix_; + + GTEST_DISALLOW_ASSIGN_(StartsWithMatcher); +}; + +// Implements the polymorphic EndsWith(substring) matcher, which +// can be used as a Matcher as long as T can be converted to a +// string. +template +class EndsWithMatcher { + public: + explicit EndsWithMatcher(const StringType& suffix) : suffix_(suffix) {} + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(StringType(s), listener); + } + + // Matches anything that can convert to StringType. + // + // This is a template, not just a plain function with const StringType&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const StringType& s2(s); + return s2.length() >= suffix_.length() && + s2.substr(s2.length() - suffix_.length()) == suffix_; + } + + void DescribeTo(::std::ostream* os) const { + *os << "ends with "; + UniversalPrint(suffix_, os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't end with "; + UniversalPrint(suffix_, os); + } + + private: + const StringType suffix_; + + GTEST_DISALLOW_ASSIGN_(EndsWithMatcher); +}; + +// Implements polymorphic matchers MatchesRegex(regex) and +// ContainsRegex(regex), which can be used as a Matcher as long as +// T can be converted to a string. +class MatchesRegexMatcher { + public: + MatchesRegexMatcher(const RE* regex, bool full_match) + : regex_(regex), full_match_(full_match) {} + + // Accepts pointer types, particularly: + // const char* + // char* + // const wchar_t* + // wchar_t* + template + bool MatchAndExplain(CharType* s, MatchResultListener* listener) const { + return s != NULL && MatchAndExplain(std::string(s), listener); + } + + // Matches anything that can convert to std::string. + // + // This is a template, not just a plain function with const std::string&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const std::string& s2(s); + return full_match_ ? RE::FullMatch(s2, *regex_) : + RE::PartialMatch(s2, *regex_); + } + + void DescribeTo(::std::ostream* os) const { + *os << (full_match_ ? "matches" : "contains") + << " regular expression "; + UniversalPrinter::Print(regex_->pattern(), os); + } + + void DescribeNegationTo(::std::ostream* os) const { + *os << "doesn't " << (full_match_ ? "match" : "contain") + << " regular expression "; + UniversalPrinter::Print(regex_->pattern(), os); + } + + private: + const internal::linked_ptr regex_; + const bool full_match_; + + GTEST_DISALLOW_ASSIGN_(MatchesRegexMatcher); +}; + +// Implements a matcher that compares the two fields of a 2-tuple +// using one of the ==, <=, <, etc, operators. The two fields being +// compared don't have to have the same type. +// +// The matcher defined here is polymorphic (for example, Eq() can be +// used to match a tuple, a tuple, +// etc). Therefore we use a template type conversion operator in the +// implementation. +template +class PairMatchBase { + public: + template + operator Matcher< ::testing::tuple >() const { + return MakeMatcher(new Impl< ::testing::tuple >); + } + template + operator Matcher&>() const { + return MakeMatcher(new Impl&>); + } + + private: + static ::std::ostream& GetDesc(::std::ostream& os) { // NOLINT + return os << D::Desc(); + } + + template + class Impl : public MatcherInterface { + public: + virtual bool MatchAndExplain( + Tuple args, + MatchResultListener* /* listener */) const { + return Op()(::testing::get<0>(args), ::testing::get<1>(args)); + } + virtual void DescribeTo(::std::ostream* os) const { + *os << "are " << GetDesc; + } + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "aren't " << GetDesc; + } + }; +}; + +class Eq2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an equal pair"; } +}; +class Ne2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "an unequal pair"; } +}; +class Lt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first < the second"; } +}; +class Gt2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first > the second"; } +}; +class Le2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first <= the second"; } +}; +class Ge2Matcher : public PairMatchBase { + public: + static const char* Desc() { return "a pair where the first >= the second"; } +}; + +// Implements the Not(...) matcher for a particular argument type T. +// We do not nest it inside the NotMatcher class template, as that +// will prevent different instantiations of NotMatcher from sharing +// the same NotMatcherImpl class. +template +class NotMatcherImpl : public MatcherInterface { + public: + explicit NotMatcherImpl(const Matcher& matcher) + : matcher_(matcher) {} + + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + return !matcher_.MatchAndExplain(x, listener); + } + + virtual void DescribeTo(::std::ostream* os) const { + matcher_.DescribeNegationTo(os); + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + matcher_.DescribeTo(os); + } + + private: + const Matcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcherImpl); +}; + +// Implements the Not(m) matcher, which matches a value that doesn't +// match matcher m. +template +class NotMatcher { + public: + explicit NotMatcher(InnerMatcher matcher) : matcher_(matcher) {} + + // This template type conversion operator allows Not(m) to be used + // to match any type m can match. + template + operator Matcher() const { + return Matcher(new NotMatcherImpl(SafeMatcherCast(matcher_))); + } + + private: + InnerMatcher matcher_; + + GTEST_DISALLOW_ASSIGN_(NotMatcher); +}; + +// Implements the AllOf(m1, m2) matcher for a particular argument type +// T. We do not nest it inside the BothOfMatcher class template, as +// that will prevent different instantiations of BothOfMatcher from +// sharing the same BothOfMatcherImpl class. +template +class BothOfMatcherImpl : public MatcherInterface { + public: + BothOfMatcherImpl(const Matcher& matcher1, const Matcher& matcher2) + : matcher1_(matcher1), matcher2_(matcher2) {} + + virtual void DescribeTo(::std::ostream* os) const { + *os << "("; + matcher1_.DescribeTo(os); + *os << ") and ("; + matcher2_.DescribeTo(os); + *os << ")"; + } + + virtual void DescribeNegationTo(::std::ostream* os) const { + *os << "("; + matcher1_.DescribeNegationTo(os); + *os << ") or ("; + matcher2_.DescribeNegationTo(os); + *os << ")"; + } + + virtual bool MatchAndExplain(T x, MatchResultListener* listener) const { + // If either matcher1_ or matcher2_ doesn't match x, we only need + // to explain why one of them fails. + StringMatchResultListener listener1; + if (!matcher1_.MatchAndExplain(x, &listener1)) { + *listener << listener1.str(); + return false; + } + + StringMatchResultListener listener2; + if (!matcher2_.MatchAndExplain(x, &listener2)) { + *listener << listener2.str(); + return false; + } + + // Otherwise we need to explain why *both* of them match. + const std::string s1 = listener1.str(); + const std::string s2 = listener2.str(); + + if (s1 == "") { + *listener << s2; + } else { + *listener << s1; + if (s2 != "") { + *listener << ", and " << s2; + } + } + return true; + } + + private: + const Matcher matcher1_; + const Matcher matcher2_; + + GTEST_DISALLOW_ASSIGN_(BothOfMatcherImpl); +}; + +#if GTEST_LANG_CXX11 +// MatcherList provides mechanisms for storing a variable number of matchers in +// a list structure (ListType) and creating a combining matcher from such a +// list. +// The template is defined recursively using the following template paramters: +// * kSize is the length of the MatcherList. +// * Head is the type of the first matcher of the list. +// * Tail denotes the types of the remaining matchers of the list. +template +struct MatcherList { + typedef MatcherList MatcherListTail; + typedef ::std::pair ListType; + + // BuildList stores variadic type values in a nested pair structure. + // Example: + // MatcherList<3, int, string, float>::BuildList(5, "foo", 2.0) will return + // the corresponding result of type pair>. + static ListType BuildList(const Head& matcher, const Tail&... tail) { + return ListType(matcher, MatcherListTail::BuildList(tail...)); + } + + // CreateMatcher creates a Matcher from a given list of matchers (built + // by BuildList()). CombiningMatcher is used to combine the matchers of the + // list. CombiningMatcher must implement MatcherInterface and have a + // constructor taking two Matchers as input. + template class CombiningMatcher> + static Matcher CreateMatcher(const ListType& matchers) { + return Matcher(new CombiningMatcher( + SafeMatcherCast(matchers.first), + MatcherListTail::template CreateMatcher( + matchers.second))); + } +}; + +// The following defines the base case for the recursive definition of +// MatcherList. +template +struct MatcherList<2, Matcher1, Matcher2> { + typedef ::std::pair ListType; + + static ListType BuildList(const Matcher1& matcher1, + const Matcher2& matcher2) { + return ::std::pair(matcher1, matcher2); + } + + template class CombiningMatcher> + static Matcher CreateMatcher(const ListType& matchers) { + return Matcher(new CombiningMatcher( + SafeMatcherCast(matchers.first), + SafeMatcherCast(matchers.second))); + } +}; + +// VariadicMatcher is used for the variadic implementation of +// AllOf(m_1, m_2, ...) and AnyOf(m_1, m_2, ...). +// CombiningMatcher is used to recursively combine the provided matchers +// (of type Args...). +template