From d155550ca2bd773d4bf3761301c93d07b345f9d2 Mon Sep 17 00:00:00 2001 From: Seonah Moon Date: Wed, 23 Dec 2020 13:54:58 +0900 Subject: [PATCH] Revert "Revert "Imported Upstream version 1.17.1"" This reverts commit 62cb64b22c599fa9c2c7d864569c017b55100279. --- AUTHORS | 2 + CHANGES | 6221 +++-- CMakeLists.txt | 738 + CONTRIBUTING.md | 15 + INSTALL | 328 - INSTALL.md | 410 + LICENSE.md | 2 +- Makefile.Watcom | 2 +- Makefile.am | 202 +- Makefile.dj | 119 +- Makefile.in | 1422 +- Makefile.inc | 237 - Makefile.m32 | 33 +- Makefile.msvc | 82 +- Makefile.netware | 6 +- README.md | 9 +- README.msvc | 44 +- RELEASE-NOTES | 97 +- SECURITY.md | 100 + aclocal.m4 | 193 +- ares_cancel.pdf | Bin 15981 -> 0 bytes ares_create_query.pdf | Bin 21150 -> 0 bytes ares_destroy.pdf | Bin 17145 -> 0 bytes ares_destroy_options.pdf | Bin 16747 -> 0 bytes ares_dup.pdf | Bin 17284 -> 0 bytes ares_expand_name.pdf | Bin 19482 -> 0 bytes ares_expand_string.pdf | Bin 17611 -> 0 bytes ares_fds.pdf | Bin 17835 -> 0 bytes ares_free_data.pdf | Bin 18022 -> 0 bytes ares_free_hostent.pdf | Bin 17772 -> 0 bytes ares_free_string.pdf | Bin 16518 -> 0 bytes ares_get_servers.pdf | Bin 19990 -> 0 bytes ares_get_servers_ports.pdf | Bin 2217 -> 0 bytes ares_gethostbyaddr.pdf | Bin 21563 -> 0 bytes ares_gethostbyname.pdf | Bin 21928 -> 0 bytes ares_gethostbyname_file.pdf | Bin 20979 -> 0 bytes ares_getnameinfo.pdf | Bin 24409 -> 0 bytes ares_getsock.pdf | Bin 19171 -> 0 bytes ares_inet_ntop.pdf | Bin 17320 -> 0 bytes ares_inet_pton.pdf | Bin 16607 -> 0 bytes ares_init.pdf | Bin 19730 -> 0 bytes ares_init_options.pdf | Bin 32448 -> 0 bytes ares_library_cleanup.pdf | Bin 22301 -> 0 bytes ares_library_init.pdf | Bin 25121 -> 0 bytes ares_mkquery.pdf | Bin 22034 -> 0 bytes ares_parse_a_reply.c | 264 - ares_parse_a_reply.pdf | Bin 19043 -> 0 bytes ares_parse_aaaa_reply.c | 264 - ares_parse_aaaa_reply.pdf | Bin 18910 -> 0 bytes ares_parse_mx_reply.pdf | Bin 20153 -> 0 bytes ares_parse_ns_reply.pdf | Bin 18328 -> 0 bytes ares_parse_ptr_reply.pdf | Bin 19362 -> 0 bytes ares_parse_soa_reply.c | 133 - ares_parse_soa_reply.pdf | Bin 18795 -> 0 bytes ares_parse_srv_reply.pdf | Bin 20049 -> 0 bytes ares_parse_txt_reply.pdf | Bin 22142 -> 0 bytes ares_process.pdf | Bin 21140 -> 0 bytes ares_query.pdf | Bin 23703 -> 0 bytes ares_save_options.pdf | Bin 19626 -> 0 bytes ares_search.pdf | Bin 23691 -> 0 bytes ares_send.pdf | Bin 21752 -> 0 bytes ares_set_local_dev.pdf | Bin 17319 -> 0 bytes ares_set_local_ip4.pdf | Bin 16005 -> 0 bytes ares_set_local_ip6.pdf | Bin 16600 -> 0 bytes ares_set_servers.pdf | Bin 20124 -> 0 bytes ares_set_servers_csv.pdf | Bin 18503 -> 0 bytes ares_set_servers_ports.pdf | Bin 2217 -> 0 bytes ares_set_servers_ports_csv.pdf | Bin 2217 -> 0 bytes ares_set_socket_callback.pdf | Bin 19226 -> 0 bytes ares_set_socket_configure_callback.pdf | Bin 19138 -> 0 bytes ares_set_sortlist.pdf | Bin 17856 -> 0 bytes ares_strerror.pdf | Bin 15058 -> 0 bytes ares_timeout.pdf | Bin 18550 -> 0 bytes ares_version.pdf | Bin 16431 -> 0 bytes buildconf | 297 +- buildconf.bat | 20 + c-ares-config.cmake.in | 21 + compile | 17 +- config.guess | 679 +- config.sub | 284 +- configure | 582 +- configure.ac | 179 +- depcomp | 10 +- docs/CMakeLists.txt | 17 + docs/Makefile.am | 11 + docs/Makefile.in | 625 + docs/Makefile.inc | 58 + acountry.1 => docs/acountry.1 | 3 +- adig.1 => docs/adig.1 | 16 +- ahost.1 => docs/ahost.1 | 3 +- ares_cancel.3 => docs/ares_cancel.3 | 6 +- .../ares_create_query.3 | 7 + ares_destroy.3 => docs/ares_destroy.3 | 8 +- .../ares_destroy_options.3 | 0 ares_dup.3 => docs/ares_dup.3 | 0 ares_expand_name.3 => docs/ares_expand_name.3 | 0 .../ares_expand_string.3 | 0 ares_fds.3 => docs/ares_fds.3 | 47 +- ares_free_data.3 => docs/ares_free_data.3 | 0 .../ares_free_hostent.3 | 0 ares_free_string.3 => docs/ares_free_string.3 | 0 docs/ares_freeaddrinfo.3 | 37 + ares_get_servers.3 => docs/ares_get_servers.3 | 0 .../ares_get_servers_ports.3 | 0 docs/ares_getaddrinfo.3 | 195 + .../ares_gethostbyaddr.3 | 0 .../ares_gethostbyname.3 | 7 +- .../ares_gethostbyname_file.3 | 0 ares_getnameinfo.3 => docs/ares_getnameinfo.3 | 0 ares_getsock.3 => docs/ares_getsock.3 | 0 ares_inet_ntop.3 => docs/ares_inet_ntop.3 | 0 ares_inet_pton.3 => docs/ares_inet_pton.3 | 0 ares_init.3 => docs/ares_init.3 | 0 .../ares_init_options.3 | 43 +- .../ares_library_cleanup.3 | 8 +- .../ares_library_init.3 | 3 + docs/ares_library_init_android.3 | 142 + docs/ares_library_initialized.3 | 34 + ares_mkquery.3 => docs/ares_mkquery.3 | 7 + .../ares_parse_a_reply.3 | 2 + .../ares_parse_aaaa_reply.3 | 2 + docs/ares_parse_caa_reply.3 | 171 + .../ares_parse_mx_reply.3 | 0 .../ares_parse_naptr_reply.3 | 0 .../ares_parse_ns_reply.3 | 0 .../ares_parse_ptr_reply.3 | 0 .../ares_parse_soa_reply.3 | 0 .../ares_parse_srv_reply.3 | 0 .../ares_parse_txt_reply.3 | 0 ares_process.3 => docs/ares_process.3 | 67 +- ares_query.3 => docs/ares_query.3 | 0 .../ares_save_options.3 | 0 ares_search.3 => docs/ares_search.3 | 0 ares_send.3 => docs/ares_send.3 | 0 .../ares_set_local_dev.3 | 4 +- .../ares_set_local_ip4.3 | 4 +- .../ares_set_local_ip6.3 | 5 +- ares_set_servers.3 => docs/ares_set_servers.3 | 3 + .../ares_set_servers_csv.3 | 3 + .../ares_set_servers_ports.3 | 0 .../ares_set_servers_ports_csv.3 | 0 .../ares_set_socket_callback.3 | 0 .../ares_set_socket_configure_callback.3 | 0 docs/ares_set_socket_functions.3 | 99 + .../ares_set_sortlist.3 | 0 ares_strerror.3 => docs/ares_strerror.3 | 0 ares_timeout.3 => docs/ares_timeout.3 | 49 +- ares_version.3 => docs/ares_version.3 | 23 +- include/CMakeLists.txt | 8 + include/Makefile.am | 7 + include/Makefile.in | 615 + ares.h => include/ares.h | 108 +- ares_build.h => include/ares_build.h | 13 + include/ares_build.h.cmake | 41 + ares_build.h.in => include/ares_build.h.in | 6 + ares_dns.h => include/ares_dns.h | 9 + ares_rules.h => include/ares_rules.h | 2 +- ares_version.h => include/ares_version.h | 8 +- install-sh | 410 +- libcares.pc.cmake | 20 + ltmain.sh | 217 +- m4/ax_code_coverage.m4 | 2 +- m4/cares-compilers.m4 | 91 - m4/cares-confopts.m4 | 40 - m4/cares-functions.m4 | 140 + m4/libtool.m4 | 46 +- m4/xc-cc-check.m4 | 2 +- maketgz | 26 +- missing | 16 +- mkinstalldirs | 162 - msvc_ver.inc | 24 + src/CMakeLists.txt | 2 + src/Makefile.am | 2 + src/Makefile.in | 658 + src/lib/CMakeLists.txt | 115 + src/lib/Makefile.am | 72 + src/lib/Makefile.in | 1596 ++ src/lib/Makefile.inc | 79 + .../lib/ares__close_sockets.c | 4 +- .../lib/ares__get_hostent.c | 3 +- src/lib/ares__parse_into_addrinfo.c | 266 + .../lib/ares__read_line.c | 0 src/lib/ares__readaddrinfo.c | 264 + src/lib/ares__sortaddrinfo.c | 495 + ares__timeval.c => src/lib/ares__timeval.c | 0 src/lib/ares_android.c | 444 + src/lib/ares_android.h | 27 + ares_cancel.c => src/lib/ares_cancel.c | 0 src/lib/ares_config.h.cmake | 432 + ares_config.h.in => src/lib/ares_config.h.in | 14 +- .../lib/ares_create_query.c | 12 +- ares_data.c => src/lib/ares_data.c | 165 +- ares_data.h => src/lib/ares_data.h | 2 + ares_destroy.c => src/lib/ares_destroy.c | 7 +- .../lib/ares_expand_name.c | 8 +- .../lib/ares_expand_string.c | 2 +- ares_fds.c => src/lib/ares_fds.c | 0 .../lib/ares_free_hostent.c | 0 .../lib/ares_free_string.c | 0 src/lib/ares_freeaddrinfo.c | 57 + src/lib/ares_getaddrinfo.c | 776 + ares_getenv.c => src/lib/ares_getenv.c | 2 - ares_getenv.h => src/lib/ares_getenv.h | 0 .../lib/ares_gethostbyaddr.c | 11 +- .../lib/ares_gethostbyname.c | 46 +- .../lib/ares_getnameinfo.c | 49 +- ares_getsock.c => src/lib/ares_getsock.c | 0 .../lib/ares_inet_net_pton.h | 0 ares_init.c => src/lib/ares_init.c | 736 +- ares_iphlpapi.h => src/lib/ares_iphlpapi.h | 0 ares_ipv6.h => src/lib/ares_ipv6.h | 7 + .../lib/ares_library_init.c | 34 +- .../lib/ares_library_init.h | 3 +- ares_llist.c => src/lib/ares_llist.c | 0 ares_llist.h => src/lib/ares_llist.h | 0 ares_mkquery.c => src/lib/ares_mkquery.c | 0 ares_nowarn.c => src/lib/ares_nowarn.c | 12 +- ares_nowarn.h => src/lib/ares_nowarn.h | 4 +- ares_options.c => src/lib/ares_options.c | 8 +- src/lib/ares_parse_a_reply.c | 215 + src/lib/ares_parse_aaaa_reply.c | 218 + src/lib/ares_parse_caa_reply.c | 209 + .../lib/ares_parse_mx_reply.c | 0 .../lib/ares_parse_naptr_reply.c | 8 +- .../lib/ares_parse_ns_reply.c | 0 .../lib/ares_parse_ptr_reply.c | 6 +- src/lib/ares_parse_soa_reply.c | 185 + .../lib/ares_parse_srv_reply.c | 0 .../lib/ares_parse_txt_reply.c | 2 +- ares_platform.c => src/lib/ares_platform.c | 7 + ares_platform.h => src/lib/ares_platform.h | 0 ares_private.h => src/lib/ares_private.h | 86 +- ares_process.c => src/lib/ares_process.c | 286 +- ares_query.c => src/lib/ares_query.c | 2 +- ares_search.c => src/lib/ares_search.c | 19 +- ares_send.c => src/lib/ares_send.c | 6 + ares_setup.h => src/lib/ares_setup.h | 0 .../lib/ares_strcasecmp.c | 0 .../lib/ares_strcasecmp.h | 0 ares_strdup.c => src/lib/ares_strdup.c | 0 ares_strdup.h => src/lib/ares_strdup.h | 0 ares_strerror.c => src/lib/ares_strerror.c | 0 src/lib/ares_strsplit.c | 174 + src/lib/ares_strsplit.h | 43 + ares_timeout.c => src/lib/ares_timeout.c | 0 ares_version.c => src/lib/ares_version.c | 0 ares_writev.c => src/lib/ares_writev.c | 4 +- ares_writev.h => src/lib/ares_writev.h | 2 +- bitncmp.c => src/lib/bitncmp.c | 0 bitncmp.h => src/lib/bitncmp.h | 0 cares.rc => src/lib/cares.rc | 2 +- config-dos.h => src/lib/config-dos.h | 12 +- config-win32.h => src/lib/config-win32.h | 42 +- inet_net_pton.c => src/lib/inet_net_pton.c | 4 +- inet_ntop.c => src/lib/inet_ntop.c | 5 +- nameser.h => src/lib/nameser.h | 7 + setup_once.h => src/lib/setup_once.h | 10 +- windows_port.c => src/lib/windows_port.c | 0 src/tools/CMakeLists.txt | 55 + src/tools/Makefile.am | 32 + src/tools/Makefile.in | 937 + src/tools/Makefile.inc | 7 + acountry.c => src/tools/acountry.c | 57 +- adig.c => src/tools/adig.c | 191 +- ahost.c => src/tools/ahost.c | 29 +- ares_getopt.c => src/tools/ares_getopt.c | 0 ares_getopt.h => src/tools/ares_getopt.h | 0 test/CMakeLists.txt | 73 + test/Makefile.am | 50 +- test/Makefile.in | 415 +- test/Makefile.inc | 9 +- test/Makefile.m32 | 61 + test/Makefile.msvc | 340 + test/README.md | 153 + test/aclocal.m4 | 191 +- test/ares-fuzz.c | 9 +- test/ares-test-ai.h | 57 + test/ares-test-fuzz-name.c | 23 + test/ares-test-fuzz.c | 11 +- test/ares-test-init.cc | 82 + test/ares-test-internal.cc | 224 +- test/ares-test-live.cc | 227 +- test/ares-test-main.cc | 6 + test/ares-test-misc.cc | 57 +- test/ares-test-mock-ai.cc | 777 + test/ares-test-mock.cc | 100 +- test/ares-test-parse-a.cc | 26 +- test/ares-test-parse-aaaa.cc | 3 +- test/ares-test-parse-caa.cc | 113 + test/ares-test-parse-naptr.cc | 29 + test/ares-test-parse-soa-any.cc | 111 + test/ares-test-parse-soa.cc | 2 +- test/ares-test.cc | 155 +- test/ares-test.h | 121 +- test/buildconf | 2 + test/compile | 348 + test/config.guess | 1480 ++ test/config.sub | 1801 ++ test/configure | 243 +- test/depcomp | 791 + test/dns-dump.cc | 7 +- test/dns-proto.cc | 17 +- test/fuzzcheck.sh | 5 + test/gmock-1.7.0/gtest/src/gtest-all.cc | 48 - test/gmock-1.7.0/src/gmock-all.cc | 47 - test/gmock-1.8.0/gmock-gtest-all.cc | 12265 +++++++++ test/gmock-1.8.0/gmock/gmock.h | 14978 +++++++++++ test/gmock-1.8.0/gtest/gtest.h | 21192 ++++++++++++++++ test/install-sh | 529 + test/ltmain.sh | 11251 ++++++++ test/missing | 215 + test-driver => test/test-driver | 10 +- vc/acountry/vc6acountry.dsp | 190 - vc/adig/vc6adig.dsp | 190 - vc/ahost/vc6ahost.dsp | 190 - vc/cares/vc6cares.dsp | 453 - vc/cares/vc6cares.dsw | 29 - vc/vc6aws.dsw | 74 - 318 files changed, 86087 insertions(+), 9703 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTING.md delete mode 100644 INSTALL create mode 100644 INSTALL.md delete mode 100644 Makefile.inc create mode 100644 SECURITY.md delete mode 100644 ares_cancel.pdf delete mode 100644 ares_create_query.pdf delete mode 100644 ares_destroy.pdf delete mode 100644 ares_destroy_options.pdf delete mode 100644 ares_dup.pdf delete mode 100644 ares_expand_name.pdf delete mode 100644 ares_expand_string.pdf delete mode 100644 ares_fds.pdf delete mode 100644 ares_free_data.pdf delete mode 100644 ares_free_hostent.pdf delete mode 100644 ares_free_string.pdf delete mode 100644 ares_get_servers.pdf delete mode 100644 ares_get_servers_ports.pdf delete mode 100644 ares_gethostbyaddr.pdf delete mode 100644 ares_gethostbyname.pdf delete mode 100644 ares_gethostbyname_file.pdf delete mode 100644 ares_getnameinfo.pdf delete mode 100644 ares_getsock.pdf delete mode 100644 ares_inet_ntop.pdf delete mode 100644 ares_inet_pton.pdf delete mode 100644 ares_init.pdf delete mode 100644 ares_init_options.pdf delete mode 100644 ares_library_cleanup.pdf delete mode 100644 ares_library_init.pdf delete mode 100644 ares_mkquery.pdf delete mode 100644 ares_parse_a_reply.c delete mode 100644 ares_parse_a_reply.pdf delete mode 100644 ares_parse_aaaa_reply.c delete mode 100644 ares_parse_aaaa_reply.pdf delete mode 100644 ares_parse_mx_reply.pdf delete mode 100644 ares_parse_ns_reply.pdf delete mode 100644 ares_parse_ptr_reply.pdf delete mode 100644 ares_parse_soa_reply.c delete mode 100644 ares_parse_soa_reply.pdf delete mode 100644 ares_parse_srv_reply.pdf delete mode 100644 ares_parse_txt_reply.pdf delete mode 100644 ares_process.pdf delete mode 100644 ares_query.pdf delete mode 100644 ares_save_options.pdf delete mode 100644 ares_search.pdf delete mode 100644 ares_send.pdf delete mode 100644 ares_set_local_dev.pdf delete mode 100644 ares_set_local_ip4.pdf delete mode 100644 ares_set_local_ip6.pdf delete mode 100644 ares_set_servers.pdf delete mode 100644 ares_set_servers_csv.pdf delete mode 100644 ares_set_servers_ports.pdf delete mode 100644 ares_set_servers_ports_csv.pdf delete mode 100644 ares_set_socket_callback.pdf delete mode 100644 ares_set_socket_configure_callback.pdf delete mode 100644 ares_set_sortlist.pdf delete mode 100644 ares_strerror.pdf delete mode 100644 ares_timeout.pdf delete mode 100644 ares_version.pdf create mode 100644 buildconf.bat create mode 100644 c-ares-config.cmake.in create mode 100644 docs/CMakeLists.txt create mode 100644 docs/Makefile.am create mode 100644 docs/Makefile.in create mode 100644 docs/Makefile.inc rename acountry.1 => docs/acountry.1 (96%) rename adig.1 => docs/adig.1 (82%) rename ahost.1 => docs/ahost.1 (97%) rename ares_cancel.3 => docs/ares_cancel.3 (95%) rename ares_create_query.3 => docs/ares_create_query.3 (96%) rename ares_destroy.3 => docs/ares_destroy.3 (90%) rename ares_destroy_options.3 => docs/ares_destroy_options.3 (100%) rename ares_dup.3 => docs/ares_dup.3 (100%) rename ares_expand_name.3 => docs/ares_expand_name.3 (100%) rename ares_expand_string.3 => docs/ares_expand_string.3 (100%) rename ares_fds.3 => docs/ares_fds.3 (58%) rename ares_free_data.3 => docs/ares_free_data.3 (100%) rename ares_free_hostent.3 => docs/ares_free_hostent.3 (100%) rename ares_free_string.3 => docs/ares_free_string.3 (100%) create mode 100644 docs/ares_freeaddrinfo.3 rename ares_get_servers.3 => docs/ares_get_servers.3 (100%) rename ares_get_servers_ports.3 => docs/ares_get_servers_ports.3 (100%) create mode 100644 docs/ares_getaddrinfo.3 rename ares_gethostbyaddr.3 => docs/ares_gethostbyaddr.3 (100%) rename ares_gethostbyname.3 => docs/ares_gethostbyname.3 (97%) rename ares_gethostbyname_file.3 => docs/ares_gethostbyname_file.3 (100%) rename ares_getnameinfo.3 => docs/ares_getnameinfo.3 (100%) rename ares_getsock.3 => docs/ares_getsock.3 (100%) rename ares_inet_ntop.3 => docs/ares_inet_ntop.3 (100%) rename ares_inet_pton.3 => docs/ares_inet_pton.3 (100%) rename ares_init.3 => docs/ares_init.3 (100%) rename ares_init_options.3 => docs/ares_init_options.3 (90%) rename ares_library_cleanup.3 => docs/ares_library_cleanup.3 (97%) rename ares_library_init.3 => docs/ares_library_init.3 (96%) create mode 100644 docs/ares_library_init_android.3 create mode 100644 docs/ares_library_initialized.3 rename ares_mkquery.3 => docs/ares_mkquery.3 (96%) rename ares_parse_a_reply.3 => docs/ares_parse_a_reply.3 (97%) rename ares_parse_aaaa_reply.3 => docs/ares_parse_aaaa_reply.3 (97%) create mode 100644 docs/ares_parse_caa_reply.3 rename ares_parse_mx_reply.3 => docs/ares_parse_mx_reply.3 (100%) rename ares_parse_naptr_reply.3 => docs/ares_parse_naptr_reply.3 (100%) rename ares_parse_ns_reply.3 => docs/ares_parse_ns_reply.3 (100%) rename ares_parse_ptr_reply.3 => docs/ares_parse_ptr_reply.3 (100%) rename ares_parse_soa_reply.3 => docs/ares_parse_soa_reply.3 (100%) rename ares_parse_srv_reply.3 => docs/ares_parse_srv_reply.3 (100%) rename ares_parse_txt_reply.3 => docs/ares_parse_txt_reply.3 (100%) rename ares_process.3 => docs/ares_process.3 (59%) rename ares_query.3 => docs/ares_query.3 (100%) rename ares_save_options.3 => docs/ares_save_options.3 (100%) rename ares_search.3 => docs/ares_search.3 (100%) rename ares_send.3 => docs/ares_send.3 (100%) rename ares_set_local_dev.3 => docs/ares_set_local_dev.3 (96%) rename ares_set_local_ip4.3 => docs/ares_set_local_ip4.3 (88%) rename ares_set_local_ip6.3 => docs/ares_set_local_ip6.3 (84%) rename ares_set_servers.3 => docs/ares_set_servers.3 (97%) rename ares_set_servers_csv.3 => docs/ares_set_servers_csv.3 (96%) rename ares_set_servers_ports.3 => docs/ares_set_servers_ports.3 (100%) rename ares_set_servers_ports_csv.3 => docs/ares_set_servers_ports_csv.3 (100%) rename ares_set_socket_callback.3 => docs/ares_set_socket_callback.3 (100%) rename ares_set_socket_configure_callback.3 => docs/ares_set_socket_configure_callback.3 (100%) create mode 100644 docs/ares_set_socket_functions.3 rename ares_set_sortlist.3 => docs/ares_set_sortlist.3 (100%) rename ares_strerror.3 => docs/ares_strerror.3 (100%) rename ares_timeout.3 => docs/ares_timeout.3 (57%) rename ares_version.3 => docs/ares_version.3 (75%) create mode 100644 include/CMakeLists.txt create mode 100644 include/Makefile.am create mode 100644 include/Makefile.in rename ares.h => include/ares.h (86%) rename ares_build.h => include/ares_build.h (95%) create mode 100644 include/ares_build.h.cmake rename ares_build.h.in => include/ares_build.h.in (95%) rename ares_dns.h => include/ares_dns.h (95%) rename ares_rules.h => include/ares_rules.h (98%) rename ares_version.h => include/ares_version.h (75%) create mode 100644 libcares.pc.cmake delete mode 100755 mkinstalldirs create mode 100644 msvc_ver.inc create mode 100644 src/CMakeLists.txt create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/lib/CMakeLists.txt create mode 100644 src/lib/Makefile.am create mode 100644 src/lib/Makefile.in create mode 100644 src/lib/Makefile.inc rename ares__close_sockets.c => src/lib/ares__close_sockets.c (94%) rename ares__get_hostent.c => src/lib/ares__get_hostent.c (98%) create mode 100644 src/lib/ares__parse_into_addrinfo.c rename ares__read_line.c => src/lib/ares__read_line.c (100%) create mode 100644 src/lib/ares__readaddrinfo.c create mode 100644 src/lib/ares__sortaddrinfo.c rename ares__timeval.c => src/lib/ares__timeval.c (100%) create mode 100644 src/lib/ares_android.c create mode 100644 src/lib/ares_android.h rename ares_cancel.c => src/lib/ares_cancel.c (100%) create mode 100644 src/lib/ares_config.h.cmake rename ares_config.h.in => src/lib/ares_config.h.in (98%) rename ares_create_query.c => src/lib/ares_create_query.c (95%) rename ares_data.c => src/lib/ares_data.c (61%) rename ares_data.h => src/lib/ares_data.h (96%) rename ares_destroy.c => src/lib/ares_destroy.c (95%) rename ares_expand_name.c => src/lib/ares_expand_name.c (97%) rename ares_expand_string.c => src/lib/ares_expand_string.c (98%) rename ares_fds.c => src/lib/ares_fds.c (100%) rename ares_free_hostent.c => src/lib/ares_free_hostent.c (100%) rename ares_free_string.c => src/lib/ares_free_string.c (100%) create mode 100644 src/lib/ares_freeaddrinfo.c create mode 100644 src/lib/ares_getaddrinfo.c rename ares_getenv.c => src/lib/ares_getenv.c (97%) rename ares_getenv.h => src/lib/ares_getenv.h (100%) rename ares_gethostbyaddr.c => src/lib/ares_gethostbyaddr.c (96%) rename ares_gethostbyname.c => src/lib/ares_gethostbyname.c (92%) rename ares_getnameinfo.c => src/lib/ares_getnameinfo.c (92%) rename ares_getsock.c => src/lib/ares_getsock.c (100%) rename ares_inet_net_pton.h => src/lib/ares_inet_net_pton.h (100%) rename ares_init.c => src/lib/ares_init.c (73%) rename ares_iphlpapi.h => src/lib/ares_iphlpapi.h (100%) rename ares_ipv6.h => src/lib/ares_ipv6.h (94%) rename ares_library_init.c => src/lib/ares_library_init.c (79%) rename ares_library_init.h => src/lib/ares_library_init.h (87%) rename ares_llist.c => src/lib/ares_llist.c (100%) rename ares_llist.h => src/lib/ares_llist.h (100%) rename ares_mkquery.c => src/lib/ares_mkquery.c (100%) rename ares_nowarn.c => src/lib/ares_nowarn.c (95%) rename ares_nowarn.h => src/lib/ares_nowarn.h (95%) rename ares_options.c => src/lib/ares_options.c (98%) create mode 100644 src/lib/ares_parse_a_reply.c create mode 100644 src/lib/ares_parse_aaaa_reply.c create mode 100644 src/lib/ares_parse_caa_reply.c rename ares_parse_mx_reply.c => src/lib/ares_parse_mx_reply.c (100%) rename ares_parse_naptr_reply.c => src/lib/ares_parse_naptr_reply.c (96%) rename ares_parse_ns_reply.c => src/lib/ares_parse_ns_reply.c (100%) rename ares_parse_ptr_reply.c => src/lib/ares_parse_ptr_reply.c (97%) create mode 100644 src/lib/ares_parse_soa_reply.c rename ares_parse_srv_reply.c => src/lib/ares_parse_srv_reply.c (100%) rename ares_parse_txt_reply.c => src/lib/ares_parse_txt_reply.c (98%) rename ares_platform.c => src/lib/ares_platform.c (99%) rename ares_platform.h => src/lib/ares_platform.h (100%) rename ares_private.h => src/lib/ares_private.h (74%) rename ares_process.c => src/lib/ares_process.c (84%) rename ares_query.c => src/lib/ares_query.c (99%) rename ares_search.c => src/lib/ares_search.c (94%) rename ares_send.c => src/lib/ares_send.c (96%) rename ares_setup.h => src/lib/ares_setup.h (100%) rename ares_strcasecmp.c => src/lib/ares_strcasecmp.c (100%) rename ares_strcasecmp.h => src/lib/ares_strcasecmp.h (100%) rename ares_strdup.c => src/lib/ares_strdup.c (100%) rename ares_strdup.h => src/lib/ares_strdup.h (100%) rename ares_strerror.c => src/lib/ares_strerror.c (100%) create mode 100644 src/lib/ares_strsplit.c create mode 100644 src/lib/ares_strsplit.h rename ares_timeout.c => src/lib/ares_timeout.c (100%) rename ares_version.c => src/lib/ares_version.c (100%) rename ares_writev.c => src/lib/ares_writev.c (94%) rename ares_writev.h => src/lib/ares_writev.h (92%) rename bitncmp.c => src/lib/bitncmp.c (100%) rename bitncmp.h => src/lib/bitncmp.h (100%) rename cares.rc => src/lib/cares.rc (98%) rename config-dos.h => src/lib/config-dos.h (94%) rename config-win32.h => src/lib/config-win32.h (88%) rename inet_net_pton.c => src/lib/inet_net_pton.c (99%) rename inet_ntop.c => src/lib/inet_ntop.c (97%) rename nameser.h => src/lib/nameser.h (97%) rename setup_once.h => src/lib/setup_once.h (97%) rename windows_port.c => src/lib/windows_port.c (100%) create mode 100644 src/tools/CMakeLists.txt create mode 100644 src/tools/Makefile.am create mode 100644 src/tools/Makefile.in create mode 100644 src/tools/Makefile.inc rename acountry.c => src/tools/acountry.c (90%) rename adig.c => src/tools/adig.c (78%) rename ahost.c => src/tools/ahost.c (79%) rename ares_getopt.c => src/tools/ares_getopt.c (100%) rename ares_getopt.h => src/tools/ares_getopt.h (100%) create mode 100644 test/CMakeLists.txt create mode 100644 test/Makefile.m32 create mode 100644 test/Makefile.msvc create mode 100644 test/README.md create mode 100644 test/ares-test-ai.h create mode 100644 test/ares-test-fuzz-name.c create mode 100644 test/ares-test-mock-ai.cc create mode 100644 test/ares-test-parse-caa.cc create mode 100644 test/ares-test-parse-soa-any.cc create mode 100755 test/buildconf create mode 100755 test/compile create mode 100755 test/config.guess create mode 100755 test/config.sub create mode 100755 test/depcomp create mode 100755 test/fuzzcheck.sh delete mode 100644 test/gmock-1.7.0/gtest/src/gtest-all.cc delete mode 100644 test/gmock-1.7.0/src/gmock-all.cc create mode 100644 test/gmock-1.8.0/gmock-gtest-all.cc create mode 100644 test/gmock-1.8.0/gmock/gmock.h create mode 100644 test/gmock-1.8.0/gtest/gtest.h create mode 100755 test/install-sh create mode 100644 test/ltmain.sh create mode 100755 test/missing rename test-driver => test/test-driver (94%) delete mode 100644 vc/acountry/vc6acountry.dsp delete mode 100644 vc/adig/vc6adig.dsp delete mode 100644 vc/ahost/vc6ahost.dsp delete mode 100644 vc/cares/vc6cares.dsp delete mode 100644 vc/cares/vc6cares.dsw delete mode 100644 vc/vc6aws.dsw diff --git a/AUTHORS b/AUTHORS index af29ec8..7db6584 100644 --- a/AUTHORS +++ b/AUTHORS @@ -37,6 +37,7 @@ Frederic Germain Geert Uytterhoeven George Neill Gisle Vanem +Google LLC Gregor Jasny Guenter Knauf Guilherme Balena Versiani @@ -45,6 +46,7 @@ Henrik Stoerner Jakub Hrozek James Bursa Jérémy Lal +John Schember Keith Shaw Lei Shi Marko Kreen diff --git a/CHANGES b/CHANGES index 93e6a43..607545d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3968 +1,4935 @@ Changelog for the c-ares project. Generated with git2changes.pl -Version 1.12.0 (29 Sep 2016) +Version 1.17.1 (19 Nov 2020) -Daniel Stenberg (29 Sep 2016) -- RELEASE-NOTES: 1.12.0 +GitHub (19 Nov 2020) +- [Brad House brought this change] -- [David Drysdale brought this change] + Travis: add iOS target built with CMake (#378) + + Issue #377 suggested that CMake builds for iOS with c-ares were broken. This PR adds an automatic Travis build for iOS CMake. + + Fix By: Brad House (@bradh352) - ares-test-misc: test ares_create_query with escaped trailing dot +bradh352 (18 Nov 2020) +- fix build -- ares_create_query: avoid single-byte buffer overwrite - - ... when the name ends with an escaped dot. +GitHub (18 Nov 2020) +- [Fabrice Fontaine brought this change] + + External projects were using non-public header ares_dns.h, make public again (#376) - CVE-2016-5180 + It appears some outside projects were relying on macros in ares_dns.h, even though it doesn't appear that header was ever meant to be public. That said, we don't want to break external integrators so we should distribute this header again. - Bug: https://c-ares.haxx.se/adv_20160929.html - -- ares_library_initialized.3: added + Fix By: Fabrice Fontaine (@ffontaine) -- make: bump CARES_VERSION_INFO for release +bradh352 (17 Nov 2020) +- note that so versioning has moved to configure.ac -David Drysdale (29 Sep 2016) -- man: update ares_init_options.3 +- note about 1.17.1 -Daniel Stenberg (29 Sep 2016) -- ares_library_init.3: corrected the ares_library_init_mem proto +- fix sed gone wrong -- README.md: remove space from link +GitHub (17 Nov 2020) +- [Daniel Stenberg brought this change] -- README: link to the correct c-ares badge! + autotools cleanup (#372) - Reported-by: David Hotham + * remove: install-sh mkinstalldirs - Fixes #63 - -- docs: minor formatting edits + They're generated when needed, no need to store in it. + + * buildconf: remove custom logic with autoreconf + + Fix By: Daniel Stenberg (@bagder) -- ares_destroy.3: formatting polish +bradh352 (17 Nov 2020) +- attempt to fix 1.17.0 release distribution issues -- ares_init.3: split the init docs into two separate man pages +Version 1.17.0 (16 Nov 2020) -- SECURITY: point to the vulnerabilities page now +bradh352 (16 Nov 2020) +- 1.17.0 release prep -- RELEASE-NOTES: synced with daa7235b1a5 +- ares_getaddrinfo(): duplicate hints ai_socktype and ai_protocol into output + + ai_socktype and ai_protocol were ignored from the hints input. They are now + duplicated into the output as expected. Currently no sanity checks on + proper values are taking place. + + Fixes: #317 + Fix By: Brad House (@bradh352) -- ares_create_query.3: edit language +- ares_parse_{a,aaaa}_reply could return larger *naddrttls than passed in - Tried to make the man page more readable. + If there are more ttls returned than the maximum provided by the requestor, then + the *naddrttls response would be larger than the actual number of elements in + the addrttls array. + + This bug could lead to invalid memory accesses in applications using c-ares. + + This behavior appeared to break with PR #257 + + Fixes: #371 + Reported By: Momtchil Momtchev (@mmomtchev) + Fix By: Brad House (@bradh352) -David Drysdale (26 Sep 2016) -- test: fix gMock to work with gcc >= 6.x +GitHub (5 Nov 2020) +- [Dustin Lundquist brought this change] + + docs: ares_set_local_ip4() uses host byte order (#368) - Taken from: - https://github.com/google/googletest/issues/705#issuecomment-235067917 + Properly document brain-dead behavior of ares_set_local_ip4() using host byte order instead of expected network byte order. + + Fix By: Dustin Lundquist -Daniel Stenberg (26 Sep 2016) -- [Brad House brought this change] +- [Łukasz Marszał brought this change] - headers: remove checks for and defines of variable sizes + empty hquery->name could lead to invalid memory access (#367) - ... they're not really used and by avoiding them in the ares_build.h - output we make the public header less dependent on data sizes. + If hquery->name is empty (=="\0"), &hquery->name[strlen(hquery->name)-1] would point to "random" place in memory. This is causing some of my address sanitizer tests to fail. + + Fix By: Łukasz Marszał (@lmarszal) -David Drysdale (24 Sep 2016) -- api: add ARES_OPT_NOROTATE optmask value +bradh352 (28 Sep 2020) +- Fix OSSFuzz reported issue in CAA reply parsing - Fix up a couple of problems with configuring whether c-ares rotates - between different name servers between requests. + OSS-Fuzz is reporting a use-of-uninitialized-value: + https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=26012 - Firstly, ares_save_options() returns (in *optmask) the value of - (channel->optmask & ARES_OPT_ROTATE), which doesn't necessarily - indicate whether the channel is or is not actually doing rotation. - This can be confusing/incorrect if: - - the channel was originally configured without ARES_OPT_ROTATE - (so it appears that the channel is not rotating) - - the /etc/resolv.conf file includes the 'rotate' option - (so the channel is actually performing rotation). + Reported By: David Drysdale (@daviddrysdale) + +GitHub (26 Sep 2020) +- [David Hotham brought this change] + + fuzz CAA parsing (#363) - Secondly, it is not possible to reliably configure a channel - to not-rotate; leaving off ARES_OPT_ROTATE is not enough, since - a 'rotate' option in /etc/resolv.conf will turn it on again. + Add fuzz support for CAA parsing - Therefore: - - add an ARES_OPT_NOROTATE optmask value to allow explicit - configuration of no-rotate behaviour - - in ares_save_options(), report the value of channel->rotate - as exactly one of (optmask & ARES_OPT_ROTATE) or - (optmask & ARES_OPT_NOROTATE). + Fix By: David Hotham (@dimbleby) + +- [Daniela Sonnenschein brought this change] + + Allow parsing of CAA Resource Record (#360) - In terms of back-compatibility: - - existing apps that set ARES_OPT_ROTATE will continue to rotate, - and to have ARES_OPT_ROTATE reported back from ares_save_options() - - existing apps that don't set ARES_OPT_ROTATE will continue to - use local config/defaults to decide whether to rotate, and will - now get ARES_OPT_ROTATE or ARES_OPT_NOROTATE reported back from - ares_save_options() rather than 0. + CAA (Certification Authority Authorization) was introduced in RFC 6844. + This has been obsoleted by RFC 8659. This commit added the possibility + to query CAA resource records with adig and adds a parser for CAA + records, that can be used in conjunction with ares_query(3). + + Closes Bug: #292 + Fix By: Daniela Sonnenschein (@lxdicted) -- ares_init_options: only propagate init failures from options +Daniel Stenberg (17 Sep 2020) +- docs: remove the html and pdf make targets - Commit 46bb820be3a8 ("ares_init_options: don't lose init failure") - changed init behaviour so that earlier errors in initialization - weren't lost. In particular, if the user passes in specific - options but they are not applied (e.g. because of an allocation - failure), that failure needs to be reported back to the user; this - also applies when duplicating a channel with ares_dup(). + They're rarely used in our daily work flow and mostly just add friction, - However, other initialization failures can be ignored and - overridden -- in particular, if init_by_resolv_conf() or - init_by_environment() fail, then falling back to default values - is OK. + Closes #362 + +bradh352 (14 Sep 2020) +- ares_process needs to always include nameser.h as it has compat + +- Define T_OPT if system doesn't provide it + +GitHub (12 Sep 2020) +- [Gisle Vanem brought this change] + + Change the mailman links (#358) - So only preserve failures from the init_by_options() stage, not - from all initialization stages. + Links when wrapping become misleading. Insert newline to prevent wrapping. - Fixes issue 60. + Fix By: Gisle Vanem (@gvanem) -- test: Force reinstall of libtool on OSX +- [Gisle Vanem brought this change] + + [adig] Update man-page for the '-x' option (#357) - Travis build environment appears to have changed. + Fix By: Gisle Vanem (@gvanem) -- test: Add valgrind build variant +- [Gisle Vanem brought this change] -- test: Add null pointer to gtest args + [adig] add '-x' option. (#356) - GoogleTest assumes that there is a null pointer in argv[argc], - so make it look like that. Without this change, tests run with - command-line arguments get memory errors under valgrind/ASAN. + Added a 'dig-style' '-x' option. Also support '-xx' for a + IPv6 bit-string PTR query. + + Fix By: Gisle Vanem (@gvanem) -Daniel Stenberg (21 Aug 2016) -- AUTHOR: maybe gitgub isn't really an author =) +bradh352 (12 Sep 2020) +- fix indentation -- AUTHORS: added contributors from the git log +- ns_t_opt -> T_OPT -- LICENSE.md: add a stand-alone license file - - Just the MIT license used in the top the source files moved out to a - stand-alone file for easier reference and discovery. +GitHub (12 Sep 2020) +- [Gisle Vanem brought this change] -- README: added "CII best practices" badge + Fixes for Watt-32 on djgpp + Windows (#355) + + No longer any relation to libcurl since '/packages/DOS/common.dj' is dropped. + This Makefile.dj has been tested on Win-10 only (using the Windows hosted djgpp cross compiler). + + Fix By: Gisle Vanem (@gvanem) -- SECURITY.md: suggested "security process" for the project +- [Gisle Vanem brought this change] -David Drysdale (17 Aug 2016) -- test: Add Clang static analysis build to Travis + Fixes for Watt-32 on Windows and MSDOS (#354) - Run scan-build over the library source code, but skip the - tests. Needs a later Clang install in Travis + Move the prototype to 'ares_private.h'. + + Fix By: Gisle Vanem (@gvanem) -- test: more info on how to run fuzz testing +bradh352 (11 Sep 2020) +- update path for include -- test: make fuzzer driver code C not C++ +- remove stale information -- test: fuzzer mode for AFL's persistent mode - - When fuzzing with AFL, if the LLVM-based instrumentation is - used (via the afl-clang-fast wrapper), then it is possible to - have a single execution of the fuzzer program iterate multiple - times over the fuzzing entrypoint (similar to libFuzzer's normal - mode of execution) with different data. This is much (e.g. 10x) - faster. +- remove stale information + +Brad House (9 Sep 2020) +- silence compiler warnings + +- Remove stale msvc files from makefile + +GitHub (9 Sep 2020) +- [Brad House brought this change] + + Reorganize source tree (#349) - Add code to support this, by checking whether __AFL_LOOP is - defined at compile-time. + Originally started by Daniel Stenberg (@bagder) with #123, this patch reorganizes the c-ares source tree to have a more modern layout. It also fixes out of tree builds for autotools, and automatically builds the tests if tests are enabled. All tests are passing which tests each of the supported build systems (autotools, cmake, nmake, mingw gmake). There may be some edge cases that will have to be caught later on for things I'm not aware of. - Also, shift the code to effectively be C rather than C++. + Fix By: Brad House (@bradh352) -- test: simplify deps for fuzzer entrypoint +Brad House (1 Sep 2020) +- remove CURLDEBUG as per #82 + +GitHub (1 Sep 2020) +- [Erik Lax brought this change] + + Detect remote DNS server does not support EDNS as per RFC 6891 (#244) - No need to depend on the rest of the test code (ares-test.h) for - the fuzzer entrypoint; this makes the entrypoint slightly simpler - to build with LLVM's libFuzzer. + EDNS retry should be based on FORMERR returned without an OPT RR record as per https://tools.ietf.org/html/rfc6891#section-7 rather than just treating any unexpected error condition as a reason to disable EDNS on the channel. - Also shift the code to effectively be C rather than C++ + Fix By: Erik Lax (@eriklax) -- test: disable MinGW tests +Brad House (27 Aug 2020) +- Fix for #345, don't use 'true' use 1 + +GitHub (27 Aug 2020) +- [Seraphime Kirkovski brought this change] + + ares_gethostbyname: Fix AF_UNSPEC support when using an ip address (#204) - The test binary built in the MinGW build is failing for some - reason. It works for me when I build locally, so I'm guessing - it's down to some sort of AppVeyor environment issue. + fake_hostent() was not supporting AF_UNSPEC, so when an ip address was specified when using AF_UNSPEC it would attempt to do a DNS lookup rather than returning a fake hostent using the ip address. - Disable for now. + Fix By: Seraphime Kirkovski (@Seraphime) -Daniel Stenberg (16 Aug 2016) -- read_tcp_data: remove superfluous NULL check +- [apenn-msft brought this change] + + Tests should use dynamic system-assigned ports rather than static port (#346) - CID 56884 by Coverity. The pointer is already derefenced before this - point so it can't be NULL here anyway. + The c-ares test suite was hardcoded to use port 5300 (and possibly 5301, 5302) for the test suite. Especially in containers, there may be no guarantee these ports are available and cause tests to fail when they could otherwise succeed. Instead, request the system to assign a port to use dynamically. This is now the default. To override, the test suite still takes the "-p " option as it always has and will honor that. + + Fix By: Anthony Penniston (@apenn-msft) -- web: http => https +Brad House (25 Aug 2020) +- Unset members of the addr struct contain garbage values (#343) + + When generating the ares_sockaddr data by getaddrinfo() it was only filling + in certain members while leaving others uninitialized. This left garbage + data if a user tried to use the unset values. memset() the ares_sockaddr + to 0 prior to filling in the values to prevent this. + + Reported By: @SmorkalovG + Fix By: Brad House (@bradh352) -GitHub (20 Jul 2016) -- [David Drysdale brought this change] +GitHub (24 Aug 2020) +- [Jonathan Maye-Hobbs brought this change] - Merge pull request #59 from fuze/master + FQDN with trailing period should be queried first with larger ndot value (#345) - Update msvc_ver.inc for VS2015 Update 3 + If a query is performed for dynamodb.us-east-1.amazonaws.com. with ndots=5, it was attempting to search the search domains rather than just attempting the FQDN that was passed it. This patch now at least attempts the FQDN first. + + We may need to determine if we should abort any further searching, however as is probably intended. + + Fix by: Jonathan Maye-Hobbs (@wheelpharoah) -- [Chris Araman brought this change] +- [Gisle Vanem brought this change] - Update msvc_ver.inc + Update acountry.c country code list (#341) - support Visual Studio 2015 Update 3 + Updated country_list[]: + * 2-letter ISO-3166 country-codes. + * Add, rename some names + codes in accordance with latest table at https://en.wikipedia.org/wiki/ISO_3166-1. + + Fix By: Gisle Vanem (@gvanem) -David Drysdale (2 May 2016) -- Fix trailing comment for #endif +- [Bulat Gaifullin brought this change] -Daniel Stenberg (30 Apr 2016) -- email: use Gisle's "new" address + Test case should honor flag HAVE_WRITEV rather than WIN32 (#344) + + Test cases where not honoring the HAVE_WRITEV flag but instead using WIN32 to determine if WRITEV was available or not. This patch fixes that. + + Fix By: Bulat Gaifullin (@bgaifullin) -David Drysdale (18 Apr 2016) -- test: drop superfluous fuzz inputs +Brad House (18 Jul 2020) +- Ensure c89 support - Where there are multiple fuzz input files that only differ in - the first two bytes (the query ID), just keep the first such - file. + A couple of for loops in Mac-specific code were using integer declarations + inside a for loop. Move the declaration to the top of the preceding + code block to retain c89 compliance. + + Reported By: Jeffrey Walton -svante karlsson (15 Apr 2016) -- Update msvc_ver.inc +GitHub (2 Jul 2020) +- [Fionn Fitzmaurice brought this change] + + Avoid buffer overflow in RC4 loop comparison (#336) - support Visual Studio 2015 Update 2 + The rc4 function iterates over a buffer of size buffer_len who's maximum + value is INT_MAX with a counter of type short that is not guaranteed to + have maximum size INT_MAX. + + In circumstances where short is narrower than int and where buffer_len + is larger than the maximum value of a short, it may be possible to loop + infinitely as counter will overflow and never be greater than or equal + to buffer_len. + + The solution is to make the comparison be between types of equal width. + This commit defines counter as an int. + + Fix By: Fionn Fitzmaurice (@fionn) -David Drysdale (31 Mar 2016) -- test: Run fuzzcheck.sh in Travis build +- [anonymoushelpishere brought this change] -- test: add fuzzing check script to tests + Updated help information for adig, acountry, and ahost. (#334) - Add a test script that runs the fuzzing command over the - corpus of DNS packets. This doesn't actually do any fuzzing - (it just runs them as inputs without generating any variations) - but it does ensure that the fuzzing entrypoint is still working. + Provide more descriptive help information for various utilities. + + Fix By: @anonymoushelpishere -- test: allow multiple files in aresfuzz command line +- [lutianxiong brought this change] + + avoid read-heap-buffer-overflow (#332) - If no arguments are specified, use stdin as input. - Otherwise treat each argument as a filename and feed - its contents to the fuzz entrypoint. + Fix invalid read in ares_parse_soa_reply.c found during fuzzing + + Fixes Bug: #333 + Fix By: lutianxiong (@ltx2018) -- test: Add corpus of DNS packets +- [Ivan Baidakou brought this change] + + Fix: sizeof(sizeof(addr.saX)) -> sizeof(addr.saX) in readaddrinfo (#331) - For fuzz testing it is useful to start from a corpus of valid - packets, so fill out the test/fuzzinput/ directory with a bunch - of inputs. + Looks like a sed-gone-wrong, a sizeof inside of a sizeof. - These packets were generated by temporarily modifying the c-ares - process_answer() function to save off any incoming response messages. + Fix By: Ivan Baidakou (@basiliscos) -- test: Add utility to show DNS packet from file +Version 1.16.1 (11 May 2020) -- [nordsturm brought this change] +Brad House (11 May 2020) +- c-ares 1.16.1 release prep - Fix nsort initialization +- update travis to use xcode11.4 + +- Prevent possible double-free in ares_getaddrinfo() if ares_destroy() is called - Author: Alexander Drachevskiy - http://c-ares.haxx.se/mail/c-ares-archive-2014-07/0004.shtml - http://c-ares.haxx.se/mail/c-ares-archive-2014-07/0014.shtml + In the event that ares_destroy() is called prior to ares_getaddrinfo() completing, + it would result in an invalid read and double-free due to calling end_hquery() twice. + + Reported By: Jann Horn @ Google Project Zero -- test: Check setting nsort=0 option is respected +GitHub (30 Apr 2020) +- [shelley vohr brought this change] -- test: Update fuzzing function prototype + fix: windows UNICODE incompatibilities with ares_getaddrinfo (#328) - libFuzzer changed expected return type from void to int - in LLVM 3.8. - -- Explicitly clear struct servent before use + Fixes the following compatibility issues: + * Use RegQueryValueExA instead of RegQueryValueEx + * Use ExpandEnvironmentStringsA instead of ExpandEnvironmentStrings + * Use RegOpenKeyExA instead of RegOpenKeyExA + * Use GetWindowsDirectoryA instead of GetWindowsDirectoryA - On a build where MSAN has been manually set up (which involves - using an MSAN-instrumented version of the standard C++ library, see - https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo) - there's a warning about use of uninitialized memory here. It - might be a false positive, but the fix is trivial so include it. + Fix By: Shelley Vohr (@codebytere) + Closes: #327 -- test: for AF_UNSPEC, return CNAME only for AAAA, but valid A record +Brad House (13 Apr 2020) +- travis: CloudFlare does not allow T_ANY requests, so live tests that use it fail. Disable. + +- travis: bump macos image to the latest + +- cast-align warnings are false for struct sockaddr, silence - Also shuffle expected responses rsp6/rsp4 into the order they will occur. + Create a macro to silence false cast-align warnings when casting + struct sockaddr * to struct sockaddr_in * and struct sockaddr_in6 *. + + Fix By: Brad House (@bradh352) -- [Chris Araman brought this change] +- MacOS: Enable libresolv support for retrieving DNS servers like iOS does. - msvc_ver.inc: support Visual Studio 2015 Update 1 +GitHub (10 Apr 2020) +- [Dmitry Igrishin brought this change] -- build: commonize MSVC version detection + CMake: Populate the INCLUDE_DIRECTORIES property of installed targets (#323) - Remove the need to copy/paste version number mapping between - Makefile.msvc and test/Makefile.msvc. + Populate the INCLUDE_DIRECTORIES property of installed targets + + Fix By: Dmitry Igrishin (@dmitigr) -- test: Use different name in live test +Brad House (10 Apr 2020) +- travis: make valgrind use cmake for tests -- test: Only pass unused args to GoogleTest +- dont try to use libtool to run valgrind -- ahost.c: add cast to fix C++ compile - - If ahost.c is force-compiled as C++ the missing cast from - (void *) to (char **) is problematic. +- valgrind requires libtool installed to wrap tests -- ares_library_cleanup: reset ares_realloc too - - Otherwise a subsequent use of the library might use a previous - incarnation's realloc() implementation. +- scan build 7 -Daniel Stenberg (9 Mar 2016) -- [Brad House brought this change] +- fix travis live test - configure: check if tests can get built before enabled - - The current approach for disabling tests is not a good solution because - it forces you to pass --disable-tests, rather than auto-detect if your - system can support the tests in the first place. Many (most?) systems - do not have C++11. This also causes issues when chain-building c-ares, - the hosting system needs to be updated to support passing this - additional flag if necessary, it doesn't seem reasonable to add this - requirement which breaks compatibility. - - This change auto-detects if the system can build the tests and - automatically disable them if it cannot. If you pass --enable-tests to - configure and the system cannot build them either due to lack of system - support, or because cross-compilation is being used, it will throw an - appropriate error since the user indicated they really did want the - tests. +- add debug for travis -David Drysdale (3 Mar 2016) -- [Viktor Szakats brought this change] +- try without sudo - Makefile.m32: add support for CROSSPREFIX +- attempt to modernize travis build environment -- [Viktor Szakats brought this change] +GitHub (6 Apr 2020) +- [Teemu R brought this change] - Makefile.m32: add support for extra flags + Allow TXT records on CHAOS qclass (#321) - Allow specification of CARES_{LD,C}FLAG_EXTRAS envvars - for mingw - -- test: Build with MinGW on AppVeyor + Some DNS servers intentionally "misuse" the obsoleted CHAOS (CH) qclass to provide things like `version.bind`, `version.server`, `authors.bind`, `hostname.bind` and `id.server`. + + C-ares was not allowing such use cases. + + Fix By: Teemu R. (@rytilahti) -- test: avoid in6addr_* constants +Brad House (5 Apr 2020) +- Remove warnings from ares_getaddrinfo.3 man page - These aren't available on MinGW, so use explicit addresses instead. + As reported in #319, non-standard macros of .IN were used. + Replace with .RS/.RE. + + Fixes: #319 + Fix By: Brad House (@bradh352) -- test: add missing #includes for dns-proto.cc +- ares_getaddrinfo man page render better for man2html -- [Gregor Jasny brought this change] +- update man pages to render better for man2html - Fix man page typos detected by Lintian +Version 1.16.0 (12 Mar 2020) -Daniel Stenberg (19 Feb 2016) -- configure: acknowledge --disable-tests - - Fixes #44 +Brad House (12 Mar 2020) +- 1.16.0 release notes draft -- AUTHORS: added contributors from the 1.11.0 release +- attempt to fix double-free introduced in e0517f9 -- bump: start working on the next version +GitHub (12 Mar 2020) +- [David Drysdale brought this change] -Version 1.11.0 (19 Feb 2016) + test: fuzzer input triggering double free (#315) + + OSS-Fuzz has reported a double-free with the fuzzer input file + included here; run with: + ./test/aresfuzz test/fuzzinput/clusterfuzz-5637790584012800 + + Bisecting the failure points to commit e0517f97d988 ("Parse SOA records + from ns_t_any response (#103)") -Daniel Stenberg (19 Feb 2016) -- RELEASE-NOTES: final edits for 1.11.0 +- [Brad House brought this change] -David Drysdale (15 Feb 2016) -- ares_dup.3: remove mention of nonexistent function + CMake: Install Manpages (#314) - ares_dup_options() doesn't exist, so don't document it. - -- test: skip repeated build steps + CMake wasn't installing manpages. - Top-level buildconf/configure now triggers for the - test/ subdir too, so don't need to do explicitly. + Fixes #297 + Fix By: Brad House (@bradh352) -- test: namespaces unavailable when cross-compiling +- [Brad House brought this change] -Daniel Stenberg (13 Feb 2016) -- configure: only run configure in test when NOT cross-compiling + Enable cmake tests for AppVeyor (#313) - ... as the tests won't run cross-compiled anyway + Tests require linking against the static library on Windows otherwise the symbols are not exported for internals being tested. + + Fix By: Brad House (@bradh352) -David Drysdale (13 Feb 2016) -- test: prefer ON_CALL to EXPECT_CALL to reduce flakes +Brad House (11 Mar 2020) +- Add AppVeyor badge + +- bump c-ares version to 1.16.0. test AppVeyor integration. + +GitHub (11 Mar 2020) +- [Brad House brought this change] + + replace all usages of inet_addr() with ares_inet_pton() which is more proper (#312) - For UDP tests, there's a chance of a retry. EXPECT_CALL only - expects a single request to arrive at the server; ON_CALL allows - for a UDP retry and repeats the same answer. + Replace usage of inet_addr() with ares_inet_pton() which is more appropriate and fixes issues with legitimate addresses like 255.255.255.0. IPv6 already used this. - Note that ON_CALL and EXPECT_CALL can't be mixed in the same - test, and that tests that have a varied sequence of responses - for the same repeated request still have to use EXPECT_CALL. + Fixes #309 + Fix By: Brad House (@bradh352) -Daniel Stenberg (13 Feb 2016) -- configure: run configure in 'test' too - - Having the test dir completely stand-alone causes too many issues for - users and devs. It still needs to be built specifically. +- [Brad House brought this change] -- configure: build silently by default + CMake: Generate WinPDB files during build (#311) + + Build and Install PDB (Windows Debug Symbol) files if supported by underlying system. + + Also update AppVeyor to test cmake builds. + + Fixes #245 + Fix By: Piotr Pietraszkiewicz (@ppietrasa) and Brad House (@bradh352) -- buildconf: run test/buildconf too if present +- [Brad House brought this change] -- test/configure: build silently by default + CMake: Rework library function checking (#310) + + CHECK_LIBRARY_EXISTS(), while it takes a function name, does not actually verify the function exists in the library being evaluated. Instead, if the function is found in any dependent library, and the referenced library also exists, it returns true. This is not desirable. + + Wrap with a Macro to change the behavior. + + Fixes: #307 + Fix By: Brad House (@bradh352) -- [Gregor Jasny brought this change] +- [Dron Rathore brought this change] - dist: Distribute README.md + Parse SOA records from ns_t_any response (#103) - Closes #42 - -Version 1.11.0 (11 Feb 2016) + Added the capability of parsing SOA record from a response buffer of ns_t_any type query, this implementation doesn't interfere with existing T_SOA query's response as that too is treated as a list of records. The function returns ARES_EBADRESP if no SOA record is found(as per RFC). + + The basic idea of sticking to RFC that a ns_t_any too should return an SOA record is something open for discussion but I have kept the functionality intact as it was previously i.e the function returns ARES_EBADRESP if it doesn't find a SOA record regardless of which response it is parsing i.e. T_SOA or T_ANY. + + Note that asking for T_ANY is generally a bad idea: + - https://blog.cloudflare.com/what-happened-next-the-deprecation-of-any/ + - https://tools.ietf.org/html/draft-ietf-dnsop-refuse-any + + Bug: #102 + Fix By: Dron Rathore (@DronRathore) -Daniel Stenberg (11 Feb 2016) -- Makefile.am: distribute the test dir too +- [Stephen Bryant brought this change] -- RELEASE-NOTES: synced with 385582bd14b68a + Added CPack functionality for generating RPM or DEB packages (#283) + + Added CPack functionality for generating RPM or DEB packages + + ie: run `cpack -G RPM` (or "DEB") after building with CMake. + + The current configuration creates 3 separate packages for the shared library, + the development files and the tools. + + Fix By: Stephen Bryant (@bf-bryants) -- [Nicolas \"Pixel\" Noble brought this change] +- [tjwalton brought this change] - ares_win32_init: make LoadLibrary work when using UNICODE too + ares_gethostbyname: Return ENODATA if no valid A or AAAA record found (#304) - Closes #17 + ares_gethostbyname() was returning ESUCCESS when no A or AAAA record was found but a CNAME pointing nowhere was present. ENODATA should be returned instead, however the hosts pointer will still be present to provide the alias list. + + * Return ENODATA if no valid A or AAAA record found + * Fix and update test ParseAReplyNoData. + * Add test for new ENODATA behaviour in ares_gethostbyname. + + Fixes Bug #303 + Fix By: @tjwalton -David Drysdale (11 Feb 2016) -- Use "resolve" as synonym of "dns" in nsswitch.conf +- [Michal Rostecki brought this change] + + test: Separate live tests from SetServers* tests (#299) - Modern Linux systems may have libnss_resolve from systemd as the - resolver, which is then configured in /etc/nsswitch.conf with - the "resolve" keyword rather than "dns". + Before this change, SetServers, SetServersPorts and SetServersCSV + contained test cases trying to make DNS queries with the google.com + hostname, which requires Internet connectivity. Tests with that + requirement should be defined in the ares-test-live.cc file and contain + "Live" prefix to filter them out with `--gtest_filter=-*.Live*` on + machines without Internet connectivity. - Fixes #33 + Fix By: Michal Rostecki (@mrostecki) -- ares_set_socket_callback: make manpage match code +- [Adam Majer brought this change] + + Only count valid addresses when response parsing (#302) - The code in ares_process.c that invokes the socket creation/connection - callback only checks for rc < 0, not for standard ares error codes. + When ares_parse_a_reply or ares_parse_aaaa_reply is called in case + where another AAAA and A responses exist, the resulting ares_addrttl + count is invalid and the structure points to gibberish. + + This is a regression since 1.15. + + Issue: https://github.com/c-ares/c-ares/issues/300 + Fix By: Adam Majer (@AdamMajer) -- Merge pull request #36 from AGWA-forks/master +Brad House (24 Dec 2019) +- [Kyle Edwards brought this change] + + CMake: Provide c-ares version in package export file (#296) - Add ares_set_socket_configure_callback() + The CMake package export file should provide version information. + + Fix By: Kyle Edwards (@KyleFromKitware) -- test: Update init tests to match behaviour +- [Ben Noordhuis brought this change] + + Accept invalid /etc/resolv.conf lookup values, ability to build container tests (#274) - Unreadable config files are now treated the same way - as absent config files. + * Add CARES_BUILD_CONTAINER_TESTS CMake option to add ability to build the Linux-only containerized tests. + * Accept invalid /etc/resolv.conf lookup values + + Before this commit invalid `lookup` values resulted in c-ares not using + any lookups without any clear indication why. After this commit it uses + the default "fb". + + Fix By: Ben Noordhuis (@bnoordhuis) -- [Fedor Indutny brought this change] +- [Christian Ammer brought this change] - Ignore `fopen` errors to use default values + Parallel A and AAAA lookups in `ares_getaddrinfo` (#290) - After 46bb820be3a83520e70e6c5f0c5133253fcd69cd `init_by_resolv_conf` - errors are no longer swallowed in `ares_init_options`. This has exposed - a previously unknown bug in `lookups` initialization code. + A and AAAA lookups for ares_getaddrinfo() are now performed in parallel. - If there is no lookup configuration in `resolv.conf`, - `init_by_resolv_conf` will attempt to read it from other files available - on the system. However, some of these files may have restricted - permissions (like `600`), which will lead to `EACCESS` errno, which in - turn is handled like a fatal error by `init_by_resolv_conf`. + For this change `ares_search` was removed from `ares_getaddrinfo`. + Instead `ares_query` in combination with `next_dns_lookup` are + doing the suffix search. - However, it sounds illogical that this error should be handled as a - fatal. There is a `init_by_defaults` call that overrides `lookups` with - default value, and certainly possible absence of lookup information is - the reason why this function exists in a first place! + Adding support for `.onion` addresses which are tested by + `TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain)` - I suggest handling any `fopen` errors as non-fatal ones, allowing to - pick up the `lookups` value from different config files, or to pick up - default value. + Fix By: Christian Ammer (@ChristianAmmer) -Andrew Ayer (9 Feb 2016) -- Document callback type in man page for ares_set_socket_callback +- [Vy Nguyen brought this change] -- Add ares_set_socket_configure_callback() + Move variables into the block where it is used to avoid unused-vars (#281) - This function sets a callback that is invoked after the socket is - created, but before the connection is established. This is an ideal - time to customize various socket options. + Warning uncovered with [-Werror, -Wunused-variables] + + Fix By: Vy Nguyen (@oontvoo) -David Drysdale (9 Feb 2016) -- test: ares_set_socket_callback failure behaviour +- [Vy Nguyen brought this change] -- test: Check ares_parse_txt_reply_ext() entrypoint + Rename local macros to avoid conflicting with system ones and remove unsed variables. (Otherwise code will break once compiled with [-Werror,-Wmacro-redefined,-Wunused-variable] ) (#280) + + Fix new getaddrinfo code to not redefine macros on some systems. + + Fix By: Vy Nguyen (@oontvoo) -- [Fedor Indutny brought this change] +- [Egor Pugin brought this change] - txt: introduce `ares_parse_txt_reply_ext` + [ares_getenv] Return NULL in all cases. (#279) - Introduce `ares_txt_ext` structure with an extra `record_start` - field, which indicates a start of a new TXT record, thus allowing to - differentiate the chunks in the same record, from a chunks in a - different record. + if ares_getenv is defined, it must return a value on all platforms. - Introduce a new API method: `ares_parse_txt_reply_ext` that works with - this kind of struct. - -- doc: Update missed repo references + Fix By: Egor Pugin (@egorpugin) -- doc: Update docs on contributing +- [Abhishek Arya brought this change] -- test: Run command line tools in Travis + Add OSS-Fuzz fuzzing badge (#278) - Do a quick execution of each of the command line tools - in the continuous integration build, so that any (say) - sanitizer failures show up. + Adds based on instructions at + https://google.github.io/oss-fuzz/getting-started/new-project-guide/#status-badge + + Patch By: Abhishek Arya (@inferno-chromium) -- acountry: drop inert test +- [Peter Eisentraut brought this change] + + ares_init_options.3: Fix layout (#275) - If ver_1 is true, then z0 and z1 must both be 'z', and so - (z0 != 'z' && z1 != 'z') can never be true. + 7e6af8e inserted the documentation of resolvconf_path in the middle of + the item for ednspsz, leading to broken layout. Fix that. - CID 56879, pointed out by Coverity. + Fix By: Peter Eisentraut (@petere) -- doc: update badge locations to master repo +- [Gregor Jasny brought this change] -- test: Enable maintainer mode + debug in Travis + manpages: Fix typos detected by lintian (#269) + + + Fix By: Gregor Jasny (@gjasny) -- test: Add an iOS build target +- [lifenjoiner brought this change] -- test: Ignore SIGPIPE in tests + keep command line usage up to date (#256) + + adig and ahost built-in help did not match args taken. + + Fix-By: @lifenjoiner -- test: More initialization tests +- [Dan Noé brought this change] -- test: Improve containerized test mechanism + ares-test.cc: Handle nullptr in AddrInfo ostream. (#268) - Aim is to ensure that code coverage information can escape the - container. To do this: - - Enter a new mount namespace too, so that we can... - - Bind mount the expected source directory into the container - - Share memory with the sub-process so coverage information is - shared too. + The const AddrInfo& argument to operator<< overload for AddrInfo can be + a nullptr unique_ptr. Handle this explicitly by printing {nullptr} if + the rest of the function cannot be safely executed. + + Fix-by: Dan Noé -- test: Make contained tests easier to write +- [Dan Noé brought this change] -- test: Add framework for containerized testing + Add missing limits.h include from ares_getaddrinfo.c (#267) - On Linux we can potentially use user and UTS namespaces to run a test - in a pseudo-container with: - - arbitrary filesystem (e.g. /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts) - - arbitrary hostname/domainname. + This files references INT_MAX, but does not include limits.h. This can + cause a build failure on some platforms. Include limits.h if we have it. - Include a first pass at the framework code to allow this, along with a - first test case that uses the container. + Fix-by: Dan Noé -- test: Use a longer timeout for less flakiness +- [Andrew Selivanov brought this change] + + fix fuzzer docs and add missing getaddrinfo docs (#265) - Having occasional test failures from timeout before multiple - queries can complete, so up the default timeout for the test - from 100ms to 1500ms. + There is a fix for a bit outdated clang fuzzer docs and ares_getaddrinfo docs. + + Fix By: Andrew Selivanov (@ki11roy) -- test: Make failure tests more robust +- [Andrew Selivanov brought this change] + + Fix leak and crash in ares_parse_a/aaaa_reply (#264) - Different platforms will do different numbers of allocations - in the processing of a given API call; just check that the - return code is either success or ENOMEM, and free off any - returned state in the former case. + * fix leak if naddress of particular type found + * fix segfault when wanted ttls count lesser than count of result records + * add fuzzer input files that trigger problems (from #263) - Also cope with ECONNREFUSED as well as ENOTFOUND. + Reported-By: David Drysdale (@daviddrysdale) + Fix-By: Andrew Selivanov (@ki11roy) -- test: Get test code building under Windows +- [Andrew Selivanov brought this change] + + fix segfault when parsing wrong type of record (#262) - - Initial nmake file based off library nmake file - - Cast socket call arguments to (char *) - - Use wrapper sclose() that maps to closesocket() or close() - - Build a config.h indicating presence of headers - - Conditionally include netdb.h - - Remove unnecessary include of sys/socket.h - - Force longer bitmask for allocation failure tracking - - Call WSAStartup() / WSACleanup() in main() - - Set TCP_NODELAY for mock server - - Turn on tests in AppVeyor build + Fixes segfault when trying to ares_parse_aaaa with AF_INET and vise versa. + + Fix By: Andrew Selivanov (@ki11roy) -- test: Disable tests that manipulate env on Windows +- work around mingw compile failure -- test: Move file lists into Makefile.inc +- c++ requires explicit casts + +- support EnvValue on Windows by implementing setenv/unsetenv + +- [Andrew Selivanov brought this change] + + getaddrinfo enhancements (#257) - In preparation for a Win32 build of the test suite. + * Service support has been added to getaddrinfo. + * ares_parse_a/aaaa_record now share code with the addrinfo parser. + * Private ares_addrinfo structure with useful extensions such as ttls (including cname ttls), + as well as the ability to list multiple cnames in chain of lookups + + Work By: Andrew Selivanov @ki11roy -- test: Add a simple multi-server test +- [Andrew Selivanov brought this change] + + fix ares__sortaddrinfo, use wrappers for sock_funcs (#258) - Check rotate option does something + Some socket functions weren't exposed for use by other areas of the library. Expose + those and make use of them in ares__sortaddrinfo(). + + Fix By: Andrew Selivanov (@ki11roy) -- test: Allow for multiple mock servers +- Fix c89 compilation support broken by .onion rejection changes - - Update the MockServer to allow separate specification of - UDP and TCP ports - - Have an array of mock servers listening on consecutive - sets of ports. - - Rename Process(fd) to ProcessFD(fd) to avoid confusion. - - Initialize channel by using the new ares_set_servers_ports() - entrypoint, so multiple ports on the same loopback address - can be used. - -- test: Update test for set/get_servers variants + Move .onion check lower after all variables have been declared. - Ports are significant in the _ports_ variant functions, so update test to cope. + Bug: #246 -- test: Make GetNameServers() utility function port-aware +- [kedixa brought this change] + + getaddrinfo: callback must be called on bad domain (#249) - Also make it generally available. + Due to an order of incrementing the remaining queries and calling ares_query, on a bad domain + the registered callback wouldn't be called. + + Bug: #248 + Fixed-By: @kedixa -- test: more testing, including of internal static functions +- [Darrin W. Cullop brought this change] -- test: more tests, especially fallback processing + Windows ARM/ARM64 requires AdvApi32 (#252) - - Make mock server listen on UDP + TCP in parallel. - - Test UDP->TCP fallback on truncation - - Test EDNS->no-EDNS fallback - - Test some environment init options - - Test nonsense reply + Fix link issues caused by missing library that appears to only be required on ARM (though + docs don't list this restriction). Doesn't hurt to require it everywhere. - test: short response + Bug: #251 + Fixed-By: Darrin Cullop (@dwcullop) -- test: more tests, particularly of initialization +- [kedixa brought this change] -- test: Run mock tests over both TCP and UDP + getaddrinfo: avoid infinite loop in case of NXDOMAIN(#240) (#242) - With the exception of a few tests that make use of the timed - retry aspect of UDP. - -- test: Run mock tests over both IPv4 and IPv6 + There are two possible causes for infinite loops fo NXDOMAIN, based on how many dots are in the domain name (one for < ARES_OPT_NDOTS and one for >= ARES_OPT_NDOTS), where it will repeat the same query over and over as the hquery->next_domain doesn't increment. + + Fix By: @kedixa -- test: Add more tests for edge cases +- Portability fix for ares__sortaddrinfo() + + replace uint32_t with unsigned int and socklen_t with ares_socklen_t + + By: Brad House -- test: more nooks and crannies of pton functions +- [Khaidi Chu brought this change] -- test: More tests for PTR parsing + fix: init bufp before reject .onion to make it can be free correctly (#241) + + When querying a .onion domain, it returns directly without setting bufp to NULL. A subsequent free() that occurs can cause a segmentation fault. + + Fix By: Khaidi Chu (@XadillaX) -- test: Use of HOSTALIAS environment variable +- [Andrew Selivanov brought this change] -- test: Add RAII utility classes for testing + Add ares__sortaddrinfo() to support getaddrinfo() sorted results (#239) - - TempFile holds specific contents - - EnvValue sets an environment variable + This is a port of RFC 6724 compliant sorting function from Android Bionic project: + https://android.googlesource.com/platform/bionic/+/e919b116d35aa7deb24ddece69c491e24c3b0d6f/libc/netbsd/net/getaddrinfo.c + + The latest version is essentially the same, except two additional parameters to test connection with (mark/uid): + https://android.googlesource.com/platform/bionic/+/master/libc/dns/net/getaddrinfo.c + + Please note that even that version has some restrictions. It doesn't support some rules from RFC 6724: + + Rule 3 (Avoid deprecated addresses) + Rule 4 (Prefer home addresses) + Rule 7 (Prefer native transport) + + Submitted By: Andrew Selivanov (@ki11roy) -- test: More search domain scenarios +- [Christian Ammer brought this change] -- test: Remove duplicate flags from Makefile.am + Increase portability of `ares-test-mock-ai.cc` (#235) + + * using portable ares_inet_pton and updated includes in ares-test-mock-ai + * forgot to remove deleted ares-test-ai.cc in Makefile.inc + + Fix By: Christian Ammer (@ChristianAmmer) -- test: Make test code leak-free +- [Fabrice Fontaine brought this change] -- test: More tests + m4/xc-cc-check.m4: use XC_CHECK_BUILD_FLAGS (#236) - - test use of sortlist - - test gethostbyname(AF_UNSPEC) - -- test: Test ares_gethostbyname_file() + Use XC_CHECK_BUILD_FLAGS instead of XC_CHECK_USER_FLAGS. + Otherwise it complains of CPPFLAGS in CFLAGS. + [Retrieved from: + https://git.buildroot.net/buildroot/tree/package/c-ares/0001-use_check_build_instead_of_check_user.patch] + + Signed-off-by: Gustavo Zacarias + Signed-off-by: Fabrice Fontaine + Submitted by: Fabrice Fontaine -- test: Add more tests of ares_getnameinfo() +- [Christian Ammer brought this change] -- test: Tweak tests, add alloc failure test + Bugfix for `ares_getaddrinfo` and additional unit tests (#234) + + This PullRequest fixes a bug in the function add_to_addrinfo which task is to add new addrinfo items to the ai_next linked list. Also additional unit tests for testing ares_getaddrinfo will be added: + + Additional mock server test classes (ares-test-mock-ai.cc): + MockTCPChannelTestAI + MockExtraOptsTestAI + MockNoCheckRespChannelTestAI + MockEDNSChannelTestAI + RotateMultiMockTestAI + NoRotateMultiMockTestAI + + Additional live tests (ares-test-live-ai.cc): + LiveGetHostByNameV4 + LiveGetHostByNameV6 + LiveGetHostByNameV4AndV6 + + Fix By: Christian Ammer (@ChristianAmmer) -- test: Test init with options +- [Christian Ammer brought this change] -- test: More tests + Remaining queries counter fix, additional unit tests for `ares_getaddrinfo` (#233) - - ares_inet_net_pton() variants - - ares_getsock() variants + Remaining queries counter fix, added tests (ParallelLookups, + SearchDomains, SearchDomainsServFailOnAAAA). Removed unnecessary + if and commented code in test. + + Fix By: Christian Ammer (@ChristianAmmer) -- test: Expose ProcessWork() function +- [Christian Ammer brought this change] -- test: More parsing tests + Add initial implementation for ares_getaddrinfo (#112) - Including: - - Split each parse function test set out into separate files. - - Add an allocation failure test for each parsing function. - - Add error check test for each parsing function. + Initial implementation for ares_getaddrinfo(). It is NOT compliant with RFC6724, though + it is expected to come closer to conformance prior to the next release. + + Features not supported include sorted addresses and honoring of service and hints + parameters. + + Implementation by: Christian Ammer (@ChristianAmmer) -- test: Add various additional tests +- [Ben Noordhuis brought this change] -- test: More tests + test: fix bad expectation in ipv6 localhost test (#227) - Include tests of internal functions, based on the value of the - CARES_SYMBOL_HIDING macro; need to configure the library with - --disable-symbol-hiding to enable these tests. - -- test: Allow command line override of mock server port + The LiveGetLocalhostByAddrV6 test expected to see "localhost" in the + result when doing an address-to-name lookup for ::1 but on my system + that resolves to "ip6-loopback" because of this stanza in /etc/hosts: + + $ grep ^::1 /etc/hosts + ::1 ip6-localhost ip6-loopback + + Fix By: Ben Noordhuis (@bnoordhuis) + Bug: #85 -- test: Add README.md documentation +- [Ben Noordhuis brought this change] -- test: Temporarily avoid latest Python requests package + ares_version.h: bump version (#230) - Currently get error from Travis on this install step, and downgrading one - version appears to fix the problem. + Version change not committed from maketgz.sh - "Could not find any downloads that satisfy the requirement pyOpenSSL>=0.13 - (from requests[security])" + Bug: #229 -- test: Add AppVeyor config file for Windows build +Daniel Stenberg (24 Oct 2018) +- ares_library_init_android.3: minor syntax edits, fixed AVAILABILITY -- test: Add configuration for a Travis build +Version 1.15.0 (23 Oct 2018) + +Brad House (23 Oct 2018) +- last minute 1.15.0 addition + +- [Ben Noordhuis brought this change] + + Report ARES_ENOTFOUND for .onion domain names as per RFC7686. (#228) - Cover Linux & OSX on the container infrastructure, but install - a later G++ to satisfy the tests' need for C++11. + Quoting RFC 7686: - Use a build matrix to include a variety of build variants: - - ASAN - - UBSAN - - LSAN - - Coverage via coveralls.io + Name Resolution APIs and Libraries (...) MUST either respond + to requests for .onion names by resolving them according to + [tor-rendezvous] or by responding with NXDOMAIN. - test: invoke ASAN and coverage in Travis build + A legacy client may inadvertently attempt to resolve a .onion + name through the DNS. This causes a disclosure that the client + is attempting to use Tor to reach a specific service. Malicious + resolvers could be engineered to capture and record such leaks, + which might have very adverse consequences for the well-being + of the user. - Also shift to use explicit build matrix + Bug: #196 + Fix By: Ben Noordhuis @bnoordhuis + +- prepare for c-ares 1.15.0 release + +- AIX Build Fix - test: Use coveralls.io for coverage tracking + AIX attempts to include both nameser_compat.h and onameser_compat.h. It appears + the proper fix is to define _USE_IRS so that only nameser_compat.h is used. - test: Add a build with UBSAN + Bug: #224 + Fix By: Brad House (@bradh352) + +- Fix crash in ares_dup() due to new ARES_OPT_RESOLVCONF - Also expand and re-order the setting of environment variables - for easier modification. + ares_dup() calls ares_init_options() by making its own fake option + mask since the original mask isn't stored but ARES_OPT_RESOLVCONF + was always set, instead of conditionally set. This caused a crash + because ares_strdup() isn't NULL-safe if no custom path was set. - test: Add LSAN build to Travis config + Made ares_dup() set ARES_OPT_RESOLVCONF conditionally. + + Fix By: Brad House (@bradh352) -- test: Add initial unit tests for c-ares library +- [Sarat Addepalli brought this change] + + Add ares_init_options() configurability for path to resolv.conf file - The tests are written in C++11, using the GoogleTest and GoogleMock - frameworks. They have their own independent autoconf setup, so that - users of the library need not have a C++ compiler just to get c-ares - working (however, the test/configure.ac file does assume the use of - a shared top-level m4/ directory). However, this autoconf setup has - only been tested on Linux and OSX so far. + Add resolvconf_path to end of struct ares_options with ARES_OPT_RESOLVCONF option + so on Unix-like systems a custom path can be specified. If no path is specified, + /etc/resolv.conf is used like normal. - Run with "./arestest", or "./arestest -v" to see extra debug info. - The GoogleTest options for running specific tests are also - available (e.g. "./arestest --gtest_filter=*Live*"). + Fix By: Sarat Addepalli @SirR4T + Fixes Bug: #220 + Review By: Brad House @bradh352 + +- remove stale variables + +- fix prototype name for ares_strsplit_free() + +- add missing prototype + +- simplify ares_strsplit() and create ares_strsplit_free() helper function + +- missing ares_strsplit.h from HHEADERS for inclusion in distribution + +- [Ruslan Baratov brought this change] + + Add CARES_BUILD_TOOLS CMake option (#214) - The tests are nowhere near complete yet (currently hitting around - 60% coverage as reported by gcov), but they do include examples - of a few different styles of testing: + Add ability to exclude building of tools (adig, ahost, acountry) in CMake. This should also close #200. - - There are live tests (ares-test-live.cc), which assume that the - current machine has a valid DNS setup and connection to the - internet; these tests issue queries for real domains but don't - particularly check what gets returned. The tests will fail on - an offline machine. + Fix By: Ruslan Baratov (@ruslo) + Bug: #200 + +- [flyingdutchman23 brought this change] + + Style. Whitespace cleanup. (#213) - - There a few mock tests (ares-test-mock.cc) that set up a fake DNS - server and inject its port into the c-ares library configuration. - These tests allow specific response messages to be crafted and - injected, and so are likely to be used for many more tests in - future. + Small whitespace cleanups. - - To make this generation/injection easier, the dns-proto.h file - includes C++ helper classes for building DNS packets. + Fix By: @flyingdutchman23 + +- [John Schember brought this change] + + Android: Support for domain search suffix (#211) - - Other library entrypoints that don't require network activity - (e.g. ares_parse_*_reply) are tested directly. + Fixes issue #207. Uses LinkProperties.getDomains() to get a list of search domains and adds them to the suffix list. This also adds a new helper function to split strings into an array based on multiple delimiters replacing multiple other functions for dealing with string splitting. - - There are few tests of library-internal functions that are not - normally visible to API users (in ares-test-internal.cc). + Submitter: John Schember (@user-none) + Fixes: #207 + Approved-by: Brad House (@bradh352) + +- [afalin brought this change] + + Improve DNS suffixes extracting from WinNT registry (#202) - - A couple of the tests use a helper method of the test fixture to - inject memory allocation failures, using the earlier change to the - library to allow override of malloc/realloc/free. + Join all global and connection specific suffix lists. Use 'HKLM\Software\Policies\Microsoft\Windows NT\DNSClient\SearchList', 'HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\Domain' as global suffix lists. - - There is also an entrypoint to allow Clang's libfuzzer to drive - the packet parsing code in ares_parse_*_reply, together with a - standalone wrapper for it (./aresfuzz) to allow use of afl-fuzz - for further fuzz testing. + Fix By: @afalin -- test: Add local copy of GoogleMock/GoogleTest 1.7.0 +- Be consistent with indention in CMakeLists.txt - Don't check in gtest/m4 files, as they are unused and interfere - with the top-level configure process. + The imported TRANSFORM_MAKEFILE_INC function from curl used space indention + but the rest of the file used tabs. Go ahead and make it tabs for + consistency as well. + + Committed By: Brad House -- doc: Show build badges in README.md +- [flyingdutchman23 brought this change] + + Fix modern gcc warning: argument to 'sizeof' in 'strncpy' call is the same expression as the source - Note that these URLs will need to be updated if/when the test branch - gets pulled into the master repo/branch. + Silence warning about using src to determine number of bytes to copy. + In this case it doesn't matter whether it is `src` or `dest`. So there + is no functionality change. + + Bug: #210 + Fix By: @flyingdutchman23 -- doc: Convert README to README.md +- [Andi Schnebinger brought this change] + + fix stringop-overflow warning of GCC (#201) - Gives better display on GitHub + When using a modern GCC to compile c-ares, there is a stringop-overflow warning. + This patch simply silences the false-positive warning, there is no actual code flaw. + + Bug: https://github.com/c-ares/c-ares/pull/201 + Fixed By: Andi Schnebinger @Iniesta8 -- doc: Update in preparation for next release +GitHub (18 May 2018) +- [David Drysdale brought this change] + + travis: do coverage in "coverage" build (#195) - Assume 1.11.0 is next (as there are various API additions). - Also add myself to AUTHORS. + Fixes #194, a mistake from commit a255081f2c3c ("travis: Only do + coverage/distcheck on normal build") -- build: Allow header compilation by Windows C++ compiler +Brad House (17 May 2018) +- [Brad Spencer brought this change] -- build: Expose whether symbol hiding is on + Apply the IPv6 server blacklist to all nameserver sources, not just Windows (#193) - Adding the CARES_SYMBOL_HIDING definition allows the test suite to - detect whether internal symbols are available or not. + For #164, I mentioned that it seemed like the IPv6 nameserver blacklist should apply to all OSes. In a mailing list post, @bradh352 agreed and suggested that I file a PR to make it so. + + This moves the blacklist check from being Windows-specific to being a general feature of config_nameservers(), no matter the nameserver source. It also simplifies the ares_ipv6_server_blacklisted() implementation to not parse and re-parse the blacklisted IPv6 addresses from strings on every check. I think they're almost as easy to read as a sequence of hex bytes in an array initializer, and it's definitely less work on each trip through the code. + + Fix By: Brad Spencer @b-spencer + PR: https://github.com/c-ares/c-ares/pull/193 -- build: Add autoconf macros for C++11 code using pthreads +- [Brad Spencer brought this change] + + Fix warnings emitted by MSVC when using -W4 (#192) - Pull in testing macros from the GNU autoconf archive to allow - configure scripts to test for and setup use of a C++11 compiler - (AX_CXX_COMPILE_STDCXX_11) and the pthreads library (AX_PTHREAD). + These changes fix a few warnings emitted by recent versions of MSVC when compiling with -W4. Half of the changes are in Windows-specific code, and the other half should be safe no matter the compiler or OS. - Note that these macros are not used by the main library autoconf, - just by the tests (which share the same m4/ directory). + The allocation function change is probably the only one that needs explanation. MSVC gives warnings about the function pointers not being stable across DLL boundaries or something to that effect, so for Windows, I've made them be called indirectly, which at least made the compiler happy. I can't say I've tested every linking combination on Windows with them before or after the change, but it seems harmless. + + Fix By: Brad Spencer @b-spencer + PR: https://github.com/c-ares/c-ares/pull/192 -- build: Add a code coverage option +- [David Hotham brought this change] + + Prevent changing name servers while queries are outstanding (#191) - Configure with: - ./configure --enable-code-coverage - Show coverage output with: - make code-coverage-capture + Changing name servers doesn't work, per #41. Better to return an error code than to crash. - Built on m4/ax_code_coverage.m4 from the GNU autoconf archive - to provide the macros to check for presence of gcov + lcov; - upstream macro modified to: - - Remove use of $(AM_DEFAULT_VERBOSITY) , as earlier versions of - autoconf (such as the one used by default on Travis) do not have this. - - Rather than automatically defining CODE_COVERAGE_RULES to be a set - of makefile rules that use ifeq/endif (which is GNU make-specific), - instead only define CODE_COVERAGE_RULES if coverages is turned on, - and in that case don't use conditionals in the makefile. + Fix-by: David Hotham @dimbleby -- api: Add entrypoints to allow use of per-server ports +David Drysdale (15 May 2018) +- [Tobias Nießen brought this change] + + Fix comment in ares_rules.h (#189) + +Brad House (6 May 2018) +- [Brad Spencer brought this change] + + Harden and rationalize c-ares timeout computation (#187) - Add user-visible entrypoints ares_{get,set}_servers_ports(3), which - take struct ares_addr_port_node rather than struct ares_addr_node. - This structure includes a UDP and TCP port number; if this is set - to zero, the channel-wide port values are used as before. + * Harden and rationalize c-ares timeout computation + * Remove the rand() part of the timeout calculation completely. - Similarly, add a new ares_set_servers_ports_csv(3) entrypoint, which - is analogous to ares_set_servers(3) except it doesn't ignore any - specified port information; instead, any per-server specified port - is used as both the UDP and TCP port for that server. + When c-ares sends a DNS query, it computes the timeout for that request as follows: - The internal struct ares_addr is extended to hold the UDP/TCP ports, - stored in network order, with the convention that a value of zero - indicates that the channel-wide UDP/TCP port should be used. + timeplus = channel->timeout << (query->try_count / channel->nservers); + timeplus = (timeplus * (9 + (rand () & 7))) / 16; + I see two issues with this code. Firstly, when either try_count or channel->timeout are large enough, this can end up as an illegal shift. - For the internal implementation of ares_dup(3), shift to use the - _ports() version of the get/set functions, so port information is - transferred correctly to the new channel. + Secondly, the algorithm for adding the random timeout (added in 2009) is surprising. The original commit that introduced this algorithm says it was done to avoid a "packet storm". But, the algorithm appears to only reduce the timeout by an amount proportional to the scaled timeout's magnitude. It isn't clear to me that, for example, cutting a 30 second timeout almost in half to roughly 17 seconds is appropriate. Even with the default timeout of 5000 ms, this algorithm computes values between 2812 ms and 5000 ms, which is enough to cause a slightly latent DNS response to get spuriously dropped. - Update manpages, and add missing ares_set_servers_csv to the lists - while we're at it - -- api: Add ares_set_sortlist(3) entrypoint + If preventing the timers from all expiring at the same time really is desirable, then it seems better to extend the timeout by a small factor so that the application gets at least the timeout it asked for, and maybe a little more. In my experience, this is common practice for timeouts: applications expect that a timeout will happen at or after the designated time (but not before), allowing for delay in detecting and reporting the timeout. Furthermore, it seems like the timeout shouldn't be extended by very much (we don't want a 30 second timeout changing into a 45 second timeout, either). - Allow explicit configuration of the channel's sortlist, by - specifying a string in the same format as the equivalent - /etc/resolv.conf option. + Consider also the documentation of channel->timeout in ares_init_options(): - This allows library users to perform the same configuration - that is available via /etc/resolv.conf, but without needing - to change that file. - -- api: Allow injection of user-specified malloc/free functions + The number of milliseconds each name server is given to respond to a query on the first try. (After the first try, the timeout algorithm becomes more complicated, but scales linearly with the value of timeout.) The default is five seconds. - Add a new ares_library_init_mem() initialization function for the - library which allows the library user to specify their own malloc, - realloc & free equivalents for use library-wide. + In the current implementation, even the first try does not use the value that the user supplies; it will use anywhere between 56% and 100% of that value. - Store these function pointers in library-wide global variables, - defaulting to libc's malloc(), realloc() and free(). + The attached patch attempts to address all of these concerns without trying to make the algorithm much more sophisticated. After performing a safe shift, this patch simply adds a small random timeout to the computed value of between 0 ms and 511 ms. I could see limiting the random amount to be no greater than a proportion of the configured magnitude, but I can't see scaling the random with the overall computed timeout. As far as I understand, the goal is just to schedule retries "not at the same exact time", so a small difference seems sufficient. - Change all calls to malloc, realloc and free to use the function pointer - instead. Also ensure that ares_strdup() is always available - (even if the local environment includes strdup(3)), and change the - library code to always use it. + UPDATE: randomization removed. - Convert calls to calloc() to use ares_malloc() + memset + Closes PR #187 + Fix by: Brad Spencer -- api: Add option to expose some internal functions +- distribute ares_android.h - Purely for testing, add --enable-expose-statics option to configure - which converts some static internal functions to be externally visible. - -- api: Expose the ares_library_initialized() function + Distribute ares_android.h when a release distribution package is + created. + + Reported By: Andrey Khranovsky + Bug: https://c-ares.haxx.se/mail/c-ares-archive-2018-04/0000.shtml -- ahost: Allow repeated -s options +- ares_set_servers_csv() on failure should not leave channel in a bad state - This also removes a potential leak where later -s options would - replace earlier ones without freeing the relevant string. + If bad data is passed to ares_set_servers_csv() or + ares_set_servers_ports_csv() it will clear the existing channel + configured DNS servers, then a call to ares_send() will fail due + to a bad malloc which may have undefined behavior. + + The fix now only clears existing servers on success. An additional + sanity check was added in ares_send() to ensure nservers >= 1 or + will result in ARES_ESERVFAIL. + + Bug: https://c-ares.haxx.se/mail/c-ares-archive-2018-03/0000.shtml + Reported-by: Francisco Sedano Crippa -- Mark unhittable lines +- docs: Not all manpages are listed - Add comments for the benefit of the lcov tool, marking - lines that cannot be hit. Typically these are fall-back - protection arms that are already covered by earlier checks, - and so it's not worth taking out the unhittable code (in case - someone changes the code between the two places in future). + Some docs aren't installed or not showing up on + https://c-ares.haxx.se/docs.html + due to not being listed in Makefile.inc. Add missing docs and + ensure docs are alphabetized. -- ares_set_servers_csv.3: make return type match code +Version 1.14.0 (16 Feb 2018) -- bitncmp: update comment to match code behaviour +Daniel Stenberg (16 Feb 2018) +- ares_android.c: fix warning: ISO C forbids an empty translation unit -- ares_striendstr: fix so non-NULL return can happen - - This looks to have been broken since it was first introduced in 2005 in - commit aba0b775ea30 ("Added ares_getnameinfo which mimics the - getnameinfo API") +- RELEASE-NOTES: some more work we did and people who helped -- config_sortlist: free any existing sortlist on (re)alloc failure +Brad House (16 Feb 2018) +- travis: skip Autotools style testing for cmake - If we get an allocation failure on 2nd or later entry in the sortlist, the - code would return ENOMEM but still leave the initial entries allocated. - Ensure that *sortlist is set to NULL whenever ENOMEM is returned. + Fix cmake test build by skipping autotools portion of test script. -- ares_dup: clear new channel on failure +- travis: standardize CMake test off of Autotools tests - If the attempt to transfer IPv6 servers from the old to the new channel - fails, the previous code would still return a channel to the user even though - an error return code was generated. This makes it likely that users would - leak the channel, so explicitly clear the channel in this case. + Instead of running 'make test', run the tests directly like autotools + does. It provides more verbose output. -- ares_init_options: don't lose init failure +- travis: Enable building tests for CMake - If (say) init_by_options() fails, the subsequent call to - init_by_defaults() was overwriting the return code with - success. Still call init_by_defaults() regardless, but track - its return value separately + Travis should auto-build and run tests for cmake builds now that + PR #168 is merged. -- ares_gethostbyname: don't leak valid-but-empty hostent - - If an AF_UNSPEC query gets a valid response to its AAAA query, - but which has no IPv6 addresses in it, then the code chains on to - a A record query. However, the hostent from the AAAA response - was being leaked along the way (because it gets replaced before - the follow-on end_hquery() invocation). +- fix version in pkgconfig -- ares_parse_txt_reply: propagate errors from per-substring loop +- Add version update to CMakeLists in maketgz + +- Release prep. Add support for pkgconfig in cmake, set versions appropriately + +Gregor Jasny (15 Feb 2018) +- CMake: Add tests + +Brad House (14 Feb 2018) +- [Gregor Jasny brought this change] + + Use cmake3 package provided by Ubuntu (#182) + +- Cmake 3.1 instead of 3.2.1 should be the minimum + +- Update RELEASE-NOTES and RELEASE-PROCEDURE.md to prepare for next release + +- get rid of c++ style comments + +- Use trusty for all builds, precise is EOL. Update clang and cmake versions. + +- Current CMakeLists.txt doesn't support 2.8.12 anymore, we need to bump the version to 3.2.1 minimum + +- Re-organize sections in INSTALL.md and add CMake section + +- [Sergey Kolomenkin brought this change] + + remove compilation warnings in MSVC (#47) + +- document handling of timeouts for ares_process and ares_process_fd to close PR #57 + +- As per Issue #155, since we do not require gethostname() during init, if it fails, there's no reason for init to fail as it is only used to populate the domain + +GitHub (7 Feb 2018) +- [David Drysdale brought this change] + + Document WSAStartup requirement (#180) + +David Drysdale (6 Feb 2018) +- [Antonio Tajuelo brought this change] + + Added coderelease.io badge to readme.md for letting people subscribe to new versions (#174) + +- [Sheel Bedi brought this change] + + Update year in LICENSE.md to 2018 (#170) + +GitHub (4 Feb 2018) +- [David Drysdale brought this change] + + travis: use VM not container for {L,A}SAN builds (#177) - If we get an allocation failure when processing a particular substring in a - TXT record, that failure is silently lost; fix that by propagating errors from - the inner loop to the outer loop. + As per https://github.com/travis-ci/travis-ci/issues/9033, container + based builds do not currently allow ptrace, which is used by LSAN and + ASAN. -- process_answer: fix things up correctly when removing EDNS option +Brad House (3 Feb 2018) +- [acthompson-google-com brought this change] + + Android JNI code leaks local references in some cases (#175) - When a server rejects an EDNS-equipped request, we retry without - the EDNS option. However, in TCP mode, the 2-byte length prefix was - being calculated wrong -- it was built from the answer length rather than - the length of the original request. + * Add Google LLC to AUTHORS. - Also, it is theoretically possible that the call to realloc() might change - the data pointed to; to allow for this, qbuf also needs updating. + * android: Explicitly delete all JNI local references, and cache JNI method IDs at initialization. - (Both these fixes were actually included in a patchset sent on the mailing - list in Oct 2012, but were included with other functional changes that - didn't get merged: - http://c-ares.haxx.se/mail/c-ares-archive-2012-10/0004.shtml) + * android: Only return ARES_ENOTINITIALIZED on failures in initialization code. -- ares__read_line: clear buf pointer on realloc failure +Gregor Jasny (2 Jan 2018) +- Embed fused Google Test 1.8.0 -- ares_expand_name: check for valid bits in label length - - The top two bits of the label length indicate whether this is a - label length (00) or an index to a name elsewhere in the message - (11). RFC1035 4.1.4 says that the other possible values for the - top two bits (01, 10) are reserved for future use. +Brad House (21 Dec 2017) +- [John Schember brought this change] -Daniel Stenberg (23 Jan 2016) -- [Gregor Jasny brought this change] + android: Check returns for obj and classes are not NULL. Document API levels for various Android functions and objects used. (#166) - Fix typos detected by lintian +- CARES_CHECK_TYPE should reference variable so a warning is not produced for -Werror compatibility + +- [Brad Spencer brought this change] + + Fix computation of IPv6 blacklist mask for values of netmask > 8. (#164) + +David Drysdale (14 Dec 2017) +- travis: Only do coverage/distcheck on normal build + +- travis: only do pip install on Linux + +- travis: only test in IPv4 mode - Closes #32 + Travis' Trusty environment does not support IPv6. + +- test: allow restriction to one IP address family + +- [Roman Teterin brought this change] + + Fix a typo in init_by_resolv_conf (#160) + +Brad House (11 Dec 2017) +- @gvanem says MSVC -RTCc option fails, looks erroneous to me, but the additional mask is harmless + +- Fix some other mingw warnings + +- Issue #143, get rid of windows build warning due to passing 'char **' to argument expecting 'const char **' - [Gregor Jasny brought this change] - Distribute all man pages + Distribute CMake files (#130) -- README.cares: s/I/Daniel +- Android variants may not have __system_property_get - ... and add a pointer to an existing version of the original area 1.1.1 - package.a + Some android systems like ARM64 may not have the __system_property_get + symbol in libc (but still have it in the public headers). Detect this + condition at build time. The __system_property_get method of retrieving + name servers is deprecated as of Oreo so should strictly be a fallback + mechanism anyhow. -- read_tcp_data: don't try to use NULL pointer after malloc failure +David Drysdale (9 Nov 2017) +- [David Hotham brought this change] + + Wrong function name throughout man page (#154) + +- ares_data.c: iterate through substructs when freeing - CID 56884, pointed out by Coverity. We really should make this function - return an error code so that a malloc() failure can return back a major - failure. + Previous code recursed into substructures, which makes it more likely + that large/heavily-nested responses could use up lots of stack. -- configure_socket: explicitly ignore return code +- test: test ares_free_data on long chain of structs + +- [Felix Yan brought this change] + + Fix a typo in inet_ntop.c (#151) + +Daniel Stenberg (29 Sep 2017) +- ares_gethostbyname.3: fix callback status values - CID 56889 in Coverity pointed out the return code from setsocknonblock() - is ignored, and this added typecast to (void) makes it explicit. + - ARES_ENOTFOUND means the _name_ wasn't found + + - ARES_ENODATA can be returned when a resolve fails + + Reported-by: Jakub Hrozek + Bug: https://c-ares.haxx.se/mail/c-ares-archive-2011-06/0012.shtml -- ahost: check the select() return code +Brad House (28 Sep 2017) +- [John Schember brought this change] + + Fix DNS server lookup breaking with Android O due to Android removing access to net.dns# system properties. (#148) - Fixes CID 137189, pointed out by Coverity + As of Android 8 (Oreo) access to net.dns# has been removed (https://developer.android.com/about/versions/oreo/android-8.0-changes.html). The reasoning given is that it, "improves privacy on the platform". Currently c-ares uses this to get the list of DNS servers. + + Now the only way to access the DNS server list is by using the Connectivity Manager though Java. This adds the necessary JNI code to use the Connectivity Manager and pull the DNS server list. The old way using __system_property_get with net.dns# remains for compatibilty. + + Using the Connectivity Manager requires the ACCESS_NETWORK_STATE permission to be set on the app. Existing applications most likely are not setting this and keeping the previous method as a fallback will at the very least ensure those apps don't break on older versions of Android. They will need to add this permission for Android 8 compatibility. + + Included in the patch are two initalization functions which are required. The JVM must be registered as well as the Connectivity Manager itself. There is no way to get the Connectivity Manager except though Java. Either being passed down to C directly or by passing in an Android Context which can be used to get the Connectivity Manager. Examples are provided in the documentation. -David Drysdale (18 Jan 2016) -- Fix buildconf on platforms using glibtoolize +- [Konstantinos Sofokleous brought this change] + + allow linking against the static msvc runtime library (#133) - Commit c49a87eea538 changed buildconf to only check for - libtoolize, but missed a line + allow linking against the static msvc runtime library -- Don't exit loop early leaving uninitialized entries +- [Gergely Nagy brought this change] + + Force using the ANSI versions of WinAPI functions (#142) - Update for commit affc63cba875d. + When compiling c-ares with a build system that defines UNICODE, + bad versions of WinAPI functions are used causing failures or even + crashes. When windows.h is included in MBCS mode (like in the default + build system), the ..A versions are the same as using the one without + any suffix. + +- [cmake] build fix on Solaris + +GitHub (11 Sep 2017) +- [Brad House brought this change] + + Win32 exclude legacy ipv6 subnets (#144) - The original patch from Gregor Jasny did not have the break - statement; I incorrectly added it to prevent continuing the loop. - However, the later entries in the array would then be left - uninitialized, causing problems for later cleanup. + win32 ipv6: add infrastructure to exclude ipv6 subnets that are known to cause issues + +- [David Drysdale brought this change] + + windows: only look for ancient compilers (#146) - So fix to match Gregor's original patch, with apologies. + Also drop the use of a versioned output directory; just use + .\msvc -Daniel Stenberg (18 Jan 2016) -- buildconf: remove check for libtool, it only requires libtoolize +- [David Drysdale brought this change] -David Drysdale (17 Jan 2016) -- [Gregor Jasny brought this change] + ares_init_options.3: match up sock_state_cb args (#141) + + Fixes #140 - Use libresolv to initialize cares on iPhone targets +Daniel Stenberg (25 Aug 2017) +- [Anna Henningsen brought this change] + + gethostbyaddr: fail with `ECANCELLED` for `ares_cancel()` - On iPhone targets like iOS, watchOS or tvOS the file - /etc/resolv.conf cannot be used to configure cares. + When `ares_cancel()` was invoked, `ares_gethostbyaddr()` + queries would fail with `ENOTFOUND` instead of `ECANCELLED`. - Instead the resolver library is queried for configuration - values. + It seems appropriate to treat `ares_cancel()` like `ares_destroy()`, + but I would appreciate review of the correctness of this change. - CC: Yury Kirpichev + Ref: https://github.com/nodejs/node/issues/14814 + + Closes #138 -Daniel Stenberg (17 Jan 2016) -- README: updated to new repo URL +David Drysdale (18 Aug 2017) +- [David Hotham brought this change] -David Drysdale (14 Jan 2016) -- [Lei Shi brought this change] + support most recent Visual Studio 2017 - Fixing slow DNS lookup issue +Brad House (26 Jul 2017) +- Preserve original DNS server order on Windows for equal metrics. - This patch is fixing the dns lookup issue due to dummy dns information - of a disconnected adapter(in my case is a bluetooth adapter). I changed - the dns lookup policy to try GetNetworkParams first because the - GetNetworkParams provides the most reliable dns information (lots of - checks were done by system). I also filter out inoperable adapter in - DNS_AdaptersAddresses in case GetNetworkParams fail. + qsort is not stable, in order to make it stable we need to record + the original index and add it as a secondary sort value when the + metrics are equal to prevent using DNS servers that may not work + at all as reported by some users. -- Merge pull request #30 from p-push/vs-2015 +David Drysdale (15 Jul 2017) +- [Anna Henningsen brought this change] + + ares_parse_naptr_reply: make buffer length check more accurate - Support Visual Studio 2015 + 9478908a490a6bf009ba58d81de8c1d06d50a117 introduced a length check + for records parsed by `ares_parse_naptr_reply()`. However, that + function is designed to parse replies which also contain non-NAPTR + records; for A records, the `rr_len > 7` check will fail as there + are only 4 bytes of payload. + In particular, parsing ANY replies for NAPTR records was broken + by that patch. + + Fix that by moving the check into the case in which it is already + known that the record is a NAPTR record. -Oleg Pudeyev (3 Jan 2016) -- [Gisle Vanem brought this change] +- appveyor: run dnsdump as a sanity check - Support Visual Studio 2015 +- travis: run dnsdump as a sanity check -David Drysdale (11 Nov 2015) -- [Andrew Andkjar brought this change] +- test: use ares_free_string() throughout + + As pointed out by Gisle Vanem in #125. - added another version case to Makefile.msvc +Daniel Stenberg (3 Jul 2017) +- RELEASE-PROCEDURE.md: how to release - nmake version 11.00.61030.0 resolves to CC_VERS_NUM = 110 + Fixes #115 + Closes #116 -- Merge pull request #26 from bitbouncer/vs-2013 +David Drysdale (2 Jul 2017) +- test: Build dnsdump on Windows too - added define for visual studio 2013 + Thanks to Gisle Vanem for showing the way: + https://github.com/c-ares/c-ares/commit/b701af8a24cf9d173b1dbe5faedcea34642e92da#commitcomment-22830845 -svante karlsson (25 Jun 2015) -- added define for visual studio 2013 +Brad House (26 Jun 2017) +- [Christian Ammer brought this change] -Jakub Hrozek (6 Nov 2014) -- ares__read_line: free buf on realloc failure + fix statement like #define - ares ssize_t define had a trailing semicolon (#120) -- Destroy options if ares_save_options fails +David Drysdale (21 Jun 2017) +- test: distribute the fuzzcheck.sh script - It's possible that, if ares_save_options failed, the opts structure - would contain some allocated memory. Calling ares_destroy_options in - this case is safe, because ares_save_options zeroes out the memory - initially. + The TESTS target runs fuzzcheck.sh so make sure it is included + in the distributed tarball. + + (The test itself will be pointless when run on a distribution, because + the fuzzing corpus directories are not shipped, but at least this + means that `make -C test test` should work.) -- [David Drysdale brought this change] +- test: run the name-parsing corpus check too - Continue loop if space for hostname not large enough +Daniel Stenberg (21 Jun 2017) +- dist: don't build/ship PDF versions in release archives - When attempting to build a search domain from the local hostname - (used as a fallback when no other methods have given a search - domain), the code doubles the buffer size on each loop iteration. - - However, the loop previously had a WHILE_FALSE terminator so the continue - statement exited the loop rather than going round again. + ... experience says very few read them and they can still get build by + those who want them.a -Daniel Stenberg (30 Oct 2014) -- ares_getnameinfo.3: there is no ares_getaddrinfo +- ares_version.h: bump version -David Drysdale (30 Sep 2014) -- [Gregor Jasny brought this change] +Version 1.13.0 (20 Jun 2017) - Prevent tmpbuf from overrunning +Daniel Stenberg (20 Jun 2017) +- RELEASE-NOTES: 1.13.0 + +- ares_set_socket_functions.3: added in 1.13.0 + +David Drysdale (18 Jun 2017) +- ares_parse_naptr_reply: check sufficient data - Fix Coverity error CID 56886. + Check that there is enough data for the required elements + of an NAPTR record (2 int16, 3 bytes for string lengths) + before processing a record. + +- test: Feed in short NAPTR + +- test: Add fuzz input with short NAPTR + +- test: add ares_parse_naptr_reply to fuzzer + +- [noiz brought this change] + + Update ares.h to support compiling with QNX + +- [Dionna Glaze brought this change] + + Simple changes to appease stricter compilers. - Signed-off-by: Gregor Jasny + ares_process.c uses htonl, which needs included. + ares_getnameinfo.c uses a dynamically selected format string for + sprintf, which -Wformat-literal doesn't like. Usually one would use + inttypes.h and a format string "%" PRIu32, but C99 is too new for some + supported platforms. +GitHub (16 Jun 2017) - [Gregor Jasny brought this change] - Re-start loop if select fails - - Fix Coverity error CID 56882 + CMake: Emulate interface library on import (#108) + Closes: #104 Signed-off-by: Gregor Jasny -- [Gregor Jasny brought this change] +Brad House (6 Jun 2017) +- [ChristianAmmer brought this change] - Free temporary variable in error path + Added support for Windows DNS Suffix Search List (#93) - Fix Coverity CID 56890 + This change solves issue #53. - Signed-off-by: Gregor Jasny + Support for suffix search lists was already built in for Linux. The search list could be set via set_search. With this change the suffix search list from Windows is read from the registry and then set into the ares configuration via set_search. There are two sources for the search list: + + The global DNS suffix search list. + The primary and connection specific DNS suffixes if the global is not available. + + Contributed by @ChristianAmmer -- [Gregor Jasny brought this change] +Daniel Stenberg (25 May 2017) +- [Thomas Köckerbauer brought this change] - Fix integer shift overflow if both tcp_socket and udp_socket are set + configure: do not heck for ar if specified manually - The problem occurs if at the start of the loop the sockindex is at the - last valid ARES_GETSOCK_MAXNUM position. If then both udp_socket and - tcp_socket are valid, sockindex gets incremented for UDP first and - points one entry behind the array for the tcp block. - So the fix is to check after every increment of sockindex if it is still - valid. + Closes #62 + +David Drysdale (23 May 2017) +- ares_expand_name: limit number of indirections + +- test: fuzz input file that takes a while to process + +- test: copy data in fuzz regression driver - Fix Coverity error CID 56878 + Oops. + +GitHub (23 May 2017) +- [David Drysdale brought this change] + + Convert char from ISO-8859-1 to UTF-8 (#99) - Signed-off-by: Gregor Jasny + Fixes #97 - [Gregor Jasny brought this change] - Null check before dereference + travis: Use trusty for cmake builds (#109) - Fix Coverity error CID 56880 - - Signed-off-by: Gregor Jasny + kubuntu-backports dropped the CMake package for Precise -Jakub Hrozek (28 Jul 2014) -- [Gisle Vanem brought this change] +David Drysdale (2 May 2017) +- [David Hotham brought this change] - Comment in ares_ipv6.h + msvc_ver.inc support most recent Visual Studio 2017 (#101) -David Drysdale (25 Jul 2014) -- CONTRIBUTING: add file to indicate mailing list is preferred +- test: use io.h not unistd.h for Windows -- Add -t u option to ahost - - Add an option to allow specification of the AF_UNSPEC - address family. +- test: try building fuzz binaries on Windows -Jakub Hrozek (24 Jul 2014) -- host_callback: Fall back to AF_INET on searching with AF_UNSPEC - - Previously, when an ares_gethostbyname() searched with AF_UNSPEC and the - first AF_INET6 call only returned CNAMEs, the host_callback never - retried AF_INET. +- test: stick to int in ares-fuzz.c - This patch makes sure than on ARES_SUCCESS, the result of AF_INET6 is - taken as authoritative only if the result contains some addresses. + Using int rather than ares_ssize_t means this file + needs no c-ares dependency - it's a general driver for + any libFuzzer-style entrypoint. -- [David Drysdale brought this change] +- test: force ARES_OPT_NOROTATE for no-rotate tests - Move memset call below platform-specific declarations - - A GitHub commenter [1] says that my recent change to ahost.c has - problems compiling on Windows + C89 platforms. +- test: check expected NOROTATE value + +- ares_create_query: use ares_free not naked free - [1] https://github.com/bagder/c-ares/commit/ee22246507c9#commitcomment-6587616 + Accidentally added in commit 65c71be1cbe5 + ("ares_create_query: avoid single-byte buffer overwrite") -- [David Drysdale brought this change] +Brad House (17 Mar 2017) +- Need ares.h for ares_ssize_t - Update ahost man page to describe -s option. - - Commit ee22246507c9 added the -s option to the - ahost command, but neglected to update the man page to - describe it. - - Also fix typo in description of -t option. +- tests should not use ssize_t, use ares_ssize_t -- ares_parse_soa_reply: Do not leak rr_name on allocation failure +GitHub (16 Mar 2017) +- [Brad House brought this change] + + Portability updates for legacy systems. (#92) - If ares_malloc_data failed, already allocated rr_name would go out of - scope. + Socklen_t should not be used in code, instead ares_socklen_t should be used. + Convert ssize_t to ares_ssize_t for portability since the public API now exposes this. -- [David Drysdale brought this change] +David Drysdale (14 Mar 2017) +- [Michael Osei brought this change] - Don't override explicitly specified search domains + Update msvc_ver.inc (#91) - Only set search domains from /etc/resolv.conf if there isn't a value - already present in the channel. + For Visual Studio 2017 builds -- [David Drysdale brought this change] +Daniel Stenberg (13 Mar 2017) +- [Brad House brought this change] - Allow specification of search domain in ahost + Windows DNS server sorting (#81) - Add the "-s domain" command line option to override the search - domains. - -Daniel Stenberg (12 May 2014) -- Revert "ares_parse_aaaa_reply: fix leak when reply contains 1 alias and no address" + Original Patch From Brad Spencer: + https://c-ares.haxx.se/mail/c-ares-archive-2016-04/0000.shtml - This reverts commit 440110b303fdbfadb3ad53d30eeb98cc45d70451. - -- [Frederic Germain brought this change] - - ares_parse_aaaa_reply: fix leak when reply contains 1 alias and no address - -- [Doug Kwan brought this change] - - ares_build.h: fix building on 64-bit powerpc + My modifications include: + * Dynamically find GetBestRoute2 since it is a Windows Vista+ symbol, and will fall back to prior behavior when not available. + * Prefer get_DNS_AdaptersAddresses as the modifications should alleviate the concerns which caused us to prefer get_DNS_NetworkParams + * Update AppVeyor to use MinGW-w64 instead of the legacy MinGW + * Fix compile error in test suite for Windows. - There are two issues. + Original message from patch below: - 1. gcc actually does not use __ppc__ and __ppc64__ but __PPC__ and - __PPC64__. The tests of __ILP32__ and __LP64__ are sufficient for gcc. + From: Brad Spencer + Date: Fri, 29 Apr 2016 14:26:23 -0300 - 2. clang defines __GNU__ and defines both __ppc64__ and __ppc__ when - targeting ppc64. This makes CARES_SIZEOF_LONG to be 4 on a ppc64 system - when building with clang. + On Windows, the c-ares DNS resolver tries first to get a full list of + DNS server addresses by enumerating the system's IPv4/v6 interfaces and + then getting the per-interface DNS server lists from those interfaces + and joining them together. The OS, at least in the way the c-ares + prefers to query them (which also may be the only or best way in some + environments), does not provide a unified list of DNS servers ordered + according to "current network conditions". Currently, c-ares will then + try to use them in whatever order the nested enumeration produces, which + may result in DNS requests being sent to servers on one interface + (hosting the current default route, for example) that are only intended + to be used via another interface (intended to be used when the first + interface is not available, for example). This, in turn, can lead to + spurious failures and timeouts simply because of the server address + order that resulted because of the enumeration process. - My patch is two change the order of the checks so that we check the - 64-bit case first. + This patch makes the (safe?) assumption that there is no other better + rule to chose which interface's DNS server list should be prioritized. + After all, a DNS lookup isn't something "per network"; applications + don't look up "these DNS names on this interface and those DNS names on + that interface". There is a single resource pool of DNS servers and the + application should presume that any server will give it the "right" + answer. However, even if all DNS servers are assumed to give equally + useful responses, it is reasonable to expect that some DNS servers will + not accept requests on all interfaces. This patch avoids the problem by + sorting the DNS server addresses using the Windows IPv4/v6 routing tables. + + For example, a request to DNS server C on interface 2 that is actually + sent over interface 1 (which may happen to have the default route) may + be rejected by or not delivered to DNS server C. So, better to use DNS + servers A and B associated with interface 1, at least as a first try. + + By using the metric of the route to the DNS server itself as a proxy for + priority of the DNS server in the list, this patch is able to adapt + dynamically to changes in the interface list, the DNS server lists per + interface, which interfaces are active, the routing table, and so on, + while always picking a good "best" DNS server first. + + In cases where any DNS server on any interface will do, this patch still + seems useful because it will prioritize a lower-metric route's (and thus + interface's) servers. -- refresh: updated now with automake 1.14 +David Drysdale (22 Feb 2017) +- [Sergii Pylypenko brought this change] -- [David Drysdale brought this change] + docs: fixed references to ares_set_local_ip4 and ares_set_local_ip6 - single_domain: Invalid memory access for empty string input +- [Calle Wilund brought this change] + + ares test: fix win32 build errors with virtual socket function tests - We noticed a small buglet in ares_search() when it gets an empty string - as input -- the single_domain() utility function in ares_search.c - accesses invalid memory (before the start of the string). + The added api requires both some typedefs not previously imported + into the test build + the test code did not fully deal with + socket differences on windows. -Guenter Knauf (31 Aug 2013) -- Fixed warning 'type specifier missing'. +- [Calle Wilund brought this change] -Daniel Stenberg (30 Aug 2013) -- [Tor Arntsen brought this change] + ares_process: fix return type of socket_create function (win32 warning) - ares_rules.h: CARES_SIZEOF_LONG doesn't exist anymore, don't test for it - - It was removed in f19387dd72432 +Daniel Stenberg (31 Jan 2017) +- [Calle Wilund brought this change] -- nowarn: use instead of configure for size of long + ares_set_socket_functions: Add man page - This makes the header file much more multi-arch friendly and can be used - as-is with both 32 bit and 64 bit builds. - -- timeoffset: made static and private + Providing some rudimentary documentation for the added functionality - ares__timeoffset() was only used once within this single source file + Closes #72 -- timeadd: make static +- [Calle Wilund brought this change] + + ares-test: Add test helpers and cases for virtual socket IO - ares__timeadd() was only ever used from within the same source + * Added test case macro to automatically run tests twice, once "normal", + once with virtual IO. + * Changed most "live" query tests to run in dual mode to verify + at least simple socket IO via virtual functions + * Added test case for settings/duping socket functions & callback data -Yang Tse (18 Jul 2013) -- xc-am-iface.m4: comments refinement +- [elcallio brought this change] -- configure: fix 'subdir-objects' distclean related issue + Implement using virtual socket IO functions when set - See XC_AMEND_DISTCLEAN comments for details. + Uses virtual socket IO functions when set on a channel. + Note that no socket options are set, nor is any binding + done by the library in this case, since the client defining + these is probably more suited to deal with this. -- configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) +- [elcallio brought this change] -- xc-am-iface.m4: provide XC_AUTOMAKE macro + Add virtual function set for socket IO + + Defines a structure of basic create, close, read/write + functions as virtual function calls, settable for individual + c-ares channels. -Daniel Stenberg (12 May 2013) -- gitignore: ignore all ares_*pdf but also CHANGES.dist +David Drysdale (30 Jan 2017) +- test: ignore aresfuzzname binary -- bump: start working towards 1.10.1 +Gregor Jasny (14 Jan 2017) +- [Stephen Sorley brought this change] -Version 1.10.0 (12 May 2013) + Always use check_symbol_exists instead of check_function_exists. -Daniel Stenberg (12 May 2013) -- RELEASE-NOTES: two more bug fixes +- Also add includes to TARGETS_INST_DEST -- [Keith Shaw brought this change] +- [Stephen Sorley brought this change] - ares_set_servers_csv: fixed IPv6 address parsing - - Fixed bug that caused the last part of an IPv6 address to be parsed as - the port number when the last part is all numeric. + Windows build fixes -- nroff: fix two syntax mistakes - - ares_parse_a_reply and ares_parse_aaaa_reply both had two \fB instead of - \fP - - Reported-by: Alexander Klauer - Bug: http://c-ares.haxx.se/mail/c-ares-archive-2013-03/0010.shtml +- CMake: Export targets -- [Alex Loukissas brought this change] +- CMake: Use GNUInstallDirs for install location defaults - build: fix build on msvc11 +David Drysdale (11 Jan 2017) +- Update Makefile.am for renamed INSTALL.md -- Makefile.am: increment -version-info for 1.10.0 release +GitHub (11 Jan 2017) +- [David Drysdale brought this change] -- README: remove unnecessary comment + docs: convert INSTALL to MarkDown & tweak (#83) -- ares_version.h: copyright end range year is now 2013 +- [Gregor Jasny brought this change] -- RELEASE-NOTES: synced with fb0737f3a0a1c37 + Merge pull request #77 from stephen-sorley/cmake_modernize + + Updated CMake minimum version to 2.8.12. -- [Paul Saab brought this change] +Stephen Sorley (4 Jan 2017) +- Changed executables to depend directly on internal libcares target, instead of against + the external-facing alias targets. - ares_parse_aaaa_reply: Plug memory leak +- Updated Travis to pull CMake 2.8.12 from kubuntu-backports ppa. + +- Updated CMake minimum version to 2.8.12. - This change is similar to ares_parse_a_reply.c in commit - bffd67f16a8f42fe6dbf79ab2e39d92eea05c8a6 + Changed the way usage requirements (include dirs, compile defs, dependent libraries) are specified, to match the recommended standard practice for modern CMake. This involves using target-specific functions (target_include_directories, target_compile_definitions, etc.), along with the PUBLIC, PRIVATE or INTERFACE modifiers. + + Updated chain-building support to imitate new-style Find modules (import libs), instead of old-style Find modules (cache variables). -- [Patrick Valsecchi brought this change] +David Drysdale (26 Dec 2016) +- [Chris Araman brought this change] - ares_parse_txt_reply: return a ares_txt_reply node for each sub-string + configure: clock_gettime workaround (#75) - Previously, the function would wrongly return all substrings merged into - one. + Commits 7518c26, c41726b, and bc14ee7 brought this workaround to the CMake build system. This expands it to the autoconf build system. + + Fixes #71 -- [Alexander Klauer brought this change] +- test: add fuzz entrypoint for ares_create_query() - library init: documentation update +- test: Add gTest/gMock files to SOURCES - This commit updates the documentation of ares_library_init() and - ares_library_cleanup() with regard to the newly introduced reference - counting of initializations and deinitializations. - -- [Alexander Klauer brought this change] + Built tarballs are not including all of the files needed + to build the test suite because they are missing from the + _SOURCES variable in Makefile.am. - library init: be recursive +- travis: Move build scripts under travis/ - Previously, a single call to ares_library_cleanup() would deinitialise - the c-ares library, regardless of how many times ares_library_init() was - called. This behaviour may cause problems in programs linking two or - more libraries which, in turn, use c-ares. The present commit fixes this - problem, deinitializing the library only after a number of calls to - ares_library_cleanup() matching the number of calls to - ares_library_init(). + Travis doesn't always propagate errors in inline multi-line + scripts, so move them all to be explicit shell scripts, each + with set -e. -- [Patrick Valsecchi brought this change] +- travis: check distributed tarball builds - protocol parsing: check input data stricter +Daniel Stenberg (25 Oct 2016) +- dist: ship msvc_ver.inc too - ... so that bad length fields aren't blindly accepted + Reported-by: Bruce Stephens - Bug: http://c-ares.haxx.se/mail/c-ares-archive-2013-04/0016.shtml + Fixes #69 -Guenter Knauf (11 Apr 2013) -- Create ares_build.h when buidling from Git. - -- Added -DCARES_STATICLIB to CFLAGS. - - Currently this static makefile does only support building the - static library libcares.a. +- [Aaron Bieber brought this change] -Daniel Stenberg (8 Apr 2013) -- [Alexander Klauer brought this change] + fix build on OpenBSD - .gitignore: ignore patch files - - This commit adds a line to .gitignore to the effect that patch files - generated by 'git format-patch' are excluded from the repository. +- ares_version.h: bump, working on 1.12.1 now -- [Alexander Klauer brought this change] +GitHub (18 Oct 2016) +- [Gregor Jasny brought this change] - ares_destroy() documentation: no new requests + Merge pull request #64 from bradh352/master - Clarify that no new requests may be added to a resolver channel that is - currently being destroyed. + Add CMake build system support to C-Ares. -- [Alexander Klauer brought this change] +Brad House (5 Oct 2016) +- suggested PROJECT_NAME change broke chain building as it needs the magic PROJECT_NAME set in the ADD_LIBRARY for matching. Fix to make both goals work - Documentation: properly document ARES_ECANCELLED - - This commit clarifies the behaviour of ares_cancel() with respect to - callbacks and adds missing documentation of ARES_ECANCELLED to the man - pages of the affected functions. +- update MacOSX 10.12 detection -- [Alexander Klauer brought this change] +- Expand XCode clock_gettime fix to include MacOS 10.12, not just iOS10 - ares_cancel(): cancel requests safely +David Drysdale (4 Oct 2016) +- Revert "travis: work around bug in PyCParser" - An invocation of ares_cancel() walks through the request list, calling - the callbacks of all pending requests on a channel. Previously, if such - a callback added a new request to the channel, the request list might - not end up empty, causing an abort by assertion failure. The present - commit ensures that precisely all requests present upon entry of - ares_cancel() are cancelled, and that adding new requests through - callbacks is safe. + This reverts commit a24a10a348fc00b8cfd684d91894a1df14880ea9. -Yang Tse (10 Mar 2013) -- ares.h: stricter CARES_EXTERN linkage decorations logic +- travis: work around bug in PyCParser - No API change involved. + See https://github.com/pyca/cryptography/issues/3187 -- ares_build.h.dist: enhance non-configure GCC ABI detection logic - - GCC specific adjustments: - - - check __ILP32__ before 32 and 64bit processor architectures in - order to detect ILP32 programming model on 64 bit processors - which, of course, also support LP64 programming model, when using - gcc 4.7 or newer. - - - keep 32bit processor architecture checks in order to support gcc - versions older than 4.7 which don't define __ILP32__ - - - check __LP64__ for gcc 3.3 and newer, while keeping 64bit processor - architecture checks for older versions which don't define __LP64__ +Brad House (3 Oct 2016) +- PROJECT_SOURCE_DIR instead of CMAKE_CURRENT_SOURCE_DIR as per @gjasny -Daniel Stenberg (9 Mar 2013) -- ares.h: there is no ares_free_soa function +- use a project name of c-ares as per @gjasny -Yang Tse (9 Mar 2013) -- Makefile.am: empty AM_LDFLAGS definition for automake 1.7 compatibility +- Import curl conversion of Makefile.inc to cmake form dynamically as per bdoetsch@ameritech.net to make maintaining multiple build systems easier -- ares_inet_ntop.3: s/socklen_t/ares_socklen_t +Daniel Stenberg (30 Sep 2016) +- dist: add ares_library_initialized.* to the tarball -- configure: use XC_LIBTOOL for portability across libtool versions +David Drysdale (30 Sep 2016) +- test: check ares_create_query with too-long name -- xc-lt-iface.m4: provide XC_LIBTOOL macro +Daniel Stenberg (30 Sep 2016) +- man pages: minor formatting edits -- Makefile.am: use AM_CPPFLAGS instead of INCLUDES +Brad House (29 Sep 2016) +- merge fc7917e from @daviddrysdale ... travis build updates for cmake -- inet_ntop.c: s/socklen_t/ares_socklen_t +- cleanups as per @gjasny ... Use naked IF statements and use NOT DEFINED -- inet_ntop.c: s/socklen_t/ares_socklen_t for portability +Version 1.12.0 (29 Sep 2016) -Daniel Stenberg (19 Feb 2013) -- ares.h: s/socklen_t/ares_socklen_t for portability +Daniel Stenberg (29 Sep 2016) +- RELEASE-NOTES: 1.12.0 -- ares_inet_ntop.3: 4th argument is socklen_t! +- [David Drysdale brought this change] -- spell inet correctly! + ares-test-misc: test ares_create_query with escaped trailing dot -- ares_inet_pton/ntop: cleanup +- ares_create_query: avoid single-byte buffer overwrite - Make sure that the symbols are always exported and present in c-ares. + ... when the name ends with an escaped dot. - Make the headers prefixed with 'ares'. + CVE-2016-5180 - Removed the inet_ntop.h version as it no longer features any content. - -- ares_inet_ntop/ares_inet_pton: added man pages + Bug: https://c-ares.haxx.se/adv_20160929.html -Yang Tse (15 Feb 2013) -- [Gisle Vanem brought this change] +Brad House (29 Sep 2016) +- CMake: Unify library versioning with the libtool methodology to make keeping library versions in sync easier with the autotools build system - curl_setup_once.h: definition of HAVE_CLOSE_S defines sclose() to close_s() +Daniel Stenberg (29 Sep 2016) +- ares_library_initialized.3: added -- [Gisle Vanem brought this change] +- make: bump CARES_VERSION_INFO for release - config-dos.h: define HAVE_CLOSE_S for MSDOS/Watt-32 +David Drysdale (29 Sep 2016) +- man: update ares_init_options.3 -- [Gisle Vanem brought this change] +Daniel Stenberg (29 Sep 2016) +- ares_library_init.3: corrected the ares_library_init_mem proto - config-dos.h: define strerror() to strerror_s_() for High-C +Brad House (28 Sep 2016) +- XCode v8 introduced clock_gettime() for iOS v10. However, it is a weak symbol, which means when earlier iOS versions try to use clock_gettime() it results in a crash due to the missing symbol. Detect this condition and do not set HAVE_CLOCK_GETTIME_MONOTONIC. -Daniel Stenberg (13 Feb 2013) -- ares_get_datatype: removed unused function +- Adds cmake build system support to C-Ares. - it was also wrongly named as internal functions require two underscores - -- ares__bitncmp: use two underscores for private functions + The patch does not modify any source files, it only adds 3 new files + (CMakelists.txt, ares_build.h.cmake, ares_config.h.cmake) which form the + build system. I've tried to go through as much of the autotools tests and + extracted what I thought was appropriate, though many of the tests aren't + as in-depth in CMake as they are for autotools ... it is unclear why some + of them exist at all, I'm guessing for legacy systems that CMake probably + doesn't support anyhow. - It used a single one previously making it look like a public one + Building the library, and examples (adig, ahost, acountry) plus installation + should work across a large number of tested platforms. The tests have not + yet been integrated. -- ares__generate_new_id: moved to ares_query.c - - ... and ares__rc4 is turned into a local static function. +Daniel Stenberg (27 Sep 2016) +- README.md: remove space from link -- ares__swap_lists: make private and static +- README: link to the correct c-ares badge! - ... since there's only one user, make it static within ares_process.c + Reported-by: David Hotham + + Fixes #63 -Yang Tse (13 Feb 2013) -- Makefile.msvc: add four VS version strings +- docs: minor formatting edits -Daniel Stenberg (13 Feb 2013) -- ares_expand_name.3: clarify how to free the data +- ares_destroy.3: formatting polish -Yang Tse (30 Jan 2013) -- zz40-xc-ovr.m4: fix 'wc' detection - follow-up 2 - - - Fix a pair of single quotes to double quotes. - - URL: http://curl.haxx.se/mail/lib-2013-01/0355.html - Reported by: Tor Arntsen +- ares_init.3: split the init docs into two separate man pages -- zz40-xc-ovr.m4: fix 'wc' detection - follow-up +- SECURITY: point to the vulnerabilities page now + +- RELEASE-NOTES: synced with daa7235b1a5 + +- ares_create_query.3: edit language - - Take into account that 'wc' may return leading spaces and/or tabs. + Tried to make the man page more readable. + +David Drysdale (26 Sep 2016) +- test: fix gMock to work with gcc >= 6.x - - Set initial IFS to space, tab and newline. + Taken from: + https://github.com/google/googletest/issues/705#issuecomment-235067917 -- zz40-xc-ovr.m4: fix 'wc' detection +Daniel Stenberg (26 Sep 2016) +- [Brad House brought this change] + + headers: remove checks for and defines of variable sizes - - Take into account that 'wc' may return leading spaces. + ... they're not really used and by avoiding them in the ares_build.h + output we make the public header less dependent on data sizes. + +David Drysdale (24 Sep 2016) +- api: add ARES_OPT_NOROTATE optmask value - - Set internationalization behavior variables. + Fix up a couple of problems with configuring whether c-ares rotates + between different name servers between requests. - Tor Arntsen analyzed and reported the issue. + Firstly, ares_save_options() returns (in *optmask) the value of + (channel->optmask & ARES_OPT_ROTATE), which doesn't necessarily + indicate whether the channel is or is not actually doing rotation. + This can be confusing/incorrect if: + - the channel was originally configured without ARES_OPT_ROTATE + (so it appears that the channel is not rotating) + - the /etc/resolv.conf file includes the 'rotate' option + (so the channel is actually performing rotation). - URL: http://curl.haxx.se/mail/lib-2013-01/0351.html - -- zz40-xc-ovr.m4: check another three basic utilities - -- zz40-xc-ovr.m4: 1.0 interface stabilization + Secondly, it is not possible to reliably configure a channel + to not-rotate; leaving off ARES_OPT_ROTATE is not enough, since + a 'rotate' option in /etc/resolv.conf will turn it on again. - - Stabilization results in 4 public interface m4 macros: - XC_CONFIGURE_PREAMBLE - XC_CONFIGURE_PREAMBLE_VER_MAJOR - XC_CONFIGURE_PREAMBLE_VER_MINOR - XC_CHECK_PATH_SEPARATOR - - Avoid one level of internal indirection - - Update comments - - Drop XC_OVR_ZZ40 macro - -- zz40-xc-ovr.m4: emit witness message in configure BODY + Therefore: + - add an ARES_OPT_NOROTATE optmask value to allow explicit + configuration of no-rotate behaviour + - in ares_save_options(), report the value of channel->rotate + as exactly one of (optmask & ARES_OPT_ROTATE) or + (optmask & ARES_OPT_NOROTATE). - This avoids witness message in output when running configure --help, - while sending the message to config.log for other configure runs. + In terms of back-compatibility: + - existing apps that set ARES_OPT_ROTATE will continue to rotate, + and to have ARES_OPT_ROTATE reported back from ares_save_options() + - existing apps that don't set ARES_OPT_ROTATE will continue to + use local config/defaults to decide whether to rotate, and will + now get ARES_OPT_ROTATE or ARES_OPT_NOROTATE reported back from + ares_save_options() rather than 0. -- zz40-xc-ovr.m4: truly do version conditional overriding +- ares_init_options: only propagate init failures from options - - version conditional overriding - - catch unexpanded XC macros - - fix double words in comments - -- zz40-xc-ovr.m4: fix variable assignment of subshell output bashism + Commit 46bb820be3a8 ("ares_init_options: don't lose init failure") + changed init behaviour so that earlier errors in initialization + weren't lost. In particular, if the user passes in specific + options but they are not applied (e.g. because of an allocation + failure), that failure needs to be reported back to the user; this + also applies when duplicating a channel with ares_dup(). - Tor Arntsen analyzed and reported the issue. + However, other initialization failures can be ignored and + overridden -- in particular, if init_by_resolv_conf() or + init_by_environment() fail, then falling back to default values + is OK. - URL: http://curl.haxx.se/mail/lib-2013-01/0306.html - -- zz40-xc-ovr.m4: reinstate strict AC_REQUIRE macro dependencies - -- zz40-xc-ovr.m4: avoid double single-quote usage - -- zz40-xc-ovr.m4: parentheses balancing of 'case' statements + So only preserve failures from the init_by_options() stage, not + from all initialization stages. - m4 quadrigraph shell comment technique allows proper autoconf - parentheses balancing in shell 'case' statements. The presence - of unbalanced parentheses may otherwise trigger expansion bugs. + Fixes issue 60. -- zz40-xc-ovr.m4: internals overhauling +- test: Force reinstall of libtool on OSX - - Update comments - - Execute commands in subshells - - Faster path separator check - - Fix missing 'test' command - - Rename private macros - - Minimize AC_REQUIRE usage + Travis build environment appears to have changed. -- zz40-xc-ovr.m4: redirect errors and warnings to stderr +- test: Add valgrind build variant -- configure: use XC_CONFIGURE_PREAMBLE early checks +- test: Add null pointer to gtest args - Some basic checks we make were placed early enough in generated - configure script when using autoconf 2.5X versions. Newer autoconf - versions expand these checks much further into the configure script, - rendering them useless. Using XC_CONFIGURE_PREAMBLE fixes placement - of early intended checks across all our autoconf supported versions. + GoogleTest assumes that there is a null pointer in argv[argc], + so make it look like that. Without this change, tests run with + command-line arguments get memory errors under valgrind/ASAN. -- zz40-xc-ovr.m4: provide XC_CONFIGURE_PREAMBLE macro +Daniel Stenberg (21 Aug 2016) +- AUTHOR: maybe gitgub isn't really an author =) -- configure: autotools compatibility fixes - step I - - Fix proper macro expansion order across autotools versions for - C compiler and preprocessor program checks. +- AUTHORS: added contributors from the git log -- configure: fix automake 1.13 compatibility - - Tested with: +- LICENSE.md: add a stand-alone license file - buildconf: autoconf version 2.69 - buildconf: autom4te version 2.69 - buildconf: autoheader version 2.69 - buildconf: automake version 1.13.1 - buildconf: aclocal version 1.13.1 - buildconf: libtool version 2.4 - buildconf: GNU m4 version 1.4.16 + Just the MIT license used in the top the source files moved out to a + stand-alone file for easier reference and discovery. -- ares_private.h: use again memdebug.h instead of curl_memdebug.h +- README: added "CII best practices" badge -- configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS - - automake 1.13 errors if AM_CONFIG_HEADER is used in configure script. +- SECURITY.md: suggested "security process" for the project -- cares-override.m4: provide AC_CONFIG_MACRO_DIR definition conditionally +David Drysdale (17 Aug 2016) +- test: Add Clang static analysis build to Travis - Provide a 'traceable' AC_CONFIG_MACRO_DIR definition only when using - an autoconf version that does not provide it, instead of what we were - doing up to now of providing and overriding AC_CONFIG_MACRO_DIR for - all autoconf versions. - -- ares_private.h: use curl_memdebug.h instead of memdebug.h + Run scan-build over the library source code, but skip the + tests. Needs a later Clang install in Travis -- vc6cares.dsp: add ares_create_query.c and ares_parse_soa_reply.c +- test: more info on how to run fuzz testing -- cares-functions.m4: improve gethostname arg 2 data type check +- test: make fuzzer driver code C not C++ -- setup_once.h: HP-UX specific 'bool', 'false' and 'true' definitions. +- test: fuzzer mode for AFL's persistent mode - Also reverts commit bceb40095a - -- configure: check if compiler halts on function prototype mismatch - -- cares-functions.m4: add gethostname arg 2 data type check and definition - -- cares-functions.m4: update thread-safeness detection of getaddrinfo() + When fuzzing with AFL, if the LLVM-based instrumentation is + used (via the afl-clang-fast wrapper), then it is possible to + have a single execution of the fuzzer program iterate multiple + times over the fuzzing entrypoint (similar to libFuzzer's normal + mode of execution) with different data. This is much (e.g. 10x) + faster. - Take in account that POSIX standard Issue 7 drops h_errno support. Now, we also - consider getaddrinfo() to be thread-safe when (_POSIX_C_SOURCE >= 200809L) or - (_XOPEN_SOURCE >= 700) independently of whether h_errno exists or not. + Add code to support this, by checking whether __AFL_LOOP is + defined at compile-time. - Take in account that h_errno might be a modifiable lvalue not defined as - a C preprocessor macro. + Also, shift the code to effectively be C rather than C++. -- setup_once.h: HP-UX issue workaround +- test: simplify deps for fuzzer entrypoint - Issue: When building a 32bit target with large file support HP-UX - header file may simultaneously provide two different - sets of declarations for sendfile and sendpath functions, one with - static and another with external linkage. Given that we do not use - mentioned functions we really don't care which linkage is the - appropriate one, but on the other hand, the double declaration emmits - warnings when using the HP-UX compiler and errors when using modern - gcc versions resulting in fatal compilation errors. + No need to depend on the rest of the test code (ares-test.h) for + the fuzzer entrypoint; this makes the entrypoint slightly simpler + to build with LLVM's libFuzzer. - Mentioned issue is now fixed as long as we don't use sendfile nor - sendpath functions. + Also shift the code to effectively be C rather than C++ -- setup_once.h: refactor inclusion of and +- test: disable MinGW tests - Inclusion of these two header files now done in setup_once.h - -- Header inclusion clean-up + The test binary built in the MinGW build is failing for some + reason. It works for me when I build locally, so I'm guessing + it's down to some sort of AppVeyor environment issue. - Remove header inclusions already done in setup_once.h + Disable for now. -- setup_once.h: HP-UX specific TRUE and FALSE definitions +Daniel Stenberg (16 Aug 2016) +- read_tcp_data: remove superfluous NULL check - Some HP-UX system headers require TRUE defined to 1 and FALSE to 0. - -- ares_timeout.c: fix compiler warning + CID 56884 by Coverity. The pointer is already derefenced before this + point so it can't be NULL here anyway. -- ares_create_query.c: IRIX compilation fix +- web: http => https -- c-ares/nameser.h: add some T_* defines for ns_t_* values +GitHub (20 Jul 2016) +- [David Drysdale brought this change] -Daniel Stenberg (7 Nov 2012) -- Revert "ares_parse_aaaa_reply: fix memory leak" + Merge pull request #59 from fuze/master - This reverts commit 50f25d8a4b2d16f4c5e0ef620238688b7a315c7a. + Update msvc_ver.inc for VS2015 Update 3 -- ares_parse_aaaa_reply: fix memory leak +- [Chris Araman brought this change] + + Update msvc_ver.inc - an allocated buffer was not freed in the successful case. + support Visual Studio 2015 Update 3 -- [Gisle Vanem brought this change] +David Drysdale (2 May 2016) +- Fix trailing comment for #endif - adig: perror() doesn't work for socket errors on windows - - ... so print the SOCKERRNO instead +Daniel Stenberg (30 Apr 2016) +- email: use Gisle's "new" address -- get_DNS_AdaptersAddresses: fix IPv6 parsing - - Use of the wrong define made the function not parse IPv6 addresses - properly. +David Drysdale (18 Apr 2016) +- test: drop superfluous fuzz inputs - Bug: http://c-ares.haxx.se/mail/c-ares-archive-2012-06/0028.shtml - Reported by: Saúl Ibarra Corretgé + Where there are multiple fuzz input files that only differ in + the first two bytes (the query ID), just keep the first such + file. -- version: bumped to 1.10.0 +svante karlsson (15 Apr 2016) +- Update msvc_ver.inc - Due to the newly added function: ares_create_query() + support Visual Studio 2015 Update 2 -- AUTHORS: synced with 83093ac450 +David Drysdale (31 Mar 2016) +- test: Run fuzzcheck.sh in Travis build + +- test: add fuzzing check script to tests - Added 21 authors since this document was last updated + Add a test script that runs the fuzzing command over the + corpus of DNS packets. This doesn't actually do any fuzzing + (it just runs them as inputs without generating any variations) + but it does ensure that the fuzzing entrypoint is still working. -- ares_create_query.3: mention when this is added +- test: allow multiple files in aresfuzz command line + + If no arguments are specified, use stdin as input. + Otherwise treat each argument as a filename and feed + its contents to the fuzz entrypoint. -- [hpopescu@ixiacom.com brought this change] +- test: Add corpus of DNS packets + + For fuzz testing it is useful to start from a corpus of valid + packets, so fill out the test/fuzzinput/ directory with a bunch + of inputs. + + These packets were generated by temporarily modifying the c-ares + process_answer() function to save off any incoming response messages. - Added new feature (rfc2671) +- test: Add utility to show DNS packet from file -- code police: fix indents, < 80 columns, reflowed comments +- [nordsturm brought this change] -Guenter Knauf (11 Jul 2012) -- Cleaned up version awk script. + Fix nsort initialization + + Author: Alexander Drachevskiy + http://c-ares.haxx.se/mail/c-ares-archive-2014-07/0004.shtml + http://c-ares.haxx.se/mail/c-ares-archive-2014-07/0014.shtml -Daniel Stenberg (30 Jun 2012) -- [Gisle Vanem brought this change] +- test: Check setting nsort=0 option is respected - read_udp_packets: bail out loop on bad sockets +- test: Update fuzzing function prototype - I can see that recvfrom() in ares_process.c many times is called with - 'udp_socket' == ARES_SOCKET_BAD. The code takes care not to call - recv/recvfrom with ARES_SOCKET_BAD in the outer-loop. So should the - inner-loop. + libFuzzer changed expected return type from void to int + in LLVM 3.8. -Yang Tse (29 Jun 2012) -- cares-compilers.m4: remove -Wstrict-aliasing=3 from clang +- Explicitly clear struct servent before use - Currently it is unknown if there is any version of clang that - actually supports -Wstrict-aliasing. What is known is that there - are several that don't support it. - -- cares-compilers.m4: -Wstrict-aliasing=3 for warning enabled gcc and clang builds + On a build where MSAN has been manually set up (which involves + using an MSAN-instrumented version of the standard C++ library, see + https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo) + there's a warning about use of uninitialized memory here. It + might be a false positive, but the fix is trivial so include it. -Daniel Stenberg (18 Jun 2012) -- version: work towards 1.9.2 (at least) +- test: for AF_UNSPEC, return CNAME only for AAAA, but valid A record + + Also shuffle expected responses rsp6/rsp4 into the order they will occur. -Version 1.9.1 (18 Jun 2012) +- [Chris Araman brought this change] -Daniel Stenberg (18 Jun 2012) -- RELEASE-NOTES: 1.9.1 coming up + msvc_ver.inc: support Visual Studio 2015 Update 1 -Version 1.9.0 (16 Jun 2012) +- build: commonize MSVC version detection + + Remove the need to copy/paste version number mapping between + Makefile.msvc and test/Makefile.msvc. -Daniel Stenberg (16 Jun 2012) -- ares_version.h: next version is 1.9.0 +- test: Use different name in live test -- [Marko Kreen brought this change] +- test: Only pass unused args to GoogleTest - ares_data.h: ARES_DATATYPE_SOA_REPLY is added in 1.9.0 +- ahost.c: add cast to fix C++ compile + + If ahost.c is force-compiled as C++ the missing cast from + (void *) to (char **) is problematic. -- RELEASE-NOTES: synced with 979bf951d +- ares_library_cleanup: reset ares_realloc too - Next release deemed to become 1.9.0 due to the new function + Otherwise a subsequent use of the library might use a previous + incarnation's realloc() implementation. -- [Marko Kreen brought this change] +Daniel Stenberg (9 Mar 2016) +- [Brad House brought this change] - SOA parser added + configure: check if tests can get built before enabled - I need to do SOA queries, so here is a parser for them. + The current approach for disabling tests is not a good solution because + it forces you to pass --disable-tests, rather than auto-detect if your + system can support the tests in the first place. Many (most?) systems + do not have C++11. This also causes issues when chain-building c-ares, + the hosting system needs to be updated to support passing this + additional flag if necessary, it doesn't seem reasonable to add this + requirement which breaks compatibility. - - ares_soa_reply: new struct - - ares_malloc_data/ares_free_soa: ARES_DATATYPE_SOA_REPLY - - ares_parse_soa_reply: actual function + This change auto-detects if the system can build the tests and + automatically disable them if it cannot. If you pass --enable-tests to + configure and the system cannot build them either due to lack of system + support, or because cross-compilation is being used, it will throw an + appropriate error since the user indicated they really did want the + tests. -Yang Tse (14 Jun 2012) -- Kill compiler warning +David Drysdale (3 Mar 2016) +- [Viktor Szakats brought this change] -- Fix libcares.pc generation for static MingW* cross builds + Makefile.m32: add support for CROSSPREFIX -Daniel Stenberg (21 May 2012) -- [Nick Alcock brought this change] +- [Viktor Szakats brought this change] - Fix UDP and TCP port byte order in saved options. + Makefile.m32: add support for extra flags - The UDP and TCP port are stored in network byte order in the - ares_channeldata, but are passed in to ares_init_options() in host byte - order. Thus we must return them from ares_save_options() in host byte - order too, or a duplicated channel will convert them again, leading to a - nonfunctional channel and a mysterious connection refused error from - ares_gethostbyname(). This breaks ares_dup(), thus the curl easy API - when c-ares is used by curl, and thus all the curl easy API's users. - -Yang Tse (28 Apr 2012) -- version: start working on 1.8.1-DEV + Allow specification of CARES_{LD,C}FLAG_EXTRAS envvars + for mingw -Version 1.8.0 (27 Apr 2012) +- test: Build with MinGW on AppVeyor -Daniel Stenberg (27 Apr 2012) -- RELEASE-NOTES: call next 1.8 instead +- test: avoid in6addr_* constants - Since we added a function, let's use a stricter bumping scheme + These aren't available on MinGW, so use explicit addresses instead. -Yang Tse (25 Apr 2012) -- INSTALL: some adjustments +- test: add missing #includes for dns-proto.cc -Daniel Stenberg (25 Apr 2012) -- GIT-INFO: mention buildconf +- [Gregor Jasny brought this change] -Yang Tse (25 Apr 2012) -- INSTALL: remove more sections that don't apply to c-ares + Fix man page typos detected by Lintian -- ares_timeout.c: fix compiler warning +Daniel Stenberg (19 Feb 2016) +- configure: acknowledge --disable-tests + + Fixes #44 -Daniel Stenberg (25 Apr 2012) -- [Ben Noordhuis brought this change] +- AUTHORS: added contributors from the 1.11.0 release - Makefile.m32: fix mingw32 build - - * add . to include path so ares_build.h is picked up - * make ar configurable to ease cross-compiling +- bump: start working on the next version -- RELEASE-NOTES: added what's happened since 1.7.5 +Version 1.11.0 (19 Feb 2016) -Guenter Knauf (22 Apr 2012) -- Updated copyright year. +Daniel Stenberg (19 Feb 2016) +- RELEASE-NOTES: final edits for 1.11.0 -Yang Tse (21 Apr 2012) -- ares_init.c: Further refactoring of Windows system's DNS fetching code +David Drysdale (15 Feb 2016) +- ares_dup.3: remove mention of nonexistent function + + ares_dup_options() doesn't exist, so don't document it. -Guenter Knauf (20 Apr 2012) -- Android: small changes to dns property part. +- test: skip repeated build steps - Prefix prop vars; kill var; use DNS_PROP_NAME_PREFIX macro. + Top-level buildconf/configure now triggers for the + test/ subdir too, so don't need to do explicitly. -- Handle CNAME-only in ares_parse_aaaa_reply(). +- test: namespaces unavailable when cross-compiling + +Daniel Stenberg (13 Feb 2016) +- configure: only run configure in test when NOT cross-compiling - posted to the c-ares list by Peter Griess . + ... as the tests won't run cross-compiled anyway -- Add support for multiple DNS servers on Android. +David Drysdale (13 Feb 2016) +- test: prefer ON_CALL to EXPECT_CALL to reduce flakes - Before, c-ares always used the first DNS server on Android, causing - network problems if this DNS server was not available. + For UDP tests, there's a chance of a retry. EXPECT_CALL only + expects a single request to arrive at the server; ON_CALL allows + for a UDP retry and repeats the same answer. - Signed-off-by: Geert Uytterhoeven + Note that ON_CALL and EXPECT_CALL can't be mixed in the same + test, and that tests that have a varied sequence of responses + for the same repeated request still have to use EXPECT_CALL. -- Added INSTALL so it gets into tarballs. +Daniel Stenberg (13 Feb 2016) +- configure: run configure in 'test' too + + Having the test dir completely stand-alone causes too many issues for + users and devs. It still needs to be built specifically. -- Added some more ifdefs to silent compiler warnings. +- configure: build silently by default -Yang Tse (17 Apr 2012) -- INSTALL: remove a non c-ares section +- buildconf: run test/buildconf too if present -- cares-compilers.m4: -Wno-pedantic-ms-format for Windows gcc 4.5 builds - - When building a Windows target with gcc 4.5 or newer and strict compiler - warnings enabled use -Wno-pedantic-ms-format in addition to other flags. +- test/configure: build silently by default -- setup_once.h: tighten requirements for stdbool.h header inclusion +- [Gregor Jasny brought this change] + + dist: Distribute README.md - Include stdbool.h only when it is available and configure is capable of - detecting a proper 'bool' data type when the header is included. + Closes #42 -- configure: NATIVE_WINDOWS no longer defined in config file +Version 1.11.0 (11 Feb 2016) -- cares-compilers.m4: double underscore decoration for visibility attribute +Daniel Stenberg (11 Feb 2016) +- Makefile.am: distribute the test dir too -- build adjustments: CARES_SYMBOL_HIDING no longer defined in config files - - configure script now provides conditional definitions for Makefile.am - that result in CARES_SYMBOL_HIDING being defined by resulting makefiles - when appropriate. +- RELEASE-NOTES: synced with 385582bd14b68a -- configure: Windows cross-compilation fixes +- [Nicolas \"Pixel\" Noble brought this change] + + ares_win32_init: make LoadLibrary work when using UNICODE too - CARES_BUILDING_LIBRARY and CARES_STATICLIB no longer defined in ares_config.h, - configure will generate appropriate conditionals so that mentioned symbols - get defined and used in Makefile derived from Makefile.am at compilation time. + Closes #17 -Guenter Knauf (17 Apr 2012) -- Added INSTALL file adapted from libcurl. +David Drysdale (11 Feb 2016) +- Use "resolve" as synonym of "dns" in nsswitch.conf - Not yet ready, and needs further edits. + Modern Linux systems may have libnss_resolve from systemd as the + resolver, which is then configured in /etc/nsswitch.conf with + the "resolve" keyword rather than "dns". + + Fixes #33 -Yang Tse (16 Apr 2012) -- ares_init.c: get_iphlpapi_dns_info() refactoring +- ares_set_socket_callback: make manpage match code + + The code in ares_process.c that invokes the socket creation/connection + callback only checks for rc < 0, not for standard ares error codes. -Guenter Knauf (16 Apr 2012) -- Kill some more compiler warnings. +- Merge pull request #36 from AGWA-forks/master + + Add ares_set_socket_configure_callback() -- Kill compiler warning about unused var. +- test: Update init tests to match behaviour + + Unreadable config files are now treated the same way + as absent config files. -- Fixed my last commit: wrong preprocessor directive. +- [Fedor Indutny brought this change] -- Check for __ANDROID__ in addition to ANDROID macro. + Ignore `fopen` errors to use default values + + After 46bb820be3a83520e70e6c5f0c5133253fcd69cd `init_by_resolv_conf` + errors are no longer swallowed in `ares_init_options`. This has exposed + a previously unknown bug in `lookups` initialization code. + + If there is no lookup configuration in `resolv.conf`, + `init_by_resolv_conf` will attempt to read it from other files available + on the system. However, some of these files may have restricted + permissions (like `600`), which will lead to `EACCESS` errno, which in + turn is handled like a fatal error by `init_by_resolv_conf`. + + However, it sounds illogical that this error should be handled as a + fatal. There is a `init_by_defaults` call that overrides `lookups` with + default value, and certainly possible absence of lookup information is + the reason why this function exists in a first place! + + I suggest handling any `fopen` errors as non-fatal ones, allowing to + pick up the `lookups` value from different config files, or to pick up + default value. -- Check for __ANDROID__ in addition to ANDROID macro. +Andrew Ayer (9 Feb 2016) +- Document callback type in man page for ares_set_socket_callback + +- Add ares_set_socket_configure_callback() - Posted to c-ares list by Wayne. + This function sets a callback that is invoked after the socket is + created, but before the connection is established. This is an ideal + time to customize various socket options. -- Fix for Android to disable useless arpa/nameser.h. +David Drysdale (9 Feb 2016) +- test: ares_set_socket_callback failure behaviour -- Fix for Android to include sys/select.h for fd_set. +- test: Check ares_parse_txt_reply_ext() entrypoint -Yang Tse (17 Mar 2012) -- ares_data.c: some NAPTR related fixes +- [Fedor Indutny brought this change] -Daniel Stenberg (16 Mar 2012) -- port numbers: convert them to network order! + txt: introduce `ares_parse_txt_reply_ext` - When the config options ARES_OPT_UDP_PORT or ARES_OPT_TCP_PORT are used, - make sure to convert them to network byte order! + Introduce `ares_txt_ext` structure with an extra `record_start` + field, which indicates a start of a new TXT record, thus allowing to + differentiate the chunks in the same record, from a chunks in a + different record. - Bug: http://c-ares.haxx.se/mail/c-ares-archive-2012-02/0004.shtml + Introduce a new API method: `ares_parse_txt_reply_ext` that works with + this kind of struct. -- white space cleanup +- doc: Update missed repo references + +- doc: Update docs on contributing + +- test: Run command line tools in Travis - - Keep code within 80 columns + Do a quick execution of each of the command line tools + in the continuous integration build, so that any (say) + sanitizer failures show up. + +- acountry: drop inert test - - Removed funny spaces after open paren and before closing paren + If ver_1 is true, then z0 and z1 must both be 'z', and so + (z0 != 'z' && z1 != 'z') can never be true. + + CID 56879, pointed out by Coverity. -- [Poul Thomas Lomholt brought this change] +- doc: update badge locations to master repo - get_iphlpapi_dns_info: fix buffer overrun +- test: Enable maintainer mode + debug in Travis + +- test: Add an iOS build target + +- test: Ignore SIGPIPE in tests + +- test: More initialization tests + +- test: Improve containerized test mechanism - I experienced a buffer overrun exception in c-ares on Windows and - tracked it down to be an error in the calculation of the 'left' variable - in get_iphlpapi_dns_info(). + Aim is to ensure that code coverage information can escape the + container. To do this: + - Enter a new mount namespace too, so that we can... + - Bind mount the expected source directory into the container + - Share memory with the sub-process so coverage information is + shared too. + +- test: Make contained tests easier to write + +- test: Add framework for containerized testing - I changed the variable type of 'left' to a _signed_ type because of the - subtraction arithmetic; not sure if a long is the best choice + On Linux we can potentially use user and UTS namespaces to run a test + in a pseudo-container with: + - arbitrary filesystem (e.g. /etc/resolv.conf, /etc/nsswitch.conf, /etc/hosts) + - arbitrary hostname/domainname. + + Include a first pass at the framework code to allow this, along with a + first test case that uses the container. -- Merge pull request #7 from saghul/naptr +- test: Use a longer timeout for less flakiness - Added support for parsing NAPTR records + Having occasional test failures from timeout before multiple + queries can complete, so up the default timeout for the test + from 100ms to 1500ms. -saghul (23 Feb 2012) -- Added support for parsing NAPTR records +- test: Make failure tests more robust + + Different platforms will do different numbers of allocations + in the processing of a given API call; just check that the + return code is either success or ENOMEM, and free off any + returned state in the former case. + + Also cope with ECONNREFUSED as well as ENOTFOUND. -Yang Tse (19 Jan 2012) -- ares_init.c: fix compiler warning on winsock builds +- test: Get test code building under Windows + + - Initial nmake file based off library nmake file + - Cast socket call arguments to (char *) + - Use wrapper sclose() that maps to closesocket() or close() + - Build a config.h indicating presence of headers + - Conditionally include netdb.h + - Remove unnecessary include of sys/socket.h + - Force longer bitmask for allocation failure tracking + - Call WSAStartup() / WSACleanup() in main() + - Set TCP_NODELAY for mock server + - Turn on tests in AppVeyor build -- configure: libtool 1.5 tweaks +- test: Disable tests that manipulate env on Windows -Daniel Stenberg (19 Dec 2011) -- ares_timeout.3: fix the NAME section +- test: Move file lists into Makefile.inc - It was clearly a copy n' paste error + In preparation for a Win32 build of the test suite. -Yang Tse (27 Sep 2011) -- [Albert Chin brought this change] +- test: Add a simple multi-server test + + Check rotate option does something - configure - m4: make CURL_CHECK_DEF ignore leading whitespace on symbol def +- test: Allow for multiple mock servers - When using Sun C compiler the preprocessor somehow inserts an extra space - in front of replaced symbol, breaking CURL_CHECK_DEF macro. To workaround - this, macro CURL_CHECK_DEF now ignores all leading whitespace in front of - symbol substitution result. + - Update the MockServer to allow separate specification of + UDP and TCP ports + - Have an array of mock servers listening on consecutive + sets of ports. + - Rename Process(fd) to ProcessFD(fd) to avoid confusion. + - Initialize channel by using the new ares_set_servers_ports() + entrypoint, so multiple ports on the same loopback address + can be used. -- ares_init.c: fix segfault triggered in ares_init_options() upon previous - failure of init_by_defaults() and incomplete cleanup there. +- test: Update test for set/get_servers variants + + Ports are significant in the _ports_ variant functions, so update test to cope. -- ares_process.c: fix compiler warning +- test: Make GetNameServers() utility function port-aware + + Also make it generally available. -- fix MSVC compiler warning 'conditional expression is constant' +- test: more testing, including of internal static functions -- setup_once.h cleanup and sync +- test: more tests, especially fallback processing + + - Make mock server listen on UDP + TCP in parallel. + - Test UDP->TCP fallback on truncation + - Test EDNS->no-EDNS fallback + - Test some environment init options + - Test nonsense reply + + test: short response -- [Denis Bilenko brought this change] +- test: more tests, particularly of initialization + +- test: Run mock tests over both TCP and UDP + + With the exception of a few tests that make use of the timed + retry aspect of UDP. + +- test: Run mock tests over both IPv4 and IPv6 + +- test: Add more tests for edge cases + +- test: more nooks and crannies of pton functions + +- test: More tests for PTR parsing + +- test: Use of HOSTALIAS environment variable + +- test: Add RAII utility classes for testing + + - TempFile holds specific contents + - EnvValue sets an environment variable + +- test: More search domain scenarios + +- test: Remove duplicate flags from Makefile.am + +- test: Make test code leak-free + +- test: More tests + + - test use of sortlist + - test gethostbyname(AF_UNSPEC) + +- test: Test ares_gethostbyname_file() + +- test: Add more tests of ares_getnameinfo() + +- test: Tweak tests, add alloc failure test + +- test: Test init with options + +- test: More tests + + - ares_inet_net_pton() variants + - ares_getsock() variants + +- test: Expose ProcessWork() function + +- test: More parsing tests + + Including: + - Split each parse function test set out into separate files. + - Add an allocation failure test for each parsing function. + - Add error check test for each parsing function. + +- test: Add various additional tests + +- test: More tests + + Include tests of internal functions, based on the value of the + CARES_SYMBOL_HIDING macro; need to configure the library with + --disable-symbol-hiding to enable these tests. + +- test: Allow command line override of mock server port + +- test: Add README.md documentation + +- test: Temporarily avoid latest Python requests package + + Currently get error from Travis on this install step, and downgrading one + version appears to fix the problem. + + "Could not find any downloads that satisfy the requirement pyOpenSSL>=0.13 + (from requests[security])" + +- test: Add AppVeyor config file for Windows build + +- test: Add configuration for a Travis build + + Cover Linux & OSX on the container infrastructure, but install + a later G++ to satisfy the tests' need for C++11. + + Use a build matrix to include a variety of build variants: + - ASAN + - UBSAN + - LSAN + - Coverage via coveralls.io + + test: invoke ASAN and coverage in Travis build + + Also shift to use explicit build matrix + + test: Use coveralls.io for coverage tracking + + test: Add a build with UBSAN + + Also expand and re-order the setting of environment variables + for easier modification. + + test: Add LSAN build to Travis config + +- test: Add initial unit tests for c-ares library + + The tests are written in C++11, using the GoogleTest and GoogleMock + frameworks. They have their own independent autoconf setup, so that + users of the library need not have a C++ compiler just to get c-ares + working (however, the test/configure.ac file does assume the use of + a shared top-level m4/ directory). However, this autoconf setup has + only been tested on Linux and OSX so far. + + Run with "./arestest", or "./arestest -v" to see extra debug info. + The GoogleTest options for running specific tests are also + available (e.g. "./arestest --gtest_filter=*Live*"). + + The tests are nowhere near complete yet (currently hitting around + 60% coverage as reported by gcov), but they do include examples + of a few different styles of testing: + + - There are live tests (ares-test-live.cc), which assume that the + current machine has a valid DNS setup and connection to the + internet; these tests issue queries for real domains but don't + particularly check what gets returned. The tests will fail on + an offline machine. + + - There a few mock tests (ares-test-mock.cc) that set up a fake DNS + server and inject its port into the c-ares library configuration. + These tests allow specific response messages to be crafted and + injected, and so are likely to be used for many more tests in + future. + + - To make this generation/injection easier, the dns-proto.h file + includes C++ helper classes for building DNS packets. + + - Other library entrypoints that don't require network activity + (e.g. ares_parse_*_reply) are tested directly. + + - There are few tests of library-internal functions that are not + normally visible to API users (in ares-test-internal.cc). + + - A couple of the tests use a helper method of the test fixture to + inject memory allocation failures, using the earlier change to the + library to allow override of malloc/realloc/free. + + - There is also an entrypoint to allow Clang's libfuzzer to drive + the packet parsing code in ares_parse_*_reply, together with a + standalone wrapper for it (./aresfuzz) to allow use of afl-fuzz + for further fuzz testing. + +- test: Add local copy of GoogleMock/GoogleTest 1.7.0 + + Don't check in gtest/m4 files, as they are unused and interfere + with the top-level configure process. + +- doc: Show build badges in README.md + + Note that these URLs will need to be updated if/when the test branch + gets pulled into the master repo/branch. + +- doc: Convert README to README.md + + Gives better display on GitHub + +- doc: Update in preparation for next release + + Assume 1.11.0 is next (as there are various API additions). + Also add myself to AUTHORS. + +- build: Allow header compilation by Windows C++ compiler + +- build: Expose whether symbol hiding is on + + Adding the CARES_SYMBOL_HIDING definition allows the test suite to + detect whether internal symbols are available or not. + +- build: Add autoconf macros for C++11 code using pthreads + + Pull in testing macros from the GNU autoconf archive to allow + configure scripts to test for and setup use of a C++11 compiler + (AX_CXX_COMPILE_STDCXX_11) and the pthreads library (AX_PTHREAD). + + Note that these macros are not used by the main library autoconf, + just by the tests (which share the same m4/ directory). + +- build: Add a code coverage option + + Configure with: + ./configure --enable-code-coverage + Show coverage output with: + make code-coverage-capture + + Built on m4/ax_code_coverage.m4 from the GNU autoconf archive + to provide the macros to check for presence of gcov + lcov; + upstream macro modified to: + - Remove use of $(AM_DEFAULT_VERBOSITY) , as earlier versions of + autoconf (such as the one used by default on Travis) do not have this. + - Rather than automatically defining CODE_COVERAGE_RULES to be a set + of makefile rules that use ifeq/endif (which is GNU make-specific), + instead only define CODE_COVERAGE_RULES if coverages is turned on, + and in that case don't use conditionals in the makefile. + +- api: Add entrypoints to allow use of per-server ports + + Add user-visible entrypoints ares_{get,set}_servers_ports(3), which + take struct ares_addr_port_node rather than struct ares_addr_node. + This structure includes a UDP and TCP port number; if this is set + to zero, the channel-wide port values are used as before. + + Similarly, add a new ares_set_servers_ports_csv(3) entrypoint, which + is analogous to ares_set_servers(3) except it doesn't ignore any + specified port information; instead, any per-server specified port + is used as both the UDP and TCP port for that server. + + The internal struct ares_addr is extended to hold the UDP/TCP ports, + stored in network order, with the convention that a value of zero + indicates that the channel-wide UDP/TCP port should be used. + + For the internal implementation of ares_dup(3), shift to use the + _ports() version of the get/set functions, so port information is + transferred correctly to the new channel. + + Update manpages, and add missing ares_set_servers_csv to the lists + while we're at it + +- api: Add ares_set_sortlist(3) entrypoint + + Allow explicit configuration of the channel's sortlist, by + specifying a string in the same format as the equivalent + /etc/resolv.conf option. + + This allows library users to perform the same configuration + that is available via /etc/resolv.conf, but without needing + to change that file. + +- api: Allow injection of user-specified malloc/free functions + + Add a new ares_library_init_mem() initialization function for the + library which allows the library user to specify their own malloc, + realloc & free equivalents for use library-wide. + + Store these function pointers in library-wide global variables, + defaulting to libc's malloc(), realloc() and free(). + + Change all calls to malloc, realloc and free to use the function pointer + instead. Also ensure that ares_strdup() is always available + (even if the local environment includes strdup(3)), and change the + library code to always use it. + + Convert calls to calloc() to use ares_malloc() + memset + +- api: Add option to expose some internal functions + + Purely for testing, add --enable-expose-statics option to configure + which converts some static internal functions to be externally visible. + +- api: Expose the ares_library_initialized() function + +- ahost: Allow repeated -s options + + This also removes a potential leak where later -s options would + replace earlier ones without freeing the relevant string. + +- Mark unhittable lines + + Add comments for the benefit of the lcov tool, marking + lines that cannot be hit. Typically these are fall-back + protection arms that are already covered by earlier checks, + and so it's not worth taking out the unhittable code (in case + someone changes the code between the two places in future). + +- ares_set_servers_csv.3: make return type match code + +- bitncmp: update comment to match code behaviour + +- ares_striendstr: fix so non-NULL return can happen + + This looks to have been broken since it was first introduced in 2005 in + commit aba0b775ea30 ("Added ares_getnameinfo which mimics the + getnameinfo API") + +- config_sortlist: free any existing sortlist on (re)alloc failure + + If we get an allocation failure on 2nd or later entry in the sortlist, the + code would return ENOMEM but still leave the initial entries allocated. + Ensure that *sortlist is set to NULL whenever ENOMEM is returned. + +- ares_dup: clear new channel on failure + + If the attempt to transfer IPv6 servers from the old to the new channel + fails, the previous code would still return a channel to the user even though + an error return code was generated. This makes it likely that users would + leak the channel, so explicitly clear the channel in this case. + +- ares_init_options: don't lose init failure + + If (say) init_by_options() fails, the subsequent call to + init_by_defaults() was overwriting the return code with + success. Still call init_by_defaults() regardless, but track + its return value separately + +- ares_gethostbyname: don't leak valid-but-empty hostent + + If an AF_UNSPEC query gets a valid response to its AAAA query, + but which has no IPv6 addresses in it, then the code chains on to + a A record query. However, the hostent from the AAAA response + was being leaked along the way (because it gets replaced before + the follow-on end_hquery() invocation). + +- ares_parse_txt_reply: propagate errors from per-substring loop + + If we get an allocation failure when processing a particular substring in a + TXT record, that failure is silently lost; fix that by propagating errors from + the inner loop to the outer loop. + +- process_answer: fix things up correctly when removing EDNS option + + When a server rejects an EDNS-equipped request, we retry without + the EDNS option. However, in TCP mode, the 2-byte length prefix was + being calculated wrong -- it was built from the answer length rather than + the length of the original request. + + Also, it is theoretically possible that the call to realloc() might change + the data pointed to; to allow for this, qbuf also needs updating. + + (Both these fixes were actually included in a patchset sent on the mailing + list in Oct 2012, but were included with other functional changes that + didn't get merged: + http://c-ares.haxx.se/mail/c-ares-archive-2012-10/0004.shtml) + +- ares__read_line: clear buf pointer on realloc failure + +- ares_expand_name: check for valid bits in label length + + The top two bits of the label length indicate whether this is a + label length (00) or an index to a name elsewhere in the message + (11). RFC1035 4.1.4 says that the other possible values for the + top two bits (01, 10) are reserved for future use. + +Daniel Stenberg (23 Jan 2016) +- [Gregor Jasny brought this change] + + Fix typos detected by lintian + + Closes #32 + +- [Gregor Jasny brought this change] + + Distribute all man pages + +- README.cares: s/I/Daniel + + ... and add a pointer to an existing version of the original area 1.1.1 + package.a - ares_getnameinfo: fix random results with c-ares 1.7.5 +- read_tcp_data: don't try to use NULL pointer after malloc failure - In ares_getnameinfo memcpy did not copy enough bytes, causing - it to return arbitrary memory contents as a result. - -- warnings: fix another 'conversion may lose significant bits' compiler warning + CID 56884, pointed out by Coverity. We really should make this function + return an error code so that a malloc() failure can return back a major + failure. -- ares_dns.h: adjust DNS__16BIT and DNS__32BIT macro definitions +- configure_socket: explicitly ignore return code - Fixing compiler warnings existing definitions triggered on these. + CID 56889 in Coverity pointed out the return code from setsocknonblock() + is ignored, and this added typecast to (void) makes it explicit. -- ares_destroy.c: fix segfault in ares_destroy_options() +- ahost: check the select() return code + + Fixes CID 137189, pointed out by Coverity -Daniel Stenberg (21 Aug 2011) -- ares_parse_srv_reply: silence compiler warnings +David Drysdale (18 Jan 2016) +- Fix buildconf on platforms using glibtoolize - ... by adding ugly typecasts. + Commit c49a87eea538 changed buildconf to only check for + libtoolize, but missed a line -- CHANGES: generate from script +- Don't exit loop early leaving uninitialized entries - The CHANGES file is now generated automatically with 'git2changes.pl', - invoked by the maketgz script which is used to build release archives. + Update for commit affc63cba875d. - The former human edited CHANGES file was renamed to CHANGES.0 in git. - -Yang Tse (21 Aug 2011) -- Makefile.netware: SIZEOF_SHORT definition - -- warnings: fix some 'conversion may lose significant bits' compiler warnings - -- configure: fix symbol hiding usability check + The original patch from Gregor Jasny did not have the break + statement; I incorrectly added it to prevent continuing the loop. + However, the later entries in the array would then be left + uninitialized, causing problems for later cleanup. - A more thorough test is done now in order to determine visibility attribute - usability, given that some compilers don't support visibility attribute on - all configurations. + So fix to match Gregor's original patch, with apologies. -Daniel Stenberg (16 Aug 2011) -- 1.7.6: start working... +Daniel Stenberg (18 Jan 2016) +- buildconf: remove check for libtool, it only requires libtoolize -Version 1.7.5 (16 Aug 2011) +David Drysdale (17 Jan 2016) +- [Gregor Jasny brought this change] -Daniel Stenberg (16 Aug 2011) -- CHANGES: synced for 1.7.5 release + Use libresolv to initialize cares on iPhone targets + + On iPhone targets like iOS, watchOS or tvOS the file + /etc/resolv.conf cannot be used to configure cares. + + Instead the resolver library is queried for configuration + values. + + CC: Yury Kirpichev -- RELEASE-NOTES: synced with bb4096effef7f000 +Daniel Stenberg (17 Jan 2016) +- README: updated to new repo URL -Jakub Hrozek (15 Aug 2011) -- Only fall back to AF_INET searches when looking for AF_UNSPEC addresses +David Drysdale (14 Jan 2016) +- [Lei Shi brought this change] -Yang Tse (10 Aug 2011) -- [Gisle Vanem brought this change] + Fixing slow DNS lookup issue + + This patch is fixing the dns lookup issue due to dummy dns information + of a disconnected adapter(in my case is a bluetooth adapter). I changed + the dns lookup policy to try GetNetworkParams first because the + GetNetworkParams provides the most reliable dns information (lots of + checks were done by system). I also filter out inoperable adapter in + DNS_AdaptersAddresses in case GetNetworkParams fail. - ares_iphlpapi.h: Watcom C fix +- Merge pull request #30 from p-push/vs-2015 - Added "!defined(_WS2DEF_)" since Watcom doesn't have - a per type guard for the typedefs 'CSADDR_INFO' (that MingW has) or - 'SOCKET_ADDRESS' (that MSVC has). But we can use the header-guard for - instead. + Support Visual Studio 2015 +Oleg Pudeyev (3 Jan 2016) - [Gisle Vanem brought this change] - Makefile.Watcom: - * The 'NTDDI_VERSION' needs to be raised to 0x05010000 - in order for SOCKADDR_STORAGE etc. to be typedefed. - * Replaced '-dUSE_WATT32' with '-dWATT32'. - * Added $(DEMOS) to the 'all' target and removed the 'demos' - target to be consistent with e.g. Makefile.msvc etc. - * 'ENABLE_IPV6' is no longer used. Hence removed the '%use_ipv6' construct. - * object-file order seems to be important (Watcom v.19). Hence - 'ares_getopt.obj' must be put after the .obj that references getopt(). - -- cares-compilers.m4: CARES_CONVERT_INCLUDE_TO_ISYSTEM adjustments - - Add CARES_CHECK_COMPILER as a requirement. - - Ensure macro does nothing unless GNU_C or CLANG compiler is used. - - This should allow usage of this macro in unforeseen placements. + Support Visual Studio 2015 -- config-win32.h: comments adjustments - followup +David Drysdale (11 Nov 2015) +- [Andrew Andkjar brought this change] -- config-win32.h: comments adjustments + added another version case to Makefile.msvc + + nmake version 11.00.61030.0 resolves to CC_VERS_NUM = 110 -Daniel Stenberg (5 Aug 2011) -- [Tom Hughes brought this change] +- Merge pull request #26 from bitbouncer/vs-2013 + + added define for visual studio 2013 - ares_parse_a_reply: fix memleak +svante karlsson (25 Jun 2015) +- added define for visual studio 2013 -Yang Tse (29 Jul 2011) -- cares-functions.m4 serial # bump +Jakub Hrozek (6 Nov 2014) +- ares__read_line: free buf on realloc failure -- Revert "configure: additional flag checks for fcntl() and socket()" +- Destroy options if ares_save_options fails - This reverts commit 5f2a3b0e48f26d24cb1fefea0dccb92d417dcbf7. + It's possible that, if ares_save_options failed, the opts structure + would contain some allocated memory. Calling ares_destroy_options in + this case is safe, because ares_save_options zeroes out the memory + initially. -- configure: additional flag checks for fcntl() and socket() +- [David Drysdale brought this change] -- xc-translit.m4 fix quoting + Continue loop if space for hostname not large enough + + When attempting to build a search domain from the local hostname + (used as a fallback when no other methods have given a search + domain), the code doubles the buffer size on each loop iteration. + + However, the loop previously had a WHILE_FALSE terminator so the continue + statement exited the loop rather than going round again. -- configure: avoid direct usage of AS_TR_* macros +Daniel Stenberg (30 Oct 2014) +- ares_getnameinfo.3: there is no ares_getaddrinfo -- xc-translit.m4 provides transliteration macros with well defined behavior. +David Drysdale (30 Sep 2014) +- [Gregor Jasny brought this change] -Jakub Hrozek (15 Jun 2011) -- Revert "Only fall back to AF_INET searches when looking for AF_UNSPEC addresses" + Prevent tmpbuf from overrunning - This reverts commit b5823d65706af687c0e5110af8f0cfdcd068997d. + Fix Coverity error CID 56886. - This patch was not reviewed properly before pushing + Signed-off-by: Gregor Jasny -- Revert "Do not use sized constants in public headers" +- [Gregor Jasny brought this change] + + Re-start loop if select fails - This reverts commit 22c01e96f7b2ae9923e1baa50bfe3c0d22297a7d. + Fix Coverity error CID 56882 - This is a Red Hat specific patch that does not belong into upstream - -- Use correct sizeof in ares_getnameinfo() - -- Do not leak rr_name on failures inside ares_parse_ptr_reply - -- Do not leak rr_name on failures inside ares_parse_a_reply + Signed-off-by: Gregor Jasny -- Do not leak rr_name on failures inside ares_parse_aaaa_reply +- [Gregor Jasny brought this change] -- Do not leak rr_name on failures inside ares_parse_ns_reply + Free temporary variable in error path + + Fix Coverity CID 56890 + + Signed-off-by: Gregor Jasny -- Fix incorrect sizeof() in ares_save_options +- [Gregor Jasny brought this change] -- Fix incorrect allocation in ares_parse_ptr_reply() + Fix integer shift overflow if both tcp_socket and udp_socket are set + + The problem occurs if at the start of the loop the sockindex is at the + last valid ARES_GETSOCK_MAXNUM position. If then both udp_socket and + tcp_socket are valid, sockindex gets incremented for UDP first and + points one entry behind the array for the tcp block. + So the fix is to check after every increment of sockindex if it is still + valid. + + Fix Coverity error CID 56878 + + Signed-off-by: Gregor Jasny -- Only fall back to AF_INET searches when looking for AF_UNSPEC addresses +- [Gregor Jasny brought this change] -- Do not use sized constants in public headers + Null check before dereference + + Fix Coverity error CID 56880 + + Signed-off-by: Gregor Jasny -Daniel Stenberg (13 Jun 2011) -- [Jakub Hrozek brought this change] +Jakub Hrozek (28 Jul 2014) +- [Gisle Vanem brought this change] - ares_free_hostent(NULL) should be a noop + Comment in ares_ipv6.h -Yang Tse (8 Jun 2011) -- configure: fix recvfrom 5th arg type qualifier detection (followup) +David Drysdale (25 Jul 2014) +- CONTRIBUTING: add file to indicate mailing list is preferred -- configure: fix recvfrom 5th arg type qualifier detection +- Add -t u option to ahost - Additionally remove whitespace from EOL - -Daniel Stenberg (4 Jun 2011) -- strlen: use size_t to receive the return + Add an option to allow specification of the AF_UNSPEC + address family. -Yang Tse (4 Jun 2011) -- xlc: avoid preprocessor definition usage when linking +Jakub Hrozek (24 Jul 2014) +- host_callback: Fall back to AF_INET on searching with AF_UNSPEC + + Previously, when an ares_gethostbyname() searched with AF_UNSPEC and the + first AF_INET6 call only returned CNAMEs, the host_callback never + retried AF_INET. + + This patch makes sure than on ARES_SUCCESS, the result of AF_INET6 is + taken as authoritative only if the result contains some addresses. -- ares_nowarn: icc 9.1 workaround +- [David Drysdale brought this change] -- ares_nowarn: header inclusion fix + Move memset call below platform-specific declarations + + A GitHub commenter [1] says that my recent change to ahost.c has + problems compiling on Windows + C89 platforms. + + [1] https://github.com/bagder/c-ares/commit/ee22246507c9#commitcomment-6587616 -- ares_init: make ares_private.h last included header again +- [David Drysdale brought this change] -- compiler warning: fix + Update ahost man page to describe -s option. - Fix compiler warning: conversion may lose significant bits - -- compiler warning: fix + Commit ee22246507c9 added the -s option to the + ahost command, but neglected to update the man page to + describe it. - Fix compiler warning: variable was set but never used + Also fix typo in description of -t option. + +- ares_parse_soa_reply: Do not leak rr_name on allocation failure - Fix compiler warning: clobber ignored + If ares_malloc_data failed, already allocated rr_name would go out of + scope. -- ares_iphlpapi: fix compiler warnings +- [David Drysdale brought this change] -- winsock: compilation fixes + Don't override explicitly specified search domains - Provide winsock iphlpapi alternative definitions to prevent compilation - failures when using a variety of winsock header implementations. - -Daniel Stenberg (17 May 2011) -- [David Stuart brought this change] + Only set search domains from /etc/resolv.conf if there isn't a value + already present in the channel. - IPv6-on-windows: find DNS servers correctly +- [David Drysdale brought this change] -- man pages: docs for the c-ares utility programs + Allow specification of search domain in ahost + + Add the "-s domain" command line option to override the search + domains. -- ares_parse_ns_reply.c: remove CVSism +Daniel Stenberg (12 May 2014) +- Revert "ares_parse_aaaa_reply: fix leak when reply contains 1 alias and no address" + + This reverts commit 440110b303fdbfadb3ad53d30eeb98cc45d70451. -Yang Tse (27 Mar 2011) -- build: fix header inclusion +- [Frederic Germain brought this change] -- getservbyport replacement for Win CE + ares_parse_aaaa_reply: fix leak when reply contains 1 alias and no address -- renamed getplatform() to ares__getplatform() to avoid namespace pollution +- [Doug Kwan brought this change] -- configure: fix libtool warning + ares_build.h: fix building on 64-bit powerpc - Recent versions of libtool are now tracing usage of AC_CONFIG_MACRO_DIR - macro and warn heavily when not used in configure script along with - ACLOCAL_AMFLAGS in Makefile.am. So in order to make libtool happy - while keeping backwards compatibility this is added. - -- adig: RFC4034 resource record type detection + There are two issues. - Can be tested with: adig -s 8.8.8.8 -t ANY example.com + 1. gcc actually does not use __ppc__ and __ppc64__ but __PPC__ and + __PPC64__. The tests of __ILP32__ and __LP64__ are sufficient for gcc. + + 2. clang defines __GNU__ and defines both __ppc64__ and __ppc__ when + targeting ppc64. This makes CARES_SIZEOF_LONG to be 4 on a ppc64 system + when building with clang. + + My patch is two change the order of the checks so that we check the + 64-bit case first. -- nameser.h: RFC4034 resource record type definitions +- refresh: updated now with automake 1.14 -- build: move platform stuff to ares_platform.c and ares_platform.h +- [David Drysdale brought this change] -- build: find out windows platform using GetVersionEx() + single_domain: Invalid memory access for empty string input + + We noticed a small buglet in ares_search() when it gets an empty string + as input -- the single_domain() utility function in ares_search.c + accesses invalid memory (before the start of the string). -- build: use getenv() replacement function for systems which lack it +Guenter Knauf (31 Aug 2013) +- Fixed warning 'type specifier missing'. -- setup_once: system error codes for Windows CE +Daniel Stenberg (30 Aug 2013) +- [Tor Arntsen brought this change] -- ares_search: use ERRNO macro for portability sake + ares_rules.h: CARES_SIZEOF_LONG doesn't exist anymore, don't test for it + + It was removed in f19387dd72432 -- System's errno.h inclusion cleanup follow-up. +- nowarn: use instead of configure for size of long - System's errno.h is conditionally included from setup_once.h + This makes the header file much more multi-arch friendly and can be used + as-is with both 32 bit and 64 bit builds. -- Windows CE specific adjustment +- timeoffset: made static and private - All versions of Windows CE support Winsock 1.1 + ares__timeoffset() was only used once within this single source file -- System's errno.h inclusion cleanup. +- timeadd: make static - System's errno.h is conditionally included from setup_once.h + ares__timeadd() was only ever used from within the same source -- ares_init: fix gethostname error detection on winsock platforms +Yang Tse (18 Jul 2013) +- xc-am-iface.m4: comments refinement -- configure: r-enable temporarily disabled detection of system's inet_ntop() +- configure: fix 'subdir-objects' distclean related issue - Detection was temporarily disabled in commit 674e044ccb21f2f63537da53565fce868f + See XC_AMEND_DISTCLEAN comments for details. -Daniel Stenberg (15 Mar 2011) -- configure: stop using the deprecated AM_INIT_AUTOMAKE syntax +- configure: automake 1.14 compatibility tweak (use XC_AUTOMAKE) -- [Gisle Vanem brought this change] +- xc-am-iface.m4: provide XC_AUTOMAKE macro - Watt-32: use errno - - Make sure Watt-32 programs use 'errno' even on Win32 targets +Daniel Stenberg (12 May 2013) +- gitignore: ignore all ares_*pdf but also CHANGES.dist -Guenter Knauf (18 Feb 2011) -- Removed commented CLFAGS no longer needed. +- bump: start working towards 1.10.1 -- Fixed CFLAGS for NetWare. - - Added -m32 to enable compilation with x86_64 compilers; - added conditional to set -fpcc-struct-return only for gcc compiler. +Version 1.10.0 (12 May 2013) -Daniel Stenberg (18 Feb 2011) -- [Gisle Vanem brought this change] +Daniel Stenberg (12 May 2013) +- RELEASE-NOTES: two more bug fixes - Watt32: fix server init - - Somewhere in the process, programs using the Watt-32 tcp/ip stack - stopped working. +- [Keith Shaw brought this change] -- [Dima Tisnek brought this change] + ares_set_servers_csv: fixed IPv6 address parsing + + Fixed bug that caused the last part of an IPv6 address to be parsed as + the port number when the last part is all numeric. - config_sortlist: (win32) missing else +- nroff: fix two syntax mistakes - Without an else there, contents of "pat" that could have been - successfully set just above, may be clobbered by successive unsuccessful - calls to "xxx_pton" or "ip_addr". + ares_parse_a_reply and ares_parse_aaaa_reply both had two \fB instead of + \fP + + Reported-by: Alexander Klauer + Bug: http://c-ares.haxx.se/mail/c-ares-archive-2013-03/0010.shtml -Yang Tse (17 Jan 2011) -- Makefile.msvc: add a couple of VS version strings +- [Alex Loukissas brought this change] -- Makefile.msvc: add a couple of VS version strings + build: fix build on msvc11 -- build: add install target to Makefile.msvc +- Makefile.am: increment -version-info for 1.10.0 release -Daniel Stenberg (27 Dec 2010) -- ares_set_servers_csv: remove unused variables +- README: remove unnecessary comment -- init_by_resolv_conf: fix compiler warnings - - The code received the return codes in the 'status' variable without - using it. Instead we just ignore those particular errors. +- ares_version.h: copyright end range year is now 2013 -- getv4: Value stored to 'dst' is never read +- RELEASE-NOTES: synced with fb0737f3a0a1c37 -- advance_tcp_send_queue: avoid NULL ptr dereference - - If given a too large 'num_bytes' value, it would cause a NULL ptr - dereference. Instead the code will now break out of the loop at the end - of the list. +- [Paul Saab brought this change] -- [Peter Pentchev brought this change] + ares_parse_aaaa_reply: Plug memory leak + + This change is similar to ares_parse_a_reply.c in commit + bffd67f16a8f42fe6dbf79ab2e39d92eea05c8a6 - configure: fix a bashism +- [Patrick Valsecchi brought this change] -- cleanup: avoid unsafe typecasts + ares_parse_txt_reply: return a ares_txt_reply node for each sub-string - Avoid the risk of reading 16bit data from an unaligned address by using - a macro that is adapted for this. - -- [Stefan Bühler brought this change] + Previously, the function would wrongly return all substrings merged into + one. - ares_expand_name: Fix encoded length for indirect root +- [Alexander Klauer brought this change] -Yang Tse (18 Dec 2010) -- build: add some explicit file references to VS project files + library init: documentation update + + This commit updates the documentation of ares_library_init() and + ares_library_cleanup() with regard to the newly introduced reference + counting of initializations and deinitializations. -- config-win32: provide HAVE_ASSERT_H definition +- [Alexander Klauer brought this change] -- build: include ares_nowarn in sample program VS project files + library init: be recursive + + Previously, a single call to ares_library_cleanup() would deinitialise + the c-ares library, regardless of how many times ares_library_init() was + called. This behaviour may cause problems in programs linking two or + more libraries which, in turn, use c-ares. The present commit fixes this + problem, deinitializing the library only after a number of calls to + ares_library_cleanup() matching the number of calls to + ares_library_init(). -- build: include ares_nowarn among SAMPLESOURCES and SAMPLEHEADERS +- [Patrick Valsecchi brought this change] -- configure: temporarily disable detection of system's inet_ntop() + protocol parsing: check input data stricter - This is done to allow compilation of ares_inet_ntop() by some daily - builds picky compilers that otherwise do not need this function. + ... so that bad length fields aren't blindly accepted + + Bug: http://c-ares.haxx.se/mail/c-ares-archive-2013-04/0016.shtml -- changes: mention last fix +Guenter Knauf (11 Apr 2013) +- Create ares_build.h when buidling from Git. -- ares_inet_ntop: remove definition and usage of macro SPRINTF +- Added -DCARES_STATICLIB to CFLAGS. - Existing definition of SPRINTF always resulted in sprintf() being used, - and sprintf() returning 'int' is already used throughout the library. + Currently this static makefile does only support building the + static library libcares.a. -- ares_inet_ntop: reapply changes from previous c-ares version (III) - - - Replace 'u_char' with 'unsigned char'. - - Replace 'u_int' with 'unsigned int'. - - use macros ERRNO and SET_ERRNO() for errno handling. +Daniel Stenberg (8 Apr 2013) +- [Alexander Klauer brought this change] -- ares_inet_ntop: reapply changes from previous c-ares version (II) + .gitignore: ignore patch files - - Remove rcsid. - - Adjust header file inclusions. - - ares_inet_ntop used only on systems without a proper inet_ntop function. + This commit adds a line to .gitignore to the effect that patch files + generated by 'git format-patch' are excluded from the repository. -- ares_inet_ntop: reapply changes from previous c-ares version (I) - - - Replace tabs with spaces. - - Use ANSI C style for function declarations and definitions. - - Use sizeof with parentheses. +- [Alexander Klauer brought this change] -- ares_inet_ntop: fix off by one error triggering out of bounds write + ares_destroy() documentation: no new requests - ares_inet_ntop would trigger an out of bounds write when the representation - of the address required 15 characters, due to not taking in account null - termination character. + Clarify that no new requests may be added to a resolver channel that is + currently being destroyed. + +- [Alexander Klauer brought this change] + + Documentation: properly document ARES_ECANCELLED - Full import of inet_ntop.c from bind-9.5.3rc1 to pull additional fixes. + This commit clarifies the behaviour of ares_cancel() with respect to + callbacks and adds missing documentation of ARES_ECANCELLED to the man + pages of the affected functions. -- ares_nowarn: add conditional inclusion of assert.h header +- [Alexander Klauer brought this change] -- fix compiler warning: conversion may lose significant bits + ares_cancel(): cancel requests safely + + An invocation of ares_cancel() walks through the request list, calling + the callbacks of all pending requests on a channel. Previously, if such + a callback added a new request to the channel, the request list might + not end up empty, causing an abort by assertion failure. The present + commit ensures that precisely all requests present upon entry of + ares_cancel() are cancelled, and that adding new requests through + callbacks is safe. -- ares_inet_net_pton: fix non-rejection of some malformed literals +Yang Tse (10 Mar 2013) +- ares.h: stricter CARES_EXTERN linkage decorations logic - ares_inet_net_pton would return wrong values when excessively large, - and invalid, netmasks are used. Fixes are from bind-9.5.3rc1, - issue also described in the WLB-2008080064 advisory. - -- setup_once: provide ISASCII macro + No API change involved. -- configure: inet_net_pton function check adjustments +- ares_build.h.dist: enhance non-configure GCC ABI detection logic - Define HAVE_INET_NET_PTON only when system's inet_net_pton function is IPv6 - capable and is not affected by the WLB-2008080064 advisory. + GCC specific adjustments: - HAVE_INET_NET_PTON_IPV6 is no longer defined nor used. - -- ares_init: fix detection of semicolon comments in resolv.conf + - check __ILP32__ before 32 and 64bit processor architectures in + order to detect ILP32 programming model on 64 bit processors + which, of course, also support LP64 programming model, when using + gcc 4.7 or newer. - File resolv.conf may either use a hash '#' or a semicolon ';' character as an - indication that the rest of the line is a comment. This fixes not recognizing - the semicolon as a valid comment indicator in resolv.conf. + - keep 32bit processor architecture checks in order to support gcc + versions older than 4.7 which don't define __ILP32__ + + - check __LP64__ for gcc 3.3 and newer, while keeping 64bit processor + architecture checks for older versions which don't define __LP64__ -- version: start working on 1.7.5 +Daniel Stenberg (9 Mar 2013) +- ares.h: there is no ares_free_soa function -Version 1.7.4 (8 Dec 2010) +Yang Tse (9 Mar 2013) +- Makefile.am: empty AM_LDFLAGS definition for automake 1.7 compatibility -Daniel Stenberg (8 Dec 2010) -- release-preps: CHANGES and RELEASE-NOTES synced +- ares_inet_ntop.3: s/socklen_t/ares_socklen_t -- ares_set_local_*: added in 1.7.4, not before +- configure: use XC_LIBTOOL for portability across libtool versions -Yang Tse (3 Dec 2010) -- build: provide SIZEOF_SIZE_T definition for non-configure builds +- xc-lt-iface.m4: provide XC_LIBTOOL macro -- build: config.dos renamed to config-dos.h +- Makefile.am: use AM_CPPFLAGS instead of INCLUDES -- build: provide SIZEOF_SIZE_T netware definition +- inet_ntop.c: s/socklen_t/ares_socklen_t -- ares_gethostbyaddr: fix compiler warning: conversion may lose significant bits +- inet_ntop.c: s/socklen_t/ares_socklen_t for portability -- configure: undo using autobuilds to temporarily verify strict aliasing warnings. +Daniel Stenberg (19 Feb 2013) +- ares.h: s/socklen_t/ares_socklen_t for portability -- fix compiler warning: rounding, sign extension, or loss of accuracy may result +- ares_inet_ntop.3: 4th argument is socklen_t! -Daniel Stenberg (2 Dec 2010) -- [Ben Noordhuis brought this change] +- spell inet correctly! - ares_parse_a_reply: fix CNAME response parsing +- ares_inet_pton/ntop: cleanup - Reply to a CNAME query doesn't contain addresses, causing - ares_parse_a_reply() to bail out with ARES_ENODATA + Make sure that the symbols are always exported and present in c-ares. - Bug: http://groups.google.com/group/nodejs/browse_thread/thread/a1268c9ea5e9ad9b + Make the headers prefixed with 'ares'. + + Removed the inet_ntop.h version as it no longer features any content. -Yang Tse (1 Dec 2010) -- fix compiler warning: conversion may lose significant bits +- ares_inet_ntop/ares_inet_pton: added man pages -- atoi: remove atoi usage +Yang Tse (15 Feb 2013) +- [Gisle Vanem brought this change] -- ares_init: fix compiler warning: conversion may lose significant bits + curl_setup_once.h: definition of HAVE_CLOSE_S defines sclose() to close_s() -- configure: fix autoconf warning +- [Gisle Vanem brought this change] -- inet_pton: fix compiler warning + config-dos.h: define HAVE_CLOSE_S for MSDOS/Watt-32 -- configure: use autobuilds to temporarily verify strict aliasing warnings. - - Temporarily, When cross-compiling with gcc 3.0 or later, enable strict aliasing - rules and warnings. Given that cross-compiled targets autobuilds do not run the - test-suite, there is no risk of running code that violates strict aliasing rules +- [Gisle Vanem brought this change] -- ares_getnameinfo: Partially revert commit 85520d66e0ac7ac73411bc25e98769a88b2f - - Upon socket address family and length validation failure return ARES_ENOTIMP - in callback again, this is the error code documented in man page and used - mostly all over the library. + config-dos.h: define strerror() to strerror_s_() for High-C -- ares_getnameinfo: Validate socket address family and length. +Daniel Stenberg (13 Feb 2013) +- ares_get_datatype: removed unused function - Validate socket address family and that the socket address length is appropriate - for the specified family. Failure is reported with ARES_EBADFAMILY in callback. - -- ares_getnameinfo: fix two compiler warnings - -- Added another VS10 version string + it was also wrongly named as internal functions require two underscores -- Fix GCC 4 compiler warning 'dereferencing type-punned pointer might break strict-aliasing rules'. +- ares__bitncmp: use two underscores for private functions + + It used a single one previously making it look like a public one -- Revert commit 494274e653936335c255a47599970de3df21e7c4 +- ares__generate_new_id: moved to ares_query.c + + ... and ares__rc4 is turned into a local static function. -- configure: fix autoconf 2.68 warning: no AC_LANG_SOURCE call detected in body +- ares__swap_lists: make private and static + + ... since there's only one user, make it static within ares_process.c -- Fix compiler warning: array subscript has type 'char' +Yang Tse (13 Feb 2013) +- Makefile.msvc: add four VS version strings -- Fix GCC 4 compiler warning 'dereferencing type-punned pointer might break strict-aliasing rules'. +Daniel Stenberg (13 Feb 2013) +- ares_expand_name.3: clarify how to free the data -- Revert following commits: - 07bc7ea79509bcc9ef6e09151e81766ed00d3392 - 3392a50ea3f8573ea4b7a9d82b9833dab60cb0e9 - 9912637d32c9987719a1ea12db591aee2941891c +Yang Tse (30 Jan 2013) +- zz40-xc-ovr.m4: fix 'wc' detection - follow-up 2 - The purpose of the whole patch was to silence a compiler warning triggered - with GCC 4 on file ares_process.c The specific compiler warning was - 'dereferencing type-punned pointer might break strict-aliasing rules'. + - Fix a pair of single quotes to double quotes. - A simpler patch will follow to equally silence the warning. - -- ares_options: reorder header inclusions to make inclusion of - ares_private.h the last included one again. - -Daniel Stenberg (12 Nov 2010) -- [Patrik Thunstrom brought this change] + URL: http://curl.haxx.se/mail/lib-2013-01/0355.html + Reported by: Tor Arntsen - adig: fix NAPTR parsing +- zz40-xc-ovr.m4: fix 'wc' detection - follow-up - I ran across a small "issue" in your adig example. + - Take into account that 'wc' may return leading spaces and/or tabs. - It is simply the last part of the NAPTR record, the replacement element, - which is not a string, as currently handled in adig, but a domain name. - -- ares_save_options: assignments instead of memcpy + - Set initial IFS to space, tab and newline. -- init_by_options: don't copy an empty sortlist +- zz40-xc-ovr.m4: fix 'wc' detection - If there aren't any sort items to copy, don't bother. Without this - little precaution it would do a malloc(0) which causes undefined - behaviors and is frowned upon by curl's memdebug-system. - -Guenter Knauf (3 Oct 2010) -- Minor Watcom makefile tweaks. - -Daniel Stenberg (30 Sep 2010) -- [Mike Crowe brought this change] - - Fix lookup with HOSTALIASES set. + - Take into account that 'wc' may return leading spaces. - ares__read_line returns ARES_EOF when it reaches the end of the - file. This will happen every time when reading to the end of the - HOSTALIASES file. Unfortunately single_domain treats this error as - being fatal. + - Set internationalization behavior variables. - Signed-off-by: Mike Crowe - -Ben Greear (24 Aug 2010) -- Add missing break that caused get_ares_servers to fail. + Tor Arntsen analyzed and reported the issue. - Reported-by: Ning Dong - Signed-off-by: Ben Greear - -Yang Tse (11 Aug 2010) -- configure: werror related adjustments - -Guenter Knauf (8 Aug 2010) -- Added copyright string to ares_version.h and make use of it in other files. + URL: http://curl.haxx.se/mail/lib-2013-01/0351.html -- Block created ares_build.h for NetWare to avoid usage from other platforms. +- zz40-xc-ovr.m4: check another three basic utilities -- Fix to overwrite default libname. +- zz40-xc-ovr.m4: 1.0 interface stabilization + + - Stabilization results in 4 public interface m4 macros: + XC_CONFIGURE_PREAMBLE + XC_CONFIGURE_PREAMBLE_VER_MAJOR + XC_CONFIGURE_PREAMBLE_VER_MINOR + XC_CHECK_PATH_SEPARATOR + - Avoid one level of internal indirection + - Update comments + - Drop XC_OVR_ZZ40 macro -- Some more Watcom makefile massage ... +- zz40-xc-ovr.m4: emit witness message in configure BODY + + This avoids witness message in output when running configure --help, + while sending the message to config.log for other configure runs. -- Some more Watcom makefile massage ... +- zz40-xc-ovr.m4: truly do version conditional overriding + + - version conditional overriding + - catch unexpanded XC macros + - fix double words in comments -Ben Greear (4 Aug 2010) -- sock-addr-storage: Detect and deal with lack of .ss_family member. +- zz40-xc-ovr.m4: fix variable assignment of subshell output bashism - AIX, at least, does not have sockaddr_storage.ss_family member. - Detect this in the configure logic and use proper #ifdefs in the - ares_process logic. + Tor Arntsen analyzed and reported the issue. - Signed-off-by: Ben Greear - Tested-by: Tor Arntsen + URL: http://curl.haxx.se/mail/lib-2013-01/0306.html -Guenter Knauf (3 Aug 2010) -- Added Watcom makefile based on libcurl's Makefile.Watcom. +- zz40-xc-ovr.m4: reinstate strict AC_REQUIRE macro dependencies -Ben Greear (31 Jul 2010) -- typo: Fix compile bug for platforms that don't have sockaddr_storage. - - Bug was introduced by me in previous commit. - - Signed-off-by: Ben Greear +- zz40-xc-ovr.m4: avoid double single-quote usage -- Fix aliasing warning in gcc 4.4.4 (at least). - - Should be no functional change, though the code gets a bit - ugglier. +- zz40-xc-ovr.m4: parentheses balancing of 'case' statements - Signed-off-by: Ben Greear + m4 quadrigraph shell comment technique allows proper autoconf + parentheses balancing in shell 'case' statements. The presence + of unbalanced parentheses may otherwise trigger expansion bugs. -Daniel Stenberg (31 Jul 2010) -- ares_set_servers_csv: use ISDIGIT +- zz40-xc-ovr.m4: internals overhauling - The IS*() set of macros are preferred to the regular is*() functions as - they help us avoid the most common pitfalls. + - Update comments + - Execute commands in subshells + - Faster path separator check + - Fix missing 'test' command + - Rename private macros + - Minimize AC_REQUIRE usage -Ben Greear (30 Jul 2010) -- cast arg to isdigit to int - - Looks like it might silence a warning on Netware build. +- zz40-xc-ovr.m4: redirect errors and warnings to stderr + +- configure: use XC_CONFIGURE_PREAMBLE early checks - Signed-off-by: Ben Greear + Some basic checks we make were placed early enough in generated + configure script when using autoconf 2.5X versions. Newer autoconf + versions expand these checks much further into the configure script, + rendering them useless. Using XC_CONFIGURE_PREAMBLE fixes placement + of early intended checks across all our autoconf supported versions. -- remove all uses of uint32_t - - Previous fix forgot a few. - - Signed-off-by: Ben Greear +- zz40-xc-ovr.m4: provide XC_CONFIGURE_PREAMBLE macro -- fix signed v/s unsigned casts warning in ares_gethostbyaddr.c +- configure: autotools compatibility fixes - step I - Signed-off-by: Ben Greear + Fix proper macro expansion order across autotools versions for + C compiler and preprocessor program checks. -- local-bind-fixup: Fix inet_pton warning. +- configure: fix automake 1.13 compatibility - Conditionally include for inet_pton - headers. + Tested with: - Signed-off-by: Ben Greear + buildconf: autoconf version 2.69 + buildconf: autom4te version 2.69 + buildconf: autoheader version 2.69 + buildconf: automake version 1.13.1 + buildconf: aclocal version 1.13.1 + buildconf: libtool version 2.4 + buildconf: GNU m4 version 1.4.16 -- build: Enable compiling with -Werror. - - This helps find compile warnings because they simply break - the build. - - To use: - ./configure --enable-warnings --enable-werror +- ares_private.h: use again memdebug.h instead of curl_memdebug.h + +- configure.ac: replace AM_CONFIG_HEADER with AC_CONFIG_HEADERS - Signed-off-by: Ben Greear + automake 1.13 errors if AM_CONFIG_HEADER is used in configure script. -- ipv6: Fix some build issues related to the local-bind feature. +- cares-override.m4: provide AC_CONFIG_MACRO_DIR definition conditionally - Signed-off-by: Ben Greear + Provide a 'traceable' AC_CONFIG_MACRO_DIR definition only when using + an autoconf version that does not provide it, instead of what we were + doing up to now of providing and overriding AC_CONFIG_MACRO_DIR for + all autoconf versions. -Guenter Knauf (29 Jul 2010) -- Replaced uint32_t with unsigned int to fix broken builds on a couple of platforms. +- ares_private.h: use curl_memdebug.h instead of memdebug.h -Daniel Stenberg (18 Jul 2010) -- [Ben Greear brought this change] +- vc6cares.dsp: add ares_create_query.c and ares_parse_soa_reply.c - local-bind: Support binding to local interface/IPs - - Add 3 new functions to set the local binding for the out-going - socket connection, and add ares_set_servers_csv() to set a - list of servers at once as a comma-separated string. +- cares-functions.m4: improve gethostname arg 2 data type check + +- setup_once.h: HP-UX specific 'bool', 'false' and 'true' definitions. - Signed-off-by: Ben Greear + Also reverts commit bceb40095a -- version: now start on 1.7.4 +- configure: check if compiler halts on function prototype mismatch -- [Andrew C. Morrow brought this change] +- cares-functions.m4: add gethostname arg 2 data type check and definition - fix memory leak in ares_getnameinfo +- cares-functions.m4: update thread-safeness detection of getaddrinfo() + + Take in account that POSIX standard Issue 7 drops h_errno support. Now, we also + consider getaddrinfo() to be thread-safe when (_POSIX_C_SOURCE >= 200809L) or + (_XOPEN_SOURCE >= 700) independently of whether h_errno exists or not. + + Take in account that h_errno might be a modifiable lvalue not defined as + a C preprocessor macro. -Version 1.7.3 (11 Jun 2010) +- setup_once.h: HP-UX issue workaround + + Issue: When building a 32bit target with large file support HP-UX + header file may simultaneously provide two different + sets of declarations for sendfile and sendpath functions, one with + static and another with external linkage. Given that we do not use + mentioned functions we really don't care which linkage is the + appropriate one, but on the other hand, the double declaration emmits + warnings when using the HP-UX compiler and errors when using modern + gcc versions resulting in fatal compilation errors. + + Mentioned issue is now fixed as long as we don't use sendfile nor + sendpath functions. -Daniel Stenberg (11 Jun 2010) -- changelogs: updated for 1.7.3 +- setup_once.h: refactor inclusion of and + + Inclusion of these two header files now done in setup_once.h -- [BogDan Vatra brought this change] +- Header inclusion clean-up + + Remove header inclusions already done in setup_once.h - init: allow c-ares to work on Android OS +- setup_once.h: HP-UX specific TRUE and FALSE definitions + + Some HP-UX system headers require TRUE defined to 1 and FALSE to 0. -- changelog: fill in the 1.7.2 changes +- ares_timeout.c: fix compiler warning -- added another pdf to ignore +- ares_create_query.c: IRIX compilation fix -Yang Tse (11 Jun 2010) -- add ares_parse_mx_reply.c to VS dsp file +- c-ares/nameser.h: add some T_* defines for ns_t_* values -Daniel Stenberg (10 Jun 2010) -- tarball: add $(CSOURCES) $(HHEADERS) to EXTRA_DIST +Daniel Stenberg (7 Nov 2012) +- Revert "ares_parse_aaaa_reply: fix memory leak" - It's not clear to me why we need this, but we apparently may - otherwise not get all files bundled in the dist tarball. - -- version: start working on 1.7.3 + This reverts commit 50f25d8a4b2d16f4c5e0ef620238688b7a315c7a. -Version 1.7.2 (10 Jun 2010) +- ares_parse_aaaa_reply: fix memory leak + + an allocated buffer was not freed in the successful case. -Daniel Stenberg (10 Jun 2010) -- RELEASE-NOTES: 1.7.2 details added +- [Gisle Vanem brought this change] -- [Jakub Hrozek brought this change] + adig: perror() doesn't work for socket errors on windows + + ... so print the SOCKERRNO instead - ares_init: Last, not first instance of domain or search should win +- get_DNS_AdaptersAddresses: fix IPv6 parsing + + Use of the wrong define made the function not parse IPv6 addresses + properly. + + Bug: http://c-ares.haxx.se/mail/c-ares-archive-2012-06/0028.shtml + Reported by: Saúl Ibarra Corretgé -- style: make code less than 80 columns wide +- version: bumped to 1.10.0 + + Due to the newly added function: ares_create_query() -Yang Tse (31 May 2010) -- [Tor Arntsen brought this change] +- AUTHORS: synced with 83093ac450 + + Added 21 authors since this document was last updated - improve alternative definition of bool to use enum instead of unsigned char +- ares_create_query.3: mention when this is added -- fix VS2010 compiler warnings +- [hpopescu@ixiacom.com brought this change] -Daniel Stenberg (18 Apr 2010) -- [Jérémy Lal brought this change] + Added new feature (rfc2671) - added ares_parse_mx_reply +- code police: fix indents, < 80 columns, reflowed comments -- repair the file mode +Guenter Knauf (11 Jul 2012) +- Cleaned up version awk script. -- remove all $Id$ lines +Daniel Stenberg (30 Jun 2012) +- [Gisle Vanem brought this change] -- remove all .cvsignore files + read_udp_packets: bail out loop on bad sockets + + I can see that recvfrom() in ares_process.c many times is called with + 'udp_socket' == ARES_SOCKET_BAD. The code takes care not to call + recv/recvfrom with ARES_SOCKET_BAD in the outer-loop. So should the + inner-loop. -- spell fix +Yang Tse (29 Jun 2012) +- cares-compilers.m4: remove -Wstrict-aliasing=3 from clang - reported by Gregor Jasny on the mailing list + Currently it is unknown if there is any version of clang that + actually supports -Wstrict-aliasing. What is known is that there + are several that don't support it. -- [Peter Pentchev brought this change] +- cares-compilers.m4: -Wstrict-aliasing=3 for warning enabled gcc and clang builds - Fix a couple of typos and grammar nits. +Daniel Stenberg (18 Jun 2012) +- version: work towards 1.9.2 (at least) -- ignore the GPG signature files too +Version 1.9.1 (18 Jun 2012) -- start the journey towards 1.7.2 +Daniel Stenberg (18 Jun 2012) +- RELEASE-NOTES: 1.9.1 coming up -- no longer CVS tagging +Version 1.9.0 (16 Jun 2012) -- ignore generated PDFs +Daniel Stenberg (16 Jun 2012) +- ares_version.h: next version is 1.9.0 -Version 1.7.1 (23 Mar 2010) +- [Marko Kreen brought this change] -Daniel Stenberg (23 Mar 2010) -- 1.7.1 + ares_data.h: ARES_DATATYPE_SOA_REPLY is added in 1.9.0 -- made README the primary readme file +- RELEASE-NOTES: synced with 979bf951d - ... and did README.cares to contain a historic reason etc. + Next release deemed to become 1.9.0 due to the new function -- s/CVS/git +- [Marko Kreen brought this change] -- git now, not CVS + SOA parser added + + I need to do SOA queries, so here is a parser for them. + + - ares_soa_reply: new struct + - ares_malloc_data/ares_free_soa: ARES_DATATYPE_SOA_REPLY + - ares_parse_soa_reply: actual function -- ignore lots of generated files +Yang Tse (14 Jun 2012) +- Kill compiler warning -- [Daniel Johnson brought this change] +- Fix libcares.pc generation for static MingW* cross builds - Fix warnings for clang +Daniel Stenberg (21 May 2012) +- [Nick Alcock brought this change] -Yang Tse (17 Mar 2010) -- replaced intel compiler option -no-ansi-alias with -fno-strict-aliasing + Fix UDP and TCP port byte order in saved options. + + The UDP and TCP port are stored in network byte order in the + ares_channeldata, but are passed in to ares_init_options() in host byte + order. Thus we must return them from ares_save_options() in host byte + order too, or a duplicated channel will convert them again, leading to a + nonfunctional channel and a mysterious connection refused error from + ares_gethostbyname(). This breaks ares_dup(), thus the curl easy API + when c-ares is used by curl, and thus all the curl easy API's users. -- update outdated serial number +Yang Tse (28 Apr 2012) +- version: start working on 1.8.1-DEV -- fix compiler warning +Version 1.8.0 (27 Apr 2012) -- watt32 compilation fix +Daniel Stenberg (27 Apr 2012) +- RELEASE-NOTES: call next 1.8 instead + + Since we added a function, let's use a stricter bumping scheme -- Added another VS10 version string +Yang Tse (25 Apr 2012) +- INSTALL: some adjustments -- fix line break +Daniel Stenberg (25 Apr 2012) +- GIT-INFO: mention buildconf -- removed usage of 's6_addr', fixing compilation issue triggered with no - longer using 'in6_addr' but only our 'ares_in6_addr' struct +Yang Tse (25 Apr 2012) +- INSTALL: remove more sections that don't apply to c-ares -Daniel Stenberg (5 Mar 2010) -- Daniel Johnson provided fixes for building with the clang compiler +- ares_timeout.c: fix compiler warning + +Daniel Stenberg (25 Apr 2012) +- [Ben Noordhuis brought this change] + + Makefile.m32: fix mingw32 build + + * add . to include path so ares_build.h is picked up + * make ar configurable to ease cross-compiling -Yang Tse (5 Mar 2010) -- Added IPv6 name servers support +- RELEASE-NOTES: added what's happened since 1.7.5 -Gisle Vanem (5 Mar 2010) -- Ops!. Readded ares_nowarn.h. +Guenter Knauf (22 Apr 2012) +- Updated copyright year. -- Added ares_nowarn.c. +Yang Tse (21 Apr 2012) +- ares_init.c: Further refactoring of Windows system's DNS fetching code -Yang Tse (28 Feb 2010) -- Added SIZEOF_INT and SIZEOF_SHORT definitions for non-configure systems +Guenter Knauf (20 Apr 2012) +- Android: small changes to dns property part. + + Prefix prop vars; kill var; use DNS_PROP_NAME_PREFIX macro. -- Added ares_nowarn.* to VC6 project file +- Handle CNAME-only in ares_parse_aaaa_reply(). + + posted to the c-ares list by Peter Griess . -- Added SIZEOF_INT definition +- Add support for multiple DNS servers on Android. + + Before, c-ares always used the first DNS server on Android, causing + network problems if this DNS server was not available. + + Signed-off-by: Geert Uytterhoeven -- fix compiler warning +- Added INSTALL so it gets into tarballs. -- fix compiler warning +- Added some more ifdefs to silent compiler warnings. -- fix compiler warning +Yang Tse (17 Apr 2012) +- INSTALL: remove a non c-ares section -Daniel Stenberg (17 Feb 2010) -- ares_reinit() +- cares-compilers.m4: -Wno-pedantic-ms-format for Windows gcc 4.5 builds - - To allow an app to force a re-read of /etc/resolv.conf etc, pretty much - like the res_init() resolver function offers + When building a Windows target with gcc 4.5 or newer and strict compiler + warnings enabled use -Wno-pedantic-ms-format in addition to other flags. -- - Tommie Gannert pointed out a silly bug in ares_process_fd() since it didn't - check for broken connections like ares_process() did. Based on that, I - merged the two functions into a single generic one with two front-ends. +- setup_once.h: tighten requirements for stdbool.h header inclusion + + Include stdbool.h only when it is available and configure is capable of + detecting a proper 'bool' data type when the header is included. -Yang Tse (30 Dec 2009) -- VMS specific preprocessor symbol checking adjustments +- configure: NATIVE_WINDOWS no longer defined in config file -- Mention last changes +- cares-compilers.m4: double underscore decoration for visibility attribute -- - Fix configure_socket() to use ares_socket_t instead of int data type. +- build adjustments: CARES_SYMBOL_HIDING no longer defined in config files + + configure script now provides conditional definitions for Makefile.am + that result in CARES_SYMBOL_HIDING being defined by resulting makefiles + when appropriate. -- - Where run-time error checks enabling compiler option /GZ was used it is now - replaced with equivalent /RTCsu for Visual Studio 2003 and newer versions. +- configure: Windows cross-compilation fixes - - Compiler option /GX is now replaced with equivalent /EHsc for all versions. + CARES_BUILDING_LIBRARY and CARES_STATICLIB no longer defined in ares_config.h, + configure will generate appropriate conditionals so that mentioned symbols + get defined and used in Makefile derived from Makefile.am at compilation time. -- - Ingmar Runge noticed that Windows config-win32.h configuration file - did not include a definition for HAVE_CLOSESOCKET which resulted in - function close() being inappropriately used to close sockets. +Guenter Knauf (17 Apr 2012) +- Added INSTALL file adapted from libcurl. + + Not yet ready, and needs further edits. -Daniel Stenberg (30 Nov 2009) -- start working on 1.7.1 +Yang Tse (16 Apr 2012) +- ares_init.c: get_iphlpapi_dns_info() refactoring -Version 1.7.0 (27 Nov 2009) +Guenter Knauf (16 Apr 2012) +- Kill some more compiler warnings. -Yang Tse (27 Nov 2009) -- Preserve empty line following last target +- Kill compiler warning about unused var. -- - Larry Lansing fixed ares_parse_srv_reply to properly parse replies - which might contain non-SRV answers, skipping over potential non-SRV - ones such as CNAMEs. +- Fixed my last commit: wrong preprocessor directive. -- When using icc, compile with -fpic and link with intel dynamic libraries. +- Check for __ANDROID__ in addition to ANDROID macro. -- Added 'currently' in italics to insist on transient situation. +- Check for __ANDROID__ in addition to ANDROID macro. + + Posted to c-ares list by Wayne. -- Fix language +- Fix for Android to disable useless arpa/nameser.h. -- Daniel wants upcoming release to be 1.7.0 +- Fix for Android to include sys/select.h for fd_set. -- Mention last changes +Yang Tse (17 Mar 2012) +- ares_data.c: some NAPTR related fixes -- - Removed from external interface preprocessor symbol definition for - CARES_HAVE_ARES_FREE_DATA. Current functionality of ares_free_data() - makes it unnecessary. +Daniel Stenberg (16 Mar 2012) +- port numbers: convert them to network order! + + When the config options ARES_OPT_UDP_PORT or ARES_OPT_TCP_PORT are used, + make sure to convert them to network byte order! + + Bug: http://c-ares.haxx.se/mail/c-ares-archive-2012-02/0004.shtml -- Added README.msvc +- white space cleanup + + - Keep code within 80 columns + + - Removed funny spaces after open paren and before closing paren -- Changed c-ares naming conventions when using MSVC as described in README.msvc +- [Poul Thomas Lomholt brought this change] -- - Mention other recent changes + get_iphlpapi_dns_info: fix buffer overrun + + I experienced a buffer overrun exception in c-ares on Windows and + tracked it down to be an error in the calculation of the 'left' variable + in get_iphlpapi_dns_info(). + + I changed the variable type of 'left' to a _signed_ type because of the + subtraction arithmetic; not sure if a long is the best choice -- - Jakub Hrozek renamed addrttl and addr6ttl structs to ares_addrttl and - ares_addr6ttl in order to prevent name space pollution, along with - necessary changes to code base and man pages.This change does not break - ABI, there is no need to recompile existing applications. But existing - applications using these structs with the old name will need source code - adjustments when recompiled using c-ares 1.6.1. +- Merge pull request #7 from saghul/naptr + + Added support for parsing NAPTR records -- - Jakub Hrozek fixed more function prototypes in man pages to sync them - with the ones declared in ares.h +saghul (23 Feb 2012) +- Added support for parsing NAPTR records -- Make configure remove the ares_build.h file included in distribution tarballs. +Yang Tse (19 Jan 2012) +- ares_init.c: fix compiler warning on winsock builds -- Fix macro redefinition. +- configure: libtool 1.5 tweaks -- Fix name space pollution. +Daniel Stenberg (19 Dec 2011) +- ares_timeout.3: fix the NAME section + + It was clearly a copy n' paste error -- Allow using different extra import libraries for debug and release builds. +Yang Tse (27 Sep 2011) +- [Albert Chin brought this change] -- Add manifest stuff to msvc makefile + configure - m4: make CURL_CHECK_DEF ignore leading whitespace on symbol def + + When using Sun C compiler the preprocessor somehow inserts an extra space + in front of replaced symbol, breaking CURL_CHECK_DEF macro. To workaround + this, macro CURL_CHECK_DEF now ignores all leading whitespace in front of + symbol substitution result. -- Sync man page with reality +- ares_init.c: fix segfault triggered in ares_init_options() upon previous + failure of init_by_defaults() and incomplete cleanup there. -- Add missing external API decoration for ares_set_socket_callback() +- ares_process.c: fix compiler warning -- Add ares_free_data() man page. +- fix MSVC compiler warning 'conditional expression is constant' -- - Provide in external interface preprocessor symbol definitions for - CARES_HAVE_ARES_FREE_DATA as an indication of function availability. +- setup_once.h cleanup and sync -- Remove typecast +- [Denis Bilenko brought this change] -- Fix comment + ares_getnameinfo: fix random results with c-ares 1.7.5 + + In ares_getnameinfo memcpy did not copy enough bytes, causing + it to return arbitrary memory contents as a result. -- Add ares_data.c and ares_data.h +- warnings: fix another 'conversion may lose significant bits' compiler warning -- Jakub Hrozek modified ares_parse_srv_reply() and ares_parse_txt_reply() API - to return a linked lists of results. These were also modified to internally - use the ares_data memory struct and as such its result must be free'ed with - ares_free_data(). +- ares_dns.h: adjust DNS__16BIT and DNS__32BIT macro definitions + + Fixing compiler warnings existing definitions triggered on these. -- Initial support for the generic ares_free_data() function that will allow - applications to free memory allocated and returned by some c-ares funtions. +- ares_destroy.c: fix segfault in ares_destroy_options() -- Make usage of calloc()'s arguments consistent with rest of code base +Daniel Stenberg (21 Aug 2011) +- ares_parse_srv_reply: silence compiler warnings + + ... by adding ugly typecasts. -- workaround icc 9.1 optimizer issue +- CHANGES: generate from script + + The CHANGES file is now generated automatically with 'git2changes.pl', + invoked by the maketgz script which is used to build release archives. + + The former human edited CHANGES file was renamed to CHANGES.0 in git. -- Add icc fvisibility bug test +Yang Tse (21 Aug 2011) +- Makefile.netware: SIZEOF_SHORT definition -- Fix icc 9.0 compiler warning: external definition with no prior declaration +- warnings: fix some 'conversion may lose significant bits' compiler warnings -- Fix three var names +- configure: fix symbol hiding usability check + + A more thorough test is done now in order to determine visibility attribute + usability, given that some compilers don't support visibility attribute on + all configurations. -- Add check for assert.h header file +Daniel Stenberg (16 Aug 2011) +- 1.7.6: start working... -- getaddrinfo is fully thread safe on solaris versions which - implement the function even when h_errno is not a macro. - - The h_errno macro test now only done on systems for which there - is no hard coded knowledge about getaddrinfo's thread safeness. +Version 1.7.5 (16 Aug 2011) -- Remove files generated on previous buildconf/configure run +Daniel Stenberg (16 Aug 2011) +- CHANGES: synced for 1.7.5 release -- Remove enable-thread / disable-thread configure option. These were only placebo - options. The library is always built as thread safe as possible on every system. +- RELEASE-NOTES: synced with bb4096effef7f000 -- Refactor how preprocessor symbol _THREAD_SAFE definition is done. +Jakub Hrozek (15 Aug 2011) +- Only fall back to AF_INET searches when looking for AF_UNSPEC addresses -- Assume that getaddrinfo is thread safe, unless hard coded - knowledge says the contrary or h_errno is not defined. +Yang Tse (10 Aug 2011) +- [Gisle Vanem brought this change] -- Related with the threadsafe capability of getaddrinfo: + ares_iphlpapi.h: Watcom C fix - - Constantine Sapuntzakis reported that Darwin 6.0 a.k.a. MAC OS X 10.2 - and newer have a threadsafe getaddrinfo. + Added "!defined(_WS2DEF_)" since Watcom doesn't have + a per type guard for the typedefs 'CSADDR_INFO' (that MingW has) or + 'SOCKET_ADDRESS' (that MSVC has). But we can use the header-guard for + instead. + +- [Gisle Vanem brought this change] + + Makefile.Watcom: + * The 'NTDDI_VERSION' needs to be raised to 0x05010000 + in order for SOCKADDR_STORAGE etc. to be typedefed. + * Replaced '-dUSE_WATT32' with '-dWATT32'. + * Added $(DEMOS) to the 'all' target and removed the 'demos' + target to be consistent with e.g. Makefile.msvc etc. + * 'ENABLE_IPV6' is no longer used. Hence removed the '%use_ipv6' construct. + * object-file order seems to be important (Watcom v.19). Hence + 'ares_getopt.obj' must be put after the .obj that references getopt(). + +- cares-compilers.m4: CARES_CONVERT_INCLUDE_TO_ISYSTEM adjustments - - Fix Dragonfly BSD triplet detection. + Add CARES_CHECK_COMPILER as a requirement. - - In case the hard-coded knowledge says that getaddrinfo is threadsafe, - an additional check is done to verify that h_errno is also defined. - If h_errno isn't defined, we finally assume that it isn't threadsafe. - Jamie Lokier provided the inspiration for this extra check. - -- AIX 5.2 and newer have threadsafe getaddrinfo. + Ensure macro does nothing unless GNU_C or CLANG compiler is used. - Add some comments to better understand what the regex's pretend to achieve. + This should allow usage of this macro in unforeseen placements. -- HP-UX 11.11 and later have threadsafe getaddrinfo +- config-win32.h: comments adjustments - followup -- Check if getaddrinfo is threadsafe when function check allows it to be used +- config-win32.h: comments adjustments -- Renamed fpGetNetworkParams and fpSystemFunction036 to avoid namespace pollution with static library +Daniel Stenberg (5 Aug 2011) +- [Tom Hughes brought this change] -- Add kernel32.lib + ares_parse_a_reply: fix memleak -- Mention last changes +Yang Tse (29 Jul 2011) +- cares-functions.m4 serial # bump -- Reinstate copyright symbol lost in previous commit +- Revert "configure: additional flag checks for fcntl() and socket()" + + This reverts commit 5f2a3b0e48f26d24cb1fefea0dccb92d417dcbf7. -- Make some strings different in resource file for debug or release builds +- configure: additional flag checks for fcntl() and socket() -- Ignore more subdirs +- xc-translit.m4 fix quoting -- Fix compiler warning: conditional expression is constant +- configure: avoid direct usage of AS_TR_* macros -- Sync linker and resource compiler options with Makefile.msvc +- xc-translit.m4 provides transliteration macros with well defined behavior. -- Follow Makefile.msvc subdirectory naming scheme, and sync compiler options +Jakub Hrozek (15 Jun 2011) +- Revert "Only fall back to AF_INET searches when looking for AF_UNSPEC addresses" + + This reverts commit b5823d65706af687c0e5110af8f0cfdcd068997d. + + This patch was not reviewed properly before pushing -- Updated MSVC makefile that allows building dynamic and static - c-ares libraries in debug and release flavours. +- Revert "Do not use sized constants in public headers" - Additionally each of the three sample programs is built against - each of the four possible c-ares libraries, generating all this - a total number of 12 executables and 4 libraries. + This reverts commit 22c01e96f7b2ae9923e1baa50bfe3c0d22297a7d. + + This is a Red Hat specific patch that does not belong into upstream -- Test for USE_WINSOCK since it is more restrictive than WIN32 +- Use correct sizeof in ares_getnameinfo() -- Make header inclusion depend on HAVE_*_H definition +- Do not leak rr_name on failures inside ares_parse_ptr_reply -- Remove unneeded preprocessor directives +- Do not leak rr_name on failures inside ares_parse_a_reply -- Adjust c-ares include paths for memory tracking enabled (--enable-curldebug) builds +- Do not leak rr_name on failures inside ares_parse_aaaa_reply -- source files used by sample programs +- Do not leak rr_name on failures inside ares_parse_ns_reply -- Renamed c-ares setup.h to ares_setup.h +- Fix incorrect sizeof() in ares_save_options -- Adjust include paths to take in account that currently: - - c-ares with --enable-curldebug uses memdebug.h from libcurl's lib subdirectory. - - memdebug.h needs access to libcurl's setup.h from libcurl's lib subdirectory - and also needs access to libcurl's generated curl_config.h +- Fix incorrect allocation in ares_parse_ptr_reply() -- Undo old temporary change once used for testing purposes +- Only fall back to AF_INET searches when looking for AF_UNSPEC addresses -- Mention many changes +- Do not use sized constants in public headers -- Mention --enable-symbol-hiding configure option +Daniel Stenberg (13 Jun 2011) +- [Jakub Hrozek brought this change] -- Symbol hiding configure options renamed to the hopefully less ambiguous - --enable-symbol-hiding and --disable-symbol-hiding as well as related - macro names and some internal variables used for them. - - Related configuration file preprocessor symbols named to - CARES_SYMBOL_HIDING and CARES_SYMBOL_SCOPE_EXTERN. + ares_free_hostent(NULL) should be a noop -- Header inclusion depending on HAVE_* symbol. - Fix two typos. +Yang Tse (8 Jun 2011) +- configure: fix recvfrom 5th arg type qualifier detection (followup) -- Comparison of the Initial revision of this file with ares_parse_a_reply.c - shows that this one is actually a modified copy of ares_parse_a_reply.c. +- configure: fix recvfrom 5th arg type qualifier detection - In order to comply with ares_parse_a_reply.c's M.I.T. license, the old - 1998 M.I.T. copyright notice is now also preserved in this file the same - as it is done in other ares_parse_*.c files. + Additionally remove whitespace from EOL -- Add CVS Id tag. - Fix identation of some license lines. +Daniel Stenberg (4 Jun 2011) +- strlen: use size_t to receive the return -- Add CVS Id tag. +Yang Tse (4 Jun 2011) +- xlc: avoid preprocessor definition usage when linking -- Fix comment +- ares_nowarn: icc 9.1 workaround -- In no particular order, changed/fixed all of the following in - ares_parse_txt_reply() current version: - - - Fixed a couple of potential double free's. - - - Fixed memory leaks upon out of memory condition. - - - Fixed pointer arithmetic. - - - Setting ntxtreply to zero upon entry for all failure cases. - - - Changed data type to size_t for variables substr_len, str_len and - the length member of ares_txt_reply struct. - - - Avoided a couple of memcpy() calls. +- ares_nowarn: header inclusion fix + +- ares_init: make ares_private.h last included header again + +- compiler warning: fix - - Changed i data type to unsigned int to prevent compiler warnings. + Fix compiler warning: conversion may lose significant bits + +- compiler warning: fix - - Adjusted a comment. + Fix compiler warning: variable was set but never used - - Use ARES_SUCCESS literal for successfull completion. + Fix compiler warning: clobber ignored + +- ares_iphlpapi: fix compiler warnings + +- winsock: compilation fixes - - Added CVS Id tag. + Provide winsock iphlpapi alternative definitions to prevent compilation + failures when using a variety of winsock header implementations. -- Add c-ares DLL resource file to distribution archive +Daniel Stenberg (17 May 2011) +- [David Stuart brought this change] -- ignore files + IPv6-on-windows: find DNS servers correctly -- Empty subdir +- man pages: docs for the c-ares utility programs -- Updated MSVC 6.0 workspace and project files that allows building - dynamic and static c-ares libraries in debug and release flavours. - - Additionally each of the three sample programs is built against - each of the four possible c-ares libraries, generating all this - a total number of 12 executables and 4 libraries. +- ares_parse_ns_reply.c: remove CVSism -Daniel Stenberg (29 Oct 2009) -- no need to check for NULL pointers before dereferencing, as the pointers - MUST be valid and they are dereferenced further down in the function - unconditionally! +Yang Tse (27 Mar 2011) +- build: fix header inclusion -- shorten the descriptions somewhat +- getservbyport replacement for Win CE -- update to the new struct name +- renamed getplatform() to ares__getplatform() to avoid namespace pollution -- Jakub Hrozek added ares_parse_txt_reply() for TXT parsing +- configure: fix libtool warning + + Recent versions of libtool are now tracing usage of AC_CONFIG_MACRO_DIR + macro and warn heavily when not used in configure script along with + ACLOCAL_AMFLAGS in Makefile.am. So in order to make libtool happy + while keeping backwards compatibility this is added. -- use 'ares_srv_reply' for proper name-spacing +- adig: RFC4034 resource record type detection + + Can be tested with: adig -s 8.8.8.8 -t ANY example.com -Yang Tse (29 Oct 2009) -- Add reference for ares_parse_srv_reply.pdf +- nameser.h: RFC4034 resource record type definitions -- Add reference for ares_parse_srv_reply docs +- build: move platform stuff to ares_platform.c and ares_platform.h -- External API function linkage decoration adjustment +- build: find out windows platform using GetVersionEx() -- External API function linkage decoration adjustment +- build: use getenv() replacement function for systems which lack it -- Initial step towards the ability to reduce c-ares exported symbols - based on the 'visibility' attribute for GNUC and __global for Sun - compilers, taking also in account __declspec function decoration - for Win32 and Symbian DLL's. - - Introducing configure options --enable-hidden-symbols and - --disable-hidden-symbols following libcurl's naming. +- setup_once: system error codes for Windows CE -- Fix comment +- ares_search: use ERRNO macro for portability sake -- Fix spelling +- System's errno.h inclusion cleanup follow-up. + + System's errno.h is conditionally included from setup_once.h -- Fix Pelles C Win32 target compilation issues +- Windows CE specific adjustment + + All versions of Windows CE support Winsock 1.1 -- John Engelhart noticed an unreleased problem relative to a duplicate - ARES_ECANCELLED error code value and missing error code description. +- System's errno.h inclusion cleanup. + + System's errno.h is conditionally included from setup_once.h -- Fix compiler warning: local variable may be used without having been initialized +- ares_init: fix gethostname error detection on winsock platforms -- Use *_CHECK_PATH_SEPARATOR_REQUIRED to ensure that *_CHECK_PATH_SEPARATOR - is only expanded and included once in the configure script. +- configure: r-enable temporarily disabled detection of system's inet_ntop() + + Detection was temporarily disabled in commit 674e044ccb21f2f63537da53565fce868f -- Our _AS_PATH_SEPARATOR_PREPARE override is now m4_defun'd instead of m4_define'd - due to autoconf 2.64 m4_require'ing it in _AS_SHELL_SANITIZE indirectly through - _AS_PATH_WALK. +Daniel Stenberg (15 Mar 2011) +- configure: stop using the deprecated AM_INIT_AUTOMAKE syntax -- Fix compiler warning: argument is incompatible with corresponding format string conversion +- [Gisle Vanem brought this change] -- Fix potential out-of-bounds read + Watt-32: use errno + + Make sure Watt-32 programs use 'errno' even on Win32 targets -- Fix compiler warning: loop without body +Guenter Knauf (18 Feb 2011) +- Removed commented CLFAGS no longer needed. -- Fix compiler warning +- Fixed CFLAGS for NetWare. + + Added -m32 to enable compilation with x86_64 compilers; + added conditional to set -fpcc-struct-return only for gcc compiler. -- Fix compiler warning +Daniel Stenberg (18 Feb 2011) +- [Gisle Vanem brought this change] -- Fix compiler warning + Watt32: fix server init + + Somewhere in the process, programs using the Watt-32 tcp/ip stack + stopped working. -- Fix compiler warning: addition result could be truncated before cast to bigger sized type +- [Dima Tisnek brought this change] -- Overhauled ares__get_hostent() + config_sortlist: (win32) missing else - - Fixing out of bounds memory overwrite triggered with malformed /etc/hosts file. - - Improving parsing of /etc/hosts file. - - Validating requested address family. - - Ensuring that failures always return a NULL pointer. - - Adjusting header inclusions. + Without an else there, contents of "pat" that could have been + successfully set just above, may be clobbered by successive unsuccessful + calls to "xxx_pton" or "ip_addr". -- Fix ssize_t redefinition errors on WIN64 reported by Alexey Simak +Yang Tse (17 Jan 2011) +- Makefile.msvc: add a couple of VS version strings + +- Makefile.msvc: add a couple of VS version strings -- more files to ignore +- build: add install target to Makefile.msvc -- Check if _REENTRANT definition is required to - make errno available as a preprocessor macro. +Daniel Stenberg (27 Dec 2010) +- ares_set_servers_csv: remove unused variables -- Attempt to silence bogus compiler warning: "Potential null pointer dereference" +- init_by_resolv_conf: fix compiler warnings + + The code received the return codes in the 'status' variable without + using it. Instead we just ignore those particular errors. -- ignore more files +- getv4: Value stored to 'dst' is never read -Gisle Vanem (7 Sep 2009) -- Suppress warnings about unused prototypes in Watt32 and Win32 programs. +- advance_tcp_send_queue: avoid NULL ptr dereference + + If given a too large 'num_bytes' value, it would cause a NULL ptr + dereference. Instead the code will now break out of the loop at the end + of the list. -- Update email address. +- [Peter Pentchev brought this change] -- Update my email address. Add ares_config.h as dependency for 'make depend'. + configure: fix a bashism -Yang Tse (6 Sep 2009) -- T_SRV portability check +- cleanup: avoid unsafe typecasts + + Avoid the risk of reading 16bit data from an unaligned address by using + a macro that is adapted for this. -Gunter Knauf (5 Sep 2009) -- changed includes to match style how we do with all other *.c files. +- [Stefan Bühler brought this change] -- changed u_int16_t to unsigned short because it is the only place within ares and curl where such a type would be used; - also it broke many autobuilds. We should probably introduce an ares_port_t if we want to use a type here. + ares_expand_name: Fix encoded length for indirect root -Gisle Vanem (5 Sep 2009) -- Replace 'uint16_t' with 'u_int16_t' since the latter is used in ares.h. +Yang Tse (18 Dec 2010) +- build: add some explicit file references to VS project files -- Added 'ares_parse_srv_reply.obj'. Added definition of 'u_int16_t'. This is I don't like; we should not depend on such non-universal types in a public header. But this is just a quick fix. +- config-win32: provide HAVE_ASSERT_H definition -Daniel Stenberg (4 Sep 2009) -- - Jakub Hrozek added ares_parse_srv_reply() for SRV parsing +- build: include ares_nowarn in sample program VS project files -Steinar H. Gunderson (27 Aug 2009) -- Support lookup of IPv4 literals in ares_gethostbyname(), even when the address family is set to AF_INET6. +- build: include ares_nowarn among SAMPLESOURCES and SAMPLEHEADERS -Gisle Vanem (3 Aug 2009) -- Remove call to LoadLibrary(). (leftover from debugging). +- configure: temporarily disable detection of system's inet_ntop() + + This is done to allow compilation of ares_inet_ntop() by some daily + builds picky compilers that otherwise do not need this function. -- Fix bad sentence. +- changes: mention last fix -Daniel Stenberg (3 Aug 2009) -- - Timo Teras changed the reason code used in the resolve callback done when - ares_cancel() is used, to be ARES_ECANCELLED instead of ARES_ETIMEOUT to - better allow the callback to know what's happening. +- ares_inet_ntop: remove definition and usage of macro SPRINTF + + Existing definition of SPRINTF always resulted in sprintf() being used, + and sprintf() returning 'int' is already used throughout the library. -- - Joshua Kwan fixed the init routine to fill in the defaults for stuff that - fails to get inited by other means. This fixes a case of when the c-ares - init fails when internet access is fone. +- ares_inet_ntop: reapply changes from previous c-ares version (III) + + - Replace 'u_char' with 'unsigned char'. + - Replace 'u_int' with 'unsigned int'. + - use macros ERRNO and SET_ERRNO() for errno handling. -Gunter Knauf (16 Jul 2009) -- test if adding ../lib to includes can fix the current break ... +- ares_inet_ntop: reapply changes from previous c-ares version (II) + + - Remove rcsid. + - Adjust header file inclusions. + - ares_inet_ntop used only on systems without a proper inet_ntop function. -- renamed generated config.h to ares_config.h in order to avoid clashes when libcurl is used with other projects which also have a config.h. +- ares_inet_ntop: reapply changes from previous c-ares version (I) + + - Replace tabs with spaces. + - Use ANSI C style for function declarations and definitions. + - Use sizeof with parentheses. -Yang Tse (21 Jun 2009) -- Refactor how libraries are checked for connect() function, follow-up. +- ares_inet_ntop: fix off by one error triggering out of bounds write + + ares_inet_ntop would trigger an out of bounds write when the representation + of the address required 15 characters, due to not taking in account null + termination character. + + Full import of inet_ntop.c from bind-9.5.3rc1 to pull additional fixes. -- Refactor how libraries are checked for connect() function, - and check for connect() as it is done for other functions. +- ares_nowarn: add conditional inclusion of assert.h header -Gisle Vanem (20 Jun 2009) -- Remove unneeded defines. +- fix compiler warning: conversion may lose significant bits -- Use select_s() and not select(). +- ares_inet_net_pton: fix non-rejection of some malformed literals + + ares_inet_net_pton would return wrong values when excessively large, + and invalid, netmasks are used. Fixes are from bind-9.5.3rc1, + issue also described in the WLB-2008080064 advisory. -Yang Tse (19 Jun 2009) -- sclose() function-like macro definition used to close a socket, - now solely based on HAVE_CLOSESOCKET and HAVE_CLOSESOCKET_CAMEL - config file preprocessor definitions. +- setup_once: provide ISASCII macro -- add CloseSocket camel case function check +- configure: inet_net_pton function check adjustments + + Define HAVE_INET_NET_PTON only when system's inet_net_pton function is IPv6 + capable and is not affected by the WLB-2008080064 advisory. + + HAVE_INET_NET_PTON_IPV6 is no longer defined nor used. -- check for socket() and closesocket() as it is done for other functions +- ares_init: fix detection of semicolon comments in resolv.conf + + File resolv.conf may either use a hash '#' or a semicolon ';' character as an + indication that the rest of the line is a comment. This fixes not recognizing + the semicolon as a valid comment indicator in resolv.conf. -- Remove HAVE_CONFIG_H definition from here, - CFLAGS from common.dj already defines it. +- version: start working on 1.7.5 -- initial step towards decoupling c-ares from libcurl for DOS +Version 1.7.4 (8 Dec 2010) -- don't ignore these subdirs, they must be removed first +Daniel Stenberg (8 Dec 2010) +- release-preps: CHANGES and RELEASE-NOTES synced -- Remove DEBUGBUILD symbol definition, is not required for programs using the library. +- ares_set_local_*: added in 1.7.4, not before -- DEBUGBUILD symbol definition for debug builds +Yang Tse (3 Dec 2010) +- build: provide SIZEOF_SIZE_T definition for non-configure builds -- ignore some subdirs +- build: config.dos renamed to config-dos.h -- fix comment +- build: provide SIZEOF_SIZE_T netware definition -- Try to make more clear that --enable-curldebug has nothing to do with --enable-debug for this library. +- ares_gethostbyaddr: fix compiler warning: conversion may lose significant bits -- Revert last change, it is inappropriate. +- configure: undo using autobuilds to temporarily verify strict aliasing warnings. -Gisle Vanem (12 Jun 2009) -- Replace CURLDEBUG with DEBUGBUILD. +- fix compiler warning: rounding, sign extension, or loss of accuracy may result -Yang Tse (11 Jun 2009) -- when running automake copy missing files instead of symlinking them +Daniel Stenberg (2 Dec 2010) +- [Ben Noordhuis brought this change] -- Adjusted to take in account that... - - With the curl memory tracking feature decoupled from the debug build feature, - CURLDEBUG and DEBUGBUILD preprocessor symbol definitions are used as follows: + ares_parse_a_reply: fix CNAME response parsing - CURLDEBUG used for curl debug memory tracking specific code (--enable-curldebug) + Reply to a CNAME query doesn't contain addresses, causing + ares_parse_a_reply() to bail out with ARES_ENODATA - DEBUGBUILD used for debug enabled specific code (--enable-debug) - -- c-ares' --enable-debug --enable-curldebug decoupling follow-up - -- mention last changes + Bug: http://groups.google.com/group/nodejs/browse_thread/thread/a1268c9ea5e9ad9b -- Remove buildconf.bat from release and daily snapshot archives. - - buildconf.bat is only for CVS tree builds. +Yang Tse (1 Dec 2010) +- fix compiler warning: conversion may lose significant bits -- Ensure that buildconf.bat does nothing unless it is used with a CVS checkout. +- atoi: remove atoi usage -- CVS-INFO file only present in CVS tree, never in release nor daily snapshot - archives. Used as a sentinel file in buildconf.bat to differentiate CVS builds. +- ares_init: fix compiler warning: conversion may lose significant bits -Gisle Vanem (8 Jun 2009) -- Update comment about "ML". Removed "-D_USE_32BIT_TIME_T" (not a requirement). +- configure: fix autoconf warning -Yang Tse (8 Jun 2009) -- just comment it out +- inet_pton: fix compiler warning -- For debugging purposes... +- configure: use autobuilds to temporarily verify strict aliasing warnings. - Disable the '-export-symbols-regex' to discard this as the origin - of link failures related with shared libraries and non-GNU linkers. - -- c-ares Makefile.am back to using $(top_builddir) for *_LDADD + Temporarily, When cross-compiling with gcc 3.0 or later, enable strict aliasing + rules and warnings. Given that cross-compiled targets autobuilds do not run the + test-suite, there is no risk of running code that violates strict aliasing rules -- c-ares' -no-undefined and --enable-curldebug adjustments +- ares_getnameinfo: Partially revert commit 85520d66e0ac7ac73411bc25e98769a88b2f + + Upon socket address family and length validation failure return ARES_ENOTIMP + in callback again, this is the error code documented in man page and used + mostly all over the library. -- Use relative path to built c-ares tree libtool library +- ares_getnameinfo: Validate socket address family and length. + + Validate socket address family and that the socket address length is appropriate + for the specified family. Failure is reported with ARES_EBADFAMILY in callback. -- John E. Malmberg noticed that the configure script was failing to detect the - timeval struct on VMS when building with _XOPEN_SOURCE_EXTENDED undefined due - to definition taking place in socket.h instead of time.h +- ares_getnameinfo: fix two compiler warnings -- Fix compiler warning: out of bound access +- Added another VS10 version string -- fix compilation on AIX +- Fix GCC 4 compiler warning 'dereferencing type-punned pointer might break strict-aliasing rules'. -- c-ares' --enable-curldebug adjustments +- Revert commit 494274e653936335c255a47599970de3df21e7c4 -- Remove temporarily introduced memory leak. +- configure: fix autoconf 2.68 warning: no AC_LANG_SOURCE call detected in body -- Temporarily introduce a memory leak to verify curl debug memory tracking works. +- Fix compiler warning: array subscript has type 'char' -- Allow curl debug memory tracking when building a shared library on - systems which support external, undefined, symbols in shared libraries. +- Fix GCC 4 compiler warning 'dereferencing type-punned pointer might break strict-aliasing rules'. -Daniel Stenberg (26 May 2009) -- language fix +- Revert following commits: + 07bc7ea79509bcc9ef6e09151e81766ed00d3392 + 3392a50ea3f8573ea4b7a9d82b9833dab60cb0e9 + 9912637d32c9987719a1ea12db591aee2941891c + + The purpose of the whole patch was to silence a compiler warning triggered + with GCC 4 on file ares_process.c The specific compiler warning was + 'dereferencing type-punned pointer might break strict-aliasing rules'. + + A simpler patch will follow to equally silence the warning. -Yang Tse (26 May 2009) -- Make ares_init(), ares_dup() and ares_init_options() return ARES_ENOTINITIALIZED - if library initialization has not been performed calling ares_library_init(). +- ares_options: reorder header inclusions to make inclusion of + ares_private.h the last included one again. -- c-ares's --enable-curldebug configure option decoupled from c-ares's --enable-debug +Daniel Stenberg (12 Nov 2010) +- [Patrik Thunstrom brought this change] -- Prevent copying 'sourced' manpages for build targets that don't use them. + adig: fix NAPTR parsing + + I ran across a small "issue" in your adig example. + + It is simply the last part of the NAPTR record, the replacement element, + which is not a string, as currently handled in adig, but a domain name. -Daniel Stenberg (23 May 2009) -- minor edits +- ares_save_options: assignments instead of memcpy -Yang Tse (21 May 2009) -- Include .pdf versions of c-ares man pages in distribution tarball. +- init_by_options: don't copy an empty sortlist + + If there aren't any sort items to copy, don't bother. Without this + little precaution it would do a malloc(0) which causes undefined + behaviors and is frowned upon by curl's memdebug-system. -- Allow generation of .html and .pdf versions of c-ares man pages. +Guenter Knauf (3 Oct 2010) +- Minor Watcom makefile tweaks. -Gisle Vanem (21 May 2009) -- $(OBJ_DIR)/ares_getopt.o must be cleaned explicitly. +Daniel Stenberg (30 Sep 2010) +- [Mike Crowe brought this change] -Yang Tse (20 May 2009) -- Mention last changes + Fix lookup with HOSTALIASES set. + + ares__read_line returns ARES_EOF when it reaches the end of the + file. This will happen every time when reading to the end of the + HOSTALIASES file. Unfortunately single_domain treats this error as + being fatal. + + Signed-off-by: Mike Crowe -- Initial ares_library_cleanup(3) man page +Ben Greear (24 Aug 2010) +- Add missing break that caused get_ares_servers to fail. + + Reported-by: Ning Dong + Signed-off-by: Ben Greear -- Update man page +Yang Tse (11 Aug 2010) +- configure: werror related adjustments -- Update man page +Guenter Knauf (8 Aug 2010) +- Added copyright string to ares_version.h and make use of it in other files. -- Initial ares_library_init(3) man page attempt +- Block created ares_build.h for NetWare to avoid usage from other platforms. -- Force revision update, to force CVS to update the $Id date string format +- Fix to overwrite default libname. -- Add same copyright notice as other c-ares files +- Some more Watcom makefile massage ... -- Fix case +- Some more Watcom makefile massage ... -- Remove run-time requirement for advapi32.dll since - c-ares can work even with no advapi32.dll at all. +Ben Greear (4 Aug 2010) +- sock-addr-storage: Detect and deal with lack of .ss_family member. + + AIX, at least, does not have sockaddr_storage.ss_family member. + Detect this in the configure logic and use proper #ifdefs in the + ares_process logic. + + Signed-off-by: Ben Greear + Tested-by: Tor Arntsen -- Intentionally avoid checking if the address of SystemFunction036, a.k.a. - RtlGenRandom, has been located or not. This function is only available on - WinXP and later. When unavailable c-ares uses portable rand() function. +Guenter Knauf (3 Aug 2010) +- Added Watcom makefile based on libcurl's Makefile.Watcom. -- - Provide in external interface preprocessor symbol definitions for - CARES_HAVE_ARES_LIBRARY_INIT and CARES_HAVE_ARES_LIBRARY_CLEANUP - to ease the use of new capabilities. +Ben Greear (31 Jul 2010) +- typo: Fix compile bug for platforms that don't have sockaddr_storage. - - Move ares_version() prototype to ares.h + Bug was introduced by me in previous commit. + + Signed-off-by: Ben Greear -- Introduction of ares_library_init() and ares_library_cleanup() +- Fix aliasing warning in gcc 4.4.4 (at least). + + Should be no functional change, though the code gets a bit + ugglier. + + Signed-off-by: Ben Greear -- Introduction of ares_library_init() and ares_library_cleanup() +Daniel Stenberg (31 Jul 2010) +- ares_set_servers_csv: use ISDIGIT + + The IS*() set of macros are preferred to the regular is*() functions as + they help us avoid the most common pitfalls. -- remove outdated comment +Ben Greear (30 Jul 2010) +- cast arg to isdigit to int + + Looks like it might silence a warning on Netware build. + + Signed-off-by: Ben Greear -- Fix preprocessor conditional expression +- remove all uses of uint32_t + + Previous fix forgot a few. + + Signed-off-by: Ben Greear -- fiX *__SOCKLEN_T definitions for remaining targets +- fix signed v/s unsigned casts warning in ares_gethostbyaddr.c + + Signed-off-by: Ben Greear -- *__SOCKLEN_T definitions for OS400 already fixed +- local-bind-fixup: Fix inet_pton warning. + + Conditionally include for inet_pton + headers. + + Signed-off-by: Ben Greear -- fIX *__SOCKLEN_T definitions for SYMBIAN32 and VMS targets +- build: Enable compiling with -Werror. + + This helps find compile warnings because they simply break + the build. + + To use: + ./configure --enable-warnings --enable-werror + + Signed-off-by: Ben Greear -Daniel Stenberg (11 May 2009) -- - Gregor Jasny made c-ares link with libtool 's -export-symbols-regex option to - only expose functions starting with ares_. +- ipv6: Fix some build issues related to the local-bind feature. + + Signed-off-by: Ben Greear -Yang Tse (11 May 2009) -- Remove experimental check. Currently there's no need for it. +Guenter Knauf (29 Jul 2010) +- Replaced uint32_t with unsigned int to fix broken builds on a couple of platforms. -- Fix an m4 overquoting triggering a spurious 'AS_TR_CPP' symbol definition - attempt in generated config.h +Daniel Stenberg (18 Jul 2010) +- [Ben Greear brought this change] -- Proper naming for the experimental compiler test and moved to *-compilers.m4 + local-bind: Support binding to local interface/IPs + + Add 3 new functions to set the local binding for the out-going + socket connection, and add ares_set_servers_csv() to set a + list of servers at once as a comma-separated string. + + Signed-off-by: Ben Greear -- Moved *_CHECK_COMPILER_HALT_ON_ERROR and *_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE to *-compilers.m4 along with other *_CHECK_COMPILER_* +- version: now start on 1.7.4 -- fIX *__SOCKLEN_T definitions for OS400 and generic GCC targets +- [Andrew C. Morrow brought this change] -- fIX *__SOCKLEN_T definitions for MVS and 370 targets + fix memory leak in ares_getnameinfo -- fIX *__SOCKLEN_T definitions for several Windows target tool-chains +Version 1.7.3 (11 Jun 2010) -- HP-UX's X/Open network library requirement check follow-up +Daniel Stenberg (11 Jun 2010) +- changelogs: updated for 1.7.3 -- HP-UX's X/Open network library requirement check follow-up +- [BogDan Vatra brought this change] -- Use build-time configured ares_socklen_t instead of socklen_t + init: allow c-ares to work on Android OS -- David McCreedy's "TPF-platform specific changes to various files" patch follow-up +- changelog: fill in the 1.7.2 changes -Daniel Stenberg (1 May 2009) -- s/libcurl/c-ares +- added another pdf to ignore -- version number typo fix +Yang Tse (11 Jun 2010) +- add ares_parse_mx_reply.c to VS dsp file -Yang Tse (1 May 2009) -- David McCreedy's "TPF-platform specific changes to various files" patch +Daniel Stenberg (10 Jun 2010) +- tarball: add $(CSOURCES) $(HHEADERS) to EXTRA_DIST + + It's not clear to me why we need this, but we apparently may + otherwise not get all files bundled in the dist tarball. -- Check definition of _XOPEN_SOURCE_EXTENDED with the compiler +- version: start working on 1.7.3 -- Check if X/Open network library is required +Version 1.7.2 (10 Jun 2010) -- cope with ares_build.h and ares_rules.h follow-up +Daniel Stenberg (10 Jun 2010) +- RELEASE-NOTES: 1.7.2 details added -- Added some notes regarding ares_build.h +- [Jakub Hrozek brought this change] -- fix EOL + ares_init: Last, not first instance of domain or search should win -- fix EOL +- style: make code less than 80 columns wide -- cope with ares_build.h and ares_rules.h +Yang Tse (31 May 2010) +- [Tor Arntsen brought this change] -- buildconf.bat for CVS-tree c-ares + improve alternative definition of bool to use enum instead of unsigned char -- Use 'unsigned int' instead of size_t attempting to avoid header inclusion +- fix VS2010 compiler warnings -- NetWare LibC's getpeername() third argument data type is size_t +Daniel Stenberg (18 Apr 2010) +- [Jérémy Lal brought this change] -- Remove temporary debug tracing for ares_socklen_t Windows targets + added ares_parse_mx_reply -- ares_socklen_t follow-up +- repair the file mode -- ares_build.h Windows follow-up +- remove all $Id$ lines -- Add temporary debug tracing for ares_socklen_t Windows targets +- remove all .cvsignore files -- ares_build.h NetWare follow-up +- spell fix + + reported by Gregor Jasny on the mailing list -- ares_build.h NetWare attempt +- [Peter Pentchev brought this change] -- Initial step towards a configure time ares_socklen_t definition + Fix a couple of typos and grammar nits. -- ignore stamp-h* +- ignore the GPG signature files too -- Added CARES_INCLUDES_SYS_TYPES +- start the journey towards 1.7.2 -- Initial step towards a configure time curl_socklen_t definition +- no longer CVS tagging -- avoid use of alloca() +- ignore generated PDFs -- Moved potential inclusion of system's malloc.h and memory.h header files to - setup_once.h. Inclusion of each header file is based on the definition of - NEED_MALLOC_H and NEED_MEMORY_H respectively. +Version 1.7.1 (23 Mar 2010) -- ignore +Daniel Stenberg (23 Mar 2010) +- 1.7.1 -Gisle Vanem (18 Apr 2009) -- Added '-DHAVE_LIMITS_H'. +- made README the primary readme file + + ... and did README.cares to contain a historic reason etc. -Yang Tse (17 Apr 2009) -- remove compiler options used while debugging the icc 9.1 optimizer issue +- s/CVS/git -- moved HAVE_LIMITS_H to common defines +- git now, not CVS -- Set HP-UX compiler warning level back to the one that exposes - the socklen_t issue on this platform. +- ignore lots of generated files -- HAVE_LIMITS_H definition for NetWare CLIB +- [Daniel Johnson brought this change] -- use HAVE_LIMITS_H symbol to protect limits.h inclusion + Fix warnings for clang -- fix compiler warning: implicit conversion shortens 64-bit value into a 32-bit value +Yang Tse (17 Mar 2010) +- replaced intel compiler option -no-ansi-alias with -fno-strict-aliasing -- s/u_long/unsigned long/ +- update outdated serial number -- Do not halt compilation when using VS2008 to build a Windows 2000 target +- fix compiler warning -- ignore +- watt32 compilation fix -Phil Blundell (3 Feb 2009) -- * February 3 2009 (Phil Blundell) - - If the server returns garbage or nothing at all in response to an AAAA query, - go on and ask for A records anyway. +- Added another VS10 version string -Daniel Stenberg (31 Jan 2009) -- - ares_gethostbyname() now accepts 'AF_UNSPEC' as a family for resolving - either AF_INET6 or AF_INET. It works by accepting any of the looksups in the - hosts file, and it resolves the AAAA field with a fallback to A. +- fix line break -Gisle Vanem (18 Jan 2009) -- fopen() returns error in 'errno' even on Windows. - So don't use ERRNO (GetLastError()). Trimmed trailing - blanks. +- removed usage of 's6_addr', fixing compilation issue triggered with no + longer using 'in6_addr' but only our 'ares_in6_addr' struct -- Constified some arguments in local functions. +Daniel Stenberg (5 Mar 2010) +- Daniel Johnson provided fixes for building with the clang compiler -Daniel Stenberg (14 Jan 2009) -- - ares.h no longer uses the HAVE_STRUCT_IN6_ADDR define check, but instead it - now declares the private struct ares_in6_addr for all systems instead of - relying on one possibly not present in the system. +Yang Tse (5 Mar 2010) +- Added IPv6 name servers support -Phil Blundell (13 Jan 2009) -- - ares__send_query() now varies the retry timeout pseudo-randomly to avoid - packet storms when several queries were started at the same time. +Gisle Vanem (5 Mar 2010) +- Ops!. Readded ares_nowarn.h. -Daniel Stenberg (11 Jan 2009) -- - Phil Blundell added the internal function ares__expand_name_for_response() - that is now used by the ares_parse_*_reply() functions instead of the - ares_expand_name() simply to easier return ARES_EBADRESP for the cases where - the name expansion fails as in responses that really isn't expected. +- Added ares_nowarn.c. -Gunter Knauf (30 Dec 2008) -- added HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID to ares Makefile.netware and sync'd with other Makefile.netware. +Yang Tse (28 Feb 2010) +- Added SIZEOF_INT and SIZEOF_SHORT definitions for non-configure systems -Daniel Stenberg (9 Dec 2008) -- use the new URL +- Added ares_nowarn.* to VC6 project file -- start over on the 1.6.1 release... +- Added SIZEOF_INT definition -Version 1.6.0 (9 Dec 2008) +- fix compiler warning -Daniel Stenberg (9 Dec 2008) -- add space +- fix compiler warning -Gisle Vanem (9 Dec 2008) -- Fix for Win32 targets using Watt-32. +- fix compiler warning -Dan Fandrich (9 Dec 2008) -- C89 compilers (like Minix' ACK) only need to handle 31 functions arguments - so split a long sprintf into two calls to get below that number. +Daniel Stenberg (17 Feb 2010) +- ares_reinit() + + - To allow an app to force a re-read of /etc/resolv.conf etc, pretty much + like the res_init() resolver function offers -Gisle Vanem (8 Dec 2008) -- Added needed defines for Watt-32 on Windows. +- - Tommie Gannert pointed out a silly bug in ares_process_fd() since it didn't + check for broken connections like ares_process() did. Based on that, I + merged the two functions into a single generic one with two front-ends. -- Undefine 'optarg', 'optind' and 'opterr' when using Watt-32 - (to get correct linkage on Windows). +Yang Tse (30 Dec 2009) +- VMS specific preprocessor symbol checking adjustments -- ares_writev() shall not be exported when using Watt-32 (has writev). - Added _USE_32BIT_TIME_T to avoid runtime warning. Applies to - VC-2008+ only. +- Mention last changes -- Removed unneeded defines HAVE_SIGNAL_H, HAVE_SIG_ATOMIC_T, - RETSIGTYPE and HAVE_PROCESS_H. +- - Fix configure_socket() to use ares_socket_t instead of int data type. -Daniel Stenberg (4 Dec 2008) -- the initial version of the ares_set_socket_callback man page +- - Where run-time error checks enabling compiler option /GZ was used it is now + replaced with equivalent /RTCsu for Visual Studio 2003 and newer versions. + + - Compiler option /GX is now replaced with equivalent /EHsc for all versions. -- Gregor Jasny provided the patch that introduces ares_set_socket_callback(), - and I edited it to also get duped by ares_dup(). +- - Ingmar Runge noticed that Windows config-win32.h configuration file + did not include a definition for HAVE_CLOSESOCKET which resulted in + function close() being inappropriately used to close sockets. -Dan Fandrich (4 Dec 2008) -- Bring the sys/include.h include test in line with curl's. +Daniel Stenberg (30 Nov 2009) +- start working on 1.7.1 -Daniel Stenberg (3 Dec 2008) -- Let's not call ares_save_options() deprecated just yet +Version 1.7.0 (27 Nov 2009) -- Introduce ares_dup(3) and new thoughts about API/ABI and how to move forwards. - Also discussed on the ml. +Yang Tse (27 Nov 2009) +- Preserve empty line following last target -Dan Fandrich (2 Dec 2008) -- Make sure sys/socket.h is included before netinet/in.h (required by - OpenWatcom C, and condoned by SUS) +- - Larry Lansing fixed ares_parse_srv_reply to properly parse replies + which might contain non-SRV answers, skipping over potential non-SRV + ones such as CNAMEs. -Daniel Stenberg (1 Dec 2008) -- minor indent fix +- When using icc, compile with -fpic and link with intel dynamic libraries. -- Convert the public config struct to the same binary size/construct as in the - latest releases to remain ABI compatible. +- Added 'currently' in italics to insist on transient situation. -Gisle Vanem (29 Nov 2008) -- Added '-DHAVE_GETHOSTNAME'. +- Fix language -Dan Fandrich (29 Nov 2008) -- Make sure sys/socket.h is included before netinet/in.h (required by - OpenWatcom C) +- Daniel wants upcoming release to be 1.7.0 -- Netware has gethostname() +- Mention last changes -- Fixed a couple of typos +- - Removed from external interface preprocessor symbol definition for + CARES_HAVE_ARES_FREE_DATA. Current functionality of ares_free_data() + makes it unnecessary. -- Don't tweak the HAVE_* macros when using autoconf +- Added README.msvc -- Make use of gethostname() conditional on it being available +- Changed c-ares naming conventions when using MSVC as described in README.msvc -- Only set TCP_NODELAY when it exists +- - Mention other recent changes -Daniel Stenberg (28 Nov 2008) -- updated with changes, preparing for a release soon +- - Jakub Hrozek renamed addrttl and addr6ttl structs to ares_addrttl and + ares_addr6ttl in order to prevent name space pollution, along with + necessary changes to code base and man pages.This change does not break + ABI, there is no need to recompile existing applications. But existing + applications using these structs with the old name will need source code + adjustments when recompiled using c-ares 1.6.1. -Yang Tse (26 Nov 2008) -- Gerald Combs fixed a bug in ares_parse_ptr_reply() which would cause a - buffer to shrink instead of expand if a reply contained 8 or more records. +- - Jakub Hrozek fixed more function prototypes in man pages to sync them + with the ones declared in ares.h -- Brad Spencer provided changes to allow buildconf to work on OS X. +- Make configure remove the ares_build.h file included in distribution tarballs. -- In preparation for the upcomming IPv6 nameservers patch, the internal - ares_addr union is now changed into an internal struct which also holds - the address family. +- Fix macro redefinition. -Dan Fandrich (20 Nov 2008) -- Make checking for struct ifreq a prerequisite for setting - HAVE_IOCTL_SIOCGIFADDR since it's needed to use SIOCGIFADDR and Watcom C - doesn't currently define it. +- Fix name space pollution. -Daniel Stenberg (20 Nov 2008) -- use unsigned short better intead of mixing with ints to prevent compiler - warnings +- Allow using different extra import libraries for debug and release builds. -- please the picky compilers by staying with short as the data we get is short - only +- Add manifest stuff to msvc makefile -- - Brad Spencer brought the new function ares_gethostbyname_file() which simply - resolves a host name from the given file, using the regular hosts syntax. +- Sync man page with reality -Yang Tse (19 Nov 2008) -- user provided PATH_SEPARATOR always overrides auto-detected one +- Add missing external API decoration for ares_set_socket_callback() -- attempting to keep lines below 80 chars +- Add ares_free_data() man page. -- provide a common PATH_SEPARATOR check method which is required by - upcomming work to support the broadest range of Autoconf versions +- - Provide in external interface preprocessor symbol definitions for + CARES_HAVE_ARES_FREE_DATA as an indication of function availability. -- check for gethostbyaddr and gethostbyname as it is done for other functions +- Remove typecast -- Make configure script check if ioctl with the SIOCGIFADDR command can be - used, and define HAVE_IOCTL_SIOCGIFADDR if appropriate. +- Fix comment -- fix leftover from previous commit +- Add ares_data.c and ares_data.h -- fix inet_pton() runtime configure check +- Jakub Hrozek modified ares_parse_srv_reply() and ares_parse_txt_reply() API + to return a linked lists of results. These were also modified to internally + use the ares_data memory struct and as such its result must be free'ed with + ares_free_data(). -- trim down configure script size +- Initial support for the generic ares_free_data() function that will allow + applications to free memory allocated and returned by some c-ares funtions. -Daniel Stenberg (15 Nov 2008) -- Fixed an OOM condition reported by Jim Meyering +- Make usage of calloc()'s arguments consistent with rest of code base -Yang Tse (14 Nov 2008) -- fix typo affecting inclusion of in configure - checks for inet_ntoa_r() inet_ntop() and inet_pton() +- workaround icc 9.1 optimizer issue -- #include in the getaddrinfo() runtime check for the memset() prototype +- Add icc fvisibility bug test -- fix symbol definition check for fcntl.h inclusion +- Fix icc 9.0 compiler warning: external definition with no prior declaration -- Refactor configure script detection of functions used to set sockets into - non-blocking mode, and decouple function detection from function capability. +- Fix three var names -Daniel Stenberg (1 Nov 2008) -- Added a TODO file to list things we want changed, added or fixed. +- Add check for assert.h header file -- - Carlo Contavalli added support for the glibc "rotate" option, as documented - in man resolv.conf: - - causes round robin selection of nameservers from among those listed. This - has the effect of spreading the query load among all listed servers, rather - than having all clients try the first listed server first every time. +- getaddrinfo is fully thread safe on solaris versions which + implement the function even when h_errno is not a macro. - You can enable it with ARES_OPT_ROTATE - -Yang Tse (1 Nov 2008) -- Adjust WIN32 freeaddrinfo, getaddrinfo and getnameinfo availability - -- WIN32 availability of freeaddrinfo, getaddrinfo and getnameinfo functions is quite - convoluted, compiler dependant and in some cases even build target dependat. - -- check for freeaddrinfo() at configuration phase - -- update aclocal file serial number - -- remove verification of the freeability of the addrinfo struct pointer members - -- fix comment - -- make CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_ADDR - and CHECK_FUNC_GETADDRINFO_UNFREEABLE_AI_CANONNAME - internal to CHECK_FUNC_GETADDRINFO - -- fix leftover + The h_errno macro test now only done on systems for which there + is no hard coded knowledge about getaddrinfo's thread safeness. -- Initial attempt to detect at configuration time if the getaddrinfo() - function returns an addrinfo with an unfreeable ai_canonname member ptr. +- Remove files generated on previous buildconf/configure run -- Initial attempt to detect at configuration time if the getaddrinfo() - function returns an addrinfo with an unfreeable ai_addr member ptr. +- Remove enable-thread / disable-thread configure option. These were only placebo + options. The library is always built as thread safe as possible on every system. -- icc adjustments: - - Select ANSI C89 dialect plus GNU extensions, again. +- Refactor how preprocessor symbol _THREAD_SAFE definition is done. -- some more temporary magic for the icc seg-fault issue +- Assume that getaddrinfo is thread safe, unless hard coded + knowledge says the contrary or h_errno is not defined. -- icc permanent adjustment: +- Related with the threadsafe capability of getaddrinfo: - Select precise floating-point model, otherwise doubles are less than 64-bit wide + - Constantine Sapuntzakis reported that Darwin 6.0 a.k.a. MAC OS X 10.2 + and newer have a threadsafe getaddrinfo. - icc test adjustment: + - Fix Dragonfly BSD triplet detection. - Select c89 dialect + - In case the hard-coded knowledge says that getaddrinfo is threadsafe, + an additional check is done to verify that h_errno is also defined. + If h_errno isn't defined, we finally assume that it isn't threadsafe. + Jamie Lokier provided the inspiration for this extra check. -- icc adjustments: - - Enable more icc warnings. +- AIX 5.2 and newer have threadsafe getaddrinfo. - Optimization disabling options used only for icc 9.1 - -- #include for exit() prototype + Add some comments to better understand what the regex's pretend to achieve. -- some more temporary magic for the icc seg-fault issue +- HP-UX 11.11 and later have threadsafe getaddrinfo -- remove from configure.ac temporary magic for the icc seg-fault issue +- Check if getaddrinfo is threadsafe when function check allows it to be used -- some more temporary magic for the icc seg-fault issue +- Renamed fpGetNetworkParams and fpSystemFunction036 to avoid namespace pollution with static library -- Charles Hardin patch: - - - handles the EINPROGRESS for UDP connects - - uses closesocket instead of close on some paths that were noticed +- Add kernel32.lib -- some more temporary magic for the icc seg-fault issue +- Mention last changes -- messages initially intended only for debug purposes, now become permanent - since these are extremely useful when compiler rejects a set of options. +- Reinstate copyright symbol lost in previous commit -- fix compiler warning +- Make some strings different in resource file for debug or release builds -- fix missing double-quotes +- Ignore more subdirs -Daniel Stenberg (17 Oct 2008) -- Charles Hardin made adig support a regular numerical dotted IP address for the - -s option as well. +- Fix compiler warning: conditional expression is constant -Yang Tse (16 Oct 2008) -- some more temporary magic for the icc seg-fault issue +- Sync linker and resource compiler options with Makefile.msvc -- Ensure that shell variable contents which have active meaning - to the shell echo command are not interpreted when trying to - remove extra whitespace from shell variable content. +- Follow Makefile.msvc subdirectory naming scheme, and sync compiler options -- Adjust Watcom C warnings: +- Updated MSVC makefile that allows building dynamic and static + c-ares libraries in debug and release flavours. - Disable warnings on structure members padding. + Additionally each of the three sample programs is built against + each of the four possible c-ares libraries, generating all this + a total number of 12 executables and 4 libraries. -- With this change Solaris target builds will now be done with _REENTRANT defined. +- Test for USE_WINSOCK since it is more restrictive than WIN32 -- Adjust Tiny C basic options: - - Remove -b from debug-enabled configuration, as Tiny C might have - been built without the memory and bounds checker support. +- Make header inclusion depend on HAVE_*_H definition -- Adjust GCC warnings: - - Better disable following warnings when cross-compiling with a gcc older - than 3.0, to avoid warnings from third party system headers: - - -Wmissing-declarations - -Wmissing-prototypes - -Wunused - -Wshadow +- Remove unneeded preprocessor directives -- fix syntax error +- Adjust c-ares include paths for memory tracking enabled (--enable-curldebug) builds -- Initial attempt to detect Watcom C compiler +- source files used by sample programs -- make naming scheme more consistent across whole file +- Renamed c-ares setup.h to ares_setup.h -- Adjust GCC warnings: +- Adjust include paths to take in account that currently: - Disable following warnings when cross-compiling with a gcc older - than 3.0, to avoid warnings from third party system headers: + c-ares with --enable-curldebug uses memdebug.h from libcurl's lib subdirectory. - -Wmissing-prototypes - -Wunused - -Wshadow + memdebug.h needs access to libcurl's setup.h from libcurl's lib subdirectory + and also needs access to libcurl's generated curl_config.h -- Adjust GCC --enable-warnings: - - Do not enable -pedantic when cross-compiling with a gcc older - than 3.0, to avoid warnings from third party system headers. +- Undo old temporary change once used for testing purposes + +- Mention many changes -- adjust SGI MIPSpro C detection +- Mention --enable-symbol-hiding configure option -- LCC compiler adjustments: +- Symbol hiding configure options renamed to the hopefully less ambiguous + --enable-symbol-hiding and --disable-symbol-hiding as well as related + macro names and some internal variables used for them. - Highest warning level is double -A, next is single -A. - Due to the big number of warnings these trigger on third - party header files it is impratical for us to use any of - them here. If you want them simply define it in CPPFLAGS. - -- remove extra space + Related configuration file preprocessor symbols named to + CARES_SYMBOL_HIDING and CARES_SYMBOL_SCOPE_EXTERN. -- split SGI compiler check. One for MIPS C and another for MIPSpro C +- Header inclusion depending on HAVE_* symbol. + Fix two typos. -- LCC compiler adjustments: +- Comparison of the Initial revision of this file with ares_parse_a_reply.c + shows that this one is actually a modified copy of ares_parse_a_reply.c. - Warning level reduced from double -A to single -A - -- Initial attempt to detect Tiny C compiler + In order to comply with ares_parse_a_reply.c's M.I.T. license, the old + 1998 M.I.T. copyright notice is now also preserved in this file the same + as it is done in other ares_parse_*.c files. -- Initial attempt to detect LCC compiler +- Add CVS Id tag. + Fix identation of some license lines. -- 1) fix bug in CONVERT_INCLUDE_TO_ISYSTEM - - 2) Disable SGI remark: controlling expression is constant +- Add CVS Id tag. -- simplify SGI C compiler check +- Fix comment -- HP C adjustments: +- In no particular order, changed/fixed all of the following in + ares_parse_txt_reply() current version: + + - Fixed a couple of potential double free's. - Due to the HP-UX socklen_t issue it is insane to use the +w1 warning level. - It generates more than 1100 warnings on socklen_t related statements. + - Fixed memory leaks upon out of memory condition. - Until the issue is somehow fixed we will just use the +w2 warning level. - -- Add debug tracing for COMPILER_WORKS_IFELSE - -- configure will also warn on 'strict compiler warning' rejected options - -- convert rejected compiler options messages into a warnings - -- remove extra whitespace from string in SGI C check - -- oops - -- Initial attempt to detect SGI C compiler - -- HP C adjustments: + - Fixed pointer arithmetic. - Disallow run-time dereferencing of null pointers. + - Setting ntxtreply to zero upon entry for all failure cases. - Disable some remarks: + - Changed data type to size_t for variables substr_len, str_len and + the length member of ares_txt_reply struct. - #4227: padding struct with n bytes to align member. + - Avoided a couple of memcpy() calls. - #4255: padding size of struct with n bytes to alignment boundary. - -- improve presentation of accepted/rejected debug/optimizer options - -- refactoring of COMPILER_BASIC_OPTS - -- Initial attempt to detect SUN C compiler - -- Initial attempt to detect HP C compiler - -- fix compiler warning: 'dot_4' may be used uninitialized in this function - -- adjust ICC_windows settings - -- fix VAR_STRIP - -- Sync up with reality - -- Initial attempt to support configure's --(dis|en)able-optimize - option to specify dis(activation) of compiler optimizations. + - Changed i data type to unsigned int to prevent compiler warnings. - If option is specified, it will be honored independant of the - --(dis|en)able-debug option. - -- fix comment - -- Initial attempt to support configure's --(dis|en)able-warnings - option to specify dis(activation) of picky compiler warnings. + - Adjusted a comment. - If option is specified, it will be honored independant of the - --(dis|en)able-debug option. + - Use ARES_SUCCESS literal for successfull completion. - If option is not specified, it will follow --(dis|en)able-debug - setting, whose default is disabled if not specified. - -- fix compiler warning: dereferencing type-punned pointer will break strict-aliasing rules + - Added CVS Id tag. -- now compiler warnings are activated for all gcc builds, not only debug ones. +- Add c-ares DLL resource file to distribution archive -- Use CFLAGS for icc linker options instead of LDFLAGS, - otherwise gethostbyname() is not detected. +- ignore files -- use ac_cv_compiler and ac_cv_compiler_num to keep compiler ID and version number +- Empty subdir -- Temporary icc adjustment: +- Updated MSVC 6.0 workspace and project files that allows building + dynamic and static c-ares libraries in debug and release flavours. - Disable floating point optimizations - -- HAVE_INET_PTON will only be defined when an IPv6 capable working - inet_pton function is available. + Additionally each of the three sample programs is built against + each of the four possible c-ares libraries, generating all this + a total number of 12 executables and 4 libraries. -- HAVE_INET_NTOP will only be defined when an IPv6 capable working - inet_ntop function is available. +Daniel Stenberg (29 Oct 2009) +- no need to check for NULL pointers before dereferencing, as the pointers + MUST be valid and they are dereferenced further down in the function + unconditionally! -- ntoa() and inet_ntoa_r() no longer used +- shorten the descriptions somewhat -- icc adjustments for icc 9.0 and prior versions: - - Disable remark #279: controlling expression is constant - - Remark triggered mostly on va_arg() and FD_ZERO() macros. +- update to the new struct name -- attempt to make work the gethostname function - check for winsock build target configurations +- Jakub Hrozek added ares_parse_txt_reply() for TXT parsing -Gisle Vanem (21 Sep 2008) -- Added HAVE_NETDB_H, HAVE_ARPA_INET_H, HAVE_STRCASECMP - and HAVE_STRNCASECMP. +- use 'ares_srv_reply' for proper name-spacing -Yang Tse (19 Sep 2008) -- icc adjustments: - - Disable remark #981: operands are evaluated in unspecified order - - Function calls which are triggering this remark, today, do not depend - on the order of evaluation of its arguments. - - Disable remark #1469: "cc" clobber ignored - - Remark triggered on htons() and ntohs() due to glibc header files. +Yang Tse (29 Oct 2009) +- Add reference for ares_parse_srv_reply.pdf -- icc adjustments +- Add reference for ares_parse_srv_reply docs -- fix netdb.h prerequisite inclusion +- External API function linkage decoration adjustment -- improve detection of getservbyport_r() +- External API function linkage decoration adjustment -- On Linux Intel's icc uses gcc's header files, so - we select ANSI C89 dialect plus GNU extensions. +- Initial step towards the ability to reduce c-ares exported symbols + based on the 'visibility' attribute for GNUC and __global for Sun + compilers, taking also in account __declspec function decoration + for Win32 and Symbian DLL's. + + Introducing configure options --enable-hidden-symbols and + --disable-hidden-symbols following libcurl's naming. -- improve detection of gethostname() +- Fix comment -- NetWare builds include "nameser.h" from the c-ares subdir +- Fix spelling -- include +- Fix Pelles C Win32 target compilation issues -- Sync up with reality +- John Engelhart noticed an unreleased problem relative to a duplicate + ARES_ECANCELLED error code value and missing error code description. -- adjust inclusion of "nameser.h" +- Fix compiler warning: local variable may be used without having been initialized -- reorder some lines in file +- Use *_CHECK_PATH_SEPARATOR_REQUIRED to ensure that *_CHECK_PATH_SEPARATOR + is only expanded and included once in the configure script. -- code cleanup +- Our _AS_PATH_SEPARATOR_PREPARE override is now m4_defun'd instead of m4_define'd + due to autoconf 2.64 m4_require'ing it in _AS_SHELL_SANITIZE indirectly through + _AS_PATH_WALK. -- NetWare seems to have writev() +- Fix compiler warning: argument is incompatible with corresponding format string conversion -- rearrange to allow internal/private use of ares_writev to any system - that lacks the writev function. +- Fix potential out-of-bounds read -- NetWare CLIB target has stricmp() and strnicmp() +- Fix compiler warning: loop without body -- include header file only when available +- Fix compiler warning -- rearrange to allow internal/private use of ares_strcasecmp to any system that - lacks the strcasecmp function. +- Fix compiler warning -- improve detection of: - strcasecmp() - strcmpi() - stricmp() - strncasecmp() - strncmpi() - strnicmp() +- Fix compiler warning -- *** empty log message *** +- Fix compiler warning: addition result could be truncated before cast to bigger sized type -Gisle Vanem (12 Sep 2008) -- djgpp does have strdup(). +- Overhauled ares__get_hostent() + + - Fixing out of bounds memory overwrite triggered with malformed /etc/hosts file. + - Improving parsing of /etc/hosts file. + - Validating requested address family. + - Ensuring that failures always return a NULL pointer. + - Adjusting header inclusions. -Yang Tse (12 Sep 2008) -- change CRLF into LF line endings +- Fix ssize_t redefinition errors on WIN64 reported by Alexey Simak -- strdup() clone for systems/configurations which lack it +- more files to ignore -- move inclusion of ares_private.h last +- Check if _REENTRANT definition is required to + make errno available as a preprocessor macro. -- icc adjustments +- Attempt to silence bogus compiler warning: "Potential null pointer dereference" -- icc adjustments +- ignore more files -- Select strict ANSI C89 conformance for icc +Gisle Vanem (7 Sep 2009) +- Suppress warnings about unused prototypes in Watt32 and Win32 programs. -- remove unnecessary typecasting of malloc() +- Update email address. -- remove unnecessary typecasting of realloc() +- Update my email address. Add ares_config.h as dependency for 'make depend'. -Daniel Stenberg (29 Aug 2008) -- we start over working towards 1.5.4 +Yang Tse (6 Sep 2009) +- T_SRV portability check -Version 1.5.3 (29 Aug 2008) +Gunter Knauf (5 Sep 2009) +- changed includes to match style how we do with all other *.c files. -Daniel Stenberg (29 Aug 2008) -- Version 1.5.3 +- changed u_int16_t to unsigned short because it is the only place within ares and curl where such a type would be used; + also it broke many autobuilds. We should probably introduce an ares_port_t if we want to use a type here. -- added the three people from RELEASE-NOTES and sorted the list alphabetically +Gisle Vanem (5 Sep 2009) +- Replace 'uint16_t' with 'u_int16_t' since the latter is used in ares.h. -Yang Tse (27 Aug 2008) -- Don't abort configuration if recvfrom() is not available. +- Added 'ares_parse_srv_reply.obj'. Added definition of 'u_int16_t'. This is I don't like; we should not depend on such non-universal types in a public header. But this is just a quick fix. -- Functionality only possible if recvfrom() is available. +Daniel Stenberg (4 Sep 2009) +- - Jakub Hrozek added ares_parse_srv_reply() for SRV parsing -- George Neill's fix acountry sample application compilation failure. +Steinar H. Gunderson (27 Aug 2009) +- Support lookup of IPv4 literals in ares_gethostbyname(), even when the address family is set to AF_INET6. -- Brad House's validation that DNS response address matches the request address +Gisle Vanem (3 Aug 2009) +- Remove call to LoadLibrary(). (leftover from debugging). -- fix the output name +- Fix bad sentence. -- Get rid of ENABLE_64BIT symbol definition and usage. - - Improve HAVE_LONGLONG symbol description. +Daniel Stenberg (3 Aug 2009) +- - Timo Teras changed the reason code used in the resolve callback done when + ares_cancel() is used, to be ARES_ECANCELLED instead of ARES_ETIMEOUT to + better allow the callback to know what's happening. -- Export 'ares_process_fd' too. +- - Joshua Kwan fixed the init routine to fill in the defaults for stuff that + fails to get inited by other means. This fixes a case of when the c-ares + init fails when internet access is fone. -Gisle Vanem (16 Aug 2008) -- Ops, remove 'use_vc'. +Gunter Knauf (16 Jul 2009) +- test if adding ../lib to includes can fix the current break ... -- Support Watt-32 under Win32. +- renamed generated config.h to ares_config.h in order to avoid clashes when libcurl is used with other projects which also have a config.h. -Yang Tse (10 Aug 2008) -- Fix: Remove now this SIZEOF_CURL_OFF_T symbol definition. - - This should have been done with the initial 64-bit curl_off_t patch. +Yang Tse (21 Jun 2009) +- Refactor how libraries are checked for connect() function, follow-up. -- Improve CURL_CHECK_DEF +- Refactor how libraries are checked for connect() function, + and check for connect() as it is done for other functions. -- Fix IBM C and DEC/Compaq C compiler detection +Gisle Vanem (20 Jun 2009) +- Remove unneeded defines. -- Initial support of curlbuild.h and curlrules.h which allows - to have a curl_off_t data type no longer gated to off_t. +- Use select_s() and not select(). -- The minimum autoconf version required for this file is 2.50 - - Avoid dot notation in aclocal serial file number, use a single number now. +Yang Tse (19 Jun 2009) +- sclose() function-like macro definition used to close a socket, + now solely based on HAVE_CLOSESOCKET and HAVE_CLOSESOCKET_CAMEL + config file preprocessor definitions. -Daniel Stenberg (4 Aug 2008) -- - Fix by Tofu Linden: - - The symptom: - * Users (usually, but not always) on 2-Wire routers and the Comcast service - and a wired connection to their router would find that the second and - subsequent DNS lookups from fresh processes using c-ares to resolve the same - address would cause the process to never see a reply (it keeps polling for - around 1m15s before giving up). - - The repro: - * On such a machine (and yeah, it took us a lot of QA to find the systems - that reproduce such a specific problem!), do 'ahost www.secondlife.com', - then do it again. The first process's lookup will work, subsequent lookups - will time-out and fail. - - The cause: - * init_id_key() was calling randomize_key() *before* it initialized - key->state, meaning that the randomness generated by randomize_key() is - immediately overwritten with deterministic values. (/dev/urandom was also - being read incorrectly in the c-ares version we were using, but this was - fixed in a later version.) - * This makes the stream of generated query-IDs from any new c-ares process - be an identical and predictable sequence of IDs. - * This makes the 2-Wire's default built-in DNS server detect these queries - as probable-duplicates and (erroneously) not respond at all. +- add CloseSocket camel case function check -Yang Tse (4 Aug 2008) -- Autoconf 2.62 has changed the behaviour of the AC_AIX macro which we use. - Prior versions of autoconf defined _ALL_SOURCE if _AIX was defined. But, - autoconf 2.62 version of AC_AIX defines _ALL_SOURCE along with other four - preprocessor symbols no matter if the system is AIX or not. To keep the - traditional behaviour, as well as an uniform one, across autoconf versions - AC_AIX is replaced with our own internal macro. +- check for socket() and closesocket() as it is done for other functions -- Adjust DEC/Compaq C compiler settings. +- Remove HAVE_CONFIG_H definition from here, + CFLAGS from common.dj already defines it. -- Another AC_TRY_LINK conversion to AC_LINK_IFELSE. - Proper definition of HAVE_function if function is found deeper. +- initial step towards decoupling c-ares from libcurl for DOS -- Sync up with reality +- don't ignore these subdirs, they must be removed first -- Rename reentrant.m4 to avoid filename clash. +- Remove DEBUGBUILD symbol definition, is not required for programs using the library. -- Add file version serial number that might be used by 'aclocal' and others. - - Keep the '#' character as the first one on the line. +- DEBUGBUILD symbol definition for debug builds -- Update copyright year. +- ignore some subdirs -- Sync comment with reality. +- fix comment -- Reinstate the 'aclocal -I m4' in buildconf and 'ACLOCAL_AMFLAGS = -I m4' way of - including our local m4/reentrant.m4 file. This even takes care of including the - file in the distribution tarball. +- Try to make more clear that --enable-curldebug has nothing to do with --enable-debug for this library. -- Add quoting for the AC_DEFINE arguments. +- Revert last change, it is inappropriate. -- Also remove the whitespace. +Gisle Vanem (12 Jun 2009) +- Replace CURLDEBUG with DEBUGBUILD. -- Also remove the extra quoting. +Yang Tse (11 Jun 2009) +- when running automake copy missing files instead of symlinking them -- Replace some '@%:@' quadigraphs by its actual representation '#'. +- Adjusted to take in account that... - This quadigraph used before a C preprocessor 'define' directive could - be fooling M4, when processing this file, and make it think that the - line contains a pure M4 'define' macro. - -- Tests done using 'aclocal -I m4' in buildconf and 'ACLOCAL_AMFLAGS = -I m4 - in top Makefile.am triggered a problem that prevented aclocal from running - successfully on SunOS 5.10 with GNU m4 1.4.5 and GNU Autoconf 2.61 + With the curl memory tracking feature decoupled from the debug build feature, + CURLDEBUG and DEBUGBUILD preprocessor symbol definitions are used as follows: - A tarball which reproduces mentioned problem is the one dated July-28-2008 - http://cool.haxx.se/curl-daily/curl-7.19.0-20080728.tar.gz + CURLDEBUG used for curl debug memory tracking specific code (--enable-curldebug) - We actually don't need all the bells and whistles that the above mechanism - provides. We only need to include our m4/reentrant.m4 file in acinclude.m4 - so here we go with this simpler mechanism. - -- for debugging purposes show ACLOCAL_FLAGS + DEBUGBUILD used for debug enabled specific code (--enable-debug) -- These lines were unintentionally removed in previous commit +- c-ares' --enable-debug --enable-curldebug decoupling follow-up -- Partially undo change that prevented SED, GREP, EGREP and AR from being changed by libtool or autoconf. +- mention last changes -- Assert that SED and GREP are set +- Remove buildconf.bat from release and daily snapshot archives. + + buildconf.bat is only for CVS tree builds. -- Require autoconf 2.57 or newer +- Ensure that buildconf.bat does nothing unless it is used with a CVS checkout. -- When calling aclocal, user defined ACLOCAL_FLAGS will now precede ours. +- CVS-INFO file only present in CVS tree, never in release nor daily snapshot + archives. Used as a sentinel file in buildconf.bat to differentiate CVS builds. -- move ACLOCAL_AMFLAGS after AUTOMAKE_OPTIONS +Gisle Vanem (8 Jun 2009) +- Update comment about "ML". Removed "-D_USE_32BIT_TIME_T" (not a requirement). -- setup.h handles definition of _REENTRANT based on NEED_REENTRANT - definition which might be defined in config.h or config-*.h files +Yang Tse (8 Jun 2009) +- just comment it out -- Remove explicit inclusion of our m4 files first. It was interesting as a test, - but it breaks aclocal execution on some systems, with the following error: +- For debugging purposes... - Can't locate object method "rel2abs" via package "File::Spec" at /usr/local/bin/aclocal line 256. + Disable the '-export-symbols-regex' to discard this as the origin + of link failures related with shared libraries and non-GNU linkers. + +- c-ares Makefile.am back to using $(top_builddir) for *_LDADD + +- c-ares' -no-undefined and --enable-curldebug adjustments -- Another step towards detecting if _REENTRANT is already defined or actually - needed, and being able to define it if appropriate for further configure tests - as well as for the generated config file. +- Use relative path to built c-ares tree libtool library -- Explicitly include our m4 files first. This might minimize the impact - that other package's underquoted m4 function definitions have on ours. +- John E. Malmberg noticed that the configure script was failing to detect the + timeval struct on VMS when building with _XOPEN_SOURCE_EXTENDED undefined due + to definition taking place in socket.h instead of time.h -- Add a 3 argument check for getprotobyname_r +- Fix compiler warning: out of bound access diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..6fe5ef3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,738 @@ +CMAKE_MINIMUM_REQUIRED (VERSION 3.1.0) + +INCLUDE (CheckIncludeFiles) +INCLUDE (CheckTypeSize) +INCLUDE (CheckFunctionExists) +INCLUDE (CheckSymbolExists) +INCLUDE (CheckCSourceCompiles) +INCLUDE (CheckStructHasMember) +INCLUDE (CheckLibraryExists) + +PROJECT (c-ares LANGUAGES C VERSION "1.17.0" ) + +# Set this version before release +SET (CARES_VERSION "1.17.1") + +INCLUDE (GNUInstallDirs) # include this *AFTER* PROJECT(), otherwise paths are wrong. + +# This is for libtool compatibility, and specified in a form that is easily +# translatable from libtool (even if the actual form doesn't make sense). +# For instance, in an autotools project, in Makefile.am there is a line that +# contains something like: +# -version-info 4:0:2 +# This breaks down into sections of current:revision:age +# This then generates a version of "(current-age).age.revision" with an +# interface version of "(current-age)" +# For example, a version of 4:0:2 would generate output such as: +# libname.so -> libname.so.2 +# libname.so.2 -> libname.so.2.2.0 +SET (CARES_LIB_VERSIONINFO "6:2:4") + + +OPTION (CARES_STATIC "Build as a static library" OFF) +OPTION (CARES_SHARED "Build as a shared library" ON) +OPTION (CARES_INSTALL "Create installation targets (chain builders may want to disable this)" ON) +OPTION (CARES_STATIC_PIC "Build the static library as PIC (position independent)" OFF) +OPTION (CARES_BUILD_TESTS "Build and run tests" OFF) +OPTION (CARES_BUILD_CONTAINER_TESTS "Build and run container tests (implies CARES_BUILD_TESTS, Linux only)" OFF) +OPTION (CARES_BUILD_TOOLS "Build tools" ON) + +# Tests require static to be enabled +IF (CARES_BUILD_TESTS) + SET (CARES_STATIC ON) + SET (CARES_STATIC_PIC ON) +ENDIF () + +# allow linking against the static runtime library in msvc +IF (MSVC) + OPTION (CARES_MSVC_STATIC_RUNTIME "Link against the static runtime library" OFF) + IF (CARES_MSVC_STATIC_RUNTIME) + # CMAKE_CONFIGURATION_TYPES is empty on non-IDE generators (Ninja, NMake) + # and that's why we also use CMAKE_BUILD_TYPE to cover for those generators. + # For IDE generators, CMAKE_BUILD_TYPE is usually empty + FOREACH (config_type ${CMAKE_CONFIGURATION_TYPES} ${CMAKE_BUILD_TYPE}) + STRING (TOUPPER ${config_type} upper_config_type) + SET (flag_var "CMAKE_C_FLAGS_${upper_config_type}") + IF (${flag_var} MATCHES "/MD") + STRING (REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}") + ENDIF () + ENDFOREACH () + + # clean up + SET (upper_config_type) + SET (config_type) + SET (flag_var) + ENDIF () +ENDIF () + +# Keep build organized. +SET (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_BINDIR}") +SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") +SET (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}") +SET (PACKAGE_DIRECTORY ${PROJECT_BINARY_DIR}/package) + +# Destinations for installing different kinds of targets (pass to install command). +SET (TARGETS_INST_DEST + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +# Function in Library +# CHECK_LIBRARY_EXISTS can't be used as it will return true if the function +# is found in a different dependent library. +MACRO (CARES_FUNCTION_IN_LIBRARY func lib var) + CHECK_FUNCTION_EXISTS ("${func}" "_CARES_FUNC_IN_LIB_GLOBAL_${func}") + IF ("${_CARES_FUNC_IN_LIB_GLOBAL_${func}}") + SET (${var} FALSE) + ELSE () + CHECK_LIBRARY_EXISTS ("${lib}" "${func}" "" ${var}) + ENDIF () +ENDMACRO () + +# Look for dependent/required libraries +CARES_FUNCTION_IN_LIBRARY (res_servicename resolv HAVE_RES_SERVICENAME_IN_LIBRESOLV) +IF (HAVE_RES_SERVICENAME_IN_LIBRESOLV) + SET (HAVE_LIBRESOLV 1) +ENDIF () + +IF (APPLE) + CHECK_C_SOURCE_COMPILES (" + #include + #include + int main() { +#if TARGET_OS_IPHONE == 0 +#error Not an iPhone target +#endif +return 0; + } + " + IOS) + + CHECK_C_SOURCE_COMPILES (" +#include +#include + int main() { +#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 +# error Not iOS v10 +#endif +return 0; + } + " + IOS_V10) + + CHECK_C_SOURCE_COMPILES (" +#include +#include +#ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 +#endif + int main() { +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +# error Not MacOSX 10.12 or higher +#endif +return 0; + } + " + MACOS_V1012) +ENDIF () + +IF ((IOS OR APPLE) AND HAVE_LIBRESOLV) + SET (CARES_USE_LIBRESOLV 1) +ENDIF() + + +CARES_FUNCTION_IN_LIBRARY (gethostbyname nsl HAVE_LIBNSL) +CARES_FUNCTION_IN_LIBRARY (gethostbyname socket HAVE_GHBN_LIBSOCKET) +CARES_FUNCTION_IN_LIBRARY (socket socket HAVE_SOCKET_LIBSOCKET) +IF (HAVE_GHBN_LIBSOCKET OR HAVE_SOCKET_LIBSOCKET) + SET(HAVE_LIBSOCKET TRUE) +ENDIF () +CARES_FUNCTION_IN_LIBRARY (clock_gettime rt HAVE_LIBRT) + + +# Look for necessary includes +CHECK_INCLUDE_FILES (sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILES (arpa/inet.h HAVE_ARPA_INET_H) +CHECK_INCLUDE_FILES (arpa/nameser_compat.h HAVE_ARPA_NAMESER_COMPAT_H) +CHECK_INCLUDE_FILES (arpa/nameser.h HAVE_ARPA_NAMESER_H) +CHECK_INCLUDE_FILES (assert.h HAVE_ASSERT_H) +CHECK_INCLUDE_FILES (errno.h HAVE_ERRNO_H) +CHECK_INCLUDE_FILES (fcntl.h HAVE_FCNTL_H) +CHECK_INCLUDE_FILES (inttypes.h HAVE_INTTYPES_H) +CHECK_INCLUDE_FILES (limits.h HAVE_LIMITS_H) +CHECK_INCLUDE_FILES (malloc.h HAVE_MALLOC_H) +CHECK_INCLUDE_FILES (memory.h HAVE_MEMORY_H) +CHECK_INCLUDE_FILES (netdb.h HAVE_NETDB_H) +CHECK_INCLUDE_FILES (netinet/in.h HAVE_NETINET_IN_H) +CHECK_INCLUDE_FILES (netinet/tcp.h HAVE_NETINET_TCP_H) +CHECK_INCLUDE_FILES (net/if.h HAVE_NET_IF_H) +CHECK_INCLUDE_FILES (signal.h HAVE_SIGNAL_H) +CHECK_INCLUDE_FILES (socket.h HAVE_SOCKET_H) +CHECK_INCLUDE_FILES (stdbool.h HAVE_STDBOOL_H) +CHECK_INCLUDE_FILES (stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILES (stdlib.h HAVE_STDLIB_H) +CHECK_INCLUDE_FILES (strings.h HAVE_STRINGS_H) +CHECK_INCLUDE_FILES (string.h HAVE_STRING_H) +CHECK_INCLUDE_FILES (stropts.h HAVE_STROPTS_H) +CHECK_INCLUDE_FILES (sys/ioctl.h HAVE_SYS_IOCTL_H) +CHECK_INCLUDE_FILES (sys/param.h HAVE_SYS_PARAM_H) +CHECK_INCLUDE_FILES (sys/select.h HAVE_SYS_SELECT_H) +CHECK_INCLUDE_FILES (sys/socket.h HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILES (sys/stat.h HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILES (sys/time.h HAVE_SYS_TIME_H) +CHECK_INCLUDE_FILES (sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES (sys/uio.h HAVE_SYS_UIO_H) +CHECK_INCLUDE_FILES (time.h HAVE_TIME_H) +CHECK_INCLUDE_FILES (dlfcn.h HAVE_DLFCN_H) +CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H) + +# Include order matters for these windows files. +CHECK_INCLUDE_FILES ("winsock2.h;windows.h" HAVE_WINSOCK2_H) +CHECK_INCLUDE_FILES ("winsock2.h;ws2tcpip.h;windows.h" HAVE_WS2TCPIP_H) +CHECK_INCLUDE_FILES ("winsock.h;windows.h" HAVE_WINSOCK_H) +CHECK_INCLUDE_FILES (windows.h HAVE_WINDOWS_H) + + +# Set system-specific compiler flags +IF (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + LIST (APPEND SYSFLAGS -D_DARWIN_C_SOURCE) +ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "Linux") + LIST (APPEND SYSFLAGS -D_GNU_SOURCE -D_POSIX_C_SOURCE=199309L -D_XOPEN_SOURCE=600) +ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + LIST (APPEND SYSFLAGS -D__EXTENSIONS__ -D_REENTRANT -D_XOPEN_SOURCE=600) +ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX") + LIST (APPEND SYSFLAGS -D_ALL_SOURCE -D_XOPEN_SOURCE=600 -D_USE_IRS) +ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + # Don't define _XOPEN_SOURCE on FreeBSD, it actually reduces visibility instead of increasing it +ELSEIF (WIN32) + LIST (APPEND SYSFLAGS -DWIN32_LEAN_AND_MEAN -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0600) +ENDIF () +ADD_DEFINITIONS(${SYSFLAGS}) + + + +# Tell C-Ares about libraries to depend on +IF (HAVE_LIBRESOLV) + LIST (APPEND CARES_DEPENDENT_LIBS resolv) +ENDIF () +IF (HAVE_LIBNSL) + LIST (APPEND CARES_DEPENDENT_LIBS nsl) +ENDIF () +IF (HAVE_LIBSOCKET) + LIST (APPEND CARES_DEPENDENT_LIBS socket) +ENDIF () +IF (HAVE_LIBRT) + LIST (APPEND CARES_DEPENDENT_LIBS rt) +ENDIF () +IF (WIN32) + LIST (APPEND CARES_DEPENDENT_LIBS ws2_32 Advapi32) +ENDIF () + + +# When checking for symbols, we need to make sure we set the proper +# headers, libraries, and definitions for the detection to work properly +# CMAKE_REQUIRED_DEFINITIONS, CMAKE_REQUIRED_LIBRARIES, and +# CMAKE_EXTRA_INCLUDE_FILES. When we're done with the detection, we'll +# unset them. + +SET (CMAKE_REQUIRED_DEFINITIONS ${SYSFLAGS}) +LIST (APPEND CMAKE_REQUIRED_LIBRARIES ${CARES_DEPENDENT_LIBS}) + +MACRO (CARES_EXTRAINCLUDE_IFSET var include) + IF (${var}) + LIST (APPEND CMAKE_EXTRA_INCLUDE_FILES ${include}) + ENDIF () +ENDMACRO () + +CARES_EXTRAINCLUDE_IFSET (HAVE_STDBOOL_H stdbool.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_TYPES_H sys/types.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_ARPA_INET_H arpa/inet.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_ARPA_NAMESER_H arpa/nameser.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_NETDB_H netdb.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_NET_IF_H net/if.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_NETINET_IN_H netinet/in.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_NETINET_TCP_H netinet/tcp.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SIGNAL_H signal.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_STDLIB_H stdlib.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_STRING_H string.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_STRINGS_H strings.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_IOCTL_H sys/ioctl.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SELECT_H sys/select.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_SOCKET_H sys/socket.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_TIME_H sys/time.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_SYS_UIO_H sys/uio.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_TIME_H time.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_FCNTL_H fcntl.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_UNISTD_H unistd.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_WINSOCK2_H winsock2.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_WS2TCPIP_H ws2tcpip.h) +CARES_EXTRAINCLUDE_IFSET (HAVE_WINDOWS_H windows.h) + +# Check Types +# CHECK_TYPE_SIZE can't be used to see if a type exists because on Apple when +# building multi-arch, it will throw an error. So we need to wrap +# CHECK_C_SOURCE_COMPILES for our tests. +MACRO (CARES_TYPE_EXISTS type var) + SET(_CARES_C_SOURCE " + #include + #include + ") + FOREACH(_C_HEADER ${CMAKE_EXTRA_INCLUDE_FILES}) + SET(_CARES_C_SOURCE "${_CARES_C_SOURCE} + #include <${_C_HEADER}>") + ENDFOREACH(_C_HEADER) + + SET(_CARES_C_SOURCE "${_CARES_C_SOURCE} + int main() { + ${type} var_exists; + (void)var_exists; + return 0; + } + ") + CHECK_C_SOURCE_COMPILES ("${_CARES_C_SOURCE}" ${var}) +ENDMACRO () + +CARES_TYPE_EXISTS (socklen_t HAVE_SOCKLEN_T) +CARES_TYPE_EXISTS (SOCKET HAVE_TYPE_SOCKET) +CARES_TYPE_EXISTS (bool HAVE_BOOL_T) +CARES_TYPE_EXISTS (ssize_t HAVE_SSIZE_T) +CARES_TYPE_EXISTS ("long long" HAVE_LONGLONG) +CARES_TYPE_EXISTS (sig_atomic_t HAVE_SIG_ATOMIC_T) +CARES_TYPE_EXISTS ("struct addrinfo" HAVE_STRUCT_ADDRINFO) +CARES_TYPE_EXISTS ("struct in6_addr" HAVE_STRUCT_IN6_ADDR) +CARES_TYPE_EXISTS ("struct sockaddr_in6" HAVE_STRUCT_SOCKADDR_IN6) +CARES_TYPE_EXISTS ("struct sockaddr_storage" HAVE_STRUCT_SOCKADDR_STORAGE) +CARES_TYPE_EXISTS ("struct timeval" HAVE_STRUCT_TIMEVAL) + + +# Check for preprocessor defines +CHECK_SYMBOL_EXISTS (AF_INET6 "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_AF_INET6) +CHECK_SYMBOL_EXISTS (O_NONBLOCK "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_O_NONBLOCK) +CHECK_SYMBOL_EXISTS (FIONBIO "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FIONBIO) +CHECK_SYMBOL_EXISTS (SIOCGIFADDR "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL_SIOCGIFADDR) +CHECK_SYMBOL_EXISTS (MSG_NOSIGNAL "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_MSG_NOSIGNAL) +CHECK_SYMBOL_EXISTS (PF_INET6 "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_PF_INET6) +CHECK_SYMBOL_EXISTS (SO_NONBLOCK "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SO_NONBLOCK) + +# XCode v8 bug: iOS when targeting less than v10, or MacOS when targeting less than v10.12 will +# say clock_gettime exists, it is a weak symbol that only exists in iOS10/MacOS10.12 and will +# cause a crash at runtime when running on older versions. Skip finding CLOCK_MONOTONIC on older +# OS's. +IF ((NOT APPLE) OR IOS_V10 OR MACOS_V1012) + CHECK_SYMBOL_EXISTS (CLOCK_MONOTONIC "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOCK_GETTIME_MONOTONIC) +ENDIF () + +CHECK_STRUCT_HAS_MEMBER("struct sockaddr_in6" sin6_scope_id "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID LANGUAGE C) + +# Check for "LL" numeric suffix support +CHECK_C_SOURCE_COMPILES ("int main() { int n=1234LL; return 0; }" HAVE_LL) + + +CHECK_SYMBOL_EXISTS (bitncmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_BITNCMP) +CHECK_SYMBOL_EXISTS (closesocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET) +CHECK_SYMBOL_EXISTS (CloseSocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CLOSESOCKET_CAMEL) +CHECK_SYMBOL_EXISTS (connect "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_CONNECT) +CHECK_SYMBOL_EXISTS (fcntl "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FCNTL) +CHECK_SYMBOL_EXISTS (freeaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_FREEADDRINFO) +CHECK_SYMBOL_EXISTS (getaddrinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETADDRINFO) +CHECK_SYMBOL_EXISTS (getenv "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETENV) +CHECK_SYMBOL_EXISTS (gethostbyaddr "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYADDR) +CHECK_SYMBOL_EXISTS (gethostbyname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTBYNAME) +CHECK_SYMBOL_EXISTS (gethostname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETHOSTNAME) +CHECK_SYMBOL_EXISTS (getnameinfo "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETNAMEINFO) +CHECK_SYMBOL_EXISTS (getservbyport_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYPORT_R) +CHECK_SYMBOL_EXISTS (getservbyname_r "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETSERVBYNAME_R) +CHECK_SYMBOL_EXISTS (gettimeofday "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_GETTIMEOFDAY) +CHECK_SYMBOL_EXISTS (if_indextoname "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IF_INDEXTONAME) +CHECK_SYMBOL_EXISTS (inet_net_pton "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NET_PTON) +IF (NOT WIN32) + # Disabled on Windows, because these functions are only really supported on Windows + # Vista or newer (_WIN32_WINNT >= 0x0600). Older versions of Windows may provide + # them as experimental non-working features, so we have to disable them manually. + CHECK_SYMBOL_EXISTS (inet_ntop "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_NTOP) + CHECK_SYMBOL_EXISTS (inet_pton "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_INET_PTON) +ENDIF () +CHECK_SYMBOL_EXISTS (ioctl "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTL) +CHECK_SYMBOL_EXISTS (ioctlsocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET) +CHECK_SYMBOL_EXISTS (IoctlSocket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_IOCTLSOCKET_CAMEL) +CHECK_SYMBOL_EXISTS (recv "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECV) +CHECK_SYMBOL_EXISTS (recvfrom "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_RECVFROM) +CHECK_SYMBOL_EXISTS (send "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SEND) +CHECK_SYMBOL_EXISTS (setsockopt "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SETSOCKOPT) +CHECK_SYMBOL_EXISTS (socket "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_SOCKET) +CHECK_SYMBOL_EXISTS (strcasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCASECMP) +CHECK_SYMBOL_EXISTS (strcmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRCMPI) +CHECK_SYMBOL_EXISTS (strdup "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRDUP) +CHECK_SYMBOL_EXISTS (stricmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRICMP) +CHECK_SYMBOL_EXISTS (strncasecmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCASECMP) +CHECK_SYMBOL_EXISTS (strncmpi "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNCMPI) +CHECK_SYMBOL_EXISTS (strnicmp "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_STRNICMP) +CHECK_SYMBOL_EXISTS (writev "${CMAKE_EXTRA_INCLUDE_FILES}" HAVE_WRITEV) + +# On Android, the system headers may define __system_property_get(), but excluded +# from libc. We need to perform a link test instead of a header/symbol test. +CHECK_FUNCTION_EXISTS (__system_property_get HAVE___SYSTEM_PROPERTY_GET) + +# Unset temporary data +SET (CMAKE_EXTRA_INCLUDE_FILES) +SET (CMAKE_REQUIRED_DEFINITIONS) +SET (CMAKE_REQUIRED_LIBRARIES) + + +################################################################################ +# recv, recvfrom, send, getnameinfo, gethostname +# ARGUMENTS AND RETURN VALUES +# +# The AutoTools build tries to be really thorough here. So much so that it +# takes forever. We really don't want to do that. Lets make some educated +# guesses based on datatypes we have available, and for others, use some 'sane' +# defaults. This should be much quicker and nearly as accurate ... and even +# if not, it probably won't matter in the least. + +IF (HAVE_SSIZE_T AND HAVE_SOCKLEN_T) + # If we have ssize_t and socklen_t, the API is usually sane and uses ssize_t and size_t for lengths + SET (RECVFROM_TYPE_RETV ssize_t) + SET (RECVFROM_TYPE_ARG3 size_t) +ELSE () + SET (RECVFROM_TYPE_RETV int) + SET (RECVFROM_TYPE_ARG3 int) +ENDIF () + +IF (HAVE_TYPE_SOCKET) + # If the SOCKET type is defined, it uses socket ... should be windows only + SET (RECVFROM_TYPE_ARG1 SOCKET) +ELSE () + SET (RECVFROM_TYPE_ARG1 int) +ENDIF() + +IF (HAVE_SOCKLEN_T) + # If we have socklen_t the APIs pretty much always actually use it + SET (RECVFROM_TYPE_ARG6 "socklen_t *") + SET (GETNAMEINFO_TYPE_ARG2 socklen_t) + SET (GETNAMEINFO_TYPE_ARG46 socklen_t) +ELSE () + SET (RECVFROM_TYPE_ARG6 "int *") + SET (GETNAMEINFO_TYPE_ARG2 int) + SET (GETNAMEINFO_TYPE_ARG46 int) +ENDIF () + +IF (WIN32) + SET (RECV_TYPE_ARG2 "char *") +ELSE () + SET (RECV_TYPE_ARG2 "void *") +ENDIF () + +# Functions are typically consistent so the equivalent fields map ... equivalently +SET (RECV_TYPE_RETV ${RECVFROM_TYPE_RETV}) +SET (SEND_TYPE_RETV ${RECVFROM_TYPE_RETV}) +SET (RECV_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}) +SET (RECVFROM_TYPE_ARG2 ${RECV_TYPE_ARG2}) +SET (SEND_TYPE_ARG1 ${RECVFROM_TYPE_ARG1}) +SET (RECV_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}) +SET (SEND_TYPE_ARG3 ${RECVFROM_TYPE_ARG3}) +SET (GETHOSTNAME_TYPE_ARG2 ${RECVFROM_TYPE_ARG3}) + +# These should always be "sane" values to use always +SET (RECVFROM_QUAL_ARG5 ) +SET (RECVFROM_TYPE_ARG4 int) +SET (RECVFROM_TYPE_ARG5 "struct sockaddr *") +SET (RECV_TYPE_ARG4 int) +SET (GETNAMEINFO_TYPE_ARG1 "struct sockaddr *") +SET (GETNAMEINFO_TYPE_ARG7 int) +SET (SEND_TYPE_ARG2 "void *") +SET (SEND_TYPE_ARG4 int) +################################################################################ + + +# HAVE_CXX11 ?? +# HAVE_SIG_ATOMIC_T_VOLATILE ?? + + +# Set a few variables by hand that C-Ares wants, logically, based on detection +# data. + +IF (HAVE_SOCKLEN_T) + Set (CARES_TYPEOF_ARES_SOCKLEN_T "socklen_t") +ELSE () + Set (CARES_TYPEOF_ARES_SOCKLEN_T "int") +ENDIF () + +IF (HAVE_SSIZE_T) + Set (CARES_TYPEOF_ARES_SSIZE_T "ssize_t") +ELSE () + IF (WIN32) + IF ("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") + Set (CARES_TYPEOF_ARES_SSIZE_T "__int64") + ELSE () + Set (CARES_TYPEOF_ARES_SSIZE_T "int") + ENDIF () + ELSE () + Set (CARES_TYPEOF_ARES_SSIZE_T "long") + ENDIF () +ENDIF () + +IF (HAVE_FCNTL AND HAVE_O_NONBLOCK) + SET (HAVE_FCNTL_O_NONBLOCK 1) +ENDIF () + +IF (HAVE_IOCTL AND HAVE_FIONBIO) + SET (HAVE_IOCTL_FIONBIO 1) +ENDIF () + +IF (HAVE_IOCTLSOCKET AND HAVE_FIONBIO) + SET (HAVE_IOCTLSOCKET_FIONBIO 1) +ENDIF () + +IF (HAVE_IOCTLSOCKET_CAMEL AND HAVE_FIONBIO) + SET (HAVE_IOCTLSOCKET_CAMEL_FIONBIO 1) +ENDIF () + +IF (HAVE_GETADDRINFO) + IF (CMAKE_SYSTEM_NAME STREQUAL "Darwin" OR + CMAKE_SYSTEM_NAME STREQUAL "HPUX" OR + CMAKE_SYSTEM_NAME STREQUAL "NetBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "SunOS" OR + CMAKE_SYSTEM_NAME STREQUAL "FreeBSD" OR + CMAKE_SYSTEM_NAME STREQUAL "AIX" OR + WIN32) + SET (HAVE_GETADDRINFO_THREADSAFE 1) + ENDIF () +ENDIF () + +IF (HAVE_TIME_H AND HAVE_SYS_TIME_H) + SET (TIME_WITH_SYS_TIME 1) +ENDIF () + +IF (HAVE_GETSERVBYPORT_R) + # TODO : Should probably autodetect + IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + SET (GETSERVBYPORT_R_ARGS 5) + ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX" OR + CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + SET (GETSERVBYPORT_R_ARGS 4) + ELSE () + # Probably linux + SET (GETSERVBYPORT_R_ARGS 6) + ENDIF () +ENDIF () + +IF (HAVE_GETSERVBYNAME_R) + # TODO : Should probably autodetect + IF (CMAKE_SYSTEM_NAME STREQUAL "SunOS") + SET (GETSERVBYNAME_R_ARGS 5) + ELSEIF (CMAKE_SYSTEM_NAME STREQUAL "AIX" OR + CMAKE_SYSTEM_NAME STREQUAL "OpenBSD") + SET (GETSERVBYNAME_R_ARGS 4) + ELSE () + # Probably linux + SET (GETSERVBYNAME_R_ARGS 6) + ENDIF () +ENDIF () + +# Set some aliases used for ares_build.h +IF (HAVE_SYS_TYPES_H) + SET (CARES_HAVE_SYS_TYPES_H 1) +ENDIF () +IF (HAVE_SYS_SOCKET_H) + SET (CARES_HAVE_SYS_SOCKET_H 1) +ENDIF() +IF (HAVE_WS2TCPIP_H) + SET (CARES_HAVE_WS2TCPIP_H 1) +ENDIF() +IF (HAVE_WINSOCK2_H) + SET (CARES_HAVE_WINSOCK2_H 1) +ENDIF() +IF (HAVE_WINDOWS_H) + SET (CARES_HAVE_WINDOWS_H 1) +ENDIF() + +# Record toplevel CMakeLists.txt path +set(CARES_TOPLEVEL_DIR "${CMAKE_CURRENT_SOURCE_DIR}") + + +# TRANSFORM_MAKEFILE_INC +# +# This function consumes the "Makefile.inc" autotools file, and converts it into +# "Makefile.inc.cmake", a cmake include file; transforming this: +# +# CSOURCES = ares__close_sockets.c \ +# ares__get_hostent.c \ +# ares__read_line.c \ +# ... +# +# into this: +# +# SET (CSOURCES +# ares__close_sockets.c +# ares__get_hostent.c +# ares__read_line.c +# ... +function(TRANSFORM_MAKEFILE_INC INPUT_FILE OUTPUT_FILE) + file(READ ${INPUT_FILE} MAKEFILE_INC_TEXT) + string(REPLACE "$(top_srcdir)" "\${PROJECT_SOURCE_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "$(top_builddir)" "\${PROJECT_BINARY_DIR}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\\\\n" "ß!ß" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REGEX REPLACE "([a-zA-Z_][a-zA-Z0-9_]*)[\t ]*=[\t ]*([^\n]*)" "SET(\\1 \\2)" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + string(REPLACE "ß!ß" "\n" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) + + string(REGEX REPLACE "\\$\\(([a-zA-Z_][a-zA-Z0-9_]*)\\)" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace $() with ${} + string(REGEX REPLACE "@([a-zA-Z_][a-zA-Z0-9_]*)@" "\${\\1}" MAKEFILE_INC_TEXT ${MAKEFILE_INC_TEXT}) # Replace @@ with ${}, even if that may not be read by CMake scripts. + file(WRITE ${OUTPUT_FILE} ${MAKEFILE_INC_TEXT}) +endfunction() + +# Directory for includes +ADD_SUBDIRECTORY (include) + +# Directory for lib and tools +ADD_SUBDIRECTORY (src) + +# Docs +ADD_SUBDIRECTORY (docs) + +# Tests +IF (CARES_BUILD_TESTS OR CARES_BUILD_CONTAINER_TESTS) + ENABLE_TESTING () + ADD_SUBDIRECTORY (test) +ENDIF () + + +# Export targets +IF (CARES_INSTALL) + SET (CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") + INCLUDE (CMakePackageConfigHelpers) + CONFIGURE_PACKAGE_CONFIG_FILE (${PROJECT_NAME}-config.cmake.in ${PROJECT_NAME}-config.cmake + INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} + PATH_VARS CMAKE_INSTALL_INCLUDEDIR + NO_CHECK_REQUIRED_COMPONENTS_MACRO + ) + + WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_NAME}-config-version.cmake VERSION "${CARES_VERSION}" COMPATIBILITY SameMajorVersion) + INSTALL (EXPORT ${PROJECT_NAME}-targets COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR} NAMESPACE ${PROJECT_NAME}::) + INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake" COMPONENT Devel DESTINATION ${CMAKECONFIG_INSTALL_DIR}) + + # pkgconfig support + IF (NOT CARES_SHARED) + SET (CPPFLAG_CARES_STATICLIB "-DCARES_STATICLIB") + FOREACH (LIB ${CARES_DEPENDENT_LIBS}) + SET (CARES_PRIVATE_LIBS "${CARES_PRIVATE_LIBS} -l${LIB}") + ENDFOREACH () + ENDIF () + CONFIGURE_FILE("libcares.pc.cmake" "libcares.pc" @ONLY) + INSTALL (FILES "${CMAKE_CURRENT_BINARY_DIR}/libcares.pc" COMPONENT Devel DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") +ENDIF () + + +# Legacy chain-building variables (provided for compatibility with old code). +# Don't use these, external code should be updated to refer to the aliases directly (e.g., Cares::cares). +SET (CARES_FOUND 1 CACHE INTERNAL "CARES LIBRARY FOUND") +SET (CARES_LIBRARIES ${PROJECT_NAME}::cares CACHE INTERNAL "CARES LIBRARIES") + + +IF (CARES_INSTALL) + # Package creation + set( CPACK_PACKAGE_NAME ${PROJECT_NAME} ) + set( CPACK_PACKAGE_VENDOR "Daniel Stenberg" ) # Github project owner + set( CPACK_PACKAGE_DESCRIPTION_SUMMARY "A C library for asynchronous DNS requests" ) + set( CPACK_PACKAGE_HOMEPAGE_URL "https://c-ares.haxx.se/" ) + set( CPACK_PACKAGE_CONTACT "https://c-ares.haxx.se/" ) + set( CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} ) + set( CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR} ) + set( CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH} ) + set( CPACK_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH} ) + set( CPACK_PACKAGE_INSTALL_DIRECTORY ${PROJECT_NAME} ) + set( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.md" ) + set( CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md" ) + + set( CPACK_COMPONENT_Library_DISPLAY_NAME "c-ares Library" ) + set( CPACK_COMPONENT_Library_DESCRIPTION "The c-ares binary library." ) + set( CPACK_COMPONENT_Library_REQUIRED 1 ) + set( CPACK_COMPONENT_Devel_DISPLAY_NAME "c-ares Development Files" ) + set( CPACK_COMPONENT_Devel_DESCRIPTION "Development files for compiling against c-ares." ) + set( CPACK_COMPONENT_Devel_REQUIRED 0 ) + IF (CARES_BUILD_TOOLS) + set( CPACK_COMPONENT_Tools_DISPLAY_NAME "c-ares Tools" ) + set( CPACK_COMPONENT_Tools_DESCRIPTION "Tools for using c-ares." ) + set( CPACK_COMPONENT_Tools_REQUIRED 0 ) + ENDIF () + + if( ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" ) + + if ( "${CPACK_PACKAGE_ARCHITECTURE}" STREQUAL "" ) + # Note: the architecture should default to the local architecture, but it + # in fact comes up empty. We call `uname -m` to ask the kernel instead. + EXECUTE_PROCESS( COMMAND uname -m COMMAND tr -d '\n' OUTPUT_VARIABLE CPACK_PACKAGE_ARCHITECTURE ) + endif() + + set( CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1 ) + set( CPACK_PACKAGE_RELEASE 1 ) + + + # RPM - https://cmake.org/cmake/help/latest/cpack_gen/rpm.html + set( CPACK_RPM_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} ) + set( CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} ) + set( CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY} ) + set( CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_HOMEPAGE_URL} ) + set( CPACK_RPM_PACKAGE_LICENSE "MIT" ) + set( CPACK_RPM_COMPONENT_INSTALL 1 ) + set( CPACK_RPM_COMPRESSION_TYPE "xz" ) + set( CPACK_RPM_PACKAGE_AUTOPROV 1 ) + + set( CPACK_RPM_Library_PACKAGE_SUMMARY ${CPACK_COMPONENT_Library_DESCRIPTION} ) + set( CPACK_RPM_Library_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} ) + set( CPACK_RPM_Library_PACKAGE_NAME "libcares${CARES_LIB_VERSION_MAJOR}" ) + set( CPACK_RPM_Library_FILE_NAME "RPM-DEFAULT" ) + + set( CPACK_RPM_Devel_PACKAGE_REQUIRES "cmake >= ${CMAKE_MINIMUM_REQUIRED_VERSION}, ${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" ) + set( CPACK_RPM_Devel_PACKAGE_SUMMARY ${CPACK_COMPONENT_Devel_DESCRIPTION} ) + set( CPACK_RPM_Devel_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} ) + set( CPACK_RPM_Devel_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-devel" ) + set( CPACK_RPM_Devel_FILE_NAME "RPM-DEFAULT" ) + + IF (CARES_BUILD_TOOLS) + set( CPACK_RPM_Tools_PACKAGE_REQUIRES "${CPACK_RPM_Library_PACKAGE_NAME} >= ${CPACK_PACKAGE_VERSION}" ) + set( CPACK_RPM_Tools_PACKAGE_SUMMARY ${CPACK_COMPONENT_Tools_DESCRIPTION} ) + set( CPACK_RPM_Tools_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE} ) + set( CPACK_RPM_Tools_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" ) + set( CPACK_RPM_Tools_FILE_NAME "RPM-DEFAULT" ) + ENDIF () + + + # DEB - https://cmake.org/cmake/help/latest/cpack_gen/deb.html + set( CPACK_DEBIAN_PACKAGE_RELEASE ${CPACK_PACKAGE_RELEASE} ) + set( CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL} ) + set( CPACK_DEB_COMPONENT_INSTALL 1 ) + set( CPACK_DEBIAN_COMPRESSION_TYPE "xz") + set( CPACK_DEBIAN_PACKAGE_SHLIBDEPS 1 ) + + if ( ${CPACK_PACKAGE_ARCHITECTURE} STREQUAL "x86_64" ) + set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64" ) # DEB doesn't always use the kernel's arch name + else() + set( CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${CPACK_PACKAGE_ARCHITECTURE} ) + endif() + + set( CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT" ) # Use default naming scheme + + set( CPACK_DEBIAN_LIBRARY_PACKAGE_NAME ${CPACK_RPM_Library_PACKAGE_NAME} ) + + set( CPACK_DEBIAN_DEVEL_PACKAGE_DEPENDS "cmake (>= ${CMAKE_MINIMUM_REQUIRED_VERSION}), ${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" ) + set( CPACK_DEBIAN_DEVEL_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-dev" ) + + IF (CARES_BUILD_TOOLS) + set( CPACK_DEBIAN_TOOLS_PACKAGE_NAME "${CPACK_PACKAGE_NAME}-tools" ) + set( CPACK_DEBIAN_TOOLS_PACKAGE_SHLIBDEPS OFF ) # dpkg-shlibdeps can't find the libs we built + set( CPACK_DEBIAN_TOOLS_PACKAGE_DEPENDS "${CPACK_DEBIAN_LIBRARY_PACKAGE_NAME} (>= ${CPACK_PACKAGE_VERSION})" ) + ENDIF () + + elseif( ${CMAKE_HOST_WIN32} ) + set( CPACK_NSIS_ENABLE_UNINSTALL_BEFORE_INSTALL ON ) + set( CPACK_NSIS_DISPLAY_NAME ${PROJECT_NAME} ) + set( CPACK_NSIS_PACKAGE_NAME ${PROJECT_NAME} ) + set( CPACK_NSIS_URL_INFO_ABOUT ${CPACK_PACKAGE_HOMEPAGE_URL} ) + endif() + + # This must always be last! + include( CPack ) +ENDIF () diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..539c45d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,15 @@ +Contributing to c-ares +====================== + +To contribute patches to c-ares, please generate a GitHub pull request +and follow these guidelines: + + - Check that the Travis builds are green for your pull request. + - Please update the test suite to add a test case for any new functionality. + - Build the library with `./configure --enable-debug --enable-maintainer-mode` and + ensure there are no new warnings. + +To improve the chances of the c-ares maintainers responding to your request: + + - Also send an email to the mailing list at `c-ares@cool.haxx.se` describing your change. + - To follow any associated discussion, please subscribe to the [mailing list](http://cool.haxx.se/mailman/listinfo/c-ares). diff --git a/INSTALL b/INSTALL deleted file mode 100644 index c78487d..0000000 --- a/INSTALL +++ /dev/null @@ -1,328 +0,0 @@ -** This file is adapted from libcurl and not yet fully rewritten for c-ares! ** - - ___ __ _ _ __ ___ ___ - / __| ___ / _` | '__/ _ \/ __| - | (_ |___| (_| | | | __/\__ \ - \___| \__,_|_| \___||___/ - - How To Compile - -Installing Binary Packages -========================== - - Lots of people download binary distributions of c-ares. This document - does not describe how to install c-ares using such a binary package. - This document describes how to compile, build and install c-ares from - source code. - -Building from git -================= - - If you get your code off a git repository, see the GIT-INFO file in the - root directory for specific instructions on how to proceed. - -UNIX -==== - A normal unix installation is made in three or four steps (after you've - unpacked the source archive): - - ./configure - make - make ahost adig acountry (optional) - make install - - You probably need to be root when doing the last command. - - If you have checked out the sources from the git repository, read the - GIT-INFO on how to proceed. - - Get a full listing of all available configure options by invoking it like: - - ./configure --help - - If you want to install c-ares in a different file hierarchy than /usr/local, - you need to specify that already when running configure: - - ./configure --prefix=/path/to/c-ares/tree - - If you happen to have write permission in that directory, you can do 'make - install' without being root. An example of this would be to make a local - install in your own home directory: - - ./configure --prefix=$HOME - make - make install - - MORE OPTIONS - ------------ - - To force configure to use the standard cc compiler if both cc and gcc are - present, run configure like - - CC=cc ./configure - or - env CC=cc ./configure - - To force a static library compile, disable the shared library creation - by running configure like: - - ./configure --disable-shared - - If you're a c-ares developer and use gcc, you might want to enable more - debug options with the --enable-debug option. - - SPECIAL CASES - ------------- - Some versions of uClibc require configuring with CPPFLAGS=-D_GNU_SOURCE=1 - to get correct large file support. - - The Open Watcom C compiler on Linux requires configuring with the variables: - - ./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \ - RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra - - -Win32 -===== - - Building Windows DLLs and C run-time (CRT) linkage issues - --------------------------------------------------------- - - As a general rule, building a DLL with static CRT linkage is highly - discouraged, and intermixing CRTs in the same app is something to - avoid at any cost. - - Reading and comprehension of Microsoft Knowledge Base articles - KB94248 and KB140584 is a must for any Windows developer. Especially - important is full understanding if you are not going to follow the - advice given above. - - KB94248 - How To Use the C Run-Time - http://support.microsoft.com/kb/94248/en-us - - KB140584 - How to link with the correct C Run-Time (CRT) library - http://support.microsoft.com/kb/140584/en-us - - KB190799 - Potential Errors Passing CRT Objects Across DLL Boundaries - http://msdn.microsoft.com/en-us/library/ms235460 - - If your app is misbehaving in some strange way, or it is suffering - from memory corruption, before asking for further help, please try - first to rebuild every single library your app uses as well as your - app using the debug multithreaded dynamic C runtime. - - MingW32 - ------- - - Make sure that MinGW32's bin dir is in the search path, for example: - - set PATH=c:\mingw32\bin;%PATH% - - then run 'make -f Makefile.m32' in the root dir. - - Cygwin - ------ - - Almost identical to the unix installation. Run the configure script in the - c-ares root with 'sh configure'. Make sure you have the sh executable in - /bin/ or you'll see the configure fail toward the end. - - Run 'make' - - Dev-Cpp - ------- - - See the separate INSTALL.devcpp file for details. - - MSVC 6 caveats - -------------- - - If you use MSVC 6 it is required that you use the February 2003 edition PSDK: - http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm - - MSVC from command line - ---------------------- - - Run the 'vcvars32.bat' file to get a proper environment. The - vcvars32.bat file is part of the Microsoft development environment and - you may find it in 'C:\Program Files\Microsoft Visual Studio\vc98\bin' - provided that you installed Visual C/C++ 6 in the default directory. - - Further details in README.msvc - - MSVC IDES - --------- - - Details in README.msvc - - Important static c-ares usage note - ---------------------------------- - - When building an application that uses the static c-ares library, you must - add '-DCARES_STATICLIB' to your CFLAGS. Otherwise the linker will look for - dynamic import symbols. - - -IBM OS/2 -======== - Building under OS/2 is not much different from building under unix. - You need: - - - emx 0.9d - - GNU make - - GNU patch - - ksh - - GNU bison - - GNU file utilities - - GNU sed - - autoconf 2.13 - - If during the linking you get an error about _errno being an undefined - symbol referenced from the text segment, you need to add -D__ST_MT_ERRNO__ - in your definitions. - - If you're getting huge binaries, probably your makefiles have the -g in - CFLAGS. - - -QNX -=== - (This section was graciously brought to us by David Bentham) - - As QNX is targeted for resource constrained environments, the QNX headers - set conservative limits. This includes the FD_SETSIZE macro, set by default - to 32. Socket descriptors returned within the c-ares library may exceed this, - resulting in memory faults/SIGSEGV crashes when passed into select(..) - calls using fd_set macros. - - A good all-round solution to this is to override the default when building - c-ares, by overriding CFLAGS during configure, example - # configure CFLAGS='-DFD_SETSIZE=64 -g -O2' - - -RISC OS -======= - The library can be cross-compiled using gccsdk as follows: - - CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \ - --host=arm-riscos-aof --without-random --disable-shared - make - - where riscos-gcc and riscos-ar are links to the gccsdk tools. - You can then link your program with c-ares/lib/.libs/libcares.a - - -NetWare -======= - To compile libcares.a / libcares.lib you need: - - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later. - - gnu make and awk running on the platform you compile on; - native Win32 versions can be downloaded from: - http://www.gknw.net/development/prgtools/ - - recent Novell LibC SDK available from: - http://developer.novell.com/ndk/libc.htm - - or recent Novell CLib SDK available from: - http://developer.novell.com/ndk/clib.htm - - Set a search path to your compiler, linker and tools; on Linux make - sure that the var OSTYPE contains the string 'linux'; set the var - NDKBASE to point to the base of your Novell NDK; and then type - 'make -f Makefile.netware' from the top source directory; - - -Android -======= - Method using a configure cross-compile (tested with Android NDK r7b): - - prepare the toolchain of the Android NDK for standalone use; this can - be done by invoking the script: - ./tools/make-standalone-toolchain.sh - which creates a usual cross-compile toolchain. Lets assume that you put - this toolchain below /opt then invoke configure with something like: - export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH - ./configure --host=arm-linux-androideabi [more configure options] - make - - if you want to compile directly from our GIT repo you might run into - this issue with older automake stuff: - checking host system type... - Invalid configuration `arm-linux-androideabi': - system `androideabi' not recognized - configure: error: /bin/sh ./config.sub arm-linux-androideabi failed - this issue can be fixed with using more recent versions of config.sub - and config.guess which can be obtained here: - http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree - you need to replace your system-own versions which usually can be - found in your automake folder: - find /usr -name config.sub - - -CROSS COMPILE -============= - (This section was graciously brought to us by Jim Duey, with additions by - Dan Fandrich) - - Download and unpack the c-ares package. - - 'cd' to the new directory. (e.g. cd c-ares-1.7.6) - - Set environment variables to point to the cross-compile toolchain and call - configure with any options you need. Be sure and specify the '--host' and - '--build' parameters at configuration time. The following script is an - example of cross-compiling for the IBM 405GP PowerPC processor using the - toolchain from MonteVista for Hardhat Linux. - - (begin script) - - #! /bin/sh - - export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin - export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include" - export AR=ppc_405-ar - export AS=ppc_405-as - export LD=ppc_405-ld - export RANLIB=ppc_405-ranlib - export CC=ppc_405-gcc - export NM=ppc_405-nm - - ./configure --target=powerpc-hardhat-linux \ - --host=powerpc-hardhat-linux \ - --build=i586-pc-linux-gnu \ - --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \ - --exec-prefix=/usr/local - - (end script) - - You may also need to provide a parameter like '--with-random=/dev/urandom' - to configure as it cannot detect the presence of a random number - generating device for a target system. The '--prefix' parameter - specifies where c-ares will be installed. If 'configure' completes - successfully, do 'make' and 'make install' as usual. - - In some cases, you may be able to simplify the above commands to as - little as: - - ./configure --host=ARCH-OS - - -PORTS -===== - This is a probably incomplete list of known hardware and operating systems - that c-ares has been compiled for. If you know a system c-ares compiles and - runs on, that isn't listed, please let us know! - - - Alpha Tru64 v5.0 5.1 - - ARM Android 1.5, 2.1, 2.3 - - MIPS IRIX 6.2, 6.5 - - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2 - - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 - - i386 Novell NetWare - - i386 Windows 95, 98, ME, NT, 2000, XP, 2003 - - x86_64 Linux - -Useful URLs -=========== - -c-ares https://c-ares.haxx.se/ - -MingW http://www.mingw.org/ -MinGW-w64 http://mingw-w64.sourceforge.net/ -OpenWatcom http://www.openwatcom.org/ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 0000000..2fd3911 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,410 @@ +** This file is adapted from libcurl and not yet fully rewritten for c-ares! ** + +``` + ___ __ _ _ __ ___ ___ + / __| ___ / _` | '__/ _ \/ __| + | (_ |___| (_| | | | __/\__ \ + \___| \__,_|_| \___||___/ + + How To Compile +``` + +Installing Binary Packages +========================== + +Lots of people download binary distributions of c-ares. This document +does not describe how to install c-ares using such a binary package. +This document describes how to compile, build and install c-ares from +source code. + +Building from Git +================= + +If you get your code off a Git repository rather than an official +release tarball, see the [GIT-INFO](GIT-INFO) file in the root directory +for specific instructions on how to proceed. + +In particular, if not using CMake you will need to run `./buildconf` (Unix) or +`buildconf.bat` (Windows) to generate build files, and for the former +you will need a local installation of Autotools. If using CMake the steps are +the same for both Git and official release tarballs. + +AutoTools Build +=============== + +### General Information, works on most Unix Platforms (Linux, FreeBSD, etc) + +A normal Unix installation is made in three or four steps (after you've +unpacked the source archive): + + ./configure + make + make ahost adig acountry (optional) + make install + +You probably need to be root when doing the last command. + +If you have checked out the sources from the git repository, read the +[GIT-INFO](GIT_INFO) on how to proceed. + +Get a full listing of all available configure options by invoking it like: + + ./configure --help + +If you want to install c-ares in a different file hierarchy than /usr/local, +you need to specify that already when running configure: + + ./configure --prefix=/path/to/c-ares/tree + +If you happen to have write permission in that directory, you can do `make +install` without being root. An example of this would be to make a local +install in your own home directory: + + ./configure --prefix=$HOME + make + make install + +### More Options + +To force configure to use the standard cc compiler if both cc and gcc are +present, run configure like + + CC=cc ./configure + # or + env CC=cc ./configure + +To force a static library compile, disable the shared library creation +by running configure like: + + ./configure --disable-shared + +If you're a c-ares developer and use gcc, you might want to enable more +debug options with the `--enable-debug` option. + +### Special Cases + +Some versions of uClibc require configuring with `CPPFLAGS=-D_GNU_SOURCE=1` +to get correct large file support. + +The Open Watcom C compiler on Linux requires configuring with the variables: + + ./configure CC=owcc AR="$WATCOM/binl/wlib" AR_FLAGS=-q \ + RANLIB=/bin/true STRIP="$WATCOM/binl/wstrip" CFLAGS=-Wextra + + +### CROSS COMPILE + +(This section was graciously brought to us by Jim Duey, with additions by +Dan Fandrich) + +Download and unpack the c-ares package. + +`cd` to the new directory. (e.g. `cd c-ares-1.7.6`) + +Set environment variables to point to the cross-compile toolchain and call +configure with any options you need. Be sure and specify the `--host` and +`--build` parameters at configuration time. The following script is an +example of cross-compiling for the IBM 405GP PowerPC processor using the +toolchain from MonteVista for Hardhat Linux. + +```sh +#! /bin/sh + +export PATH=$PATH:/opt/hardhat/devkit/ppc/405/bin +export CPPFLAGS="-I/opt/hardhat/devkit/ppc/405/target/usr/include" +export AR=ppc_405-ar +export AS=ppc_405-as +export LD=ppc_405-ld +export RANLIB=ppc_405-ranlib +export CC=ppc_405-gcc +export NM=ppc_405-nm + +./configure --target=powerpc-hardhat-linux \ + --host=powerpc-hardhat-linux \ + --build=i586-pc-linux-gnu \ + --prefix=/opt/hardhat/devkit/ppc/405/target/usr/local \ + --exec-prefix=/usr/local +``` + +You may also need to provide a parameter like `--with-random=/dev/urandom` +to configure as it cannot detect the presence of a random number +generating device for a target system. The `--prefix` parameter +specifies where c-ares will be installed. If `configure` completes +successfully, do `make` and `make install` as usual. + +In some cases, you may be able to simplify the above commands to as +little as: + + ./configure --host=ARCH-OS + + +### Cygwin (Windows) + +Almost identical to the unix installation. Run the configure script in the +c-ares root with `sh configure`. Make sure you have the sh executable in +`/bin/` or you'll see the configure fail toward the end. + +Run `make` + + +### QNX + +(This section was graciously brought to us by David Bentham) + +As QNX is targeted for resource constrained environments, the QNX headers +set conservative limits. This includes the `FD_SETSIZE` macro, set by default +to 32. Socket descriptors returned within the c-ares library may exceed this, +resulting in memory faults/SIGSEGV crashes when passed into `select(..)` +calls using `fd_set` macros. + +A good all-round solution to this is to override the default when building +c-ares, by overriding `CFLAGS` during configure, example: + + # configure CFLAGS='-DFD_SETSIZE=64 -g -O2' + + +### RISC OS + +The library can be cross-compiled using gccsdk as follows: + + CC=riscos-gcc AR=riscos-ar RANLIB='riscos-ar -s' ./configure \ + --host=arm-riscos-aof --without-random --disable-shared + make + +where `riscos-gcc` and `riscos-ar` are links to the gccsdk tools. +You can then link your program with `c-ares/lib/.libs/libcares.a`. + + +### Android + +Method using a configure cross-compile (tested with Android NDK r7b): + + - prepare the toolchain of the Android NDK for standalone use; this can + be done by invoking the script: + + ./tools/make-standalone-toolchain.sh + + which creates a usual cross-compile toolchain. Lets assume that you put + this toolchain below `/opt` then invoke configure with something + like: + + ``` + export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH + ./configure --host=arm-linux-androideabi [more configure options] + make + ``` + - if you want to compile directly from our GIT repo you might run into + this issue with older automake stuff: + + ``` + checking host system type... + Invalid configuration `arm-linux-androideabi': + system `androideabi' not recognized + configure: error: /bin/sh ./config.sub arm-linux-androideabi failed + ``` + this issue can be fixed with using more recent versions of `config.sub` + and `config.guess` which can be obtained here: + http://git.savannah.gnu.org/gitweb/?p=config.git;a=tree + you need to replace your system-own versions which usually can be + found in your automake folder: + `find /usr -name config.sub` + + +CMake builds +============ + +Current releases of c-ares introduce a CMake v3+ build system that has been +tested on most platforms including Windows, Linux, FreeBSD, MacOS, AIX and +Solaris. + +In the most basic form, building with CMake might look like: + +```sh +cd /path/to/cmake/source +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/cares .. +make +sudo make install +``` + +Options +------- + +Options to CMake are passed on the command line using "-D${OPTION}=${VALUE}". +The values defined are all boolean and take values like On, Off, True, False. + +* CARES_STATIC - Build the static library (off by default) +* CARES_SHARED - Build the shared library (on by default) +* CARES_INSTALL - Hook in installation, useful to disable if chain building +* CARES_STATIC_PIC - Build the static library as position-independent (off by + default) + + +Ninja +----- + +Ninja is the next-generation build system meant for generators like CMake that +heavily parallize builds. Its use is very similar to the normal build: + +```sh +cd /path/to/cmake/source +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local/cares -G "Ninja" .. +ninja +sudo ninja install +``` + +Windows MSVC Command Line +------------------------- + +``` +cd \path\to\cmake\source +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:\cares -G "NMake Makefiles" .. +nmake +nmake install +``` + +Windows MinGW-w64 Command Line via MSYS +--------------------------------------- +``` +cd \path\to\cmake\source +mkdir build +cd build +cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=C:\cares -G "MSYS Makefiles" .. +make +make install +``` + + +Platform-specific build systems +=============================== + +Win32 +----- + +### Building Windows DLLs and C run-time (CRT) linkage issues + +As a general rule, building a DLL with static CRT linkage is highly +discouraged, and intermixing CRTs in the same app is something to +avoid at any cost. + +Reading and comprehension of Microsoft Knowledge Base articles +KB94248 and KB140584 is a must for any Windows developer. Especially +important is full understanding if you are not going to follow the +advice given above. + + - [KB94248](http://support.microsoft.com/kb/94248/en-us) - How To Use the C Run-Time + + - [KB140584](http://support.microsoft.com/kb/140584/en-us) - How to link with the correct C Run-Time (CRT) library + + - [KB190799](http://msdn.microsoft.com/en-us/library/ms235460) - Potential Errors Passing CRT Objects Across DLL Boundaries + +If your app is misbehaving in some strange way, or it is suffering +from memory corruption, before asking for further help, please try +first to rebuild every single library your app uses as well as your +app using the debug multithreaded dynamic C runtime. + + +### MingW32 + +Make sure that MinGW32's bin dir is in the search path, for example: + + set PATH=c:\mingw32\bin;%PATH% + +then run 'make -f Makefile.m32' in the root dir. + + +### MSVC 6 caveats + +If you use MSVC 6 it is required that you use the February 2003 edition PSDK: +http://www.microsoft.com/msdownload/platformsdk/sdkupdate/psdk-full.htm + + +### MSVC from command line + +Run the `vcvars32.bat` file to get a proper environment. The +`vcvars32.bat` file is part of the Microsoft development environment and +you may find it in `C:\Program Files\Microsoft Visual Studio\vc98\bin` +provided that you installed Visual C/C++ 6 in the default directory. + +Further details in [README.msvc](README.msvc) + + +### Important static c-ares usage note + +When building an application that uses the static c-ares library, you must +add `-DCARES_STATICLIB` to your `CFLAGS`. Otherwise the linker will look for +dynamic import symbols. + + +IBM OS/2 +-------- + +Building under OS/2 is not much different from building under unix. +You need: + + - emx 0.9d + - GNU make + - GNU patch + - ksh + - GNU bison + - GNU file utilities + - GNU sed + - autoconf 2.13 + +If during the linking you get an error about `_errno` being an undefined +symbol referenced from the text segment, you need to add `-D__ST_MT_ERRNO__` +in your definitions. + +If you're getting huge binaries, probably your makefiles have the `-g` in +`CFLAGS`. + + +NetWare +------- + +To compile `libcares.a` / `libcares.lib` you need: + + - either any gcc / nlmconv, or CodeWarrior 7 PDK 4 or later. + - gnu make and awk running on the platform you compile on; + native Win32 versions can be downloaded from: + http://www.gknw.net/development/prgtools/ + - recent Novell LibC SDK available from: + http://developer.novell.com/ndk/libc.htm + - or recent Novell CLib SDK available from: + http://developer.novell.com/ndk/clib.htm + +Set a search path to your compiler, linker and tools; on Linux make +sure that the var `OSTYPE` contains the string 'linux'; set the var +`NDKBASE` to point to the base of your Novell NDK; and then type +`make -f Makefile.netware` from the top source directory; + + +PORTS +===== + +This is a probably incomplete list of known hardware and operating systems +that c-ares has been compiled for. If you know a system c-ares compiles and +runs on, that isn't listed, please let us know! + + - Alpha Tru64 v5.0 5.1 + - ARM Android 1.5, 2.1, 2.3 + - MIPS IRIX 6.2, 6.5 + - Power AIX 3.2.5, 4.2, 4.3.1, 4.3.2, 5.1, 5.2 + - i386 Linux 1.3, 2.0, 2.2, 2.3, 2.4, 2.6 + - i386 Novell NetWare + - i386 Windows 95, 98, ME, NT, 2000, XP, 2003 + - x86_64 Linux + + +Useful URLs +=========== + + - c-ares: https://c-ares.haxx.se/ + - MingW: http://www.mingw.org/ + - MinGW-w64: http://mingw-w64.sourceforge.net/ + - OpenWatcom: http://www.openwatcom.org/ diff --git a/LICENSE.md b/LICENSE.md index 86b520b..ad6bb52 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # c-ares license -Copyright (c) 2007 - 2016, Daniel Stenberg with many contributors, see AUTHORS +Copyright (c) 2007 - 2018, Daniel Stenberg with many contributors, see AUTHORS file. Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/Makefile.Watcom b/Makefile.Watcom index 7a450a0..fa529a5 100644 --- a/Makefile.Watcom +++ b/Makefile.Watcom @@ -52,7 +52,7 @@ LFLAGS += debug all CFLAGS += -d0 !endif -CFLAGS += -d_WIN32_WINNT=0x0501 +CFLAGS += -d_WIN32_WINNT=0x0600 # # Change to suite. diff --git a/Makefile.am b/Makefile.am index 3ba40ba..eef3d3d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,207 +1,31 @@ -AUTOMAKE_OPTIONS = foreign nostdinc +AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install -ACLOCAL_AMFLAGS = -I m4 - -# Specify our include paths here, and do it relative to $(top_srcdir) and -# $(top_builddir), to ensure that these paths which belong to the library -# being currently built and tested are searched before the library which -# might possibly already be installed in the system. -# -# When using the low-level hard-hacking memory leak tracking code from -# libcurl the generated curl/curlbuild.h file must also be reachable. -# Using the libcurl lowlevel code from within c-ares library is ugly and -# only works when c-ares is built and linked with a similarly debug-build -# libcurl, but we do this anyway for convenience. -# -# $(top_builddir)/../include/curl for generated curlbuild.h included from curl.h -# $(top_builddir)/../include is for libcurl's generated curl/curlbuild.h file -# $(top_srcdir)/../include is for libcurl's external include files -# $(top_builddir)/../lib is for libcurl's generated lib/curl_config.h file -# $(top_srcdir)/../lib is for libcurl's lib/setup.h and other "private" files -# $(top_builddir) is for c-ares's generated ares_config.h file -# $(top_srcdir) is for c-ares's ares_setup.h and other "c-ares-private" files - -if CURLDEBUG -AM_CPPFLAGS = -I$(top_builddir)/../include/curl \ - -I$(top_builddir)/../include \ - -I$(top_srcdir)/../include \ - -I$(top_builddir)/../lib \ - -I$(top_srcdir)/../lib \ - -I$(top_builddir) \ - -I$(top_srcdir) -else -AM_CPPFLAGS = -I$(top_builddir) \ - -I$(top_srcdir) -endif - -lib_LTLIBRARIES = libcares.la - -man_MANS = $(MANPAGES) - -MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \ - vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw - -if CURLDEBUG -PROGS = -else -PROGS = ahost adig acountry -endif - -noinst_PROGRAMS =$(PROGS) +MSVCFILES = msvc_ver.inc buildconf.bat # adig and ahost are just sample programs and thus not mentioned with the # regular sources and headers -EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj \ - Makefile.m32 Makefile.netware Makefile.msvc Makefile.Watcom $(man_MANS) \ - config-win32.h RELEASE-NOTES libcares.pc.in buildconf get_ver.awk maketgz \ - TODO ares_build.h.in $(PDFPAGES) cares.rc README.msvc $(MSVCFILES) \ - $(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL \ - README.md LICENSE.md +EXTRA_DIST = AUTHORS CHANGES README.cares $(man_MANS) RELEASE-NOTES \ + c-ares-config.cmake.in libcares.pc.cmake libcares.pc.in buildconf get_ver.awk \ + maketgz TODO README.msvc $(MSVCFILES) INSTALL.md README.md LICENSE.md \ + CMakeLists.txt Makefile.dj Makefile.m32 Makefile.netware Makefile.msvc \ + Makefile.Watcom AUTHORS CONTRIBUTING.md SECURITY.md TODO + CLEANFILES = $(PDFPAGES) $(HTMLPAGES) -DISTCLEANFILES = ares_build.h +DISTCLEANFILES = include/ares_build.h -DIST_SUBDIRS = test +DIST_SUBDIRS = include src test docs + +SUBDIRS = @BUILD_SUBDIRS@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcares.pc -CARES_VERSION_INFO = -version-info 4:0:2 -# This flag accepts an argument of the form current[:revision[:age]]. So, -# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to -# 1. -# -# If either revision or age are omitted, they default to 0. Also note that age -# must be less than or equal to the current interface number. -# -# Here are a set of rules to help you update your library version information: -# -# 1.Start with version information of 0:0:0 for each libtool library. -# -# 2.Update the version information only immediately before a public release of -# your software. More frequent updates are unnecessary, and only guarantee -# that the current interface number gets larger faster. -# -# 3.If the library source code has changed at all since the last update, then -# increment revision (c:r+1:a) -# -# 4.If any interfaces have been added, removed, or changed since the last -# update, increment current, and set revision to 0. (c+1:r=0:a) -# -# 5.If any interfaces have been added since the last public release, then -# increment age. (c:r:a+1) -# -# 6.If any interfaces have been removed since the last public release, then -# set age to 0. (c:r:a=0) -# - -AM_LDFLAGS = - -libcares_la_LDFLAGS_EXTRA = - -if CARES_LT_SHLIB_USE_VERSION_INFO -libcares_la_LDFLAGS_EXTRA += $(CARES_VERSION_INFO) -endif - -if CARES_LT_SHLIB_USE_NO_UNDEFINED -libcares_la_LDFLAGS_EXTRA += -no-undefined -endif - -if CARES_LT_SHLIB_USE_MIMPURE_TEXT -libcares_la_LDFLAGS_EXTRA += -mimpure-text -endif - -libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA) - -# Add -Werror if defined -CFLAGS += @CARES_CFLAG_EXTRAS@ - -if USE_CPPFLAG_CARES_STATICLIB -AM_CPPFLAGS += $(CPPFLAG_CARES_STATICLIB) -endif - -libcares_la_CFLAGS_EXTRA = - -libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY - -if DOING_CARES_SYMBOL_HIDING -libcares_la_CFLAGS_EXTRA += $(CFLAG_CARES_SYMBOL_HIDING) -libcares_la_CPPFLAGS_EXTRA += -DCARES_SYMBOL_HIDING -endif - -@CODE_COVERAGE_RULES@ -libcares_la_LDFLAGS += $(CODE_COVERAGE_LDFLAGS) -libcares_la_CFLAGS_EXTRA += $(CODE_COVERAGE_CFLAGS) - -libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA) - -libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA) - -# Makefile.inc provides the CSOURCES and HHEADERS defines -include Makefile.inc - -libcares_la_SOURCES = $(CSOURCES) $(HHEADERS) - # where to install the c-ares headers libcares_ladir = $(includedir) -# what headers to install on 'make install': -libcares_la_HEADERS = ares.h ares_version.h ares_dns.h \ - ares_build.h ares_rules.h - -ahost_SOURCES = ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -ahost_LDADD = $(top_builddir)/libcares.la -ahost_CFLAGS = $(AM_CFLAGS) -ahost_CPPFLAGS = $(AM_CPPFLAGS) - -adig_SOURCES = adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -adig_LDADD = $(top_builddir)/libcares.la -adig_CFLAGS = $(AM_CFLAGS) -adig_CPPFLAGS = $(AM_CPPFLAGS) - -acountry_SOURCES = acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -acountry_LDADD = $(top_builddir)/libcares.la -acountry_CFLAGS = $(AM_CFLAGS) -acountry_CPPFLAGS = $(AM_CPPFLAGS) - -SOURCEDMANDIR = man3 -SOURCEDMANPAGES = ares_init.3 - -clean-local: clean-sourced-manpages - -clean-sourced-manpages: - @srcdmandir='$(SOURCEDMANDIR)'; \ - echo "rm -rf $(top_builddir)/$$srcdmandir"; \ - rm -rf $(top_builddir)/$$srcdmandir - -sourced-manpages: clean-sourced-manpages - @srcdmandir='$(SOURCEDMANDIR)'; \ - srcdmanfiles='$(SOURCEDMANPAGES)'; \ - mkdir $(top_builddir)/$$srcdmandir; \ - for file in $$srcdmanfiles; do \ - if test -f $(top_srcdir)/$$file; then \ - echo "cp $(top_srcdir)/$$file $(top_builddir)/$$srcdmandir/$$file"; \ - cp $(top_srcdir)/$$file $(top_builddir)/$$srcdmandir/$$file; \ - fi; \ - done - -MAN2HTML = roffit --mandir=. < $< >$@ - -SUFFIXES = .3 .html - -html: sourced-manpages $(HTMLPAGES) - -.3.html: - $(MAN2HTML) - -pdf: sourced-manpages $(PDFPAGES) -.3.pdf: - @(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \ - groff -Tps -man $< >$$foo.ps; \ - ps2pdf $$foo.ps $@; \ - rm $$foo.ps; \ - echo "converted $< to $@") # Make files named *.dist replace the file without .dist extension dist-hook: diff --git a/Makefile.dj b/Makefile.dj index f891f7f..a88aae2 100644 --- a/Makefile.dj +++ b/Makefile.dj @@ -1,85 +1,102 @@ # # c-ares Makefile for djgpp/gcc/Watt-32. -# By Gisle Vanem 2004. +# By Gisle Vanem 2004 - 2020. # +include src/lib/Makefile.inc +CSOURCES := $(addprefix src/lib/, $(CSOURCES)) +CSOURCES := $(filter-out src/lib/windows_port.c, $(CSOURCES)) -TOPDIR = .. +VPATH = src/lib src/tools -DEPEND_PREREQ = ares_config.h +# +# Root directory for Waterloo tcp/ip. +# WATT_ROOT should be set during Watt-32 install. +# +WATT32_ROOT = $(realpath $(WATT_ROOT)) +WATT32_LIB = $(WATT32_ROOT)/lib/libwatt.a -include ../packages/DOS/common.dj -include Makefile.inc +OBJ_DIR = djgpp -CFLAGS += -DWATT32 -Dselect=select_s +CFLAGS = -g -O2 -I./include -I./src/lib \ + -I$(WATT32_ROOT)/inc -Wall \ + -DWATT32 -DHAVE_CONFIG_H \ + -Dselect=select_s LDFLAGS = -s -ifeq ($(USE_CURLDEBUG),1) - EX_LIBS = ../lib/libcurl.a - OBJ_HACK = $(OBJECTS) -else - OBJ_HACK = libcares.a -endif +ifeq ($(OS),Windows_NT) + # + # Windows hosted djgpp cross compiler. Get it from: + # https://github.com/andrewwutw/build-djgpp/releases + # + DJ_PREFIX ?= c:/some-path/djgpp/bin/i586-pc-msdosdjgpp- + CC = $(DJ_PREFIX)gcc -ifeq ($(USE_SSL),1) - EX_LIBS += $(OPENSSL_ROOT)/lib/libssl.a $(OPENSSL_ROOT)/lib/libcrypt.a +else + # + # The normal djgpp 'gcc' for MSDOS. + # + CC = gcc endif -ifeq ($(USE_ZLIB),1) - EX_LIBS += $(ZLIB_ROOT)/libz.a -endif +OBJECTS = $(addprefix $(OBJ_DIR)/, \ + $(notdir $(CSOURCES:.c=.o))) -ifeq ($(USE_IDNA),1) - EX_LIBS += $(LIBIDN_ROOT)/lib/dj_obj/libidn.a -liconv -endif +GENERATED = src/lib/ares_config.h \ + include/ares_build.h -EX_LIBS += $(WATT32_ROOT)/lib/libwatt.a +TARGETS = libcares.a acountry.exe adig.exe ahost.exe -OBJECTS = $(addprefix $(OBJ_DIR)/, $(CSOURCES:.c=.o)) +.SECONDARY: $(OBJ_DIR)/ares_getopt.o -all: $(OBJ_DIR) ares_config.h libcares.a ahost.exe adig.exe acountry.exe +all: $(OBJ_DIR) $(GENERATED) $(TARGETS) @echo Welcome to c-ares. libcares.a: $(OBJECTS) - ar rs $@ $? - -ares_config.h: config-dos.h - $(COPY) $^ $@ + ar rs $@ $(OBJECTS) -ahost.exe: ahost.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) - $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) +src/lib/ares_config.h: src/lib/config-dos.h + cp --update $< $@ -adig.exe: adig.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) - $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) +include/ares_build.h: include/ares_build.h.dist + cp --update $< $@ -acountry.exe: acountry.c $(OBJ_DIR)/ares_getopt.o $(OBJ_HACK) - $(CC) $(LDFLAGS) $(CFLAGS) -o $@ $^ $(EX_LIBS) +%.exe: src/tools/%.c $(OBJ_DIR)/ares_getopt.o libcares.a + $(call compile_and_link, $@, $^ $(WATT32_LIB)) -# clean generated files +# Clean generated files and objects. # -genclean: - - $(DELETE) ares_config.h +clean: + - rm -f depend.dj $(GENERATED) $(OBJ_DIR)/*.o + - rmdir $(OBJ_DIR) -# clean object files and subdir +# Clean everything # -objclean: genclean - - $(DELETE) $(OBJ_DIR)$(DS)*.o - - $(RMDIR) $(OBJ_DIR) +realclean vclean: clean + - rm -f $(TARGETS) $(TARGETS:.exe=.map) -# clean without removing built library and programs -# -clean: objclean - - $(DELETE) depend.dj +$(OBJ_DIR): + - mkdir $@ + +$(OBJ_DIR)/%.o: %.c + $(CC) $(CFLAGS) -o $@ -c $< + @echo + +define compile_and_link + $(CC) -o $(1) $(CFLAGS) $(LDFLAGS) -Wl,--print-map,--sort-common $(2) > $(1:.exe=.map) + @echo +endef + +DEP_REPLACE = sed -e 's@\(.*\)\.o: @\n$$(OBJ_DIR)\/\1.o: @' \ + -e 's@$(WATT32_ROOT)@$$(WATT32_ROOT)@g' -# clean everything # -realclean vclean: clean - - $(DELETE) libcares.a - - $(DELETE) acountry.exe - - $(DELETE) adig.exe - - $(DELETE) ahost.exe - - $(DELETE) libcares.a +# One may have to do 'make -f Makefile.dj clean' first in case +# a foreign 'curl_config.h' is making trouble. +# +depend: $(GENERATED) Makefile.dj + $(CC) -MM $(CFLAGS) $(CSOURCES) | $(DEP_REPLACE) > depend.dj -include depend.dj diff --git a/Makefile.in b/Makefile.in index 7ae617a..35994e4 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,9 +14,6 @@ @SET_MAKE@ - - - VPATH = @srcdir@ am__is_gnu_make = { \ if test -z '$(MAKELEVEL)'; then \ @@ -91,15 +88,7 @@ PRE_UNINSTALL = : POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ -noinst_PROGRAMS = $(am__EXEEXT_1) -@CARES_LT_SHLIB_USE_VERSION_INFO_TRUE@am__append_1 = $(CARES_VERSION_INFO) -@CARES_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_2 = -no-undefined -@CARES_LT_SHLIB_USE_MIMPURE_TEXT_TRUE@am__append_3 = -mimpure-text -@USE_CPPFLAG_CARES_STATICLIB_TRUE@am__append_4 = $(CPPFLAG_CARES_STATICLIB) -@DOING_CARES_SYMBOL_HIDING_TRUE@am__append_5 = $(CFLAG_CARES_SYMBOL_HIDING) -@DOING_CARES_SYMBOL_HIDING_TRUE@am__append_6 = -DCARES_SYMBOL_HIDING subdir = . -SUBDIRS = ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ @@ -123,14 +112,41 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ - $(am__configure_deps) $(libcares_la_HEADERS) \ - $(am__DIST_COMMON) + $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs -CONFIG_HEADER = ares_config.h ares_build.h +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/lib/ares_config.h \ + $(top_builddir)/include/ares_build.h CONFIG_CLEAN_FILES = libcares.pc CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ @@ -158,138 +174,8 @@ am__uninstall_files_from_dir = { \ || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ $(am__cd) "$$dir" && rm -f $$files; }; \ } -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \ - "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libcares_ladir)" -LTLIBRARIES = $(lib_LTLIBRARIES) -libcares_la_LIBADD = -am__objects_1 = libcares_la-ares__close_sockets.lo \ - libcares_la-ares__get_hostent.lo \ - libcares_la-ares__read_line.lo libcares_la-ares__timeval.lo \ - libcares_la-ares_cancel.lo libcares_la-ares_data.lo \ - libcares_la-ares_destroy.lo libcares_la-ares_expand_name.lo \ - libcares_la-ares_expand_string.lo libcares_la-ares_fds.lo \ - libcares_la-ares_free_hostent.lo \ - libcares_la-ares_free_string.lo libcares_la-ares_getenv.lo \ - libcares_la-ares_gethostbyaddr.lo \ - libcares_la-ares_gethostbyname.lo \ - libcares_la-ares_getnameinfo.lo libcares_la-ares_getsock.lo \ - libcares_la-ares_init.lo libcares_la-ares_library_init.lo \ - libcares_la-ares_llist.lo libcares_la-ares_mkquery.lo \ - libcares_la-ares_create_query.lo libcares_la-ares_nowarn.lo \ - libcares_la-ares_options.lo libcares_la-ares_parse_a_reply.lo \ - libcares_la-ares_parse_aaaa_reply.lo \ - libcares_la-ares_parse_mx_reply.lo \ - libcares_la-ares_parse_naptr_reply.lo \ - libcares_la-ares_parse_ns_reply.lo \ - libcares_la-ares_parse_ptr_reply.lo \ - libcares_la-ares_parse_soa_reply.lo \ - libcares_la-ares_parse_srv_reply.lo \ - libcares_la-ares_parse_txt_reply.lo \ - libcares_la-ares_platform.lo libcares_la-ares_process.lo \ - libcares_la-ares_query.lo libcares_la-ares_search.lo \ - libcares_la-ares_send.lo libcares_la-ares_strcasecmp.lo \ - libcares_la-ares_strdup.lo libcares_la-ares_strerror.lo \ - libcares_la-ares_timeout.lo libcares_la-ares_version.lo \ - libcares_la-ares_writev.lo libcares_la-bitncmp.lo \ - libcares_la-inet_net_pton.lo libcares_la-inet_ntop.lo \ - libcares_la-windows_port.lo -am__objects_2 = -am_libcares_la_OBJECTS = $(am__objects_1) $(am__objects_2) -libcares_la_OBJECTS = $(am_libcares_la_OBJECTS) -AM_V_lt = $(am__v_lt_@AM_V@) -am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -am__v_lt_0 = --silent -am__v_lt_1 = -libcares_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcares_la_CFLAGS) \ - $(CFLAGS) $(libcares_la_LDFLAGS) $(LDFLAGS) -o $@ -@CURLDEBUG_FALSE@am__EXEEXT_1 = ahost$(EXEEXT) adig$(EXEEXT) \ -@CURLDEBUG_FALSE@ acountry$(EXEEXT) -PROGRAMS = $(noinst_PROGRAMS) -am__objects_3 = acountry-ares_getopt.$(OBJEXT) \ - acountry-ares_nowarn.$(OBJEXT) \ - acountry-ares_strcasecmp.$(OBJEXT) -am_acountry_OBJECTS = acountry-acountry.$(OBJEXT) $(am__objects_3) \ - $(am__objects_2) -acountry_OBJECTS = $(am_acountry_OBJECTS) -acountry_DEPENDENCIES = $(top_builddir)/libcares.la -acountry_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(acountry_CFLAGS) \ - $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_4 = adig-ares_getopt.$(OBJEXT) adig-ares_nowarn.$(OBJEXT) \ - adig-ares_strcasecmp.$(OBJEXT) -am_adig_OBJECTS = adig-adig.$(OBJEXT) $(am__objects_4) \ - $(am__objects_2) -adig_OBJECTS = $(am_adig_OBJECTS) -adig_DEPENDENCIES = $(top_builddir)/libcares.la -adig_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(adig_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_5 = ahost-ares_getopt.$(OBJEXT) \ - ahost-ares_nowarn.$(OBJEXT) ahost-ares_strcasecmp.$(OBJEXT) -am_ahost_OBJECTS = ahost-ahost.$(OBJEXT) $(am__objects_5) \ - $(am__objects_2) -ahost_OBJECTS = $(am_ahost_OBJECTS) -ahost_DEPENDENCIES = $(top_builddir)/libcares.la -ahost_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ahost_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_P = $(am__v_P_@AM_V@) -am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) -am__v_P_0 = false -am__v_P_1 = : -AM_V_GEN = $(am__v_GEN_@AM_V@) -am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) -am__v_GEN_0 = @echo " GEN " $@; -am__v_GEN_1 = -AM_V_at = $(am__v_at_@AM_V@) -am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) -am__v_at_0 = @ -am__v_at_1 = -DEFAULT_INCLUDES = -depcomp = $(SHELL) $(top_srcdir)/depcomp -am__depfiles_maybe = depfiles -am__mv = mv -f -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libcares_la_SOURCES) $(acountry_SOURCES) $(adig_SOURCES) \ - $(ahost_SOURCES) -DIST_SOURCES = $(libcares_la_SOURCES) $(acountry_SOURCES) \ - $(adig_SOURCES) $(ahost_SOURCES) -RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ - ctags-recursive dvi-recursive html-recursive info-recursive \ - install-data-recursive install-dvi-recursive \ - install-exec-recursive install-html-recursive \ - install-info-recursive install-pdf-recursive \ - install-ps-recursive install-recursive installcheck-recursive \ - installdirs-recursive pdf-recursive ps-recursive \ - tags-recursive uninstall-recursive -am__can_run_installinfo = \ - case $$AM_UPDATE_INFO_DIR in \ - n|no|NO) false;; \ - *) (install-info --version) >/dev/null 2>&1;; \ - esac -man3dir = $(mandir)/man3 -NROFF = nroff -MANS = $(man_MANS) +am__installdirs = "$(DESTDIR)$(pkgconfigdir)" DATA = $(pkgconfig_DATA) -HEADERS = $(libcares_la_HEADERS) RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ distclean-recursive maintainer-clean-recursive am__recursive_targets = \ @@ -297,9 +183,8 @@ am__recursive_targets = \ $(RECURSIVE_CLEAN_TARGETS) \ $(am__extra_recursive_targets) AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ - cscope distdir dist dist-all distcheck -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)ares_config.h.in ares_build.h.in + cscope distdir distdir-am dist dist-all distcheck +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -319,11 +204,9 @@ am__define_uniq_tagged_files = \ ETAGS = etags CTAGS = ctags CSCOPE = cscope -am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ - $(srcdir)/ares_build.h.in $(srcdir)/ares_config.h.in \ - $(srcdir)/libcares.pc.in AUTHORS INSTALL NEWS TODO compile \ - config.guess config.sub depcomp install-sh ltmain.sh missing \ - mkinstalldirs +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/libcares.pc.in \ + AUTHORS NEWS TODO compile config.guess config.sub install-sh \ + ltmain.sh missing DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -375,13 +258,13 @@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ CC = @CC@ CCDEPMODE = @CCDEPMODE@ - -# Add -Werror if defined -CFLAGS = @CFLAGS@ @CARES_CFLAG_EXTRAS@ +CFLAGS = @CFLAGS@ CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ @@ -504,365 +387,33 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -AUTOMAKE_OPTIONS = foreign nostdinc -ACLOCAL_AMFLAGS = -I m4 -@CURLDEBUG_FALSE@AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) \ -@CURLDEBUG_FALSE@ $(am__append_4) - -# Specify our include paths here, and do it relative to $(top_srcdir) and -# $(top_builddir), to ensure that these paths which belong to the library -# being currently built and tested are searched before the library which -# might possibly already be installed in the system. -# -# When using the low-level hard-hacking memory leak tracking code from -# libcurl the generated curl/curlbuild.h file must also be reachable. -# Using the libcurl lowlevel code from within c-ares library is ugly and -# only works when c-ares is built and linked with a similarly debug-build -# libcurl, but we do this anyway for convenience. -# -# $(top_builddir)/../include/curl for generated curlbuild.h included from curl.h -# $(top_builddir)/../include is for libcurl's generated curl/curlbuild.h file -# $(top_srcdir)/../include is for libcurl's external include files -# $(top_builddir)/../lib is for libcurl's generated lib/curl_config.h file -# $(top_srcdir)/../lib is for libcurl's lib/setup.h and other "private" files -# $(top_builddir) is for c-ares's generated ares_config.h file -# $(top_srcdir) is for c-ares's ares_setup.h and other "c-ares-private" files -@CURLDEBUG_TRUE@AM_CPPFLAGS = -I$(top_builddir)/../include/curl \ -@CURLDEBUG_TRUE@ -I$(top_builddir)/../include \ -@CURLDEBUG_TRUE@ -I$(top_srcdir)/../include \ -@CURLDEBUG_TRUE@ -I$(top_builddir)/../lib \ -@CURLDEBUG_TRUE@ -I$(top_srcdir)/../lib -I$(top_builddir) \ -@CURLDEBUG_TRUE@ -I$(top_srcdir) $(am__append_4) -lib_LTLIBRARIES = libcares.la -man_MANS = $(MANPAGES) -MSVCFILES = vc/vc6aws.dsw vc/acountry/vc6acountry.dsp vc/adig/vc6adig.dsp \ - vc/ahost/vc6ahost.dsp vc/cares/vc6cares.dsp vc/cares/vc6cares.dsw - -@CURLDEBUG_FALSE@PROGS = ahost adig acountry -@CURLDEBUG_TRUE@PROGS = +AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install +MSVCFILES = msvc_ver.inc buildconf.bat # adig and ahost are just sample programs and thus not mentioned with the # regular sources and headers -EXTRA_DIST = AUTHORS CHANGES README.cares Makefile.inc Makefile.dj \ - Makefile.m32 Makefile.netware Makefile.msvc Makefile.Watcom $(man_MANS) \ - config-win32.h RELEASE-NOTES libcares.pc.in buildconf get_ver.awk maketgz \ - TODO ares_build.h.in $(PDFPAGES) cares.rc README.msvc $(MSVCFILES) \ - $(CSOURCES) $(HHEADERS) config-dos.h acountry.1 adig.1 ahost.1 INSTALL \ - README.md LICENSE.md +EXTRA_DIST = AUTHORS CHANGES README.cares $(man_MANS) RELEASE-NOTES \ + c-ares-config.cmake.in libcares.pc.cmake libcares.pc.in buildconf get_ver.awk \ + maketgz TODO README.msvc $(MSVCFILES) INSTALL.md README.md LICENSE.md \ + CMakeLists.txt Makefile.dj Makefile.m32 Makefile.netware Makefile.msvc \ + Makefile.Watcom AUTHORS CONTRIBUTING.md SECURITY.md TODO CLEANFILES = $(PDFPAGES) $(HTMLPAGES) -DISTCLEANFILES = ares_build.h -DIST_SUBDIRS = test +DISTCLEANFILES = include/ares_build.h +DIST_SUBDIRS = include src test docs +SUBDIRS = @BUILD_SUBDIRS@ pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libcares.pc -CARES_VERSION_INFO = -version-info 4:0:2 -# This flag accepts an argument of the form current[:revision[:age]]. So, -# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to -# 1. -# -# If either revision or age are omitted, they default to 0. Also note that age -# must be less than or equal to the current interface number. -# -# Here are a set of rules to help you update your library version information: -# -# 1.Start with version information of 0:0:0 for each libtool library. -# -# 2.Update the version information only immediately before a public release of -# your software. More frequent updates are unnecessary, and only guarantee -# that the current interface number gets larger faster. -# -# 3.If the library source code has changed at all since the last update, then -# increment revision (c:r+1:a) -# -# 4.If any interfaces have been added, removed, or changed since the last -# update, increment current, and set revision to 0. (c+1:r=0:a) -# -# 5.If any interfaces have been added since the last public release, then -# increment age. (c:r:a+1) -# -# 6.If any interfaces have been removed since the last public release, then -# set age to 0. (c:r:a=0) -# -AM_LDFLAGS = -libcares_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \ - $(am__append_3) -libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA) \ - $(CODE_COVERAGE_LDFLAGS) -libcares_la_CFLAGS_EXTRA = $(am__append_5) $(CODE_COVERAGE_CFLAGS) -libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY $(am__append_6) -libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA) -libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA) -CSOURCES = ares__close_sockets.c \ - ares__get_hostent.c \ - ares__read_line.c \ - ares__timeval.c \ - ares_cancel.c \ - ares_data.c \ - ares_destroy.c \ - ares_expand_name.c \ - ares_expand_string.c \ - ares_fds.c \ - ares_free_hostent.c \ - ares_free_string.c \ - ares_getenv.c \ - ares_gethostbyaddr.c \ - ares_gethostbyname.c \ - ares_getnameinfo.c \ - ares_getsock.c \ - ares_init.c \ - ares_library_init.c \ - ares_llist.c \ - ares_mkquery.c \ - ares_create_query.c \ - ares_nowarn.c \ - ares_options.c \ - ares_parse_a_reply.c \ - ares_parse_aaaa_reply.c \ - ares_parse_mx_reply.c \ - ares_parse_naptr_reply.c \ - ares_parse_ns_reply.c \ - ares_parse_ptr_reply.c \ - ares_parse_soa_reply.c \ - ares_parse_srv_reply.c \ - ares_parse_txt_reply.c \ - ares_platform.c \ - ares_process.c \ - ares_query.c \ - ares_search.c \ - ares_send.c \ - ares_strcasecmp.c \ - ares_strdup.c \ - ares_strerror.c \ - ares_timeout.c \ - ares_version.c \ - ares_writev.c \ - bitncmp.c \ - inet_net_pton.c \ - inet_ntop.c \ - windows_port.c - -HHEADERS = ares.h \ - ares_build.h \ - ares_data.h \ - ares_dns.h \ - ares_getenv.h \ - ares_inet_net_pton.h \ - ares_iphlpapi.h \ - ares_ipv6.h \ - ares_library_init.h \ - ares_llist.h \ - ares_nowarn.h \ - ares_platform.h \ - ares_private.h \ - ares_rules.h \ - ares_strcasecmp.h \ - ares_strdup.h \ - ares_version.h \ - ares_writev.h \ - bitncmp.h \ - nameser.h \ - ares_setup.h \ - setup_once.h - -MANPAGES = ares_cancel.3 \ - ares_destroy.3 \ - ares_destroy_options.3 \ - ares_dup.3 \ - ares_expand_name.3 \ - ares_expand_string.3 \ - ares_fds.3 \ - ares_free_data.3 \ - ares_free_hostent.3 \ - ares_free_string.3 \ - ares_get_servers.3 \ - ares_get_servers_ports.3 \ - ares_gethostbyaddr.3 \ - ares_gethostbyname.3 \ - ares_gethostbyname_file.3 \ - ares_getnameinfo.3 \ - ares_getsock.3 \ - ares_init.3 \ - ares_init_options.3 \ - ares_library_cleanup.3 \ - ares_library_init.3 \ - ares_mkquery.3 \ - ares_create_query.3 \ - ares_parse_a_reply.3 \ - ares_parse_aaaa_reply.3 \ - ares_parse_mx_reply.3 \ - ares_parse_naptr_reply.3 \ - ares_parse_ns_reply.3 \ - ares_parse_ptr_reply.3 \ - ares_parse_soa_reply.3 \ - ares_parse_srv_reply.3 \ - ares_parse_txt_reply.3 \ - ares_process.3 \ - ares_query.3 \ - ares_save_options.3 \ - ares_search.3 \ - ares_send.3 \ - ares_set_local_dev.3 \ - ares_set_local_ip4.3 \ - ares_set_local_ip6.3 \ - ares_set_servers.3 \ - ares_set_servers_csv.3 \ - ares_set_servers_ports.3 \ - ares_set_servers_ports_csv.3 \ - ares_set_socket_callback.3 \ - ares_set_socket_configure_callback.3 \ - ares_set_sortlist.3 \ - ares_strerror.3 \ - ares_timeout.3 \ - ares_version.3 \ - ares_inet_pton.3 \ - ares_inet_ntop.3 - -HTMLPAGES = ares_cancel.html \ - ares_destroy.html \ - ares_destroy_options.html \ - ares_dup.html \ - ares_expand_name.html \ - ares_expand_string.html \ - ares_fds.html \ - ares_free_data.html \ - ares_free_hostent.html \ - ares_free_string.html \ - ares_get_servers.html \ - ares_get_servers_ports.html \ - ares_gethostbyaddr.html \ - ares_gethostbyname.html \ - ares_gethostbyname_file.html \ - ares_getnameinfo.html \ - ares_getsock.html \ - ares_init.html \ - ares_init_options.html \ - ares_library_cleanup.html \ - ares_library_init.html \ - ares_mkquery.html \ - ares_create_query.html \ - ares_parse_a_reply.html \ - ares_parse_aaaa_reply.html \ - ares_parse_mx_reply.html \ - ares_parse_ns_reply.html \ - ares_parse_ptr_reply.html \ - ares_parse_soa_reply.html \ - ares_parse_srv_reply.html \ - ares_parse_txt_reply.html \ - ares_process.html \ - ares_query.html \ - ares_save_options.html \ - ares_search.html \ - ares_send.html \ - ares_set_local_dev.html \ - ares_set_local_ip4.html \ - ares_set_local_ip6.html \ - ares_set_servers.html \ - ares_set_servers_csv.html \ - ares_set_servers_ports.html \ - ares_set_servers_ports_csv.html \ - ares_set_socket_callback.html \ - ares_set_socket_configure_callback.html \ - ares_set_sortlist.html \ - ares_strerror.html \ - ares_timeout.html \ - ares_version.html \ - ares_inet_pton.html \ - ares_inet_ntop.html - -PDFPAGES = ares_cancel.pdf \ - ares_destroy.pdf \ - ares_destroy_options.pdf \ - ares_dup.pdf \ - ares_expand_name.pdf \ - ares_expand_string.pdf \ - ares_fds.pdf \ - ares_free_data.pdf \ - ares_free_hostent.pdf \ - ares_free_string.pdf \ - ares_get_servers.pdf \ - ares_get_servers_ports.pdf \ - ares_gethostbyaddr.pdf \ - ares_gethostbyname.pdf \ - ares_gethostbyname_file.pdf \ - ares_getnameinfo.pdf \ - ares_getsock.pdf \ - ares_init.pdf \ - ares_init_options.pdf \ - ares_library_cleanup.pdf \ - ares_library_init.pdf \ - ares_mkquery.pdf \ - ares_create_query.pdf \ - ares_parse_a_reply.pdf \ - ares_parse_aaaa_reply.pdf \ - ares_parse_mx_reply.pdf \ - ares_parse_ns_reply.pdf \ - ares_parse_ptr_reply.pdf \ - ares_parse_soa_reply.pdf \ - ares_parse_srv_reply.pdf \ - ares_parse_txt_reply.pdf \ - ares_process.pdf \ - ares_query.pdf \ - ares_save_options.pdf \ - ares_search.pdf \ - ares_send.pdf \ - ares_set_local_dev.pdf \ - ares_set_local_ip4.pdf \ - ares_set_local_ip6.pdf \ - ares_set_servers.pdf \ - ares_set_servers_csv.pdf \ - ares_set_servers_ports.pdf \ - ares_set_servers_ports_csv.pdf \ - ares_set_socket_callback.pdf \ - ares_set_socket_configure_callback.pdf \ - ares_set_sortlist.pdf \ - ares_strerror.pdf \ - ares_timeout.pdf \ - ares_version.pdf \ - ares_inet_pton.pdf \ - ares_inet_ntop.pdf - -SAMPLESOURCES = ares_getopt.c \ - ares_nowarn.c \ - ares_strcasecmp.c - -SAMPLEHEADERS = ares_getopt.h \ - ares_nowarn.h \ - ares_strcasecmp.h - - -# Makefile.inc provides the CSOURCES and HHEADERS defines -libcares_la_SOURCES = $(CSOURCES) $(HHEADERS) # where to install the c-ares headers libcares_ladir = $(includedir) -# what headers to install on 'make install': -libcares_la_HEADERS = ares.h ares_version.h ares_dns.h \ - ares_build.h ares_rules.h - -ahost_SOURCES = ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -ahost_LDADD = $(top_builddir)/libcares.la -ahost_CFLAGS = $(AM_CFLAGS) -ahost_CPPFLAGS = $(AM_CPPFLAGS) -adig_SOURCES = adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -adig_LDADD = $(top_builddir)/libcares.la -adig_CFLAGS = $(AM_CFLAGS) -adig_CPPFLAGS = $(AM_CPPFLAGS) -acountry_SOURCES = acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) -acountry_LDADD = $(top_builddir)/libcares.la -acountry_CFLAGS = $(AM_CFLAGS) -acountry_CPPFLAGS = $(AM_CPPFLAGS) -SOURCEDMANDIR = man3 -SOURCEDMANPAGES = ares_init.3 -MAN2HTML = roffit --mandir=. < $< >$@ -SUFFIXES = .3 .html -all: ares_config.h ares_build.h - $(MAKE) $(AM_MAKEFLAGS) all-recursive +all: all-recursive .SUFFIXES: -.SUFFIXES: .3 .html .c .lo .o .obj .pdf am--refresh: Makefile @: -$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ @@ -881,10 +432,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; -$(srcdir)/Makefile.inc $(am__empty): $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) $(SHELL) ./config.status --recheck @@ -894,686 +444,9 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS) $(am__aclocal_m4_deps): - -ares_config.h: stamp-h1 - @test -f $@ || rm -f stamp-h1 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 - -stamp-h1: $(srcdir)/ares_config.h.in $(top_builddir)/config.status - @rm -f stamp-h1 - cd $(top_builddir) && $(SHELL) ./config.status ares_config.h -$(srcdir)/ares_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) - ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) - rm -f stamp-h1 - touch $@ - -ares_build.h: stamp-h2 - @test -f $@ || rm -f stamp-h2 - @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 - -stamp-h2: $(srcdir)/ares_build.h.in $(top_builddir)/config.status - @rm -f stamp-h2 - cd $(top_builddir) && $(SHELL) ./config.status ares_build.h - -distclean-hdr: - -rm -f ares_config.h stamp-h1 ares_build.h stamp-h2 libcares.pc: $(top_builddir)/config.status $(srcdir)/libcares.pc.in cd $(top_builddir) && $(SHELL) ./config.status $@ -install-libLTLIBRARIES: $(lib_LTLIBRARIES) - @$(NORMAL_INSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - list2=; for p in $$list; do \ - if test -f $$p; then \ - list2="$$list2 $$p"; \ - else :; fi; \ - done; \ - test -z "$$list2" || { \ - echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ - } - -uninstall-libLTLIBRARIES: - @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ - for p in $$list; do \ - $(am__strip_dir) \ - echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ - done - -clean-libLTLIBRARIES: - -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) - @list='$(lib_LTLIBRARIES)'; \ - locs=`for p in $$list; do echo $$p; done | \ - sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ - sort -u`; \ - test -z "$$locs" || { \ - echo rm -f $${locs}; \ - rm -f $${locs}; \ - } - -libcares.la: $(libcares_la_OBJECTS) $(libcares_la_DEPENDENCIES) $(EXTRA_libcares_la_DEPENDENCIES) - $(AM_V_CCLD)$(libcares_la_LINK) -rpath $(libdir) $(libcares_la_OBJECTS) $(libcares_la_LIBADD) $(LIBS) - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - -acountry$(EXEEXT): $(acountry_OBJECTS) $(acountry_DEPENDENCIES) $(EXTRA_acountry_DEPENDENCIES) - @rm -f acountry$(EXEEXT) - $(AM_V_CCLD)$(acountry_LINK) $(acountry_OBJECTS) $(acountry_LDADD) $(LIBS) - -adig$(EXEEXT): $(adig_OBJECTS) $(adig_DEPENDENCIES) $(EXTRA_adig_DEPENDENCIES) - @rm -f adig$(EXEEXT) - $(AM_V_CCLD)$(adig_LINK) $(adig_OBJECTS) $(adig_LDADD) $(LIBS) - -ahost$(EXEEXT): $(ahost_OBJECTS) $(ahost_DEPENDENCIES) $(EXTRA_ahost_DEPENDENCIES) - @rm -f ahost$(EXEEXT) - $(AM_V_CCLD)$(ahost_LINK) $(ahost_OBJECTS) $(ahost_LDADD) $(LIBS) - -mostlyclean-compile: - -rm -f *.$(OBJEXT) - -distclean-compile: - -rm -f *.tab.c - -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-acountry.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-ares_getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-ares_nowarn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-ares_strcasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-adig.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-ares_getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-ares_nowarn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-ares_strcasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ahost.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ares_getopt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ares_nowarn.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ares_strcasecmp.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__close_sockets.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__get_hostent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__read_line.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__timeval.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_cancel.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_create_query.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_data.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_destroy.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_name.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_string.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_fds.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_hostent.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_string.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getenv.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getsock.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_init.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_library_init.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_llist.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_mkquery.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_nowarn.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_options.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_platform.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_process.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_query.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_search.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_send.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strdup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strerror.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_timeout.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_version.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_writev.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-bitncmp.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_net_pton.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_ntop.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-windows_port.Plo@am__quote@ - -.c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< - -.c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ -@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ -@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ -@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< - -libcares_la-ares__close_sockets.lo: ares__close_sockets.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__close_sockets.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__close_sockets.Tpo -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__close_sockets.Tpo $(DEPDIR)/libcares_la-ares__close_sockets.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__close_sockets.c' object='libcares_la-ares__close_sockets.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c - -libcares_la-ares__get_hostent.lo: ares__get_hostent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__get_hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__get_hostent.Tpo -c -o libcares_la-ares__get_hostent.lo `test -f 'ares__get_hostent.c' || echo '$(srcdir)/'`ares__get_hostent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__get_hostent.Tpo $(DEPDIR)/libcares_la-ares__get_hostent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__get_hostent.c' object='libcares_la-ares__get_hostent.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__get_hostent.lo `test -f 'ares__get_hostent.c' || echo '$(srcdir)/'`ares__get_hostent.c - -libcares_la-ares__read_line.lo: ares__read_line.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__read_line.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__read_line.Tpo -c -o libcares_la-ares__read_line.lo `test -f 'ares__read_line.c' || echo '$(srcdir)/'`ares__read_line.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__read_line.Tpo $(DEPDIR)/libcares_la-ares__read_line.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__read_line.c' object='libcares_la-ares__read_line.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__read_line.lo `test -f 'ares__read_line.c' || echo '$(srcdir)/'`ares__read_line.c - -libcares_la-ares__timeval.lo: ares__timeval.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__timeval.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__timeval.Tpo -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__timeval.Tpo $(DEPDIR)/libcares_la-ares__timeval.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__timeval.c' object='libcares_la-ares__timeval.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c - -libcares_la-ares_cancel.lo: ares_cancel.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_cancel.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_cancel.Tpo -c -o libcares_la-ares_cancel.lo `test -f 'ares_cancel.c' || echo '$(srcdir)/'`ares_cancel.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_cancel.Tpo $(DEPDIR)/libcares_la-ares_cancel.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_cancel.c' object='libcares_la-ares_cancel.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_cancel.lo `test -f 'ares_cancel.c' || echo '$(srcdir)/'`ares_cancel.c - -libcares_la-ares_data.lo: ares_data.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_data.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_data.Tpo -c -o libcares_la-ares_data.lo `test -f 'ares_data.c' || echo '$(srcdir)/'`ares_data.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_data.Tpo $(DEPDIR)/libcares_la-ares_data.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_data.c' object='libcares_la-ares_data.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_data.lo `test -f 'ares_data.c' || echo '$(srcdir)/'`ares_data.c - -libcares_la-ares_destroy.lo: ares_destroy.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_destroy.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_destroy.Tpo -c -o libcares_la-ares_destroy.lo `test -f 'ares_destroy.c' || echo '$(srcdir)/'`ares_destroy.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_destroy.Tpo $(DEPDIR)/libcares_la-ares_destroy.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_destroy.c' object='libcares_la-ares_destroy.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_destroy.lo `test -f 'ares_destroy.c' || echo '$(srcdir)/'`ares_destroy.c - -libcares_la-ares_expand_name.lo: ares_expand_name.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_name.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_name.Tpo -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_name.Tpo $(DEPDIR)/libcares_la-ares_expand_name.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_name.c' object='libcares_la-ares_expand_name.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c - -libcares_la-ares_expand_string.lo: ares_expand_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_string.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_string.Tpo -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_string.Tpo $(DEPDIR)/libcares_la-ares_expand_string.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_string.c' object='libcares_la-ares_expand_string.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c - -libcares_la-ares_fds.lo: ares_fds.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_fds.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_fds.Tpo -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_fds.Tpo $(DEPDIR)/libcares_la-ares_fds.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_fds.c' object='libcares_la-ares_fds.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c - -libcares_la-ares_free_hostent.lo: ares_free_hostent.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_free_hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_free_hostent.Tpo -c -o libcares_la-ares_free_hostent.lo `test -f 'ares_free_hostent.c' || echo '$(srcdir)/'`ares_free_hostent.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_free_hostent.Tpo $(DEPDIR)/libcares_la-ares_free_hostent.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_free_hostent.c' object='libcares_la-ares_free_hostent.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_free_hostent.lo `test -f 'ares_free_hostent.c' || echo '$(srcdir)/'`ares_free_hostent.c - -libcares_la-ares_free_string.lo: ares_free_string.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_free_string.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_free_string.Tpo -c -o libcares_la-ares_free_string.lo `test -f 'ares_free_string.c' || echo '$(srcdir)/'`ares_free_string.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_free_string.Tpo $(DEPDIR)/libcares_la-ares_free_string.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_free_string.c' object='libcares_la-ares_free_string.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_free_string.lo `test -f 'ares_free_string.c' || echo '$(srcdir)/'`ares_free_string.c - -libcares_la-ares_getenv.lo: ares_getenv.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getenv.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getenv.Tpo -c -o libcares_la-ares_getenv.lo `test -f 'ares_getenv.c' || echo '$(srcdir)/'`ares_getenv.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getenv.Tpo $(DEPDIR)/libcares_la-ares_getenv.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getenv.c' object='libcares_la-ares_getenv.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getenv.lo `test -f 'ares_getenv.c' || echo '$(srcdir)/'`ares_getenv.c - -libcares_la-ares_gethostbyaddr.lo: ares_gethostbyaddr.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_gethostbyaddr.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_gethostbyaddr.Tpo -c -o libcares_la-ares_gethostbyaddr.lo `test -f 'ares_gethostbyaddr.c' || echo '$(srcdir)/'`ares_gethostbyaddr.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_gethostbyaddr.Tpo $(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_gethostbyaddr.c' object='libcares_la-ares_gethostbyaddr.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_gethostbyaddr.lo `test -f 'ares_gethostbyaddr.c' || echo '$(srcdir)/'`ares_gethostbyaddr.c - -libcares_la-ares_gethostbyname.lo: ares_gethostbyname.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_gethostbyname.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_gethostbyname.Tpo -c -o libcares_la-ares_gethostbyname.lo `test -f 'ares_gethostbyname.c' || echo '$(srcdir)/'`ares_gethostbyname.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_gethostbyname.Tpo $(DEPDIR)/libcares_la-ares_gethostbyname.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_gethostbyname.c' object='libcares_la-ares_gethostbyname.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_gethostbyname.lo `test -f 'ares_gethostbyname.c' || echo '$(srcdir)/'`ares_gethostbyname.c - -libcares_la-ares_getnameinfo.lo: ares_getnameinfo.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getnameinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getnameinfo.Tpo -c -o libcares_la-ares_getnameinfo.lo `test -f 'ares_getnameinfo.c' || echo '$(srcdir)/'`ares_getnameinfo.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getnameinfo.Tpo $(DEPDIR)/libcares_la-ares_getnameinfo.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getnameinfo.c' object='libcares_la-ares_getnameinfo.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getnameinfo.lo `test -f 'ares_getnameinfo.c' || echo '$(srcdir)/'`ares_getnameinfo.c - -libcares_la-ares_getsock.lo: ares_getsock.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getsock.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getsock.Tpo -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getsock.Tpo $(DEPDIR)/libcares_la-ares_getsock.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getsock.c' object='libcares_la-ares_getsock.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c - -libcares_la-ares_init.lo: ares_init.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_init.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_init.Tpo -c -o libcares_la-ares_init.lo `test -f 'ares_init.c' || echo '$(srcdir)/'`ares_init.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_init.Tpo $(DEPDIR)/libcares_la-ares_init.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_init.c' object='libcares_la-ares_init.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_init.lo `test -f 'ares_init.c' || echo '$(srcdir)/'`ares_init.c - -libcares_la-ares_library_init.lo: ares_library_init.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_library_init.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_library_init.Tpo -c -o libcares_la-ares_library_init.lo `test -f 'ares_library_init.c' || echo '$(srcdir)/'`ares_library_init.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_library_init.Tpo $(DEPDIR)/libcares_la-ares_library_init.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_library_init.c' object='libcares_la-ares_library_init.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_library_init.lo `test -f 'ares_library_init.c' || echo '$(srcdir)/'`ares_library_init.c - -libcares_la-ares_llist.lo: ares_llist.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_llist.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_llist.Tpo -c -o libcares_la-ares_llist.lo `test -f 'ares_llist.c' || echo '$(srcdir)/'`ares_llist.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_llist.Tpo $(DEPDIR)/libcares_la-ares_llist.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_llist.c' object='libcares_la-ares_llist.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_llist.lo `test -f 'ares_llist.c' || echo '$(srcdir)/'`ares_llist.c - -libcares_la-ares_mkquery.lo: ares_mkquery.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_mkquery.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_mkquery.Tpo -c -o libcares_la-ares_mkquery.lo `test -f 'ares_mkquery.c' || echo '$(srcdir)/'`ares_mkquery.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_mkquery.Tpo $(DEPDIR)/libcares_la-ares_mkquery.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_mkquery.c' object='libcares_la-ares_mkquery.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_mkquery.lo `test -f 'ares_mkquery.c' || echo '$(srcdir)/'`ares_mkquery.c - -libcares_la-ares_create_query.lo: ares_create_query.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_create_query.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_create_query.Tpo -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_create_query.Tpo $(DEPDIR)/libcares_la-ares_create_query.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_create_query.c' object='libcares_la-ares_create_query.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c - -libcares_la-ares_nowarn.lo: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_nowarn.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_nowarn.Tpo -c -o libcares_la-ares_nowarn.lo `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_nowarn.Tpo $(DEPDIR)/libcares_la-ares_nowarn.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='libcares_la-ares_nowarn.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_nowarn.lo `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c - -libcares_la-ares_options.lo: ares_options.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_options.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_options.Tpo -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_options.Tpo $(DEPDIR)/libcares_la-ares_options.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_options.c' object='libcares_la-ares_options.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c - -libcares_la-ares_parse_a_reply.lo: ares_parse_a_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_a_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_a_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_a_reply.c' object='libcares_la-ares_parse_a_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c - -libcares_la-ares_parse_aaaa_reply.lo: ares_parse_aaaa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_aaaa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_aaaa_reply.c' object='libcares_la-ares_parse_aaaa_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c - -libcares_la-ares_parse_mx_reply.lo: ares_parse_mx_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_mx_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_mx_reply.c' object='libcares_la-ares_parse_mx_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c - -libcares_la-ares_parse_naptr_reply.lo: ares_parse_naptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_naptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_naptr_reply.c' object='libcares_la-ares_parse_naptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c - -libcares_la-ares_parse_ns_reply.lo: ares_parse_ns_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ns_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ns_reply.c' object='libcares_la-ares_parse_ns_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c - -libcares_la-ares_parse_ptr_reply.lo: ares_parse_ptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ptr_reply.c' object='libcares_la-ares_parse_ptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c - -libcares_la-ares_parse_soa_reply.lo: ares_parse_soa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_soa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_soa_reply.c' object='libcares_la-ares_parse_soa_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c - -libcares_la-ares_parse_srv_reply.lo: ares_parse_srv_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_srv_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_srv_reply.c' object='libcares_la-ares_parse_srv_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c - -libcares_la-ares_parse_txt_reply.lo: ares_parse_txt_reply.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_txt_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_txt_reply.c' object='libcares_la-ares_parse_txt_reply.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c - -libcares_la-ares_platform.lo: ares_platform.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_platform.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_platform.Tpo -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_platform.Tpo $(DEPDIR)/libcares_la-ares_platform.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_platform.c' object='libcares_la-ares_platform.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c - -libcares_la-ares_process.lo: ares_process.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_process.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_process.Tpo -c -o libcares_la-ares_process.lo `test -f 'ares_process.c' || echo '$(srcdir)/'`ares_process.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_process.Tpo $(DEPDIR)/libcares_la-ares_process.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_process.c' object='libcares_la-ares_process.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_process.lo `test -f 'ares_process.c' || echo '$(srcdir)/'`ares_process.c - -libcares_la-ares_query.lo: ares_query.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_query.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_query.Tpo -c -o libcares_la-ares_query.lo `test -f 'ares_query.c' || echo '$(srcdir)/'`ares_query.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_query.Tpo $(DEPDIR)/libcares_la-ares_query.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_query.c' object='libcares_la-ares_query.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_query.lo `test -f 'ares_query.c' || echo '$(srcdir)/'`ares_query.c - -libcares_la-ares_search.lo: ares_search.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_search.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_search.Tpo -c -o libcares_la-ares_search.lo `test -f 'ares_search.c' || echo '$(srcdir)/'`ares_search.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_search.Tpo $(DEPDIR)/libcares_la-ares_search.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_search.c' object='libcares_la-ares_search.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_search.lo `test -f 'ares_search.c' || echo '$(srcdir)/'`ares_search.c - -libcares_la-ares_send.lo: ares_send.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_send.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_send.Tpo -c -o libcares_la-ares_send.lo `test -f 'ares_send.c' || echo '$(srcdir)/'`ares_send.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_send.Tpo $(DEPDIR)/libcares_la-ares_send.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_send.c' object='libcares_la-ares_send.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_send.lo `test -f 'ares_send.c' || echo '$(srcdir)/'`ares_send.c - -libcares_la-ares_strcasecmp.lo: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strcasecmp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo $(DEPDIR)/libcares_la-ares_strcasecmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='libcares_la-ares_strcasecmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c - -libcares_la-ares_strdup.lo: ares_strdup.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strdup.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strdup.Tpo -c -o libcares_la-ares_strdup.lo `test -f 'ares_strdup.c' || echo '$(srcdir)/'`ares_strdup.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strdup.Tpo $(DEPDIR)/libcares_la-ares_strdup.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strdup.c' object='libcares_la-ares_strdup.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strdup.lo `test -f 'ares_strdup.c' || echo '$(srcdir)/'`ares_strdup.c - -libcares_la-ares_strerror.lo: ares_strerror.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strerror.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strerror.Tpo -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strerror.Tpo $(DEPDIR)/libcares_la-ares_strerror.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strerror.c' object='libcares_la-ares_strerror.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c - -libcares_la-ares_timeout.lo: ares_timeout.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_timeout.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_timeout.Tpo -c -o libcares_la-ares_timeout.lo `test -f 'ares_timeout.c' || echo '$(srcdir)/'`ares_timeout.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_timeout.Tpo $(DEPDIR)/libcares_la-ares_timeout.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_timeout.c' object='libcares_la-ares_timeout.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_timeout.lo `test -f 'ares_timeout.c' || echo '$(srcdir)/'`ares_timeout.c - -libcares_la-ares_version.lo: ares_version.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_version.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_version.Tpo -c -o libcares_la-ares_version.lo `test -f 'ares_version.c' || echo '$(srcdir)/'`ares_version.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_version.Tpo $(DEPDIR)/libcares_la-ares_version.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_version.c' object='libcares_la-ares_version.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_version.lo `test -f 'ares_version.c' || echo '$(srcdir)/'`ares_version.c - -libcares_la-ares_writev.lo: ares_writev.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_writev.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_writev.Tpo -c -o libcares_la-ares_writev.lo `test -f 'ares_writev.c' || echo '$(srcdir)/'`ares_writev.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_writev.Tpo $(DEPDIR)/libcares_la-ares_writev.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_writev.c' object='libcares_la-ares_writev.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_writev.lo `test -f 'ares_writev.c' || echo '$(srcdir)/'`ares_writev.c - -libcares_la-bitncmp.lo: bitncmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-bitncmp.lo -MD -MP -MF $(DEPDIR)/libcares_la-bitncmp.Tpo -c -o libcares_la-bitncmp.lo `test -f 'bitncmp.c' || echo '$(srcdir)/'`bitncmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-bitncmp.Tpo $(DEPDIR)/libcares_la-bitncmp.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bitncmp.c' object='libcares_la-bitncmp.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-bitncmp.lo `test -f 'bitncmp.c' || echo '$(srcdir)/'`bitncmp.c - -libcares_la-inet_net_pton.lo: inet_net_pton.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-inet_net_pton.lo -MD -MP -MF $(DEPDIR)/libcares_la-inet_net_pton.Tpo -c -o libcares_la-inet_net_pton.lo `test -f 'inet_net_pton.c' || echo '$(srcdir)/'`inet_net_pton.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-inet_net_pton.Tpo $(DEPDIR)/libcares_la-inet_net_pton.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_net_pton.c' object='libcares_la-inet_net_pton.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-inet_net_pton.lo `test -f 'inet_net_pton.c' || echo '$(srcdir)/'`inet_net_pton.c - -libcares_la-inet_ntop.lo: inet_ntop.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-inet_ntop.lo -MD -MP -MF $(DEPDIR)/libcares_la-inet_ntop.Tpo -c -o libcares_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-inet_ntop.Tpo $(DEPDIR)/libcares_la-inet_ntop.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libcares_la-inet_ntop.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c - -libcares_la-windows_port.lo: windows_port.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-windows_port.lo -MD -MP -MF $(DEPDIR)/libcares_la-windows_port.Tpo -c -o libcares_la-windows_port.lo `test -f 'windows_port.c' || echo '$(srcdir)/'`windows_port.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-windows_port.Tpo $(DEPDIR)/libcares_la-windows_port.Plo -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows_port.c' object='libcares_la-windows_port.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-windows_port.lo `test -f 'windows_port.c' || echo '$(srcdir)/'`windows_port.c - -acountry-acountry.o: acountry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-acountry.o -MD -MP -MF $(DEPDIR)/acountry-acountry.Tpo -c -o acountry-acountry.o `test -f 'acountry.c' || echo '$(srcdir)/'`acountry.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-acountry.Tpo $(DEPDIR)/acountry-acountry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acountry.c' object='acountry-acountry.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-acountry.o `test -f 'acountry.c' || echo '$(srcdir)/'`acountry.c - -acountry-acountry.obj: acountry.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-acountry.obj -MD -MP -MF $(DEPDIR)/acountry-acountry.Tpo -c -o acountry-acountry.obj `if test -f 'acountry.c'; then $(CYGPATH_W) 'acountry.c'; else $(CYGPATH_W) '$(srcdir)/acountry.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-acountry.Tpo $(DEPDIR)/acountry-acountry.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acountry.c' object='acountry-acountry.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-acountry.obj `if test -f 'acountry.c'; then $(CYGPATH_W) 'acountry.c'; else $(CYGPATH_W) '$(srcdir)/acountry.c'; fi` - -acountry-ares_getopt.o: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_getopt.o -MD -MP -MF $(DEPDIR)/acountry-ares_getopt.Tpo -c -o acountry-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_getopt.Tpo $(DEPDIR)/acountry-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='acountry-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c - -acountry-ares_getopt.obj: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_getopt.obj -MD -MP -MF $(DEPDIR)/acountry-ares_getopt.Tpo -c -o acountry-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_getopt.Tpo $(DEPDIR)/acountry-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='acountry-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` - -acountry-ares_nowarn.o: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_nowarn.o -MD -MP -MF $(DEPDIR)/acountry-ares_nowarn.Tpo -c -o acountry-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_nowarn.Tpo $(DEPDIR)/acountry-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='acountry-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c - -acountry-ares_nowarn.obj: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_nowarn.obj -MD -MP -MF $(DEPDIR)/acountry-ares_nowarn.Tpo -c -o acountry-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_nowarn.Tpo $(DEPDIR)/acountry-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='acountry-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` - -acountry-ares_strcasecmp.o: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_strcasecmp.o -MD -MP -MF $(DEPDIR)/acountry-ares_strcasecmp.Tpo -c -o acountry-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_strcasecmp.Tpo $(DEPDIR)/acountry-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='acountry-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c - -acountry-ares_strcasecmp.obj: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_strcasecmp.obj -MD -MP -MF $(DEPDIR)/acountry-ares_strcasecmp.Tpo -c -o acountry-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_strcasecmp.Tpo $(DEPDIR)/acountry-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='acountry-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` - -adig-adig.o: adig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-adig.o -MD -MP -MF $(DEPDIR)/adig-adig.Tpo -c -o adig-adig.o `test -f 'adig.c' || echo '$(srcdir)/'`adig.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-adig.Tpo $(DEPDIR)/adig-adig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adig.c' object='adig-adig.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-adig.o `test -f 'adig.c' || echo '$(srcdir)/'`adig.c - -adig-adig.obj: adig.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-adig.obj -MD -MP -MF $(DEPDIR)/adig-adig.Tpo -c -o adig-adig.obj `if test -f 'adig.c'; then $(CYGPATH_W) 'adig.c'; else $(CYGPATH_W) '$(srcdir)/adig.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-adig.Tpo $(DEPDIR)/adig-adig.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adig.c' object='adig-adig.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-adig.obj `if test -f 'adig.c'; then $(CYGPATH_W) 'adig.c'; else $(CYGPATH_W) '$(srcdir)/adig.c'; fi` - -adig-ares_getopt.o: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_getopt.o -MD -MP -MF $(DEPDIR)/adig-ares_getopt.Tpo -c -o adig-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_getopt.Tpo $(DEPDIR)/adig-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='adig-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c - -adig-ares_getopt.obj: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_getopt.obj -MD -MP -MF $(DEPDIR)/adig-ares_getopt.Tpo -c -o adig-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_getopt.Tpo $(DEPDIR)/adig-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='adig-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` - -adig-ares_nowarn.o: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_nowarn.o -MD -MP -MF $(DEPDIR)/adig-ares_nowarn.Tpo -c -o adig-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_nowarn.Tpo $(DEPDIR)/adig-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='adig-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c - -adig-ares_nowarn.obj: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_nowarn.obj -MD -MP -MF $(DEPDIR)/adig-ares_nowarn.Tpo -c -o adig-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_nowarn.Tpo $(DEPDIR)/adig-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='adig-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` - -adig-ares_strcasecmp.o: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_strcasecmp.o -MD -MP -MF $(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o adig-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_strcasecmp.Tpo $(DEPDIR)/adig-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='adig-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c - -adig-ares_strcasecmp.obj: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_strcasecmp.obj -MD -MP -MF $(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o adig-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_strcasecmp.Tpo $(DEPDIR)/adig-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='adig-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` - -ahost-ahost.o: ahost.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ahost.o -MD -MP -MF $(DEPDIR)/ahost-ahost.Tpo -c -o ahost-ahost.o `test -f 'ahost.c' || echo '$(srcdir)/'`ahost.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ahost.Tpo $(DEPDIR)/ahost-ahost.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ahost.c' object='ahost-ahost.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ahost.o `test -f 'ahost.c' || echo '$(srcdir)/'`ahost.c - -ahost-ahost.obj: ahost.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ahost.obj -MD -MP -MF $(DEPDIR)/ahost-ahost.Tpo -c -o ahost-ahost.obj `if test -f 'ahost.c'; then $(CYGPATH_W) 'ahost.c'; else $(CYGPATH_W) '$(srcdir)/ahost.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ahost.Tpo $(DEPDIR)/ahost-ahost.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ahost.c' object='ahost-ahost.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ahost.obj `if test -f 'ahost.c'; then $(CYGPATH_W) 'ahost.c'; else $(CYGPATH_W) '$(srcdir)/ahost.c'; fi` - -ahost-ares_getopt.o: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_getopt.o -MD -MP -MF $(DEPDIR)/ahost-ares_getopt.Tpo -c -o ahost-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_getopt.Tpo $(DEPDIR)/ahost-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='ahost-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c - -ahost-ares_getopt.obj: ares_getopt.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_getopt.obj -MD -MP -MF $(DEPDIR)/ahost-ares_getopt.Tpo -c -o ahost-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_getopt.Tpo $(DEPDIR)/ahost-ares_getopt.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='ahost-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` - -ahost-ares_nowarn.o: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_nowarn.o -MD -MP -MF $(DEPDIR)/ahost-ares_nowarn.Tpo -c -o ahost-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_nowarn.Tpo $(DEPDIR)/ahost-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='ahost-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_nowarn.o `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c - -ahost-ares_nowarn.obj: ares_nowarn.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_nowarn.obj -MD -MP -MF $(DEPDIR)/ahost-ares_nowarn.Tpo -c -o ahost-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_nowarn.Tpo $(DEPDIR)/ahost-ares_nowarn.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='ahost-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_nowarn.obj `if test -f 'ares_nowarn.c'; then $(CYGPATH_W) 'ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/ares_nowarn.c'; fi` - -ahost-ares_strcasecmp.o: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_strcasecmp.o -MD -MP -MF $(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ahost-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_strcasecmp.Tpo $(DEPDIR)/ahost-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='ahost-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_strcasecmp.o `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c - -ahost-ares_strcasecmp.obj: ares_strcasecmp.c -@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_strcasecmp.obj -MD -MP -MF $(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ahost-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_strcasecmp.Tpo $(DEPDIR)/ahost-ares_strcasecmp.Po -@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='ahost-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_strcasecmp.obj `if test -f 'ares_strcasecmp.c'; then $(CYGPATH_W) 'ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/ares_strcasecmp.c'; fi` - mostlyclean-libtool: -rm -f *.lo @@ -1582,49 +455,6 @@ clean-libtool: distclean-libtool: -rm -f libtool config.lt -install-man3: $(man_MANS) - @$(NORMAL_INSTALL) - @list1=''; \ - list2='$(man_MANS)'; \ - test -n "$(man3dir)" \ - && test -n "`echo $$list1$$list2`" \ - || exit 0; \ - echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ - { for i in $$list1; do echo "$$i"; done; \ - if test -n "$$list2"; then \ - for i in $$list2; do echo "$$i"; done \ - | sed -n '/\.3[a-z]*$$/p'; \ - fi; \ - } | while read p; do \ - if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; echo "$$p"; \ - done | \ - sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ - sed 'N;N;s,\n, ,g' | { \ - list=; while read file base inst; do \ - if test "$$base" = "$$inst"; then list="$$list $$file"; else \ - echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ - $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ - fi; \ - done; \ - for i in $$list; do echo "$$i"; done | $(am__base_list) | \ - while read files; do \ - test -z "$$files" || { \ - echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ - $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ - done; } - -uninstall-man3: - @$(NORMAL_UNINSTALL) - @list=''; test -n "$(man3dir)" || exit 0; \ - files=`{ for i in $$list; do echo "$$i"; done; \ - l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ - sed -n '/\.3[a-z]*$$/p'; \ - } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ - -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ - dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) install-pkgconfigDATA: $(pkgconfig_DATA) @$(NORMAL_INSTALL) @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ @@ -1646,27 +476,6 @@ uninstall-pkgconfigDATA: @list='$(pkgconfig_DATA)'; test -n "$(pkgconfigdir)" || list=; \ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ dir='$(DESTDIR)$(pkgconfigdir)'; $(am__uninstall_files_from_dir) -install-libcares_laHEADERS: $(libcares_la_HEADERS) - @$(NORMAL_INSTALL) - @list='$(libcares_la_HEADERS)'; test -n "$(libcares_ladir)" || list=; \ - if test -n "$$list"; then \ - echo " $(MKDIR_P) '$(DESTDIR)$(libcares_ladir)'"; \ - $(MKDIR_P) "$(DESTDIR)$(libcares_ladir)" || exit 1; \ - fi; \ - for p in $$list; do \ - if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - echo "$$d$$p"; \ - done | $(am__base_list) | \ - while read files; do \ - echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libcares_ladir)'"; \ - $(INSTALL_HEADER) $$files "$(DESTDIR)$(libcares_ladir)" || exit $$?; \ - done - -uninstall-libcares_laHEADERS: - @$(NORMAL_UNINSTALL) - @list='$(libcares_la_HEADERS)'; test -n "$(libcares_ladir)" || list=; \ - files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ - dir='$(DESTDIR)$(libcares_ladir)'; $(am__uninstall_files_from_dir) # This directory's subdirectories are mostly independent; you can cd # into them and run 'make' without going through this Makefile. @@ -1774,7 +583,10 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags -rm -f cscope.out cscope.in.out cscope.po.out cscope.files -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -1842,7 +654,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -1857,6 +669,10 @@ dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -1868,7 +684,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -1886,7 +702,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -1896,9 +712,11 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -1967,11 +785,10 @@ distcleancheck: distclean exit 1; } >&2 check-am: all-am check: check-recursive -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) $(HEADERS) \ - ares_config.h ares_build.h +all-am: Makefile $(DATA) installdirs: installdirs-recursive installdirs-am: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(pkgconfigdir)" "$(DESTDIR)$(libcares_ladir)"; do \ + for dir in "$(DESTDIR)$(pkgconfigdir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-recursive @@ -2008,34 +825,33 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-recursive -clean-am: clean-generic clean-libLTLIBRARIES clean-libtool clean-local \ - clean-noinstPROGRAMS mostlyclean-am +clean-am: clean-generic clean-libtool mostlyclean-am distclean: distclean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) -rm -f Makefile -distclean-am: clean-am distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags +distclean-am: clean-am distclean-generic distclean-libtool \ + distclean-tags dvi: dvi-recursive dvi-am: +html: html-recursive + html-am: info: info-recursive info-am: -install-data-am: install-libcares_laHEADERS install-man \ - install-pkgconfigDATA +install-data-am: install-pkgconfigDATA install-dvi: install-dvi-recursive install-dvi-am: -install-exec-am: install-libLTLIBRARIES +install-exec-am: install-html: install-html-recursive @@ -2045,7 +861,7 @@ install-info: install-info-recursive install-info-am: -install-man: install-man3 +install-man: install-pdf: install-pdf-recursive @@ -2060,14 +876,14 @@ installcheck-am: maintainer-clean: maintainer-clean-recursive -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic mostlyclean: mostlyclean-recursive -mostlyclean-am: mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive pdf-am: @@ -2075,72 +891,30 @@ ps: ps-recursive ps-am: -uninstall-am: uninstall-libLTLIBRARIES uninstall-libcares_laHEADERS \ - uninstall-man uninstall-pkgconfigDATA - -uninstall-man: uninstall-man3 +uninstall-am: uninstall-pkgconfigDATA -.MAKE: $(am__recursive_targets) all install-am install-strip +.MAKE: $(am__recursive_targets) install-am install-strip .PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ am--refresh check check-am clean clean-cscope clean-generic \ - clean-libLTLIBRARIES clean-libtool clean-local \ - clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \ + clean-libtool cscope cscopelist-am ctags ctags-am dist \ dist-all dist-bzip2 dist-gzip dist-hook dist-lzip dist-shar \ - dist-tarZ dist-xz dist-zip distcheck distclean \ - distclean-compile distclean-generic distclean-hdr \ - distclean-libtool distclean-tags distcleancheck distdir \ - distuninstallcheck dvi dvi-am html html-am info info-am \ - install install-am install-data install-data-am install-dvi \ - install-dvi-am install-exec install-exec-am install-html \ - install-html-am install-info install-info-am \ - install-libLTLIBRARIES install-libcares_laHEADERS install-man \ - install-man3 install-pdf install-pdf-am install-pkgconfigDATA \ - install-ps install-ps-am install-strip installcheck \ - installcheck-am installdirs installdirs-am maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ + dist-tarZ dist-xz dist-zip dist-zstd distcheck distclean \ + distclean-generic distclean-libtool distclean-tags \ + distcleancheck distdir distuninstallcheck dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-pkgconfigDATA install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs installdirs-am \ + maintainer-clean maintainer-clean-generic mostlyclean \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES \ - uninstall-libcares_laHEADERS uninstall-man uninstall-man3 \ - uninstall-pkgconfigDATA + tags tags-am uninstall uninstall-am uninstall-pkgconfigDATA .PRECIOUS: Makefile -@CODE_COVERAGE_RULES@ - -clean-local: clean-sourced-manpages - -clean-sourced-manpages: - @srcdmandir='$(SOURCEDMANDIR)'; \ - echo "rm -rf $(top_builddir)/$$srcdmandir"; \ - rm -rf $(top_builddir)/$$srcdmandir - -sourced-manpages: clean-sourced-manpages - @srcdmandir='$(SOURCEDMANDIR)'; \ - srcdmanfiles='$(SOURCEDMANPAGES)'; \ - mkdir $(top_builddir)/$$srcdmandir; \ - for file in $$srcdmanfiles; do \ - if test -f $(top_srcdir)/$$file; then \ - echo "cp $(top_srcdir)/$$file $(top_builddir)/$$srcdmandir/$$file"; \ - cp $(top_srcdir)/$$file $(top_builddir)/$$srcdmandir/$$file; \ - fi; \ - done - -html: sourced-manpages $(HTMLPAGES) - -.3.html: - $(MAN2HTML) - -pdf: sourced-manpages $(PDFPAGES) - -.3.pdf: - @(foo=`echo $@ | sed -e 's/\.[0-9]$$//g'`; \ - groff -Tps -man $< >$$foo.ps; \ - ps2pdf $$foo.ps $@; \ - rm $$foo.ps; \ - echo "converted $< to $@") - # Make files named *.dist replace the file without .dist extension dist-hook: find $(distdir) -name "*.dist" -exec rm {} \; diff --git a/Makefile.inc b/Makefile.inc deleted file mode 100644 index 22580b7..0000000 --- a/Makefile.inc +++ /dev/null @@ -1,237 +0,0 @@ - -CSOURCES = ares__close_sockets.c \ - ares__get_hostent.c \ - ares__read_line.c \ - ares__timeval.c \ - ares_cancel.c \ - ares_data.c \ - ares_destroy.c \ - ares_expand_name.c \ - ares_expand_string.c \ - ares_fds.c \ - ares_free_hostent.c \ - ares_free_string.c \ - ares_getenv.c \ - ares_gethostbyaddr.c \ - ares_gethostbyname.c \ - ares_getnameinfo.c \ - ares_getsock.c \ - ares_init.c \ - ares_library_init.c \ - ares_llist.c \ - ares_mkquery.c \ - ares_create_query.c \ - ares_nowarn.c \ - ares_options.c \ - ares_parse_a_reply.c \ - ares_parse_aaaa_reply.c \ - ares_parse_mx_reply.c \ - ares_parse_naptr_reply.c \ - ares_parse_ns_reply.c \ - ares_parse_ptr_reply.c \ - ares_parse_soa_reply.c \ - ares_parse_srv_reply.c \ - ares_parse_txt_reply.c \ - ares_platform.c \ - ares_process.c \ - ares_query.c \ - ares_search.c \ - ares_send.c \ - ares_strcasecmp.c \ - ares_strdup.c \ - ares_strerror.c \ - ares_timeout.c \ - ares_version.c \ - ares_writev.c \ - bitncmp.c \ - inet_net_pton.c \ - inet_ntop.c \ - windows_port.c - -HHEADERS = ares.h \ - ares_build.h \ - ares_data.h \ - ares_dns.h \ - ares_getenv.h \ - ares_inet_net_pton.h \ - ares_iphlpapi.h \ - ares_ipv6.h \ - ares_library_init.h \ - ares_llist.h \ - ares_nowarn.h \ - ares_platform.h \ - ares_private.h \ - ares_rules.h \ - ares_strcasecmp.h \ - ares_strdup.h \ - ares_version.h \ - ares_writev.h \ - bitncmp.h \ - nameser.h \ - ares_setup.h \ - setup_once.h - -MANPAGES = ares_cancel.3 \ - ares_destroy.3 \ - ares_destroy_options.3 \ - ares_dup.3 \ - ares_expand_name.3 \ - ares_expand_string.3 \ - ares_fds.3 \ - ares_free_data.3 \ - ares_free_hostent.3 \ - ares_free_string.3 \ - ares_get_servers.3 \ - ares_get_servers_ports.3 \ - ares_gethostbyaddr.3 \ - ares_gethostbyname.3 \ - ares_gethostbyname_file.3 \ - ares_getnameinfo.3 \ - ares_getsock.3 \ - ares_init.3 \ - ares_init_options.3 \ - ares_library_cleanup.3 \ - ares_library_init.3 \ - ares_mkquery.3 \ - ares_create_query.3 \ - ares_parse_a_reply.3 \ - ares_parse_aaaa_reply.3 \ - ares_parse_mx_reply.3 \ - ares_parse_naptr_reply.3 \ - ares_parse_ns_reply.3 \ - ares_parse_ptr_reply.3 \ - ares_parse_soa_reply.3 \ - ares_parse_srv_reply.3 \ - ares_parse_txt_reply.3 \ - ares_process.3 \ - ares_query.3 \ - ares_save_options.3 \ - ares_search.3 \ - ares_send.3 \ - ares_set_local_dev.3 \ - ares_set_local_ip4.3 \ - ares_set_local_ip6.3 \ - ares_set_servers.3 \ - ares_set_servers_csv.3 \ - ares_set_servers_ports.3 \ - ares_set_servers_ports_csv.3 \ - ares_set_socket_callback.3 \ - ares_set_socket_configure_callback.3 \ - ares_set_sortlist.3 \ - ares_strerror.3 \ - ares_timeout.3 \ - ares_version.3 \ - ares_inet_pton.3 \ - ares_inet_ntop.3 - -HTMLPAGES = ares_cancel.html \ - ares_destroy.html \ - ares_destroy_options.html \ - ares_dup.html \ - ares_expand_name.html \ - ares_expand_string.html \ - ares_fds.html \ - ares_free_data.html \ - ares_free_hostent.html \ - ares_free_string.html \ - ares_get_servers.html \ - ares_get_servers_ports.html \ - ares_gethostbyaddr.html \ - ares_gethostbyname.html \ - ares_gethostbyname_file.html \ - ares_getnameinfo.html \ - ares_getsock.html \ - ares_init.html \ - ares_init_options.html \ - ares_library_cleanup.html \ - ares_library_init.html \ - ares_mkquery.html \ - ares_create_query.html \ - ares_parse_a_reply.html \ - ares_parse_aaaa_reply.html \ - ares_parse_mx_reply.html \ - ares_parse_ns_reply.html \ - ares_parse_ptr_reply.html \ - ares_parse_soa_reply.html \ - ares_parse_srv_reply.html \ - ares_parse_txt_reply.html \ - ares_process.html \ - ares_query.html \ - ares_save_options.html \ - ares_search.html \ - ares_send.html \ - ares_set_local_dev.html \ - ares_set_local_ip4.html \ - ares_set_local_ip6.html \ - ares_set_servers.html \ - ares_set_servers_csv.html \ - ares_set_servers_ports.html \ - ares_set_servers_ports_csv.html \ - ares_set_socket_callback.html \ - ares_set_socket_configure_callback.html \ - ares_set_sortlist.html \ - ares_strerror.html \ - ares_timeout.html \ - ares_version.html \ - ares_inet_pton.html \ - ares_inet_ntop.html - -PDFPAGES = ares_cancel.pdf \ - ares_destroy.pdf \ - ares_destroy_options.pdf \ - ares_dup.pdf \ - ares_expand_name.pdf \ - ares_expand_string.pdf \ - ares_fds.pdf \ - ares_free_data.pdf \ - ares_free_hostent.pdf \ - ares_free_string.pdf \ - ares_get_servers.pdf \ - ares_get_servers_ports.pdf \ - ares_gethostbyaddr.pdf \ - ares_gethostbyname.pdf \ - ares_gethostbyname_file.pdf \ - ares_getnameinfo.pdf \ - ares_getsock.pdf \ - ares_init.pdf \ - ares_init_options.pdf \ - ares_library_cleanup.pdf \ - ares_library_init.pdf \ - ares_mkquery.pdf \ - ares_create_query.pdf \ - ares_parse_a_reply.pdf \ - ares_parse_aaaa_reply.pdf \ - ares_parse_mx_reply.pdf \ - ares_parse_ns_reply.pdf \ - ares_parse_ptr_reply.pdf \ - ares_parse_soa_reply.pdf \ - ares_parse_srv_reply.pdf \ - ares_parse_txt_reply.pdf \ - ares_process.pdf \ - ares_query.pdf \ - ares_save_options.pdf \ - ares_search.pdf \ - ares_send.pdf \ - ares_set_local_dev.pdf \ - ares_set_local_ip4.pdf \ - ares_set_local_ip6.pdf \ - ares_set_servers.pdf \ - ares_set_servers_csv.pdf \ - ares_set_servers_ports.pdf \ - ares_set_servers_ports_csv.pdf \ - ares_set_socket_callback.pdf \ - ares_set_socket_configure_callback.pdf \ - ares_set_sortlist.pdf \ - ares_strerror.pdf \ - ares_timeout.pdf \ - ares_version.pdf \ - ares_inet_pton.pdf \ - ares_inet_ntop.pdf - -SAMPLESOURCES = ares_getopt.c \ - ares_nowarn.c \ - ares_strcasecmp.c - -SAMPLEHEADERS = ares_getopt.h \ - ares_nowarn.h \ - ares_strcasecmp.h diff --git a/Makefile.m32 b/Makefile.m32 index c27a597..e7a423b 100644 --- a/Makefile.m32 +++ b/Makefile.m32 @@ -8,7 +8,7 @@ ######################################################## ## Nothing more to do below this line! -LIB = libcares.a +LIB = src/lib/libcares.a AR = $(CROSSPREFIX)ar CC = $(CROSSPREFIX)gcc @@ -17,15 +17,15 @@ RANLIB = $(CROSSPREFIX)ranlib #RM = rm -f CP = cp -afv -CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I. +CFLAGS = $(CARES_CFLAG_EXTRAS) -O2 -Wall -I./include -I./src/lib -D_WIN32_WINNT=0x0600 CFLAGS += -DCARES_STATICLIB LDFLAGS = $(CARES_LDFLAG_EXTRAS) -s LIBS = -lwsock32 # Makefile.inc provides the CSOURCES and HHEADERS defines -include Makefile.inc +include src/lib/Makefile.inc -OBJLIB := $(patsubst %.c,%.o,$(strip $(CSOURCES))) +OBJLIB := $(patsubst %.c,src/lib/%.o,$(strip $(CSOURCES))) $(LIB): $(OBJLIB) @@ -34,21 +34,21 @@ $(LIB): $(OBJLIB) all: $(LIB) demos -demos: adig.exe ahost.exe acountry.exe +demos: src/tools/adig.exe src/tools/ahost.exe src/tools/acountry.exe tags: etags *.[ch] -%.exe: %.o ares_getopt.o $(LIB) +%.exe: %.o src/tools/ares_getopt.o $(LIB) $(LD) $(LDFLAGS) -o $@ $^ $(LIBS) -$(OBJLIB): ares.h ares_dns.h ares_private.h ares_build.h ares_rules.h +$(OBJLIB): include/ares.h include/ares_dns.h include/ares_build.h .c.o: - $(CC) $(CFLAGS) -c $< + $(CC) $(CFLAGS) -o $@ -c $< -ares_build.h: - $(CP) ares_build.h.dist ares_build.h +include/ares_build.h: + $(CP) include/ares_build.h.dist include/ares_build.h check: @@ -59,18 +59,19 @@ install: ${INSTALL} -m 644 $(LIB) ${DESTDIR}${libdir} ${RANLIB} ${DESTDIR}${libdir}/$(LIB) chmod u-w ${DESTDIR}${libdir}/$(LIB) - ${INSTALL} -m 444 ${srcdir}/ares.h ${DESTDIR}${includedir} - ${INSTALL} -m 444 ${srcdir}/ares_build.h ${DESTDIR}${includedir} - ${INSTALL} -m 444 ${srcdir}/ares_rules.h ${DESTDIR}${includedir} + ${INSTALL} -m 444 ${srcdir}/include/ares.h ${DESTDIR}${includedir} + ${INSTALL} -m 444 ${srcdir}/include/ares_build.h ${DESTDIR}${includedir} + ${INSTALL} -m 444 ${srcdir}/include/ares_rules.h ${DESTDIR}${includedir} + ${INSTALL} -m 444 ${srcdir}/include/ares_version.h ${DESTDIR}${includedir} (for man in $(MANPAGES); do \ ${INSTALL} -m 444 ${srcdir}/$${man} ${DESTDIR}${mandir}/man3; \ done) clean: - $(RM) ares_getopt.o $(OBJLIB) $(LIB) adig.exe ahost.exe acountry.exe + $(RM) src/tools/ares_getopt.o $(OBJLIB) $(LIB) src/tools/adig.exe src/tools/ahost.exe src/tools/acountry.exe distclean: clean $(RM) config.cache config.log config.status Makefile -ifeq "$(wildcard ares_build.h.dist)" "ares_build.h.dist" - $(RM) ares_build.h +ifeq "$(wildcard include/ares_build.h.dist)" "include/ares_build.h.dist" + $(RM) include/ares_build.h endif diff --git a/Makefile.msvc b/Makefile.msvc index e05e317..21d3de6 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -80,18 +80,17 @@ USE_WATT32 = 0 # Verify that current subdir is the c-ares source one # ---------------------------------------------------- -!IF ! EXIST(.\ares_init.c) +!IF ! EXIST(.\src\lib\ares_init.c) ! MESSAGE Can not process Makefile.msvc from outside of c-ares source subdirectory. ! MESSAGE Change to the subdirectory where Makefile.msvc is found, and try again. ! ERROR See previous message. !ENDIF # ------------------------------------------------------------------ -# Base subdir is the common root from which other subdirs will hang, -# the name depends on MSVC version being used when building c-ares. +# Base subdir is the common root from which other subdirs will hang. # ------------------------------------------------------------------ -BASE_DIR = .\$(CC_VERS_STR) +BASE_DIR = .\msvc # ---------------------------------------- # Subdir holding sources for all projects @@ -184,14 +183,14 @@ CFLAGS = /UWIN32 /DWATT32 /I$(WATT_ROOT)\inc EX_LIBS_REL = $(WATT_ROOT)\lib\wattcpvc_imp.lib EX_LIBS_DBG = $(WATT_ROOT)\lib\wattcpvc_imp_d.lib !ELSE -CFLAGS = /DWIN32 +CFLAGS = /DWIN32 /D_WIN32_WINNT=0x0600 EX_LIBS_REL = ws2_32.lib advapi32.lib kernel32.lib EX_LIBS_DBG = ws2_32.lib advapi32.lib kernel32.lib !ENDIF -# ----------------------------------------- -# Switches that depend on compiler version -# ----------------------------------------- +# ------------------------------------------------- +# Switches that depend on ancient compiler versions +# ------------------------------------------------- !IF $(CC_VERS_NUM) == 60 PDB_NONE = /pdb:none @@ -213,7 +212,7 @@ RT_ERROR_CHECKING = /RTCsu CC_CMD_REL = cl.exe /nologo $(RTLIB) /DNDEBUG /O2 CC_CMD_DBG = cl.exe /nologo $(RTLIBD) /D_DEBUG /Od /Zi $(RT_ERROR_CHECKING) -CC_CFLAGS = $(CFLAGS) /I. /W3 /EHsc /FD +CC_CFLAGS = $(CFLAGS) /I.\src\lib /I.\include /W3 /EHsc /FD RC_CMD_REL = rc.exe /l 0x409 /d "NDEBUG" RC_CMD_DBG = rc.exe /l 0x409 /d "_DEBUG" @@ -281,7 +280,8 @@ RC_CMD = $(RC_CMD_DBG) # Makefile.inc provides lists of source files # -------------------------------------------- -!INCLUDE .\Makefile.inc +!INCLUDE .\src\lib\Makefile.inc +!INCLUDE .\src\tools\Makefile.inc # ---------------------------- # Build lists of object files @@ -309,6 +309,7 @@ CARES_OBJS = $(CARES_OBJS) $(CARES_OBJDIR)\cares.res !ERROR Problem generating PROG1_OBJS list. !ENDIF PROG1_OBJS = $(PROG1_OBJS:.c=.obj) +PROG1_OBJS = $(PROG1_OBJS:/=\) PROG1_OBJS = $(PROG1_OBJS) $(PROG1_OBJDIR)\acountry.obj !IF [ECHO PROG2_OBJS=^$(PROG2_OBJDIR)\$(SAMPLESOURCES: = $(PROG2_OBJDIR^)\) > .\prog2_objs.inc] == 0 @@ -319,6 +320,7 @@ PROG1_OBJS = $(PROG1_OBJS) $(PROG1_OBJDIR)\acountry.obj !ERROR Problem generating PROG2_OBJS list. !ENDIF PROG2_OBJS = $(PROG2_OBJS:.c=.obj) +PROG2_OBJS = $(PROG2_OBJS:/=\) PROG2_OBJS = $(PROG2_OBJS) $(PROG2_OBJDIR)\adig.obj !IF [ECHO PROG3_OBJS=^$(PROG3_OBJDIR)\$(SAMPLESOURCES: = $(PROG3_OBJDIR^)\) > .\prog3_objs.inc] == 0 @@ -329,10 +331,12 @@ PROG2_OBJS = $(PROG2_OBJS) $(PROG2_OBJDIR)\adig.obj !ERROR Problem generating PROG3_OBJS list. !ENDIF PROG3_OBJS = $(PROG3_OBJS:.c=.obj) +PROG3_OBJS = $(PROG3_OBJS:/=\) PROG3_OBJS = $(PROG3_OBJS) $(PROG3_OBJDIR)\ahost.obj !ENDIF + # -------------------------------- # Only our custom inference rules # -------------------------------- @@ -340,21 +344,33 @@ PROG3_OBJS = $(PROG3_OBJS) $(PROG3_OBJDIR)\ahost.obj .SUFFIXES: .SUFFIXES: .c .rc -{$(SRCDIR)}.rc{$(CARES_OBJDIR)}.res: +{$(SRCDIR)\src\lib}.rc{$(CARES_OBJDIR)}.res: $(RC_CMD) /Fo $@ $< -{$(SRCDIR)}.c{$(CARES_OBJDIR)}.obj: +{$(SRCDIR)\src\lib}.c{$(CARES_OBJDIR)}.obj: $(CC_CMD) $(CC_CFLAGS) $(CARES_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< -{$(SRCDIR)}.c{$(PROG1_OBJDIR)}.obj: +{$(SRCDIR)\src\tools}.c{$(PROG1_OBJDIR)}.obj: $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< -{$(SRCDIR)}.c{$(PROG2_OBJDIR)}.obj: +{$(SRCDIR)\src\tools}.c{$(PROG2_OBJDIR)}.obj: $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< -{$(SRCDIR)}.c{$(PROG3_OBJDIR)}.obj: +{$(SRCDIR)\src\tools}.c{$(PROG3_OBJDIR)}.obj: $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< +# Hack Alert! we reference ../lib/ files in the Makefile.inc for tools as they +# share some files with the library itself. We need to hack around that here. + +{$(SRCDIR)\src\lib}.c{$(PROG1_OBJDIR)\..\lib}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG1_OBJDIR)\$(@F) /Fd$(PROG1_OBJDIR)\ /c $< + +{$(SRCDIR)\src\lib}.c{$(PROG2_OBJDIR)\..\lib}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG2_OBJDIR)\$(@F) /Fd$(PROG2_OBJDIR)\ /c $< + +{$(SRCDIR)\src\lib}.c{$(PROG3_OBJDIR)\..\lib}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$(PROG3_OBJDIR)\$(@F) /Fd$(PROG3_OBJDIR)\ /c $< + # ------------------------------------------------------------- # # ------------------------------------------------------------- # # Default target when no CFG library type has been specified, # @@ -365,10 +381,10 @@ PROG3_OBJS = $(PROG3_OBJS) $(PROG3_OBJDIR)\ahost.obj !IF "$(VALID_CFGSET)" == "FALSE" ALL: - $(MAKE) /f .\Makefile.msvc CFG=lib-release ALL - $(MAKE) /f .\Makefile.msvc CFG=lib-debug ALL - $(MAKE) /f .\Makefile.msvc CFG=dll-release ALL - $(MAKE) /f .\Makefile.msvc CFG=dll-debug ALL + $(MAKE) /NOLOGO /f .\Makefile.msvc CFG=lib-release ALL + $(MAKE) /NOLOGO /f .\Makefile.msvc CFG=lib-debug ALL + $(MAKE) /NOLOGO /f .\Makefile.msvc CFG=dll-release ALL + $(MAKE) /NOLOGO /f .\Makefile.msvc CFG=dll-debug ALL clean: @-RMDIR /S /Q $(BASE_DIR) >NUL 2>&1 @@ -390,22 +406,26 @@ install: ALL: c-ares acountry adig ahost @ -c-ares: $(HHEADERS) $(CSOURCES) $(CARES_OBJDIR) $(CARES_OBJS) $(CARES_OUTDIR) +# $(HHEADERS) $(CSOURCES) +c-ares: $(CARES_OBJDIR) $(CARES_OBJS) $(CARES_OUTDIR) $(CARES_LINK) $(CARES_LFLAGS) /out:$(CARES_OUTDIR)\$(CARES_TARGET) $(CARES_OBJS) ! IF "$(USE_RES_FILE)" == "TRUE" @if exist $(CARES_OUTDIR)\$(CARES_TARGET).manifest mt -nologo -manifest $(CARES_OUTDIR)\$(CARES_TARGET).manifest -outputresource:$(CARES_OUTDIR)\$(CARES_TARGET);2 ! ENDIF -acountry: c-ares acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) $(PROG1_OBJDIR) $(PROG1_OBJS) $(PROG1_OUTDIR) - $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG1_OUTDIR)\acountry.exe $(PROG1_OBJS) +# acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +acountry: c-ares $(PROG1_OBJDIR) $(PROG1_OBJS) $(PROG1_OUTDIR) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG1_OUTDIR)\acountry.exe $(PROG1_OBJS:..\lib=) @if exist $(PROG1_OUTDIR)\acountry.exe.manifest mt -nologo -manifest $(PROG1_OUTDIR)\acountry.exe.manifest -outputresource:$(PROG1_OUTDIR)\acountry.exe;1 -adig: c-ares adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) $(PROG2_OBJDIR) $(PROG2_OBJS) $(PROG2_OUTDIR) - $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG2_OUTDIR)\adig.exe $(PROG2_OBJS) +# adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +adig: c-ares $(PROG2_OBJDIR) $(PROG2_OBJS) $(PROG2_OUTDIR) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG2_OUTDIR)\adig.exe $(PROG2_OBJS:..\lib=) @if exist $(PROG2_OUTDIR)\adig.exe.manifest mt -nologo -manifest $(PROG2_OUTDIR)\adig.exe.manifest -outputresource:$(PROG2_OUTDIR)\adig.exe;1 -ahost: c-ares ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) $(PROG3_OBJDIR) $(PROG3_OBJS) $(PROG3_OUTDIR) - $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG3_OUTDIR)\ahost.exe $(PROG3_OBJS) +# ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +ahost: c-ares $(PROG3_OBJDIR) $(PROG3_OBJS) $(PROG3_OUTDIR) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG3_OUTDIR)\ahost.exe $(PROG3_OBJS:..\lib=) @if exist $(PROG3_OUTDIR)\ahost.exe.manifest mt -nologo -manifest $(PROG3_OUTDIR)\ahost.exe.manifest -outputresource:$(PROG3_OUTDIR)\ahost.exe;1 $(CARES_OUTDIR): $(CARES_DIR) @@ -444,11 +464,11 @@ install: @if not exist "$(INSTALL_DIR)" mkdir "$(INSTALL_DIR)" @if not exist "$(INSTALL_DIR_LIB)" mkdir "$(INSTALL_DIR_LIB)" @if not exist "$(INSTALL_DIR_INC)" mkdir "$(INSTALL_DIR_INC)" - @copy /y $(CARES_OUTDIR)\*.* "$(INSTALL_DIR_LIB)" >NUL - @copy /y $(SRCDIR)\ares.h "$(INSTALL_DIR_INC)" >NUL - @copy /y $(SRCDIR)\ares_build.h "$(INSTALL_DIR_INC)" >NUL - @copy /y $(SRCDIR)\ares_rules.h "$(INSTALL_DIR_INC)" >NUL - @copy /y $(SRCDIR)\ares_version.h "$(INSTALL_DIR_INC)" >NUL + @copy /y $(CARES_OUTDIR)\*.* "$(INSTALL_DIR_LIB)" >NUL + @copy /y $(SRCDIR)\include\ares.h "$(INSTALL_DIR_INC)" >NUL + @copy /y $(SRCDIR)\include\ares_build.h "$(INSTALL_DIR_INC)" >NUL + @copy /y $(SRCDIR)\include\ares_rules.h "$(INSTALL_DIR_INC)" >NUL + @copy /y $(SRCDIR)\include\ares_version.h "$(INSTALL_DIR_INC)" >NUL @echo Installed c-ares $(CFG) !ENDIF diff --git a/Makefile.netware b/Makefile.netware index fa8f831..e1a8a55 100644 --- a/Makefile.netware +++ b/Makefile.netware @@ -34,7 +34,7 @@ ifndef LIBARCH LIBARCH = LIBC endif -# must be equal to NDEBUG or DEBUG, CURLDEBUG +# must be equal to NDEBUG or DEBUG ifndef DB DB = NDEBUG endif @@ -134,9 +134,7 @@ else # INCLUDES += -I$(SDK_CLIB)/include/nlm/obsolete # INCLUDES += -I$(SDK_CLIB)/include endif -ifeq ($(DB),CURLDEBUG) -INCLUDES += -I../include -endif + CFLAGS += -I. $(INCLUDES) ifeq ($(MTSAFE),YES) diff --git a/README.md b/README.md index fdf3a71..148338f 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,11 @@ c-ares ====== [![Build Status](https://travis-ci.org/c-ares/c-ares.svg?branch=master)](https://travis-ci.org/c-ares/c-ares) -[![Windows Build Status](https://ci.appveyor.com/api/projects/status/03i7151772eq3wn3/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares) +[![Windows Build Status](https://ci.appveyor.com/api/projects/status/aevgc5914tm72pvs/branch/master?svg=true)](https://ci.appveyor.com/project/c-ares/c-ares/branch/master) [![Coverage Status](https://coveralls.io/repos/c-ares/c-ares/badge.svg?branch=master&service=github)](https://coveralls.io/github/c-ares/c-ares?branch=master) [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/291/badge)](https://bestpractices.coreinfrastructure.org/projects/291) +[![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/c-ares.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:c-ares) +[![Releases](https://coderelease.io/badge/c-ares/c-ares)](https://coderelease.io/github/repository/c-ares/c-ares) This is c-ares, an asynchronous resolver library. It is intended for applications which need to perform DNS queries without blocking, or need to @@ -12,8 +14,9 @@ perform multiple DNS queries in parallel. The primary examples of such applications are servers which communicate with multiple clients and programs with graphical user interfaces. -The full source code is available in the 'c-ares' release archives, and in a -git repository: http://github.com/c-ares/c-ares +The full source code is available in the ['c-ares' release archives](https://c-ares.haxx.se/download/), +and in a git repository: http://github.com/c-ares/c-ares. See the +[INSTALL.md](INSTALL.md) file for build information. If you find bugs, correct flaws, have questions or have comments in general in regard to c-ares (or by all means the original ares too), get in touch with us diff --git a/README.msvc b/README.msvc index 4ff8700..396f497 100644 --- a/README.msvc +++ b/README.msvc @@ -1,6 +1,6 @@ - ___ __ _ _ __ ___ ___ + ___ __ _ _ __ ___ ___ / __| ___ / _` | '__/ _ \/ __| | (_ |___| (_| | | | __/\__ \ \___| \__,_|_| \___||___/ @@ -64,46 +64,6 @@ to c-ares source folder where Makefile.msvc file is located. - How to build using Visual Studio 6 IDE - -------------------------------------- - - A VC++ 6.0 reference workspace (vc6aws.dsw) is available within the 'vc' - folder to allow proper building of the library and sample programs. - - 1) Open the vc6aws.dsw workspace with MSVC6's IDE. - 2) Select 'Build' from top menu. - 3) Select 'Batch Build' from dropdown menu. - 4) Make sure that the sixteen project configurations are 'checked'. - 5) Click on the 'Build' button. - 6) Once the sixteen project configurations are built you are done. - - Dynamic and static c-ares libraries are built in debug and release flavours, - and can be located each one in its own subdirectory, dll-debug, dll-release, - lib-debug and lib-release, all of them below the 'vc\cares' subdirectory. - - In the same way four executable versions of each sample program are built, - each using its respective library. The resulting sample executables are - located in its own subdirectory, dll-debug, dll-release, lib-debug and - lib-release, below the 'vc\acountry', 'vc\adig' and 'vc\ahost'folders. - - These reference VC++ 6.0 configurations are generated using the dynamic CRT. - - - How to build using Visual Studio 2003 or newer IDE - -------------------------------------------------- - - First you have to convert the VC++ 6.0 reference workspace and project files - to the Visual Studio IDE version you are using, following next steps: - - 1) Open vc\vc6aws.dsw with VS20XX. - 2) Allow VS20XX to update all projects and workspaces. - 3) Save ALL and close VS20XX. - 4) Open vc\vc6aws.sln with VS20XX. - 5) Select batch build, check 'all' projects and click 'build' button. - - Same comments relative to generated files and folders as done above for - Visual Studio 6 IDE apply here. - Relationship between c-ares library file names and versions ----------------------------------------------------------- @@ -139,4 +99,4 @@ Have Fun! - + diff --git a/RELEASE-NOTES b/RELEASE-NOTES index dffb023..5128c93 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,46 +1,69 @@ -c-ares version 1.12.0 +c-ares version 1.17.1 + +Due to a packaging issue with 1.17.0, we have released 1.17.1 to address that +issue. See 1.17.0 release notes below.. + + +c-ares version 1.17.0 + +Security: + o avoid read-heap-buffer-overflow in ares_parse_soa_reply found during + fuzzing [2] [3] + o Avoid theoretical buffer overflow in RC4 loop comparison [5] + o Empty hquery->name could lead to invalid memory access [15] + o ares_parse_{a,aaaa}_reply() could return a larger *naddrttls than was + passed in [17] Changes: + o Update help information for adig, acountry, and ahost [4] + o Test Suite now uses dynamic system-assigned ports rather than hardcoded + ports to prevent failures in containers [10] + o Detect remote DNS server does not support EDNS using rules from RFC 6891 [12] + o Source tree has been reorganized to use a more modern layout [13] + o Allow parsing of CAA Resource Record [14] - o api: add ARES_OPT_NOROTATE optmask value - Bug fixes: + o readaddrinfo bad sizeof() [1] + o Test cases should honor HAVE_WRITEV flag, not depend on WIN32 [6] + o FQDN with trailing period should be queried first [7] + o ares_getaddrinfo() was returning members of the struct as garbage values if + unset, and was not honoring ai_socktype and ai_protocol hints. [8] [9] + o ares_gethostbyname() with AF_UNSPEC and an ip address would fail [11] + o Properly document ares_set_local_ip4() uses host byte order [16] - o CVE-2016-5180: ares_create_query single byte out of buffer write [4] - o configure: acknowledge --disable-tests [1] - o man pages: fix typos detected by Lintian - o test: add missing #includes for dns-proto.cc - o test: avoid in6addr_* constants - o test: Build with MinGW on AppVeyor - o Makefile.m32: add support for extra flags - o Makefile.m32: add support for CROSSPREFIX - o configure: check if tests can get built before enabled - o ares_library_cleanup: reset ares_realloc too - o ahost.c: add cast to fix C++ compile - o test: Only pass unused args to GoogleTest - o build: commonize MSVC version detection - o msvc_ver.inc: support Visual Studio 2015 Update 1, 2, 3 - o test: for AF_UNSPEC, return CNAME only for AAAA, but valid A record - o ares_getnameinfo: explicitly clear struct servent before use - o test: Update fuzzing function prototype - o init: fix nsort initialization - o test: add fuzzing check script to tests - o web: http => https - o read_tcp_data: remove superfluous NULL check - o LICENSE.md: add a stand-alone license file - o SECURITY.md: suggested "security process" for the project - o ares_init_options: only propagate init failures from options [2] - o headers: remove checks for and defines of variable sizes - o test: fix gMock to work with gcc >= 6.x [3] - Thanks go to these friendly people for their efforts and contributions: - - Alexander Drachevskiy, Brad House, Chris Araman, Daniel Stenberg, - David Drysdale, Gregor Jasny, Svante Karlsson, Viktor Szakats + @anonymoushelpishere + Anthony Penniston (@apenn-msft) + Brad House (@bradh352) + Bulat Gaifullin (@bgaifullin) + Daniela Sonnenschein (@lxdicted) + Daniel Stenberg (@bagder) + David Hotham (@dimbleby) + Fionn Fitzmaurice (@fionn) + Gisle Vanem (@gavenm) + Ivan Baidakou (@basiliscos) + Jonathan Maye-Hobbs (@wheelpharoah) + Łukasz Marszał (@lmarszal) + lutianxiong (@ltx2018) + Seraphime Kirkovski (@Seraphime) +(14 contributors) References to bug reports and discussions on issues: + [1] = https://github.com/c-ares/c-ares/pull/331 + [2] = https://github.com/c-ares/c-ares/pull/332 + [3] = https://github.com/c-ares/c-ares/issues/333 + [4] = https://github.com/c-ares/c-ares/pull/334 + [5] = https://github.com/c-ares/c-ares/pull/336 + [6] = https://github.com/c-ares/c-ares/pull/344 + [7] = https://github.com/c-ares/c-ares/pull/345 + [8] = https://github.com/c-ares/c-ares/issues/343 + [9] = https://github.com/c-ares/c-ares/issues/317 + [10] = https://github.com/c-ares/c-ares/pull/346 + [11] = https://github.com/c-ares/c-ares/pull/204 + [12] = https://github.com/c-ares/c-ares/pull/244 + [13] = https://github.com/c-ares/c-ares/pull/349 + [14] = https://github.com/c-ares/c-ares/pull/360 + [15] = https://github.com/c-ares/c-ares/pull/367 + [16] = https://github.com/c-ares/c-ares/pull/368 + [17] = https://github.com/c-ares/c-ares/issues/371 - [1] = https://github.com/c-ares/c-ares/issues/44 - [2] = https://github.com/c-ares/c-ares/issues/60 - [3] = https://github.com/google/googletest/issues/705#issuecomment-235067917 - [4] = https://c-ares.haxx.se/adv_20160929.html diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..3f2a457 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,100 @@ +c-ares security +=============== + +This document is intended to provide guidance on how security vulnerabilities +should be handled in the c-ares project. + +Publishing Information +---------------------- + +All known and public c-ares vulnerabilities will be listed on [the c-ares web +site](https://c-ares.haxx.se/vulns.html). + +Security vulnerabilities should not be entered in the project's public bug +tracker unless the necessary configuration is in place to limit access to the +issue to only the reporter and the project's security team. + +Vulnerability Handling +---------------------- + +The typical process for handling a new security vulnerability is as follows. + +No information should be made public about a vulnerability until it is +formally announced at the end of this process. That means, for example that a +bug tracker entry must NOT be created to track the issue since that will make +the issue public and it should not be discussed on the project's public +mailing list. Also messages associated with any commits should not make any +reference to the security nature of the commit if done prior to the public +announcement. + +- The person discovering the issue, the reporter, reports the vulnerability + privately to `c-ares-security@haxx.se`. That's an email alias that reaches a + handful of selected and trusted people. + +- Messages that do not relate to the reporting or managing of an undisclosed + security vulnerability in c-ares are ignored and no further action is + required. + +- A person in the security team sends an e-mail to the original reporter to + acknowledge the report. + +- The security team investigates the report and either rejects it or accepts + it. + +- If the report is rejected, the team writes to the reporter to explain why. + +- If the report is accepted, the team writes to the reporter to let him/her + know it is accepted and that they are working on a fix. + +- The security team discusses the problem, works out a fix, considers the + impact of the problem and suggests a release schedule. This discussion + should involve the reporter as much as possible. + +- The release of the information should be "as soon as possible" and is most + often synced with an upcoming release that contains the fix. If the + reporter, or anyone else, thinks the next planned release is too far away + then a separate earlier release for security reasons should be considered. + +- Write a security advisory draft about the problem that explains what the + problem is, its impact, which versions it affects, solutions or + workarounds, when the release is out and make sure to credit all + contributors properly. + +- Request a CVE number from + [distros@openwall](http://oss-security.openwall.org/wiki/mailing-lists/distros) + when also informing and preparing them for the upcoming public security + vulnerability announcement - attach the advisory draft for information. Note + that 'distros' won't accept an embargo longer than 19 days. + +- Update the "security advisory" with the CVE number. + +- The security team commits the fix in a private branch. The commit message + should ideally contain the CVE number. This fix is usually also distributed + to the 'distros' mailing list to allow them to use the fix prior to the + public announcement. + +- At the day of the next release, the private branch is merged into the master + branch and pushed. Once pushed, the information is accessible to the public + and the actual release should follow suit immediately afterwards. + +- The project team creates a release that includes the fix. + +- The project team announces the release and the vulnerability to the world in + the same manner we always announce releases. It gets sent to the c-ares + mailing list and the oss-security mailing list. + +- The security web page on the web site should get the new vulnerability + mentioned. + +C-ARES-SECURITY (at haxx dot se) +-------------------------------- + +Who is on this list? There are a couple of criteria you must meet, and then we +might ask you to join the list or you can ask to join it. It really isn't very +formal. We basically only require that you have a long-term presence in the +c-ares project and you have shown an understanding for the project and its way +of working. You must've been around for a good while and you should have no +plans in vanishing in the near future. + +We do not make the list of partipants public mostly because it tends to vary +somewhat over time and a list somewhere will only risk getting outdated. diff --git a/aclocal.m4 b/aclocal.m4 index a35aab8..8ddf2f7 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.2 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.16.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.16.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -346,49 +345,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -397,18 +390,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -495,8 +487,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -563,7 +555,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -605,7 +597,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +618,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -648,7 +640,7 @@ AC_SUBST([am__leading_dot])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -683,7 +675,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -691,49 +683,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -772,7 +757,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -801,7 +786,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -848,7 +833,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -867,7 +852,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -948,7 +933,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1008,7 +993,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1036,7 +1021,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1055,7 +1040,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/ares_cancel.pdf b/ares_cancel.pdf deleted file mode 100644 index 783b2d6bde6b8a3fc07ebcbda9a231736c42d381..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15981 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 diff --git a/ares_create_query.pdf b/ares_create_query.pdf deleted file mode 100644 index 9f5fe02994c1a3a2e90542eb95c74c2145a1e50d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21150 zcmbrk1yr2N5-y6nOK^7`+=9EiTd=`hgF6Iw2o?zL1c%^G2<~oy;O_n)JK1NSbI-Z! zt@qZfnZN(;uIlcp>h7vr)hR#4yps}3^ke?sU$=MNTXan~?BVTjgc2OL|dsYKsEL1U=I~C{1 zMoG{?bt*WeCmtL^-cWH<(ugb$E`@7^GcRkx_n?(^NmNQIybC#5^sHk0lV=DKOl}6# zL+P``;`q5vOj$T8S?PEvss@(SBVZvO%c-%mpXlfJIG+%71r)%SBBIz^S7$p}+rpaA z^Tl10A@0J++di+m6OSPr;1X>!&Ag;Zb$XFCqUpPn4?DQX{9y!%A{NRjG`vuNKmhVStnDRy0|ge>F9 zSu5(#>h~WUagxv0MJUdx&XBoB>zm7B$;rjyD>x>C;2|kR_4P+Tv{^C#1ce~x&DD+$ zE*D?~R^$-&z>%aa<+s6^UtQh(oIWtBCrbV*7Hskmn>St%PH_uqoV)+-RNgS*c56U# zA|7A#VdO*h3`N+Cp}Y^ifXH=@zyFp}^HFqMhz@rVRAI$;QSV0tKw5^7ggYKm#a9{s@e0z;N-puy)L=+1CIj{vRmXDUS=3vMGJR!>KKWveg^!v$owu`YbFAq@&s9@-4M>4 zzGcf{{+uvFU^;chV$&Xho#no|NZQ`yd_=?xqfr@-{f|D563dSalS0kbmO3IZFqYn& zVD;;Tp|mS}7~i%*(K7hRLDbAyA5(vHXn)!nUjDv&@Nl&;{jl-#ZgXdN))8AtFt~r8 zhfF8ZFgrVPNl~Pz&7q&;ZgS3Eqw*BgMa(!@g(S#m5;&YdJ`tn>^1~V7{A1#Na)6|W zkZP6xmdfHekEiZ@;K?_}A;Uo#;vCQ`NW=xvXeNIPkwg0C{Sn&YD!(bBPG>H4=&YDM zi;oTwRv0kYuFY+li3FIedrXXJf($ayUz1&;v7up^kN2Bp&~sKOX;fJ#xAUl-1~N=! zsuSGfdre80Ia?ZGu^d%mtwSMUIn${~C$a5jC?=h@lw_RQ3OEuzGd$|*Kr~p$zA?OL z0|CnJPt}gde!-^jug>zeLID+B#N8V8fK|_vscTn>Mo_;#23$_n|+Uf)D z22amt&vWK7Rn17whMl0JDj8aNHOhbwyvi|pq1J`)_;x>XC5h#FUIGprnjVmRh7%=-dDP0CcNl_&oGb1fP6x~obW8ILqIhlbe2 z*ZPd$W`5_#H|W?!DW4z1G2(OdkWreyG z9W{dJmaqdA*Xb>rI>Sgg0|s5%DT@5m0<&qbj<)>qs0li<(U0DZ$D{a`Qd~Y!n}lJG zWoV$>eqN~TdEyb!g8Qfn+{T{4kDhX^g;~6&nshZ3hN|JswYra7zQ99eB zs6vDbFxKS!>Kr(#J1W+E-ejDE@Z=ssCClugF}NRvB8KZA4oxkE*VCmT^UJrl&Kz7; zp35W`_{byf`D*XWZFwN|Rh6cq%vUp6#*;Oh(%P`Q4KYffFn!$1SCEQEH6}?!YL9Rz zIp@+dS?sDdm}A`#XJRte2^6u14fTx^AJ6;GTo{%pnkr~e5Nm^}Mo9DMSw6&4zXv!*T`Gr^&8#5@vOKw)a zsjJw%9Gy{W=d!BaCK7`SLeq2xa?Uqp;dq2ak{>npU-|G;6`9m+AtI?QMWJ^G+QQMvS;XAX zk(iAMAZz%$%*@6N(6BIZHh0n?W@Tml^?jYo?+@HxPj;riYyPzSdH(M4|F!*v^9zSp z{;yv)HnzW?ESy}w%1p$srN7!S|EXyu1tl?6@!y&jwzD?*KlJ>|R{y)6Sy}#} zXO_S949CL$w?zIWo4-r1tuK=NpR!`-e5L;N`_kuC8yp;*zn*`}ukD;Kn))OA*LLm~ zUA(rx)WdNwzfSs>9@#nmjrtemORs;;??o@a?c=v~yioko>x-@a(*Mi*U-rTNQeq`oURCo)NUxk6Pwf z>=*w3+|sYJ`8Vagy#H3-@6xN;{GRjQ>-n|re{Ap9_Fu;H^8CZ`kBnYN{O_MXtNPzP ze$)L=4!>mf50fEgd8PQDhs3Ye|DT5hD>uNw#qK5Ew=gqzemOFj0Hzjj%r91AV`1y! z^v}cNU)STm&Vqkk2fyr5-q7adB>Nv%hw#fSufy;%0x<*2%f0j}Uk+|oy;qpQ%!!x{ z4j|-Y{Cd;BRK8r&hW3)c*D3w=`Z~^Q+bbm;;II2g$kxpI#X*1rs5k>{)QOpyxZnVC z7EVqthwHEF=GA850Ghwqu(7=~zurwR9s@PN5MTr_2ABYV0MnNv5?}_f09XO60X6_z zfIYze)#I=RnmYeg`Xw2F1HcjB1aJm8n>zx502hFZtqIW4$=J>j2zU>02YAr@62J>| z0%Rp-{)MCb9$UbwhznWP8yFs+v6v8aRJHY$XfVQ@N*saiXI_Nu z*+rU))z(d{Rs6T$E2DAqBs?>Fu8uKr}X^)mQ)wI+YB-&hU%p>paUbM5gvRdYHNTF-<>I;>yM0e`j!zTBTvkhxzk=xJ*@8=tT zgK)-c=!Sj6{kU~_+w4Y_dyVB}*9}*Co~>@ARk}u<1DL~=6@)|Ruw-2yD#?eLAY$oT zyGuJ6INTS|#U}!3Y!|1S{1|@OAEq#F3QUtjcE&dq@yX3`%OksZ)MKn8u<;`gvDn;K z$hD0v)hb8&8i8sLl_UsS>s1>RGnZsV(XK&h#X7w}k5}P$`?Qmb)P$_4bG~YRUoWz3 zZ2``ui!|F6vvxnJl^fO^{l+&|*!g*Q-L=s#0X#!JWjcBVwZ>3!2)7!NRuFeisrqT| z(?KFxfU{qU)Z=r0QrOSk{RGZ+s8CfMj zZN{5F0Sv_C6R~XOLRJ=@V3kN1Ct*PKsdssv4ZtSsR!B+XR+4Q6%SSCuyDzSDll$jC4eYl|QK6ttzjtzI`% zuhtzW5xQ&}ioCWCl__g8z@CV5oXgB}>FuKUhIF=G9rA~dkG-uW$>ca}N>$Gep9gyP z>}GKVKluj}t|`v(;YHnU8zZK7@ZFp{ z(jh{?T51}>os4Qr%YsVbt+Mb{k4?>qQ^l)!@SfespJ0mNW^my#`LH8TMVlj`dmNkI(Q~QZKA%Bq9P(9bP-=iguWXjPfvq{CE3B*Bq4y#5Q6gnh&386dSu}2q3;#5% zP7HYHBu`2UXc^xqz63$>5abO>xL}A>y{J%fxG>Iew-s~jTmNxtnO*6`#$!1r5MNV1 z!p6S((P*$|=7hHgv^AMu3A5nk8eEbidtgmxUL?xN)evms&cG zT%X)L?mDs_%I6O8@`psg=2v^&d(M-AKpZsnu6g?WE^`)K83@Zvq&297ems1CsqJ;s zF13Ao9;-;kEB@T+5|;z1Ma*z*SZ27>X9d*`Awr6*1wk&Vnn~M_($_)k z5Q%!S*F35m+Q1~%CjFeLx;g{#9aI7W?xI*Z0dY>wwIQBQTS5)F7Ch#&!#gbPjuk&6 z^89#OhP97=EBTj2t=cJ|Ys&e`%BYGLqI*^q?}&Lw5BUNUmdy#9pHT9N4M3c0^*nh* z)NSa#;TFb4WQle*jiPJLS`*TtfVZmIpy?oT^7NSsUJZs9q;1?>kJcKkr1pVnsks5)zyT&jV4;kjLwO_M)O)>mU`0xIrw$P zD$bY4M=~Rw5C=Pb-I8_#@*9>A?(I(lRlKHv>9sTNy$&suSZE|y8+;MoSa=Nad}Zwn zhT4wfvLc)`Ulq| z9rHFKu?b&be*Vv}Xpo15oSN%T7Xr;5Q9DQ6la5epHc?P@^R~?UFu4n+5Inj&8g*GP zkP4B6`!eFC<7l<`Ac>0R^7Ab{!EEDV8 z^1|7)este?O5=xpBs0RiGfu8^<#_cs|J(-b6H+hvN|C_vUUMW0F?H$iz5xxL9}De) zG>K?xN+F_VhpV}q10WTwQ&a4hU32^c#0x~BM0)H4CnIReb>l z9kuAe_Vqhk$C;T7Ql4dd7Z{_-HJy?9_-KS$jMh+&+-W?j3Bu)c!WNgzh{1Jj_0=pQ z`F9@;!HQ-Utu*9 z;(hL@^_O`XW{M%Gw~!bm-Qo6DOep-l$3tB4R3n>CGH2vjaLGSP%`nhUyH4&=hPWoN zqt9ip1On(P;oGza9stU+6^4h#ikeQiyg-J2tMg*Z$=Qd=!3+D{Bu7#T4N6Gi>@y4S z!3H-CsSYKt`>3*a#OL4Y1iXEm--|(WmR97z-Z=Q~hlv-W&*?4U>a?~ZtqryF-JiZA zWY+=zNz6QA@I-|x(Oykl{-qtvWCL2+iPLTf|0ZX7asp$GqaNY%&M#1zw2;8;iGYzT z<%>LIP^y<)a&2sOz{f_EHC~799b^rnRdQ3_pS-tDu~(s?N{Yx1>SA%KQ`%bP&BM$RAp~JWG)1+>0C#9X(!YMx2j0L0Ooa zO~7byxRN~?K_i{YhsduX;sVc%9*d8(goC(B(O&;vS(VrL?E4m}Q0t%(r`9Ee$GKQf zNu3I1|2n6J7~`eO>cj(Mn#9 zv;d3omjcW5MM;bN0!KumDrz4%PHpxQk(;4+mFHPU?ao`@F6q2M>`wMDOGq!I`L#uN zAg1VWZZM2d+VI+(*O6Qh+(26@#4DK>*?!WJ;uP1;t51KY)}AQZ!RA|)_~zd)lZBkM z)Q$&<{Q0o#;T;=i$2-u-!yuWE^|F=9uM)OPO84{TB;ni{iRU5qSsakopy{|A4HO)v zoS0eCIpL2GKb0m|-P=C7csM-To^S|O0nMe}q^Y$?#Wq<<1O^~tbBD>6X zfS*WQ)}FLkO5&_9zfa|^xnK7ba{LA|ggEHAp$L{A0!B?asWt2-JSr}32PSVfP*k(P z0I-nNYDFzt4)NeKYLBfNmQDvVKk4$zYsjr3!T8D1Fm+G%BWd_x0>Kb6$$3cKE%Uq9 zb_vDWe%|t7C4u9eAYx(P0lOxHYx<|}UcDtV3y7y42GE#<8T0!zNh+X7k4V<@gCbTo z9#_&KpCq2+;!a3qs@0WsVYtLgySE(G-|C6h&F+Ho^HN_&3{p&lcO_twX^c9ra`z%$ zTnf>j+`PdzeTL38H4r}?2OBIern7noW+zL-W%@+9u89Az9z(IpV6qZYyve8je4Efo z;`i=oyAUV?S0nQwV}gF`EnH{-AMD-%0Z+#5@b<<^ZB&Gy|7S%8j4f~NG#P&dT{@VQ zphSJR5Fnfyg`J|;^I&htRZWiunen?o0e^suxSP1W23y@=%Xr($Vgw<%f={Ej-AaYg zk(U;H(=f7AcjQXbBy%}qN;(hUQQDj)!adQ*9(eLAJooQF_b;I7pE39=`tskx;{T4b z{S_3yz`+bGOf1CQFWfjdx&Fk&tp5m#UqG#Y2F0(h{|btk{%26k!SR0$iaB0G?LR@W z5I`6p0uTj=0VDxZ09k+>Kpvm~Pz1c-4**qw8bBSO^%6M$37gFTW-kc=FTer7{IBR4 z=;ZV#fPO&}>`Z=#%ud#ZPUZk7dqZR3OZfbsf%CtG&Ho8z{{s~Ne;+opF|)G$BW!lj z@KjZqO%t$?91#LlI#SB!aPS%~AN4rYoSNap#Kbs-q_qQs=we+*MIZ@6k#t3aL6L+( zBL;;Kij#m)HLufucll^u+Ny3>D0A$5aA;Gw9BTV@<{K=*j!QHG8hf>j+lSi7lOKa;byW-l24S(<8hgoh2`f^X~y+F1%~KkotsyPGU9gX%!G;78n*1@IS@llB_fcJa%+OUUQax(BqCF{)z7S0kVh3h@>h- zQ&bcsBFwwTX9MJv!y#5v*qS8g!&Z->5nfdQ45d065!x}zVwjpJOjV$!+yVIt#Zwdv z#SF?ZYI9fv3<-1KoahZ2z7fs{&bm+@3Nkk|SIVm9qd1itE@#61oN;hJO^ikh#0teq zbD9lho$f|rwGp;O zc+K8~+=hrGjEb_@cMO|-M8?kuLzL%1Dzb)NM@am}c4Ky`)MsLMHW7#V|ldPACldK_z?nx;iYo_3x24pP-Obc&bgC)t{T z7yp(Q=yn(9x-R47R-Q_vbo%G40KW&?vs@R?4acqoNaS%soZXqJ62wysT++)^;2sy^ zQ^ufFfjSLdrv)5Ge0E8nQL&YU3r8(jNdwKjA4;*5clDVjPqP#1E^8HL=U&{ujI=bQdW${~YWcOAP@EEZ6cP^-quwxW7 z&!$@r!KWzfsZx8Sm=r{o)S93I`3fhG`aZr-Yc2U>{XPSb~*pZ=`SD9zDlMf`>f%mPAow89+^68*l&rk4bFPO^lmFz@8JMzz(TZq>2 z7zTac-lg<&HX$Rzp4CklWVL|IRmLO~o<%MGjQ$Jy!O<}OcYKW%$WmTiVHm_^6cNJx;m5qNq4{hx1A5$q zb!E2t5w1zMnJcy|8$ZC0=Ad{~R_!!CaX>oJdt*EZp)ra9;k#-~g`VU3*NuJ&n)3~eWE zhA$u80C{%Dn6(lM^#R0Ra!y(==4y9x-J3x$OKU#?yJ??3xR<6+B4e$|F^RraVj|GV zt(Zhs972a|a_~*mG2#OQ8zWL@=qZNvs(mONU+MD)B}tRn>mHmkq{WYn5=A`$(@Udg zKmoUO>vNIp_B&dfg<7DH2&QLh{%GgPh5fO#$p*b<$2Va9^G5udqx9es#l0auARRET z6q}TWnc#RbM=2OQh_@uHDgA^1C5re#p=qr~w++mlJb#E&@k{JM%}iA1^mdPVz06vW zQo`&Fzbse5k_YrQcQj-)*RH*a6nLX}CzE5D@s5dJxwsO*e8fVv8Dx5UkIRYU(8SrK zgl)6v1QsqK4txPBpTr?NFf5-mv87T6}MjH+ETm2I_C*L;`Vmj!iHlx zS|WJesb*bIyaom2)Ly1%fGbj8OE}ib$iV<48Z8YOr>p11{Pt~tb!}g7Lv7lyO9z6b zvkRsk#kN|e-`%y9Mtd6_t~Lwx(n{(f7@w*_=(((Cb4j+?n6e_Ep;w9j#QmGzO>X*m zY}76(x>RM*zT@rsF-7mug2GnhXHSzI#f|cGa6N@P$ca0!IN?-euxd5AN8$HJkTb!i z^v*xX@OS*_%8Yi49VUoo2y6C6Rb(kG8pn*#mqGbK;A{28lmL(&#P@bi+V4$R3u#>k)*gcPN?<32{-Ycj0-svdn{<61~ zNp{iih$gv3`|*<0nM6CY6cZzPHO8}9dX$RNWnXS%AQ-LGI4@<;s3LWRh*lKtIV9-W z@_F35=u0;JM*2B1BzB(CidjXUc@3*C^-y0dMKtE=x_Xrm~W71zNV z65KkUW1k5x4J+xOE#!fN6WFwJM4~ij4=GzfnGTK{3Q(MQ-iFbc#n{t@@v6jN6m0eZ zG4lN1TaMZvM9FkVpA*5;E0qUt`{6mWUm+Tei`_Gh&&La6hRBEuNj&FwcJ?!T3{B#~ z7vIanR7kzJ(b&XtrcI|Ex?L`L zqX=C#vqwla9pcO~kyi|I zru~7uyT>jFr^=(Ir4IvljU4h8ju8aJ65Ox+^9<0M?M^{#THA0YRYq>@pt=BJCv53S zEHoTRhJpnpo3XT<9W1buoJ}>5R#DDn5Pu^vBO`I==|ZM8^RgUCNXF_sRRyqaL^-y~ zZ(h7#lJi9sW7Wje)j?hmG)3!*H8Va|B?G329r{yeN4wiQyqZNe3RAtr^4(elkQ+K_~yY+tK8 zCo#}JqpZub&8jw`i&z5`47f0NcHX?}!PbXZ1>Uj`)gq5GQw~)Mg*OGn1G%2-aE;l5 z>l049aiW+T>rnT%e;7ma>)!pik-EP{U1xNh+bd}cz`=B{OWx*;MDh^{Jewd*swS=! zqyV2H*#&Z;k65-pNGUY1^$v27H;HU_AaxIyxs9HF?^_|A{kE!0B~Z~W!z_$8={0M@ zSsCa)0G(1cv;PL)wK}n-&|xzWndSmDtPMDGrWla8iV#gFex;NkmFH6_jHAn;7VT+2 zYtdK|(LEH(?>sS%;LeNUKU5H)61<%DDO_ic?ezO|4t89I)NzEvK|iWHG=mWQSOC@c z&!az_mI1afagY^-a`xIP&+cPk4Mj<+m}!poX_#e5Z$4$5@O;AwNMB#AGBfxoUzV@L zs~uFyg#nM16U_AHdOG+fJWzre^7#W2{N*kic}4E-d#RyM?jK@!U7rzRI;Kivk)=px zOqcAymQED0t~8vQD|F&wYIK3~Bzcy`l#BR@XTUCCks?sW+Kb@440yh;NuAH4i z&Zwo3HR*Ea*dsVLB5C1OPyDV-3c{+$+aYBPy^UW!KfJs{%m3#7dHVY;s@1jUiMQ>( z^-a&WRZR``LQlcYOmYOKi;qikG0n@qP+2Om4QEi=bb<}}4?5bVUD&d6PziU-y|+~h z(uyT?(@I}5n#3CB_dVMV!qSOKq(?^32jC{yJN=A`aVCd#2{qh?_uSh+p}OYB1h&q( zeMn>((IsQZ1SXDy_!vuhcI7skTxY|lpu$*n=HeH1S(I;tT;pLx{d*{HU2wK$i3+4f zr4SKUlAhdF2vMp_nMD21bL7Eg9IA+7&^qL1jPi-=6;Lt-P0!H*te| zJhI6^$Q7^@NPgo@?Dnmh*~V5vPQCc5tBA4GD9Ddh4C$Pn&Ok;vf#GaU{%JTa@(? zZl$-~1b^<$x$rWSSJJ+v@%1)$XOmxP zpf_hIG`xyDtVd5&Dnm1M{g#1Tx#3%0B&H&5;JCLqvpSlGT4euR9M$x<*>38UO{X>_ zu~VK~*Bx$tgx1m`DZ1jtJX*c)C0odw7}5nT=qkgm874T-qGBpyEE}dwmW49*KvX!7SeucQfp#fNMo=JViIH5rfpmk+ zrFOzs&}M_?=TahFxmimZSAOpPThKP}%N!u9PkqP}48AQChy(>c3ARz@P5Pj?C zD`%8ca)#Vn{Urz63+s|VVYvz>2V;oeT?`N@z$$E-(c$_rfYh>U-$hPC(S4~x+65?| zd1+<#xr3<7`E14LL`60ow^-U>m-co~cR#a#t;TXQnv$ZzJGtRGxxc}U%fP~=8EB!j zg$Msk%&1WtnwAC(t-Yiu^ELLa-K&dXbcna8WFAx=wid80cVk`+EUraAge$(9gldJxq9U!OtrtphQgoC>s^Rmdr>VTA8WAbUp{`(vC zi0b!N^BPA=Y2#h8D=H5N&-7F{cD1$>c;#ESf(d99KN{D07>^vj?`p3b-oXzxV)06n8G zBRH@4%}ZL|3q0dw^(zCy*v{I{7GP{=V`KOy8^Yox8{%Kcj=8(NInefZdW7{~5YMm7 zke5seTNfLnmmCNSGh2Wiz|I!(-@v2)%xe5c8rA=M@Q9s@o$DXqk+&wSrpjzRKl9Iw z+&cA6^Bj&U?b2zUMcTUA`4Y_XAuzZAmQiEjpMq$Tu9RqK!hS*Ss+6b@g*?bMbu*vK z%f%KK+pb){)_c1Vt^D*pJ~UWuUTwbiiHYqPnKvtMoqd{Ze{#|6>4Ala=uJaQi;s(K zpy#3^W1Qsl2~O=c`YCUqZvvjkeYdzniS)4xN`>-jXlwSC8NIN30&8u=0wTS40WGtN zfv%aFlY)lZcV*+t+6RpkM(@Mp)iV7i%fptNoaZJMJ5OPKY2}|S8Ycq5u)A9GIIyX= z_sT3A@Mk}x-exrb=nVANTGoQ{0xlYteA|Rkdioerwc-}58@3Myyx#)a4ctCc%i|Mi zI-68(?z9E<hz(hCjvqaCQM2co;me>^Z@ZEssc0sN_yCC5Yf8A5V0vL zeSm~4Imf#F4*}R7@ENaUCon!C0e?fP8X~zRrmC=-NV0WaO0xt@%Qx(z#|1HyLwPw; zZj^SJWgmI3bcdYG3Wrk9ew?3e`(~x_UEaZ401)ICnQiPBDkt{~1uk^9u@0ag79M=g z?g7t-tPrfYre5qn?3PlO#Fki&wo+@%IEK>rt@_G_YrbZ?@0pXHbb&t($>`6RH-_RF ztG|suCPP05RS?a|H6G;K!OUmV9>waWM#f|)u`XrP(9-K7;R*v^HhG>HwAMk2Jr}CT zBVQ7X_?(HWA_$G8`~`EOD2X+R23$YHGw$*hW{JP6A`>=Y*(6VE4{Vu@R~|9TvWORI zhc#-qIhfjiqCGcJJZYTe{gj-TmReE>D;s@ITTE;1mf}~FQTa|0Y2$EOX{BK4TeOm; z1128OWo?oOG*U9)T&1#T^7!26uSr_VgO>MD>fYTUrazgmhPCT3V8@n@-v|lpTz4NU z!no75Nw5Zm(;p2?=kJJ#_8lyEu~nUlerDQlxj?%4`1E}&syX0vCsO{TdhM|AU_5r5 zLN}3uaum-}T98mNg?5^y76kKb%;;lj$;=E0718^WgG@?zdyvAot88PVz1lYECwLFo z5#i6gwMi^xG>rOM;ovUQBIO)386gT5*z%pdUrz33hcCD3ABuD7HUoz$sWiEK4wM4I z*4}i3$&(Z_B+`myV-F0mSgFe8Jrcu!fbRN#etSh(24W5tg(SkC2A@l^o$?t_0UK`F zV7;1IMR)=(^x@jxZYTA^4#Z^gB=eXU5lf%{-TRB6Y}Vn-E%$yb=0s4|sm!4%D<5QW zgU$r4Cq}x#HDNu5ruiag?3KcG+QD}j3(ML3+|c~j3>h$3T^4VjTFA*c0Bq_vH2Lho zn3QzF6karHhPD21fxlfr~!Ho;y#ea^~?J&md_ib?%Fu zYe!e7OxH{?o|^4^K*<3kjnN=J^1RODep}tUHOtYg&X~3Ip;2MRqX(F(uj3JZ;)q6P zpZoNUmSkfN3lVgZ28VfYp;(Wd-r`>+ylVx>aWmY|mp!}q!T3@3S9+eW`416qX$ul5 zsXN1Y!!(V^+5y@5{U=a4@Qt5(qAW&=xB?LGTSMl|Nz$Iy_l_%dt@-(=Mdy4ZM$kwbM;qTc8BZFj4I3zU7si{(X-s;f7Gq*5Hw4GAA%y=$tCgoUX0o*vkRAvmrb9g z+D4;MF*#|@Jwy?8_(p~`ciE)eRLpfqos=oAf9fOGiu5 z`obW6W0yFBp&y$!2k7h90#-1ogMBR)#-$TAl_vT;4OPNqvT`q=GZ?7MsLzt`Aw!DX zA*0XLW>V8ME!o}lJR0w&7{WPKBFB?~+|N5jS<^CT9}|*lPjWe+$WZBp{&u5uKS}@R zB~-f;r$I-i7Pe%=I)g2ZS6nV>9mQ7`f-$fpada}#f;pR%=Ef|gVE~yPt1nlv^vmd(Z9-i0OR6SdY$F`U2`Cw+vZU2=EJnE^B zdR-Z8?aBRH?GVO>!U{_i*Vbif!p`fW#4}>6Ua`n34KNpYdptMKtIsW!*(WE^cRSGZH zvpv#A@Pfzoeb(>qTfgHQRv0ehU}c6h6}IP1vV)~?3H8c%XiX4_|VGvy_6Q;$XF^g<^4EbkJBheGL^#^1)D1%S4a zo;XQ9x}J_;EiA|aLOO-Az6rb4%J#9-t-w8 z8L~BFw(Hzo{A%d0E9BmnN$bDDD!j`Hcvmj96xXLuHC`dXwSBj5w{=fzO z$;`B&TKkhA>QBKf%!;mT$b3I}S_dT9)N2RK@MQAR>l@MFWlf|5zoTNse)w@|+RvFlvcR*qzJIS>0H~+e42E zj2Zmcj6GAiXK(HUwzlDC(mJ)CHpXGzH6|LJIc3Ti`GkqDDjMsG4+*9BY=RWgay!Hl zF5UxjIa1CXAfj~;Ck4}dou+wfZ;f)FU`$&g{HkgRigmgKVgu{4&8Mlh>$ws9o1zqvAS zKb!e`U9yk*>b6@~qxzdX2RVzU@M)VhGZ3~3j{ile$Z#O12tV<>Tx z{!JJsBk6bqydA$2OS?8Ec@3cAdpj@56ONIMWR*v+9zjJ)orp zY%GAR#RxHr4RN#(jx_`72HU{5)#coN`fb4b@Q$BBI>lWXEy8iiYU+ak`mqwG6f7<^ zDzQaUM`a;Wf+vduWMqCTes}$`MWsntkItw-s)moK4H;ObgQXzT9iC;Sy(@Y@$I}Io zxz>-&xo7r{z|4fwD}+|0$cE>vj~s?Y4sis1J!RuCYImtO%8+dFtc&ckxEN}?jvF;} znnQTfC~&616slRF@IQ-G$0Hv`J+DD$_26fY5Az^NnUayu=L(r4V#WPL477XlS)A5m zb>4UiZC#Cq-^8ZR!OBK?NQ=-Hud1wv)?FssiP*>R&fvr!Y;FbRCxV^@!?Fhpjbo%5 z=gie;1UHaeO7bE3>O>=m|AotGJx(O-6!rEqF>cQcxvMxr;UmJD$%)9K!lMWkl)|hY zsIUFa5PX>@nLSZR`_wRE>DW91(Iiva9p961$5UgA8#3$~P})ph>1T3~72A;K*LVX&{tjnOOcMr&z0*hSy-h_=Iil=Q4vIsR9BS$IR!z*Z?u2-n zB|U=%1y4|NAjRy97|@%h~K4bVTw;F=28r7zh`tKLKkmP|#e2RWK>&C|&-8bhveMn}lw zN*TTLUWkhR+`Vpi+FA)q1LA zCdu7z3eJ08dQeW1W|2T7e-oB@C7_=4(Oe-D9omSZIQ84Em;*7GH8z4j`t>TG$CIRr zaB!D4jN|TdTxfm8f+wnc6vk%4A$6*X!X30nWRltux4fdt-nfBG^~zIx8+Yu}-Fjt= zuz+AobJuOk52#MDyNz$3@CxO_6TU(aSg3JN-&Y+G*nxf|QmD>GEZqVpwDl8P?`k$Z zz@jdT-Y38OAjTQ5-5AH}nmLsdl_6dYTD@mU49o#UCdGx!MojN}l{tlbgk)^#&*Y-k z+fb@DO2sjclsV&i+%UxkoR2lX$<#7q{INJ~$}l$G+pC=~NFSJL%QBO36!tbWxzk=> z2R;Lds$R9dvR``rOU526myACc1{U2W+!C_F7W00wvPu9;4Y}mt=m`ljQP{XYUNf9n zt$kT6OHfLZjYgDJqfp4{#tP!oHnAt$Q2%EZ=G)>C2A0;yx9o5SQ{WCLN`(c`OL^;jgYQSzZ6uA^d>6l-D2G@I`f^Z7Y1Xe712lORiihyu_ zQ%l@+Gn>Z395v{7cUfvZXUxQ zM4?PMX6TK$TpK$bsreMyA-GyuIX&c(03E4ZxDJ8XOl?s8*1EnR#6OKu5P62`$HTYm zi%v_m4>1(y%c?N38v70c*7*z2JXWEg-c1~yttb>qcaPd~v2PRx9aXps*h&Wx?{1hr z1ti4iFE$FWP*KY&I&xbed#IcUH z$YaVe_fp*RdYSH{U1hiNan(o4o1nJ^2xf_!M5cxp=&pc;&Q{-o)?%}rAC+HyK<&}| zSkZiS&)J@w<-J7Fk|}iw*Hr@%h2Mi2aB(m0P)8_CamIS+%D9 zbl`|)I@4#~I+nt(J%ev2_v#Sm?gr@yvQuqiHLwQA!^?Pu^i6Gr+JsdGtqQc)WTQ2- z8PL9&kS2-g>Qmd3>r67c(-Z~qD7k1i6e(Hs^Qe-iVE**LFbfanOLMK0Sf4uCaLQj0 z>1C!sqZs%MuNNM&2Ul7sJ~m@fw{VEmJUy{|Q`Tz+(Qhb=w_jLkFs5{ z*{Q6gilavx=zgTkGDv@k3z$4%%n(7u#b@~vAztFk7iy?N`tgbG4RynYJCp5q6dcmfkOO5Ku~(^-L;$QEzy$% z#1FENbxtksv5uoaBwJ#(rHlCYy%V(hktbA5)( z`iQdkp*d;|5kdmEER2*DCBbs~gt*qRb3#Qtj7GQgK({*t<=keIB3fgiPTX<(%7Xx( zwF0W~j|OPyHP97>4_ap5#XREi!l}r2!YTy)2;%2K%%z4D@j8>8`$@?O7B*?0X6lnC zEo(k2jYMhgmRk-ck}sT0+4EJGh&s-WCGz_Rg^wZk^f!m-90`!`HfhVkglLC_z=@J# zPZ$~>M^`Vs!3fWMea=WU^qO3p|p8yXmhKODmIMH(NJ#Wx~&M$&FGWbMpNud-Bu z4r?G3?CE>_0AbFdxmayVT+MkUyn-m$ZK3cK(CmIxKRTYL8AnN?I0u%p@hQu%G|d7d z=C1Kw=6py&F091$p(gqjpRU8m%AO1Se#u+fuU=kOeS|VC|4%Dd7ve@0g{d!MkXn(} z9}q5E+Sy`f=H5F$$qdOXOOn=wOiuj;NeGnFl`19gI74h%Eb0+D7-udzG>eU*B{oc<% zzIA?m_tu5t%&z-yUw+{i=hfEN-!HB1edy;4b0!c**nGzfcqb;FY9eU% z%+2IaE*_a-fR5g21Px$LK%GY2YwDdG7pv$nXJU~P2RU_nP}*zt|9Wd7$Psh1ezmo>D}2StJ4$`y2I(fnDE2Y-6+Rx1t=^YPpuKnsT~g zWfZ<_D=JTjLwF2>Pum$MqnV1WrS1N9!H}6F`@t8mp#*+_nGUQNR;yx%Iqv9*MRat< zZ$@3p1_bWVII;Khr)3qyX0jI`pglKa0i&0I^}tyzK*6vV=p1{of=Cd7QbFqO7_0SAS&_wP$UD>a zml>2w|L(CygB@vx(+hs3)quw5g~I5)RT&r@w8DCv9acrO>o&8k31KE+u~pF> zKWvzAw#^^_!Voh8M~iSKIU@^SMs8HMjX3w_>rr=7cUdm!b6U878_5hNxNkc|AKR ztq(yNKg$wuILnjSg3gi*YgB_Pn#TFXVax#x^6)N*UN+25%9ld}9-2;QJHTT=X^LG~ z-GNj^krd>ho{UNwFhH<@yq=6=8TuSXWtd8!H7+CRgbZUwaJxqy`l*tM_;E&=Y zIbjQ-N(MUf$8b2EurGrd)50hYbQ3t4DA2Mnjst5GGASXGqDUzvpma#b zw~P8bKJos)_xrB@Uf13`_slsnXU>`V&3&Jlvy5uevYcQp9z4dLwYYpdUH}LHGq=MN z5dkVg9jy^I06t`n22j@49szX$0A=mX5Kw8T1JJmKh044sGP$z$SHXu&wVJ^eg$eOeUM~D^e|qk2vhxL zzWsbQ*K#Rvc~`qOOV(f6Dp@`}QQ>ts>DWg22eQrM8sh@DK-~NgouMEr=}^iG?rld= zXW@{jz30&b4`Zw(N!~!oR|&P2DTqg!lAfn@q{_%N~a-Q58q5jqd$BA-_8bIl8d>x(zQG-fK9bG#wBSqZoqN8L@5ApT&rG;%gAI&K zUu~SfPM~lY8dcDXjk9^Vvyk_RAGZ?SVe&nc=sIqZV^p4W@XPds6F1ph@|$$eI4nQq z1$jLH#6hm6us(j*iI5CHIP3_Wy(^pB*izAH%!;?I7 zDR6(fq^)uW4De|k0MQ?%>`<0x2tBZP?DyFQOCF|7E-HSW3emqET?zQH+a zLz1>}1Oi&LZT31YY~{m~=xybsGTcMWSMej%lHF>KjcOm1Jpf#y?1_9 zk?SOy4%Qm-=%jdae>tY(xQOK@-sZdXcg;`<;-{Ux{MqfrOrkUlUYMqlE#rYRE3>*P zXyo>9!QzP|v>3(>8q*=-w~Bh0${22Q?^NJM7>^bmy}X;ACJ=T;-+9zV?l=q0q|?`b zIq`u2O_8KePyF?i$F;ud4j~I!75q`Nm$yK+wXV-!QciZ}-pZsN<}l!$yPwadIsT{? zal>ZfegD)Ngt|ZSwXG?piaY$k5i9i~Cwr$5ww|4Nzvr84hdft@cyWEf z2!vX#>*{>KG9Bs8hwRzlk(b%G_+Y$`JHB>(JHE{oGQOL%Wb4brMJMgLmzsI2D9IvD z`qt)V>q2tG`qBnVahwUm=Z5!%6`va3uQOwv)0Ca=z0=bWA)a9*ebs8>=UNv=w}SiK zk8|kIaesUFS!*W$W>~ElE;jabMJb(l;D8K96tx^*R5rYVP}`xp->j!aq4@pXHT~_6 zHW#gIn7H}FseNy zi!2Pu4o1PQ1|AYofl|nOWQ}mZA6Y-;LpAXOnUS?21q5752nPU_Y%SpcL%bjL83T|t zxT2~=)%KGW{0Hk#PAM~lnLW(w<{0S4iLFPj8v2;d3)jR!^Zb48LggF{jJ z0_sTVtLqrBYuP$L;hYM{zSvq^DpDE>w{Wp_Lcm-A;LA>3_V=;~scBmmI6}(C%mpCG z4^%e$nFfPFKwVo)gbmyfzzaf2!NY^<#E&b|=9hV>d~SY}Xvlk%9UYM?psk}dlGRbd z5pMg(y{4-<0yTP27DB4!4-23w_1V`QR^737Bpwd5T|1)*j1_&hwO2;Tll+J(s{+atz@5pjg zN&wjx6b+IG@ACI2A4(QfKYx~8wtiX1|A)0ucK(O4G?X-@m3|sa1Lk1n_;+iebn)L9 ziy!h2WBpJK>iWB>ewgxyu`X4FQqynWp9=gV@6TFLO8uc|lxa{Ylu1ykL8Vb&R68ho zRK5UGbwBej2L*};MT;s!<^QPn&(zO$k+hcvLrV1f@1+rbO8Li>xilSW$o!Na?^i!A z`-^NJMfof5XZ=6hy=?tbt{-yz^@@`7f2R0J{~v2W>XeV?w?P5`|1ji#n#rirpM&Fa zo%mzwqtNM(o4@0Nw5^pD6uDF&*9Jp8Fb@c5Ws3(!jsyo=M_0JOy>|Ae*6 zF?Y|*0s0>yP!hRXAr~u7r0sYFApkx>h%xG+-5QQWL?qVn-~lDz7N{i)S%O?`%$($* zw$?U3Z&3}Q%8=Z6z#q6O;b?7-T2A zzg|lOc_CtAf4qM{6C9Kcq1OX83-7{$^G0}{OL&($&Qmko%6%8o*-*vW`DnWktpLA} zV#P)&ZyiJNtAqDR*Hj#NB)f4H=YrJHH>Ue5O93&;6Fl%pte0IyhKPkQ|I<0|?=wVE zR->JZrvie@i;IHGZB=8}uk~!x@VYP-va-D6V_A%u3Ng0ldLx$5F4l*}^WeCEgTT_| zuGP1d$Me)IL!otXlG_%P*gd8xc0~2XO+t%9oCc%tI&IkcL=*qTXT`aevo1Q@@s8M{ z(u{BMq@*eVx35uu6_`>TZQ&vq4`x0F~^R2jX_r2l|FNtrKoC9W>wZzUH<9M;%^Ks zc|i|NeUqOyp_y47pPgO7(Cr%re2MZZ0I-A?%R#?EsQ*PdB9GxxkubrSzOx~O{} zRb|jY0H#2ePSALI*!@Y_<7bs0Z^wK#nlflX&=O0C&p>NmWT?h(<|gLYJ)=s)Xb!NK z7pJ)$HGLtQ)|m% z>eRZmh;UbQheWG`;Il|-Z1m(PJatSqF&C5Lu485h=!8P!B=H^kWRhOVyY7gin%mP; z*Yh7bC5bOY+ug+%*kYP=UL+5yFWQKAFLlX8kZr$@^EW(A%xd*A^JX^mxHfcW`w0z_B9YmMy?q` zgp{^*YoiQM}iQDCs3 zefE&9ZM=ThqbKv=@$d&}Sfc3nD_zsHUfc5Px%NHFe@2_7&~FlOf)3do*Kzds6~zj= z-}`YK-=47GRTHVYFoCNwJBYOTuD85+6_2prK?Vr_-di&t-nKwrP^PKhYs(L4?UuWk zSR#R%9Zv>UcN&a>Gw}~<#6S9yV?`!_(0#*&$@y-r`RatFOE=Lf3$BPk?qjIry(vza zAo728XYkuiE2W2OH&q_{F(iQJw>^^Pc8?(t@EXv%xN`&bc=XpNb0lp26<$%#d;f-i z|Nijw3;no3+yFsjU3>z3zu*t@8}teA{RR4vk1W7HpbyFVAFvP1hh+O7z>g0FsK3BZ z0w@KP2Fd{CfeJunpbGFFP!*^K)BtJ%wSd|{eIz)VBjM2!36R!6Yor$i>0LoWr7iFQ z5-#nba5&Hb=m>Olbufpzz-_G^fiR#G&_KsXTY zWM%;cB7g`R7bq0y3Uqa}MDkm}T%bTVpgYj>FF5@7r}N*Q^8b4r=79+E{RYIYy0}`J z<1fX)49l|tc%tMiOky&I)~^U%ZL)3E(MXuptZ;~NEYNY~C2`xpVNXPQ2Fty-2ZF0R!aoL^j=v|LP4w_Dw8 zn{%?FzR?r;gx$SMseNLKanPH(8+sG+7+-A`7S-*({aTqT&Gy~ueB~IeSO&hPl~lbT zMry}|r%|=A*d1O4YAQyEW@SQ!quL5ht7GsmA(q-MB5Ce}$h zPwbo~Aj!cPOF9s45e%$~`lwRI5KHDAt{r@w4wzgqyUMkSck*0d#@cJ(+6fgsWPE7tF|V&qM_KDs$YjjK8DEq0{?=N> zQp1~sLDnoyVfRl)%Z(FiFn(IJL8oQGB@2kPPi6=q*0+)ZC%#AvHtK~V7PowexohZK z(*=eQW{$I5EvDf+`^%WPxxT}P?kb6 zPfX)hVj=FE?svtUmRboVH?s=w^WsJ-#&lP|^iq-$%@uk;8jF(1dmv%a)Xjyn_6P z<=j(JKii(-yw&!;W~ckuMm;p{w@qaWC|NIbp0nb2qJ?l9+>8{ksi4mw{31xsreq?> z;$Bk0hoGPed~S4K!c?Iz_Vnr4q|Hif3qtz2W!pX1r5<|@7{{VqVY=)(J>JWttt-^U zb^_2f4(Ik&R;=_3yJe$5;l>5@hUES2#NOC}g|Wmek4hpB*KUF?g3^t^O;$>gWA-eu zk<^=`%$1Qh^M&0tZlq=Os>Z#w><`3ZiAo$G)W4T}autt8N@;}qdN}$VT`e(|ROXa5 zVEYwus`PiNj#urTkxJEsTube{z1d=VX>N+%VL|9Fpj>q*=JiFtBYLB2%bQ*?0-xqB zZ%1ss(TeEjcFh|L&KL`Y+M<7~99(pJ8iiE|eHz(6`O@nJUkAab6&lM_rx9kRmOOS} z?t<*WRl+xM9$n@QF@^_R)C(Q*hcL?Pfgqg5yTS|<`DUyavW^ZfxdJlclK?F0etJr6 z_Dh5_YKEVDH#G*IWd|{RE}6McrdN0fVqy_`E$%6v8>E%8JW-jPnttSv<=B7&3`+PA zG`*6mp_2Y0%si(sX^QAXpD~3wfXvIfoc&(RE(NC9V%%c%{<5vU9he}ex^X30&Mrh72hwLM5m$u1T`YS@7x6gOzMY=p8%q(O ziESWs_9edgo@2pl^fM;eBe!UNt2a83WyV-cLOmOpuPi2IVJ@@a*z~xGRqs6@#Tb*$ zgPUmY-+%Pk@IiP7z>>#iOb@Sl_V?yY+s`W0L69tF#eNVxJCzTxF9{^A-W zB%1@wzw$%CDrY-nVEwIYE^01Fq( zMc`g}z>uK$n^*}Use?}q*OHbsTsSCF2je)?_dQ%BA#vrw9=x+F@)a?_z{+ht+mWzeU zPu3+K3phSxuC}X_$sNPhx~0V7CCc)i3ZZqCEk5D9CnF|fx|i{Vh9+gLj7|@en9+bh zcJ)m~!zew8cCt9{8ZzPjL*vG7`?6iO6c)E8ZZ>v(^1`ou{7*#Gr~AbS`nMLljAc9~ zd8j6`ORv_Q+-(tSQmdhGa7~VtY0)t1FKs8qRhE^42y^Jj@_ku>XCAb5ks0-1iPb)& z7tbXz5xxEV{*tac)isr_dr5iVsmV1%aHe(pK|BPJv+R^g5;vNjesqL6X*By}kS{H` zGTNsFjx!`Zo$c2odFzR&=nz4+HsvXk#3OJkMzY$H)jO)dj?9Ga&a3S+4An70dEv@< zu_H4~_0Y59) zVeoVytA`SQ)!DoFwtMcdwVA}VXG|u#@v6`F!g3T^ak6Hckx0GSap2|?_4G(C`&t}v zyT+oF7Y|N)-ldF~c`VX(AN%!m))Uz{~E9iC3)j9<1 z+$&!r)Utb=|a+Ldefa!cAr^z@8Z4u{jOEbER1-!rFM*PC=Mmd48B(Z`ayGxBv$(iqHw z-lY{a$Pufo9DQviwsCSo!vuC??EQF-@GcgYSr(1TtM2L#ba?n_J2xQpDe#+k4TF)U zUwcQSp_I9Nw4P|$7o&VamL>gfSV(R>KwJsdV75yf{?5mTF#RmtKq3fqmBCLKFhxGu zm>Svo3eZ)aI1mkxWSTt1dOmypqE~VgWEYKjz-mRLf0$cxOgrFkm+o_f8X_9^%bo0G ze_+oO^Idwnx=$t1G#ta4&R4nA$LwyaDT8p^I#WfidB1L+Q&~*J4AY`&(l_xHR5)VK zv+CZ)3;k?vWIK55_p~^UaLnSvfySWg^*bF${FW40YAc%DPsCpc5%U|FuSzyMEXxh} z(>n4SQxk76pRnJGs<6m8`2^acJ{}#_<>~EH)+}A@bE&(g*7Ib1*2v~F!r@7Q%1!;g z7kygrzzJHHvO%3yk+9%UceBKh)*6oQ$@{cjI0_tMC(M%`Lxc2U4F>vxR-I;Y@_i>0 zOV_t>L%5PwIBU|wBnwXsoY;J4iFrxx*%3W0ovvmYaK61Ejz9jwB`stmmhd1>g#e9? zSeIVBz-C~hw<(5(N_-jk^=cv3UIMS4 zp3vE}DN!=W;Q7+sgA0|uiQL~#U(XV2AUnS*Ow|qbfy79TnEPNB09GQ6%!oJkpC96d zp4)&=uh3A~S=h)&=TUjc&jwEste-i27;YoO+tK+for$>;o9r)K&;4p7Cc}xo&ZIv%ciJaj zKVJWC8}$<3%zd`a!xDOryf7iUJNkg69?K@Q$ijQ~Z^0e(-r0TLcDaQJ-IVOAvD^G#r;$+fed1u0*Ad`#MxDlhlUN7gXx*p&&skat~~#z^ky9jgVUh)+ViDu5M}q(C5}O z^CG7mM*IdgRrmC-da5b)#tC#Y5a+8$ z-zCe)CV$d~Um_ny5#AYajU-AcXsV!mS$MKs$JrVuQzqK5Nhf6De7*v7b@C1TW3YEg zc<8(UH#?YFnEb@9P7L$iVFat1M$o`!EmSz8#<`bFBP_U{0ocxgJDZkt5|K-Tt;%B( ze!cUtw(FCbym@s;{MOpyvHR#)YB{En7=DnI=~Zo2lHs z!N8jlwMLW9Y10~Q4=hrA7r|sknv=seTHRL@kH*-@ct0SB&+_3H0++IcN0tE`%yrzt z5}@MJ^hu*vPtm=tlNQ{?c|SzoWZ6eT!!DW8)lGxOg%dw6VtBL7JH zR1DLH_s|ccIZpFSc37t-TOK9W!~3-#G>d5rk?<)?+QxJJ&vpRCODOLdzf=mV4Jv z^=_o3-P3-QS*lXV8z7|1DcqZ*?nSARUxdCB1cL84H}|-aC8s{!*OKN*x)EiMckD%nDZ7HzjY)1WzQdAP zrs#QKI-JC%(aG|Zev(~Cf(!3#OEs|f2Ee=Wg>%Pj?5=m&9E?bVb1|>xZTIyD(*$4m zuLz;7XngnG<=ypET3DVL+uVI^?2)fio8Izi)Ld-*XX@FdB^&AKe*rb?SzS?Y|dl{#A%ev1~NR?#iA+uxM|eHA6Knlxn1-i zqN~(Agt@P^vo2eN{VDavi>`5uY$vxUoV`b^{Zkeg`OgK&o_k2=EBoy27QtqjeBx^Y zqp;q3F9?UQK1w1t&Hmg+*IbUa50|zV4Pi(2 z7X_NzET`XCMILA8Kf+}VHm7NI5V}5S^N!-{cbP8PSAI*%rF|n>Z*4f(J`86SX4=XT zUl81D(h&Wp@9Xb73;)se_3v9zfB3$@$Xzl%r0ZYc57+f4aWFNJrSe zy8Xf2g8%0F`iHkm7AW@@kJsP*T^2A02eV7B*X6DQ&i9Po7{VR)cQ=?P&;+?|aU_Z2F#m6! zFkd~SCrr1#1-$fWL7F@|(VXl->5DqTI)f($a?}Ru=@@9xl0jlC94dKqhWIRoK{Rxx zK{K@_2{k3mwkm^CmPrGl9mwWH}i%m3tE$3vHf}Ef9D~?w#7U9hG z^A3vJnpJJ%I-9j87pObu75A}Q^P76|e1aBEDGpbLk9~}Pa^W2Uz*!b;_h|LSeI9X= zM96SkSupw7&p^J&uscld-faTm8?+=}slI%nfs62M)WIuOKTQ+Yek~t@!Sug24}}19 zNP2MG=Z)vJ+aKzwc#uB80h)8psWi({Gn+8`g!AK=nggri^i&VYo_AuIi&rHG+_k48 zBn=Bch^UVs3g_(9X^-&;6Og24Tq23-^r4H@lWxAd#`K7IKlo}@@+>Jwd%`RUkaQ|- zkQ5#Pnn!y;J|KWSI69a&k+8-LuOBX7E?eG9u;-3B4Kk4J3%FwWaB4SpsOF7(7A#8@ zxMl1Fn=_1B;^^1g+jNs#^Yb<9!RNoRsh8DaIh2^jSk2h6kG=MOKW6`oFqZHWA*T{Q zkeo}!$SZWUb4UuS>8q2C1hdylDrcGPZ3zEJE=LS?kJs@d3!wlHZvf@ECbu})^ySoCt()(rXN-T=O+_cK1)+aWBIOLj;^rGY_7E75chJtPg+S-w6 zvk%Kjy{?JAR#cHZ34T}#g7(-e)Vv-oFV;9PC|1osQ_O-CcLR;)A7ejRsg2kHswLY3 z(UT?4D0!-vwaN~+B+f0^eR~1)3OeJZ9w;(;yz8GtFGno7c?uW!jw<; zP+s3KwiXNet2BdM1D_4Tjy$@E9wdlX`|o3u0(xS^=L>@dJvJ6U3Z0TNT_sunMxPPV@!h?B z8gRwH7s|4Z;BV#az79Ko{Rm7QHlJKxJEMJqoy79}t4r7pI(3iCH^`!6cC(f@S#CWG zwmQPQym}m$^N@B(rgU`v>~qT;dGZk zTnKpkE`HGKso!Eg%-%{E-)d6@m(sLipgku~h=WJgxHh##3m49?r*7(8T~zqI_#*kn zfuFA?scYcHipQ`{IBxiIm{6rk>-=HSNGzQC3_~KS{K_F zr{H1G!M<139R(zj~ZX{Ac3S(jAjsMJV@;AkEk;h#$se-|qzN#CG*nnfN;YD|Uk zoiP!B#;11EG^Jmq?e5aT1-S-yqEkA(W+aVyIzD{yeT^I+WtmWb&Z)TECso_e>TGVs z>3#wap1M(4l24vo!5y{x7V$zuXP>KvL{*=@e#G#>y7ul z`5R3sa;@+TYEFh?~mtn(Sk--UhI`vQV!rpMu1>jr_WsV}g4{=gvLsnr8Ywvm=~yXhiI3GOZG^O`d+%>DNHINd-dc@mlAFeSOnu0D zZ79%Gs{R+?XFYwQbX4;S8crnUV zLj!72>C?t6z;~anvRse3Z~9bLKk~qy*AA>XTrskdyy0j2RhmS~g_F)sQoCeq9ql7_ z9LRp3U)PFVv?;RuMAp_jN`;tEx!U$CFqu)~|mvECiW=25ft z80u)(&m@#O_$10iCy%N=+vp;lTn|%a~wt%(X$f^ZBlV=EyWkG&P@4dysQ>&cu49-06uQ zI$fe1JD&E5LA%kO@1luq5ZO(WxpDml@2xb4=@eZNIolqglLX-C15?oJr*VGmq|)-@t|7xnvQ3m3iH&{v*Oreg zB5%YM=LqCFC)&)4zgDwQ4&9$F7hf^(SN%T1+alGd+LpdY`wU+BvaCF*F_@owjr^I; zlfEQN+zDG^>F&p?WQ&?FOV6@xOor|A48CIW>pi}gzX$thbGGMgR3|2#5%0^L#5}kp zUnFTP#u1eJOn_Y)q^Zz#Pu4$>`q>Ee9-cw-YFM3|DBaoHBQbar)>K&8cSUvHR^As& zfN5-y@N8ui?7m6|2d~>`tDZeW5SGL7YKCqUy=tM6en`A2H~b_79LW2WEmo@U+Pr$t#mtGmDE^cDluaeY%E3q5=Jl2r?Ws~ZEuWg~-bwdW@KM`uA3?L?zM1N|6Pb)k28JL-;4 zbui&~!h87$aaJ;;#W2F@Q^FivOv~7VyND6VEK-;rWaJ+*?$>^0sY8Qru{9%n@Xg~8 z23W(mgqla5HtWRL6;1sif`TrEl36)L*Ci{5PT+g!^G4ME9!Kp8x6z~&@RS~L-uE_q z4Lbn36RVs|Nszub_MEeZA}X@YMhUDF9en&3`-LPf5fVEONW?ippUDYYp!PZD~PBhe-+q*Ij}is?%?(J@>@V}JlUBR(K7=2Wj`Ct1(~bEnRVw_kt210s*hS~+f%vFhRtZ?TgNBx^@6Jr>lQq8)P@9OAzNQje!h zqsf~gG&0YboqA$buQ6u_pZmhp-<1n$$G$Qn>o#T|Wh}w}O&y^dm;!wj#XuIL!$+ec z?9$|>VXI~(4^-rIQ)W?Nkq^G#K|3DfNMKf9fEm$e`_)CpgbT>2T^L}VW~a6HbaPiF zI&|)}HQma@Lpg$1Qm1bomFRrLt$4gPWAS=gvS;CVkyHKLDH;0K}aU3DLvl;QlA0yI?fFf9rQG_oH8csDs(-*ds*d%QlP(&00j-EF^Str$5n6f5>6_< z!5C3()Uj~pH{ib6{0Yd(AlWINLRoC^tZD+=YIBtJq~htPbfb+e+jZ_IJPDf=i^(5v zNN7DrgY7NJr?+suOI=k2R5*S(QeYj*;rP-fGP^~dA^a*LGd__NSf)_NH$KM0TR4V8 zrFm9WCi-4-A%`XE%vv>JZTt%%?5)YQop3~XPsWqi8KpLvSMIG z6oe#HQQaA#aNInQgwJed(;iofl`+%+2$%v7&hD-IuJ(eecNd<;4+$h{N(nWjyF$sC znCZ*Dk>`QNyE!nzvk48UA@4a^T+lK=X z&nIpV9=)BA1uYl1#@Dp9dvW)18H94HSia=y1n}Dld-TRgvTs-U)JZt>E|9YmuoYqH z>$3@(GRR1hQCWubhWP}K)8FoSDqD*&QvAWVSp7tu8_D;>#)KxBIZ@Mw z-0bl0x$E~RTA$ZjUg1u%!z{e$(A$>jGX#k}08HLQ@qZ)97XDoVIg? zo**PyUH7R)ZC;&LcXUuh@_vJ|8$+sKS-L{@0`cls2A7(%iKSNzWS)}DV7n$XyMo-7 zhT5W{mKPNz1VQH+@=yKeSz?}P%t7f3uakYjgr?lIV&TlqI58N$Ch7D=xt$L!HkW6k zgqnyPuGt)+IM#EWMY%F6Op=x7V()$ShF=72&k>bw{>`|KyJ=}(eJDk8UG|uz)$w4g zs>&(1A{{<6^CZioV>HCS^?>#_TeG?zYvZrBYx2E(o$DFrZ=`X^I?kE!;7$(q_S;zg z7X2Brk$9o&nmS(_&SZVO+dXz1x~?9wpB9`dEV!C0AMkALUh`vNzpBO-i`klrDZfA)T4|*Ye=l#gJxTKzSgFzcVWXkN6Ib_{I}45t zSkL>XA31Tfaq^iz?lHBX91;&h&(ym(z3J&QMvY|qe#SEb z(x?r*y9e=P?<+V{+NG|rpP$oa$j}T$j<3DrraPw+oDlOUXjG)q?5K$2=mSfsY3gf_ zFTbm$nSxCOdj?Tkjqnt4Bz|5WefsIwIBd);w9P^{#>DQ-|pp&`5NCt~zkq~fmq2jfnw0>)OSg~UYj;O`15oCK~zoDl@h zFKlUmjh)r6T!2H1M-v9BA3zSDUzd1?_CKytC($H_QPSbYZEfLojM?iiWp&*jDWzX2 zSX4hGSu3@J-J;o$zLGC?lDU`cgZSsZ?q9{^$9N@8?vyk+M34dxESvl-%_G26!AEkPjHnF3AcqI z)&=l=FOpSy3Q`-=G3RI_vyu#G-!P35E*`HF857M}d>Y=o*F3+Td2A*i&ZKyg-mP3m z*zKaG{5uzhX^e-^ra;}OXU&z{uW6|T&*trW*Y^%|*GH}6IyS&%F&_$mjTV(UnwhTj zh41ibuWWkId?I^nqDAq>dK#LLMs?>&b!~6USQF80{yih&Yx`qy?Nd(j+{B*~b?Djf z`5?-E)|D*_J5j3Bq5OxK5f*fZ&bV(oYb~A{^=xeKmh%G+pNJni1@myTsuNRC07cV8 zZe?SZzfx%JNvqk7bGygkei#@FwYqp;D@Pmw8}@J_EP#6mf7x2am=u$lm*Q^}2$L3E zp$aR8?0UQiX%T;uf0Z&QZen-bln(@tY@k1MaX+rmWpsMSY&ScqRlGU$hSVZP`~VXV5wHWF zucGbV$Bj=-;glQYYe#9fBeTKYjD8T3Trkg2$k#^w$g;y^Cw&ZzCUn|dOkK7L9e$h= zj_=(}I4xqWv%BH`=j7kKCMevOlvbs(d7YY{-a6){H_bO^jF zr=jpqH~3}r(eEehf5j#Jc@$hvMfuk`a4>}D&+~^O;vUEYkPn~;fH~CK)=`vsv#FIC zU~4JLtjntcQgM=k+Stl_xj;3&?rB+gJ+Kh8WEL006A?E0)Umq=AeK`%xkCPL$aOfp8K60^Qx+ zx!fUKFc)heSWr+92;v5Eb8{joIN_d-2r~~(M>svQy-PuC_5NUUgmYcW#D(;+18wzy zU@j2wS3|!J(AvTr0jP$}%wetwQD#?HTT3B60e&dR48+T64&~)T9{jfgbApf`PBUI^ zeuyB%(gJKQ_^Uam-^Bb&d&mN0gAk-1kSQT#=$oah1=K~9Sx!wEAZG)EBYwnX0g&nt zWCs51{{NO#NZb6o7LW%0sRj`wjgSg5WXsA^8hO-Kj2i^z;{*wEatmsKAwoRdLcBce zAZ{TLNCfydN~H0TtWuXJbpIRH-za}$g}G=UhlH553(U$2;D$QVi?jroi<_GZ@}tE| zwx3iYK$MMs)6W04zRa9dRQ_j;IXIw(G>T408fM|@fD8&zkp6!eF#p>&wzT*|U?*1> z`^(v3i3~5XhoWSIBh3s(N^EH%WCe3^Fhh=QGbblxRG=9Gsc0Z_Ofrj!APW(;2z#j5 z<=m67NBl_G+oI-@kiD6swJ5U(rzORRzt+bs$onsJ zs9@v2(jk@bk30w}YT|EnJbcLA_3{^f%FX9)mM z)7A@$v>N~!M-4-UDkDdj1^}qwXaxhHMjJ9JT0t6MC<5UIBllE!1tkPz`FZ%kGCVxU rM)+hwk`OS2kB6I2?Eg+-jEaJWBg|Y7mxBe&$IB1KV`P+3mBsr%Z=3RM diff --git a/ares_destroy_options.pdf b/ares_destroy_options.pdf deleted file mode 100644 index cebd0a7e02eddddf5e54daf71eabd53ca594ebe1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16747 zcmb`v1z40_(*R7TfV5IB-7L$}-CdH>5=+AZyQCnUN=T=alz@nWl!DTo(g@OsfCADW z|1QSk^E~hS{onsz-*WAJ-)GLuoO5Q*%zbvw8JM-@6}dq?{CLb=Tk!>W0svkB)XEW0 zTpXwlakYcn0|XHe9iXCvGaTXp04h3L!XfeyYp4xGQW6ga_kdWs;Q3^S>wj>a;l1%@ zNcYZ6hq}J$CCe**jRJ1nGW$<}rqYeD(dz(GCKnQeYP+fOEm}KP5PgkfhXPZel;pa9 z*R3HGMzrTA;|p%f*|8GO`)RMG4!)G@1(ZrHVr8F+%4DJkF6s$j_>lR;(3b_ZxZj1& z<@WQOkp|A~28x(H#P}-L#jMQd%yHg;u5`o_p%KLUBt20-2-Y4p80h}d8NN=WSeJy| zO(%NyhLo+$E3kf;ihNlq-t(TER_H7f*AjovJBQNM zSEH>$e6{x(^u-t+d3QJelA7uQ>+%4KJr%H@jNK@H7lmCdsWZI+Dy(njh!ayScZ&`$QoWvNjPcyNJ z_XFoK%E5^sSEf4Wwu*03r&47@ZDBR}lE4QKA3XPRcSyW7w`sJn$gnK+u9Y~O#Q331 zA=Wp;kr4?$rdHBayW#8i(#qVOI~*>}K}w^7qeQ`bn+IH*ljx4i4!4W$qV0HSS1{aV zep>Wk{kBefU~M#=_uacGAR&i$>V40Phzp~94kdDUDyEi0^P7N6FV&NtTEs!g;m`m}xOX^BweH?cf&TTK!)+Ol(wDQ=1bB4PQP(LO`v~q zcvq|VD?5Yyp}ImoVuKFWZ3<_PuJJcch_7^j&5naB+$Ut-Ex*(_hw^SDS$vS*3# z93F4lH0mZ;l(C7vZmN3FGr+hk>m&hsNc!BRf^!m%c5G`HJ8Sn#qH83u_eVKjPLFQ6 zI?bd&Ty1_@6ygbKg-F{&-i7&j@qU8%|1wZLUpEL)+tLmK)PUGHSjs|u04BVMY5@@e zfG|Iw86Hpv3P+eLfER(~0da)`z(`w0fFUrbr-wBJhOlyN52&>+1a1OE_yGV=58?wy z&?)%9m2|I2LCE$HB#KZ3ISA<;bnp;{50pcc5gcKF-=LrULpJflfgrdcItaMxAq)Ui zbFhH{Oz?j2GXo$vcp_OMx&0&s{U-fMDQ5|{bcWjfV)3*08W6ap4Wb6XhaBuxcYZPu z`a6TahJgpv($)ZgBqe{f^oJC6gz%7bI)C)z4=1Pt;==>+A?txUAYMGsRg*v+VLah~ z&>(SsI!;+j7z8OVpoWf)rnWMto`VYn#;t-Fi-Yx*Amt%2YYzuEIMf3Gx*F8gc(1Au zl6LTb!R72N5p}!*Ky}Ms1&|=n(7^_74>JMq2_akm@h8BGP&h9y9`cU-0}G2F>yb)y zMR;ikS33lmtBfnm;dfcr(+ZB9I!N^(Wb#}5Nb-LU!B|H}UiQ}zWTDPB{~7>NYdZgV z0ARj9`p*aY)qgxbfxr6x;|bAkF!<{GV;o2fB;*Pc@88(Js04(NPghq2mJlCO3&<<- zD=3K6E24~$7E&t6XCzF7pZ^DrkT9Mg2-$rkwt#@(RqYQRS9Dk0kWa`zq>QhwSD5?= z9!Lu09obK0uaV_nnnB)$k#GbINr}Ak{=i1`x zP6z5@>H1H7A?5JDQI`<-U+VfLiocYFg#1wE4@F&x;m3r$63K7T{SeU4Df*MoPlX{> zg8W{o455x6qC%Fgro@%vkZKY}JRzZo?@w_esgT$|l=y=y65}U-#QlfTu9Ssn`_KDt zr6J&dD($C=e;d@VJ|J;^jqXPq$P$v{@78`!)8FOaH9tm#fd5yFpEUnNy?`M9A5#PX z`k}`EX35CfpHt)NCGp$zk*?`?;h%m%-oe%uf_P6LUJNF9Abwt;tpgqiF%MiETs>iC ze>jT2eEeT_|Cdj@nsJ(zE{NCCfAN2^h*y;fw-6tIn~zr*z%K$uOaQPMa&2h`1AzJP zfHE*^=XS!cUB+viiNsSv5u*HZK1Usin|zXrzG*aFyMBn=BE%KB%Ij52FCCj{<-4TC(W z`RZdsNX&a0zO#{q(4cnrh@aWX(K!d8PE>}*tP`WgP}JQ~y{0(&#PxERVb<8h^R9{I zBIhOj9&Hsxk8yV(=L-prmyKq?dm=egdd8u*OGZt|9L*k#bCvULWFGK^FA^9vRH%-- zjtgelT;iMtqK5#|=kM~HyvNZA-csUtMD>J%UGBxGYl1pc$a&1@&Ch&XH_Lg``#?KR zy*JVVz(j++(3VahRp`JVtyBj0}oDdcR?N zgDrOBRqBfokI42%o^63M*jsPWZ?q6mdb%#=yWutwJ~$;c{PN-Zr?oBSAf+?*y?U)> zNmZIPZ?Wv7r2Z2O8YI?ln; z5iNoib$&_u|cqJ8v2+fg=Xx`~s-w&)1gbE~-P6=T<`UjCfXp|8payE~qnZR4ZIg@?bTY29P^U*2ybvz7IPE;;Z8^06U z3I7`}V@l5DX!EF&H)E(4q;zgqRif9wqtj6L$J_5pjar$kd$w?Q^aaxg5Z_==q?om@ zR!h^~-8XCrVJ000_ekfK;7B>rl1*7ut*<5fX(P^Lw-MZ=(&k9{)gTtx166H zF@12t=9!tcmg;Uv)8g+7Mex*d7C2EtJ_ObMBIZ1a#Mh$VdbW) z7TGJN=lDaC{d9y_a-VP_PhlR{SD-iVzTH7Coc_LEzgkWF>3EUL!2jeK|MRly$}jRF zT^k=j1i?#CSn#)3I02{mO#Y16yo6ka{^ict%2517Z*#Q4G;pf1=<1a z5J3S%CD0yd@9Sm{aYZ;;XP`3#1_QbvysfLJixtEJ=3w{3@wy>@nK(mi;lQgW52U9D zx*=FYZGavKw+wT$w1xoTK)AgJ1OoH~db-*msI8$M5TF;(_isM?pUe0^eh&QaeKtS8 zkkB7a+tUzNPj|9W5|jYbmS#R;18BU~tb92!AzCwNpeNsssvXRWfg^{8q5Sr`ERL?1 za(W30E>n;?9uDz!_h-UGmE-1-_bkc-nhy`>n`Z+y)+!IY@&dlhA556AIx(}_<-R$( z3|zRpSg<7~)WxBAAh4alCc|ddtU+?ip~bAd-x6f5n|?Hf5`Hck=$ysqW{YkYDG78< zruG*l?JaK00pkchs6DVh_foO)d%-5k0@=Ziyg;V_nl)|(UY@v(Z^o}hlw5wd*&)o= zBjbMDgmbA(+NnlD8n#4caa-2sDg0Rr6TQ0lq~VME&xYm#T9t1*wq6EEUvGa}X{9oJ z*iI{!RKz}C)-=}I8ZgRusBnsRq;#Utb^L&kPLwA1>!)HO3ZT&|e}#?AhJ9Qsy6W7o zjDpwkqtM%Bt%%(dgym^iC`gr}nB`HbW2ZE^SmQ{@|uOXkGtdH&1Jjy~qm z)mMG>P7gjaPg0IiYETYMf#rnSM3-kC0_}EkKS{xEY?^fy1mU`FTS|hfI|YsGQMJcu zg2x`EmwBYQX}9_qzVEH*Uv?y77q_J+x}n1<11{xp0uf9eHnz!YuCG0{Pr$QLtt|x* z**Jjl+1dT2<2V;_PYLucqu$3o>sPpIWeR=S9AWN8_{|FJLLu6yY*hHU2mr9aGM{^H zk+4G9aWCYsBtcLk!6CmkTJ3f=HUFAf`Yj@`!YuiJwvl4 zOG%xi8Mf7E;j`YGPdIfGraS%TIvqptKjPH~5fG?j#M<(h1&NQ$)qRnp@>uweu@L%t zRf?X+B2C)DMfjnlqS|WkcWj&WT{V+UrDyxBd#xckZUp!G?>XbfE^X;SoVD0ta zaS*o3|FC1vk-Tca&V7=SH(FTzs$xX3k#WNnj@;3;2$@Hr}%t4Sdr@w^nA|KR=EYDGgUu3>nx#3iPqn3AbE~` z>=mulPMJ*fHlB=Z?if>(c1tUMbA38YquR`b9ba8*iOuT$G+!Q8M#THQ&{XS`F4SLgm{V)^8Vg`Q(*B3yTwLx=iNA>pe?2!jy#13w$Lkb%BXI`#IH zsr{Z@p!Bn7?DJ(NjSn%=54}K8QKP^%PKq`S=Y1}pB=o|?TOfAXyKH+Q&y+irD4%4H zyv7RWNvBGC1mIWkQdW~8fW^BymTm>ONxB+RR*5{f6}y9N&@B~>A4?$lxRFvjzjyPc zPjpINtnXw`2-icCv2^Nyl05Ul=lYONRWrM95Snt=VlQ7~&OL|!0 z=lPG8JNu_=d`BC^DZd{1qSdg62Gb+z;p39RyzH%KJhy_K2BU|$IETLVF zV_7Dg`t617^Dn*`>3_t+JbJ{)eL=elp;BP3qAxRW!PKj(En0VWR&u-h@co(arN~U0 z?BkwtolOQ7d%8zCwT5X2*0UCVFV2sp9wT&%TJz zuM9e^qb>~e1#DT2b}fu&+GFPE**z#KX)t02@Atpx{YHhlif3Ub5hOKxM{5gYW{dVI z#Z8W{>q}Di@SDieC&b?pzI}?XzqhVFyKnxuMu$a@Z7fKs;OVn8qMGG04)#fm|0hetU8*G{swxa|?F*D|Nv|{?4 zU4_PGv?9sb%Vnf6FM~sLx?v~!963R<+cu`z>daVrPYNusw^6LPO1>r0C?!&RmsYG3s0_nCrxEa$7$EE8e59clR2u*ltPZHbFzWJg920v^P;5IaRs* zB-qANK9#cQrOOJgrIDrDeD*|t5KBCaJ3W^r;wG?s8_LP)0`^f??{{|eb_(6k2WN+h z=dU~O1SrCj1_ycA*xs+9#;a>&JR<7rp)^rS09!!`W+>*FBw)owW#w49L*0F4Y;35^ z$z>frF;9jRI@fM1&F^37%(@w{kmRrU`HuXBH>mOJoHhgc=HrHmohoDN5- z=mr*@+o8AAyQ9Ty?uA13E^AGB#a&DGJ=T1wMw!V2fg55d0yE9nBi)?ux>&`_0_7ToIN$L=X2X%{(b&Kji5cXs-1Q4qRoh*fIjfsjfB9o#JaueFm*JN^s-Z$ zmr)H4*cg}=mKph^S&z;+IiAYuYd#g)gDv2C_YI<>^omPs=x5ZHzUscnB}TPN8xPk4 zBoZgM>rv&RiN6Z8ahD=qwQRsH$)C7c&x-f z#0HSBx?th;DXr1k+ERaJTB*)}v<#0ds$>uc8Q(i5|90+l7E5d$%TgX@Q89sfU6Zz4 zZTr(p!2|OJi5d!D9`m3z`YI`4_*l#9xx-_Qp@T_UuL#j^AWyfOXOkxsern;31z+hq zwg3<4#@|amH>3dE{^%o&cej=Hk!G)Nf|K6NJ|k1@{oV@hLk_jB$};)+ya0I+8cE1* z6)or!%Kn7Acs!SQY5$C?-N7U&rnkskd%Z>HHuJ38%pnnHpLA#ro4@D&rP6bt<^ z)}I~7A}E&Bf@BxbYEUAUBFIap8-2mf> zB&=A!>6GYh!$P0A6JKpJIS^uiZc^~oo21oGpo(}tGlSi#z4)IJ3-5HV! z&V4~`_imkHaBVMpueFP8PEMA{tYqHcsN%yRrjM#jS4!QmA6+Bs>fAuN0onGGPVYqH zh5nl1*Juf5>1N9BOxJim*i>wt7whs4DUqk7_o_YWaPUIwHP58q?ytq)6s#MZ%*tcU z#{5v2JGkZt?s>=>faRp$d6K{@hp7Li9Ja*eljF-)HE*^b4p(yD+oqJP6V(NOWhrVC`?((OS`PXGq z679J)wLIQi8Hk$!KKCeOA{b28&uW2XI&9SNY?KYY^&sb>1j8h~D`r37^mHlxe7OdNB`K`CRC6#Gc7NP^mEmbg3>E^p+ z>u7{+B`61yvJJd!=L(tFs#0`kOpR?ZAbBs|R^05}n3$5-ZoOsx_GY|X?s3ijNQhGI zVX^UBk@%739WnHPy$#*hnzt*bUZ=gNqp2t>I(!z7ZfaQZlZ!^`b|8IwRCcLB z90it0T+13+0iequj#$*}Mi38{g=@ts#;^Hsh}nev!| zh~=vr?Y%u;j=fdFpQBwC#h$&zU#+0J43&EjOE6Au zTUcE~C$_o}smK8?+?E5ow>0$C9E~j`E%UfZETahtFXj3wFV)X~?-rB?`)Y3;qg_U} zq$WMYpW)pJnGmybr#XAuP8H!S_*(RkeVaOqjWi-~&l1N2t(&0Y)qU}r)h$Akl_qpO zPT#LJ?=x*l<8AL_=V1q#3rM{(1?SY>Y1t^cpM~w(Mp~PH@auUc;NG z54iG74fRL0ZJjX=k_Dy{lb`mgBqW!O&f8 zQ#IPe?n36Z8UtN@->i&)W7l2UMMl>%M;AGS>X&w$pMAuy z35|%Wi-d-zy?+xW(^BZ}uH=h=khcye*MF?3X$k`lsfTexep)RF6E6iK1t zpPH6czu-BVNncpSutr&h>)XgcjwBdJ0uHQ-UeQ4rVq z@=&nG{J?+J`};-5Y#fhhYnw@j(=uto7e?VT`fnW*QfRNnoJ2g`UM)98-hyeix^)fE zfLaM34me!oW}S#NuiNBJ$L+rglybj>FWt0(F&(d!N7v1}Z|wwWb`^dtKk$(>^hGB% zz)%p?Jk#sWns_F(aS*YD_hx>2+Lp_Sr`q5~%)ua!sGVWRF;pVevFzXBwSR7F{I}@Z zf7u259bN+=Hs=Hpn-0RiHy!?ruKj(_K^Rf|E4l{yZ+i|PK9TB8B$Zc z3aY98E3AeLs{K8dcD3t)h^W~*AcAW4S5dU9tr%nw&A}Cd*tdWpu5Ld9Xa7?O4dR6e z!u>sv2KR>kGnnQL^ac6>{U9FDzeUylxzYW{w&VXkswTk4|7TP!;Lgve+Di7a_S1GY z;;hn2IVb%Z;|{;_iRu^%)SD?P88$fk3BgR#K{j?lD3<(|gh?1SB*QuiZl&YK9cAdX zg>SZ9)Mh=87G37epx9@K%bRCu6)7n;xr+-6N0*48TBL$-Kf@ia3Gpu*^cF&aCG2am1X_`eBsS znO|ArNUKOB+nvII)u~?@=jjixe~v=20#-l9VLBwHj=BirbPt+RreT_Ao(B*TXGL?j z6I%(6$oJDPMNvjkMw_*xwMKs=!N;XoRR0>y+-`7R9wHf9=EW1*D*PICgI?L&QfEEc8nDfE^?nHvZ=c6^%~!?O!tJ}ZBDY#Z;@QmqWD`=F8QSRKBC!Z)Gb^C&Gw#9HmU*+^O^Xgm0 zHrV@*;f*i6q%A7q0}P{D*$?O&nDT;BTgOuLr1J~ZVUHp*-V?oJY|`qCA-Z*4Jm13; zHDd%1iff@x{zGH3jUR5rFyB69{EdVmlyFCs_Vz*!3mJjhPKee<3(;IXYr3VIV`@0& z7xfn>2G6+RFn;(_DE*{4OK__*amJ^2CKwy=nL@f1~(McYuKR_y?s(NP%05h zrDNEAU#4%-YGwQ3d_F(a#;$42+P|~^J&ReY%6?RYB$+At*t5V7cg~uF<3Xth;17H_)urOAC3Wr5bmNVf4cu=74XAS)vBu?*F-*P_{8jV8ksy6k+nUNA;1-OYXx z>;8J}+g-F`Nwa=#puD?yx_9baQA(Pln$>T+&f#fdGc$VKgk zJ6y^W>Yr$my>Hk1hB56+Z(%;`K7CbfP5n_h5%Y*#NLSarS19r*{H)HO4@vLucCBQg z2B^l7c0UTP=czh)n~3;fm*l*LeJu1i>Y6ECa+vwVFz!m9Uo1s-34PG#GF;Dw*K@JY zLPyDTn$1`io)(YzrOP{-T*Knb%g2w?b$O)kQb65}cFbotlPNPl#Mw8xU9D6+pTs;H z+G8uqu5?T`xhaVMc@d+@jkv#(iD;9Fd=o@ftmE<~twMp>S2Zb5)v=co8y*0ut(6!c zp{2@gWR*UaNGaJ@iS6I(e*4v6L#+l9E+KMiO@4e}eb+I;F0Pfc~1IcMXb?S>P* z-2JJdB}Y){x~2!9YVVIO=92!=g#djKUrb+V%w$moOI3GOOTIjBpVOUPN3jD)p4&Hd zB|lHTs8#H)sPjW5PmN+6rtaEo{!}WskCLerDVy%(w64PV`*f(guRrYDPEqnVnwKQo?!{8$F#^$BlD|eGo^<>7ma- zqY`XTX*hN(uWw}{HKF=}*+JWO2$!y70h1W{SH>qALg8P}tKP$k=r$t}a?MS0vq^L@ z$1oXKdB)(Iu|`MG_7P{VW7vlCyKQ9gxcWsytB>}~Sy55^!}h6G*+is1pfIJKH)N#)pm`Z}!v{-bR zo^6`o}aJx%Pe^=k={O7aAw zDQe7|wK0P~6({MJc5OfUOqZM%kl(dy)|=OSUKjKwne!FJ)N+zhIxPi7Qq(&IS@vlI z?J|s;(q#r~oRfKc>nYFW^>1sVsvdu==$Xnd;e3>vys1N-f?oC3w{+I1WORKK_EpR< zx1>*~^dJxCMjxlxqO9=FoPSC8R6*T(QpJN4O2V(#HD`Uj!nX$jQo0$o!=eh9J!2%0 zr%Ms0!7t==QgAlH-Y16*Kd!&6Y}$fNiF1<#TKHt;CBs}6!}n{)goJlgbNaXkFs%Uk z%Q(;^qs>t^ z+TA+{r|`$`eYC4>en11s{+y%O9ONX~cF;<55yhI?v;QPWv!`-{Qq}_R+PZ++XI&S1 zTO#SIS=x_}tu(8us;b{p@rP3tYMT|XV<|S4RlYj2(mi*7cN?!#ieV5JS4$&JArxE> zpF0b!Iy!oP&4SXcF92_-_^3V`T>wIB=7Z~U9D=>HN9M4{WF)Iel~*Xgej0|Qdatqt ze{d&5rCrc=M`NOkl=s3(&{XI^$ow&nUS?dl-bQ^MskrsF&9zykHWsaE>9O7Y z>Zw{>!WosFW3`N}yoirt*-U%wF$wbReI-PR(9a&QO9&b1dB<0Yy}Vk@1tdlg>g;FsIupIlZfSRa#w!>gNN0 zvBIMpn&9$9;w&RnGvDAdh9n8pH}5WVl`rnE?%2KZP>?Ts&Q>e@y`rAtE45Rv|6aFO$Bcf@_#&TnqkYdr7wUCEi=kb)^x%3UBU=*{l3){k&iEQr1 zkxUQcLecoThxRq_XnDpa*$(!&sP2v83- zvrR;eB2eeHubh$`YIOftmB*8Q{A3A-hzw=}gE8IoxN$Yf-oDXNX~{fBm^!-bn%vwA zw2s@oZC*;+72IeYK|5TxBXA#alFz5!6%D^9TubLZj926454MSi8(|IM66r>u)%&G~ zPM9wT&zUyp&}(Yxb)x%a9hH1l=xz}H{&jB{_ZB^mXE^gLVQLa>h0rM_3|#EL?bZYC z*4ppwI9=sGP0d^b-K41jhi;*hi+o_+_{10(J)_fWo^+$mu{iGirMdYL| z*)!GGVd_Z5#mf{J2GO-m`WCaUJ5Rpz)CO`ah!^S$u2~39h$!eT`JBHX}F{`CfLEK76rU`KtDYO(ZIBg2RIbn&C#myoR@o zPJxY3uS8*XW@Zi!wlVB%3>iB{lMAfD^B9d=={4Wqiz(-RX}WU{b9gAWJ4Wz^BSeNu zXbAg|&yU!92n16zbZOxGUXjO9t!@;U_o2ED(#2Xr#S~(!$t+|` zht>Cw<_UIU7wd*_NR!4!S7So_?;Af=4W?Fjsxp$*+$FSoEh;a74)gN(qr3H&=XvF| zjRf#uYF0n*&%{;TC-poH7<#B`_mp(2E8kX31ZxhPP0ze{t=vLMlZKh+RKzMajH&so zd*qh#pq(}yR&-m7X)zA646S`{OzhpEx1{&)q<-mj4RNG@`6X-lUw09+mWPqby^WweZhlYRg0UymwZvH4vl$gTKgF7}#0Ce1={rig6Cy zT=CKTba_3ia;~Vg{nf`&j`kfKYNbF&dF+=Xo`iFpTE(1d17|d(o-CW*CK?l%-+DPF)^n__{_^c)WHh zKIRK|@r$jesNV3?!CY8Vw_w%ZaM6@7!Zs2ZPZ%9ZE5TPDNOfK{Xeuzvv%PC`VI5-j z5{H9B#rsWx9#|GErF|l5;a=|{HL=9d`-FSU3gpU}vbf9jXp|WM-1{9vZc7q;>Dp?1e`57t9Y?7YxKv5X+%nDQKhR zn-Qxfp%{gIQRmB`4*s_#uN@kQ7+Ei0b6xZA-H|=>S*A3h62+E0dAdxAVuxPOyHp~? z(iTDD6fnC&vaa@W-pzQ$j-dbzF?2jV4y0iNC(IPo6N)h(GOI z|B=$%R7XeMUrq<+WF4U9WM!Q_{LBiUr+O>*wb~fw_d_gBr)&>LoAFDWzCar}M%xbR zFjWSIc;9eF$B0y;?I^l$o7e73`I5aRI(_OwTWHw$b?TZ$o@FVgX&ePU9*Hk0rCSz( z(&D?mSI)TKS;Ywofp3kp!ohrCfm=zWu`0PQaRdz$q3G2rV0p0AZ4puUa0+ALpy34d zF0X|yLoBhCRK6EwpVy$c6)I6iqdUd<4to~yyEGr8aN;hq23CImWVu#aw=Y6NgHjk; z$5PP1Z!hYgn`JmM>NWg|uj^Qb8qRLfx_F~rtVXR*(6S0Se_)b78v(^-8}Yq_Q15>b zU_I_h`g-pU)<@A}Oz5@uWuIR_i{ZY(7vHkXBfTGt#vTx(ZB;(Ba?UGyQB&IdzKJN8 z|L__v_B|@acP_kKH?P+gkJ~1Pr&sgO-E`h~{dxs<#QFImv;*`gq#nb;YUW4`& z${AO*)57lwZI4DvpU7L9W-I#vZcc{KMJ8HX?!>=Lm)_ziRvAUFd^Y&0!G-76$etxl zG+J@4yXzxfN5}9B`s{wuReMh=-+CxbjO5|{`t&oLLlD`Qbs|x}ceJMu-dLAkcRG`q zlv_KN62z%r08G59IlfRc5AeU9=r&&%f1lLtR&duy=tlULjebL)qkzwh!IS}PY#YOx zEh8m$j((jH7?ihm1!ENngNXgU$qo&O1-v_pXNjQ2dF72?x@ApMQIYy(+PX}9L;HS* z|N7DwqN=tNl*ZxV0rEk`2g7q3G zjPq^PFfNi|G4xw+8w|^zjq~G`a}yNXN(Xvc;?K~-ll6Hei+D>zwleoS=CDHZwV}^j z)&@Rv)ZDn%DI1y(pU218wIJp`9{6`$`6`j<&tsdvQjGpO*nLMs{nx2(5SU-^_X$C9 zDIdfEMJEUxUxS~mk-Ft$Bn??hWWa}Eq%CMVT_3O zt~%my=Qo)vjOVIPJc#3;K!-a(5Dzc#S3|!Jy*fZ$0mz0et)QN8306-}2OCjAVIc^w zC9eRt6+}Rg8w9ciaq}WR+}03FurQe4%F0?$@Keve;}q ztsx!~tV-JI03~}U4E`g<3V;xY2rKaC@c*xRh0x7^mI6YdKgA%9z!B9zBw*S4$|Fw0 zO7ii71i5)dxcNl%KwwdRK2ZUFPF_AyUS4tFKQIx>N07>09isi;kp6-B2PxD;4>2Vq z?L45iwg4~Wfm?(oKs3FmkINKtz#SO-yL@I^l-ki4jXGA#2JF@8w{al5TeI6)}pph4;M?s+_rRc zLnQcF!V!W7BIYEkq&T7y?f`d&NM6~Vj5GYlgR=wDmPDN`UF{@TeYkBPww9jGa8^lu z*DGwBAKGwsko@s*MF;$g*MHE}6$oM52(UK#uC`DBa<(B7 zoK@rjCgQxZiZUX?U|9tjIk14BoPsc)0xt+GEF{9uC&J4ImY4j0$1p=CG{fMQ9`LKl R0un@I(BUyND`+X={Xdp^-17hc diff --git a/ares_dup.pdf b/ares_dup.pdf deleted file mode 100644 index bc376a5753a504261903d6ecb2ea8464d1025cb3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17284 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 z 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 diff --git a/ares_expand_name.pdf b/ares_expand_name.pdf deleted file mode 100644 index 332812ae4c384a019d4c878239b4622421d74638..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19482 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 diff --git a/ares_fds.pdf b/ares_fds.pdf deleted file mode 100644 index dc7f2d215e953b37b939f8bf018fb7cceb889cfa..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17835 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 diff --git a/ares_free_data.pdf b/ares_free_data.pdf deleted file mode 100644 index 0a940b1db9e010522e7fa9d9e369d486afc986dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18022 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 qlY=7F0)_Ak%7MlH-w>v#>Eg*d7px(E4 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 diff --git a/ares_gethostbyaddr.pdf b/ares_gethostbyaddr.pdf deleted file mode 100644 index 96d0b15b69907c45c69d7c8b016345a4a6fad145..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21563 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 diff --git a/ares_gethostbyname.pdf b/ares_gethostbyname.pdf deleted file mode 100644 index c6608d315125633f3f836292861b538f54825011..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21928 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 H&L+PDM?Tsw diff --git a/ares_gethostbyname_file.pdf b/ares_gethostbyname_file.pdf deleted file mode 100644 index e4c53c3fd1e02a5b9ba7a8404f79ae30a6b2618e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20979 zcmbrl1y~)+vIdG1+}&Nn!rk2=XmDM)yKC^^5Ik6LcXxLWPH;#F?!g`;*?Z@ld(M6L zd+%G{n(pbYs;RE7nXdk)hC)$P{52B;D=fvp_vjp0HeyC%TSE(2US5DK(8kosjF|no zMF}8oZsi1YAO?tA88`t&fkw8*Kz@E$M<)lMfiBJH9$++ zd>^UbK*^AWfmRv{Rc9w6e5#d(EVWWkMBR^&+r)dL;^s80sjKglCxO;gs`HNWs^@f7 zG-T|L$zO(iu6n34dFNQtc*okulRYFyD~uKRMeT??k#Y`YeM3+((FD+0UrE(wY9wWT zNDJwBovZgbZNDdJ+5MtIV}Gg>PJ|ObkA*60#aYVfT`tFnr_9R4kn`2szB!l)=3V7} z9q-TmMy{U+>LpW4=`9@4u&mQ3u*wfxW`Tfon4~2a?28Y3Pw#y)URw?0KqLu%hp)-b zjyMHyqOrc~!0HyU{d`CvuD>M(wJVaHTWRy*<~D}2p~&dYxU10vU%lGLEpDv5G;Kf` z<#?y3K|Ag#=AioC)svX1YeG^j#)L}ByBM#@Hw2T*c?t`Q9V6;g^*9(C8$$>?8Ct)U zQeQp9;bX|LvYsHXqN%gX`HsuOvPm6IMqgk|e%S5!4;eLb_cZAZ&Z(-#jqeI%=wONK8X?DLrjB{QZ{TQ^BC)bhOc#kB29;mA%)5s49!TG*=3@^G@U)ST66C#fIH%z zCBQ`rN_h)J1oBOnS+`D{&EUZ_X6!Ua^JR5W-{o7x2kU20u&zIN-oqh3R6oFm&ft7i%%^p5#|wkoD}SksSaZ@T}V^t|NP02^v6Ys}Fr&l-$BL zN&&55Jz}8;jx&ik#KuObkcxLYvm!*xY}1ExWi^U^(QCd>2kU62yj4ul9gFR_v>)=D4n4Z@^Mvh+DKNL&4I=b z*N(-t@1bYE!lwpwj6;1x5`8k_exERyCyzAEbAYUlEKWujH}|O zFgiupfpYBk;%e&UR4;2_qLi6zo@evAiyw?@kOMJPVx@VuERBXxgmF5plAy*azni%C zss|jNSt@+hCm_j?Bj!Q7VbK*T8)?b)r!t^)YIWc%_Xe?=_0Oy;fwUK@UP(v@4Q~kV zf^$o7mvm&pbSZlw!mg>&gueI?Xz^`8`%Pk&j`Zyc?oagWE)IM;6%kp0wU1cF=9K~p%wRt>_}n*~WJG8o7((B7u}I&kBF>wD0LNJY}% zJ%vRaL~rA^RsUm+mboff(6=00n>CX-s?s5dtA|6#WQ(=}dH~{e@A^sdS`p&x{pPG) z9*7kXuyV;&6^&CTp-s{Za%^HRz1X=o;aRXfVFIx^Z?-wm;1gr6M+175G{`a}9l0fy zY^2ij8E-7XvQ#UBeV1DO;cL77c{|0oKy$$6s|t59(I$(hK0&dag1t_RWuB^475cb` zKgam0l+)JUUa|(lLM46+(fF-}>);Nf(-DkUY{i7=py z7c)7xS)bouz~;<>ZM&FfhdJ`rAcr2izGpx%^wu*yay2JH0w*KD?$jOdLv@MARdp7m zG$ZR3x+=S>TUSILZ*yeem#!`YQQS^uYmpjdNGC!_bIe}u_FZ^0{+fnp^z&Kq=4q_9 zrioJ2aL0OpvcB;|EYE7p&Y{QALUYj6z~$a@CRMO~EYXKF-H?1KkS#F*%NFogntTbK zLiUB&;{;o=CY|{kh-n5ot#y?g#0b{0?Xr_l;9Jf*d)M~Pd`+fKZpxdAQV!`XECY%4 zn;tbk4CIVe{UHck1!rtRNqa+JWDAh>3NrOtcKDHKR`k(g=S38zHwd)T!uK}a4%ZTQg;%iv?C z4pV+E;w2%>OWQhG-j9^tNFvBFeIM_iTW zBOODDvgc~&IV_Hf69sC!2;V86)TVq#Xcsl@U_+aS8*B1&-%TU z411K9Rk&beV5hz?5e429wzTj%U!A8v4`7Grgw`aTLvY|?6M+}M|5Tt6&Qh0j#R8lU z96b)4zwSMCc%>8!AXrPjGR~FAt}|b@dLTMQVj08 zUOA!>wez%pdphRt=Ljq^2hG0&&8;dANjPZztYiRgA6S*+OV}~E`EkFO`3LafYtYec z_W_5)fe1!{v15!_P6f_Ql@EfGD&g$CP@jP6;!HUSJO^j42#3ASzz||>0q9OIp5f=( z$fbnbCR;7LFLcALUa3dDl`BH^Sp@htW>MjwM_V2BmF(H>Y$*E35IM{4*gm!IO?*Q# zpTP9el^TFH#=oPD=h{nz@)DQ4l*~-5oUp&!SpSJ$RNU==07U~+AV3aiY;GWI>qe}_ z_}tCL#YW7@%B%wmP_lJ;j%A1$pQ#*xHcrGWFM-Z;Gtkl2*}(|t_#6T$I@lU11D&)0 z&p{F~Kn3XL^voyb<|Lu~la=Y^de1E4w$JQLFQJnX>~mBE5P3d-mgq?QchhhEUM}$~ zx_XxOtRV4E4IPOAGUmpP#9FYw`6BH%E7RYszd1z=oD8gNP5%<{TYEX6 zlY#Mb4>9u#!%ua73*h)y0sjmG7NDRgN6f^}|JRlNu%Z$N>D<_voZo?4Sv^|n3(|T=EhEDj#|VlEG$3& zFS`8x!Tu`Q82@hhtLLxsH^u+g{%6V05`M{NWqmQ<%aNJm#SAa4ziNNAaWFIgY<=PS z#lynMMf~!Aq5IYHqRBJ;i?`W4$J*vLrq2Vk5wdYK|NC6o+0g05$6x&DdGh}DlNZ*1 zx3#jkl&Hp=-?kREwKD!6mj3B2|Jl+k%zs$=+3de94a>~-%U=Iz%=owUf3^Lh_<8)V z7G~pkk@EBSO!HzJc6N@RXeDRzYy zpHB1A!}(nM-ScyDUU*)pU;6%Wl7DKyulr2<(@mbW`LleH{jXZRoW1Dx;;O%Ue%|0O z^}jTE>HmxCFv{*d^K>*tY;{m+LAG4l)6e|5f}z5hR* zkA(|h?`->w9hjS%IsJA;Sf*zmu{O7HcKpLBe?IL0yx5DA{j(VS^hS9DYv6xfIE0_q zc&*n=EbPRunV*-U7wfWfvFN-&7N(BGEX=R~AxEQ^h5otqd5t!(lLWr#^y~EHLN9$U ztgwJz%aM?csnv6Q01Hrd0$QsPGcj_)0_4mc9iN}ZKc9gwZVL-|`&$g_a~J}6S(=^$ z25Nu-zz6^Ym;lTG<^W586~G!`1F!|y0qkC44J)9D)34f3s{kATjsPcslbHh$2yg~C z+ZY2K9F1%pfB<)zpTm9zUw|ycOh1vBf9~R+=f4g13!eECoq5*!&jmu{FF1#porRO1 z|8L+1s0L$)CV@#nLXIS{&=(#6A!xr}4(uzA?hVar4?9!JchIxmF7q_{TY#d)^9KUp!9bEi9RK=pf!ZJU<`O)d=@u}ll zj{_lv8!~&!tb!aU6I6|1f953RVzN+~oGd}Mt3aY#5PvQ;m7CMRx*5haIN4E!#}PD(RqVoXJMt-nXc?IlTGt?VzD z#Gn^b>7NdjGdXAEnW=ME{4l-OYN>vg>F2rMql5Kj#~f}EyiB8o-MGV@5fkkY1^pA) zMNH%M{c6-utk%Mi4ESLn2m((9RizN_=@0S;+Nyxnb>qgA%W^;1bwMgptT0J=A*T%q z+V-O?@gxfgd+Nd{&UN}zaN6T{Nk*!V+s ztb%N7Ft%IX^ednv61KjB2{}ca40j0$;M-dc zIv93ill^>;tlg=|6loE!DwbX5N+VO0_~=zv;_0@e_JX8mHef2!!vJad(JZF<`%fN6Ai?u9W7BqcWZG*CAh&<8k!ov@D zOjl3;RsYA}14h@TnH^e|CN3U1_Ov6vQ#W}=47(wBV^$o6eydy7tr0EoRl6&4%BM~n zh+CC{9sHU4E4I%9czdyy>zpmigmM04>kn<)bXxrRN+WcG3_~eYO0|fQ88?@+>Tkc~ zZInMU9-~Sc__?8Eq1awb;f3XWmu~o?0s2G8Tk7FsJ)5Z{$skChR30sA0S4y2Q;QEj2j3qA^tSaWyX zaPTmZD1QW-)LDFJAiU;px#0S|W?y|oE{Iq19yg-LV#|E+gwB9~;$0(d9A!#E*ZM;JE58RAUKc}mHHzxU^KAShkLAdJfi}s~+ z;OY=0%%C6b?()Wlwhhm890-~W$8LM?8Yq9Xw~vyY>$A4(wRobLg5s7c4Mk%{^eV|F zQ_yRa3DTs-=MbOPqHU7kay?m+o{dF}N{FgpxSePZpL!}Z>=DHzcSclVM< zI>{jcmgOJ=J^-(`5#-nIar%+Yj=Eu>KC!fAz{mAlg)mXsM1j^0+cGT?sHEv*<_6N@ zB?1U7Ud@I?MQFw=Gh;xD@tT`#kPM+ZL7w~8J*c-GW(X%v9dGAJr8@MFKp8*b1k)Svw79G-X_3g`>C^$)Pk8R8#aK8a^JHyL;^9p{7&% zAWW98}*(OFaezXQhCeWdALUU z)$uDqgXLEK$ravvMp+~sKX!JZ5Jb+jwg>MvAyCD(KCQ2=>K{HEY#8-^71cqp!#JJ% z7O4&=cb~NE3U{5Dl!iu52ezICkF42dYK5$p5Wk9sZuYR2XWhh^gSj%Xp_&R%|R9!uD zpP=pL=B$s$HqobMtTz-kC3q01@2 z4?OlH#P*ZIUS)X?#3p9TwUetpNEVidSeSW`#Pp}P9`eN&6i2;WMp@lcr4ky^?TStm zKgCM+A=xAzCiR{bBAk3C_K{7Re}vE^?X4Q|m6Ch4TkAXl`mze%P0~9|addBCNoROKB>sb~%C;MOFJo`VKpvm~Py{^hod7BTRe%~m z<2mMk2Be-hI*yhA!{_kd$ky800AT!c8(?A%Fa?-Czbt+3|G6iy0$2eZ9e-{MY@DqP zp96k#)Bk0MVD~K6*7)Z}!O_mZ2>85R_+K^({|?#x0sZ~oHwvum9BhAV6rA6}s3^}j z^E1UbDvDC@VN6o;hak$&Eop|-k7Hn<*n_AL!-ICC6APk}lL%tRW%%O=$3UP8LSf*5 zQRg@paw^OrUa7TRUs_}~w6!%ftcJ9>Tef+3w!41uI4Fy+i*p?3zq`MC>NvjZAVAz; z4_de5oVk)w>a7N*?eDdhalYiTzU z^_&{1A4uiL;1fQHnhxzk$|&b3?LkVrFmV^*HI_NZ1^4UjB>1i<^O20_Ej`Hugiu2_)VL+3WP9^hd0U z2VKpI3RCoPvvhkGO4r?T4cjr?)S%Wq55T$Zh7OXPu91Bw6i0>$f4zM_zx^a>Ru%p` z7DZa+1G1g$gi|#8snLKy7jt+SsrC(lHUS7??WswHroI`Tx zhl~;PgY$BV{A!Hr)BHk9R^aW|Mvm>yL^~So$lcCp({qV5y%1M7JHBl%(5ArQkM9r- zggtYBEkT=4@T&?J*ZgO9?mJ?&;(iQ6ZVl4WJGdf+rz%QVscF|m9|9;&D817Md{56$ zy4+<95xvpfXSs=uVOQiezsbYh2z)sV)oiDh3g?vx(v>YL&bZCWm_fwq-mxRWN=?DW z9n-8vzRh+AtOc<4&UA8Q=`T)%0$4vyCgCAvAx)x+nVsm~a@|k%8^dId()A%NNXiT zhD{QA9|mH^HOr;mM=xr(+r<#6ZmS;UP++izC{#i_*`6;)t^Tu0Hj-wxo=-WBr}63c!A znrv7(~jM;O;)9lwB;iYF+nE)I49iF9HqHM{DQadOe(GlZ$x#^Bijbj)`( zBh|5Z$u_tuDjJptxQBA|?Bg8J+4C{#OKa=o=8mpMqT&jS6D^#+J+}0LnRbU2JqNtl zNKXiX%wXaS4B*R`P4XH9sX{{$&TQrv1Smhiqw;z}^q6Bpnf zqMb?{87koBM3x1XP{%+rO63dQwyD{hn|@*r1;A?R>!09IR1|WVSB>mcHKo{hF6ad9 z>906#O(q^KzGNR~8Kvgj&I*)uuUp53bd4t~d&p2tTw1{uGV<{DM^juK|2zX8ma&ly z!~8_nJz(Zaxu~UG!rm)8Nlz&NfQ5!SkOV+&a{2b1qH#Xvhuzpy`b6v1M9N)OAUY&U zX_T}K_Ft+$&{RP-8G-O7o+b>+k-9@C$&L4W9^KJ##ku(NAX(tLlt~ z%gf(I+Z`ck-|%?}_S|Y1R}~k&MFhHRjA5yUAnl4b!wDwB5z>{C7Exi z%uL!4g2X$5`6+u&Ue{UK-5rA(8l$;5?yA*54lnERVQD|}DC`dF8m6Hkk4p$^ZtffB z>U2)*GNg-pv~PA=Lr_p9!Xklge>&~gLYCE+z&=}hj|}bZ-`YY@E=AtU%pxU zu8_sd4fZvCvszEfH{VC;u9>K+XEm(i73lT1!4|>&kfsU!V7@cO{lM7wDK6O2=>tikI9W&}xWZjtOV!X}t)+i!5 zb-*qUT(eS}J&>UM;J9YfX4@;&kr3-jmDB@8kgsSBJUxput{d<7n%-DN#1d5CguWH( zSiEm}zs;SIsi#>yg9WaaSU*ksPIcQgO+1Eb(*|}Kf0h2=(At{cpbNPc7PdrYM2HJ$ zS@#kBL{Hl#{}{!FBvzu^K+G$cTI}PioI<|9SPlk+rCTcqkpdMI9nGBB-psDp zH{FZAk2vj+dsg?La$IqCtnBiy=oA@Y0;kxTvn!^SU<#+AGD5{2mBGMrW_ZSB&phK+ zjArzqUhh!YD3Z&>8Eszed4UxY19duL!YCv4G%Y$UFLD&ItD2~P7R>%ODhk^}HnVk)vEQB-n!92dVpkN^6np}r_ zN^Qm%Z6OU;A=3-=i}AfzsrQ`fp$Y6r=r>H3k_<4-q3^6}~n=|LxBM ztetr)z6^GgcqMSf&et?1bmm_AMI8gEATiWVytqM(Q%8fuTdQ={#f$f$Qrm!o?rJ!%)ql84EcmD{uO7~a;rVY^K2{vPjWFF$X?<)As?lw>_gh7NItZReWWIl zp@R5kGON4O@casm_n29b(MduTw&O0m9VDW2c6`hX`AcgD{ z*Y4ub*O0VzJ^KpN-Kes>H|U!0kWj+k!A%Kchuv)mdxfr})V^wuM1;ANVkIxnHFuNj z{pcPVvI6EC7-G;(y)C2^3dFcZ(8Gc^AGoq$XxMPxcRH!ZV`cl1hK}$3O%tIYHd7;2 zo_*Ggt*<#J$4f}aMv8w@acF$B+$Q9FHgSE8jYkCd#yr3(j2)^p|0;|jdw{o1GB=Dq zoAPd2K;F)$tNM=QK6Lql+w1$fbs=r(w6{=K2Kfb>Q;Igi7pF#kXuUU+536`)Wgx4u zr#4vgJGc#Rww5KmvuJs$8_~B9&YaQd4Q*z|KBt!3wuqjCv)Y?$1jxF_x!`5JwGek= zR3FEx^>pRCgZR-kpRI7OUUT~>3$-PYDd838yFwfHp>JG>(9-p_LZO_?CzwN=NOzI& z=o!O4V)$NG>Ize(`;V(jpDwUF)&Zy+vW>f62ld)l<^{e`zhW$9+Wz3LrZ@T4(z?9p zHTXJI)=iRclk=$ppZmbf(!2XRynfdiEX^p&V4}gd_dcREBWiD!Ka+0*9>{XDLU6a% zbh2eR9Yo#FZqJPh#$Qn#US4Qf?NS}q%?QcB7eh@(c+=gIZ`WLsoQAI}f?A0PrEKd9 zxuaaoZ{R2~CMRbgtJ~-PbeWmjyxE>~x?ddxSIcPGpWvqs%DANn_??nI|qRTF5TGrEISjCr{csyDMMzGbtxrL@4s^)*4bU z!Z#=Goqw|1?r#gpFx`TjR{mC=&Xa(S(QrzuNlROng*uzCRA=hYTvytlbFt-Ww~G~v z1kU}=Y$Gt*qZ)s`^w>=Ax~z*|>|RPJ=@b84dxW7D;^$e|dafHgZ59!+^8NO z(xWR$k%}V=LJW?!CfvBuch~xBgrm;`?V3|?E6AMj*lsN~>h5{8*!wibzihy|&G!*3 z-&#nV7A|~5s8`zO4Z}SA62-fQuH)Yhc9YD?Up?#HQ(sBNeCF~d5*G`RkFpE(ZlffJ zWXO33`~=VbhV@z25f+3BP4WF92QAvXuE66t| z?_FINI1A(wM>MDSL%ONL`gUAR6YJ8FdaW{yfl7oYZ?jTOj0r^54N8}^ulohQ!~+FA zb)!y=;{;Fi;!4+b-(Sz;q|yWz9evrbys^X?l9f2}390n82er4-KQ8C}aG4sOB3?E2QK=_QD$H{9EaA44 z;pF&#z>Y$rnbBC9nUz?wtNMEsD^De)re?ezW7^YVhG4IfG76pg@S}IJZl{{iUEM~G zJL?mym~;S}?I#sZMZ?!$Rln8o(=4XOneo->6^AA*)ht`psUEr*$S44Tu9jj|(fqyRTFM&choHK@^nI8yO;S{)GRJHqdSwB z7`)Q}Ml~qKgB|d_LaKKc2zIlChulZt1hQuuydUMqy?h*QF}G|dUw_)Vph+witpE&R zVHP<<5@$*~m}KxCI;FSPU!tF_pgOR=p_h~$i`U0O_9otBVU@(?z%uWpP{ABEBkkMG z!6maX4eW@!$7-Vh-ZsmjqsqaD0Yi-0VwvJaTC<7<^WV|6Zk#RG+~!P7so^$%!EcB8 zsOV}K9DqncL4bO4xG@laH!|#>E!&BOBTK2DtgNgNLnZ%y5kG*ZUJ7B}UfYfU%QFq= z^yw|W{kHLa3d?FiaBy!y&teBt%ol4!<;<8U zUAE4}Bfzn5Cl6xoD#wWu%9XRW?y_$t{lX7$0Q8tkX2(uQ*m(uzkr0DIxI%ln+c%2n zOZ-~Y=9{(EZ6e|zEoUs6;4MhBTVi8p3y*xFzbdc%! z>_4M}%v}Eo9sD;y@C6Q(_z4I~{|yQL1qi;tfxl2dD_fgCu)v==2hWKC&xoLjxyy5k zz;m+UGd5@jFmtyv1KRwZF7Puw;yG!+#@q(@oH=0oeEcuj1HZ9B`#}O*#%Cnw*Lwox&T}OZvU2N@bB4sf20fj-{C{H=WLrl;6v}f;KS|oEkzZ>m{5+Y zKoLuV64hDmiA{*XLfK*72@*$Q7;+x)cgV!>284<3$g@fq=_PfXS#?T0Zim*kT1)LM zNVbk&Jg62Ljy#TC___^aSq^=lo}Lh%4D=Ca7@-20M(Ai6=z&2J!rGFp4|k};i9)Z_ z#UFxT6z_X&(ONY0G0{dH%=8A!oO7@pvpv{XIG~M~v3bBYT`0&+C?&*1^BFWLvrmrv)|siu_n^F{xSLQ1D0Bdt{+P&)u&*rcv(*5TZjb zLeDP3xlr&L%)eGU9)DZYt70~rORXa+)#@i)FcuTxK zZ{r1U5OT4P?vB-uKRU~Aq+>av?Y7%#?mML&c0Pt?^s(1uj`FZoc_EcBr|R}c_~D{#yM&FlhLJ89n8SERGOg^Y&1~mnqU7@Gb!-?I zt2XFG1u+P#G$xGwGR?)&sH=AH4fDHJ|V#^>?zA|IYL1| zrRMKqv9b%Hv8Bk@4ug8WSTRhw>)1bw8Dzu5<^F!sCTV!Z;j4ZJrFfSl@UE#IbJ^Vv z^a7^E5O?bvS_I+;L`-$e&nj`>^(;zCt@+@xdQuH)GeX8Up8>s*Ta=5ErC##8IYkTa z{SC-<(H|)@MNBE#i_jon0Za`i21(%PsLixSJ}Ko2d)<$a%m}Vt^9&$bULqeXrMPLr zp)9Pyb5D8Ro)Mto7V0CWc9?K&W(QS#5T@F{=sAu-(oyq{-aXBONw2aTnbJchZ1lZL zIY}*d^6Adn=f6q6*LoU5SyO?e%3s7jS>tr9P;cD9zKB5-nBr7VU2!rM;aN>i#N7H%tlpP)yqR{16jYpj`m@6C3OjkT0DdfC2 zuyJ;$llnhW7<6Ucvt@5)@flGg_S0xm4;;ux_v+KrA86C8~qiI}KAX6Ty!xH1cOuWH9Tm z)$yOd5jwY{m>V^3Ui$oWvdPYxF>oa|bKh{x{dMYdZ%xv7D7FUwH|JpC{mFK5KSI&o zVwv(INN!*78|L(x9Tix15Vb40W=BWw6P}Nv9}bZODe4NRQ!Ayiwvk`*k<3@Q429?==|>Ag&80gKj^gb4sgT;67xBIQbdjbzTh|cA2;OJ*r_5fTkjaA) zo|xz}duYi}ZrbA2a!*PLgQ%k#r5b8f;b|cB6*XGLi`EN?; zFPSV}d!cPH$WelUsav#=!vJL*Sy#GY)%=>4oZmW0;Hl!B=5Yol2_I$Fxt1a0K{$wp zB_`x)tpDUqp~{g%b8zN;#p^slln}&}7+VzSmHikjg&-?N)_uvwlP4H=r0fSpk}vuB zco$ZXRb#|7Q~bmRyxOu}MXwXlt#hz8X^V~7ExhYy1~{^pA8wt1$6YPy_%~P|@YR7O zj&p*L=pOF67D5)fu*3~+H{Z{!xE@qNd^wxha_J#^9Rdwey{^Sw-WQySnmIGs(6WB} zN>JtfI!jX7`WQpiTPJGla;R+ME=g&E(0q&RyNhs9Bj&7QOWMI*NNUc!%5oLW*PO?x zJ~MyLx_yb=cSQHl&=|&>3bT-lKdi}r#DsFCHlkU-g|&Cvz6(zB#&Y+@viJ#wx9t9`U4k#jSQvl=I#pV3 ziYD$zArYSdhAq6*fC`=Og*dz;@tV_dq8jFYcnswoeIXeg$Q5i`!bDazOpi>66;Uj7 z=?0FF?RWTm~ra{C`Hhrtd(V0;BFgL=nSNFh(iV&8+nScHjw zOva>(0N+kYcI5NAL4O^K49+_A6-+Wg!m4TgE~~Akw*BM$^2m}THd~UF^@nJgM&&~R zvAo_!ogxO+bsG<9vf^!4)Jwu{-Bv<#v=AdbZY!-B z4c1J_AVv(lO&`XWVLmL}+H|e&=PU;*V_|3Eo z&AaS^(}A<|^eC(GVj3s(UuC;b&hK!gtG@Z7vXrx>Ii<-o^@&CW6eeb9I?ia0RwJL4 ztYuJ4J43aU2{tt`ul9###Ce*N)3AKRm?#=`B75dNVcS-K-8Lpxv7-2%L!Vt$VrbGH zM%r0~4DGGL#`h$%*f)9V;1pQKw2nD!%AID}CToUX>`*N22HhBFME0{kknIhxq-Z$! z(qz*Bs7GlMRqPFuScGW`J7^RbzH<=!2}OcY&v;)EJ?Go;hbCEnFMomP-Zb=$tWB7 zqqccpNQU!*q`&2HB}(|*U?Ble$+l}Q-H#82hR{!Y=Mj?Jr^Vq(L#v9n zH6}At4Ox$&6l|q=IQ(0QClve5or&nXvxflGEB`U_OU0R9w42csXZmkc2}l#s)^4n4Op;1SGVw? zD9VFil}D_Uwlm8=s-b)^JBlA^xX*TIc|VOhh93A$B0QXETMok~Msu>W&=-`&OgsU> z@slRTAgHlueO{)*YW^jsAa)U_@ih-*vzH>spi2#DLbMv1!Rs*07F!ZEQcMrHG0#Rs z<_ebusPR)Ilz#0-rT83V4vwAqHRf{PM>;1#qpx>qy_sTOmLf5&n1ohQ71`$J>B zaw2~xQu-)-1UF7=uA{l@8l)f-1^wEr@tiYd6Q%&b;9jV3Fa~E%k|F$cr76<8`<}qlVt^LjvZ|TE~ zl*>N!Ly9$1(nFd$2rC+X{L$FSkTfP`LB6;+l!-^6GI1qu&SHbW53Hr>fYV?iPpHB1 zwFp&pklQ6-+Z>n(E_Tc($lF)~*cx-OcD1S5H>#zffW1UY44PrHXjNU^RZJDv*;Ohg z#;{EEWPuj^y zc7G``WrpRDL{FWCRWlzYX^&vpk7+$}3d%#~uO({+ zJ(*o@$;ATgraf8rLnIWwc|f@ni~(O~fv@l`*7W#s-ZD^K(3mK~TA6Acz%4n@v3g7* zHkXcFn&Op~t)rT$sLN7R!9^X6>sV6c>&8g*~jWA zd=GNK48K+tysD7sdzi5!`lgW7cIvpwiCA`v)(j?o#JrfU^tYN_Ff7LC{h1=!j9(zD zEdhF9zL0IxSD*STk0PDv%mmqBPeK-hG@3Jf-(vN-V61+Xb1K-If(m6X^66FO8x`hw zYsbfrBiOdi`WCi%ePv@E!{;jr3fNlFC&@X7$kp;GOQdKXZ??yc1+Od9xp753?VToB`;UupX<4#Tj%;u4i z$=^pszaN7K<=1!2q;le9cQ83|vQE}WO+t(t0{1C!Dd+Nnuz$~r)i_w z#mrRCLLyJ>Nl`8QFR)Q*Z!~3(Q)wGzC&`5JDq)!hakU{Eswr*PX=@Wz1Jy;ufjHzB z+dD(r+AaJtRbBFodtvh#HPih!4)4t!f|ck#X2UTJ(l5C%I8m*WI?Wcc7a}yRfCULb z&Kj$IknTqdHE6{^V(wLY=k;Dq&^D>xgAsE1cRK$UO$nl2FV-!VM1Snh5>7^&96lLw}}2O zypDldBwKF|+T?ZRqML{&b3I_PpH`L5M(>*=v3-e*)VM{OFkCqX;p)^6jm)CfB(U=r zWMoA64W=-@npvCCBuv)Wp=R@u#Nv-<2bN_i?=cU$F+r^!c8n^SCR_D+JCjD#N4zV8 zn8ZR)m93j=1D5%HFA4v2iY8&ki|(MnLzAZoqd-hEH>vDSI5oSh#1ArRnQ+lHhUidR zuQtgWE9%OQiz1c?up8>kNjGT^YSw4rE8>G)`RX)6ob>NB(H zDp&&&gBxF>rnF_fukgT+4vZh6>p~o_zu)4mbGy@2voJDKu+ipAPuehlb-HckZA07# z(TJ%Sj*<`MM6v0x-z31>>V~6i72Gln@zr*?DOx=sO#)*j$Z|hC_O5B<$zrf(%rBe; zo|nC=?+u}G-HGl5tY2>e4s6+1tSsni@!Tacyb-e2YDcgJuJ+{jGF2 z3a$$Kl&!p-^PZQ>iQ~oY)7a~1o!g3w>cC5PrvRP9+eoQbz8QM^-VswUb))ic2kk?a zw6092RZUhJ)ZLCIo^q=E1!0>Q%5gzZOuL`P`Wwsr+vkR+@wCw^wfB`K?lf= zW+O>V?WAqMj@9_#&Ya!%9v6>HOw&wPRu#-?Xjfm<=UFTql>A_XY)aQDogx==Atk(?3{b(-HIW${Ir$z*y>l1{+#*5)4GbET_TnFC5$xVzM`255&w;$2v{MzA6Ot)V zTIvZDy;(=8Owjgmy88ehTSOa$r5tY}4{01A`T_rQ=Go1yuR*YJjJkK-#b9>wB6r( z+@5oQErCwNhCowu8$PPzmj9=fE9y-f2Ey2mrkrUDrztuenz?%?h^Pte;n$2lK(DdjX^sX)j2MREE=i_1w0s%4~r`g1vd$d+@ zF;`+nNe!tUJ$gI5BvqcLk4Z&@?&t;@FF%mDM1$rmFCU4a+Z0QdVeDRkJ7KXPK6&(^ zstT8}*=(lIOg%5}nc+ANM z*3}WBkvNT%Zxf{1fXCs;jq`FG;A{s)0p5(DLZBJWB=x)avP!Bn^6T3Bm{yBPny6ZG z(;&O|=v)hRWmC5;>;_KQHb@FKahBNS3#b*gaKh#dnI+AJ ztZmC}yN2kP4gXB5)7Y!RegX2H#@R* KczF7C(E0-^1(k6C diff --git a/ares_getnameinfo.pdf b/ares_getnameinfo.pdf deleted file mode 100644 index faa29a1136c9744b072e1d4d9921c6b9c90d2eaf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24409 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 EKiI-2?f?J) diff --git a/ares_getsock.pdf b/ares_getsock.pdf deleted file mode 100644 index eaea9a3a30e1eccd937e5598ef39133605ec2a4b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19171 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 diff --git a/ares_inet_ntop.pdf b/ares_inet_ntop.pdf deleted file mode 100644 index 8bf5cbb776bf565ab43070968e3523a8fd1b5264..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17320 zcmb`v1zeQN_b^TfD5Zpy0*iDmyTH=jjdb_YJ}!*##7OhZU7 zUKRmf(dNfIC6P_Y8?p#$Zg`3}-e>79k$@k}F|kDUmusF#_jgXz5=$=`;WuaPO7117y@X&&aG$%5#? za(y2<6Ei;V1=KxdI*PGQI$M=Z3i~wfm{`k9xyvZuml*l7Vw=19POf+Bi{VoPV1b2% z!0N1~*~_Nx?VHfCHJ!$75u;^ha511l<0tD%uSWutiLE#a`3z~25c zfwJ4Dg5||Ca$Gp*9n&d0#TmstrGS?E3J$vZ}(K5HW%yq$Dd#&p0wAlUO1c&Gy*M#|}Ygja@^$c3Q zAyO`nl+S|}5vk-Ytz?f0@$V)UFdDM*db_?L3)%RlE~zr|NIHa@xw!|H{&K%Q$cf>dy%s0GoFN3XhPMM0(Vn*ZgE@6?fGMU&j?A(OMXlj)|FIQ-QVtZ z9Y<+Cb?b5Li;s0|V}^hr!R7$`I7>q?giEnx@NTk13}d_Q_1w_j*Jw@*KZb!X?gQ=- zcikN?IqCCz+@CgS^|iZrEkdZ9goO0G}wTsMKIpyMQ#WaAz!yVf6!hH$%Sm$ z(l-s$8exfC4CwwRod;TP^ajf@lE+_ctza!+Q{l{+XaV{v4~BwY9~++sh1Ky{7JC(m zVRzHJmBCLMqp9a@r#5M1f6yE}tdpB6Du1D)$CNW1xzroK@`>BI>do!&!tx-BP9i_r zhq}{wd^j4|Y4*b6OoR6&b4j1=ux}qNeJ=Kq zu-q)3Tbmrq! fuMJ8Fi)g8p{rWIL>O~phO{4O{52B%Ok_IGeUw7Kbq#K*gaU^D( zAkfu|gK#T+ZPROqDiL(wlrRcF$8GXXLz~*I5&{Mb)Y_hshN+dn`~19~Rvbp)RtzaiFa1@98LM#=`*<)~gryzRRgA>3Y~95(5< z=K{%Q%pTl(6t0;Cu2HsdnHnE89o0BJiquK4EiCf%uXOx868TZhuc%;tDyxEB5i;gH z{>qS@0%M9Xuw>pw4ewhAab4o0JWiB2qc}X7eZd^ ziWG!u4@n~DiX;c2W*<#l~`=%&u+k425$lB6YF1x-z5;6mA8xcSE?s0H7w) ztPAqdz~03c$;?I41#bW6y_UNr0@a^TK0_MnPoJQO|EZUTw5FE2^e?@nT%D}{r4`DR zn*UiV9`J8kfx&-hg$w5UOY%Qt=HcN1p#FYp@e||f_m}>EY4KBQ}4+aAu z5dN#{A7xZMKhjz}0)ogA_f@?h(vGNlBpeq4LMec{dK)D6gEkP*f-g_fK4;99McGA%E$FWJud3{OH*X)sM=pOKfB8>dKBM3TKs*m{t3IP{X?h!j`0g0De-^%@RP9Vq`!w5MUaRY7aaY4wQ;B4>W z4mbHNSo{_I{~G&$1-q+0r)J@doUi^%V3b16VMd(%U;rnW`=??V##Vq`1JJ(N@yM)(JWN;R3Y~P-k5LKOZho)gBH< z#=omrit3!WK>c4_czKa@sKASy4q1Rupgqt9=n8ZLB7p8L)=(JS$`uA>z0v{svIXS< zfUe%We$)Ps=^8n!{(K$#{cQ{>!|xGR`j6K)K?tvy*q`rdP)%nQBPeMAF#M1$%4J24 z%EWclsR7Vu?er1)kq%F&i>w%bGV=D=&E`)xmBe*jps6Vp^{-o;gPP*hl<}-gED|~4 zDiiNI;stryS^LttK+=y?V#UvncTHQE40(HKnV6ZG2L-+NMAq-(udJcrchdNn*lKtt zeXFXg`Ak@b@ul%C_tx%RmuEQ-^&Skk7I?psK*NKnpI=NFJ~s$Wr;)3Y4?^o?Gb-0% zsvgc8Zgox;o1GY{sjT^)b{W5?I;g8)^z72(x$r2pQ2G5PI-`kEXQpaN=bCqj2wkJd zns#eDkP@_Ty`c6JcJ0{Mm}SBR{l+CG8d}0f>$(^2N@y!Ngd?GH8Uzk+2!m`1f{nS+ z0y_LA;sp0HzX-;#==XxQ*k4F;T}~PDX4tg()NIgKV6KupbV%O{YiKSKpSfvao$@+( z#D7=gu3Xphn%0YSD$2G4#Xjee53gctX7$vfSwGfXHjoSD;D7^wrikJ&d2jng9c`k= z>T|6p=d~kPQSu!%`>*u2#T2&I>zhdf_`i~oQ|mp;`Jnc=tM!NGlVs_)4G$?GRbf3T z*EVR107)9M_4?Vxr7N^SntuCVw|?MdGp>sza159kM%bU3p1(C>i2T+iBV}Y(V$`;M zTXVR$iiNJ#Ok50Zi(sr(FwM+RFpW57^G>1%TFo@wZWqy$!^heS>0lAw2qAsWccw+v zI-%(j*v^=LHk6 zF-U3aqjdHJS-zV3GvzZkm+DXZYcAERuFTw~7LTvVo)3n!wScO{~zGZeHR&T6Zp2_;R&s!csCbKS4 zz9Q$C^3n;dEPaPqI1|A?He5iRDFWrKm@0>!Ha>BuKGd(K*M*ks*37s(-o3`&c*Dm` z-B*IwS0H$!`#rH-q|Q89ZMGslLAIKq{DAdg-dQ?nU3&Bgtx9$A(1}<*Pl(}iNA*pc zy~vPu4alj~Vh9G>1;zrXwE^|u^!KOut7nPdgD&dX@IOVx|NK~W6%)BpVGRTjMDl_N zK>mz~ynjVR0m$DXBJv>y_*+B-{g;Rcf*{HM4H7N`JJ1gZd4 zfoec?paxJAs0Gvp>Hu|t20#lS@`)7+vxhqZt$xOzyae~?)fLA3LD!c>Tko;V&fiNH(2!}e`Te&*9 zx&YyB7FJMXY)06@pirRuZ!sF^0rdG>oc`zI{co=c|MNJ_%Oik%EdDc4yX)Q1*IG{( z12L@U1mW`I+L2TgmpdLzHH~A*mf$VnMt!|@T^Zw=LI<(bb>+Rtuvd`)bYcmJY|8bA z6HVGPw`!+!jZ)J-k3QCNO>Ml0ycn1{34JDfl;*uA=$*BanYe#`dDOCf6tHb^i*Wcl zb|`2$3XldgU8GlfSeeaLxDMJl8QwU0iWYvcCc4;(p{BC1G9*5KK(2Ru;KY)4!{3%j z1>5S!?sMuqQiF5=m)Pu=(ELb@R1TxMv%rco`_av~*Ll{L{%;+b%{Zb+d^mf=!6%A& zN!G30vu5#klj#nH7?d89`kcf-yuR&E4aN~!GhEK!xh7dQ#r2&CYg=LRa|V;zQU5V7 z56tZQMHxllMesz>v2;kMJaHTo^>mGQKaO$=ml=w>-*Ly(|3LFfC#4%Cb zT^38%A0+8Z-K9?<4i39n88V?*#vpawY)RUZyz=3MY8jIl3uu?A0sqt~h&*m(y|T&YI+!Y~&;%cI1N; zU}^F}W=pWB+y}b+-UklY1$kM*E}mr`e!`-#)8j|^JX4u^Ye?K5W=A zN#f$SZTjHH<2YItTAgPjns$JwqaA5f>B8Wd2}rr<8hAQkxhR7czDtoA9fpW)j*5N4 z+-xO2&@Y<%{Z{8KJa3Kc`vis(&a$Q64He_mg|C|H#=3&>0SW9_jIsdr#L~j99U4K_ z$jQu9jT3BE1FrA3Z&aFRZ2U0SJH6e+5?$)umXucIoPk*ACmb8qu{ifMF)bT!ehfx@ zDtw{gK+no6;cyQxiHPm4ng!kR!Jd#?M2I`XP^zAe4g_N0kd8KLk_}6WOnT0woAu1j zOfUwKc66ib+F5Hyb7oyJZMT2dE0us>vL`iOkmXD4_Cj|(Gll0J*7|Hf zsc+79!n%4XF#o_9Av@5j1p^oH#;21$+04m&ZNi32);XQ2y+H}r4N7M+rpLbm_dB=F;$&AP8vWJ|o@pZk9aFybsd_lXzs_$Z|@-nTSm-#L^f=JLLge5pu;P$Nn1P_>?4oL|Kr9$hEXr z8!b#CJp=Gq3jceFa5^DlI3G;;0blW<-HXzVQ9X2LzVVRO+leNOoK+FmHX>Ue$m1y< zc*tHb9~!n+#b@;Im-60Z-H`9V+<8%XVy#o(j`@;VRQ*z(c^N$OA#tE3?W;=)$8BauaB0`Ax=Q=)1V^&R|SH#X|4z)b1k}zNsW;RU&qASIh4i<|z z-6#=5XCaLu%P(NT50`YUL6eh+tQ?N_3XS=mb_P%PPTQr>vLrC>3R{n-T{pKMQ+#iN z3+vm@)omouh(CEh=tkr>xXx&K?K+r{ad)dVUjf<*d6=#ppT2?__bAj}m zCh=jBT+x&HvIK%t8V;ILAv@ZALuvuo}?l(&|K5pCCinLv2Z(~g*zm6ZtDIy z>|*~asyjE=5?v)}+psHH+5NJ5K1dRR9^loGCOr|YO{RBykAJD+_h{YdChDW zC^V_3O+PNDUTc5|FlCsdC}T9Si<{x{(P7R%mlwFiVLGD`TX=&-X?@?tBH=D62Grie zKvO5e6u+3ym#}PpnD)?$VY}iL9|6OCP@nx`v-Ds~?@D1#t*(boV!Or-{2XHwgPAP; zGCRzXwi$}^b>Fk#g7eq2&aApavhKBpAL?pY7-DDS6l(`4Bpct5dmk;lg!D-Js-=Dg ze28?jq7pVYQ8}KY*WSF|q`q}0il%vZ{Ni~kdqv6)d?oD-z3lz@{!nt$r7_nxh934& z=+xX@xV~SCIWkRdPu8YeJS2NE6%$)%|Qx; zMtsd6Oj+Bi={!lVQBFvcELs-II~tzE+;q5oEA;hJW=GjGyVM_K6q-XhA46d`HT0mb zHV`?+M!5y)2|~}D*dWCOCqmyAh_!eTGLR!Oh_R|~W{pl#{TIV1#xXP)fb<@xJwE zy`J-P>+lloLA7r@n?mC_5U#EEuaTfx6)GQbhOeV{)0QZ`GOEDy`>LYy;{ht|a9a*u6%wf>pM z*Sn{meHt=PGU~&t%asfYTGc-a_kF_YY4Y{>fKH61DwiuE^f0`}@~}lJai*13tmH=g zx^wludW7sWziY@4Q)xEqdCC<+I~gsa zP>=7{fq2?`PU=tHUAXL{Q>-M-T9fhUu1W=7=c$^LVGz%uU&GgN@xQz_bc?vk%Imc9)1SUomCf_!1y&av>F|g6i*sZDinBfGU z)!fNctA16l_fE}W>ppK>*LjU+Rp_XaxOFIdZ7qMPTeoHRihr^o$=AFgTLvFhSMyvJ zP&0bw0Hu(MYEOK6s32?}o$Fo z75QEJ^)M}FD>RqL!1mC@Eb+?V(0d>6`N`zCHQeG1Tl8w+=#sxC5=_>9bLc@9Qvzmm zh8^~W@&r1tOOEiu)#Cai+Hfa@y;s*QEskEbzw!90v&QpfU7|F+#i+D+Y^HEw13qmi z5PCKH~Vmm@r)B5l+TkeJXTq>!PWj~&gm|&gzM8W zCc{Fy*xkT(>+R){OV3MvhVl0I1BHS+(cvw%RXLjHj95qUL(r@Jl;|=@6#bcm^_Gkrf@$J|yZe+=$d*F0K?euiJ~iDWa=t@kLtxxl zl+0ZW2RF=G(jiwVLN!$?H9BL&U&?vw#Rhs#@iydvDC$zNA5dA9XJ`j zJRA!lZ|wpHpS1_r&)B=9=BQ0Hq*mc^k=4U~n0MT$0BUKMwB>CW5)0in!{woqe-T?A z++Nm4?!<>{Q(LJzwEGEw7}H9ueeRQSFEG@kE`Y8`AI!J+8T_O8p{i{*TLqAd{bT9| z?zale{z#1Xaur+O1yR z3RT?^Y`ep`_k`?ff}K*eJum92|Yj^AHzFt<8q~;AgsG5B0Mu%SbSudhnI93 zj-iEkv_-LSCZQ(ONl?Qx)7v2)6CYKJo-b@8JeV7k6MsNz)@jDBFh%K{iIBUa@1;jV z`;@XXzAsFV83I2e(PTI)b`QjrevH-_GCCGF=qg-4Otyat7?q3d?T{#2&(Y zbJD|KK0dI{F$VN0nO~Nmy<1G}ykNZTz?1zg@bDb)91VdrU(_P7%W@VVvt8ww6!n_e zRnhs8z^bb;Ry^~?N^3SugP2Z@AgVn?2V8mmt$mS|;Iml1(_l@!;*l{5DmE3>1qP^U z^>Z5*+$W4P+O01DYWg|w@ucOskHINbr>AvOHYSY4`9cM%QWiFaEXvugD$D67Lg5fY zoh6#-VsMl%qlw^XNf5DOLEmoS>jdJtMoX;+*(&)k^$*&l^7h5__v|x^LDlb#wI=6! z9Y2>BZ`gAJVdG&X`voDd2cBTWtKOgjPpR=ip1oi#8Q_OA`pdd^*X@Ci>N0V4LW|kE zo{r-dL*Q0MsWlLdLA>Gh&1IDaxh7WZhK^*4A5p*y@Mwi&!q9@qz@Fk3T++&6; zm5ZP0oqO&)xF$H$`>H)wMWj>Dt>fhE6-m+ZhwN=Z9^NkTI}U+IvRPL6O=#Y*9;Vd* zEkeZ8*3*gGSrKz$Llza&`*#qG>tF3`hh-&Z1@2S_#!0*ar=_X}Fn{e8qtBV?5tcbv zq|0ipv_Sv-Y4d{&SDU{<4r&l$!yw3bNNsqE})6=e@qglKsFA*9CS zz>mgl_ncAeEjjJ-Qu$Kt?sU*4rofTd_qTN{R32_)RbLj3$G-fatyXVm8Pl!1Wii-o zU4MSw<-30KD+h0Ct@+!VTI*)&v!N<=*R%cj4n`d7{EOk%$7aVL69uwjYJwkggkx|v zTM4av*ckfkF63{JthT;l&7)I8QKoYWewJ80))x-Az-wIsiT`^A?4P?1|7`*6zid1yX5}kdY1*z z@*j&_HugXpQ-v@I1*zg-wBX#X8hpYB?bI`GT09L*>KKfg98wsKQetMxtk3u#PTJB|M@?2=CyU|RcC&PFI&`@F zKC;0({v(wVNLFo4wvTZqr>4ZL$OHC91oD)>*|RS%Zf0>1FUL}B=JIa4O{GUq}G&FT?xh!{Vk(3eY7y6cwvTQ%PwiTYL_Lf2PX6H{q9AMLUV99C=` z=T00g`7M*2kzf)s;}kx3@h$kGbN;1tT&BXPZ80|1m1|bzR)5sdb+e8*eaY7<*KV;# zcgg^WWM0c%Bcbb>mSI^$E_`)FiFQ%l%bZXyV>~4K5_R6?vxK%wxQo3jZ%JPny+b$0 zFvmzpq#PwEg9l1gV9a8ii8|@xvP550^SXt1gRAnXIZ;*@*&_~6Mik>#bxI|bZQ~$Y z)&b{_TR##f`)$A2n5~p8Wzxqbv}v|$W1bUp76xYSzspQ%{62HsXeM6$BkjUlcK_nS zX|9@o7ChUtMw=-P$@Z>rZ~uz5&2imKW4(3eyrFq$c57}6G;WnGf6%dtmrpil=w-Vo zp8L_6jZna%7i~W;k?*#4e=Ikf^Nr=+H+~yw>Uqnkn5ArBjx>pPm6P$V zc`X^7qkY=@Y|{FYc}uUJGUqA9Li`1DjLM&Iqkqy8G7IOZ3F|>mE+2@{)t#ZNW@j7Sgl2>juyD^*lBXK?l&8OlVos+cpQzJ>LUM~49$_M7-yA3^w-XY(sm!=m8 z&({+iJx`7eSZ)`x2~*ayZyhn4Z!LGzc;zERbAFY9U5Cg&U64X&8ID087;3`yLAm+6NBSmWH( zGlzJh^vkv$d4hg%w|Lo|Qjdr(vpiZ$MOp?@TguFsDT%8lbYjebH|%$&qaDe`UeEj> zI41JTIOJY9yNDwy#c4sa8v!uTmb`oTy?MjlOzEi3xK&wNI&clUzEc-+JWB9j$^N4A zO|U8&5!(CM$+NM9cwX@nISJZCBVjBT{4S>kFj~2PSvJ$;z|EbTGYIfmcNE9>Cyze> z%)p!9bFw4QDsq`>JR1GkXVDl1pPzA-_*JLKIhvD|xbmkNq7$^ZWf>OLIAG4oq`XNL z7%rFE%PN$z+3|oD9;7I?#MsjfD>t^keM)DPS*Ff3u_mjr3b;wpl|0qYJ5V5m^VU$g zoC+$~rleU>iP`k={;bcv!8D3zDPO3Wj!6nY*H(M_{lY2cl=5}V&^MS$1vG;mB|-Gd z5AT}``R#~5P9o?w&IA`sa6NJ9W_|foanjCdbl9!$GI7sT>8Mb%QY(}-ATMRgK1p|T z>mxToMUL3Gjw1V9N3hpBpT@+=k%fy3zJ`NCOXCTn9j1DU);IU#H}9!NV;2X1%Hdv5 zT76oL-ZCpbA)K>6k-8Y7tT=lzItd6TPs^mK0_M7cBY|>XzCQ1^0WXkvhb4vLI)}!v zZKkYQ7L9j)Np*=^%@i1+m*|T9&ZbCWw@84fd1UOQZaDwOGnD#W^}uVjvEyrZbh#yG zQt4EuYUBv!UEvOv=?b};r4N`Geai1E2L^pe$e7OO%Kq#q;u`{FAACUG$Tyx( zj6_zoE4raIn!;*4tx1cmElYUxCNVu>BdO`I)$NfvRz0Vz&mJX-lUvrHwBzRr06Jmi zyGnp-O667hC%7+mjM2+C-#t+>Uky%&Dc2`>@9v}?>6?|TPCl0McC?ZNOOGq2Nq7Up-HX!}0rW|D$0g{%Uj`Nui4oiK79W^l_`W_KrDN)x3m+}-S*|4=vT?L z^fUCATpD^GXCr~RwPtRTFXR%K2cOuGuA&RkwKyu6=Y7|U__2_Qep+(cwrJk|Sazp4 zR0aJ+hqcp=4uAIy<3p*l{madf{kwLdVGiR{BNDhPdoyLEv4*CAe&CCpBwo^~S|*Fg z7q}Baou*S2Z{w*G^-DZ77{3VYVH$2lE7b7u$(1OvEh;YH;v^SxPjeO=z7uMv7q}Fz z8F>z|3wnrytKF?Qm9{w4Cjx(VuzPLbGMzwA{XDo7B%=&|__){0UiL0X=LJ7HUJlMX z+~@gOg)S1+N~@r)jp)dJRWW2e>)9 z$@ufkGv=KS463Ehy!lu%-cbBQoXw2iovQVH-@Q1Fn0GQWmZxZqof_672SX}s&<5Lj zao)yHvi2kcIs?rJ@|G6vmQvjAZXx$*r5!2|ltAk7zz4TkrT zrvK!vYrWxa19i01xf_r6-~-+LhYalMEZyg3QOU(`G|h=Ig^XARls0>*n)qNe6#~FF z`y1}QwvFWVruNLzh-(q`@Ch*pi|{N z!yR9_M_K~W;35Kr0SW;Y6@>s(;|lHto50vltt=$Y?usv8r%YKq8L_`q;$dgCOQ%`Y zelqlKW=$p1(qEUQ?y_QVj>(|laO;uJO!=#M9xDcaN#T7z;TUfcp9gp<2^O8aF?BYqJgb zV~-nznuWv-dmK3BO&wTl$;KtOR&Cja(OOn_irmCjGAS=tWOmrg&85sE?Mk$aR)le~f%rSN35fE8o2x zKzf%oN>zk7u@c9rfar3INkNpd4L@2^%;&n3ZKh&#aE<}Eqf&PvAfR+~^I3`b z&5fctO9SRdE>KCT!OkBQkn}j5rPZm!R-a~Yd4yTAL2g;khrGhVT;{41(d>msQ7V!) zGWTD*+-c!Efg=(}wlvue8;nb4C7t=$-nIKv&4sy)Xu00^Bz}BQ6_6EXnJSrKI6w`o zBHNq~aG=x<7uHc{ZKS@*J1anNslex0>i&L#==cp}#H)Y=^MHsV=@42&eP?c>i3(nj z9u|4%X2g*~w&DJ*cW>NJnkX4KdIx56W;Z44)pCRBAj8O@ygv6>QkgwN(Nd)GT)0>S zz_(@u>lfj1qFhsvcsbc(TdofO`kq13#>2GL_`c>qf4>g<&cZuRJ^VFa99yPf0ig}a zmBb%6GjIm?eh9q~mZWX)uy(5_dY~+dNieCaftAVJWc1EQ$)Of|2v1E&$WX0DsHvU8 zZkSg=*#3EXK-P4D&vP-%jcv8wrE?D&`AmWf=S~9Mw|&DHJZD+HjkUhd^9_;=yI-oZ z#G$?22>KqDzun_^9CnEi;}Ck=#E*V+ag12FAy_w7)-y6I+vb^c6R1gL zl_yflA~DeKR#Kzr+GX{GhK>Cpu?n-5>L}?+savq--K6ZsV&j-gQ&ob;HF`&wK4q){ zFVVv9Pl<-(1`@Qg2E#H8V>;CitC*N`@%5Y?pq%_;PhFM2NP%9BkofREyMq~sAzd{$ zP&X0G`M%;s&5gd@d((mBbsCMzv3S#ujruuWx_P&2Y=)qd<(1xTh|VOmrGXpu_p5ba zrRM2IuF1Z|JCWxh87bYl9zrc}SfF?WWS-B||GN92^IkC`e*3A8?zl8S$4SQVCY(WE zfeqiI<@OGhEq-~}r!6k+Enu!_Ygl#B*aIFI?9=cj+-UmCm+2|k=I|@eONpt(FV;g6 zdBf))tXR&Wm2bbOpt;nFe6mthtCXVK)5J(n)RyzjEPfQjuDtgUJ0b6RO;}Qh-7Wk& z0-QIKt)6k&qGP0v$!Yr%WanxdAM3~4d}*4(_u#!ANpDJ+Mg1HOZYLAIglU) z`A$H3;469hMLzKSY$vjJzruX7d&9ylOH6#i_uEJgcWcIcf^nL`YK-W?fKU6GKyL`y z*Dh&?Mk7_Quo$0~$K#F<&1%|l`Uv`x2w{O?Jw?8$c6)|9fYJ&oP3+Sd#Ep_^?c$lQ znl)M@T5Dwws>HI*jmRX^LI=j>@2svinbLgEUC{iVrD!!mp^V(f$)~d0=#Z+-1SY-V z#i6uUDTxiBEsv1Qa^`eH&z#kCmyR(}NJ`oqPbSBtWZ_6sgnF?f_O0tQx+C+;kh(@Q<{lEOwEtLeMJJqB94yC)H=UhMgA z0(8m*_~_5f-*LUd3FEVQM22|b)9y|+m;e39sZO19V)5{LiM&IGW?P0Ft)|_Pt1E)!HWo;_2zK}_VhkggKIW^(&?qjO)>ywtwMB3hG z)v0(nv}`eApSTpullTcssbHII+1e3=$g(wvW6p{D^0rpjMzHr*OM|iJlZaVT?xabM zl){MIO&5uqeiUly-CBlbweQqp zU6njF(ju&@JJ3(Pxg$d0ab}Z?chWzT_W~Q9P7q(eCsF9MFL^3vx*;9rm7BT{KIg&# z=luR&_dx?%vgQ<8+V@w=ox&q(yDv3xCbzOB>s|*|z71~6C2yqlBrrkO+c+XQy|)C1 zk(|&lDjsy0#>l<|uKF@i4EW?6v9arrGZwwY>bY_HG}1Wk(MVa@N=;!|-Q%^wy2k@+ z+UPX5wECZw4aZIH@VX?=T9g<(kUw%#(Z4ZtH;C-8_3+?f@Xp#yb>D5Btm%rPBkM=D z^V%~wZ9(&2v+Io=TgK+#N5nKadW+FF^;Jmx2A-whfM9z^Z##D0eif@p6%HtDDe+wS zpf@XyDS-1P{DF8Yh!QSTE!LpLb$B*X#F*=@w;a4@vH*RhQpdR5f}fq_<=R$M%HFvh zLgZZ5=7)9OYFW<{*%)0vWTLbU{BV;!H-?dW`o2m8Ww+Y7EY)1N>By@OOz1dv&yNR> zxH&d8ESkoQB02l0VR^RSeSB-djalx1_E+PKmv;_}FA0RPF|bW+52UG^X{Q>*G(2YyRIse8 zU8Es*xQ^3)Y^U?qiI?BVg5mY(SLkg`AQX#B#|z$TZM`q+VIH~&Bj9Y%jFhYq;F<#h z$nNtLq`PB$%tvoY*tRvp*bdFz%-T|3{{bLasOEiSien}dbHbQ56RkB7(VaKZTaW>f zy&#~8j4oOzdmBOtO7kHk=O7}n*t$2d2Jl3?-?+v5{!HOEaxu4u+;tVJ z(0-_v$0;;v@mDYTb?`o_Uhs^YR1xwEX6Jc(!m2Hg5Yd+D_~tgqKYtX6L9-j+^QB!m zG87)yy_-nF*q0~jPBoYq_<8F!!3Gd`>^c{K__juXQFHU;!OFlskNlQJYx5G}w#dVl zn77xA3ECD+u?eOkI=%?{qnp#7+q`L?{d|(rBOrD-M@D3N%<$=TSnkYpwul3b04D{t zUDGv}km{v`?~h;mSjcK~(oomSW%vw=UN#P%@Z~1tt#}1EL@@Adi^^B7_w8yu8%IC? z=r+>sr6{Fah&%>wQYHT5GX{>{ocTr2xAl@pVH%FZ<1EEs%Prg<;1e1CqH_Tp3-T#B z@3TELmkfrF!FP`n_rwd5r?pF5p&D^mCE$RmqDSjd^FXN(WFmPdRe$}+FYgO!U4#$>7w_f zHC5#9p%A=;yqw*fk!ef-FJ~tgxR949^A(8@vWx-)nE_WQ2uD$7eN_zr!qwHu(H;Q+ za|v>RI6*ud02>(c7`>+}%n<)?X86%Rv?fdh?|eo5{g_(1%YfpoZQF{r;sr1!h*#8OXZ=%{@ z5apxatn=wzm3HU^jP|)79v( zwgN((peWhkNH>F!5?fmd*|@@-Es%ZN!p#kty=Q?y8XAb~lgwfw$V!Ag!U-yNHTEQ( z5I+k}_NcKWYm3%s|u!;PMLwg766H2$%&j3k!z)M;HL0mc0)Y={Eo} z-`N$JQjE-T(*yt&U2I$dNJFBsmlb6IMk0b>9zH=S9T2f9*QbvFWBn9E&1`9&? lL3~nj5V8L|h6yTL8IG`kA+90au5v%`^M2p${5a?Az1H5V?ET;8tg{yuEja}q5HCMIOZ$54b9?~+9{^!# zk1r+$RD(I&y4eAss1hBZ0^HFJ<_Z8RI9j;DyPpEeB;ruhwc0=Po;?3s>?5< zOsg_)$f#s8Hvfi`oAJ<=Fo%Y+M3M>sJn2hKQ~6Ap$k#0}q?$x>lX2em>dE`lqMtLhfipXv!vnoe^wLiWuFqlH09xskW$d zU=|F`HEP#v!ws+#Jg3u#uCm-PQy4@bUQ8ARid%8cqPSjY>g(hc(0rRQ*4xGGz&3DAQ}flYCL;~jL&TqEq*yK zKL+`x#dK^nkkZ^--W&7wA<`t5Q%Yj2$?covEKb>5oJ!fs1sJtLPDpk?Ym!7Ad)@Us zuFJH-oNp+-)O6)~cabu*7EDUCA%WD_&%QioEa+>ukMEWjsgSQsJfV@HT$)17{(9fT zgn<|q*CYkT8_=26&d3ZD5of-MKWa=;+Nb`l)S&)Ty5`%g=*gfJ0x_m5EU+}va?5Wr z(lTwG_mCZGejoiod50#=4%BbT!*-*eCWR@7p38Ps!7@L+QP_w)*<8;x8>NUa`vnN?S_vcPp!h(#FPK9t`#MeE0yAoVjsKQ|&0=&nir!B< zF3^SZxx|EXbs1lC%}0YP5)k|tpVDg1@pxmatay>)bhIXixM#i;(3r}rZR8hyVn zxif#m{A%`yL^(^JxLbje&V73RjYmkBT|~;$N+3|ETe67ArAw@seZVvK$$*%Le@p+& z3?T0d%-Q-UY@x2uP=^LM^ce&a7R3Kq#{VY_>Uq1sfLa!|FrYfj8g3zj@B*0fp{fOh z1pq?)U~_z+4#EuuiU2+ol`G8I4FEwSCaM^QM7XB8Jhfhe>E0QF#A zZYVx^FE>Tq3sw-iKNO1s0>utOW3UcB3SNP-sC!h4NWdROKjlMr@dKt&t)T=2Tu6un z09E1ENPsE+kM_&~s21GOO`==-$qM>|^(UvSg`0&V!uD4aKc!cPxmj4FY5-ugvKQj~ zY(Vg@4g9GFK2TFj9RQM$_|?;IR@4#1NAv0YCdY3}jSdKm4+5j>fjS^Qe9%RgKpi1` zp}+B zL5Dv7I8e1{&pM+PNVu~tsxfD2XC(ZOdtG-+H}rTy`wV5MKYW5_{<~g!+DfvDazFKw zK{#6fLo2i^b^cu|2>5rcgnns-4;J`S@?SDTAP@lh_lFigC@%i~)c;TIe&-MnMBiQf zMbQa@!2l>!@Z$XI8eK1lvKB;07Q)6+qt!2tfbBeZh$;N1uNj zC>c<_{E!6g3p5A%jFuZ!j=KBhmmg6h|+7lQv#6*T}+E<|7da1q)hfB*e!3A&YE#z9^G zbQZew!cizE{4mmwR?+2X#|WX!b>S#5_@@!k?nP7na2uNLuLs)PKTM65=fX)p&lhI@ zDd#Uq&}a1E_$fO+`utN*RL|(zpEW-Q$WQLydPMd0KOX-->II?VzgA_`;`!s<*s%uCY3(=w8(<<3X`?D2 z91EiyA$c=Mq9SSF414yp^mToMQ(#@JhAM%TxkWq=Qf;*B?IU4G3rA-%FG%*GTD0WJ z_w8E^tS0>L8Club*!qRNcf^*j6D}@c5VkV-nA>W3CTvtxSAHRWfw@-O&bPUJ-8n5Y z((rB%BGs4TDimURAT zN4?)b$u#ZUBS&&X%*opO(v{Pl5Td09)SY?Z~9Y_V1x13uwc)4n1WW+M= z?B>cj76wM#fOU0|y9&l)Ch<^+f)`I6f@7fayoOpN6Bq0cyyaGKU(p*rr>{pEqdDDpcv>}t6R!BSa<|OztAx_# z^6NJg{(|dN)bxgFnSB~DZH>n|kDti4*F;`}R@{I86nljsACRCW|Jo>{pm>onP{(g~ zee;+ggJoGFj=Sf!Nhti})@i#bbJ#|koQ&!1Ler+NlsX>^D%hDCZ%axbZQWR^ly0S_ zDBTME&gq?S6KFMAN7*7~s6dFb6a1E4bS0P~N8m)4wsBO)IiQ6l`@nrbMN)%FU#?Q{ zgD}Rc#+$pX-8ap@9)>c-K%cvQyD^@ut)ag$UL2sI!5Tn(A5*#`lBpXz>6U+d$u*+! z@GAk8^qhC9vgUgYXC8lrPY~UWzey(P$v_#K*V#rbSgHZ>VxrB}UFioAPR$oZIK725 zm4aIWYx)^?luu+7Rze7oZN)y>)ym7|HNN$a-Zyy4iGByEY!1j~j8bK5Xr`&2xTp>e zH|39vDNC16Oawf9@Q5gm%Z}x%g9VeJqNeLS)B3#NN*c~3HW|!$mfG~L%|dC2|0(ma z^LMc%ysV0Am^3xqjn>!TORC>_PCObNCmzmkS}wKrBUHQ~oNN-`p=n8>UhDU}eYPGc zAOOQA?#nh4GZLjPO@x*ic{m->F3-)EH@<9oh?q|~hx>}1VkyeTHL`c^lf*Nbk z&qsfKSig8=_#JK0kAVM%ivRxfbb*O{XjlUQgi&olg`j^RBLAO=Ctcd|qwE8O-6(z>8u zMjT-_ZorExS2VZ-T~MtdtbwjTBoGO6f?FXR5zauQi-i>oh0Jbtt}qzT{WpXLdi({W z|NaF3+nd1u9;5leVAPZEA0X{+ctuZlxmp6myqpLodR0*> z;XaepH8OzITMEqk905vrRx*#U-vZ)q$YRSo(sODE=}*|NZB1`f-7EE(nD9JiJldW1 z2`D>gd^2r|U~yn!V;ei4K0e-m-BgB`566yrmweYKmH9ExK|HI1C@(b#Y1~r}?|I`G zsBy9+I@f-Q*Ku~9pRfO3w5Z<}v0BEJQ(IC;Du=c5HmAYG9=*GcX371>io}q!RHR|yt!<>1pt}i1GT7w)ZLXH0<-uEQ24te) zB;jdooR-w($)oCiN-vm3$d1Ef!@b+yU}w0n=8;423@us9AAHAZxse+F8ie}{=L$P>w+yk(Ga99v`-AOc519@J1mtpAxBu&Twk; zdR9+kjfTIOVm&-RV(0r6SD(wrjK1fUt6-CMSwrhd(OfoUS4g4q6=SN$@vmjoTgbdp zB;M_PKg*BHmQc-(aU!!$>EBMm%>T%`V4U8rc_4DrfLra+jb}QIbh^nCEib;@ac{

uYVcgq@pn3!|)jwnu^*L;ap43aao$W2xf$})H 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 iw*~@^~A0;KiXwL8#LNSD7(;>zL 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 QTwJgh*3&&ve2V`607-$(QUCw| diff --git a/ares_library_cleanup.pdf b/ares_library_cleanup.pdf deleted file mode 100644 index eb1ba3dd393df1166aabfd14e032741fc8ec038d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22301 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 diff --git a/ares_library_init.pdf b/ares_library_init.pdf deleted file mode 100644 index 057b569f816de6c3bee22332e263cab721ff02cd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25121 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

f~N+DMQ;$BJV1(J9|c#??v55 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 rCSb9NC4!~GU^Z)Ma0vhR5s5Snn9)QTO!f_gV -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_ARPA_NAMESER_H -# include -#else -# include "nameser.h" -#endif -#ifdef HAVE_ARPA_NAMESER_COMPAT_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "ares.h" -#include "ares_dns.h" -#include "ares_private.h" - -int ares_parse_a_reply(const unsigned char *abuf, int alen, - struct hostent **host, - struct ares_addrttl *addrttls, int *naddrttls) -{ - unsigned int qdcount, ancount; - int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; - int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ - int naliases; - long len; - const unsigned char *aptr; - char *hostname, *rr_name, *rr_data, **aliases; - struct in_addr *addrs; - struct hostent *hostent; - const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; - - /* Set *host to NULL for all failure cases. */ - if (host) - *host = NULL; - /* Same with *naddrttls. */ - if (naddrttls) - *naddrttls = 0; - - /* Give up if abuf doesn't have room for a header. */ - if (alen < HFIXEDSZ) - return ARES_EBADRESP; - - /* Fetch the question and answer count from the header. */ - qdcount = DNS_HEADER_QDCOUNT(abuf); - ancount = DNS_HEADER_ANCOUNT(abuf); - if (qdcount != 1) - return ARES_EBADRESP; - - /* Expand the name from the question, and skip past the question. */ - aptr = abuf + HFIXEDSZ; - status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len); - if (status != ARES_SUCCESS) - return status; - if (aptr + len + QFIXEDSZ > abuf + alen) - { - ares_free(hostname); - return ARES_EBADRESP; - } - aptr += len + QFIXEDSZ; - - if (host) - { - /* Allocate addresses and aliases; ancount gives an upper bound for - both. */ - addrs = ares_malloc(ancount * sizeof(struct in_addr)); - if (!addrs) - { - ares_free(hostname); - return ARES_ENOMEM; - } - aliases = ares_malloc((ancount + 1) * sizeof(char *)); - if (!aliases) - { - ares_free(hostname); - ares_free(addrs); - return ARES_ENOMEM; - } - } - else - { - addrs = NULL; - aliases = NULL; - } - - naddrs = 0; - naliases = 0; - - /* Examine each answer resource record (RR) in turn. */ - for (i = 0; i < (int)ancount; i++) - { - /* Decode the RR up to the data field. */ - status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); - if (status != ARES_SUCCESS) - break; - aptr += len; - if (aptr + RRFIXEDSZ > abuf + alen) - { - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } - rr_type = DNS_RR_TYPE(aptr); - rr_class = DNS_RR_CLASS(aptr); - rr_len = DNS_RR_LEN(aptr); - rr_ttl = DNS_RR_TTL(aptr); - aptr += RRFIXEDSZ; - if (aptr + rr_len > abuf + alen) - { - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } - - if (rr_class == C_IN && rr_type == T_A - && rr_len == sizeof(struct in_addr) - && strcasecmp(rr_name, hostname) == 0) - { - if (addrs) - { - if (aptr + sizeof(struct in_addr) > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - memcpy(&addrs[naddrs], aptr, sizeof(struct in_addr)); - } - if (naddrs < max_addr_ttls) - { - struct ares_addrttl * const at = &addrttls[naddrs]; - if (aptr + sizeof(struct in_addr) > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - memcpy(&at->ipaddr, aptr, sizeof(struct in_addr)); - at->ttl = rr_ttl; - } - naddrs++; - status = ARES_SUCCESS; - } - - if (rr_class == C_IN && rr_type == T_CNAME) - { - /* Record the RR name as an alias. */ - if (aliases) - aliases[naliases] = rr_name; - else - ares_free(rr_name); - naliases++; - - /* Decode the RR data and replace the hostname with it. */ - status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, - &len); - if (status != ARES_SUCCESS) - break; - ares_free(hostname); - hostname = rr_data; - - /* Take the min of the TTLs we see in the CNAME chain. */ - if (cname_ttl > rr_ttl) - cname_ttl = rr_ttl; - } - else - ares_free(rr_name); - - aptr += rr_len; - if (aptr > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - } - - if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) - /* the check for naliases to be zero is to make sure CNAME responses - don't get caught here */ - status = ARES_ENODATA; - if (status == ARES_SUCCESS) - { - /* We got our answer. */ - if (naddrttls) - { - const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; - for (i = 0; i < n; i++) - { - /* Ensure that each A TTL is no larger than the CNAME TTL. */ - if (addrttls[i].ttl > cname_ttl) - addrttls[i].ttl = cname_ttl; - } - *naddrttls = n; - } - if (aliases) - aliases[naliases] = NULL; - if (host) - { - /* Allocate memory to build the host entry. */ - hostent = ares_malloc(sizeof(struct hostent)); - if (hostent) - { - hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); - if (hostent->h_addr_list) - { - /* Fill in the hostent and return successfully. */ - hostent->h_name = hostname; - hostent->h_aliases = aliases; - hostent->h_addrtype = AF_INET; - hostent->h_length = sizeof(struct in_addr); - for (i = 0; i < naddrs; i++) - hostent->h_addr_list[i] = (char *) &addrs[i]; - hostent->h_addr_list[naddrs] = NULL; - if (!naddrs && addrs) - ares_free(addrs); - *host = hostent; - return ARES_SUCCESS; - } - ares_free(hostent); - } - status = ARES_ENOMEM; - } - } - if (aliases) - { - for (i = 0; i < naliases; i++) - ares_free(aliases[i]); - ares_free(aliases); - } - ares_free(addrs); - ares_free(hostname); - return status; -} diff --git a/ares_parse_a_reply.pdf b/ares_parse_a_reply.pdf deleted file mode 100644 index 71937c70f777d0ade33dc723cb0ecdab322cce21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19043 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�=>fyXd;IJ(#ZK&)JJ@FHC-Ecw*nF||Jmgg*(=S;JsX zd_bUwhX<<%JFBCM6%fSB%L`-!1HoVxI0lQWmjleylf}W63SQqeAyAz^vN^c2Uem-1 z-#!3Bb$}pNHsG&{ejQ|nIywLl6`Ptly1@kL+}xlRd|aj++~yWMoGfM#PA(P@$P&cD z2LG^_o0@U3adVn-a+q5Fs?O;*GXGK^JON%IJDd;jJ3e^Ou!WmB#6^%!T15dMZSCj^ z`w`I!fU|>_4*0YA|0$~AviWx|zyHmv!i5jdDt>(^`hS!4H_YF%I=X1UyM&OHi=(9_z#Vap8ZHSC zD;Uhm{-eh0Y(KFCfCw4=#-0B(zf7GJ75{sV+1n$!Gy;!L!qME#9v&YjEAfBRVgA!H zwlM#LU?(>hyX(`NQ*2?*XX)r-Zwl|*rcO@qcxqD^oY6pdpQIBK zfG5JBFgu9Q_1F`&gZ;R%gCfQfpPi|Ll^~rbiv`5e)Xfe?C#30cjcxHm8g@{jA2-+e zfPa?tFS5D@!N)dSY`{Ne4k1jyf9Ug{E9lSZ5*`mBNaul=4F3@s@mu8juW?QPZ^N1a zzJrPwC2)o##tFRyA7YTP@q&3l>>S|h@kPhRMh8cOkHh}~@e?@b~;0EeG2c+@1~O$C2}v4Ppx;2X_4v9bL#FNg>H4?Hjk9?<-^yl_syUo7yKIzVjP@IC3j!q~tZJaDG}1&@uBo8zA} zgAq~Tf5l^mZ>s(s28O>N;vXEie~Tc<8GO{2fjJpgPnW0+$;A{ssz1_)8w(amH!@psa(XBLLCc;O~==l>q1q zi1CPnxWuJ6K@wb?k|16&b`YDC7&jLiJC}q6yA%(n(Ep5Kh Lq@j^imcsl$#wUQ< diff --git a/ares_parse_aaaa_reply.c b/ares_parse_aaaa_reply.c deleted file mode 100644 index 5b38bb5..0000000 --- a/ares_parse_aaaa_reply.c +++ /dev/null @@ -1,264 +0,0 @@ - -/* Copyright 1998 by the Massachusetts Institute of Technology. - * Copyright 2005 Dominick Meglio - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of M.I.T. not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" - * without express or implied warranty. - */ - -#include "ares_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_ARPA_NAMESER_H -# include -#else -# include "nameser.h" -#endif -#ifdef HAVE_ARPA_NAMESER_COMPAT_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_LIMITS_H -# include -#endif - -#include "ares.h" -#include "ares_dns.h" -#include "ares_inet_net_pton.h" -#include "ares_private.h" - -int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, - struct hostent **host, struct ares_addr6ttl *addrttls, - int *naddrttls) -{ - unsigned int qdcount, ancount; - int status, i, rr_type, rr_class, rr_len, rr_ttl, naddrs; - int cname_ttl = INT_MAX; /* the TTL imposed by the CNAME chain */ - int naliases; - long len; - const unsigned char *aptr; - char *hostname, *rr_name, *rr_data, **aliases; - struct ares_in6_addr *addrs; - struct hostent *hostent; - const int max_addr_ttls = (addrttls && naddrttls) ? *naddrttls : 0; - - /* Set *host to NULL for all failure cases. */ - if (host) - *host = NULL; - /* Same with *naddrttls. */ - if (naddrttls) - *naddrttls = 0; - - /* Give up if abuf doesn't have room for a header. */ - if (alen < HFIXEDSZ) - return ARES_EBADRESP; - - /* Fetch the question and answer count from the header. */ - qdcount = DNS_HEADER_QDCOUNT(abuf); - ancount = DNS_HEADER_ANCOUNT(abuf); - if (qdcount != 1) - return ARES_EBADRESP; - - /* Expand the name from the question, and skip past the question. */ - aptr = abuf + HFIXEDSZ; - status = ares__expand_name_for_response(aptr, abuf, alen, &hostname, &len); - if (status != ARES_SUCCESS) - return status; - if (aptr + len + QFIXEDSZ > abuf + alen) - { - ares_free(hostname); - return ARES_EBADRESP; - } - aptr += len + QFIXEDSZ; - - /* Allocate addresses and aliases; ancount gives an upper bound for both. */ - if (host) - { - addrs = ares_malloc(ancount * sizeof(struct ares_in6_addr)); - if (!addrs) - { - ares_free(hostname); - return ARES_ENOMEM; - } - aliases = ares_malloc((ancount + 1) * sizeof(char *)); - if (!aliases) - { - ares_free(hostname); - ares_free(addrs); - return ARES_ENOMEM; - } - } - else - { - addrs = NULL; - aliases = NULL; - } - naddrs = 0; - naliases = 0; - - /* Examine each answer resource record (RR) in turn. */ - for (i = 0; i < (int)ancount; i++) - { - /* Decode the RR up to the data field. */ - status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); - if (status != ARES_SUCCESS) - break; - aptr += len; - if (aptr + RRFIXEDSZ > abuf + alen) - { - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } - rr_type = DNS_RR_TYPE(aptr); - rr_class = DNS_RR_CLASS(aptr); - rr_len = DNS_RR_LEN(aptr); - rr_ttl = DNS_RR_TTL(aptr); - aptr += RRFIXEDSZ; - if (aptr + rr_len > abuf + alen) - { - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } - - if (rr_class == C_IN && rr_type == T_AAAA - && rr_len == sizeof(struct ares_in6_addr) - && strcasecmp(rr_name, hostname) == 0) - { - if (addrs) - { - if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - memcpy(&addrs[naddrs], aptr, sizeof(struct ares_in6_addr)); - } - if (naddrs < max_addr_ttls) - { - struct ares_addr6ttl * const at = &addrttls[naddrs]; - if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - ares_free(rr_name); - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - memcpy(&at->ip6addr, aptr, sizeof(struct ares_in6_addr)); - at->ttl = rr_ttl; - } - naddrs++; - status = ARES_SUCCESS; - } - - if (rr_class == C_IN && rr_type == T_CNAME) - { - /* Record the RR name as an alias. */ - if (aliases) - aliases[naliases] = rr_name; - else - ares_free(rr_name); - naliases++; - - /* Decode the RR data and replace the hostname with it. */ - status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, - &len); - if (status != ARES_SUCCESS) - break; - ares_free(hostname); - hostname = rr_data; - - /* Take the min of the TTLs we see in the CNAME chain. */ - if (cname_ttl > rr_ttl) - cname_ttl = rr_ttl; - } - else - ares_free(rr_name); - - aptr += rr_len; - if (aptr > abuf + alen) - { /* LCOV_EXCL_START: already checked above */ - status = ARES_EBADRESP; - break; - } /* LCOV_EXCL_STOP */ - } - - /* the check for naliases to be zero is to make sure CNAME responses - don't get caught here */ - if (status == ARES_SUCCESS && naddrs == 0 && naliases == 0) - status = ARES_ENODATA; - if (status == ARES_SUCCESS) - { - /* We got our answer. */ - if (naddrttls) - { - const int n = naddrs < max_addr_ttls ? naddrs : max_addr_ttls; - for (i = 0; i < n; i++) - { - /* Ensure that each A TTL is no larger than the CNAME TTL. */ - if (addrttls[i].ttl > cname_ttl) - addrttls[i].ttl = cname_ttl; - } - *naddrttls = n; - } - if (aliases) - aliases[naliases] = NULL; - if (host) - { - /* Allocate memory to build the host entry. */ - hostent = ares_malloc(sizeof(struct hostent)); - if (hostent) - { - hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); - if (hostent->h_addr_list) - { - /* Fill in the hostent and return successfully. */ - hostent->h_name = hostname; - hostent->h_aliases = aliases; - hostent->h_addrtype = AF_INET6; - hostent->h_length = sizeof(struct ares_in6_addr); - for (i = 0; i < naddrs; i++) - hostent->h_addr_list[i] = (char *) &addrs[i]; - hostent->h_addr_list[naddrs] = NULL; - if (!naddrs && addrs) - ares_free(addrs); - *host = hostent; - return ARES_SUCCESS; - } - ares_free(hostent); - } - status = ARES_ENOMEM; - } - } - if (aliases) - { - for (i = 0; i < naliases; i++) - ares_free(aliases[i]); - ares_free(aliases); - } - ares_free(addrs); - ares_free(hostname); - return status; -} diff --git a/ares_parse_aaaa_reply.pdf b/ares_parse_aaaa_reply.pdf deleted file mode 100644 index b436426bfa669f21e9b3560aabbedf0bb7b3d21d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18910 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 diff --git a/ares_parse_mx_reply.pdf b/ares_parse_mx_reply.pdf deleted file mode 100644 index 83945edb2d8a30d7962a902cbb871fab6b70f057..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20153 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 gCH{8|Gx$pepq`cvyVyzb=^% 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 - * - * Permission to use, copy, modify, and distribute this - * software and its documentation for any purpose and without - * fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright - * notice and this permission notice appear in supporting - * documentation, and that the name of M.I.T. not be used in - * advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" - * without express or implied warranty. - */ - -#include "ares_setup.h" - -#ifdef HAVE_NETINET_IN_H -# include -#endif -#ifdef HAVE_NETDB_H -# include -#endif -#ifdef HAVE_ARPA_INET_H -# include -#endif -#ifdef HAVE_ARPA_NAMESER_H -# include -#else -# include "nameser.h" -#endif -#ifdef HAVE_ARPA_NAMESER_COMPAT_H -# include -#endif - -#include "ares.h" -#include "ares_dns.h" -#include "ares_data.h" -#include "ares_private.h" - -int -ares_parse_soa_reply(const unsigned char *abuf, int alen, - struct ares_soa_reply **soa_out) -{ - const unsigned char *aptr; - long len; - char *qname = NULL, *rr_name = NULL; - struct ares_soa_reply *soa = NULL; - int qdcount, ancount; - int status; - - if (alen < HFIXEDSZ) - return ARES_EBADRESP; - - /* parse message header */ - qdcount = DNS_HEADER_QDCOUNT(abuf); - ancount = DNS_HEADER_ANCOUNT(abuf); - if (qdcount != 1 || ancount != 1) - return ARES_EBADRESP; - aptr = abuf + HFIXEDSZ; - - /* query name */ - status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len); - if (status != ARES_SUCCESS) - goto failed_stat; - aptr += len; - - /* skip qtype & qclass */ - if (aptr + QFIXEDSZ > abuf + alen) - goto failed; - aptr += QFIXEDSZ; - - /* rr_name */ - status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); - if (status != ARES_SUCCESS) - goto failed_stat; - aptr += len; - - /* skip rr_type, rr_class, rr_ttl, rr_rdlen */ - if (aptr + RRFIXEDSZ > abuf + alen) - goto failed; - aptr += RRFIXEDSZ; - - /* allocate result struct */ - soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY); - if (!soa) - { - status = ARES_ENOMEM; - goto failed_stat; - } - - /* nsname */ - status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, &len); - if (status != ARES_SUCCESS) - goto failed_stat; - aptr += len; - - /* hostmaster */ - status = ares__expand_name_for_response(aptr, abuf, alen, &soa->hostmaster, &len); - if (status != ARES_SUCCESS) - goto failed_stat; - aptr += len; - - /* integer fields */ - if (aptr + 5 * 4 > abuf + alen) - goto failed; - soa->serial = DNS__32BIT(aptr + 0 * 4); - soa->refresh = DNS__32BIT(aptr + 1 * 4); - soa->retry = DNS__32BIT(aptr + 2 * 4); - soa->expire = DNS__32BIT(aptr + 3 * 4); - soa->minttl = DNS__32BIT(aptr + 4 * 4); - - ares_free(qname); - ares_free(rr_name); - - *soa_out = soa; - - return ARES_SUCCESS; - -failed: - status = ARES_EBADRESP; - -failed_stat: - ares_free_data(soa); - if (qname) - ares_free(qname); - if (rr_name) - ares_free(rr_name); - return status; -} - diff --git a/ares_parse_soa_reply.pdf b/ares_parse_soa_reply.pdf deleted file mode 100644 index 8e573dcc53bda34f7bce35c6a2b09a181c056c2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18795 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 ItIFW~9~|%AP5=M^ diff --git a/ares_parse_srv_reply.pdf b/ares_parse_srv_reply.pdf deleted file mode 100644 index 5bab37b90233cdaec3d7fb68cd7dc8990400b876..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20049 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 JE-^JJ^1t7Y24?^O diff --git a/ares_process.pdf b/ares_process.pdf deleted file mode 100644 index 0620ea37765b8720fb7db76b78e1624523912636..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21140 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 diff --git a/ares_search.pdf b/ares_search.pdf deleted file mode 100644 index 43258e6cde71dfd94fc048b1e7c9aee96156ea7e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23691 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 Q5(P&XNN8)DJ6cHm8#&7z%K!iX diff --git a/ares_send.pdf b/ares_send.pdf deleted file mode 100644 index 222353b893aad72f8ce1058c770d535d06d8af6d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21752 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 UHEvui7!bT+n%UdC`+AuD7j`wRnE(I) diff --git a/ares_set_local_dev.pdf b/ares_set_local_dev.pdf deleted file mode 100644 index afbd7940fabf611149e78027db299db0cd360c36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17319 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

ceCHlUTfpy0@ZxF? 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 diff --git a/ares_set_local_ip6.pdf b/ares_set_local_ip6.pdf deleted file mode 100644 index fe8aa2c3b6f01e6f82589f1bf1c8873bf436f606..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16600 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≻uo^bNl3! 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 diff --git a/ares_set_servers_csv.pdf b/ares_set_servers_csv.pdf deleted file mode 100644 index 8e64a79b3a1a32ad5eff310f226cbadf1798a4ff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18503 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 UcPUvR>o8H5bhML`;kP60Z`o{poB#j- diff --git a/ares_set_socket_callback.pdf b/ares_set_socket_callback.pdf deleted file mode 100644 index 53fcad627b0b22c2195ad7c9cf25554dcdd6ce90..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19226 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 diff --git a/ares_set_socket_configure_callback.pdf b/ares_set_socket_configure_callback.pdf deleted file mode 100644 index 9df47b1384efe3df876440a7391587f1d6d931ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19138 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 diff --git a/ares_strerror.pdf b/ares_strerror.pdf deleted file mode 100644 index f55fc80dc8b9b84743e8229185b1306764ce00c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15058 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 P4&X=~4UOb|Da`)^u4F*c diff --git a/ares_timeout.pdf b/ares_timeout.pdf deleted file mode 100644 index 1d1e43ffb7c263ba0c39e296bc4364764cb921ae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18550 zcmb`v1zeQd(*P{3NGdI{NawOkF4A4nAtkxM(%mTyA}OtuARPkIrASH%(xHHKcgnYm zalQBc|L^yH-|t=6XHU$`InT^FXXcr6=Al!TkYWR|b79hTZbWBeasxO3cE*;N0s=q< zsI9rP1%L-$q6(CPSvx}=0YE8hBWI`t)WpsdDkOyINg_6m(V8U2Wp?epuzvAltW9M`unnw|PAehqjN*vdtCJ!w`+FSvc!(Yee!>2^ z&m80|NI)Ux_4oR@joOnVb}_HIok8DSnCJoZn(rH$Gf=>7JwX}Q+xs}8vC-Md#*{gW zwPClO&EKGlzP-F>TYZ{bT&7jC9fyl^`6at(zFBd-GVP*b=hg?19;&?V4*K!j1K}Fz zD1ipkkc-aS)i(W(kI|sWj8sQIrCHWQ%A;HEeE`PnckMmEPjvM>9yP5c6s5%rZJ zw1JnzDhzC76yvPqVaBpzAFBuY?09SJc-NzLi?<8p&lH!Bin2fAY-(n14^PtJzY;T+ zmPx$@LfMQ~zgE2=X?U$vP z^#bWAzhr>c#^r))pEC3TdjQI%4W*P_bPh@~E-}#5?&Ixw0iizBL(v`G7eZ9(~ z*#7C!d*dMTm%h4wxH#9Im_G8ge`6i=uE4MPv%9F@=Pe`LqpOSii!M?}n zW(^Hg)KKB!$2@pM{Ls^{oc43RwknxnhfKzSk5zOalc#F~r7E>qJIz;%WJrt~ng(CS z5`i)0QlP@+ZMJZFt11nhXDAa)(W|2&XUTcn^Wx5f`+{6wQHJipG z-&+<#dXGeRgcJNVv%n}nS}}W?nX;#l8HoiOOT90}2lS9M25+ijFB6n4h3Cbu(7W)3 zzul;dbMZLEu&dBy zI0Lb`*l6!I`W#DKW>cqQ&gY9-yd1=Fep1e$+aKv6RX&VU)`cGOG(`2yG7FlbRDR)`0d}0eYqE~JRUVLm8P1fn}^xC!zW-sHZ z0d6!6M;X^VuMF`A4|i4eHoR|tkoC*%R||RUedg2EXMi#eIrESA**O%QiL0aQvF84MJK@TqM!XkH1R`i z!KuMJ2)OQ{696a=Gj#&!V*a3~4}eo}L6AgH`-uwrjrtQ)+{oF;+RpqJiJ!fH2z53x zh1USUh?~9c&QAioe<$$QZD0bGlpg{>LPEb<`h$zAyqE|))j#_2hw4=YfiXc~L_JUy z#DNLAZW5@k1!i*1NC~Kui6hM3 z+0GFFy1uFF`@OD$a~kI8G?(Tx~EaIyU!A&5r)$z`cW z;u`YGKe;SsXKnf~9wP>p>VM`jC-@H@gZO^&7!%C>gAYIM;79rw-+z?-fVjT?SI%+s zA~3J7a2NzY5%jvJ0{~z)}$oHS(kycSv zmC^hu9#uOVBinz<2XXKJ8}aaR{!2W+ZlB|Clj859L5S#l{5z(BwvYW@<@Z_2*~bS)ZqfByVM(EZiFA3{RpuBQ@w zX#A|Xo=S-HuU;VPe_zE4EC$z|x@^2)02`R&#|p*+;nYVwVwpPuIKh}eQ703G{)Csp zRiBZ)3>0Q=@iU8P2T_MW#RUFXJ1H6R744wb2BC5H$~BPEPQp?s^diz(*)1 z@X=2)TwL&K#EK8s!;C;9pa~EPv;bNIZGg5wJD@$#9-+Lgp=QoMQjUnWfsQ~YpcB*v zW@2Y;XA5)&I$JnGp+FZ~Q>depiJc=9=n8aay1sMx10$3Z0J?s9{DWt|j0?C8@Z*v4 z&nHTF&;MM3#eY45f;qW3g@k@TY(h0|E326kHG@K?HJ!CAMkQ?6M{Ru6&Dka=3mY_4 zZfjCTL>rgfq(`Eqj=@0oXrW@D4&p^pxQ`mNv(qN7EQ0o2$hlg`f081j$i~g>?Udqi zOaJD_tq(8yw?6h?F89CKzq+bhPTzhoXJp7}Zit0$a>a_xh z`vC^f4wWa%*~_ziZW#r=j`hB=@rScVd-~21v;dS{Nys5n`y-40U z?S!-k=z^j5NXj3%|D%*`6EdiJtTY_g|y2TN%jd34Xve^?T7`i>$S;?j&Fn%bJ zE^Wmeh{D^^LP5%pR$HcOP+Yl47LAvod~c)xhla#`sQL-NMyCklPG6EYKe>;;-d)2W z%FG=U`g)~2$4{b}1Iny&6B13Rpp&(srh!twA=gvptF!7^X^w!oImi)@fmYY5Ro`SC z)AAw8ZjeQ^NFvS&L){GV_FG|!ddc*<>9JAVld63a+Mxk}flp7PROuqQTZJ6Wv${)5 z<$%W$Y(y%0+SXsGMr6-WbbRVjw5S83FDr^(A+I$0jHOZrS7E=UZyf>?M9xZYE9ByK z(0Qky+k%IVaFaSUFl{MoH*;MXs^z*Red%5gI27MdHA*w>Ys1B*+a}&d)AJl5-Vg|{ z-MlNY-p8^Wy6OB#U?<-0j5O>xO`fqd%iQpdRdIC_Qcu=LO|yK)g7PyYJ1YyU(8vqb zV0AV&02mC8Q%9~2dl0d=xz(rBWK#J|>m81#Kq+QxV0DOb3DYnw^=wvurNxzwpM(EX z!N-fyXJ7j#x;=(UHLDVGUd@_)mR29}>MhJfC$sTop=9IXJ>9^*P5CTZ@g@6)uzd<1 zPT^!0;Wid}J^R~Ryy|=FG}*-HL-!N;-@O7&jc`q(yE%~hRA!4Tu!@_GJW49*VCR7@?n~Pj_e&JIr^kMg&AIySQ6>O9u(QLw9ZX zeE-Cvvza{pqs3c)%9?4Y-K%$nrfTft?mhm6(DKT|hJn+`y~_s?^6IUeIz3j?H*9ft z2?U{nPm{&-2+q6b&Ph!_-rOgMa;PpMW6q>1gbG>uYD>{olegCfY>puN-_=S=ZNi?> zSE4`llPq><_b+m<&6Lbmwt7zY*e55#;Pqj0+l_*IOx~xMoSrj0uj+IU?)u{w8#<sPIe&`Zl@mPQ|FFlM`|+Kl4LNy~=eVWnF`cojG=R|S z?o{we1%5UjVWQ;^#2GOx=FYHpulwTanNInEw?1-kT-d=f6TeXzR`zBzxtHR(KgODO zn_;+8BKyZ|5{DpPbuaPd0gRW(Z=Nzqv*Fn5q*HRcm6K&+rnXrX$_t40eJjm1BU~aR zS`9EqGAWoXVjD|Jy&+tvNlZkpRvl`^+!-3KTwB*Z1(3sO>{gSv}pIHIAyZxAkVZ(krF*O&|#6TnxG%~vf3$Q;_%^ec){1z zy?jFH2#LBoV##!@+9mB*S}M|89xZ2*DsFz6!%fN~5ru0Z17z%Yn{#IjfS`skcV5GuC0yP01q52VO!= z_S;M5GhYJvDf(bV`sOSXvbX9|xt!Qnc2*{zplht#YxOQD860F}fcQU1C~_rL`joWg zqfQ$hj%p^1CUV~yMqYCKYRlsp*=V;{y_BnmJ-*!imc<&lyVr?dHB#>Z&m>&YYHFV)|qp3{eVN{aL`U>Tpu zkO`3v1*t5@4;Q2clOb`?;lOXxYxa|9*TXU~>KXGF1JxBABiC(L5I*vu+(pnd3I1C98 zK)jodU*{ctdoPZ8?UoL#yk=^J5se*P@c`lPC0`)0)m*!;2 zeC*bry}wm=0r?QMNJQ0xCFR^Gz`gDcD+qo3SP5!M8*+K??!yvQ#KY^~{W{lAb$^<} z2yelEvRD7}qwTe|%7HLAK>!Gx77riKZ(Eh?FI$z5=Wn(u{BaWahph_wZ?-BA9PNLw zRe2B=@Go0c6etdq07?R7fU-aZ;6tDyPzk6ER0XO5)qxs7ZMeMy_g_FAVNONO}3O8=efadVs3U~$F%!R=XU2CY5)3vp0>tbUJw_joA|AXOc52t5m`osRUH!^|3 zZC{ta*}Z?WdjIL#`NKu@zqfihA>3SlSiLSV;r3{ZdFQjcRR^L9Z>=M<%C6 z`49NBRWaHN{4s;5MM&-dM3Cd~09f5Pw~Vk*WdKO1+4sd!F{~-p1jZDPAk)WZ)){3@ zO*O}^RP`QKO%xV$<+GmarX}e{8BNDmesfosb6=Go169az%$Iy+^By&O$FtIOJJp5x zJb&Ns748#t+u>u`ZF-*FOkCnKckF>Qiuvf$J}F4$U}6#zduZjZVTYNvrsy+TI&R*R zC=@RmVxWHgM$7hv(TAyRbOwTp@3egCtVyqA0*Pbey&XbWS=3nju#-&b7rO(Gd%z31 zZC~GfZhH{u79LOQk#cp6B&j0LD+e7)s}!qQ>~ea)C-gCTE~S=*Nw4t%D+e| z(iEy3inJF9PvJAMQ(A z5GB5O7yuUPPZvnM(5zUqhsBUnI1YL#ctn-o)>*5!G1o;$Q6ZYEZe~JT5)H0bSJgm@ zJY=Sb$?-aPMMh!tGUpSO1JgkCCCTKYmbCP;L4gD2)J~`ug@Rml{RGENyjK|#K8@8E6s=gv<BMP>(o_jG7puRb8-|fP7s}2cE8Q3o6IZhl7jJ5MKQw~WRxw(P zBBm#|9{*YTlOPN6CtvI5g-JeTNyCw1gK3OGkqXxL1I>ZhZB7n5Ze=v+Xx_(nJ+W^k zUIn29g(xhko+DjQJ}!JZ*&yxktg$M~<|4wL8A!e;wr$Vwjy{otPrtuK!-y?VHD5iq z`z{BDA4!-wK++?AQf1=iy+D4QHS~wrgM*CrU+fmEiVBM|1+jy_mLWUbESbt@I?Z87 z+$KN3sHVd{3%wCMWWifMGCeVB|B+l`RPCkNRZfNzlFg#x%|T-`J9nuq(O~s>752a> zqZ80-?Lp%iz8MS33r08X zX&(nAeR)J4N%ZAZCaBStN_r$(3_1MlZlYJfK6k((MO93s;#UqcB^RT#?>HjJXU*dFY$OC&m_1T)g2rhmUIO?!jmbvbo@Z@`J%zdH{Up=~TS%OX) z)BUQmo4W8&=n1)=_G)g7p}c}_bG+D$3Ow%5wR=Fn5@9)urPap!eEW50?g#SzDJ0SK zNyiA*U7`)BK`mdHxcz$ij=8NyHKB&|6IrH`NOeLxCJe_TO2IIRMpoaBP)zMYR-SJ; zH1`1G+JlQk*>}!}`Dkt5d4G{maypS5XJLXiBLV0H4GXBGx6@<4Xr&`#M7(V5I5wfV zSu{4uH*hm&C^;~kgNV1y>c(bvXM^V*w*PqTzvQ@tsg$76O zl8_vfYvMCUUDPu*!USiX)&lP>eLnrib`^q)73?_8F zHHT5!TJ##u29Dcl&S`=)c($8%X`ep6SxDHl6IK5+-(B! zX?h|;v>Bk_S1v=LDFxmi7qu&3t6CXAN(klRiyoDvQnB0J*&^+p=q$W9#B&=|L@49|z`DT^a@odYP z@8v^j7L6=QJ_7~W*r@kQaRT#WPNy{WQfvwD=Xfsa2p z4NXIk+_bx0@?O0vlzUy~FUoB5LL+Q#wewzQ1@4mV)7gYUCMvSEErC&md~?DCZuOKb z(((F|PBf%BeMhrxBHO$Qw>4_0+%rbCSoDRqt)bd`#L_nA!uVVgZj1vWyc;&8Bd34KPQcQ+P-)hybcIsEPr})0=51u zaw)GN_~?IPe}Kvyk77O5RPsQ!d)yqGhY$#Y2~Oh`%Jaw^OE!M`MTGPh{|&dsZcLpTCH=;Uz+){n^~M-O6BHnxAyKxQpfx$P zK`QwXjnM*!VcC~Oy*th?-twb=v2nhzFq3D+hgoiVzuBzAP5SQLJm=}EP#Z{D&1Y4L z_gzxIWC88zd~`F^&_gy$s-#QJ!jU>G!9c1q)^F^ae5sH}#0Q!ZG@ciIR1VV{I>+h$ z#r;~!&jMR2nlm5z;g*Y~5`1{pE%cc8JO&r2!#Z|PX1v?+ta&sMw+8tF6lG9e#6bdZ%Pg?bWO*x`6$(^aI7r8ZXF(_hKh4ML%m;s4=6B2D#P|O#gX}Eb(&E zmDsvdSU~p9&lKkN?}<(OkAkJRa$I&;H>l-Dpvegx)^SVs zqb(WF8NAORG!`^xoU6VYjp3iMo^{^trhezZh#H#7_la7pi&`vnSL^^?h;igKXIT9+ z^Em2?hCmRNSMb#noUDxUHs4c-n@9EPp?RA!})h~9O7G#IKNcCqUO?UcU z3B$JdW+(GMtFQF*%A@8=KBrSg0jJlMB8Bd^e`^vidMn+%P>Fha$L7A?t)p=Ed1>z^ znVj$dIDX&6lvg<<;;0KA4K3PRU@kNaFO|ShhIpl|R`Jv~JA^N7kIkWYm!%n_K}&Jx!jCkL(cRv8@}A%LA|aV(}e< zTh^-@vNP&DMTNXx$ip_wY$=6l3^->sp5o^X7N6$Jc9gOF9Pged1emE+4q4k; z6i{F8P6eFAykK_lZ02a-DDe(_$(1eiCfu^>;}w}s2(dfnDmys7Jn93R{f+Y3mohU@ z7rK_}K~x)UJtl4ChZq7MxU!TQCGG&%l$88cb>Eng_d-SM-z$>honDy1xz<7LWq^5gpr`XW)ejoEUNp zAPu1EQ&84&^A{^X*zIL?UL8@i=A=qwSqjbsqt+Hm4QHMsmlKhls=th`HntmlKbB)L zyU5v$Bfal=qPghfOK_Un`YL$TW-y`n$YQ`iu$*bY{(FRGW`pfk`_UZv`ZD2>HwosB z2N`g>1=|aFM_)=5`5>(Hd*j4jwRCVs*Xq=_C`)8=Uy1j*N8(x%CUNU%xL?e7p81#> zI=7zU31O_z+niKQcvkz8k@o9H3j?P528k!X01R8&zt&aBo3nAyDuIA?0AUoxuU~n0 zcl=WP2HIZmZ5qa5FQOQ(9OL>ob$dL>LH%SE*ROBSK=3WhEwG?0AU2}ISjp>XoVKs( zA+zfsY?y1Oe8SqMl50|@xVi){-MV{b;gpOc?6YJ+J#0p?NK@DEo{ou44cBDss`YcA|yQn=gHiXXj+#OtD7ctTNlL#@(-IL#x==4O-&6@(oWPfr02a~{#d&y6nC8vRnvxZ`wt9-k z*ERJ|B2D>ocE-MV&D5)Y^Ua6JHw3U0kg|b%zEzMucS(t0qN0hQHPU4dP63y&fu;pB ztRH{8T`G!NMVBzydMx!@Af}dz2@fhb7tHxtN8mA?fCj9DoO#d+g>#?#`7O_KgFJ=U ziG45YhlfqBMq`HhGa_y_l9@u9TGhu3c47M@RpIB9!>#}U0Z z@)qqgNpb}xVaA)~o#cHa1t4+pD1eA5;BC*2rHMYQf{)EXjTVL_#jW$+A%|P>)c%7h%N@Hse#=SORI z+etdP1Gic_g(L2`ub-+aY@j5~?Hdr^7He51o`*D^rnO|$e|KCXo!^5l&PNv1Jl+v3 ziDClebQRf{3JF6W+%t%xMfaVg=>BSqDG3r@$>mWe^xmC3(p( z@>n6@-wu?2ZYTaX|H*&Zd;aY}0r3I&csSt>6uw^$lt29^h+VnA_WJn#=05?!bN_j- z4-ENF{*%ACOeBF)K&?OI zT~PQIp)Jf73g0KRgJ1v4Ug1xdiNoKVCOjK_3HXV>T3M zsRID}c<4|{)M|D7*Kc(q)k>aE9(k^B%1pT(f3@AxKSn(t)wOGCpfsvLK409px;Rhs zB^lq)CJAgyrb=j!?tOeWraxNN>9RR)&se$FOa;h+B$syP)02d@#MyQ+q2HU>yoQs( z{^S#y{ealhZo`eRFWU+Oj9qeaG9Pz+zsZPn6%}c8hcDE}T+(`a)0yVr*)UiJq} z)O}ubm-Ik(ZoxpRq(mo2(PD$PU0lU>iU=hcEE!BJIY?ZO-?xLJ`mr&ori!n9QL|}29M%xm zoBN%QJ8(>p#^qS?bc4~1$_%B;wJHoZxLHwkqk@gMO^n7Bt+9!oof=zJ=#Sf43%J%vdFn;H0fJ6CmMa}9<GhBk93T_m>3H&qt^8Jb-;H z>BnWK(iyt@dO2w|X@&t~PlC{{syU2|F0WQDbq>wmxuc4u#202CKV2#){SJ8^ zHnQ@}q~INjS1s<%T%ksQEG6yy&2Uxmlzw!X*Ba#g;{0Okz@(7pF$W=-4ApJj7N@u2 zr&#ZjH(v>&e!F9Xh!%-lMxS6wd62z#CxM+AA-acZ5k& zdx{5+Q)=X^pU?F_(+DlHOfuE5Y`HNQZY|_eexq+U7k43S)@NWD_EmVtdlOgG(Yz^p z?smTyviW;L`>&q*Z5Bi?TA7Q*`@BB~=|zd2)_JLFWct&PPGzpPpy3g(jV}7;Lq0(4 z`FdEmW~O9@tvkPK#p(tC_w?>$EAmjOvFgolgzfkZpNdHV1+RnjIz6cbjRQA~3$i(C z0NRO|s-jZbzAkcBvz=eiZ!P;epRZflbf2$W0QDDNQGCMFLi^!E64c{295LAPa0)3|7LZdcmt7Y(hT(jL5{E+~jqw*}nW zy>oKMYLcndu4q&BQqgfTV{juu&Xp)0xiHc`FdC+8TWU0&W|*2Nl8Z7|M66-K9?y|v zu`RsKT3txUW1Bmk$BtndxbSLU{qaLp1)Z&a`&olq)k1u{qHDm+b6unIwGDsks)%g& zE)fecb!K6RPYBgznRHLceI9)<_1yi0lR>(&WTpv2`!$)`jVmS(;w&Fs>bbl;ZI{B- zakCh83%hs@>{3AUCr!DH?ZJBv1TJsLEKQouL&q`)N^%dnXM=dhKkT3-l4}tb$d8Di z5qQ=yb;g}+}VC5p~%G2@$9B3?-4yw6v^(`Oz=Db{zZG4q<<^{~5 zm`^y4{#d|q;>Poa;EO>%o8*}dt!J7HBw<%*vI=v4=Zo5Me4EpBo6}gT-4hl2$Ad2h zQ#Dg2++&J6BMp&Rh_${E%k29jhdo8hjeTa4C`0BYJtS{I7~xy(ah@-{Jv<}a(Wd?7 z-VI{c1J@Xih(Uwu2_UH~?|2?b)=~}U*5F{ZTHD6+nD$;SbnfFFdSBI4^FD%8=b-Sw8;m;>XBS zg}a-%;0D+9pbC3};6ZbBM!x|UDVxvj87v9HSq=J{u5${SIXp-X1{!&Tn*bFKvf#EW z7{cNOHkUzT*dKa`7fO%4*y#1@;^3D-w@CqqjkQm=DA)_gIq z=fqzi*0DYVgDUg+9pgu8)I*XnT@u!id!7wNuiwlI3HM7V8~Hs}DH9_=Z3$Q<}d zS)wHYy}EfkALOrU$nNIc_F?Cld2gSpQ&Ah5wJh%;u)g(@%Wp}ksY9v>`68=_XSifR z;uR}UE&B}@b6o_E3X~qe>F5MDK07hNYv9Kr-epYp#VR^9VpQXKxzSDM7eC-w-=~ z9eAm6iLQp-g!WbHl!YDbsme?2t(@pDEV!_FRSaS1Z8~r@NerYXLX;AVx;3m`ayn*; zRDTnOU@s*Nxa1u92a>$|XG>$e# z!D-x%V{OgQV6#i3RNAAwfVpL0oh!fE&3Rbff}*6~yIMdgk*=Gu2gTI*Y!&Hc?4UmB zMu^i{m-*Yvyg;O>#8wj=0m4PCJe=$g93%Vq=>{{?IuoS}e1qtqp+Y7#q+2oFj+LsP znY9DBTDrEFN`b6nBxp80a?0rB-*QX%>!F<=G_wiS<))qqNdmp@lb`OG5cVwIc}7xd zj|X#9tE;PO%uYPM!S4Q~F^ai~j1iJ4qMcrxLM`=xdz*iu@>cQ{+uhO>&*+lT&M?l1 zXL1mjBrCp3Aty2?;G8uW)VL~l-{t-(^+9@2NiPS@%70YEtg`o5oGr{hw=iNJlQ_GO zdB+PldM1o$!CFXhqFm~#5D|`+J zKRuz%9t~W0zNGW1Fv!J!SY20NxZcWL&E3LRj1|br?1Sr`B(Z^EMZK?J2i0Y$scW8` z@Jw+&?{xB$!!U^{Of~(4pRuKe`V9Q~P)1@^n^Di-Ps2KX9X8<}HQ2~Vcvjo4qWRF8 zJHm>)C3b`vne26_HX&b?YR#izqpG9sZ@S-|>t0B~g3Y8v4;PO1rt(q(sj^aJmw!5_4eD$ibphFQ7=*r@Gf(5!8fHrtL=C~@S7Q&V zDM7NJ+)3K%$7T9>$L!l8Exi;GYM=?=4RaQoGvlcizx@;0<><@zrUR{Y^^yMGi2;c< z?@1U?;;Qs#U65RmHj|QybQ{)t2w@u2Jqiu;v@iS%3)ddxq~e?gn@X7NfoUS|RBguz zF&Sjtt2Jv7+gium_=fYY6HpV-K--8k6Gn=x_hjszkz;gsxBcvs?DIZF`sWHBZ@k{# z@encY;$7Ae;Oqe_RQZ<8d~N72W7?7e134c64d{VPON-wM7pqj4Cl@bIABcnFMFmK` zh1WtG47d)X?Hi^P-v-*+Z(3a8pcp54QVyBxiqhpnJ`Y*1vKEZ4h!U^3RB>lG^7FTP z3}%-mRmICdE(Ol3_5#+(0U7CW^yIUy$Q3-ORam3C6iwzH^e2MnZz@glOJuvs7Bv|r z@3%RCIRtmdF)A`HT7BrllFm0AP2a3pb#@QWskFVlnY+o>vuy)R7O;8HBSlMkAV zq3vbHBya%hy)hjjwJ-o+uu2X!t`g`-j7TEM)f*Jx%$FB*bAbN%@0&ucgQQ?F`$ip79;jX_J)j!p~${$=S!0Y0g)kdz<08lo_9a0hk!g1Fx#;ZIQ!`QFMsg z?+h1LuJ^iVw!)IT+l<93bCfGy2OXS{^}o~^=Kx@vJGcj(ob%%>Dx z@vP=oWXA(k;@xHPf{$M#!xopnQuaDVd~?i7LcSR#c6-&K@V?M&+y)^^c2GAgyZ{XZ zKy7?La?|`gI)el!bx(w-4!ALXZs%=}Umxt?w4<5ORrp@;qR{0CGc*Z1owZc+ zliMA)W5Pps(Y+~*79YZcTYKcoY%K(wH`(Ke&l^f#tP;~Y+fS)7gIO+D8HG5XD+?cS zW~Sf(vOZf=^~+hwJ9sJ(tUfFuGZBg z%Q#+sxF2sIrt)pb?q}5DMpQWp_h$AEKqah!Z!p?_b|pr|M){r`A5pL<+K8!9mRtv6 zm{BT9H29Tfr+3(BtKmSRS?$e!+tQ0i;#0O&K`TR(5dj1QL~?Yhp1v;ouXyf$IOEgS z88X5T-4>(tp{)mdo>a=wxDR^-@zlO**Ak+E1QKYxKk>Qq-6;m*(w;kKjN}Vfnqw^r z*`CN7Djne`r1%)BH7EvnvoRpO!O{)nFuU!A^Z;6lRm$dpfTB$oihs9Ub2Oh{DWRB2(O?5S#Wm{H0BxV|%gGa~d+ zsSoTLd7Zq7Gx$EB0yW)hzDM(_{NsD+TC}9N)M$U17^WF#|3-Pn!>lK?9x=%@v_05F zV=a`a#o0G0nd!I!RAmRBzEW(`d(U^Cd~4v7#VmgRK!otpx#m2x|I&@B+VyHXtpiD} zZ_i$hvk1;Ly_`*PU^oxCU_T+eQ2DO0&%Ind+P@2$+$nvhMg_{3I!P8}yPaoxl2H?k zADuE|L44j{H`-B}HPEtpg4PPT!T#)Ox37D=GR1{@6CAsoI)^`1I+_T0?ZvzNJ)L(zkg8~0xK>!E3N?S~7-hEG6b^`a*e_(hW@iie*& z3T7YDQw(}&%V|h5t?o+CdmJo(i|MXKOHrs@A?6WgVWBGl73G!`WL2|Oh7UNU^k?s5 zjVT?SuEv#{kEH3y9J7ZD#n;IjMxxAN2Jvia$DPG8e#&WD*XDXoj%~&Quqv4+prnxI z@)hgm*;GJomi|0v)XET@qR#Ifz{dT7Dv>4H5|V#2R5x?mZSHs)1(#2_#pxbrkuX^FIYpB=<>OV2lik8?XFXT0*bKjmoM|H7H$Oymh4 zh$X&r`E}&6=>V3a{zxtcmduRtJD-sxYm$fzRP+~ZpDtgRXKAM!zJ_XM#)9;#JsJB0+ zOv-Or9F5(oxYWG>^c*$nt?W>yXHWJql|jK9L;~$_HZwD z``h!d-Tv9b^P=JJk2()ea6mlExtqSzGCG*P`{oPuXfq}R z6;Ea>`ss8FoAbslL$y!RfaAc7xgCi-33ATjcuMm+FGjX2)yJnZcfUD0=96TaJs>Ud zgFfzuzMuF;Tx9q1{Bl;K7Ec6t=d3u?Y48r0-Fvyk;OUOJfbkFCdzzzbD=h9Bd*+OB z%DR&(R*3pKWHoXKGCYpE(Pe}0_O(&|xt3*`JA)OO4V(YP(nqPP;AQ%P%qP8urf9Q* z$3u-$IYXu#_03BI+dQ91qRirl9`Rg3u+Di6b_L1)?c=_VZv69*;IFvHzhW~UJyiG= zm;vJC;`x0I^W3n!{`b8MYf*7yvL+K?W`Eha3;>#i1538Ba&3nx~?= ziKmqb#FRl;2vb1V2p)9`Wpg*OXEVEg$$%389@`>#UtCo|>OKO%o!{NY-Uc3i32?Wu zwsqon7i73b;fJRY#XttYHHfp7Aj6}F$^d6OJ8LVLGXTsEVF$5+I9UN^j_@!XH#=6*e&H?<@(61wwFgsfSqG2OrI~Qj` z1{W8YDL;=12m}FfaI+ahxp~+?ATtmf2mHeZ<}xvYf=zh9U?})kbM}99^Kb3JE8q=s z!ubGC@xw!FO01_3w> z|3i4lrJ08W{QRX5`~)cv8wZ393{eMh@^f+Wb8xV5fZ)Bxnj~BCsBKqb87c&UnV^b4; zGdo8cBly@hvbTpv9UD2r84ZMwNd_SSc%?JU*%~TzJ@-Vdoqr^(VTifJZ*632F38}{ zW(qYkafPf+JC7Sbkelc)x zFu=j!^YH%#;^%B&{7>_R>31-@yCc*L9;gWhVImf+A0Ge@H#a9Yzzp!S48#k8$4DYR z0NbBsAYML11o7X>IN;Hh@W}3elyUR^tBivK@h*UW!g2o#4#dX|-z@w)9GI8;pSbXK zmlM9H`wuwIf0yxq{zIQ3eDEmgzvFUp^10iu-Er}BEpCOh+SM_>58Wz|o0`Tan7pS%;u~@7Q?~flkAP@iIN>;UF~kS!Thb!7DA!Q$!mA>7U#Nhmql9> zAGpN+2M`gw&r)XaLRrF3qUi32Dp8h~JnAvGl?E8Qg0CC<)iyU8^0g&1TilFve%;#= z9HPxaP52N!55Mgh8{9P$xZohhQsS0K{SBuhi)y;)%GVS=2DuM9QOZBp1+*;u+`!5^7hzGgW~ez%Gs5<`Odcb+*=Xderjs636jTa81Jgm z&8l7#J$JVDRda5x%@TyE!AE1GzT`*M7qu}NPj$cV(~M)Kj45~Ya8PfjePKlCk-t3-9;r56!n17R>CEps znYK{$NYd21EitxMFA^I9(*+?98#B@fN)9z>l?vdSm10sR+XW(1{P0}KBURS?*b+_j zSV5@Oc~)cjAVZ$%!0OSP+qRjHkMM-(4kM*-94RDeM=ENb%k(gPTpfya9LVr^)uH^E z%>}#qbK^s7qm)jb@kq}D!4=J~RorS*I?XMSz2#xL(?$)k!%a=@`IXuAodFdA@aw!y zRh$|;crM(NG^Oe@?~A9#?z9smmI2WNaUS2$>k&74i)+H7SnnFjg;zywXcnk)JXX}d zN7b5qXpA{i=}l<=Ua7oWy1ekpwV;EgrO_2gL<+;T+M}y9G@dG(^@6vp2)zhnnx8mv zj6OLz$AcKI1(Mufe2FENuU77d2^{Wql{?evQ_?BxsY%R!Ro-+rd(_7_+l&gJ4g-UW z&B`Bu)Js$z8mtb`jWpgkpHQ%UcR;LOOvX?vmN!07JvrO< z5RZPuk>D|m?l3O&QD9wvj6mMgBN(+#)zH})g!CxPnyqF`$WDw*{^rN5>%lOP+T+E{ zo7?uIK49ff6%OZL?Lhfwo*$OK*LK4VDc77D2MM`e$joG@o6CmZ30e8PYlmhTn%hnz z$C6qhz1KUp_i{$s8U{>04K}f7i_~{k*&Kjm5xeo?9LY$&#mJ3X3Jb1S3MY-j3bs_d z%Quk}KEuBM;w!o2cZ^BU;a!-U-OquHOrZupYRIFWP(di(&n$sI?Sh`a2MnlX?EnL+ z!|dSJGVXo=QxLLP5Gn|O2=JNX0d?HHkX8Z!LP8;6Ze9R>lnFs*!#v%+5we^8*0t!Th|Cc=CQ;in^DmU{rfZ6a{xAIv8b?bnuY&1}KYsN7m>G_#^8l zeW)gW*ezsjNCE+u6nX-Hs&G3`fGOUO`pf~y8oW_eqH6nz3jPE2C#I~mm$i$#!>=lS zQm+p4vbIB(0QgXyy(H&n1;T%=;LmR00X4PM0bmJ(v_=2~1c7SSKht0^1ZW7i^K$ew1@QBukU)4S zTK@>5v<8Zi2fxAjx)6ck25UEYx}!h9(4qwc6nNC>4+$af^Ke(?kZfFgN#2_X!@ z69S{iM!g9N3SGjZ(m&e$Gj-X*C4YZVg^~ga{+BdR>0k2r@kHhPk_ZawQYxrk{mB3S zAQhCf|1K0Q4IN{3t)D{Cad)+L`@2+7dhmY{iZK5#rT#-GKbU~Jqr~x3)d4?5_Cq8n zX8fn?&yqjuK`H1jrlOuG=A#($Bk!`6OT|UyLy##{KJvO0JxY`)SX9~1{GVd_v;H3p zzZ4FVvfrP-6beNxN~O{X-`|! zjEF2jPG;5~N-(&CT3~_w+=Xw@agp z(oZ~~(a%Z*1dwhx4)r$fZ1t9{|2w*Z+@v(K1)|SnHXY z(LH?;H<$oFh%~mDuQ*N+e09?E@f*Z{NHKR6iX*S1OF|)^SDnPk+WO7+;6}vOyM@kv zJt39PN(B~nXm@MRAM|2gCrEq{a4~$UHhDr<>5t72Ol6(Fb|>Imy5Zj2H;?WIbX9M> z$u!*GJNgz$@$4v|AV2q{=>~*l8ad=lx+H@x7H$KsmgqQpV@Ka)lz#I7PcBN2NwClQ5rsALOj1&!-iw59_YCrB zIafIO;^p(yOiF5t~+3q1B0g#W+X9BtLnqwHzBz z1nA2e&AyhNmNxR$VtL`tpqpmH`$aC${s3IK67)2iuwLHg_)VP-1%`5u!3nXlrY5!$JO`oRaezI33X*uX_ylYo94|b3g zZVUUJNv_eIN{Ey@2D*#;@_Dbbc<5!_(&tff2TFCM+sI!*ufKsn1FzuXX?OLtvb-(&pHR*TtAWXtAZ*XB_ zhXCUy15L(5P{jKH!7{g3@;9_IjMaqfSo2?f=BzPlQLq@fCJw8;An?{@^TXGMjB_+Yd0q=*V4IaT+66`|B2}=Df!})Py%P$ z$1rlm%o~hD221=6Oq^QQ-gu|D1vW?5_~15Jq$TqNMJZO%VD%MGoB-_Gj01PBxF&`a zXj0_+Vqn>;ZZ@K!wSsFW*74QVLpr*?Q}P)y;knt84_-?N7#$tmsEdDiDogc*eDd}# z56#T;UR+PJSl45<4h$=toX(NY9?8{3pYP`=2Xa^9Q@B$+KcIIpwbg>z1b2>te{l0I1T6tn{T8~ZT!5(U~@a)Rd zK9VwbKEb}!W;rhS+|1pYrRGDLLzcLZ#-ZCjQMa;S^cq?B0ZLi)Rz!*&p`Ek`IWNWA zEjoI?Q_l}00ui{+H&aAUbNlBos@<5Mw)AP(@|^onX^$6RDpXoeQg?{ZFPJQ4m0=pf z-t|*D5Hh}07&edE>=l5}N`wpM6?stQE{&QP%(SVM+SWvqZfKE=D;i(Rn^t4|{P~cr zXO+;-4$x=Gw6OgKwf6d}$8otZ`Q4(U7P9|ldH;Q7_J`dS5(GezbqPU){$hBA{xrN0 zWcoM5i(C}}|1`Wpg8#wtf`yQ1|AXnhH0QreuQX5=COc*kCQu8g1JniT z0ri2#Kx-g!aScPjJ)MEJKs%(Jc0lf-ATxlDNK@?sbb)z#A}zL?x2p{d;R$y@8E+4i z8|4DC_xh1Spymvq2eJ-#yGz6F>0xaP19}0yf!=O*NGw}-1nh6t{_noVZ$8Wa-P-dD zf_}I5-Uj%3x)YfaV3t(?v8hp+6}(%&{!stWq^h)uG9m^TbdBSUs1zm{K^G7~zt7nX@84dP0fe!Xn#&sIwZ=eo& z=O-6CUpv09YPpSZ5Ji5dQB2}Y16lz4m3+j9Y!_CaUKyJtZoZ21UBtmgoY)`n;PH${ zCqXrFcE~k82dPO>iu4}bQ!d-En-u`Xq|7whlaYDz2m9A}%?>2pLpr>s*zZJReW%7H zpzLQY8}0P}$Yz<%)c=M;)svYeBietj)4X;76K)lL6XM~#D0Hiq1-Sp6NQ*)cD905$ zPePN%JWMz|laiNM&jXct7OXhU`+8eEkbgYnXyh9fV=vZFLFv>xA19oKOuWKRI{T$_ z?--nbf_Z02CQ|Y`n`K%Xwp?*0GQrY3#cA4Er7Q33H^`l^8j_|Jf~BH4e4RvAqzCiI zwdvm6Kl7M=XUTP#NZtwd2+3&-ofh22neCa~ne%BSY&nm(_A2m2Uhk8l=Z?6+Ii%nK z`)>2kAr1l42hzln2_6Y7#P@rfS4DF}zwGUi1)LAz-x&$Kfo06}5%Lv>+hLi%4Zr}; z>aL-kqt?F=^HfvFlH}N#{5Rv zO-1>D)c6NI<^ei{k(j`OkL+gM`}RNp_vShKkS__^jx1XG=LUS8ig$zen6OFC1va`j zK7W}K)d?s5a%47LR>cEm0r`cGv!|rJaDI)T5zVpJY09@HsDIn1r)z2H;M^qK$ZVf4 z==|hr`r9*#!ve2~Aso1Sqt5&O>a~>v8Im9ZX){obGWxgeZh#m*PWu@N=Hk~4hZD5$ z*w9z)H)Kl|5i=Ig(1CgipQpYw+kFfvPITgXW9P^p zL!B6}JY2C;m`5GeafDrxN5iRfomAu{Jr1@EwJ3$%KK__W3}q>1nVP?M+h;K0SCTO1 zFJjNodY6qJhB?TJHP4CQz0=fP!=6kh8tUjll-?U|ZaiKTVbodj4bL}<>bbIbpYleK z#SkOVom*hbfsIlirr%&|gg+nVjxRDzb8kCWbpZm{igB91ZBUSqnpe_GKiL6v$G2I2 zr_TPGN>vN^b-L>cQM7e$c*3In%2Ic^lD&?~<_&#$YgkMoItt&``Zhv7o#) z@O+wT9*4UgZBhwKx}I5z6cM(%oZJS@@b_SX>l#w|3d1xe+y z@2?;Fvq5dr+~?b!_C2-|a0_Qfx9L*4SR6jRaGed^^KS>?KiT>?(Udjl-52NNU6^S!*_(CSgn;&eGPjBIh0zl>Dfe*L9K?(CBNnV?uqUU>MW&Fcr%u0t8FN`zCnMkw!l>;^FA3T!? zjlpmWx4EzS%A{>Ec3M{btd4-Ym~ho4jh5|Id|v;07Ug(%IR|#HHQ|d9{ng5}tm+5s zh_e7_!Ody;jEf2xZ$HlH0di4#1J9?*q49Ub-Y$xnTnkpB|CDs(NmhqnPCH_dC+bcf zT(Se0;lH6&sv}%LihU7Za@fpg z$#vQb2~d+Eb5gegMU$Nw@+3M za+*BMBI6CpWz4+|kP{%f>^Mf*I;i}5)j=0QfU&KP~h#}6{UJ*Kjk+}vM}fG*?l6**Jxqds~uo49ruO}|IZ-YSZn8GUfGd-P0& zpO1gstzWxfr=mY+YDS*caVwXqNNq5BSdUH$ci?EGnKoUa%HcalWrCYwuC&Ix89vCs z$wi#6C7B(JLr^X#P1OnS8NM6&3ePJMj%dnq>8oCVlIjMJ88!6ux0K%9N*EpR^_=~ za+^BOc&emh_~{pc{MS2vEOAl6FSBkw_HKJGPirO?EX-OE8*MPYa|3tH?Bqppp?0IQ z9Emdv7mfX71%x%dU0b`NYI=C_zE`)Sz3NS{h|{18V#}EL+6AJ00dbV#h%Y|<&Nw)A zjm_y<+Nx+wM-Y<~>?Mw%lYFjBa_mE;Q%b*UL9NwhJ_oOLv&_z1MDTFqyuyf0**hh3u1z zVI%ifcCoKeW)k#JR?2X~hgYc1Qw?;1+XFmswWkvhK40D78%9U9iN z<`VpF^&3raKbre%Lb{tTnpVD62^hqIdHCA|sE?V{-tw)MNw~n``aygHSW_jPhAZ)^LVr%;^j~ z;PeL!*0p=zH%a3jDV8=(T^J^4ZEcX^jd3p=U9Daoy2yFQMvTrwH}1h+xOEr(kx;t8 zlH=NO+vxbzC9mEKgqrAD-f*rd{m;QF= zc1EWVRYSh?J#Swo@3e8M?*^G<4aK)u?PLW%ek;3rROG z38mjLSCxdrf)r`<@PWBJo#sun=oH>T-Z84gZ7JIUcI7WstU^86-z1JK&!Hg>E0aQ2 zKCy20Vyd+c1xnv{A2xf7+KLQ6!h`j`iw|qMew}w`X~OIMI}-|3v8cf22F>uW?I-ka>WcU;KJHV;{+B1Br(*#EDg@vd{w}de4A`RG7!+^#L&Xi%V+V_xzFFEGc7FTIQ$uN zXe@jj|4HsacbAyXGP^`AVhBAQKb?IX?*@?_=ZomP3kj+==B=E_=*d{JCb*Af68lpVx&1O+QDEGVu~}K91(Eq>0)_NZ$Qw=daSk;$w~e- z=o2)_=6b*6 z0heewzd+`U6VK;0&{&4;@X%O_Jy-aYjVrvo{@vQ+Cro!ih1DD5`DM*eMMp|n!Fw#O#g;MZ&S}J)bP}XY zD0MjMODW?s4M}LIsh(ilpee7S->T+39_!tRNlhyJ_D07m>OuX=Aze)aBfPSbyAh9) z{f#MCw&42^@rZ_Lp$z7dmQq@=Xr@>}952i5`CR18u?zsD{xXYh#BI2|HEq zwrFO+*}-Cs?&BA|$H^bdUevkWn$!_f^>Egq*GRtpkse-nW4mV{kVLvQl4Xs&@?%rC z+Wcl9_lY9l!7h=tmgIKi&|vUdDllA#32q85zvt&%p0*2$SmKyub`>2>oUzew=#AvZiBLdXqI2;`UF{o7tA1hp^u=Uyl3^$(XD ziTR&gZa(P0x!iwja7thL*a|>Jq?fG%RQu^^|MIg9kbbre(!sWMcXhSCbh9saT7mXJ zd$@kUqCN^6v4!d){zA;4kmn%Mk%Xdf~qA zfAhnEzCb^qKQI7>aR18&?B74-{r1h{|L&3t3V}htZNLT_;p*ucHnoEhJKi!_Mam7h z4f-=Cy-um)BJXM_A4uE7bnLJ4hY#FgNz7JbVG7R=_fPRB%ig$cThTCNRP6Kgv-|gp zhR+)<&w4fkgeRNk12)e$S&faAw>^&LS7#QEKZBl@>4LDs!241;qq^SxM2Z>X54+>hZo*l@v|qx#8NmnW}Z zJ`Wmu{ygXz`Z5_p*S7Xzhm@d4$nC>phpows2JS##jqP6lypO$CZG!QLc0`wHnZFDXWh1`n{m-wCtQc)~Z1Su&pFW=q7{Cc6o{4nr z461<}F$>XWMGU@bwDANJ50Ga?);v9(M31|3>!~5gy|sB#?s8Q|Z|j)? zy`}lNS#6mzVxUqIBgw6Bxv~N^2MoJpeYzo85t&W)^n0m^2X|xGoLtF^P6Lg;h?CQl zI#QWDwTCVj%1iQwF}(e7%9w~VRS_by?>Fi-K3Tl7rXQ}jJr%&xUM-xE9%A5yAEbO? zySCxV8w^ar9;0wg`3g%2v;`fnqieR|7T4sTQMc=}bB|fDFVS@CCe9jHtXW=l5DU{? zB7-=r`nuyNz!;;J#Q}O}`OoCmuP`af8F|}VVcE4A-%1pIpmf`+rCU=zAon(RnSnun z#85%oCBGW`38N;>;l1@`K?!dPf`^66xcspP>%^Pa?zhKJTH~;j1F&+GyT3^qElgF z{lOr{)kzevNvD_;=J^Obdl2Od-!=CT$Y+9Cs2E ziPK3E8d8(?j@Kg~F*F&;CYGDGK5-qiH{70|%-Y4Spl;t_>(!UvAQRNO5@F%?rsm_r z+AA%b0J}h|nWZPpe$21wPZjH=x!Ac_#k~w|j$`SnuU0jF_{3L~JJiSj4*QK@18-?5 z4Q)&gKBEO~i?_&XvpYMn^~4zW%ftK!V-wR5uNqc=^(uV+B#Vt<3kBL2oKNyHK3MN+ zQq@u{62DKoaZW|{T=CJ?@X1wIBkWsiUvx$)@f_3+A`NrY)msySLC@sTi!ZJ5In0TUrDct&8tt_k}_oZb+VuqGz zO$vcI8`YwL+1w2)_Az*#SJ*9P{qExghOnBsip%&z%*AS*)!b_Tfj$%l6Rpd z+$_~;Dcn-j(RP?hhN>)kakF~HG=PLh^~d{*941^$_XH`)%rT?YUX&yk__hXc(bBeH zV7SrZ7JaI(8}li-%OCyn3#SG)i$!zuh8N{_Rl1(zc2WvsL5Bk{)CN%T7JlVR!*t0> zTW@3EM_M+x;_@RQ=yg4|9M0wFFO6i8=vQyc6mb|li+(euny;^~t#hT4&SSuS8y z!Nt}pX#esptq0o%Y*Qb*xF9Noi_j^!M%xyxxYNbgtIL0vx9!xvtmWmROvaSHq5%xOQ1IX#-cBx<7vVnt(ryvZa~&K#Wf5C4xgOf2=?8(Ce$-o;c&{(&9A}a|J}_p~KxM^7JL43f zDYzHb+>U9|qG?1ypPmI&Mt|)kdrF{SetoM#A~0eTPAo*i>gZFKOWBC)B^t29CSW+sy{3w z`QzLo3;CE9!DvR86K(YJBSTPKdtd%%mNEgE&|bGtN3V$36We!`G`{QA3dTypDzJi5 zqY5tVy?KSfsN2QmG0S+@3ge*z7y+$fHDrYaC#ADD!Xcxz{rp}g$%UMid<;={IC>2q zat*y9S8`b%9YCA2a=P#W6# zh^ps(WmFFC)Ro(2EBjZ;I`TRW^&guvSia&OY}ie}bw+z!&{}@fJ+wr)RB(!0^XzHq z!Q3JSS&f3B404b1&A5h}t*gFnKkMkZr2V-%eVp{hBtF~ch;WW>uK54&fMRao`!HjigUvz38A& zRIDDdrkE#ar5qdLN*Y^Vn=*hm%z`ymLsH6L5_Zfa#Ahl`CuNi$~^z$a$>67HMisTWE{*U%i{7a$n?sf%I^-)w!eUz>hLs+{C zLG7Y@JfC6Ri#MkE6fU|$0~X1KS7Qlt`qyu0(xb~_<#4Wcn;N1CV4NuXu0&GUl8Gl+@t5MbMYma z$8I5pnqVfKmE084Aj4c3tENMBIF->ag;b85Iz+V=epL*v)ryMCdJH zHN)0|y;P-+Pol&O9@m|HKgFWrx<@KSIOh2iBh!A*UXNVS2($ODdURjzO|+rW=QrB# zIi(~-dDV9p5ST4hgpLfA4I%-WduqFi@M(Cag_dBUHFV$#>SHBadE&9A$q^ zLagT5&R!2|7Z{Z%GDy^S9S>3NzPg++={X+)p886BYe`=$4I4_5%uDel)#%lgV4`<1ps}{btsW10ktAB(+Dz{p5^0n+zxV>V5n3Q^6ic)jJ zlfv}ik(Yj7&{g33;_a0&ln#Bs4^2fzMsM!r91_*aDq<7@@b7yiBae+!_e9|b7)4b#cO9O{VIHQux2rqoZebqb?%uN@!(q*4yG`67RUD+iO_Ihd_*;3bv^82nr4kLIs1SmqNML2fTGkfv?xUtmtx_df!ScYE2Squ;IU>tVvU#r$LLaJqSEQDsw<#kG zf!@;TK+haf6N#KJ;Ks-{sYslknZlgZNn#x~dYqYx&Nx^OKDI=YnYFcR)pW_bvPY#qG+(z9W3bI!l`X>zRA4_vQD$F9qwT{43-)a{ed8Hhr3|tUl)YE>>32 zkI8nzO4=F$@!{X0eRRYK(gvg3l3JpBhwg86nXmY8e~^P;Ck@nXx=Rmu#%tT0uReuU z{a}}+b583crG3NCgsboUtE%64$jeNM`qz+`$fM`2QFqD($ zLtS>UNbU`RF^!2(mtE1yuJPVnAx#VYNBI2*#LHA>YEA^`4*)N2XetY@GH|g9+|hY`NBIGDXwPfNX$r39=y?l|7!UWw+j#HjezZ*Nx6i7ZI?P9} zjU)yN6+cTl?`k+0iffw^{&?K^WRdvmhgTKqhNdF!32$!%U@?48k$&IvxDwYG#M<+{ zohQ!k&6a|wv9D&sJ72=!Q}x~sv~29fXD4|J!K8tFb!?B+*=!{D;A$?@CQZGKlsBPX(R}M%N!zPwb|wAwShVSDneul5~Zk4^#^iYn8*5~rc|9xgbCl4q{R(4m0~PcXlCLgdua?B3jxBf{~K&w0&o z#i6rvWGMc@{#+ua2NkZZLC?fnbT?%-=PgWE|79(+l!>!L?a*#!&^l)JUW)M4lMkM2 z-7F(mc@m65qPv4qj$^qjWqHvz#HZ_~?{7;g=1k%BIaNR+6u)?s}|=QLSS2{>WT+eP-hZP@b%@nDIg9* z^OndVlk1^|*zC94pKQ4(V~kWezH`vcJ>2!3!Jiqy3159eyodwzs9zPq=e$)KK5YK| zLbD@9;Csm?qXM9U`>Ns!KP0aJ2@3P#Xya(ef6+uK^ zJPkpq{8$D1>K8Vr4U(dBMaOTs%2;vkFebAl;0XtXb=Elv(OYgS^ABwp)^pmcwNFOb z+=s?O-_~(Be`OZn;j+BG+T$GFzaC8)=1ikR5gTB%kUbs$sgP4K$hV#LfZWXc)#yjB z-EwZzD*9@BLA7eg_WZ|NOBX|Jpz~Oa<7<8rw=pQX&Q`|aLp+j$YCnwXyzmPh-q0*R z39VcX2#KVo-9Krw@ZVfwi0a88miT^u^At@?jYgp^_W_ps)9vtgthc51lKc8J8^hzp z&MRAYklQO|IF${|xU!4rP(Kny>!d<%6+8op zvs)yg_3@A%FUG~DrdQDVDdrqD+DnCa+K5lT@J!d!>Vko4(RXq$>=d4lIPy`OCuH!q zscRICxbV^R+Yfa={f=(9*Oc?mz5L6ll;2O#{fbxl^XRUTy4oM-cKHQ_{@6Aalk`I# zAajO!0c>Cna5r)Gowg2k0NhTT-B3^+r0yXLbA&4eAYi%y8hW+?&bClHc1a05F-dD= zun>&L&)S2>{xUky6M#IyEPg{)M@``d3cydq&(*^f88!p(b9Hg^6!8;hzeEv1rcv2I zcEBZwm$Nv#k-8SZ%iZ0@8SVw(L>${2|=k4S;Ic+Q!}6OPt-?8*V2eWD5pE!5~2% z8f+CyFaf99C0D@vtNa3XTxHI_tNtlb>M+5LFzV91rVix<0uzS||V-4AKF zz$JbpF7beW*7Yy4y39h3ZKT+Me^?F)JiveH_us4NPjiVp#w^b6i!z4)IMDoCT;8v7 z&GB!;niKhH6g5ha3`dO<4mlCjAOk`9pkRIh{>$;j4g#?w!I0zde}VWp8aV!Kym0;z zgy@HW*&_pW_`rB5gZ1MF5E2yR7X;V?e&&JsAjl4&egLsnSAmeM@ks++e7$_Y8P}$Ai9e~m{WVEcZ9Kcje00iNeQIJ;< zPyh)FfdwGavLIv>r!>E?AOx(y2jQ3a-yzIV(XpOh)(EdlWdS287sg{{mDg0j`+opB C3sSxS diff --git a/buildconf b/buildconf index a779d86..4e4c17e 100755 --- a/buildconf +++ b/buildconf @@ -1,297 +1,4 @@ #!/bin/sh -#-------------------------------------------------------------------------- -# die prints argument string to stdout and exits this shell script. -# -die(){ - echo "buildconf: $@" - exit 1 -} - -#-------------------------------------------------------------------------- -# findtool works as 'which' but we use a different name to make it more -# obvious we aren't using 'which'! ;-) -# -findtool(){ - file="$1" - - if { echo "$file" | grep "/" >/dev/null 2>&1; } then - # when file is given with a path check it first - if test -f "$file"; then - echo "$file" - return - fi - fi - - old_IFS=$IFS; IFS=':' - for path in $PATH - do - IFS=$old_IFS - # echo "checks for $file in $path" >&2 - if test -f "$path/$file"; then - echo "$path/$file" - return - fi - done - IFS=$old_IFS -} - -#-------------------------------------------------------------------------- -# removethis() removes all files and subdirectories with the given name, -# inside and below the current subdirectory at invocation time. -# -removethis(){ - if test "$#" = "1"; then - find . -depth -name $1 -print > buildconf.tmp.$$ - while read fdname - do - if test -f "$fdname"; then - rm -f "$fdname" - elif test -d "$fdname"; then - rm -f -r "$fdname" - fi - done < buildconf.tmp.$$ - rm -f buildconf.tmp.$$ - fi -} - -#-------------------------------------------------------------------------- -# Ensure that buildconf runs from the subdirectory where configure.ac lives -# -if test ! -f configure.ac || - test ! -f ares_init.c || - test ! -f m4/cares-functions.m4; then - echo "Can not run buildconf from outside of c-ares source subdirectory!" - echo "Change to the subdirectory where buildconf is found, and try again." - exit 1 -fi - -#-------------------------------------------------------------------------- -# GNU libtool preliminary check -# -want_lt_major=1 -want_lt_minor=4 -want_lt_patch=2 -want_lt_version=1.4.2 - -# This approach that tries 'glibtoolize first is intended for systems that -# have GNU libtool named as 'glibtoolize' and libtoolize not being GNU's. - -libtoolize=`findtool glibtoolize 2>/dev/null` -if test ! -x "$libtoolize"; then - libtoolize=`findtool ${LIBTOOLIZE:-libtoolize}` -fi -if test -z "$libtoolize"; then - echo "buildconf: libtoolize not found." - echo " You need GNU libtoolize $want_lt_version or newer installed." - exit 1 -fi - -lt_pver=`$libtoolize --version 2>/dev/null|head -n 1` -lt_qver=`echo $lt_pver|sed -e "s/([^)]*)//g" -e "s/^[^0-9]*//g"` -lt_version=`echo $lt_qver|sed -e "s/[- ].*//" -e "s/\([a-z]*\)$//"` -if test -z "$lt_version"; then - echo "buildconf: libtoolize not found." - echo " You need GNU libtoolize $want_lt_version or newer installed." - exit 1 -fi -old_IFS=$IFS; IFS='.'; set $lt_version; IFS=$old_IFS -lt_major=$1 -lt_minor=$2 -lt_patch=$3 - -if test -z "$lt_major"; then - lt_status="bad" -elif test "$lt_major" -gt "$want_lt_major"; then - lt_status="good" -elif test "$lt_major" -lt "$want_lt_major"; then - lt_status="bad" -elif test -z "$lt_minor"; then - lt_status="bad" -elif test "$lt_minor" -gt "$want_lt_minor"; then - lt_status="good" -elif test "$lt_minor" -lt "$want_lt_minor"; then - lt_status="bad" -elif test -z "$lt_patch"; then - lt_status="bad" -elif test "$lt_patch" -gt "$want_lt_patch"; then - lt_status="good" -elif test "$lt_patch" -lt "$want_lt_patch"; then - lt_status="bad" -else - lt_status="good" -fi -if test "$lt_status" != "good"; then - echo "buildconf: libtoolize version $lt_version found." - echo " You need GNU libtoolize $want_lt_version or newer installed." - exit 1 -fi - -#-------------------------------------------------------------------------- -# perl check -# -PERL=`findtool ${PERL:-perl}` -if test -z "$PERL"; then - echo "buildconf: perl not found" - exit 1 -fi - -#-------------------------------------------------------------------------- -# Remove files generated on previous buildconf/configure run. -# -for fname in .deps \ - .libs \ - *.la \ - *.lo \ - *.a \ - *.o \ - Makefile \ - Makefile.in \ - aclocal.m4 \ - aclocal.m4.bak \ - ares_build.h \ - ares_config.h \ - ares_config.h.in \ - autom4te.cache \ - compile \ - config.guess \ - config.log \ - config.lt \ - config.status \ - config.sub \ - configure \ - depcomp \ - libcares.pc \ - libtool \ - libtool.m4 \ - libtool.m4.tmp \ - ltmain.sh \ - ltoptions.m4 \ - ltsugar.m4 \ - ltversion.m4 \ - lt~obsolete.m4 \ - missing \ - stamp-h1 \ - stamp-h2 ; do - removethis "$fname" -done - -#-------------------------------------------------------------------------- -# run the correct scripts now -# - -echo "buildconf: running libtoolize" -${libtoolize} --copy --automake --force || die "libtoolize command failed" - -# When using libtool 1.5.X (X < 26) we copy libtool.m4 to our local m4 -# subdirectory and this local copy is patched to fix some warnings that -# are triggered when running aclocal and using autoconf 2.62 or later. - -if test "$lt_major" = "1" && test "$lt_minor" = "5"; then - if test -z "$lt_patch" || test "$lt_patch" -lt "26"; then - echo "buildconf: copying libtool.m4 to local m4 subdir" - ac_dir=`${ACLOCAL:-aclocal} --print-ac-dir` - if test -f $ac_dir/libtool.m4; then - cp -f $ac_dir/libtool.m4 m4/libtool.m4 - else - echo "buildconf: $ac_dir/libtool.m4 not found" - fi - if test -f m4/libtool.m4; then - echo "buildconf: renaming some variables in local m4/libtool.m4" - $PERL -i.tmp -pe \ - 's/lt_prog_compiler_pic_works/lt_cv_prog_compiler_pic_works/g; \ - s/lt_prog_compiler_static_works/lt_cv_prog_compiler_static_works/g;' \ - m4/libtool.m4 - rm -f m4/libtool.m4.tmp - fi - fi -fi - -if test -f m4/libtool.m4; then - echo "buildconf: converting all mv to mv -f in local m4/libtool.m4" - $PERL -i.tmp -pe 's/\bmv +([^-\s])/mv -f $1/g' m4/libtool.m4 - rm -f m4/libtool.m4.tmp -fi - -echo "buildconf: running aclocal" -${ACLOCAL:-aclocal} -I m4 $ACLOCAL_FLAGS || die "aclocal command failed" - -echo "buildconf: converting all mv to mv -f in local aclocal.m4" -$PERL -i.bak -pe 's/\bmv +([^-\s])/mv -f $1/g' aclocal.m4 - -echo "buildconf: running autoheader" -${AUTOHEADER:-autoheader} || die "autoheader command failed" - -echo "buildconf: running autoconf" -${AUTOCONF:-autoconf} || die "autoconf command failed" - -echo "buildconf: running automake" -${AUTOMAKE:-automake} --add-missing --copy || die "automake command failed" - -#-------------------------------------------------------------------------- -# GNU libtool complementary check -# -# Depending on the libtool and automake versions being used, config.guess -# might not be installed in the subdirectory until automake has finished. -# So we can not attempt to use it until this very last buildconf stage. -# -if test ! -f ./config.guess; then - echo "buildconf: config.guess not found" -else - buildhost=`./config.guess 2>/dev/null|head -n 1` - case $buildhost in - *-*-darwin*) - need_lt_major=1 - need_lt_minor=5 - need_lt_patch=26 - need_lt_check="yes" - ;; - *-*-hpux*) - need_lt_major=1 - need_lt_minor=5 - need_lt_patch=24 - need_lt_check="yes" - ;; - esac - if test ! -z "$need_lt_check"; then - if test -z "$lt_major"; then - lt_status="bad" - elif test "$lt_major" -gt "$need_lt_major"; then - lt_status="good" - elif test "$lt_major" -lt "$need_lt_major"; then - lt_status="bad" - elif test -z "$lt_minor"; then - lt_status="bad" - elif test "$lt_minor" -gt "$need_lt_minor"; then - lt_status="good" - elif test "$lt_minor" -lt "$need_lt_minor"; then - lt_status="bad" - elif test -z "$lt_patch"; then - lt_status="bad" - elif test "$lt_patch" -gt "$need_lt_patch"; then - lt_status="good" - elif test "$lt_patch" -lt "$need_lt_patch"; then - lt_status="bad" - else - lt_status="good" - fi - if test "$lt_status" != "good"; then - need_lt_version="$need_lt_major.$need_lt_minor.$need_lt_patch" - echo "buildconf: libtool version $lt_version found." - echo " $buildhost requires GNU libtool $need_lt_version or newer installed." - rm -f configure - exit 1 - fi - fi -fi - -#-------------------------------------------------------------------------- -# Finished successfully. -# -echo "buildconf: OK" - -if test -f "test/buildconf"; then - cd test && ./buildconf -fi - -exit 0 +echo "*** Do not use buildconf. Instead, just use: autoreconf -fi" >&2 +exec ${AUTORECONF:-autoreconf} -fi "${@}" diff --git a/buildconf.bat b/buildconf.bat new file mode 100644 index 0000000..dcee452 --- /dev/null +++ b/buildconf.bat @@ -0,0 +1,20 @@ +@echo off +REM +REM +REM This batch file must be used to set up a git tree to build on +REM systems where there is no autotools support (i.e. Microsoft). +REM +REM This file is not included nor needed for c-ares' release +REM archives, neither for c-ares' daily snapshot archives. + +if exist GIT-INFO goto start_doing +ECHO ERROR: This file shall only be used with a c-ares git checkout. +goto end_all +:start_doing + +if not exist include\ares_build.h.dist goto end_ares_build_h +copy /Y include\ares_build.h.dist include\ares_build.h +:end_ares_build_h + +:end_all + diff --git a/c-ares-config.cmake.in b/c-ares-config.cmake.in new file mode 100644 index 0000000..464837b --- /dev/null +++ b/c-ares-config.cmake.in @@ -0,0 +1,21 @@ +@PACKAGE_INIT@ + +set_and_check(c-ares_INCLUDE_DIR "@PACKAGE_CMAKE_INSTALL_INCLUDEDIR@") + +include("${CMAKE_CURRENT_LIST_DIR}/c-ares-config-version.cmake") +include("${CMAKE_CURRENT_LIST_DIR}/c-ares-targets.cmake") + +set(c-ares_LIBRARY c-ares::cares) + +if(@CARES_SHARED@) + add_library(c-ares::cares_shared INTERFACE IMPORTED) + set_target_properties(c-ares::cares_shared PROPERTIES INTERFACE_LINK_LIBRARIES "c-ares::cares") + set(c-ares_SHARED_LIBRARY c-ares::cares_shared) +elseif(@CARES_STATIC@) + add_library(c-ares::cares_static INTERFACE IMPORTED) + set_target_properties(c-ares::cares_static PROPERTIES INTERFACE_LINK_LIBRARIES "c-ares::cares") +endif() + +if(@CARES_STATIC@) + set(c-ares_STATIC_LIBRARY c-ares::cares_static) +endif() diff --git a/compile b/compile index a85b723..23fcba0 100755 --- a/compile +++ b/compile @@ -1,9 +1,9 @@ #! /bin/sh # Wrapper for compilers which do not understand '-c -o'. -scriptversion=2012-10-14.11; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # Written by Tom Tromey . # # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2012-10-14.11; # UTC # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -53,7 +53,7 @@ func_file_conv () MINGW*) file_conv=mingw ;; - CYGWIN*) + CYGWIN* | MSYS*) file_conv=cygwin ;; *) @@ -67,7 +67,7 @@ func_file_conv () mingw/*) file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` ;; - cygwin/*) + cygwin/* | msys/*) file=`cygpath -m "$file" || echo "$file"` ;; wine/*) @@ -255,7 +255,8 @@ EOF echo "compile $scriptversion" exit $? ;; - cl | *[/\\]cl | cl.exe | *[/\\]cl.exe ) + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) func_cl_wrapper "$@" # Doesn't return... ;; esac @@ -339,9 +340,9 @@ exit $ret # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/config.guess b/config.guess index 1659250..f50dcdb 100755 --- a/config.guess +++ b/config.guess @@ -1,8 +1,8 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2015-08-20' +timestamp='2018-02-24' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2015-08-20' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -27,7 +27,7 @@ timestamp='2015-08-20' # Originally written by Per Bothner; maintained since 2000 by Ben Elliston. # # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess # # Please send patches to . @@ -39,7 +39,7 @@ Usage: $0 [OPTION] Output the configuration name of the system \`$me' is run on. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -50,7 +50,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -107,9 +107,9 @@ trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; dummy=$tmp/dummy ; tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; + ,,) echo "int x;" > "$dummy.c" ; for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then CC_FOR_BUILD="$c"; break ; fi ; done ; @@ -132,14 +132,14 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown -case "${UNAME_SYSTEM}" in +case "$UNAME_SYSTEM" in Linux|GNU|GNU/*) # If the system lacks a compiler, then just pick glibc. # We could probably try harder. LIBC=gnu - eval $set_cc_for_build - cat <<-EOF > $dummy.c + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" #include #if defined(__UCLIBC__) LIBC=uclibc @@ -149,13 +149,20 @@ Linux|GNU|GNU/*) LIBC=gnu #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'` + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi ;; esac # Note: order is significant - the case branches are not exclusive. -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in *:NetBSD:*:*) # NetBSD (nbsd) targets should (where applicable) match one or # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, @@ -169,27 +176,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # portion of the name. We always set it to "unknown". sysctl="sysctl -n hw.machine_arch" UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ - /sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ echo unknown)` - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in armeb) machine=armeb-unknown ;; arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; sh5el) machine=sh5le-unknown ;; earmv*) - arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'` - endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'` - machine=${arch}${endian}-unknown + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; esac # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ELF__ then @@ -205,10 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Determine ABI tags. - case "${UNAME_MACHINE_ARCH}" in + case "$UNAME_MACHINE_ARCH" in earm*) expr='s/^earmv[0-9]/-eabi/;s/eb$//' - abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"` + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` ;; esac # The OS release @@ -216,42 +226,55 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # thus, need a distinct triplet. However, they do not need # kernel version information, so it can be replaced with a # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in + case "$UNAME_VERSION" in Debian*) release='-gnu' ;; *) - release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2` + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` ;; esac # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: # contains redundant information, the shorter form: # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}${abi}" + echo "$machine-${os}${release}${abi}" exit ;; *:Bitrig:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" exit ;; *:OpenBSD:*:*) UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" exit ;; *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" exit ;; *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" exit ;; macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" exit ;; *:Sortix:*:*) - echo ${UNAME_MACHINE}-unknown-sortix + echo "$UNAME_MACHINE"-unknown-sortix exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; alpha:OSF1:*:*) case $UNAME_RELEASE in *4.0) @@ -268,63 +291,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` case "$ALPHA_CPU_TYPE" in "EV4 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; + UNAME_MACHINE=alpha ;; "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; + UNAME_MACHINE=alphaev5 ;; "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; + UNAME_MACHINE=alphaev56 ;; "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; + UNAME_MACHINE=alphapca56 ;; "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; + UNAME_MACHINE=alphapca57 ;; "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; + UNAME_MACHINE=alphaev6 ;; "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; + UNAME_MACHINE=alphaev67 ;; "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; + UNAME_MACHINE=alphaev68 ;; "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; + UNAME_MACHINE=alphaev69 ;; "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; + UNAME_MACHINE=alphaev7 ;; "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; + UNAME_MACHINE=alphaev79 ;; esac # A Pn.n version is a patched version. # A Vn.n version is a released version. # A Tn.n version is a released field test version. # A Xn.n version is an unreleased experimental baselevel. # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" # Reset EXIT trap before exiting to avoid spurious non-zero exit code. exitcode=$? trap '' 0 exit $exitcode ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; Amiga*:UNIX_System_V:4.0:*) echo m68k-unknown-sysv4 exit ;; *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos + echo "$UNAME_MACHINE"-unknown-amigaos exit ;; *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos + echo "$UNAME_MACHINE"-unknown-morphos exit ;; *:OS/390:*:*) echo i370-ibm-openedition @@ -336,7 +350,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in echo powerpc-ibm-os400 exit ;; arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} + echo arm-acorn-riscix"$UNAME_RELEASE" exit ;; arm*:riscos:*:*|arm*:RISCOS:*:*) echo arm-unknown-riscos @@ -363,38 +377,38 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sparc) echo sparc-icl-nx7; exit ;; esac ;; s390x:SunOS:*:*) - echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" exit ;; i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) - echo i386-pc-auroraux${UNAME_RELEASE} + echo i386-pc-auroraux"$UNAME_RELEASE" exit ;; i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) - eval $set_cc_for_build - SUN_ARCH="i386" + eval "$set_cc_for_build" + SUN_ARCH=i386 # If there is a compiler, see if it is configured for 64-bit objects. # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. # This test works for both compilers. - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ grep IS_64BIT_ARCH >/dev/null then - SUN_ARCH="x86_64" + SUN_ARCH=x86_64 fi fi - echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:6*:*) # According to config.sub, this is the proper way to canonicalize # SunOS6. Hard to guess exactly what SunOS6 will be like, but # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; sun4*:SunOS:*:*) case "`/usr/bin/arch -k`" in @@ -403,25 +417,25 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in ;; esac # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" exit ;; sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" exit ;; sun*:*:4.2BSD:*) UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 case "`/bin/arch`" in sun3) - echo m68k-sun-sunos${UNAME_RELEASE} + echo m68k-sun-sunos"$UNAME_RELEASE" ;; sun4) - echo sparc-sun-sunos${UNAME_RELEASE} + echo sparc-sun-sunos"$UNAME_RELEASE" ;; esac exit ;; aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} + echo sparc-auspex-sunos"$UNAME_RELEASE" exit ;; # The situation for MiNT is a little confusing. The machine name # can be virtually everything (everything which is not @@ -432,44 +446,44 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # MiNT. But MiNT is downward compatible to TOS, so this should # be no problem. atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} + echo m68k-atari-mint"$UNAME_RELEASE" exit ;; milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} + echo m68k-milan-mint"$UNAME_RELEASE" exit ;; hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} + echo m68k-hades-mint"$UNAME_RELEASE" exit ;; *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} + echo m68k-unknown-mint"$UNAME_RELEASE" exit ;; m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} + echo m68k-apple-machten"$UNAME_RELEASE" exit ;; powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} + echo powerpc-apple-machten"$UNAME_RELEASE" exit ;; RISC*:Mach:*:*) echo mips-dec-mach_bsd4.3 exit ;; RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} + echo mips-dec-ultrix"$UNAME_RELEASE" exit ;; VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} + echo vax-dec-ultrix"$UNAME_RELEASE" exit ;; 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} + echo clipper-intergraph-clix"$UNAME_RELEASE" exit ;; mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #ifdef __cplusplus #include /* for printf() prototype */ int main (int argc, char *argv[]) { @@ -478,23 +492,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in #endif #if defined (host_mips) && defined (MIPSEB) #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); #endif #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); #endif #endif exit (-1); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} + echo mips-mips-riscos"$UNAME_RELEASE" exit ;; Motorola:PowerMAX_OS:*:*) echo powerpc-motorola-powermax @@ -520,17 +534,17 @@ EOF AViiON:dgux:*:*) # DG/UX returns AViiON for all architectures UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] then - echo m88k-dg-dgux${UNAME_RELEASE} + echo m88k-dg-dgux"$UNAME_RELEASE" else - echo m88k-dg-dguxbcs${UNAME_RELEASE} + echo m88k-dg-dguxbcs"$UNAME_RELEASE" fi else - echo i586-dg-dgux${UNAME_RELEASE} + echo i586-dg-dgux"$UNAME_RELEASE" fi exit ;; M88*:DolphinOS:*:*) # DolphinOS (SVR3) @@ -547,7 +561,7 @@ EOF echo m68k-tektronix-bsd exit ;; *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" exit ;; ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id @@ -559,14 +573,14 @@ EOF if [ -x /usr/bin/oslevel ] ; then IBM_REV=`/usr/bin/oslevel` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" exit ;; *:AIX:2:3) if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include main() @@ -577,7 +591,7 @@ EOF exit(0); } EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` then echo "$SYSTEM_NAME" else @@ -591,7 +605,7 @@ EOF exit ;; *:AIX:*:[4567]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 else IBM_ARCH=powerpc @@ -600,18 +614,18 @@ EOF IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" exit ;; *:AIX:*:*) echo rs6000-ibm-aix exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) echo romp-ibm-bsd4.4 exit ;; ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to exit ;; # report: romp-ibm BSD 4.3 *:BOSX:*:*) echo rs6000-bull-bosx @@ -626,28 +640,28 @@ EOF echo m68k-hp-bsd4.4 exit ;; 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; 9000/[678][0-9][0-9]) if [ -x /usr/bin/getconf ]; then sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 esac ;; esac fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #define _HPUX_SOURCE #include @@ -680,13 +694,13 @@ EOF exit (0); } EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` test -z "$HP_ARCH" && HP_ARCH=hppa fi ;; esac - if [ ${HP_ARCH} = "hppa2.0w" ] + if [ "$HP_ARCH" = hppa2.0w ] then - eval $set_cc_for_build + eval "$set_cc_for_build" # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -697,23 +711,23 @@ EOF # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess # => hppa64-hp-hpux11.23 - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | grep -q __LP64__ then - HP_ARCH="hppa2.0w" + HP_ARCH=hppa2.0w else - HP_ARCH="hppa64" + HP_ARCH=hppa64 fi fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" exit ;; ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" exit ;; 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #include int main () @@ -738,11 +752,11 @@ EOF exit (0); } EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && { echo "$SYSTEM_NAME"; exit; } echo unknown-hitachi-hiuxwe2 exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) echo hppa1.1-hp-bsd exit ;; 9000/8??:4.3bsd:*:*) @@ -751,7 +765,7 @@ EOF *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) echo hppa1.0-hp-mpeix exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) echo hppa1.1-hp-osf exit ;; hp8??:OSF1:*:*) @@ -759,9 +773,9 @@ EOF exit ;; i*86:OSF1:*:*) if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk + echo "$UNAME_MACHINE"-unknown-osf1mk else - echo ${UNAME_MACHINE}-unknown-osf1 + echo "$UNAME_MACHINE"-unknown-osf1 fi exit ;; parisc*:Lites*:*:*) @@ -786,127 +800,109 @@ EOF echo c4-convex-bsd exit ;; CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ -e 's/\.[^.]*$/.X/' exit ;; CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' exit ;; F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" exit ;; i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" exit ;; sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} + echo sparc-unknown-bsdi"$UNAME_RELEASE" exit ;; *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" exit ;; *:FreeBSD:*:*) UNAME_PROCESSOR=`/usr/bin/uname -p` - case ${UNAME_PROCESSOR} in + case "$UNAME_PROCESSOR" in amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin + echo "$UNAME_MACHINE"-pc-cygwin exit ;; *:MINGW64*:*) - echo ${UNAME_MACHINE}-pc-mingw64 + echo "$UNAME_MACHINE"-pc-mingw64 exit ;; *:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 + echo "$UNAME_MACHINE"-pc-mingw32 exit ;; *:MSYS*:*) - echo ${UNAME_MACHINE}-pc-msys - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 + echo "$UNAME_MACHINE"-pc-msys exit ;; i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 + echo "$UNAME_MACHINE"-pc-pw32 exit ;; *:Interix*:*) - case ${UNAME_MACHINE} in + case "$UNAME_MACHINE" in x86) - echo i586-pc-interix${UNAME_RELEASE} + echo i586-pc-interix"$UNAME_RELEASE" exit ;; authenticamd | genuineintel | EM64T) - echo x86_64-unknown-interix${UNAME_RELEASE} + echo x86_64-unknown-interix"$UNAME_RELEASE" exit ;; IA64) - echo ia64-unknown-interix${UNAME_RELEASE} + echo ia64-unknown-interix"$UNAME_RELEASE" exit ;; esac ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - 8664:Windows_NT:*) - echo x86_64-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin + echo "$UNAME_MACHINE"-pc-uwin exit ;; amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" exit ;; *:GNU:*:*) # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" exit ;; *:GNU/*:*:*) # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC} + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" exit ;; i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix + echo "$UNAME_MACHINE"-pc-minix exit ;; aarch64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; aarch64_be:Linux:*:*) UNAME_MACHINE=aarch64_be - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; alpha:Linux:*:*) case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in @@ -919,61 +915,64 @@ EOF EV68*) UNAME_MACHINE=alphaev68 ;; esac objdump --private-headers /bin/sh | grep -q ld.so.1 - if test "$?" = 0 ; then LIBC="gnulibc1" ; fi - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arc:Linux:*:* | arceb:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; arm*:Linux:*:*) - eval $set_cc_for_build + eval "$set_cc_for_build" if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_EABI__ then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" else if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ | grep -q __ARM_PCS_VFP then - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi else - echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf fi fi exit ;; avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; cris:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; crisv32:Linux:*:*) - echo ${UNAME_MACHINE}-axis-linux-${LIBC} + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" exit ;; e2k:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; frv:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; hexagon:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" exit ;; ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; mips:Linux:*:* | mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" #undef CPU #undef ${UNAME_MACHINE} #undef ${UNAME_MACHINE}el @@ -987,64 +986,74 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'` - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; } + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; openrisc*:Linux:*:*) - echo or1k-unknown-linux-${LIBC} + echo or1k-unknown-linux-"$LIBC" exit ;; or32:Linux:*:* | or1k*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; padre:Linux:*:*) - echo sparc-unknown-linux-${LIBC} + echo sparc-unknown-linux-"$LIBC" exit ;; parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-${LIBC} + echo hppa64-unknown-linux-"$LIBC" exit ;; parisc:Linux:*:* | hppa:Linux:*:*) # Look for CPU level case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-${LIBC} ;; - PA8*) echo hppa2.0-unknown-linux-${LIBC} ;; - *) echo hppa-unknown-linux-${LIBC} ;; + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; esac exit ;; ppc64:Linux:*:*) - echo powerpc64-unknown-linux-${LIBC} + echo powerpc64-unknown-linux-"$LIBC" exit ;; ppc:Linux:*:*) - echo powerpc-unknown-linux-${LIBC} + echo powerpc-unknown-linux-"$LIBC" exit ;; ppc64le:Linux:*:*) - echo powerpc64le-unknown-linux-${LIBC} + echo powerpc64le-unknown-linux-"$LIBC" exit ;; ppcle:Linux:*:*) - echo powerpcle-unknown-linux-${LIBC} + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux-${LIBC} + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" exit ;; sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; tile*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-${LIBC} + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" exit ;; x86_64:Linux:*:*) - echo ${UNAME_MACHINE}-pc-linux-${LIBC} + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi exit ;; xtensa*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-${LIBC} + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" exit ;; i*86:DYNIX/ptx:4*:*) # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. @@ -1058,34 +1067,34 @@ EOF # I am not positive that other SVR4 systems won't match this, # I just have to hope. -- rms. # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" exit ;; i*86:OS/2:*:*) # If we were able to find `uname', then EMX Unix compatibility # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx + echo "$UNAME_MACHINE"-pc-os2-emx exit ;; i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop + echo "$UNAME_MACHINE"-unknown-stop exit ;; i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos + echo "$UNAME_MACHINE"-unknown-atheos exit ;; i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable + echo "$UNAME_MACHINE"-pc-syllable exit ;; i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} + echo i386-unknown-lynxos"$UNAME_RELEASE" exit ;; i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp + echo "$UNAME_MACHINE"-pc-msdosdjgpp exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" fi exit ;; i*86:*:5:[678]*) @@ -1095,12 +1104,12 @@ EOF *Pentium) UNAME_MACHINE=i586 ;; *Pent*|*Celeron) UNAME_MACHINE=i686 ;; esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" exit ;; i*86:*:3.2:*) if test -f /usr/options/cb.name; then UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 @@ -1110,9 +1119,9 @@ EOF && UNAME_MACHINE=i686 (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" else - echo ${UNAME_MACHINE}-pc-sysv32 + echo "$UNAME_MACHINE"-pc-sysv32 fi exit ;; pc:*:*:*) @@ -1120,7 +1129,7 @@ EOF # uname -m prints for DJGPP always 'pc', but it prints nothing about # the processor, so we play safe by assuming i586. # Note: whatever this is, it MUST be the same as what config.sub - # prints for the "djgpp" host, or else GDB configury will decide that + # prints for the "djgpp" host, or else GDB configure will decide that # this is a cross-build. echo i586-pc-msdosdjgpp exit ;; @@ -1132,9 +1141,9 @@ EOF exit ;; i860:*:4.*:*) # i860-SVR4 if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 fi exit ;; mini*:CTIX:SYS*5:*) @@ -1154,9 +1163,9 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ && { echo i486-ncr-sysv4; exit; } ;; @@ -1165,28 +1174,28 @@ EOF test -r /etc/.relid \ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} + echo m68k-unknown-lynxos"$UNAME_RELEASE" exit ;; mc68030:UNIX_System_V:4.*:*) echo m68k-atari-sysv4 exit ;; TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} + echo sparc-unknown-lynxos"$UNAME_RELEASE" exit ;; rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} + echo rs6000-unknown-lynxos"$UNAME_RELEASE" exit ;; PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} + echo powerpc-unknown-lynxos"$UNAME_RELEASE" exit ;; SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} + echo mips-dde-sysv"$UNAME_RELEASE" exit ;; RM*:ReliantUNIX-*:*:*) echo mips-sni-sysv4 @@ -1197,7 +1206,7 @@ EOF *:SINIX-*:*:*) if uname -p 2>/dev/null >/dev/null ; then UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 + echo "$UNAME_MACHINE"-sni-sysv4 else echo ns32k-sni-sysv fi @@ -1217,23 +1226,23 @@ EOF exit ;; i*86:VOS:*:*) # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos + echo "$UNAME_MACHINE"-stratus-vos exit ;; *:VOS:*:*) # From Paul.Green@stratus.com. echo hppa1.1-stratus-vos exit ;; mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} + echo m68k-apple-aux"$UNAME_RELEASE" exit ;; news*:NEWS-OS:6*:*) echo mips-sony-newsos6 exit ;; R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} + echo mips-nec-sysv"$UNAME_RELEASE" else - echo mips-unknown-sysv${UNAME_RELEASE} + echo mips-unknown-sysv"$UNAME_RELEASE" fi exit ;; BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. @@ -1252,46 +1261,56 @@ EOF echo x86_64-unknown-haiku exit ;; SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} + echo sx4-nec-superux"$UNAME_RELEASE" exit ;; SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} + echo sx5-nec-superux"$UNAME_RELEASE" exit ;; SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} + echo sx6-nec-superux"$UNAME_RELEASE" exit ;; SX-7:SUPER-UX:*:*) - echo sx7-nec-superux${UNAME_RELEASE} + echo sx7-nec-superux"$UNAME_RELEASE" exit ;; SX-8:SUPER-UX:*:*) - echo sx8-nec-superux${UNAME_RELEASE} + echo sx8-nec-superux"$UNAME_RELEASE" exit ;; SX-8R:SUPER-UX:*:*) - echo sx8r-nec-superux${UNAME_RELEASE} + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" exit ;; Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} + echo powerpc-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" exit ;; *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - eval $set_cc_for_build + eval "$set_cc_for_build" if test "$UNAME_PROCESSOR" = unknown ; then UNAME_PROCESSOR=powerpc fi - if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then - if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ - (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \ - grep IS_64BIT_ARCH >/dev/null + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null then case $UNAME_PROCESSOR in i386) UNAME_PROCESSOR=x86_64 ;; powerpc) UNAME_PROCESSOR=powerpc64 ;; esac fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi fi elif test "$UNAME_PROCESSOR" = i386 ; then # Avoid executing cc on OS X 10.9, as it ships with a stub @@ -1302,27 +1321,33 @@ EOF # that Apple uses in portable devices. UNAME_PROCESSOR=x86_64 fi - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" exit ;; *:procnto*:*:* | *:QNX:[0123456789]*:*) UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then + if test "$UNAME_PROCESSOR" = x86; then UNAME_PROCESSOR=i386 UNAME_MACHINE=pc fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" exit ;; *:QNX:*:4*) echo i386-pc-qnx exit ;; - NEO-?:NONSTOP_KERNEL:*:*) - echo neo-tandem-nsk${UNAME_RELEASE} + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" exit ;; NSE-*:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" exit ;; *:NonStop-UX:*:*) echo mips-compaq-nonstopux @@ -1331,18 +1356,18 @@ EOF echo bs2000-siemens-sysv exit ;; DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" exit ;; *:Plan9:*:*) # "uname -m" is not consistent, so use $cputype instead. 386 # is converted to i386 for consistency with other x86 # operating systems. - if test "$cputype" = "386"; then + if test "$cputype" = 386; then UNAME_MACHINE=i386 else UNAME_MACHINE="$cputype" fi - echo ${UNAME_MACHINE}-unknown-plan9 + echo "$UNAME_MACHINE"-unknown-plan9 exit ;; *:TOPS-10:*:*) echo pdp10-unknown-tops10 @@ -1363,14 +1388,14 @@ EOF echo pdp10-unknown-its exit ;; SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} + echo mips-sei-seiux"$UNAME_RELEASE" exit ;; *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" exit ;; *:*VMS:*:*) UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in + case "$UNAME_MACHINE" in A*) echo alpha-dec-vms ; exit ;; I*) echo ia64-dec-vms ; exit ;; V*) echo vax-dec-vms ; exit ;; @@ -1379,34 +1404,48 @@ EOF echo i386-pc-xenix exit ;; i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" exit ;; i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos + echo "$UNAME_MACHINE"-pc-rdos exit ;; i*86:AROS:*:*) - echo ${UNAME_MACHINE}-pc-aros + echo "$UNAME_MACHINE"-pc-aros exit ;; x86_64:VMkernel:*:*) - echo ${UNAME_MACHINE}-unknown-esx + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs exit ;; esac +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 < in order to provide the needed -information to handle your system. +If $0 has already been updated, send the following data and any +information you think might be pertinent to config-patches@gnu.org to +provide the necessary information to handle your system. config.guess timestamp = $timestamp @@ -1425,16 +1464,16 @@ hostinfo = `(hostinfo) 2>/dev/null` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" EOF exit 1 # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/config.sub b/config.sub index 1acc966..1d8e98b 100755 --- a/config.sub +++ b/config.sub @@ -1,8 +1,8 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2015 Free Software Foundation, Inc. +# Copyright 1992-2018 Free Software Foundation, Inc. -timestamp='2015-08-20' +timestamp='2018-02-22' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -15,7 +15,7 @@ timestamp='2015-08-20' # General Public License for more details. # # You should have received a copy of the GNU General Public License -# along with this program; if not, see . +# along with this program; if not, see . # # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -33,7 +33,7 @@ timestamp='2015-08-20' # Otherwise, we print the canonical config type on stdout and succeed. # You can get the latest version of this script from: -# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub # This file is supposed to be the same for all GNU packages # and recognize all the CPU types, system types and aliases @@ -53,12 +53,11 @@ timestamp='2015-08-20' me=`echo "$0" | sed -e 's,.*/,,'` usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS Canonicalize a configuration name. -Operation modes: +Options: -h, --help print this help, then exit -t, --time-stamp print date of last modification, then exit -v, --version print version number, then exit @@ -68,7 +67,7 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright 1992-2015 Free Software Foundation, Inc. +Copyright 1992-2018 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -95,7 +94,7 @@ while test $# -gt 0 ; do *local*) # First pass through any local machine types. - echo $1 + echo "$1" exit ;; * ) @@ -113,24 +112,24 @@ esac # Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). # Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ - kopensolaris*-gnu* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; android-linux) os=-linux-android - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown ;; *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` else os=; fi ;; esac @@ -179,44 +178,44 @@ case $os in ;; -sco6) os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5) os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco4) os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2.[4-9]*) os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco3.2v[4-9]*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco5v6*) # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -sco*) os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -isc) os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -clix*) basic_machine=clipper-intergraph ;; -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` ;; -lynx*178) os=-lynxos178 @@ -228,10 +227,7 @@ case $os in os=-lynxos ;; -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` ;; -psos*) os=-psos @@ -264,7 +260,7 @@ case $basic_machine in | fido | fr30 | frv | ft32 \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | hexagon \ - | i370 | i860 | i960 | ia64 \ + | i370 | i860 | i960 | ia16 | ia64 \ | ip2k | iq2000 \ | k1om \ | le32 | le64 \ @@ -300,8 +296,9 @@ case $basic_machine in | nios | nios2 | nios2eb | nios2el \ | ns16k | ns32k \ | open8 | or1k | or1knd | or32 \ - | pdp10 | pdp11 | pj | pjl \ + | pdp10 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ | pyramid \ | riscv32 | riscv64 \ | rl78 | rx \ @@ -315,7 +312,7 @@ case $basic_machine in | ubicom32 \ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ | visium \ - | we32k \ + | wasm32 \ | x86 | xc16x | xstormy16 | xtensa \ | z8k | z80) basic_machine=$basic_machine-unknown @@ -336,7 +333,7 @@ case $basic_machine in basic_machine=$basic_machine-unknown os=-none ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) ;; ms1) basic_machine=mt-unknown @@ -365,7 +362,7 @@ case $basic_machine in ;; # Object if more than one company name word. *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; # Recognize the basic CPU types with company name. @@ -388,7 +385,7 @@ case $basic_machine in | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | hexagon-* \ - | i*86-* | i860-* | i960-* | ia64-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ | ip2k-* | iq2000-* \ | k1om-* \ | le32-* | le64-* \ @@ -429,6 +426,7 @@ case $basic_machine in | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ | pyramid-* \ | riscv32-* | riscv64-* \ | rl78-* | romp-* | rs6000-* | rx-* \ @@ -445,6 +443,7 @@ case $basic_machine in | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ | vax-* \ | visium-* \ + | wasm32-* \ | we32k-* \ | x86-* | x86_64-* | xc16x-* | xps100-* \ | xstormy16-* | xtensa*-* \ @@ -458,7 +457,7 @@ case $basic_machine in # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) - basic_machine=i386-unknown + basic_machine=i386-pc os=-bsd ;; 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) @@ -492,7 +491,7 @@ case $basic_machine in basic_machine=x86_64-pc ;; amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; amdahl) basic_machine=580-amdahl @@ -521,7 +520,7 @@ case $basic_machine in basic_machine=i386-pc os=-aros ;; - asmjs) + asmjs) basic_machine=asmjs-unknown ;; aux) @@ -537,7 +536,7 @@ case $basic_machine in os=-linux ;; blackfin-*) - basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; bluegene*) @@ -545,13 +544,13 @@ case $basic_machine in os=-cnk ;; c54x-*) - basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c55x-*) - basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c6x-*) - basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; c90) basic_machine=c90-cray @@ -640,10 +639,18 @@ case $basic_machine in basic_machine=rs6000-bull os=-bosx ;; - dpx2* | dpx2*-bull) + dpx2*) basic_machine=m68k-bull os=-sysv3 ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; ebmon29k) basic_machine=a29k-amd os=-ebmon @@ -733,9 +740,6 @@ case $basic_machine in hp9k8[0-9][0-9] | hp8[0-9][0-9]) basic_machine=hppa1.0-hp ;; - hppa-next) - os=-nextstep3 - ;; hppaosf) basic_machine=hppa1.1-hp os=-osf @@ -748,26 +752,26 @@ case $basic_machine in basic_machine=i370-ibm ;; i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv32 ;; i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv4 ;; i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-sysv ;; i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` os=-solaris2 ;; i386mach) basic_machine=i386-mach os=-mach ;; - i386-vsta | vsta) + vsta) basic_machine=i386-unknown os=-vsta ;; @@ -786,19 +790,16 @@ case $basic_machine in os=-sysv ;; leon-*|leon[3-9]-*) - basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'` + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` ;; m68knommu) basic_machine=m68k-unknown os=-linux ;; m68knommu-*) - basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; - m88k-omron*) - basic_machine=m88k-omron - ;; magnum | m3230) basic_machine=mips-mips os=-sysv @@ -830,10 +831,10 @@ case $basic_machine in os=-mint ;; mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` ;; mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown ;; monitor) basic_machine=m68k-rom68k @@ -852,7 +853,7 @@ case $basic_machine in os=-msdos ;; ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` ;; msys) basic_machine=i686-pc @@ -894,7 +895,7 @@ case $basic_machine in basic_machine=v70-nec os=-sysv ;; - next | m*-next ) + next | m*-next) basic_machine=m68k-next case $os in -nextstep* ) @@ -939,6 +940,12 @@ case $basic_machine in nsr-tandem) basic_machine=nsr-tandem ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; op50n-* | op60c-*) basic_machine=hppa1.1-oki os=-proelf @@ -971,7 +978,7 @@ case $basic_machine in os=-linux ;; parisc-*) - basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` os=-linux ;; pbd) @@ -987,7 +994,7 @@ case $basic_machine in basic_machine=i386-pc ;; pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc @@ -1002,16 +1009,16 @@ case $basic_machine in basic_machine=i786-pc ;; pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; pn) basic_machine=pn-gould @@ -1021,23 +1028,23 @@ case $basic_machine in ppc | ppcbe) basic_machine=powerpc-unknown ;; ppc-* | ppcbe-*) - basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; - ppcle | powerpclittle | ppc-le | powerpc-little) + ppcle | powerpclittle) basic_machine=powerpcle-unknown ;; ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ppc64) basic_machine=powerpc64-unknown ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) + ppc64le | powerpc64little) basic_machine=powerpc64le-unknown ;; ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; ps2) basic_machine=i386-ibm @@ -1091,17 +1098,10 @@ case $basic_machine in sequent) basic_machine=i386-sequent ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; sh5el) basic_machine=sh5le-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) + simso-wrs) basic_machine=sparclite-wrs os=-vxworks ;; @@ -1120,7 +1120,7 @@ case $basic_machine in os=-sysv4 ;; strongarm-* | thumb-*) - basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'` + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` ;; sun2) basic_machine=m68000-sun @@ -1242,6 +1242,9 @@ case $basic_machine in basic_machine=hppa1.1-winbond os=-proelf ;; + x64) + basic_machine=x86_64-pc + ;; xbox) basic_machine=i686-pc os=-mingw32 @@ -1250,20 +1253,12 @@ case $basic_machine in basic_machine=xps100-honeywell ;; xscale-* | xscalee[bl]-*) - basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'` + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` ;; ymp) basic_machine=ymp-cray os=-unicos ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - z80-*-coff) - basic_machine=z80-unknown - os=-sim - ;; none) basic_machine=none-none os=-none @@ -1292,10 +1287,6 @@ case $basic_machine in vax) basic_machine=vax-dec ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; pdp11) basic_machine=pdp11-dec ;; @@ -1305,9 +1296,6 @@ case $basic_machine in sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; cydra) basic_machine=cydra-cydrome ;; @@ -1327,7 +1315,7 @@ case $basic_machine in # Make sure to match an already-canonicalized machine name. ;; *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 exit 1 ;; esac @@ -1335,10 +1323,10 @@ esac # Here we canonicalize certain aliases for manufacturers. case $basic_machine in *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` ;; *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` ;; *) ;; @@ -1349,8 +1337,8 @@ esac if [ x"$os" != x"" ] then case $os in - # First match some system type aliases - # that might get confused with valid system types. + # First match some system type aliases that might get confused + # with valid system types. # -solaris* is a basic system type, with this one exception. -auroraux) os=-auroraux @@ -1361,18 +1349,19 @@ case $os in -solaris) os=-solaris2 ;; - -svr4*) - os=-sysv4 - ;; -unixware*) os=-sysv4.2uw ;; -gnu/linux*) os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` ;; - # First accept the basic system types. + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. + # Each alternative MUST end in a * to match a version number. # -sysv* is not here because it comes later, after sysvr4. -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ @@ -1382,24 +1371,26 @@ case $os in | -aos* | -aros* | -cloudabi* | -sortix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -bitrig* | -openbsd* | -solidbsd* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* | -cegcc* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ | -linux-newlib* | -linux-musl* | -linux-uclibc* \ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*) + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1416,12 +1407,12 @@ case $os in -nto*) os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) - os=`echo $os | sed -e 's|mac|macos|'` + os=`echo "$os" | sed -e 's|mac|macos|'` ;; -linux-dietlibc) os=-linux-dietlibc @@ -1430,10 +1421,10 @@ case $os in os=`echo $os | sed -e 's|linux|linux-gnu|'` ;; -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` ;; -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` ;; -opened*) os=-openedition @@ -1444,12 +1435,6 @@ case $os in -wince*) os=-wince ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; -utek*) os=-bsd ;; @@ -1474,7 +1459,7 @@ case $os in -nova*) os=-rtmk-nova ;; - -ns2 ) + -ns2) os=-nextstep2 ;; -nsk*) @@ -1496,7 +1481,7 @@ case $os in -oss*) os=-sysv3 ;; - -svr4) + -svr4*) os=-sysv4 ;; -svr3) @@ -1511,32 +1496,38 @@ case $os in -ose*) os=-ose ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) os=-mint ;; - -aros*) - os=-aros - ;; -zvmoe) os=-zvmoe ;; -dicos*) os=-dicos ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; -nacl*) ;; + -ios) + ;; -none) ;; *) # Get rid of the `-' at the beginning of $os. os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 exit 1 ;; esac @@ -1626,12 +1617,12 @@ case $basic_machine in sparc-* | *-sun) os=-sunos4.1.1 ;; + pru-*) + os=-elf + ;; *-be) os=-beos ;; - *-haiku) - os=-haiku - ;; *-ibm) os=-aix ;; @@ -1671,7 +1662,7 @@ case $basic_machine in m88k-omron*) os=-luna ;; - *-next ) + *-next) os=-nextstep ;; *-sequent) @@ -1686,9 +1677,6 @@ case $basic_machine in i370-*) os=-mvs ;; - *-next) - os=-nextstep3 - ;; *-gould) os=-sysv ;; @@ -1798,15 +1786,15 @@ case $basic_machine in vendor=stratus ;; esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` ;; esac -echo $basic_machine$os +echo "$basic_machine$os" exit # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'write-file-functions 'time-stamp) # time-stamp-start: "timestamp='" # time-stamp-format: "%:y-%02m-%02d" # time-stamp-end: "'" diff --git a/configure b/configure index 6aa90cf..ca35a19 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for c-ares 1.12.0. +# Generated by GNU Autoconf 2.69 for c-ares 1.17.1. # # Report bugs to . # @@ -824,12 +824,12 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='c-ares' PACKAGE_TARNAME='c-ares' -PACKAGE_VERSION='1.12.0' -PACKAGE_STRING='c-ares 1.12.0' +PACKAGE_VERSION='1.17.1' +PACKAGE_STRING='c-ares 1.17.1' PACKAGE_BUGREPORT='c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares' PACKAGE_URL='' -ac_unique_file="ares_ipv6.h" +ac_unique_file="src/lib/ares_ipv6.h" # Factoring default headers for most tests. ac_includes_default="\ #include @@ -871,6 +871,7 @@ ac_subst_vars='am__EXEEXT_FALSE am__EXEEXT_TRUE LTLIBOBJS LIBOBJS +BUILD_SUBDIRS subdirs CARES_CFLAG_EXTRAS CARES_PRIVATE_LIBS @@ -880,8 +881,6 @@ DOING_CARES_SYMBOL_HIDING_TRUE RANDOM_FILE DOING_NATIVE_WINDOWS_FALSE DOING_NATIVE_WINDOWS_TRUE -CURLDEBUG_FALSE -CURLDEBUG_TRUE CPPFLAG_CARES_STATICLIB USE_CPPFLAG_CARES_STATICLIB_FALSE USE_CPPFLAG_CARES_STATICLIB_TRUE @@ -921,7 +920,6 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR am__untar @@ -987,6 +985,7 @@ AM_V MAINT MAINTAINER_MODE_FALSE MAINTAINER_MODE_TRUE +CARES_VERSION_INFO target_alias host_alias build_alias @@ -1025,7 +1024,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME SHELL -PATH_SEPARATOR' +PATH_SEPARATOR +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -1035,7 +1035,6 @@ enable_debug enable_optimize enable_warnings enable_werror -enable_curldebug enable_symbol_hiding enable_expose_statics with_gcov @@ -1619,7 +1618,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures c-ares 1.12.0 to adapt to many kinds of systems. +\`configure' configures c-ares 1.17.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1690,7 +1689,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of c-ares 1.12.0:";; + short | recursive ) echo "Configuration of c-ares 1.17.1:";; esac cat <<\_ACEOF @@ -1711,8 +1710,6 @@ Optional Features: --disable-warnings Disable strict compiler warnings --enable-werror Enable compiler warnings as errors --disable-werror Disable compiler warnings as errors - --enable-curldebug Enable curl debug memory tracking - --disable-curldebug Disable curl debug memory tracking --enable-symbol-hiding Enable hiding of library internal symbols --disable-symbol-hiding Disable hiding of library internal symbols --enable-expose-statics Enable exposure of internal static functions for @@ -1831,7 +1828,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -c-ares configure 1.12.0 +c-ares configure 1.17.1 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -2412,7 +2409,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by c-ares $as_me 1.12.0, which was +It was created by c-ares $as_me 1.17.1, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2761,6 +2758,9 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu +CARES_VERSION_INFO="6:2:4" + + @@ -2769,7 +2769,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -ac_config_headers="$ac_config_headers ares_config.h ares_build.h" +ac_config_headers="$ac_config_headers src/lib/ares_config.h include/ares_build.h" @@ -2836,7 +2836,7 @@ AM_BACKSLASH='\' - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debug build options" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable debug build options" >&5 $as_echo_n "checking whether to enable debug build options... " >&6; } OPT_DEBUG_BUILD="default" # Check whether --enable-debug was given. @@ -2938,29 +2938,6 @@ fi $as_echo "$want_werror" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable curl debug memory tracking" >&5 -$as_echo_n "checking whether to enable curl debug memory tracking... " >&6; } - OPT_CURLDEBUG_BUILD="default" - # Check whether --enable-curldebug was given. -if test "${enable_curldebug+set}" = set; then : - enableval=$enable_curldebug; OPT_CURLDEBUG_BUILD=$enableval -fi - - case "$OPT_CURLDEBUG_BUILD" in - no) - want_curldebug="no" - ;; - default) - want_curldebug="no" - ;; - *) - want_curldebug="yes" - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $want_curldebug" >&5 -$as_echo "$want_curldebug" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable hiding of library internal symbols" >&5 $as_echo_n "checking whether to enable hiding of library internal symbols... " >&6; } OPT_SYMBOL_HIDING="default" @@ -3202,7 +3179,8 @@ if test -z "$EGREP" || test "$EGREP" = "not_found"; then fi -if test -n "$ac_tool_prefix"; then +if test -z "$AR"; then + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 @@ -3302,8 +3280,9 @@ else AR="$ac_cv_path_AR" fi -if test -z "$AR" || test "$AR" = "not_found"; then - as_fn_error $? "ar not found in PATH. Cannot continue without ar." "$LINENO" 5 + if test -z "$AR" || test "$AR" = "not_found"; then + as_fn_error $? "ar not found in PATH. Cannot continue without ar." "$LINENO" 5 + fi fi @@ -3519,7 +3498,7 @@ fi fi # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.13" # Extract the first word of "lcov", so it can be a program name with args. set dummy lcov; ac_word=$2 @@ -3719,9 +3698,6 @@ fi -if test -f ${srcdir}/ares_build.h; then - rm -f ${srcdir}/ares_build.h -fi ac_aux_dir= @@ -4000,7 +3976,8 @@ $as_echo "$as_me: $xc_bad_var_msg libraries. Use LIBS for: $xc_word" >&6;} test $xc_bad_var_cflags = yes || test $xc_bad_var_ldflags = yes || test $xc_bad_var_cppflags = yes; then - as_fn_error $? "Can not continue. Fix errors mentioned immediately above this line." "$LINENO" 5 + { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Continuing even with errors mentioned immediately above this line." >&5 +$as_echo "$as_me: WARNING: Continuing even with errors mentioned immediately above this line." >&2;} fi # Find a good install program. We prefer a C program (faster), @@ -5526,7 +5503,7 @@ $as_echo "#define HAVE_CXX11 1" >>confdefs.h fi -am__api_version='1.15' +am__api_version='1.16' { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5 $as_echo_n "checking whether build environment is sane... " >&6; } @@ -5859,45 +5836,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -5944,7 +5921,7 @@ fi # Define the identity of the package. PACKAGE='c-ares' - VERSION='1.12.0' + VERSION='1.17.1' cat >>confdefs.h <<_ACEOF @@ -5974,8 +5951,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -6282,7 +6259,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -9106,7 +9083,7 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cru} +: ${AR_FLAGS=cr} @@ -9606,11 +9583,8 @@ _LT_EOF test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -9670,7 +9644,7 @@ static const void *lt_preloaded_setup() { #endif _LT_EOF # Now try linking the two files. - mv -f conftest.$ac_objext conftstm.$ac_objext + mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext @@ -10827,8 +10801,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF @@ -12233,6 +12207,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -13483,9 +13463,9 @@ fi hpux9*) if test yes = "$GCC"; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: @@ -16157,7 +16137,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -16640,7 +16620,7 @@ fi ld_shlibs_CXX=no ;; aCC*) - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -16649,11 +16629,11 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -16714,7 +16694,7 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -16789,8 +16769,8 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv -f \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -16988,7 +16968,7 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: @@ -17053,7 +17033,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -17137,7 +17117,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -17148,7 +17128,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' @@ -19244,6 +19224,7 @@ $as_echo "$xc_lt_build_static_only" >&6; } + # # Automake conditionals based on libtool related checks # @@ -21722,105 +21703,6 @@ $as_echo "no" >&6; } - cares_builddir=`pwd` - supports_curldebug="unknown" - if test "$want_curldebug" = "yes"; then - if test "x$enable_shared" != "xno" && - test "x$enable_shared" != "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown enable_shared setting." >&5 -$as_echo "$as_me: WARNING: unknown enable_shared setting." >&2;} - supports_curldebug="no" - fi - if test "x$enable_static" != "xno" && - test "x$enable_static" != "xyes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unknown enable_static setting." >&5 -$as_echo "$as_me: WARNING: unknown enable_static setting." >&2;} - supports_curldebug="no" - fi - if test "$supports_curldebug" != "no"; then - if test "$enable_shared" = "yes" && - test "x$xc_lt_shlib_use_no_undefined" = 'xyes'; then - supports_curldebug="no" - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: shared library does not support undefined symbols." >&5 -$as_echo "$as_me: WARNING: shared library does not support undefined symbols." >&2;} - fi - if test ! -f "$srcdir/../include/curl/curlbuild.h.dist"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: c-ares source not embedded in curl's CVS tree." >&5 -$as_echo "$as_me: WARNING: c-ares source not embedded in curl's CVS tree." >&2;} - supports_curldebug="no" - elif test ! -f "$srcdir/../include/curl/Makefile.in"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: curl's buildconf has not been run." >&5 -$as_echo "$as_me: WARNING: curl's buildconf has not been run." >&2;} - supports_curldebug="no" - elif test ! -f "$cares_builddir/../libcurl.pc" || - test ! -f "$cares_builddir/../include/curl/curlbuild.h"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: curl's configure has not been run." >&5 -$as_echo "$as_me: WARNING: curl's configure has not been run." >&2;} - supports_curldebug="no" - elif test ! -f "$cares_builddir/../lib/curl_config.h"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libcurl's curl_config.h is missing." >&5 -$as_echo "$as_me: WARNING: libcurl's curl_config.h is missing." >&2;} - supports_curldebug="no" - elif test ! -f "$cares_builddir/../config.status"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: curl's config.status is missing." >&5 -$as_echo "$as_me: WARNING: curl's config.status is missing." >&2;} - supports_curldebug="no" - fi - if test "$supports_curldebug" != "no"; then - grep '^#define USE_ARES' "$cares_builddir/../lib/curl_config.h" >/dev/null - if test "$?" -ne "0"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libcurl configured without c-ares support." >&5 -$as_echo "$as_me: WARNING: libcurl configured without c-ares support." >&2;} - supports_curldebug="no" - fi - fi - if test "$supports_curldebug" != "no"; then - grep 'CPPFLAGS.*CURLDEBUG' "$cares_builddir/../config.status" >/dev/null - if test "$?" -ne "0"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: libcurl configured without curldebug support." >&5 -$as_echo "$as_me: WARNING: libcurl configured without curldebug support." >&2;} - supports_curldebug="no" - fi - fi - fi - fi - # - if test "$want_curldebug" = "yes"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if curl debug memory tracking can be enabled" >&5 -$as_echo_n "checking if curl debug memory tracking can be enabled... " >&6; } - test "$supports_curldebug" = "no" || supports_curldebug="yes" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $supports_curldebug" >&5 -$as_echo "$supports_curldebug" >&6; } - if test "$supports_curldebug" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cannot enable curl debug memory tracking." >&5 -$as_echo "$as_me: WARNING: cannot enable curl debug memory tracking." >&2;} - want_curldebug="no" - fi - fi - # - if test "$want_curldebug" = "yes"; then - -$as_echo "#define BUILDING_LIBCURL 1" >>confdefs.h - - CPPFLAGS="-DCURLDEBUG $CPPFLAGS" - squeeze CPPFLAGS - fi - # - if test "$want_debug" = "yes"; then - CPPFLAGS="-DDEBUGBUILD $CPPFLAGS" - squeeze CPPFLAGS - fi - - if test x$want_curldebug = xyes; then - CURLDEBUG_TRUE= - CURLDEBUG_FALSE='#' -else - CURLDEBUG_TRUE='#' - CURLDEBUG_FALSE= -fi - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for windows.h" >&5 @@ -22107,6 +21989,7 @@ _ACEOF ;; esac + CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" ;; *) ac_cv_header_winsock_h="no" @@ -22470,32 +22353,7 @@ fi if test "x$host_vendor" = "xapple"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iPhone target" >&5 -$as_echo_n "checking for iPhone target... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - -#include "TargetConditionals.h" - -int main (void) -{ - -#if TARGET_OS_IPHONE == 0 -#error Not an iPhone target -#endif -return 0; - - ; - return 0; -} - -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_servicename" >&5 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing res_servicename" >&5 $as_echo_n "checking for library containing res_servicename... " >&6; } if ${ac_cv_search_res_servicename+:} false; then : $as_echo_n "(cached) " >&6 @@ -22552,19 +22410,11 @@ $as_echo "#define CARES_USE_LIBRESOLV 1" >>confdefs.h else - as_fn_error $? "Unable to find libresolv which is required for iPhone targets" "$LINENO" 5 + as_fn_error $? "Unable to find libresolv which is required for iPhone targets" "$LINENO" 5 fi -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - fi ac_fn_c_check_func "$LINENO" "strcasecmp" "ac_cv_func_strcasecmp" @@ -22904,7 +22754,91 @@ $as_echo "$tst_connect_need_LIBS" >&6; } esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 +if test "x$host_vendor" = "xapple"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for iOS minimum version 10 or later" >&5 +$as_echo_n "checking for iOS minimum version 10 or later... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include +#include + +int main (void) +{ + +#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 +#error Not iOS 10 or later +#endif +return 0; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ac_cv_ios_10="yes" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi + +if test "x$host_vendor" = "xapple"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for macOS minimum version 10.12 or later" >&5 +$as_echo_n "checking for macOS minimum version 10.12 or later... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +#include +#include + +int main (void) +{ + +#ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +#error Not macOS 10.12 or later +#endif +return 0; + + ; + return 0; +} + +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +$as_echo "yes" >&6; } + ac_cv_macos_10_12="yes" + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + +fi + +if test "x$host_vendor" != "xapple" || test "x$ac_cv_ios_10" = "xyes" || test "x$ac_cv_macos_10_12" = "xyes"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if ${ac_cv_header_time+:} false; then : $as_echo_n "(cached) " >&6 @@ -23160,6 +23094,7 @@ _ACEOF fi # +fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use libgcc" >&5 $as_echo_n "checking whether to use libgcc... " >&6; } @@ -23794,12 +23729,17 @@ fi # check for ssize_t ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "$ac_includes_default" if test "x$ac_cv_type_ssize_t" = xyes; then : - + CARES_TYPEOF_ARES_SSIZE_T=ssize_t else + CARES_TYPEOF_ARES_SSIZE_T=int +fi -$as_echo "#define ssize_t int" >>confdefs.h -fi + +cat >>confdefs.h <<_ACEOF +#define CARES_TYPEOF_ARES_SSIZE_T ${CARES_TYPEOF_ARES_SSIZE_T} +_ACEOF + # check for bool type @@ -31007,6 +30947,15 @@ fi done +ac_fn_c_check_func "$LINENO" "__system_property_get" "ac_cv_func___system_property_get" +if test "x$ac_cv_func___system_property_get" = xyes; then : + + +$as_echo "#define HAVE___SYSTEM_PROPERTY_GET 1" >>confdefs.h + + +fi + for ac_header in sys/types.h sys/socket.h netdb.h @@ -31898,14 +31847,20 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $build_tests" >&5 $as_echo "$build_tests" >&6; } + +BUILD_SUBDIRS="include src docs" if test "x$build_tests" = "xyes" ; then subdirs="$subdirs test" + BUILD_SUBDIRS="${BUILD_SUBDIRS} test" fi -ac_config_files="$ac_config_files Makefile libcares.pc" + + +ac_config_files="$ac_config_files Makefile include/Makefile src/Makefile src/lib/Makefile src/tools/Makefile docs/Makefile libcares.pc" + cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure @@ -32068,10 +32023,6 @@ if test -z "${USE_CPPFLAG_CARES_STATICLIB_TRUE}" && test -z "${USE_CPPFLAG_CARES as_fn_error $? "conditional \"USE_CPPFLAG_CARES_STATICLIB\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 fi -if test -z "${CURLDEBUG_TRUE}" && test -z "${CURLDEBUG_FALSE}"; then - as_fn_error $? "conditional \"CURLDEBUG\" was never defined. -Usually this means the macro was only invoked conditionally." "$LINENO" 5 -fi if test -z "${DOING_NATIVE_WINDOWS_TRUE}" && test -z "${DOING_NATIVE_WINDOWS_FALSE}"; then as_fn_error $? "conditional \"DOING_NATIVE_WINDOWS\" was never defined. Usually this means the macro was only invoked conditionally." "$LINENO" 5 @@ -32470,7 +32421,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by c-ares $as_me 1.12.0, which was +This file was extended by c-ares $as_me 1.17.1, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -32536,7 +32487,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -c-ares config.status 1.12.0 +c-ares config.status 1.17.1 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" @@ -32655,7 +32606,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -33048,11 +32999,16 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in - "ares_config.h") CONFIG_HEADERS="$CONFIG_HEADERS ares_config.h" ;; - "ares_build.h") CONFIG_HEADERS="$CONFIG_HEADERS ares_build.h" ;; + "src/lib/ares_config.h") CONFIG_HEADERS="$CONFIG_HEADERS src/lib/ares_config.h" ;; + "include/ares_build.h") CONFIG_HEADERS="$CONFIG_HEADERS include/ares_build.h" ;; "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;; "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; + "include/Makefile") CONFIG_FILES="$CONFIG_FILES include/Makefile" ;; + "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;; + "src/lib/Makefile") CONFIG_FILES="$CONFIG_FILES src/lib/Makefile" ;; + "src/tools/Makefile") CONFIG_FILES="$CONFIG_FILES src/tools/Makefile" ;; + "docs/Makefile") CONFIG_FILES="$CONFIG_FILES docs/Makefile" ;; "libcares.pc") CONFIG_FILES="$CONFIG_FILES libcares.pc" ;; *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; @@ -33653,29 +33609,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -33693,53 +33655,50 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "libtool":C) @@ -33757,7 +33716,6 @@ $as_echo X"$file" | cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff --git a/configure.ac b/configure.ac index b89ce35..703bde0 100644 --- a/configure.ac +++ b/configure.ac @@ -1,15 +1,44 @@ AC_PREREQ(2.57) -dnl Version not hardcoded here. Fetched later from ares_version.h -AC_INIT([c-ares], [1.12.0], +AC_INIT([c-ares], [1.17.1], [c-ares mailing list: http://cool.haxx.se/mailman/listinfo/c-ares]) +CARES_VERSION_INFO="6:2:4" +dnl This flag accepts an argument of the form current[:revision[:age]]. So, +dnl passing -version-info 3:12:1 sets current to 3, revision to 12, and age to +dnl 1. +dnl +dnl If either revision or age are omitted, they default to 0. Also note that age +dnl must be less than or equal to the current interface number. +dnl +dnl Here are a set of rules to help you update your library version information: +dnl +dnl 1.Start with version information of 0:0:0 for each libtool library. +dnl +dnl 2.Update the version information only immediately before a public release of +dnl your software. More frequent updates are unnecessary, and only guarantee +dnl that the current interface number gets larger faster. +dnl +dnl 3.If the library source code has changed at all since the last update, then +dnl increment revision (c:r+1:a) +dnl +dnl 4.If any interfaces have been added, removed, or changed since the last +dnl update, increment current, and set revision to 0. (c+1:r=0:a) +dnl +dnl 5.If any interfaces have been added since the last public release, then +dnl increment age. (c:r:a+1) +dnl +dnl 6.If any interfaces have been removed since the last public release, then +dnl set age to 0. (c:r:a=0) +dnl +AC_SUBST([CARES_VERSION_INFO]) + XC_OVR_ZZ50 XC_OVR_ZZ60 CARES_OVERRIDE_AUTOCONF -AC_CONFIG_SRCDIR([ares_ipv6.h]) -AC_CONFIG_HEADERS([ares_config.h ares_build.h]) +AC_CONFIG_SRCDIR([src/lib/ares_ipv6.h]) +AC_CONFIG_HEADERS([src/lib/ares_config.h include/ares_build.h]) AC_CONFIG_MACRO_DIR([m4]) AM_MAINTAINER_MODE m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) @@ -18,7 +47,6 @@ CARES_CHECK_OPTION_DEBUG CARES_CHECK_OPTION_OPTIMIZE CARES_CHECK_OPTION_WARNINGS CARES_CHECK_OPTION_WERROR -CARES_CHECK_OPTION_CURLDEBUG CARES_CHECK_OPTION_SYMBOL_HIDING CARES_CHECK_OPTION_EXPOSE_STATICS @@ -59,19 +87,18 @@ AC_SUBST([EGREP]) dnl AR is mandatory for configure process and libtool. dnl This is target dependent, so check it as a tool. -AC_PATH_TOOL([AR], [ar], [not_found], - [$PATH:/usr/bin:/usr/local/bin]) -if test -z "$AR" || test "$AR" = "not_found"; then - AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.]) +if test -z "$AR"; then + dnl allow it to be overridden + AC_PATH_TOOL([AR], [ar], [not_found], + [$PATH:/usr/bin:/usr/local/bin]) + if test -z "$AR" || test "$AR" = "not_found"; then + AC_MSG_ERROR([ar not found in PATH. Cannot continue without ar.]) + fi fi AC_SUBST([AR]) AX_CODE_COVERAGE -dnl Remove non-configure distributed ares_build.h -if test -f ${srcdir}/ares_build.h; then - rm -f ${srcdir}/ares_build.h -fi dnl dnl Detect the canonical host and target build environment @@ -104,6 +131,7 @@ esac XC_LIBTOOL + # # Automake conditionals based on libtool related checks # @@ -173,16 +201,13 @@ CARES_CHECK_COMPILER_ARRAY_SIZE_NEGATIVE CARES_CHECK_COMPILER_PROTOTYPE_MISMATCH CARES_CHECK_COMPILER_SYMBOL_HIDING -CARES_CHECK_CURLDEBUG -AM_CONDITIONAL(CURLDEBUG, test x$want_curldebug = xyes) - dnl ********************************************************************** dnl Compilation based checks should not be done before this point. dnl ********************************************************************** dnl ********************************************************************** -dnl Make sure that our checks for headers windows.h winsock.h winsock2.h -dnl and ws2tcpip.h take precedence over any other further checks which +dnl Make sure that our checks for headers windows.h winsock.h winsock2.h +dnl and ws2tcpip.h take precedence over any other further checks which dnl could be done later using AC_CHECK_HEADER or AC_CHECK_HEADERS for dnl this specific header files. And do them before its results are used. dnl ********************************************************************** @@ -194,6 +219,7 @@ case X-"$ac_cv_native_windows" in CURL_CHECK_HEADER_WINSOCK CURL_CHECK_HEADER_WINSOCK2 CURL_CHECK_HEADER_WS2TCPIP + CPPFLAGS="$CPPFLAGS -D_WIN32_WINNT=0x0600" ;; *) ac_cv_header_winsock_h="no" @@ -351,27 +377,12 @@ if test "$HAVE_GETHOSTBYNAME" != "1"; then AC_MSG_ERROR([couldn't find libraries for gethostbyname()]) fi -dnl resolv lib for iPhone +dnl resolv lib for Apple (MacOS and iOS) AS_IF([test "x$host_vendor" = "xapple"], [ - AC_MSG_CHECKING([for iPhone target]) - AC_COMPILE_IFELSE([ - AC_LANG_PROGRAM([[ -#include "TargetConditionals.h" - ]], [[ -#if TARGET_OS_IPHONE == 0 -#error Not an iPhone target -#endif -return 0; - ]]) - ],[ - AC_MSG_RESULT([yes]) - AC_SEARCH_LIBS([res_servicename], [resolv], [ - AC_DEFINE([CARES_USE_LIBRESOLV], [1], [Use resolver library to configure cares]) - ], [ - AC_MSG_ERROR([Unable to find libresolv which is required for iPhone targets]) - ]) - ],[ - AC_MSG_RESULT([no]) + AC_SEARCH_LIBS([res_servicename], [resolv], [ + AC_DEFINE([CARES_USE_LIBRESOLV], [1], [Use resolver library to configure cares]) + ], [ + AC_MSG_ERROR([Unable to find libresolv which is required for iPhone targets]) ]) ]) @@ -388,11 +399,62 @@ ac_cv_func_strcasecmp="no" CARES_CHECK_LIBS_CONNECT +dnl iOS 10? +AS_IF([test "x$host_vendor" = "xapple"], [ + AC_MSG_CHECKING([for iOS minimum version 10 or later]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include + ]], [[ +#if TARGET_OS_IPHONE == 0 || __IPHONE_OS_VERSION_MIN_REQUIRED < 100000 +#error Not iOS 10 or later +#endif +return 0; + ]]) + ],[ + AC_MSG_RESULT([yes]) + ac_cv_ios_10="yes" + ],[ + AC_MSG_RESULT([no]) + ]) +]) + +dnl macOS 10.12? +AS_IF([test "x$host_vendor" = "xapple"], [ + AC_MSG_CHECKING([for macOS minimum version 10.12 or later]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ +#include +#include + ]], [[ +#ifndef MAC_OS_X_VERSION_10_12 +# define MAC_OS_X_VERSION_10_12 101200 +#endif +#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_12 +#error Not macOS 10.12 or later +#endif +return 0; + ]]) + ],[ + AC_MSG_RESULT([yes]) + ac_cv_macos_10_12="yes" + ],[ + AC_MSG_RESULT([no]) + ]) +]) + dnl ********************************************************************** dnl In case that function clock_gettime with monotonic timer is available, dnl check for additional required libraries. dnl ********************************************************************** -CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC +dnl Xcode 8 bug: iOS when targeting less than 10, or macOS when targeting less than 10.12 will +dnl say clock_gettime exists, it is a weak symbol that only exists in iOS 10 or macOS 10.12 and will +dnl cause a crash at runtime when running on older versions. Skip finding CLOCK_MONOTONIC on older +dnl Apple OS's. +if test "x$host_vendor" != "xapple" || test "x$ac_cv_ios_10" = "xyes" || test "x$ac_cv_macos_10_12" = "xyes"; then + CURL_CHECK_LIBS_CLOCK_GETTIME_MONOTONIC +fi AC_MSG_CHECKING([whether to use libgcc]) AC_ARG_ENABLE(libgcc, @@ -485,7 +547,7 @@ CURL_CHECK_STRUCT_TIMEVAL AC_CHECK_TYPE(long long, [AC_DEFINE(HAVE_LONGLONG, 1, [Define to 1 if the compiler supports the 'long long' data type.])] - longlong="yes" + longlong="yes" ) if test "xyes" = "x$longlong"; then @@ -505,8 +567,12 @@ fi # check for ssize_t -AC_CHECK_TYPE(ssize_t, , - AC_DEFINE(ssize_t, int, [the signed version of size_t])) +AC_CHECK_TYPE(ssize_t, [ CARES_TYPEOF_ARES_SSIZE_T=ssize_t ], + [ CARES_TYPEOF_ARES_SSIZE_T=int ]) + +AC_DEFINE_UNQUOTED([CARES_TYPEOF_ARES_SSIZE_T], ${CARES_TYPEOF_ARES_SSIZE_T}, + [the signed version of size_t]) + # check for bool type AC_CHECK_TYPE([bool],[ @@ -585,7 +651,7 @@ CARES_CHECK_CONSTANT( #include #endif #endif - ], [PF_INET6], + ], [PF_INET6], AC_DEFINE_UNQUOTED(HAVE_PF_INET6,1,[Define to 1 if you have PF_INET6.]) ) @@ -609,7 +675,7 @@ CARES_CHECK_CONSTANT( #include #endif #endif - ], [AF_INET6], + ], [AF_INET6], AC_DEFINE_UNQUOTED(HAVE_AF_INET6,1,[Define to 1 if you have AF_INET6.]) ) @@ -637,7 +703,7 @@ CARES_CHECK_STRUCT( #include #endif #endif - ], [in6_addr], + ], [in6_addr], AC_DEFINE_UNQUOTED(HAVE_STRUCT_IN6_ADDR,1,[Define to 1 if you have struct in6_addr.]) ) @@ -664,7 +730,7 @@ CARES_CHECK_STRUCT( #include #endif #endif - ], [sockaddr_in6], + ], [sockaddr_in6], AC_DEFINE_UNQUOTED(HAVE_STRUCT_SOCKADDR_IN6,1, [Define to 1 if you have struct sockaddr_in6.]) ac_have_sockaddr_in6=yes ) @@ -753,6 +819,11 @@ AC_CHECK_FUNCS([bitncmp \ ]) ]) +dnl Android. Some variants like arm64 may no longer have __system_property_get +dnl in libc, but they are defined in the headers. Perform a link check. +AC_CHECK_FUNC([__system_property_get], [ + AC_DEFINE([HAVE___SYSTEM_PROPERTY_GET], [1], [Define if __system_property_get exists.]) +]) dnl Check if the getnameinfo function is available dnl and get the types of five of its arguments. @@ -780,7 +851,7 @@ AC_HELP_STRING([--with-random=FILE], else AC_MSG_WARN([cannot check for /dev/urandom while cross compiling; assuming none]) fi - + ] ) if test -n "$RANDOM_FILE" && test X"$RANDOM_FILE" != Xno ; then @@ -837,10 +908,22 @@ if test "x$build_tests" = "xyes" ; then fi AC_MSG_RESULT([$build_tests]) + +BUILD_SUBDIRS="include src docs" if test "x$build_tests" = "xyes" ; then AC_CONFIG_SUBDIRS([test]) + BUILD_SUBDIRS="${BUILD_SUBDIRS} test" fi -AC_CONFIG_FILES([Makefile libcares.pc]) +AC_SUBST(BUILD_SUBDIRS) + +AC_CONFIG_FILES([Makefile \ + include/Makefile \ + src/Makefile \ + src/lib/Makefile \ + src/tools/Makefile \ + docs/Makefile \ + libcares.pc ]) + AC_OUTPUT XC_AMEND_DISTCLEAN(['.']) diff --git a/depcomp b/depcomp index fc98710..6b39162 100755 --- a/depcomp +++ b/depcomp @@ -1,9 +1,9 @@ #! /bin/sh # depcomp - compile a program generating dependencies as side-effects -scriptversion=2013-05-30.07; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -16,7 +16,7 @@ scriptversion=2013-05-30.07; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -783,9 +783,9 @@ exit 0 # Local Variables: # mode: shell-script # sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt new file mode 100644 index 0000000..5b91d31 --- /dev/null +++ b/docs/CMakeLists.txt @@ -0,0 +1,17 @@ +# Headers and Man Pages installation target +IF (CARES_INSTALL) + # ManPages + FILE (GLOB DevelManPages "." "*.3") + INSTALL (FILES ${DevelManPages} + DESTINATION ${CMAKE_INSTALL_MANDIR}/man3 + COMPONENT Devel + ) + + IF (CARES_BUILD_TOOLS) + FILE (GLOB ToolManPages "." "*.1") + INSTALL (FILES ${ToolManPages} + DESTINATION ${CMAKE_INSTALL_MANDIR}/man1 + COMPONENT Tools + ) + ENDIF () +ENDIF () diff --git a/docs/Makefile.am b/docs/Makefile.am new file mode 100644 index 0000000..289445c --- /dev/null +++ b/docs/Makefile.am @@ -0,0 +1,11 @@ +#*************************************************************************** + +########################################################################### + +AUTOMAKE_OPTIONS = foreign subdir-objects no-dependencies + +include Makefile.inc + +man_MANS = $(MANPAGES) + +EXTRA_DIST = $(MANPAGES) ahost.1 adig.1 acountry.1 Makefile.inc CMakeLists.txt diff --git a/docs/Makefile.in b/docs/Makefile.in new file mode 100644 index 0000000..9ceca3a --- /dev/null +++ b/docs/Makefile.in @@ -0,0 +1,625 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +#*************************************************************************** + +########################################################################### +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = docs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/m4/cares-compilers.m4 \ + $(top_srcdir)/m4/cares-confopts.m4 \ + $(top_srcdir)/m4/cares-functions.m4 \ + $(top_srcdir)/m4/cares-override.m4 \ + $(top_srcdir)/m4/cares-reentrant.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/lib/ares_config.h \ + $(top_builddir)/include/ares_build.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +depcomp = +am__maybe_remake_depfiles = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +man3dir = $(mandir)/man3 +am__installdirs = "$(DESTDIR)$(man3dir)" +NROFF = nroff +MANS = $(man_MANS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ +CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ +CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign subdir-objects no-dependencies +MANPAGES = ares_cancel.3 \ + ares_create_query.3 \ + ares_destroy.3 \ + ares_destroy_options.3 \ + ares_dup.3 \ + ares_expand_name.3 \ + ares_expand_string.3 \ + ares_fds.3 \ + ares_free_data.3 \ + ares_free_hostent.3 \ + ares_free_string.3 \ + ares_freeaddrinfo.3 \ + ares_get_servers.3 \ + ares_get_servers_ports.3 \ + ares_getaddrinfo.3 \ + ares_gethostbyaddr.3 \ + ares_gethostbyname.3 \ + ares_gethostbyname_file.3 \ + ares_getnameinfo.3 \ + ares_getsock.3 \ + ares_inet_ntop.3 \ + ares_inet_pton.3 \ + ares_init.3 \ + ares_init_options.3 \ + ares_library_cleanup.3 \ + ares_library_init.3 \ + ares_library_init_android.3 \ + ares_library_initialized.3 \ + ares_mkquery.3 \ + ares_parse_a_reply.3 \ + ares_parse_aaaa_reply.3 \ + ares_parse_caa_reply.3 \ + ares_parse_mx_reply.3 \ + ares_parse_naptr_reply.3 \ + ares_parse_ns_reply.3 \ + ares_parse_ptr_reply.3 \ + ares_parse_soa_reply.3 \ + ares_parse_srv_reply.3 \ + ares_parse_txt_reply.3 \ + ares_process.3 \ + ares_query.3 \ + ares_save_options.3 \ + ares_search.3 \ + ares_send.3 \ + ares_set_local_dev.3 \ + ares_set_local_ip4.3 \ + ares_set_local_ip6.3 \ + ares_set_servers.3 \ + ares_set_servers_csv.3 \ + ares_set_servers_ports.3 \ + ares_set_servers_ports_csv.3 \ + ares_set_socket_callback.3 \ + ares_set_socket_configure_callback.3 \ + ares_set_socket_functions.3 \ + ares_set_sortlist.3 \ + ares_strerror.3 \ + ares_timeout.3 \ + ares_version.3 + +man_MANS = $(MANPAGES) +EXTRA_DIST = $(MANPAGES) ahost.1 adig.1 acountry.1 Makefile.inc CMakeLists.txt +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign docs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign docs/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(srcdir)/Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-man3: $(man_MANS) + @$(NORMAL_INSTALL) + @list1=''; \ + list2='$(man_MANS)'; \ + test -n "$(man3dir)" \ + && test -n "`echo $$list1$$list2`" \ + || exit 0; \ + echo " $(MKDIR_P) '$(DESTDIR)$(man3dir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(man3dir)" || exit 1; \ + { for i in $$list1; do echo "$$i"; done; \ + if test -n "$$list2"; then \ + for i in $$list2; do echo "$$i"; done \ + | sed -n '/\.3[a-z]*$$/p'; \ + fi; \ + } | while read p; do \ + if test -f $$p; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; echo "$$p"; \ + done | \ + sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \ + sed 'N;N;s,\n, ,g' | { \ + list=; while read file base inst; do \ + if test "$$base" = "$$inst"; then list="$$list $$file"; else \ + echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \ + $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \ + fi; \ + done; \ + for i in $$list; do echo "$$i"; done | $(am__base_list) | \ + while read files; do \ + test -z "$$files" || { \ + echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \ + $(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \ + done; } + +uninstall-man3: + @$(NORMAL_UNINSTALL) + @list=''; test -n "$(man3dir)" || exit 0; \ + files=`{ for i in $$list; do echo "$$i"; done; \ + l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \ + sed -n '/\.3[a-z]*$$/p'; \ + } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \ + -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \ + dir='$(DESTDIR)$(man3dir)'; $(am__uninstall_files_from_dir) +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(MANS) +installdirs: + for dir in "$(DESTDIR)$(man3dir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-man + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: install-man3 + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-man + +uninstall-man: uninstall-man3 + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-man3 install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags-am uninstall uninstall-am uninstall-man \ + uninstall-man3 + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/docs/Makefile.inc b/docs/Makefile.inc new file mode 100644 index 0000000..fbd7492 --- /dev/null +++ b/docs/Makefile.inc @@ -0,0 +1,58 @@ +MANPAGES = ares_cancel.3 \ + ares_create_query.3 \ + ares_destroy.3 \ + ares_destroy_options.3 \ + ares_dup.3 \ + ares_expand_name.3 \ + ares_expand_string.3 \ + ares_fds.3 \ + ares_free_data.3 \ + ares_free_hostent.3 \ + ares_free_string.3 \ + ares_freeaddrinfo.3 \ + ares_get_servers.3 \ + ares_get_servers_ports.3 \ + ares_getaddrinfo.3 \ + ares_gethostbyaddr.3 \ + ares_gethostbyname.3 \ + ares_gethostbyname_file.3 \ + ares_getnameinfo.3 \ + ares_getsock.3 \ + ares_inet_ntop.3 \ + ares_inet_pton.3 \ + ares_init.3 \ + ares_init_options.3 \ + ares_library_cleanup.3 \ + ares_library_init.3 \ + ares_library_init_android.3 \ + ares_library_initialized.3 \ + ares_mkquery.3 \ + ares_parse_a_reply.3 \ + ares_parse_aaaa_reply.3 \ + ares_parse_caa_reply.3 \ + ares_parse_mx_reply.3 \ + ares_parse_naptr_reply.3 \ + ares_parse_ns_reply.3 \ + ares_parse_ptr_reply.3 \ + ares_parse_soa_reply.3 \ + ares_parse_srv_reply.3 \ + ares_parse_txt_reply.3 \ + ares_process.3 \ + ares_query.3 \ + ares_save_options.3 \ + ares_search.3 \ + ares_send.3 \ + ares_set_local_dev.3 \ + ares_set_local_ip4.3 \ + ares_set_local_ip6.3 \ + ares_set_servers.3 \ + ares_set_servers_csv.3 \ + ares_set_servers_ports.3 \ + ares_set_servers_ports_csv.3 \ + ares_set_socket_callback.3 \ + ares_set_socket_configure_callback.3 \ + ares_set_socket_functions.3 \ + ares_set_sortlist.3 \ + ares_strerror.3 \ + ares_timeout.3 \ + ares_version.3 diff --git a/acountry.1 b/docs/acountry.1 similarity index 96% rename from acountry.1 rename to docs/acountry.1 index 74c4e34..269ae1f 100644 --- a/acountry.1 +++ b/docs/acountry.1 @@ -24,7 +24,8 @@ Display this help and exit. Be more verbose. Print extra information. .SH "REPORTING BUGS" Report bugs to the c-ares mailing list: -\fBhttp://cool.haxx.se/mailman/listinfo/c-ares\fR +.br +\fBhttps://cool.haxx.se/mailman/listinfo/c-ares\fR .SH "SEE ALSO" .PP adig(1), ahost(1). diff --git a/adig.1 b/docs/adig.1 similarity index 82% rename from adig.1 rename to docs/adig.1 index 76e9689..fa5c766 100644 --- a/adig.1 +++ b/docs/adig.1 @@ -46,9 +46,23 @@ PTR, PX, RP, RT, SIG, SOA, SRV, TXT, WKS, X25, .TP \fB\-U\fR port Use specified UDP port to connect to DNS server. +.TP +\fB\-x\fR +For an IPv4 \fB-t PTR a.b.c.d\fR lookup, query for +.br +\fBd.c.b.a.in-addr.arpa.\fR +This more often gives correct names in the \fBANSWER\fR. +.br +For an IPv6 \fB-t PTR addr\fR lookup, query for \fBa.b.c....z.IP6.ARPA.\fR +.TP +\fB\-xx\fR +As for \fB-x\fR and an IPv6 address, compact \fBa.b.c....z.IP6.ARPA.\fR into a RFC-2673 bit-string. +This compacted \fBbit-string\fR form is not supported by many DNS-servers. + .SH "REPORTING BUGS" Report bugs to the c-ares mailing list: -\fBhttp://cool.haxx.se/mailman/listinfo/c-ares\fR +.br +\fBhttps://cool.haxx.se/mailman/listinfo/c-ares\fR .SH "SEE ALSO" .PP acountry(1), ahost(1). diff --git a/ahost.1 b/docs/ahost.1 similarity index 97% rename from ahost.1 rename to docs/ahost.1 index c83cfcf..89a3920 100644 --- a/ahost.1 +++ b/docs/ahost.1 @@ -35,7 +35,8 @@ for DNS configuration; it has no effect on other platforms (such as Win32 or Android). .SH "REPORTING BUGS" Report bugs to the c-ares mailing list: -\fBhttp://cool.haxx.se/mailman/listinfo/c-ares\fR +.br +\fBhttps://cool.haxx.se/mailman/listinfo/c-ares\fR .SH "SEE ALSO" .PP acountry(1), adig(1). diff --git a/ares_cancel.3 b/docs/ares_cancel.3 similarity index 95% rename from ares_cancel.3 rename to docs/ares_cancel.3 index e534e3f..1a2d3f5 100644 --- a/ares_cancel.3 +++ b/docs/ares_cancel.3 @@ -18,9 +18,9 @@ ares_cancel \- Cancel a resolve .SH SYNOPSIS .nf -.B #include -.PP -.B void ares_cancel(ares_channel \fIchannel\fP) +#include + +void ares_cancel(ares_channel \fIchannel\fP) .fi .SH DESCRIPTION The \fBares_cancel(3)\fP function cancels all lookups/requests made on the the diff --git a/ares_create_query.3 b/docs/ares_create_query.3 similarity index 96% rename from ares_create_query.3 rename to docs/ares_create_query.3 index 59af0f0..1ab0624 100644 --- a/ares_create_query.3 +++ b/docs/ares_create_query.3 @@ -58,6 +58,13 @@ can return any of the following values: .B ARES_SUCCESS Construction of the DNS query succeeded. .TP 15 +.B ARES_ENOTFOUND +The query name +.I name +refers to a +.I .onion +domain name. See RFC 7686. +.TP 15 .B ARES_EBADNAME The query name .I name diff --git a/ares_destroy.3 b/docs/ares_destroy.3 similarity index 90% rename from ares_destroy.3 rename to docs/ares_destroy.3 index 7af7fe3..9cdee30 100644 --- a/ares_destroy.3 +++ b/docs/ares_destroy.3 @@ -18,9 +18,9 @@ ares_destroy \- Destroy a resolver channel .SH SYNOPSIS .nf -.B #include -.PP -.B void ares_destroy(ares_channel \fIchannel\fP) +#include + +void ares_destroy(ares_channel \fIchannel\fP) .fi .SH DESCRIPTION The \fBares_destroy(3)\fP function destroys the name service channel @@ -28,7 +28,7 @@ identified by \fIchannel\fP, freeing all memory and closing all sockets used by the channel. \fBares_destroy(3)\fP invokes the callbacks for each pending query on the -channel, passing a status of \IARES_EDESTRUCTION\fP. These calls give the +channel, passing a status of \fIARES_EDESTRUCTION\fP. These calls give the callbacks a chance to clean up any state which might have been stored in their arguments. A callback must not add new requests to a channel being destroyed. .SH SEE ALSO diff --git a/ares_destroy_options.3 b/docs/ares_destroy_options.3 similarity index 100% rename from ares_destroy_options.3 rename to docs/ares_destroy_options.3 diff --git a/ares_dup.3 b/docs/ares_dup.3 similarity index 100% rename from ares_dup.3 rename to docs/ares_dup.3 diff --git a/ares_expand_name.3 b/docs/ares_expand_name.3 similarity index 100% rename from ares_expand_name.3 rename to docs/ares_expand_name.3 diff --git a/ares_expand_string.3 b/docs/ares_expand_string.3 similarity index 100% rename from ares_expand_string.3 rename to docs/ares_expand_string.3 diff --git a/ares_fds.3 b/docs/ares_fds.3 similarity index 58% rename from ares_fds.3 rename to docs/ares_fds.3 index 743e45e..07063fb 100644 --- a/ares_fds.3 +++ b/docs/ares_fds.3 @@ -15,43 +15,30 @@ .\" .TH ARES_FDS 3 "23 July 1998" .SH NAME -ares_fds \- Get file descriptors to select on for name service +ares_fds \- return file descriptors to select on .SH SYNOPSIS .nf -.B #include -.PP -.B int ares_fds(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, -.B fd_set *\fIwrite_fds\fP) +#include + +int ares_fds(ares_channel \fIchannel\fP, + fd_set *\fIread_fds\fP, + fd_set *\fIwrite_fds\fP) .fi .SH DESCRIPTION -The -.B ares_fds -function retrieves the set of file descriptors which the calling -application should select on for reading and writing for the +The \fBares_fds(3)\fP function retrieves the set of file descriptors which the +calling application should select on for reading and writing for the processing of name service queries pending on the name service channel -identified by -.IR channel . +identified by \fIchannel\fP. + File descriptors will be set in the file descriptor sets pointed to by -.I read_fds -and -.I write_fds -as appropriate. File descriptors already set in -.I read_fds -and -.I write_fds -will remain set; initialization of the file descriptor sets -(using -.BR FD_ZERO ) -is the responsibility of the caller. +\fIread_fds\fP and \fIwrite_fds\fP as appropriate. File descriptors already +set in \fIread_fds\fP and \fIwrite_fds\fP will remain set; initialization of +the file descriptor sets (using \fBFD_ZERO\fP) is the responsibility of the +caller. .SH RETURN VALUES -.B ares_fds -returns one greater than the number of the highest socket set in either -.I read_fds -or -.IR write_fds . -If no queries are active, -.B ares_fds -will return 0. +\fBares_fds(3)\fP returns a value that is one greater than the number of the +highest socket set in either \fIread_fds\fP or \fIwrite_fds\fP. If no queries +are active, \fBares_fds(3)\fP returns 0. .SH SEE ALSO .BR ares_timeout (3), .BR ares_process (3) diff --git a/ares_free_data.3 b/docs/ares_free_data.3 similarity index 100% rename from ares_free_data.3 rename to docs/ares_free_data.3 diff --git a/ares_free_hostent.3 b/docs/ares_free_hostent.3 similarity index 100% rename from ares_free_hostent.3 rename to docs/ares_free_hostent.3 diff --git a/ares_free_string.3 b/docs/ares_free_string.3 similarity index 100% rename from ares_free_string.3 rename to docs/ares_free_string.3 diff --git a/docs/ares_freeaddrinfo.3 b/docs/ares_freeaddrinfo.3 new file mode 100644 index 0000000..8a8ad59 --- /dev/null +++ b/docs/ares_freeaddrinfo.3 @@ -0,0 +1,37 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_FREEADDRINFO 3 "31 October 2018" +.SH NAME +ares_freeaddrinfo \- Free addrinfo structure allocated by ares functions +.SH SYNOPSIS +.nf +#include + +void ares_freeaddrinfo(struct ares_addrinfo *\fIai\fP) +.fi +.SH DESCRIPTION +The +.B ares_freeaddrinfo +function frees a +.B struct ares_addrinfo +returned in \fIresult\fP of +.B ares_addrinfo_callback +.SH SEE ALSO +.BR ares_getaddrinfo (3), +.SH AUTHOR +Christian Ammer +.BR +Andrew Selivanov diff --git a/ares_get_servers.3 b/docs/ares_get_servers.3 similarity index 100% rename from ares_get_servers.3 rename to docs/ares_get_servers.3 diff --git a/ares_get_servers_ports.3 b/docs/ares_get_servers_ports.3 similarity index 100% rename from ares_get_servers_ports.3 rename to docs/ares_get_servers_ports.3 diff --git a/docs/ares_getaddrinfo.3 b/docs/ares_getaddrinfo.3 new file mode 100644 index 0000000..6cae0ff --- /dev/null +++ b/docs/ares_getaddrinfo.3 @@ -0,0 +1,195 @@ +.\" +.\" Copyright 1998 by the Massachusetts Institute of Technology. +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_GETADDRINFO 3 "4 November 2018" +.SH NAME +ares_getaddrinfo \- Initiate a host query by name and service +.SH SYNOPSIS +.nf +.B #include +.PP +.B typedef void (*ares_addrinfo_callback)(void *\fIarg\fP, int \fIstatus\fP, +.B int \fItimeouts\fP, struct ares_addrinfo *\fIresult\fP) +.PP +.B void ares_getaddrinfo(ares_channel \fIchannel\fP, const char *\fIname\fP, +.B const char* \fIservice\fP, const struct ares_addrinfo_hints *\fIhints\fP, +.B ares_addrinfo_callback \fIcallback\fP, void *\fIarg\fP) +.fi +.SH DESCRIPTION +The +.B ares_getaddrinfo +function initiates a host query by name on the name service channel +identified by +.IR channel . +The +.I name +and +.I service +parameters give the hostname and service as NULL-terminated C strings. +The +.I hints +parameter is an +.BR ares_addrinfo_hints +structure: +.PP +.RS +.EX +struct ares_addrinfo_hints { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; +}; +.EE +.RE +.TP +.I ai_family +Specifies desired address family. AF_UNSPEC means return both AF_INET and AF_INET6. +.TP +.I ai_socktype +Specifies desired socket type, for example SOCK_STREAM or SOCK_DGRAM. +Setting this to 0 means any type. +.TP +.I ai_protocol +Setting this to 0 means any protocol. +.TP +.I ai_flags +Specifies additional options, see below. +.PP +.TP 19 +.B ARES_AI_NUMERICSERV +If this option is set +.I service +field will be treated as a numeric value. +.TP 19 +.B ARES_AI_CANONNAME +The ares_addrinfo structure will return a canonical names list. +.TP 19 +.B ARES_AI_NOSORT +Result addresses will not be sorted and no connections to resolved addresses will be attempted. +.TP 19 +.B ARES_AI_ENVHOSTS +Read hosts file path from the environment variable +.I CARES_HOSTS . +.PP +When the query is complete or has failed, the ares library will invoke \fIcallback\fP. +Completion or failure of the query may happen immediately, or may happen +during a later call to \fIares_process(3)\fP, \fIares_destroy(3)\fP or +\fIares_cancel(3)\fP. +.PP +The callback argument +.I arg +is copied from the +.B ares_getaddrinfo +argument +.IR arg . +The callback argument +.I status +indicates whether the query succeeded and, if not, how it failed. It +may have any of the following values: +.TP 19 +.B ARES_SUCCESS +The host lookup completed successfully. +.TP 19 +.B ARES_ENOTIMP +The ares library does not know how to find addresses of type +.IR family . +.TP 19 +.B ARES_ENOTFOUND +The +.I name +was not found. +.TP 19 +.B ARES_ENOMEM +Memory was exhausted. +.TP 19 +.B ARES_ECANCELLED +The query was cancelled. +.TP 19 +.B ARES_EDESTRUCTION +The name service channel +.I channel +is being destroyed; the query will not be completed. +.PP +On successful completion of the query, the callback argument +.I result +points to a +.B struct ares_addrinfo +which contains two linked lists, one with resolved addresses and another with canonical names. +.PP +.RS +.EX +struct ares_addrinfo { + struct ares_addrinfo_cname *cnames; + struct ares_addrinfo_node *nodes; +}; +.EE +.RE +.PP +.I ares_addrinfo_node +structure is similar to RFC3493 addrinfo, but without canonname and with extra ttl field. +.RS +.PP +.EX +struct ares_addrinfo_node { + int ai_ttl; + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + ares_socklen_t ai_addrlen; + struct sockaddr *ai_addr; + struct ares_addrinfo_node *ai_next; +}; +.EE +.RE +.PP +.I ares_addrinfo_cname +structure is a linked list of CNAME records where +.I ttl +is a time to live +.I alias +is a label of the resource record and +.I name +is a value (canonical name) of the resource record. +See RFC2181 10.1.1. CNAME terminology. +.RS +.PP +.EX +struct ares_addrinfo_cname { + int ttl; + char *alias; + char *name; + struct ares_addrinfo_cname *next; +}; +.EE +.RE +.PP +The reserved memory has to be deleted by +.B ares_freeaddrinfo. + +The result is sorted according to RFC6724 except: + - Rule 3 (Avoid deprecated addresses) + - Rule 4 (Prefer home addresses) + - Rule 7 (Prefer native transport) + +Please note that the function will attempt a connection +on each of the resolved addresses as per RFC6724. +.SH SEE ALSO +.BR ares_freeaddrinfo (3) +.SH AUTHOR +Christian Ammer +.br +Andrew Selivanov diff --git a/ares_gethostbyaddr.3 b/docs/ares_gethostbyaddr.3 similarity index 100% rename from ares_gethostbyaddr.3 rename to docs/ares_gethostbyaddr.3 diff --git a/ares_gethostbyname.3 b/docs/ares_gethostbyname.3 similarity index 97% rename from ares_gethostbyname.3 rename to docs/ares_gethostbyname.3 index 6b24ea4..cfd6a0a 100644 --- a/ares_gethostbyname.3 +++ b/docs/ares_gethostbyname.3 @@ -66,9 +66,12 @@ The hostname is composed entirely of numbers and periods, but is not a valid representation of an Internet address. .TP 19 +.B ARES_ENODATA +There was no data returned to extract a result from. +.TP 19 .B ARES_ENOTFOUND -The address -.I addr +The name +.I name was not found. .TP 19 .B ARES_ENOMEM diff --git a/ares_gethostbyname_file.3 b/docs/ares_gethostbyname_file.3 similarity index 100% rename from ares_gethostbyname_file.3 rename to docs/ares_gethostbyname_file.3 diff --git a/ares_getnameinfo.3 b/docs/ares_getnameinfo.3 similarity index 100% rename from ares_getnameinfo.3 rename to docs/ares_getnameinfo.3 diff --git a/ares_getsock.3 b/docs/ares_getsock.3 similarity index 100% rename from ares_getsock.3 rename to docs/ares_getsock.3 diff --git a/ares_inet_ntop.3 b/docs/ares_inet_ntop.3 similarity index 100% rename from ares_inet_ntop.3 rename to docs/ares_inet_ntop.3 diff --git a/ares_inet_pton.3 b/docs/ares_inet_pton.3 similarity index 100% rename from ares_inet_pton.3 rename to docs/ares_inet_pton.3 diff --git a/ares_init.3 b/docs/ares_init.3 similarity index 100% rename from ares_init.3 rename to docs/ares_init.3 diff --git a/ares_init_options.3 b/docs/ares_init_options.3 similarity index 90% rename from ares_init_options.3 rename to docs/ares_init_options.3 index ff677c9..b9d52a8 100644 --- a/ares_init_options.3 +++ b/docs/ares_init_options.3 @@ -21,6 +21,28 @@ ares_init_options \- Initialize a resolver channel .nf #include +struct ares_options { + int flags; + int timeout; /* in seconds or milliseconds, depending on options */ + int tries; + int ndots; + unsigned short udp_port; + unsigned short tcp_port; + int socket_send_buffer_size; + int socket_receive_buffer_size; + struct in_addr *servers; + int nservers; + char **domains; + int ndomains; + char *lookups; + ares_sock_state_cb sock_state_cb; + void *sock_state_cb_data; + struct apattern *sortlist; + int nsort; + int ednspsz; + char *resolvconf_path; +}; + int ares_init_options(ares_channel *\fIchannelptr\fP, struct ares_options *\fIoptions\fP, int \fIoptmask\fP) @@ -118,16 +140,16 @@ should be set to a string of the characters "b" or "f", where "b" indicates a DNS lookup and "f" indicates a lookup in the hosts file. .TP 18 .B ARES_OPT_SOCK_STATE_CB -.B void (*\fIsock_state_cb\fP)(void *data, int s, int read, int write); +.B void (*\fIsock_state_cb\fP)(void *data, ares_socket_t socket_fd, int readable, int writable); .br .B void *\fIsock_state_cb_data\fP; .br A callback function to be invoked when a socket changes state. -.I s +.I socket_fd will be passed the socket whose state has changed; -.I read +.I readable will be set to true if the socket should listen for read events, and -.I write +.I writable will be set to true if the socket should listen for write events. The value of .I sock_state_cb_data @@ -163,6 +185,15 @@ The receive buffer size to set for the socket. The message size to be advertized in EDNS; only takes effect if the .B ARES_FLAG_EDNS flag is set. +.TP 18 +.B ARES_OPT_RESOLVCONF +.B char *\fIresolvconf_path\fP; +.br +The path to use for reading the resolv.conf file. The +.I resolvconf_path +should be set to a path string, and will be honoured on *nix like systems. The +default is +.B /etc/resolv.conf .br .PP The \fIoptmask\fP parameter also includes options without a corresponding @@ -238,6 +269,9 @@ c-ares library initialization not yet performed. .SH NOTES When initializing from .B /etc/resolv.conf, +(or, alternatively when specified by the +.I resolvconf_path +path location) \fBares_init_options(3)\fP reads the \fIdomain\fP and \fIsearch\fP directives to allow lookups of short names relative to the domains specified. The \fIdomain\fP and \fIsearch\fP directives override one another. If more that @@ -259,4 +293,3 @@ Greg Hudson, MIT Information Systems Copyright 1998 by the Massachusetts Institute of Technology. .br Copyright (C) 2004-2010 by Daniel Stenberg. - diff --git a/ares_library_cleanup.3 b/docs/ares_library_cleanup.3 similarity index 97% rename from ares_library_cleanup.3 rename to docs/ares_library_cleanup.3 index d60c378..a1ffa6a 100644 --- a/ares_library_cleanup.3 +++ b/docs/ares_library_cleanup.3 @@ -19,11 +19,9 @@ ares_library_cleanup \- c-ares library deinitialization .SH SYNOPSIS .nf -.B #include -.PP -.B void ares_library_cleanup(void) -.PP -.B cc file.c -lcares +#include + +void ares_library_cleanup(void) .fi .SH DESCRIPTION .PP diff --git a/ares_library_init.3 b/docs/ares_library_init.3 similarity index 96% rename from ares_library_init.3 rename to docs/ares_library_init.3 index 4734f92..b38cf32 100644 --- a/ares_library_init.3 +++ b/docs/ares_library_init.3 @@ -68,6 +68,9 @@ that \fIares_library_init(3)\fP might call functions from other libraries that are thread unsafe, and could conflict with any other thread that is already using these other libraries. .PP +On Windows platforms, the library user should ensure that \fIWSAStartup()\fP +is called before the c-ares library is initialized and used. +.PP Win32/64 application DLLs shall not call \fIares_library_init(3)\fP from the DllMain function. Doing so will produce deadlocks and other problems. .SH FLAGS diff --git a/docs/ares_library_init_android.3 b/docs/ares_library_init_android.3 new file mode 100644 index 0000000..9e1ac4c --- /dev/null +++ b/docs/ares_library_init_android.3 @@ -0,0 +1,142 @@ +.\" +.\" Copyright (C) 2017 by John Schember +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_LIBRARY_INIT_ANDROID 3 "13 Sept 2017" +.SH NAME +ares_library_init_android \- c-ares library Android initialization +.SH SYNOPSIS +.nf +#include + +int ares_library_init_android(jobject \fIconnectivity_manager\fP) + +int ares_library_android_initialized(); + +void ares_library_init_jvm(JavaVM *\fIjvm\fP) + +.fi +.SH DESCRIPTION +The \fIares_library_init_android(3)\fP function performs initializations +internally required by the c-ares library when used on Android. This can take +place anytime after \fIares_library_init(3)\fP. It must take place after +\fIares_library_init_jvm\fP. ares_library_init_android must be called before +DNS resolution will work on Android 8 (Oreo) or newer when targetSdkVersion is +set to 26+. + +As of Android 8 (API level 26) getting DNS server information has +becomei more restrictive and can only be accessed using the +Connectivity Manager. It is necessary to pass the connectivity +manager to c-ares via JNI. Also, the ACCESS_NETWORK_STATE permission +must be present in the Android application. + +Android older than 8 do not need to to be initialized as they +are less restrictive. However, this is a run time not compile time +limitation. Proper Android initialization should take place regardless +of the targeted Android version. + +Deinitialization will take place though \fIares_library_cleanup(3)\fP. + +The \fBares_library_init_jvm\fP function allows the caller to register the JVM +with c-ares. It's meant to be called during JNI_OnLoad because you're +guaranteed to have the JVM in that function. The JVM is required in order to +use the Connectivty Manager registered using +\fIares_library_init_android(3)\fP. This must be call before +\fIares_library_init_android(3)\fP. + +The \fBares_library_android_initialized\fP function can be used to check +whether c-ares has been initialized for use with Android. +.SH RETURN VALUES +ARES_SUCCESS will be returned on success otherwise an error code will be +returned. +.SH THREAD SAFETY +.B These init functions are not thread safe. +You have to call it once the program has started, but this call must be done +before the program starts any other thread. This is required to avoid +potential race conditions in library initialization, and also due to the fact +these might call functions from other libraries that +are thread unsafe, and could conflict with any other thread that is already +using these other libraries. +.SH JNI +Accessing the Connectivity Manager though Java: + +Register the \fIares_library_android_init\fP. +.nf + static JNINativeMethod funcs[] = { + { "initialize_native", "(Landroid/net/ConnectivityManager;)I", + (void *)&ares_library_init_android} + }; + + JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) + { + JNIEnv *env = NULL; + jclass cls = NULL; + jint res; + + if ((*vm)->GetEnv(vm, (void **)&env, JNI_VERSION_1_6) != JNI_OK) + return -1; + + cls = (*env)->FindClass(env, JNIT_CLASS); + if (cls == NULL) + return -1; + + res = (*env)->RegisterNatives(env, cls, funcs, sizeof(funcs)/sizeof(funcs[0])); + if (res != 0) + return -1; + + ares_library_init_jvm(vm); + return JNI_VERSION_1_6; + } +.fi +Calling the registered function from Java: +.nf + public class MyObject { + static { + System.loadLibrary("cares"); + } + + private static native boolean initialize_native(ConnectivityManager + connectivity_manager); + + public static boolean initialize(Context context) { + initialize_native((ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE)); + } + } +.fi +Initializing the Connectivity Manager in JNI directly using an Android +Context. It is assumed the JVM has aleady been registered through +\fIJNI_OnLoad\fP. +.nf + void initialize(jobject android_context) + { + jclass obj_cls = jni_get_class(env, "android/content/Context"); + jmethodID obj_mid = jni_get_method_id(env, obj_cls, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;"); + jfieldID fid = (*env)->GetStaticFieldID(env, obj_cls, "CONNECTIVITY_SERVICE", "Ljava/lang/String;"); + jstring str = (*env)->GetStaticObjectField(env, obj_cls, fid); + connectivity_manager = (*env)->CallObjectMethod(env, android_context, obj_mid, str); + if (connectivity_manager == NULL) + return; + ares_library_init_android(connectivity_manager); + } +.fi +.SH AVAILABILITY +This function was first introduced in c-ares version 1.15.0. +.SH SEE ALSO +.BR ares_library_init(3), +.BR ares_library_cleanup(3), +.SH AUTHOR +John Schember +.PP +Copyright (C) 2017 by John Schember + diff --git a/docs/ares_library_initialized.3 b/docs/ares_library_initialized.3 new file mode 100644 index 0000000..3e2727f --- /dev/null +++ b/docs/ares_library_initialized.3 @@ -0,0 +1,34 @@ +.\" +.\" Copyright (C) 2016 by Daniel Stenberg +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_LIBRARY_INITIALIZED 3 "29 Sep 2016" +.SH NAME +ares_library_initialized \- get the initialization state +.SH SYNOPSIS +.nf +#include + +int ares_library_initialized(void) +.fi +.SH DESCRIPTION +Returns information if c-ares needs to get initialized. +.SH RETURN VALUE +\fIARES_ENOTINITIALIZED\fP if not initialized and \fIARES_SUCCESS\fP if no +initialization is needed. +.SH AVAILABILITY +This function was first introduced in c-ares version 1.11.0 +.SH SEE ALSO +.BR ares_library_init(3), +.BR ares_library_cleanup(3) diff --git a/ares_mkquery.3 b/docs/ares_mkquery.3 similarity index 96% rename from ares_mkquery.3 rename to docs/ares_mkquery.3 index b2c90a9..c8afad8 100644 --- a/ares_mkquery.3 +++ b/docs/ares_mkquery.3 @@ -64,6 +64,13 @@ can return any of the following values: .B ARES_SUCCESS Construction of the DNS query succeeded. .TP 15 +.B ARES_ENOTFOUND +The query name +.I name +refers to a +.I .onion +domain name. See RFC 7686. +.TP 15 .B ARES_EBADNAME The query name .I name diff --git a/ares_parse_a_reply.3 b/docs/ares_parse_a_reply.3 similarity index 97% rename from ares_parse_a_reply.3 rename to docs/ares_parse_a_reply.3 index 8db8ed9..8e4908a 100644 --- a/ares_parse_a_reply.3 +++ b/docs/ares_parse_a_reply.3 @@ -75,4 +75,6 @@ Memory was exhausted. .SH AUTHOR Greg Hudson, MIT Information Systems .br +Andrew Selivanov +.br Copyright 1998 by the Massachusetts Institute of Technology. diff --git a/ares_parse_aaaa_reply.3 b/docs/ares_parse_aaaa_reply.3 similarity index 97% rename from ares_parse_aaaa_reply.3 rename to docs/ares_parse_aaaa_reply.3 index 476a3f1..674acc5 100644 --- a/ares_parse_aaaa_reply.3 +++ b/docs/ares_parse_aaaa_reply.3 @@ -76,3 +76,5 @@ Memory was exhausted. Dominick Meglio .br Copyright 2005 by Dominick Meglio. +.BR +Andrew Selivanov diff --git a/docs/ares_parse_caa_reply.3 b/docs/ares_parse_caa_reply.3 new file mode 100644 index 0000000..71bd6be --- /dev/null +++ b/docs/ares_parse_caa_reply.3 @@ -0,0 +1,171 @@ +.\" +.\" Copyright 2020 Danny Sonnenschein +.\" +.\" Permission to use, copy, modify, and distribute this +.\" software and its documentation for any purpose and without +.\" fee is hereby granted, provided that the above copyright +.\" notice appear in all copies and that both that copyright +.\" notice and this permission notice appear in supporting +.\" documentation, and that the name of M.I.T. not be used in +.\" advertising or publicity pertaining to distribution of the +.\" software without specific, written prior permission. +.\" M.I.T. makes no representations about the suitability of +.\" this software for any purpose. It is provided "as is" +.\" without express or implied warranty. +.\" +.TH ARES_PARSE_CAA_REPLY 3 "16 September 2020" +.SH NAME +ares_parse_caa_reply \- Parse a reply to a DNS query of type CAA +.SH SYNOPSIS +.nf +#include + +int ares_parse_caa_reply(const unsigned char* \fIabuf\fP, int \fIalen\fP, + struct ares_caa_reply **\fIcaa_out\fP); +.fi +.SH DESCRIPTION +The +.BR "ares_parse_caa_reply" +function parses the response to a query of type CAA into a +linked list (one element per sub-string) of +.IR "struct ares_caa_reply" +The parameters +.I abuf +and +.I alen +give the contents of the response. The result is stored in allocated +memory and a pointer to it stored into the variable pointed to by +.IR caa_out . +It is the caller's responsibility to free the resulting +.IR caa_out +structure when it is no longer needed using the function +.B ares_free_data(3) +.PP +The structure +.I ares_caa_reply(3) +contains the following fields: +.sp +.in +4n +.nf +struct ares_caa_reply { + struct ares_caa_reply *next; + int critical; + unsigned char *property; + size_t plength; /* plength excludes null */ + unsigned char *value; + size_t length; /* length excludes null */ +}; +.fi +.in +.PP +.SH RETURN VALUES +.BR "ares_parse_caa_reply" +can return any of the following values: +.TP 15 +.B ARES_SUCCESS +The response was successfully parsed. +.TP 15 +.B ARES_EBADRESP +The response was malformatted. +.TP 15 +.B ARES_ENODATA +The response did not contain an answer to the query. +.TP 15 +.B ARES_ENOMEM +Memory was exhausted. +.SH EXAMPLE +.nf +#include +#include +#include +#include + +#include +#include +#include + +#include "ares.h" + +static void dns_callback(void *arg, + int status, + int timeouts, + unsigned char *abuf, + int alen) + { + struct ares_caa_reply *caa_out; + int err; + + err = ares_parse_caa_reply (abuf, alen, &caa_out); + if (err == ARES_SUCCESS) + { + struct ares_caa_reply *caa_curr; + for (caa_curr=caa_out; caa_curr; caa_curr=caa_curr->next) + printf ("%s. CAA %i %s \\"%s\\"\\n", arg, + caa_curr->critical, + caa_curr->property, + caa_curr->value); + } + else + { + printf ("err=%i\\n", err); + } + ares_free_data (caa_out); + } + +static void main_loop(ares_channel *channel) + { + int nfds, count; + fd_set readers, writers; + struct timeval tv, *tvp; + while (1) + { + FD_ZERO (&readers); + FD_ZERO (&writers); + nfds = ares_fds (*channel, &readers, &writers); + if (nfds == 0) + break; + tvp = ares_timeout (*channel, NULL, &tv); + count = select (nfds, &readers, &writers, NULL, tvp); + ares_process (*channel, &readers, &writers); + } + } + +int main(int argc, char **argv) + { + const char *sversion; + int iversion; + int err; + + sversion = ares_version (&iversion); + printf ("c-ares version %s\\n", sversion); + + char *domain = "wikipedia.org"; + if (argc > 1) + domain = argv[1]; + + ares_channel channel; + if ((err = ares_init (&channel)) != ARES_SUCCESS) + { + printf ("ares_init() failed (%i)\\n", err); + exit (EXIT_FAILURE); + } + + ares_query (channel, domain, + 1, /* ns_c_in */ + 257, /* T_CAA */ + dns_callback, domain); + + main_loop (&channel); + + ares_destroy (channel); + + exit (EXIT_SUCCESS); + } +.fi +.SH AVAILABILITY +This function was first introduced in c-ares version 1.17.0. +.SH SEE ALSO +.BR ares_query (3) +.BR ares_free_data (3) +.SH AUTHOR +Written by Danny Sonnenschein , on behalf of platynum, https://platynum.ch diff --git a/ares_parse_mx_reply.3 b/docs/ares_parse_mx_reply.3 similarity index 100% rename from ares_parse_mx_reply.3 rename to docs/ares_parse_mx_reply.3 diff --git a/ares_parse_naptr_reply.3 b/docs/ares_parse_naptr_reply.3 similarity index 100% rename from ares_parse_naptr_reply.3 rename to docs/ares_parse_naptr_reply.3 diff --git a/ares_parse_ns_reply.3 b/docs/ares_parse_ns_reply.3 similarity index 100% rename from ares_parse_ns_reply.3 rename to docs/ares_parse_ns_reply.3 diff --git a/ares_parse_ptr_reply.3 b/docs/ares_parse_ptr_reply.3 similarity index 100% rename from ares_parse_ptr_reply.3 rename to docs/ares_parse_ptr_reply.3 diff --git a/ares_parse_soa_reply.3 b/docs/ares_parse_soa_reply.3 similarity index 100% rename from ares_parse_soa_reply.3 rename to docs/ares_parse_soa_reply.3 diff --git a/ares_parse_srv_reply.3 b/docs/ares_parse_srv_reply.3 similarity index 100% rename from ares_parse_srv_reply.3 rename to docs/ares_parse_srv_reply.3 diff --git a/ares_parse_txt_reply.3 b/docs/ares_parse_txt_reply.3 similarity index 100% rename from ares_parse_txt_reply.3 rename to docs/ares_parse_txt_reply.3 diff --git a/ares_process.3 b/docs/ares_process.3 similarity index 59% rename from ares_process.3 rename to docs/ares_process.3 index 7fb8371..caabbf1 100644 --- a/ares_process.3 +++ b/docs/ares_process.3 @@ -18,15 +18,15 @@ ares_process \- Process events for name resolution .SH SYNOPSIS .nf -.B #include -.PP -.B void ares_process(ares_channel \fIchannel\fP, fd_set *\fIread_fds\fP, -.B fd_set *\fIwrite_fds\fP) -.fi -.PP -.B void ares_process_fd(ares_channel \fIchannel\fP, -.B ares_socket_t \fIread_fd\fP, -.B ares_socket_t \fIwrite_fd\fP) +#include + +void ares_process(ares_channel \fIchannel\fP, + fd_set *\fIread_fds\fP, + fd_set *\fIwrite_fds\fP) + +void ares_process_fd(ares_channel \fIchannel\fP, + ares_socket_t \fIread_fd\fP, + ares_socket_t \fIwrite_fd\fP) .fi .SH DESCRIPTION The \fBares_process(3)\fP function handles input/output events and timeouts @@ -35,42 +35,41 @@ associated with queries pending on the name service channel identified by The file descriptor sets pointed to by \fIread_fds\fP and \fIwrite_fds\fP should have file descriptors set in them according to whether the file descriptors specified by \fIares_fds(3)\fP are ready for reading and writing. -(The easiest way to determine this information is to invoke -.B select -with a timeout no greater than the timeout given by \fIares_timeout(3)\fP ). -.PP -The -.B ares_process -function will invoke callbacks for pending queries if they complete -successfully or fail. +(The easiest way to determine this information is to invoke \fBselect(3)\fP +with a timeout no greater than the timeout given by \fIares_timeout(3)\fP). + +The \fBares_process(3)\fP function will invoke callbacks for pending queries +if they complete successfully or fail. \fBares_process_fd(3)\fP works the same way but acts and operates only on the specific file descriptors (sockets) you pass in to the function. Use -ARES_SOCKET_BAD for "no action". This function is of course provided to allow -users of c-ares to void select() in their applications and within c-ares. -.SS EXAMPLE +ARES_SOCKET_BAD for "no action". This function is provided to allow users of +c-ares to void \fIselect(3)\fP in their applications and within c-ares. + +To only process possible timeout conditions without a socket event occurring, +one may pass NULL as the values for both \fIread_fds\fP and \fIwrite_fds\fP for +\fBares_process(3)\fP, or ARES_SOCKET_BAD for both \fIread_fd\fP and +\fIwrite_fd\fP for \fBares_process_fd(3)\fP. +.SH EXAMPLE The following code fragment waits for all pending queries on a channel to complete: -.PP -.RS + .nf int nfds, count; fd_set readers, writers; struct timeval tv, *tvp; -while (1) - { - FD_ZERO(&readers); - FD_ZERO(&writers); - nfds = ares_fds(channel, &readers, &writers); - if (nfds == 0) - break; - tvp = ares_timeout(channel, NULL, &tv); - count = select(nfds, &readers, &writers, NULL, tvp); - ares_process(channel, &readers, &writers); - } +while (1) { + FD_ZERO(&readers); + FD_ZERO(&writers); + nfds = ares_fds(channel, &readers, &writers); + if (nfds == 0) + break; + tvp = ares_timeout(channel, NULL, &tv); + count = select(nfds, &readers, &writers, NULL, tvp); + ares_process(channel, &readers, &writers); +} .fi -.RE .SH SEE ALSO .BR ares_fds (3), .BR ares_timeout (3) diff --git a/ares_query.3 b/docs/ares_query.3 similarity index 100% rename from ares_query.3 rename to docs/ares_query.3 diff --git a/ares_save_options.3 b/docs/ares_save_options.3 similarity index 100% rename from ares_save_options.3 rename to docs/ares_save_options.3 diff --git a/ares_search.3 b/docs/ares_search.3 similarity index 100% rename from ares_search.3 rename to docs/ares_search.3 diff --git a/ares_send.3 b/docs/ares_send.3 similarity index 100% rename from ares_send.3 rename to docs/ares_send.3 diff --git a/ares_set_local_dev.3 b/docs/ares_set_local_dev.3 similarity index 96% rename from ares_set_local_dev.3 rename to docs/ares_set_local_dev.3 index f446888..7d82133 100644 --- a/ares_set_local_dev.3 +++ b/docs/ares_set_local_dev.3 @@ -31,8 +31,8 @@ for the option to work. If SO_BINDTODEVICE is not supported or the setsocktop call fails (probably because of permissions), the error is silently ignored. .SH SEE ALSO -.BR ares_set_local_ipv4 (3) -.BR ares_set_local_ipv6 (3) +.BR ares_set_local_ip4 (3) +.BR ares_set_local_ip6 (3) .SH NOTES This function was added in c-ares 1.7.4 .SH AUTHOR diff --git a/ares_set_local_ip4.3 b/docs/ares_set_local_ip4.3 similarity index 88% rename from ares_set_local_ip4.3 rename to docs/ares_set_local_ip4.3 index 82f5fae..e68e80e 100644 --- a/ares_set_local_ip4.3 +++ b/docs/ares_set_local_ip4.3 @@ -24,8 +24,8 @@ ares_set_local_ip4 \- Set local IPv4 address outgoing requests. .fi .SH DESCRIPTION The \fBares_set_local_ip4\fP function sets the IP address for outbound -requests. This allows users to specify outbound interfaces when used -on multi-homed systems. +requests. The parameter \fIlocal_ip\fP is specified in host byte order. This +allows users to specify outbound interfaces when used on multi-homed systems. .SH SEE ALSO .BR ares_set_local_ip6 (3) .SH NOTES diff --git a/ares_set_local_ip6.3 b/docs/ares_set_local_ip6.3 similarity index 84% rename from ares_set_local_ip6.3 rename to docs/ares_set_local_ip6.3 index cafa963..e659f5c 100644 --- a/ares_set_local_ip6.3 +++ b/docs/ares_set_local_ip6.3 @@ -24,8 +24,9 @@ ares_set_local_ip6 \- Set local IPv6 address outgoing requests. .fi .SH DESCRIPTION The \fBares_set_local_ip6\fP function sets the IPv6 address for outbound -IPv6 requests. This allows users to specify outbound interfaces when used -on multi-homed systems. The local_ip6 argument must be 16 bytes in length. +IPv6 requests. The parameter \fIlocal_ip6\fP is specified in network byte +order. This allows users to specify outbound interfaces when used on +multi-homed systems. The local_ip6 argument must be 16 bytes in length. .SH SEE ALSO .BR ares_set_local_ip4 (3) .SH NOTES diff --git a/ares_set_servers.3 b/docs/ares_set_servers.3 similarity index 97% rename from ares_set_servers.3 rename to docs/ares_set_servers.3 index a48c11c..65ad1e1 100644 --- a/ares_set_servers.3 +++ b/docs/ares_set_servers.3 @@ -72,6 +72,9 @@ was invalid. .TP 15 .B ARES_ENOTINITIALIZED c-ares library initialization not yet performed. +.TP 15 +.B ARES_ENOTIMP +Changing name servers configuration while queries are outstanding is not implemented. .SH SEE ALSO .BR ares_set_servers_csv (3), .BR ares_get_servers (3), diff --git a/ares_set_servers_csv.3 b/docs/ares_set_servers_csv.3 similarity index 96% rename from ares_set_servers_csv.3 rename to docs/ares_set_servers_csv.3 index cad2078..9679d58 100644 --- a/ares_set_servers_csv.3 +++ b/docs/ares_set_servers_csv.3 @@ -68,6 +68,9 @@ was invalid. .TP 15 .B ARES_ENOTINITIALIZED c-ares library initialization not yet performed. +.TP 15 +.B ARES_ENOTIMP +Changing name servers configuration while queries are outstanding is not implemented. .SH SEE ALSO .BR ares_set_servers (3) .SH AVAILABILITY diff --git a/ares_set_servers_ports.3 b/docs/ares_set_servers_ports.3 similarity index 100% rename from ares_set_servers_ports.3 rename to docs/ares_set_servers_ports.3 diff --git a/ares_set_servers_ports_csv.3 b/docs/ares_set_servers_ports_csv.3 similarity index 100% rename from ares_set_servers_ports_csv.3 rename to docs/ares_set_servers_ports_csv.3 diff --git a/ares_set_socket_callback.3 b/docs/ares_set_socket_callback.3 similarity index 100% rename from ares_set_socket_callback.3 rename to docs/ares_set_socket_callback.3 diff --git a/ares_set_socket_configure_callback.3 b/docs/ares_set_socket_configure_callback.3 similarity index 100% rename from ares_set_socket_configure_callback.3 rename to docs/ares_set_socket_configure_callback.3 diff --git a/docs/ares_set_socket_functions.3 b/docs/ares_set_socket_functions.3 new file mode 100644 index 0000000..1cb0b85 --- /dev/null +++ b/docs/ares_set_socket_functions.3 @@ -0,0 +1,99 @@ +.\" +.TH ARES_SET_SOCKET_FUNCTIONS 3 "13 Dec 2016" +.SH NAME +ares_set_socket_functions \- Set socket io callbacks +.SH SYNOPSIS +.nf +.B #include +.PP +.B struct ares_socket_functions { + ares_socket_t(*\fIasocket\fP)(int, int, int, void *); + int(*\fIaclose\fP)(ares_socket_t, void *); + int(*\fIaconnect\fP)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *); + ares_ssize_t(*\fIarecvfrom\fP)(ares_socket_t, void *, size_t, int, struct sockaddr *, ares_socklen_t *, void *); + ares_ssize_t(*\fIasendv\fP)(ares_socket_t, const struct iovec *, int, void *); + }; + +.PP +.B void ares_set_socket_functions(ares_channel \fIchannel\fP, + const struct ares_socket_functions * \fIfunctions\fP, + void *\fIuser_data\fP); + +.fi +.SH DESCRIPTION +.PP +This function sets a set of callback \fIfunctions\fP in the given ares channel handle. +These callback functions will be invoked to create/destroy socket objects and perform +io, instead of the normal system calls. A client application can override normal network +operation fully through this functionality, and provide its own transport layer. +.PP +All callback functions are expected to operate like their system equivalents, and to +set +.BR errno(3) +to an appropriate error code on failure. C-ares also expects all io functions to behave +asynchronously, i.e. as if the socket object has been set to non-blocking mode. Thus +read/write calls (for TCP connections) are expected to often generate +.BR EAGAIN +or +.BR EWOULDBLOCK. + +.PP +The \fIuser_data\fP value is provided to each callback function invocation to serve as +context. +.PP +The +.B ares_socket_functions +must provide the following callbacks: +.TP 18 +.B \fIasocket\fP +.B ares_socket_t(*)(int \fIdomain\fP, int \fItype\fP, int \fIprotocol\fP, void * \fIuser_data\fP) +.br +Creates an endpoint for communication and returns a descriptor. \fIdomain\fP, \fItype\fP, and \fIprotocol\fP +each correspond to the parameters of +.BR socket(2). +Returns ahandle to the newly created socket, or -1 on error. +.TP 18 +.B \fIaclose\fP +.B int(*)(ares_socket_t \fIfd\fP, void * \fIuser_data\fP) +.br +Closes the socket endpoint indicated by \fIfd\fP. See +.BR close(2) +.TP 18 +.B \fIaconnect\fP +.B int(*)(ares_socket_t \fIfd\fP, const struct sockaddr * \fIaddr\fP, ares_socklen_t \fIaddr_len\fP, void * \fIuser_data\fP) +.br +Initiate a connection to the address indicated by \fIaddr\fP on a socket. See +.BR connect(2) + +.TP 18 +.B \fIarecvfrom\fP +.B ares_ssize_t(*)(ares_socket_t \fIfd\fP, void * \fIbuffer\fP, size_t \fIbuf_size\fP, int \fIflags\fP, struct sockaddr * \fIaddr\fP, ares_socklen_t * \fIaddr_len\fP, void * \fIuser_data\fP) +.br +Receives data from remote socket endpoint, if available. If the \fIaddr\fP parameter is not NULL and the connection protocol provides the source address, the callback should fill this in. See +.BR recvfrom(2) + +.TP 18 +.B \fIasendv\fP +.B ares_ssize_t(*)(ares_socket_t \fIfd\fP, const struct iovec * \fIdata\fP, int \fIlen\fP, void * \fIuser_data\fP) +.br +Send data, as provided by the iovec array \fIdata\fP, to the socket endpoint. See +.BR writev(2), + +.PP +The +.B ares_socket_functions +struct provided is not copied but directly referenced, +and must thus remain valid through out the channels and any created socket's lifetime. +.SH AVAILABILITY +Added in c-ares 1.13.0 +.SH SEE ALSO +.BR ares_init_options (3), +.BR socket(2), +.BR close(2), +.BR connect(2), +.BR recv(2), +.BR recvfrom(2), +.BR send(2), +.BR writev(2) +.SH AUTHOR +Carl Wilund diff --git a/ares_set_sortlist.3 b/docs/ares_set_sortlist.3 similarity index 100% rename from ares_set_sortlist.3 rename to docs/ares_set_sortlist.3 diff --git a/ares_strerror.3 b/docs/ares_strerror.3 similarity index 100% rename from ares_strerror.3 rename to docs/ares_strerror.3 diff --git a/ares_timeout.3 b/docs/ares_timeout.3 similarity index 57% rename from ares_timeout.3 rename to docs/ares_timeout.3 index acf8f74..c57685d 100644 --- a/ares_timeout.3 +++ b/docs/ares_timeout.3 @@ -18,43 +18,28 @@ ares_timeout \- return maximum time to wait .SH SYNOPSIS .nf -.B #include -.PP -.B struct timeval *ares_timeout(ares_channel \fIchannel\fP, -.B struct timeval *\fImaxtv\fP, struct timeval *\fItv\fP) +#include + +struct timeval *ares_timeout(ares_channel \fIchannel\fP, + struct timeval *\fImaxtv\fP, + struct timeval *\fItv\fP) .fi .SH DESCRIPTION -The -.B ares_timeout -function determines the maximum time for which the caller should wait before -invoking \fIares_process(3)\fP to process timeouts. The parameter -.I maxtv -specifies a existing maximum timeout, or -.B NULL +The \fBares_timeout(3)\fP function determines the maximum time for which the +caller should wait before invoking \fIares_process(3)\fP to process timeouts. +The parameter \fImaxtv\fP specifies a existing maximum timeout, or \fBNULL\fP if the caller does not wish to apply a maximum timeout. The parameter -.I tv -must point to a writable buffer of type -.BR "struct timeval" . -It is valid for -.I maxtv -and -.I tv -to have the same value. -.PP -If no queries have timeouts pending sooner than the given maximum -timeout, -.B ares_timeout -returns the value of -.IR maxtv; -otherwise -.B ares_timeout -stores the appropriate timeout value into the buffer pointed to by -.I tv -and returns the value of -.IR tv . +\fItv\fP must point to a writable buffer of type \fBstruct timeval\fP It is +valid for \fImaxtv\fP and \fItv\fP to have the same value. + +If no queries have timeouts pending sooner than the given maximum timeout, +\fBares_timeout(3)\fP returns the value of \fImaxtv\fP; otherwise +\fBares_timeout(3)\fP stores the appropriate timeout value into the buffer +pointed to by \fItv\fP and returns the value of \fItv\fP. .SH SEE ALSO .BR ares_fds (3), -.BR ares_process (3) +.BR ares_process (3), +.BR ares_process_fd (3) .SH AUTHOR Greg Hudson, MIT Information Systems .br diff --git a/ares_version.3 b/docs/ares_version.3 similarity index 75% rename from ares_version.3 rename to docs/ares_version.3 index 49b1302..9ba7831 100644 --- a/ares_version.3 +++ b/docs/ares_version.3 @@ -18,23 +18,18 @@ ares_version \- Get the version number of the library .SH SYNOPSIS .nf -.B #include -.PP -.B const char *ares_version(int *\fIversion\fP) +#include + +const char *ares_version(int *\fIversion\fP) .fi .SH DESCRIPTION -The -.B ares_version -function gets the library version as a string and optionally as an integer -stored in the -.IR version , -argument. If you pass a NULL, no integer is attempted to be returned. +The \fBares_version(3)\fP function gets the library version as a string and +optionally as an integer stored in the \fIversion\fP argument. If you pass a +NULL, no integer is attempted to be returned. The integer is built up as 24bit number, with 8 separate bits used for major number, minor number and patch number. This makes a version string such as 1.2.3 will be returned as the hexadecimal number 0x010203 (decimal 66051). -.SH NOTES -This function is not compatible with ares. -.SH AUTHOR -Daniel Stenberg - +.SH "SEE ALSO" +.BR ares_init (3), +.BR ares_library_init (3) diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt new file mode 100644 index 0000000..439e7bb --- /dev/null +++ b/include/CMakeLists.txt @@ -0,0 +1,8 @@ +# Write ares_build.h configuration file. This is an installed file. +CONFIGURE_FILE (ares_build.h.cmake ${PROJECT_BINARY_DIR}/ares_build.h) + +# Headers installation target +IF (CARES_INSTALL) + SET (CARES_HEADERS ares.h ares_version.h "${PROJECT_BINARY_DIR}/ares_build.h" ares_rules.h ares_dns.h) + INSTALL (FILES ${CARES_HEADERS} COMPONENT Devel DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +ENDIF () diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 0000000..125a686 --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,7 @@ +AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install + +# what headers to install on 'make install': +include_HEADERS = ares.h ares_version.h ares_build.h ares_rules.h ares_dns.h + +EXTRA_DIST = ares_build.h.cmake ares_build.h.in ares_build.h.dist CMakeLists.txt diff --git a/include/Makefile.in b/include/Makefile.in new file mode 100644 index 0000000..8a88efe --- /dev/null +++ b/include/Makefile.in @@ -0,0 +1,615 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/m4/cares-compilers.m4 \ + $(top_srcdir)/m4/cares-confopts.m4 \ + $(top_srcdir)/m4/cares-functions.m4 \ + $(top_srcdir)/m4/cares-override.m4 \ + $(top_srcdir)/m4/cares-reentrant.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(include_HEADERS) \ + $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/lib/ares_config.h ares_build.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(includedir)" +HEADERS = $(include_HEADERS) +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + ares_build.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/ares_build.h.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ +CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ +CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install + +# what headers to install on 'make install': +include_HEADERS = ares.h ares_version.h ares_build.h ares_rules.h ares_dns.h +EXTRA_DIST = ares_build.h.cmake ares_build.h.in ares_build.h.dist CMakeLists.txt +all: ares_build.h + $(MAKE) $(AM_MAKEFLAGS) all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +ares_build.h: stamp-h2 + @test -f $@ || rm -f stamp-h2 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h2 + +stamp-h2: $(srcdir)/ares_build.h.in $(top_builddir)/config.status + @rm -f stamp-h2 + cd $(top_builddir) && $(SHELL) ./config.status include/ares_build.h + +distclean-hdr: + -rm -f ares_build.h stamp-h2 + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + if test -n "$$list"; then \ + echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \ + fi; \ + for p in $$list; do \ + if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir) + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(HEADERS) ares_build.h +installdirs: + for dir in "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-hdr distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: install-includeHEADERS + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: uninstall-includeHEADERS + +.MAKE: all install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ + clean-libtool cscopelist-am ctags ctags-am distclean \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-includeHEADERS install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-includeHEADERS + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/ares.h b/include/ares.h similarity index 86% rename from ares.h rename to include/ares.h index cbd30f6..70a1baf 100644 --- a/ares.h +++ b/include/ares.h @@ -38,7 +38,8 @@ require it! */ #if defined(_AIX) || defined(__NOVELL_LIBC__) || defined(__NetBSD__) || \ defined(__minix) || defined(__SYMBIAN32__) || defined(__INTEGRITY) || \ - defined(ANDROID) || defined(__ANDROID__) + defined(ANDROID) || defined(__ANDROID__) || defined(__OpenBSD__) || \ + defined(__QNXNTO__) #include #endif #if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) @@ -67,6 +68,10 @@ # include #endif +#if defined(ANDROID) || defined(__ANDROID__) +#include +#endif + #ifdef __cplusplus extern "C" { #endif @@ -130,6 +135,9 @@ extern "C" { /* More error codes */ #define ARES_ECANCELLED 24 /* introduced in 1.7.0 */ +/* More ares_getaddrinfo error codes */ +#define ARES_ESERVICE 25 /* introduced in 1.?.0 */ + /* Flag values */ #define ARES_FLAG_USEVC (1 << 0) #define ARES_FLAG_PRIMARY (1 << 1) @@ -159,6 +167,7 @@ extern "C" { #define ARES_OPT_ROTATE (1 << 14) #define ARES_OPT_EDNSPSZ (1 << 15) #define ARES_OPT_NOROTATE (1 << 16) +#define ARES_OPT_RESOLVCONF (1 << 17) /* Nameinfo flag values */ #define ARES_NI_NOFQDN (1 << 0) @@ -186,6 +195,8 @@ extern "C" { #define ARES_AI_V4MAPPED (1 << 4) #define ARES_AI_ALL (1 << 5) #define ARES_AI_ADDRCONFIG (1 << 6) +#define ARES_AI_NOSORT (1 << 7) +#define ARES_AI_ENVHOSTS (1 << 8) /* Reserved for future use */ #define ARES_AI_IDN (1 << 10) #define ARES_AI_IDN_ALLOW_UNASSIGNED (1 << 11) @@ -265,12 +276,15 @@ struct ares_options { struct apattern *sortlist; int nsort; int ednspsz; + char *resolvconf_path; }; struct hostent; struct timeval; struct sockaddr; struct ares_channeldata; +struct ares_addrinfo; +struct ares_addrinfo_hints; typedef struct ares_channeldata *ares_channel; @@ -299,6 +313,11 @@ typedef int (*ares_sock_config_callback)(ares_socket_t socket_fd, int type, void *data); +typedef void (*ares_addrinfo_callback)(void *arg, + int status, + int timeouts, + struct ares_addrinfo *res); + CARES_EXTERN int ares_library_init(int flags); CARES_EXTERN int ares_library_init_mem(int flags, @@ -306,6 +325,12 @@ CARES_EXTERN int ares_library_init_mem(int flags, void (*afree)(void *ptr), void *(*arealloc)(void *ptr, size_t size)); +#if defined(ANDROID) || defined(__ANDROID__) +CARES_EXTERN void ares_library_init_jvm(JavaVM *jvm); +CARES_EXTERN int ares_library_init_android(jobject connectivity_manager); +CARES_EXTERN int ares_library_android_initialized(void); +#endif + CARES_EXTERN int ares_library_initialized(void); CARES_EXTERN void ares_library_cleanup(void); @@ -356,6 +381,36 @@ CARES_EXTERN void ares_set_socket_configure_callback(ares_channel channel, CARES_EXTERN int ares_set_sortlist(ares_channel channel, const char *sortstr); +CARES_EXTERN void ares_getaddrinfo(ares_channel channel, + const char* node, + const char* service, + const struct ares_addrinfo_hints* hints, + ares_addrinfo_callback callback, + void* arg); + +CARES_EXTERN void ares_freeaddrinfo(struct ares_addrinfo* ai); + +/* + * Virtual function set to have user-managed socket IO. + * Note that all functions need to be defined, and when + * set, the library will not do any bind nor set any + * socket options, assuming the client handles these + * through either socket creation or the + * ares_sock_config_callback call. + */ +struct iovec; +struct ares_socket_functions { + ares_socket_t(*asocket)(int, int, int, void *); + int(*aclose)(ares_socket_t, void *); + int(*aconnect)(ares_socket_t, const struct sockaddr *, ares_socklen_t, void *); + ares_ssize_t(*arecvfrom)(ares_socket_t, void *, size_t, int, struct sockaddr *, ares_socklen_t *, void *); + ares_ssize_t(*asendv)(ares_socket_t, const struct iovec *, int, void *); +}; + +CARES_EXTERN void ares_set_socket_functions(ares_channel channel, + const struct ares_socket_functions * funcs, + void *user_data); + CARES_EXTERN void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, @@ -473,6 +528,15 @@ struct ares_addr6ttl { int ttl; }; +struct ares_caa_reply { + struct ares_caa_reply *next; + int critical; + unsigned char *property; + size_t plength; /* plength excludes null termination */ + unsigned char *value; + size_t length; /* length excludes null termination */ +}; + struct ares_srv_reply { struct ares_srv_reply *next; char *host; @@ -524,6 +588,44 @@ struct ares_soa_reply { unsigned int minttl; }; +/* + * Similar to addrinfo, but with extra ttl and missing canonname. + */ +struct ares_addrinfo_node { + int ai_ttl; + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + ares_socklen_t ai_addrlen; + struct sockaddr *ai_addr; + struct ares_addrinfo_node *ai_next; +}; + +/* + * alias - label of the resource record. + * name - value (canonical name) of the resource record. + * See RFC2181 10.1.1. CNAME terminology. + */ +struct ares_addrinfo_cname { + int ttl; + char *alias; + char *name; + struct ares_addrinfo_cname *next; +}; + +struct ares_addrinfo { + struct ares_addrinfo_cname *cnames; + struct ares_addrinfo_node *nodes; +}; + +struct ares_addrinfo_hints { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; +}; + /* ** Parse the buffer, starting at *abuf and of length alen bytes, previously ** obtained from an ares_search call. Put the results in *host, if nonnull. @@ -544,6 +646,10 @@ CARES_EXTERN int ares_parse_aaaa_reply(const unsigned char *abuf, struct ares_addr6ttl *addrttls, int *naddrttls); +CARES_EXTERN int ares_parse_caa_reply(const unsigned char* abuf, + int alen, + struct ares_caa_reply** caa_out); + CARES_EXTERN int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, diff --git a/ares_build.h b/include/ares_build.h similarity index 95% rename from ares_build.h rename to include/ares_build.h index 9a865e3..5e3ba9f 100644 --- a/ares_build.h +++ b/include/ares_build.h @@ -191,4 +191,17 @@ typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; #endif +/* Data type definition of ares_ssize_t. */ +#ifdef _WIN32 +# ifdef _WIN64 +# define CARES_TYPEOF_ARES_SSIZE_T __int64 +# else +# define CARES_TYPEOF_ARES_SSIZE_T long +# endif +#else +# define CARES_TYPEOF_ARES_SSIZE_T ssize_t +#endif + +typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; + #endif /* __CARES_BUILD_H */ diff --git a/include/ares_build.h.cmake b/include/ares_build.h.cmake new file mode 100644 index 0000000..ac32d47 --- /dev/null +++ b/include/ares_build.h.cmake @@ -0,0 +1,41 @@ +#ifndef __CARES_BUILD_H +#define __CARES_BUILD_H + +#define CARES_TYPEOF_ARES_SOCKLEN_T @CARES_TYPEOF_ARES_SOCKLEN_T@ +#define CARES_TYPEOF_ARES_SSIZE_T @CARES_TYPEOF_ARES_SSIZE_T@ + +/* Prefix names with CARES_ to make sure they don't conflict with other config.h + * files. We need to include some dependent headers that may be system specific + * for C-Ares */ +#cmakedefine CARES_HAVE_SYS_TYPES_H +#cmakedefine CARES_HAVE_SYS_SOCKET_H +#cmakedefine CARES_HAVE_WINDOWS_H +#cmakedefine CARES_HAVE_WS2TCPIP_H +#cmakedefine CARES_HAVE_WINSOCK2_H +#cmakedefine CARES_HAVE_WINDOWS_H + +#ifdef CARES_HAVE_SYS_TYPES_H +# include +#endif + +#ifdef CARES_HAVE_SYS_SOCKET_H +# include +#endif + +#ifdef CARES_HAVE_WINSOCK2_H +# include +#endif + +#ifdef CARES_HAVE_WS2TCPIP_H +# include +#endif + +#ifdef CARES_HAVE_WINDOWS_H +# include +#endif + + +typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; +typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; + +#endif /* __CARES_BUILD_H */ diff --git a/ares_build.h.in b/include/ares_build.h.in similarity index 95% rename from ares_build.h.in rename to include/ares_build.h.in index e582523..24e3a98 100644 --- a/ares_build.h.in +++ b/include/ares_build.h.in @@ -91,4 +91,10 @@ /* Data type definition of ares_socklen_t. */ typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t; +/* Integral data type used for ares_ssize_t. */ +#undef CARES_TYPEOF_ARES_SSIZE_T + +/* Data type definition of ares_ssize_t. */ +typedef CARES_TYPEOF_ARES_SSIZE_T ares_ssize_t; + #endif /* __CARES_BUILD_H */ diff --git a/ares_dns.h b/include/ares_dns.h similarity index 95% rename from ares_dns.h rename to include/ares_dns.h index 79f993b..bc8aa7b 100644 --- a/ares_dns.h +++ b/include/ares_dns.h @@ -16,6 +16,15 @@ * without express or implied warranty. */ +/* + * NOTE TO INTEGRATORS: + * + * This header is made public due to legacy projects relying on it. + * Please do not use the macros within this header, or include this + * header in your project as it may be removed in the future. + */ + + /* * Macro DNS__16BIT reads a network short (16 bit) given in network * byte order, and returns its value as an unsigned short. diff --git a/ares_rules.h b/include/ares_rules.h similarity index 98% rename from ares_rules.h rename to include/ares_rules.h index e617fdc..cac23cf 100644 --- a/ares_rules.h +++ b/include/ares_rules.h @@ -83,7 +83,7 @@ /* * Verify that the size previously defined and expected for - * ares_socklen_t is actually the the same as the one reported + * ares_socklen_t is actually the same as the one reported * by sizeof() at compile time. */ diff --git a/ares_version.h b/include/ares_version.h similarity index 75% rename from ares_version.h rename to include/ares_version.h index 92c8584..0bee17d 100644 --- a/ares_version.h +++ b/include/ares_version.h @@ -3,15 +3,15 @@ #define ARES__VERSION_H /* This is the global package copyright */ -#define ARES_COPYRIGHT "2004 - 2016 Daniel Stenberg, ." +#define ARES_COPYRIGHT "2004 - 2020 Daniel Stenberg, ." #define ARES_VERSION_MAJOR 1 -#define ARES_VERSION_MINOR 12 -#define ARES_VERSION_PATCH 0 +#define ARES_VERSION_MINOR 17 +#define ARES_VERSION_PATCH 1 #define ARES_VERSION ((ARES_VERSION_MAJOR<<16)|\ (ARES_VERSION_MINOR<<8)|\ (ARES_VERSION_PATCH)) -#define ARES_VERSION_STR "1.12.0" +#define ARES_VERSION_STR "1.17.1" #if (ARES_VERSION >= 0x010700) # define CARES_HAVE_ARES_LIBRARY_INIT 1 diff --git a/install-sh b/install-sh index 377bb86..20d8b2e 100755 --- a/install-sh +++ b/install-sh @@ -1,7 +1,7 @@ #!/bin/sh # install - install a program, script, or datafile -scriptversion=2011-11-20.07; # UTC +scriptversion=2018-03-11.20; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -41,19 +41,15 @@ scriptversion=2011-11-20.07; # UTC # This script is compatible with the BSD install script, but was written # from scratch. +tab=' ' nl=' ' -IFS=" "" $nl" +IFS=" $tab$nl" -# set DOITPROG to echo to test this script +# Set DOITPROG to "echo" to test this script. -# Don't use :- since 4.3BSD and earlier shells don't like it. doit=${DOITPROG-} -if test -z "$doit"; then - doit_exec=exec -else - doit_exec=$doit -fi +doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. @@ -68,17 +64,6 @@ mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} -posix_glob='?' -initialize_posix_glob=' - test "$posix_glob" != "?" || { - if (set -f) 2>/dev/null; then - posix_glob= - else - posix_glob=: - fi - } -' - posix_mkdir= # Desired mode of installed file. @@ -97,7 +82,7 @@ dir_arg= dst_arg= copy_on_change=false -no_target_directory= +is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE @@ -137,46 +122,57 @@ while test $# -ne 0; do -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" - shift;; + shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 - case $mode in - *' '* | *' '* | *' -'* | *'*'* | *'?'* | *'['*) - echo "$0: invalid mode: $mode" >&2 - exit 1;; - esac - shift;; + case $mode in + *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) + echo "$0: invalid mode: $mode" >&2 + exit 1;; + esac + shift;; -o) chowncmd="$chownprog $2" - shift;; + shift;; -s) stripcmd=$stripprog;; - -t) dst_arg=$2 - # Protect names problematic for 'test' and other utilities. - case $dst_arg in - -* | [=\(\)!]) dst_arg=./$dst_arg;; - esac - shift;; + -t) + is_target_a_directory=always + dst_arg=$2 + # Protect names problematic for 'test' and other utilities. + case $dst_arg in + -* | [=\(\)!]) dst_arg=./$dst_arg;; + esac + shift;; - -T) no_target_directory=true;; + -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; - --) shift - break;; + --) shift + break;; - -*) echo "$0: invalid option: $1" >&2 - exit 1;; + -*) echo "$0: invalid option: $1" >&2 + exit 1;; *) break;; esac shift done +# We allow the use of options -d and -T together, by making -d +# take the precedence; this is for compatibility with GNU install. + +if test -n "$dir_arg"; then + if test -n "$dst_arg"; then + echo "$0: target directory not allowed when installing a directory." >&2 + exit 1 + fi +fi + if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. @@ -207,6 +203,15 @@ if test $# -eq 0; then exit 0 fi +if test -z "$dir_arg"; then + if test $# -gt 1 || test "$is_target_a_directory" = always; then + if test ! -d "$dst_arg"; then + echo "$0: $dst_arg: Is not a directory." >&2 + exit 1 + fi + fi +fi + if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 @@ -223,16 +228,16 @@ if test -z "$dir_arg"; then *[0-7]) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw='% 200' + u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then - u_plus_rw= + u_plus_rw= else - u_plus_rw=,u+rw + u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac @@ -266,122 +271,113 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then - if test -n "$no_target_directory"; then - echo "$0: $dst_arg: Is a directory" >&2 - exit 1 + if test "$is_target_a_directory" = never; then + echo "$0: $dst_arg: Is a directory" >&2 + exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else - # Prefer dirname, but fall back on a substitute if dirname fails. - dstdir=` - (dirname "$dst") 2>/dev/null || - expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$dst" : 'X\(//\)[^/]' \| \ - X"$dst" : 'X\(//\)$' \| \ - X"$dst" : 'X\(/\)' \| . 2>/dev/null || - echo X"$dst" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q' - ` - + dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - - # With -d, create the new directory with the user-specified mode. - # Otherwise, rely on $mkdir_umask. - if test -n "$dir_arg"; then - mkdir_mode=-m$mode - else - mkdir_mode= - fi - - posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # Create intermediate dirs using mode 755 as modified by the umask. + # This is like FreeBSD 'install' as of 1997-10-28. + umask=`umask` + case $stripcmd.$umask in + # Optimize common cases. + *[2367][2367]) mkdir_umask=$umask;; + .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; + + *[0-7]) + mkdir_umask=`expr $umask + 22 \ + - $umask % 100 % 40 + $umask % 20 \ + - $umask % 10 % 4 + $umask % 2 + `;; + *) mkdir_umask=$umask,go-w;; + esac + + # With -d, create the new directory with the user-specified mode. + # Otherwise, rely on $mkdir_umask. + if test -n "$dir_arg"; then + mkdir_mode=-m$mode + else + mkdir_mode= + fi + + posix_mkdir=false + case $umask in + *[123567][0-7][0-7]) + # POSIX mkdir -p sets u+wx bits regardless of umask, which + # is incompatible with FreeBSD 'install' when (umask & 300) != 0. + ;; + *) + # Note that $RANDOM variable is not portable (e.g. dash); Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writeable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p' feature. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibilities with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; + esac;; esac if $posix_mkdir && ( - umask $mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" + umask $mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else @@ -391,53 +387,51 @@ do # directory the slow way, step by step, checking for races as we go. case $dstdir in - /*) prefix='/';; - [-=\(\)!]*) prefix='./';; - *) prefix='';; + /*) prefix='/';; + [-=\(\)!]*) prefix='./';; + *) prefix='';; esac - eval "$initialize_posix_glob" - oIFS=$IFS IFS=/ - $posix_glob set -f + set -f set fnord $dstdir shift - $posix_glob set +f + set +f IFS=$oIFS prefixes= for d do - test X"$d" = X && continue - - prefix=$prefix$d - if test -d "$prefix"; then - prefixes= - else - if $posix_mkdir; then - (umask=$mkdir_umask && - $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break - # Don't fail if two instances are running concurrently. - test -d "$prefix" || exit 1 - else - case $prefix in - *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; - *) qprefix=$prefix;; - esac - prefixes="$prefixes '$qprefix'" - fi - fi - prefix=$prefix/ + test X"$d" = X && continue + + prefix=$prefix$d + if test -d "$prefix"; then + prefixes= + else + if $posix_mkdir; then + (umask=$mkdir_umask && + $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break + # Don't fail if two instances are running concurrently. + test -d "$prefix" || exit 1 + else + case $prefix in + *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; + *) qprefix=$prefix;; + esac + prefixes="$prefixes '$qprefix'" + fi + fi + prefix=$prefix/ done if test -n "$prefixes"; then - # Don't fail if two instances are running concurrently. - (umask $mkdir_umask && - eval "\$doit_exec \$mkdirprog $prefixes") || - test -d "$dstdir" || exit 1 - obsolete_mkdir_used=true + # Don't fail if two instances are running concurrently. + (umask $mkdir_umask && + eval "\$doit_exec \$mkdirprog $prefixes") || + test -d "$dstdir" || exit 1 + obsolete_mkdir_used=true fi fi fi @@ -450,14 +444,25 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -472,15 +477,12 @@ do # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && - old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && - new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && - - eval "$initialize_posix_glob" && - $posix_glob set -f && + old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && + new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && + set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && - $posix_glob set +f && - + set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then @@ -493,24 +495,24 @@ do # to itself, or perhaps because mv is so ancient that it does not # support -f. { - # Now remove or move aside any old file at destination location. - # We try this two ways since rm can't unlink itself on some - # systems and the destination file might be busy for other - # reasons. In this case, the final cleanup might fail but the new - # file should still install successfully. - { - test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || - { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } - } || - { echo "$0: cannot unlink or rename $dst" >&2 - (exit 1); exit 1 - } - } && - - # Now rename the file to the real destination. - $doit $mvcmd "$dsttmp" "$dst" + # Now remove or move aside any old file at destination location. + # We try this two ways since rm can't unlink itself on some + # systems and the destination file might be busy for other + # reasons. In this case, the final cleanup might fail but the new + # file should still install successfully. + { + test ! -f "$dst" || + $doit $rmcmd -f "$dst" 2>/dev/null || + { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && + { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + } || + { echo "$0: cannot unlink or rename $dst" >&2 + (exit 1); exit 1 + } + } && + + # Now rename the file to the real destination. + $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 @@ -519,9 +521,9 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/libcares.pc.cmake b/libcares.pc.cmake new file mode 100644 index 0000000..d5532d5 --- /dev/null +++ b/libcares.pc.cmake @@ -0,0 +1,20 @@ +#*************************************************************************** +# Project ___ __ _ _ __ ___ ___ +# / __|____ / _` | '__/ _ \/ __| +# | (_|_____| (_| | | | __/\__ \ +# \___| \__,_|_| \___||___/ +# +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix}/@CMAKE_INSTALL_BINDIR@ +libdir=${prefix}/@CMAKE_INSTALL_LIBDIR@ +includedir=${prefix}/@CMAKE_INSTALL_INCLUDEDIR@ + +Name: c-ares +URL: https://c-ares.haxx.se/ +Description: asynchronous DNS lookup library +Version: @CARES_VERSION@ +Requires: +Requires.private: +Cflags: -I${includedir} @CPPFLAG_CARES_STATICLIB@ +Libs: -L${libdir} -lcares +Libs.private: @CARES_PRIVATE_LIBS@ diff --git a/ltmain.sh b/ltmain.sh index 147d758..0cb7f90 100644 --- a/ltmain.sh +++ b/ltmain.sh @@ -31,7 +31,7 @@ PROGRAM=libtool PACKAGE=libtool -VERSION="2.4.6 Debian-2.4.6-0.1" +VERSION="2.4.6 Debian-2.4.6-14" package_revision=2.4.6 @@ -387,7 +387,7 @@ EXIT_SKIP=77 # $? = 77 is used to indicate a skipped test to automake. # putting '$debug_cmd' at the start of all your functions, you can get # bash to show function call trace with: # -# debug_cmd='eval echo "${FUNCNAME[0]} $*" >&2' bash your-script-name +# debug_cmd='echo "${FUNCNAME[0]} $*" >&2' bash your-script-name debug_cmd=${debug_cmd-":"} exit_cmd=: @@ -1370,7 +1370,7 @@ func_lt_ver () #! /bin/sh # Set a version string for this script. -scriptversion=2014-01-07.03; # UTC +scriptversion=2015-10-07.11; # UTC # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 @@ -1530,6 +1530,8 @@ func_run_hooks () { $debug_cmd + _G_rc_run_hooks=false + case " $hookable_fns " in *" $1 "*) ;; *) func_fatal_error "'$1' does not support hook funcions.n" ;; @@ -1538,16 +1540,16 @@ func_run_hooks () eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift + if eval $_G_hook '"$@"'; then + # store returned options list back into positional + # parameters for next 'cmd' execution. + eval _G_hook_result=\$${_G_hook}_result + eval set dummy "$_G_hook_result"; shift + _G_rc_run_hooks=: + fi done - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result + $_G_rc_run_hooks && func_run_hooks_result=$_G_hook_result } @@ -1557,10 +1559,16 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed +# full positional parameter list in your hook function, you may remove/edit +# any options that you action, and then pass back the remaining unprocessed # options in '_result', escaped suitably for -# 'eval'. Like this: +# 'eval'. In this case you also must return $EXIT_SUCCESS to let the +# hook's caller know that it should pay attention to +# '_result'. Returning $EXIT_FAILURE signalizes that +# arguments are left untouched by the hook and therefore caller will ignore the +# result variable. +# +# Like this: # # my_options_prep () # { @@ -1570,9 +1578,11 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result +# # No change in '$@' (ignored completely by this hook). There is +# # no need to do the equivalent (but slower) action: +# # func_quote_for_eval ${1+"$@"} +# # my_options_prep_result=$func_quote_for_eval_result +# false # } # func_add_hook func_options_prep my_options_prep # @@ -1581,25 +1591,37 @@ func_run_hooks () # { # $debug_cmd # +# args_changed=false +# # # Note that for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in -# --silent|-s) opt_silent=: ;; +# --silent|-s) opt_silent=: +# args_changed=: +# ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift +# args_changed=: # ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@", we could need that later +# # if $args_changed is true. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result +# if $args_changed; then +# func_quote_for_eval ${1+"$@"} +# my_silent_option_result=$func_quote_for_eval_result +# fi +# +# $args_changed # } # func_add_hook func_parse_options my_silent_option # @@ -1611,16 +1633,32 @@ func_run_hooks () # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." # -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result +# false # } # func_add_hook func_validate_options my_option_validation # -# You'll alse need to manually amend $usage_message to reflect the extra +# You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + _G_func_options_finish_exit=false + if func_run_hooks func_options ${1+"$@"}; then + func_options_finish_result=$func_run_hooks_result + _G_func_options_finish_exit=: + fi + + $_G_func_options_finish_exit +} + + # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the @@ -1630,17 +1668,28 @@ func_options () { $debug_cmd - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} + _G_rc_options=false - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} + for my_func in options_prep parse_options validate_options options_finish + do + if eval func_$my_func '${1+"$@"}'; then + eval _G_res_var='$'"func_${my_func}_result" + eval set dummy "$_G_res_var" ; shift + _G_rc_options=: + fi + done + + # Save modified positional parameters for caller. As a top-level + # options-parser function we always need to set the 'func_options_result' + # variable (regardless the $_G_rc_options value). + if $_G_rc_options; then + func_options_result=$_G_res_var + else + func_quote_for_eval ${1+"$@"} + func_options_result=$func_quote_for_eval_result + fi - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result + $_G_rc_options } @@ -1649,9 +1698,9 @@ func_options () # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete +# needs to propagate that back to rest of this script, then the complete # modified list must be put in 'func_run_hooks_result' before -# returning. +# returning $EXIT_SUCCESS (otherwise $EXIT_FAILURE is returned). func_hookable func_options_prep func_options_prep () { @@ -1661,10 +1710,14 @@ func_options_prep () opt_verbose=false opt_warning_types= - func_run_hooks func_options_prep ${1+"$@"} + _G_rc_options_prep=false + if func_run_hooks func_options_prep ${1+"$@"}; then + _G_rc_options_prep=: + # save modified positional parameters for caller + func_options_prep_result=$func_run_hooks_result + fi - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result + $_G_rc_options_prep } @@ -1678,18 +1731,20 @@ func_parse_options () func_parse_options_result= + _G_rc_parse_options=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. - func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift + if func_run_hooks func_parse_options ${1+"$@"}; then + eval set dummy "$func_run_hooks_result"; shift + _G_rc_parse_options=: + fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break + _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -1704,7 +1759,10 @@ func_parse_options () ;; --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break + if test $# = 0 && func_missing_arg $_G_opt; then + _G_rc_parse_options=: + break + fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above @@ -1757,15 +1815,25 @@ func_parse_options () shift ;; - --) break ;; + --) _G_rc_parse_options=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; esac + + $_G_match_parse_options && _G_rc_parse_options=: done - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result + + if $_G_rc_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + func_parse_options_result=$func_quote_for_eval_result + fi + + $_G_rc_parse_options } @@ -1778,16 +1846,21 @@ func_validate_options () { $debug_cmd + _G_rc_validate_options=false + # Display all warnings if -W was not given. test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" - func_run_hooks func_validate_options ${1+"$@"} + if func_run_hooks func_validate_options ${1+"$@"}; then + # save modified positional parameters for caller + func_validate_options_result=$func_run_hooks_result + _G_rc_validate_options=: + fi # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result + $_G_rc_validate_options } @@ -2068,7 +2141,7 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname $scriptversion Debian-2.4.6-14 automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` @@ -2270,6 +2343,8 @@ libtool_options_prep () nonopt= preserve_args= + _G_rc_lt_options_prep=: + # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2293,11 +2368,18 @@ libtool_options_prep () uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; + *) + _G_rc_lt_options_prep=false + ;; esac - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote_for_eval ${1+"$@"} + libtool_options_prep_result=$func_quote_for_eval_result + fi + + $_G_rc_lt_options_prep } func_add_hook func_options_prep libtool_options_prep @@ -2309,9 +2391,12 @@ libtool_parse_options () { $debug_cmd + _G_rc_lt_parse_options=false + # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do + _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -2386,15 +2471,22 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote_for_eval ${1+"$@"} + libtool_parse_options_result=$func_quote_for_eval_result + fi - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result + $_G_rc_lt_parse_options } func_add_hook func_parse_options libtool_parse_options @@ -7275,10 +7367,13 @@ func_mode_link () # -specs=* GCC specs files # -stdlib=* select c++ std lib with clang # -fsanitize=* Clang/GCC memory and address sanitizer + # -fuse-ld=* Linker select flags for GCC + # -static-* direct GCC to link specific libraries statically + # -fcilkplus Cilk Plus language extension features for C/C++ -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \ -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \ -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \ - -specs=*|-fsanitize=*) + -specs=*|-fsanitize=*|-fuse-ld=*|-static-*|-fcilkplus) func_quote_for_eval "$arg" arg=$func_quote_for_eval_result func_append compile_command " $arg" diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4 index 5120c3b..67b2774 100644 --- a/m4/ax_code_coverage.m4 +++ b/m4/ax_code_coverage.m4 @@ -104,7 +104,7 @@ AC_DEFUN([AX_CODE_COVERAGE],[ ]) # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.13" AC_CHECK_PROG([LCOV], [lcov], [lcov]) AC_CHECK_PROG([GENHTML], [genhtml], [genhtml]) diff --git a/m4/cares-compilers.m4 b/m4/cares-compilers.m4 index 2b98a68..542003b 100644 --- a/m4/cares-compilers.m4 +++ b/m4/cares-compilers.m4 @@ -1179,97 +1179,6 @@ squeeze() { ]) -dnl CARES_CHECK_CURLDEBUG -dnl ------------------------------------------------- -dnl Settings which depend on configure's curldebug given -dnl option, and other additional configure pre-requisites. -dnl Using the curl debug memory tracking feature in c-ares -dnl is a hack that actually can only be used/enabled when -dnl c-ares is built directly in curl's CVS tree, as a static -dnl library or as a shared one on those systems on which -dnl shared libraries support undefined symbols, along with -dnl an equally configured libcurl. - -AC_DEFUN([CARES_CHECK_CURLDEBUG], [ - AC_REQUIRE([XC_LIBTOOL])dnl - AC_REQUIRE([CARES_SHFUNC_SQUEEZE])dnl - cares_builddir=`pwd` - supports_curldebug="unknown" - if test "$want_curldebug" = "yes"; then - if test "x$enable_shared" != "xno" && - test "x$enable_shared" != "xyes"; then - AC_MSG_WARN([unknown enable_shared setting.]) - supports_curldebug="no" - fi - if test "x$enable_static" != "xno" && - test "x$enable_static" != "xyes"; then - AC_MSG_WARN([unknown enable_static setting.]) - supports_curldebug="no" - fi - if test "$supports_curldebug" != "no"; then - if test "$enable_shared" = "yes" && - test "x$xc_lt_shlib_use_no_undefined" = 'xyes'; then - supports_curldebug="no" - AC_MSG_WARN([shared library does not support undefined symbols.]) - fi - if test ! -f "$srcdir/../include/curl/curlbuild.h.dist"; then - AC_MSG_WARN([c-ares source not embedded in curl's CVS tree.]) - supports_curldebug="no" - elif test ! -f "$srcdir/../include/curl/Makefile.in"; then - AC_MSG_WARN([curl's buildconf has not been run.]) - supports_curldebug="no" - elif test ! -f "$cares_builddir/../libcurl.pc" || - test ! -f "$cares_builddir/../include/curl/curlbuild.h"; then - AC_MSG_WARN([curl's configure has not been run.]) - supports_curldebug="no" - elif test ! -f "$cares_builddir/../lib/curl_config.h"; then - AC_MSG_WARN([libcurl's curl_config.h is missing.]) - supports_curldebug="no" - elif test ! -f "$cares_builddir/../config.status"; then - AC_MSG_WARN([curl's config.status is missing.]) - supports_curldebug="no" - fi - if test "$supports_curldebug" != "no"; then - grep '^#define USE_ARES' "$cares_builddir/../lib/curl_config.h" >/dev/null - if test "$?" -ne "0"; then - AC_MSG_WARN([libcurl configured without c-ares support.]) - supports_curldebug="no" - fi - fi - if test "$supports_curldebug" != "no"; then - grep 'CPPFLAGS.*CURLDEBUG' "$cares_builddir/../config.status" >/dev/null - if test "$?" -ne "0"; then - AC_MSG_WARN([libcurl configured without curldebug support.]) - supports_curldebug="no" - fi - fi - fi - fi - # - if test "$want_curldebug" = "yes"; then - AC_MSG_CHECKING([if curl debug memory tracking can be enabled]) - test "$supports_curldebug" = "no" || supports_curldebug="yes" - AC_MSG_RESULT([$supports_curldebug]) - if test "$supports_curldebug" = "no"; then - AC_MSG_WARN([cannot enable curl debug memory tracking.]) - want_curldebug="no" - fi - fi - # - if test "$want_curldebug" = "yes"; then - dnl TODO: Verify if the BUILDING_LIBCURL definition is still required. - AC_DEFINE(BUILDING_LIBCURL, 1, [when building as static part of libcurl]) - CPPFLAGS="-DCURLDEBUG $CPPFLAGS" - squeeze CPPFLAGS - fi - # - if test "$want_debug" = "yes"; then - CPPFLAGS="-DDEBUGBUILD $CPPFLAGS" - squeeze CPPFLAGS - fi -]) - - dnl CARES_CHECK_COMPILER_HALT_ON_ERROR dnl ------------------------------------------------- dnl Verifies if the compiler actually halts after the diff --git a/m4/cares-confopts.m4 b/m4/cares-confopts.m4 index 135036a..eb52ee7 100644 --- a/m4/cares-confopts.m4 +++ b/m4/cares-confopts.m4 @@ -18,45 +18,6 @@ # serial 11 -dnl CARES_CHECK_OPTION_CURLDEBUG -dnl ------------------------------------------------- -dnl Verify if configure has been invoked with option -dnl --enable-curldebug or --disable-curldebug, and set -dnl shell variable want_curldebug value as appropriate. - -AC_DEFUN([CARES_CHECK_OPTION_CURLDEBUG], [ - AC_BEFORE([$0],[CARES_CHECK_CURLDEBUG])dnl - AC_MSG_CHECKING([whether to enable curl debug memory tracking]) - OPT_CURLDEBUG_BUILD="default" - AC_ARG_ENABLE(curldebug, -AC_HELP_STRING([--enable-curldebug],[Enable curl debug memory tracking]) -AC_HELP_STRING([--disable-curldebug],[Disable curl debug memory tracking]), - OPT_CURLDEBUG_BUILD=$enableval) - case "$OPT_CURLDEBUG_BUILD" in - no) - dnl --disable-curldebug option used - want_curldebug="no" - ;; - default) - dnl configure option not specified - want_curldebug="no" - ;; - *) - dnl --enable-curldebug option used. - dnl The use of this option value is a request to enable curl's - dnl debug memory tracking for the c-ares library. This is a big - dnl hack that can only be done when a whole bunch of requisites - dnl are simultaneously satisfied. Later on, these requisites are - dnl verified and if they are not fully satisfied the option will - dnl be ignored and act as if --disable-curldebug had been given - dnl setting shell variable want_curldebug to 'no'. - want_curldebug="yes" - ;; - esac - AC_MSG_RESULT([$want_curldebug]) -]) - - dnl CARES_CHECK_OPTION_DEBUG dnl ------------------------------------------------- dnl Verify if configure has been invoked with option @@ -65,7 +26,6 @@ dnl variable want_debug value as appropriate. AC_DEFUN([CARES_CHECK_OPTION_DEBUG], [ AC_BEFORE([$0],[CARES_CHECK_OPTION_WARNINGS])dnl - AC_BEFORE([$0],[CARES_CHECK_OPTION_CURLDEBUG])dnl AC_BEFORE([$0],[XC_CHECK_PROG_CC])dnl AC_MSG_CHECKING([whether to enable debug build options]) OPT_DEBUG_BUILD="default" diff --git a/m4/cares-functions.m4 b/m4/cares-functions.m4 index 7c7c92b..0f3992c 100644 --- a/m4/cares-functions.m4 +++ b/m4/cares-functions.m4 @@ -1661,6 +1661,146 @@ AC_DEFUN([CARES_CHECK_FUNC_GETSERVBYPORT_R], [ ]) +dnl CARES_CHECK_FUNC_GETSERVBYNAME_R +dnl ------------------------------------------------- +dnl Verify if getservbyname_r is available, prototyped, +dnl and can be compiled. If all of these are true, and +dnl usage has not been previously disallowed with +dnl shell variable cares_disallow_getservbyname_r, then +dnl HAVE_GETSERVBYNAME_R will be defined. + +AC_DEFUN([CARES_CHECK_FUNC_GETSERVBYNAME_R], [ + AC_REQUIRE([CARES_INCLUDES_NETDB])dnl + # + tst_links_getservbyname_r="unknown" + tst_proto_getservbyname_r="unknown" + tst_compi_getservbyname_r="unknown" + tst_allow_getservbyname_r="unknown" + tst_nargs_getservbyname_r="unknown" + # + AC_MSG_CHECKING([if getservbyname_r can be linked]) + AC_LINK_IFELSE([ + AC_LANG_FUNC_LINK_TRY([getservbyname_r]) + ],[ + AC_MSG_RESULT([yes]) + tst_links_getservbyname_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_links_getservbyname_r="no" + ]) + # + if test "$tst_links_getservbyname_r" = "yes"; then + AC_MSG_CHECKING([if getservbyname_r is prototyped]) + AC_EGREP_CPP([getservbyname_r],[ + $cares_includes_netdb + ],[ + AC_MSG_RESULT([yes]) + tst_proto_getservbyname_r="yes" + ],[ + AC_MSG_RESULT([no]) + tst_proto_getservbyname_r="no" + ]) + fi + # + if test "$tst_proto_getservbyname_r" = "yes"; then + if test "$tst_nargs_getservbyname_r" = "unknown"; then + AC_MSG_CHECKING([if getservbyname_r takes 4 args.]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $cares_includes_netdb + ]],[[ + if(0 != getservbyname_r(0, 0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_getservbyname_r="yes" + tst_nargs_getservbyname_r="4" + ],[ + AC_MSG_RESULT([no]) + tst_compi_getservbyname_r="no" + ]) + fi + if test "$tst_nargs_getservbyname_r" = "unknown"; then + AC_MSG_CHECKING([if getservbyname_r takes 5 args.]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $cares_includes_netdb + ]],[[ + if(0 != getservbyname_r(0, 0, 0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_getservbyname_r="yes" + tst_nargs_getservbyname_r="5" + ],[ + AC_MSG_RESULT([no]) + tst_compi_getservbyname_r="no" + ]) + fi + if test "$tst_nargs_getservbyname_r" = "unknown"; then + AC_MSG_CHECKING([if getservbyname_r takes 6 args.]) + AC_COMPILE_IFELSE([ + AC_LANG_PROGRAM([[ + $cares_includes_netdb + ]],[[ + if(0 != getservbyname_r(0, 0, 0, 0, 0, 0)) + return 1; + ]]) + ],[ + AC_MSG_RESULT([yes]) + tst_compi_getservbyname_r="yes" + tst_nargs_getservbyname_r="6" + ],[ + AC_MSG_RESULT([no]) + tst_compi_getservbyname_r="no" + ]) + fi + AC_MSG_CHECKING([if getservbyname_r is compilable]) + if test "$tst_compi_getservbyname_r" = "yes"; then + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + fi + # + if test "$tst_compi_getservbyname_r" = "yes"; then + AC_MSG_CHECKING([if getservbyname_r usage allowed]) + if test "x$cares_disallow_getservbyname_r" != "xyes"; then + AC_MSG_RESULT([yes]) + tst_allow_getservbyname_r="yes" + else + AC_MSG_RESULT([no]) + tst_allow_getservbyname_r="no" + fi + fi + # + AC_MSG_CHECKING([if getservbyname_r might be used]) + if test "$tst_links_getservbyname_r" = "yes" && + test "$tst_proto_getservbyname_r" = "yes" && + test "$tst_compi_getservbyname_r" = "yes" && + test "$tst_allow_getservbyname_r" = "yes"; then + AC_MSG_RESULT([yes]) + AC_DEFINE_UNQUOTED(HAVE_GETSERVBYNAME_R, 1, + [Define to 1 if you have the getservbyname_r function.]) + AC_DEFINE_UNQUOTED(GETSERVBYNAME_R_ARGS, $tst_nargs_getservbyname_r, + [Specifies the number of arguments to getservbyname_r]) + if test "$tst_nargs_getservbyname_r" -eq "4"; then + AC_DEFINE(GETSERVBYNAME_R_BUFSIZE, sizeof(struct servent_data), + [Specifies the size of the buffer to pass to getservbyname_r]) + else + AC_DEFINE(GETSERVBYNAME_R_BUFSIZE, 4096, + [Specifies the size of the buffer to pass to getservbyname_r]) + fi + ac_cv_func_getservbyname_r="yes" + else + AC_MSG_RESULT([no]) + ac_cv_func_getservbyname_r="no" + fi +]) + + dnl CARES_CHECK_FUNC_INET_NET_PTON dnl ------------------------------------------------- dnl Verify if inet_net_pton is available, prototyped, can diff --git a/m4/libtool.m4 b/m4/libtool.m4 index b202060..a6d21ae 100644 --- a/m4/libtool.m4 +++ b/m4/libtool.m4 @@ -728,7 +728,6 @@ _LT_CONFIG_SAVE_COMMANDS([ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. @@ -1042,8 +1041,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR cr libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR cr libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF @@ -1493,7 +1492,7 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cru} +: ${AR_FLAGS=cr} _LT_DECL([], [AR], [1], [The archiver]) _LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) @@ -4064,7 +4063,8 @@ _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4124,7 +4124,7 @@ static const void *lt_preloaded_setup() { #endif _LT_EOF # Now try linking the two files. - mv -f conftest.$ac_objext conftstm.$ac_objext + mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext @@ -4704,6 +4704,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -5677,9 +5683,9 @@ _LT_EOF hpux9*) if test yes = "$GCC"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl+b $wl$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: @@ -6439,7 +6445,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -6805,7 +6811,7 @@ if test yes != "$_lt_caught_CXX_error"; then _LT_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -6814,11 +6820,11 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then - _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support _LT_TAGVAR(ld_shlibs, $1)=no @@ -6879,7 +6885,7 @@ if test yes != "$_lt_caught_CXX_error"; then # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6954,8 +6960,8 @@ if test yes != "$_lt_caught_CXX_error"; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv -f \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -7153,7 +7159,7 @@ if test yes != "$_lt_caught_CXX_error"; then # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' + _LT_TAGVAR(archive_cmds, $1)='tempext=`echo $shared_ext | $SED -e '\''s/\([[^()0-9A-Za-z{}]]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath,$libdir' _LT_TAGVAR(hardcode_libdir_separator, $1)=: @@ -7218,7 +7224,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -7302,7 +7308,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7313,7 +7319,7 @@ if test yes != "$_lt_caught_CXX_error"; then # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' @@ -8264,7 +8270,7 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do fi while true; do cat conftest.in conftest.in >conftest.tmp - mv -f conftest.tmp conftest.in + mv conftest.tmp conftest.in cp conftest.in conftest.nl echo >>conftest.nl $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break diff --git a/m4/xc-cc-check.m4 b/m4/xc-cc-check.m4 index cd55405..777decf 100644 --- a/m4/xc-cc-check.m4 +++ b/m4/xc-cc-check.m4 @@ -59,7 +59,7 @@ dnl Private macro. AC_DEFUN([_XC_PROG_CC], [ AC_REQUIRE([_XC_PROG_CC_PREAMBLE])dnl - AC_REQUIRE([XC_CHECK_USER_FLAGS])dnl + AC_REQUIRE([XC_CHECK_BUILD_FLAGS])dnl AC_REQUIRE([AC_PROG_INSTALL])dnl AC_REQUIRE([AC_PROG_CC])dnl AC_REQUIRE([AM_PROG_CC_C_O])dnl diff --git a/maketgz b/maketgz index e3bb77a..ec1ecea 100755 --- a/maketgz +++ b/maketgz @@ -7,7 +7,7 @@ if($version eq "") { exit; } -if(!-f "ares.h") { +if(!-f "include/ares.h") { print "run this script in the ares source root dir\n"; exit; } @@ -18,9 +18,9 @@ $major += 0; $minor += 0; $patch += 0; -open(VER, "ares_version.h.dist"); +open(VER, "include/ares_version.h.dist"); while() { $_ =~ s/^\#define ARES_VERSION_MAJOR .*/\#define ARES_VERSION_MAJOR $major/; $_ =~ s/^\#define ARES_VERSION_MINOR .*/\#define ARES_VERSION_MINOR $minor/; @@ -31,7 +31,7 @@ while() { } close(VER); close(NEWV); -print "ares_version.h.dist created\n"; +print "include/ares_version.h.dist created\n"; if(!-f "configure") { print "running buildconf\n"; @@ -40,6 +40,9 @@ if(!-f "configure") { print "adding $version in the configure.ac file\n"; `sed -e 's/AC_INIT.*/AC_INIT([c-ares], [$version],/' < configure.ac > configure.ac.dist`; +print "adding $version in the CMakeLists.txt file\n"; +`sed -e 's/SET.*CARES_VERSION.*/SET (CARES_VERSION "$version")/' < CMakeLists.txt > CMakeLists.txt.dist && rm -f CMakeLists.txt && mv CMakeLists.txt.dist CMakeLists.txt`; + # now make a new configure script with this print "makes a new configure script\n"; `autoconf configure.ac.dist >configure`; @@ -48,17 +51,6 @@ print "makes a new configure script\n"; print "running configure\n"; `./configure`; -# generate HTML versions of man pages -# Deactivated for now. It seems that man pages need some adjustments -# relative to paragraph and/or line breaks for proper html formatting. -# EXTRA_DIST will need $(HTMLPAGES) when this is fully activated. -# print "running make html\n"; -# `make -s html`; - -# generate PDF versions of man pages -print "running make pdf\n"; -`make -s pdf`; - print "produce CHANGES\n"; `git log --pretty=fuller --no-color --date=short --decorate=full -1000 | ./git2changes.pl > CHANGES.dist`; @@ -72,6 +64,6 @@ print "running make dist\n"; print "removing temporary configure.ac file\n"; `rm configure.ac.dist`; print "removing temporary ares_version.h file\n"; -`rm ares_version.h.dist`; +`rm include/ares_version.h.dist`; print "NOTE: now tag this release!\n"; diff --git a/missing b/missing index f62bbae..8d0eaad 100755 --- a/missing +++ b/missing @@ -1,9 +1,9 @@ #! /bin/sh # Common wrapper for a few potentially missing GNU programs. -scriptversion=2013-10-28.13; # UTC +scriptversion=2018-03-07.03; # UTC -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # Originally written by Fran,cois Pinard , 1996. # This program is free software; you can redistribute it and/or modify @@ -17,7 +17,7 @@ scriptversion=2013-10-28.13; # UTC # GNU General Public License for more details. # You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# along with this program. If not, see . # As a special exception to the GNU General Public License, if you # distribute this file as part of a program that contains a @@ -101,9 +101,9 @@ else exit $st fi -perl_URL=http://www.perl.org/ -flex_URL=http://flex.sourceforge.net/ -gnu_software_URL=http://www.gnu.org/software +perl_URL=https://www.perl.org/ +flex_URL=https://github.com/westes/flex +gnu_software_URL=https://www.gnu.org/software program_details () { @@ -207,9 +207,9 @@ give_advice "$1" | sed -e '1s/^/WARNING: /' \ exit $st # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: diff --git a/mkinstalldirs b/mkinstalldirs deleted file mode 100755 index 55d537f..0000000 --- a/mkinstalldirs +++ /dev/null @@ -1,162 +0,0 @@ -#! /bin/sh -# mkinstalldirs --- make directory hierarchy - -scriptversion=2009-04-28.21; # UTC - -# Original author: Noah Friedman -# Created: 1993-05-16 -# Public domain. -# -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -nl=' -' -IFS=" "" $nl" -errstatus=0 -dirmode= - -usage="\ -Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ... - -Create each directory DIR (with mode MODE, if specified), including all -leading file name components. - -Report bugs to ." - -# process command line arguments -while test $# -gt 0 ; do - case $1 in - -h | --help | --h*) # -h for help - echo "$usage" - exit $? - ;; - -m) # -m PERM arg - shift - test $# -eq 0 && { echo "$usage" 1>&2; exit 1; } - dirmode=$1 - shift - ;; - --version) - echo "$0 $scriptversion" - exit $? - ;; - --) # stop option processing - shift - break - ;; - -*) # unknown option - echo "$usage" 1>&2 - exit 1 - ;; - *) # first non-opt arg - break - ;; - esac -done - -for file -do - if test -d "$file"; then - shift - else - break - fi -done - -case $# in - 0) exit 0 ;; -esac - -# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and -# mkdir -p a/c at the same time, both will detect that a is missing, -# one will create a, then the other will try to create a and die with -# a "File exists" error. This is a problem when calling mkinstalldirs -# from a parallel make. We use --version in the probe to restrict -# ourselves to GNU mkdir, which is thread-safe. -case $dirmode in - '') - if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then - echo "mkdir -p -- $*" - exec mkdir -p -- "$@" - else - # On NextStep and OpenStep, the 'mkdir' command does not - # recognize any option. It will interpret all options as - # directories to create, and then abort because '.' already - # exists. - test -d ./-p && rmdir ./-p - test -d ./--version && rmdir ./--version - fi - ;; - *) - if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 && - test ! -d ./--version; then - echo "mkdir -m $dirmode -p -- $*" - exec mkdir -m "$dirmode" -p -- "$@" - else - # Clean up after NextStep and OpenStep mkdir. - for d in ./-m ./-p ./--version "./$dirmode"; - do - test -d $d && rmdir $d - done - fi - ;; -esac - -for file -do - case $file in - /*) pathcomp=/ ;; - *) pathcomp= ;; - esac - oIFS=$IFS - IFS=/ - set fnord $file - shift - IFS=$oIFS - - for d - do - test "x$d" = x && continue - - pathcomp=$pathcomp$d - case $pathcomp in - -*) pathcomp=./$pathcomp ;; - esac - - if test ! -d "$pathcomp"; then - echo "mkdir $pathcomp" - - mkdir "$pathcomp" || lasterr=$? - - if test ! -d "$pathcomp"; then - errstatus=$lasterr - else - if test ! -z "$dirmode"; then - echo "chmod $dirmode $pathcomp" - lasterr= - chmod "$dirmode" "$pathcomp" || lasterr=$? - - if test ! -z "$lasterr"; then - errstatus=$lasterr - fi - fi - fi - fi - - pathcomp=$pathcomp/ - done -done - -exit $errstatus - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" -# time-stamp-end: "; # UTC" -# End: diff --git a/msvc_ver.inc b/msvc_ver.inc new file mode 100644 index 0000000..595cbdf --- /dev/null +++ b/msvc_ver.inc @@ -0,0 +1,24 @@ +# ----------------------------------------------- +# Detect NMAKE version deducing old MSVC versions +# ----------------------------------------------- + +!IFNDEF _NMAKE_VER +! MESSAGE Macro _NMAKE_VER not defined. +! MESSAGE Use MSVC's NMAKE to process this makefile. +! ERROR See previous message. +!ENDIF + +!IF "$(_NMAKE_VER)" == "6.00.8168.0" +CC_VERS_NUM = 60 +!ELSEIF "$(_NMAKE_VER)" == "6.00.9782.0" +CC_VERS_NUM = 60 +!ELSEIF "$(_NMAKE_VER)" == "7.00.8882" +CC_VERS_NUM = 70 +!ELSEIF "$(_NMAKE_VER)" == "7.00.9466" +CC_VERS_NUM = 70 +!ELSEIF "$(_NMAKE_VER)" == "7.00.9955" +CC_VERS_NUM = 70 +!ELSE +# Pick an arbitrary bigger number for all later versions +CC_VERS_NUM = 199 +!ENDIF diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..6750c17 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY (lib) +ADD_SUBDIRECTORY (tools) diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..2e97e42 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,2 @@ +EXTRA_DIST=CMakeLists.txt +SUBDIRS=lib tools diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 0000000..094b00d --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,658 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/m4/cares-compilers.m4 \ + $(top_srcdir)/m4/cares-confopts.m4 \ + $(top_srcdir)/m4/cares-functions.m4 \ + $(top_srcdir)/m4/cares-override.m4 \ + $(top_srcdir)/m4/cares-reentrant.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/lib/ares_config.h \ + $(top_builddir)/include/ares_build.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +DIST_SUBDIRS = $(SUBDIRS) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ +CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ +CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = CMakeLists.txt +SUBDIRS = lib tools +all: all-recursive + +.SUFFIXES: +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile +installdirs: installdirs-recursive +installdirs-am: +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-recursive + -rm -f Makefile +distclean-am: clean-am distclean-generic distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: + +.MAKE: $(am__recursive_targets) install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am check \ + check-am clean clean-generic clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + installdirs-am maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \ + ps ps-am tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt new file mode 100644 index 0000000..7d37be2 --- /dev/null +++ b/src/lib/CMakeLists.txt @@ -0,0 +1,115 @@ + +# Transform Makefile.inc +transform_makefile_inc("Makefile.inc" "${PROJECT_BINARY_DIR}/src/lib/Makefile.inc.cmake") +include(${PROJECT_BINARY_DIR}/src/lib/Makefile.inc.cmake) + +# Write ares_config.h configuration file. This is used only for the build. +CONFIGURE_FILE (ares_config.h.cmake ${PROJECT_BINARY_DIR}/ares_config.h) + +# Build the dynamic/shared library +IF (CARES_SHARED) + ADD_LIBRARY (${PROJECT_NAME} SHARED ${CSOURCES}) + + # Convert CARES_LIB_VERSIONINFO libtool version format into VERSION and SOVERSION + # Convert from ":" separated into CMake list format using ";" + STRING (REPLACE ":" ";" CARES_LIB_VERSIONINFO ${CARES_LIB_VERSIONINFO}) + LIST (GET CARES_LIB_VERSIONINFO 0 CARES_LIB_VERSION_CURRENT) + LIST (GET CARES_LIB_VERSIONINFO 1 CARES_LIB_VERSION_REVISION) + LIST (GET CARES_LIB_VERSIONINFO 2 CARES_LIB_VERSION_AGE) + MATH (EXPR CARES_LIB_VERSION_MAJOR "${CARES_LIB_VERSION_CURRENT} - ${CARES_LIB_VERSION_AGE}") + SET (CARES_LIB_VERSION_MINOR "${CARES_LIB_VERSION_AGE}") + SET (CARES_LIB_VERSION_RELEASE "${CARES_LIB_VERSION_REVISION}") + + SET_TARGET_PROPERTIES (${PROJECT_NAME} PROPERTIES + EXPORT_NAME cares + OUTPUT_NAME cares + COMPILE_PDB_NAME cares + COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + SOVERSION ${CARES_LIB_VERSION_MAJOR} + VERSION "${CARES_LIB_VERSION_MAJOR}.${CARES_LIB_VERSION_MINOR}.${CARES_LIB_VERSION_RELEASE}" + ) + + TARGET_INCLUDE_DIRECTORIES (${PROJECT_NAME} + PUBLIC "$" + "$" + "$" + "$" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" + ) + + TARGET_COMPILE_DEFINITIONS (${PROJECT_NAME} PRIVATE HAVE_CONFIG_H=1 CARES_BUILDING_LIBRARY) + + TARGET_LINK_LIBRARIES (${PROJECT_NAME} PUBLIC ${CARES_DEPENDENT_LIBS}) + + IF (CARES_INSTALL) + INSTALL (TARGETS ${PROJECT_NAME} + EXPORT ${PROJECT_NAME}-targets + COMPONENT Library + ${TARGETS_INST_DEST} + ) + INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cares.pdb + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT Library + OPTIONAL + ) + ENDIF () + SET (STATIC_SUFFIX "_static") + + # For chain building: add alias targets that look like import libs that would be returned by find_package(c-ares). + ADD_LIBRARY (${PROJECT_NAME}::cares_shared ALIAS ${PROJECT_NAME}) + ADD_LIBRARY (${PROJECT_NAME}::cares ALIAS ${PROJECT_NAME}) +ENDIF () + +# Build the static library +IF (CARES_STATIC) + SET (LIBNAME ${PROJECT_NAME}${STATIC_SUFFIX}) + + ADD_LIBRARY (${LIBNAME} STATIC ${CSOURCES}) + + SET_TARGET_PROPERTIES (${LIBNAME} PROPERTIES + EXPORT_NAME cares${STATIC_SUFFIX} + OUTPUT_NAME cares${STATIC_SUFFIX} + COMPILE_PDB_NAME cares${STATIC_SUFFIX} + COMPILE_PDB_OUTPUT_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} + ) + + IF (CARES_STATIC_PIC) + SET_TARGET_PROPERTIES (${LIBNAME} PROPERTIES POSITION_INDEPENDENT_CODE True) + ENDIF () + + TARGET_INCLUDE_DIRECTORIES (${LIBNAME} + PUBLIC "$" + "$" + "$" + "$" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" + ) + + TARGET_COMPILE_DEFINITIONS (${LIBNAME} + PUBLIC CARES_STATICLIB + PRIVATE HAVE_CONFIG_H=1 + ) + + TARGET_LINK_LIBRARIES (${LIBNAME} PUBLIC ${CARES_DEPENDENT_LIBS}) + IF (CARES_INSTALL) + INSTALL (TARGETS ${LIBNAME} EXPORT ${PROJECT_NAME}-targets COMPONENT Devel + ${TARGETS_INST_DEST} + ) + INSTALL(FILES ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/cares${STATIC_SUFFIX}.pdb + DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT Library + OPTIONAL + ) + ENDIF () + + # For chain building: add alias targets that look like import libs that would be returned by find_package(c-ares). + ADD_LIBRARY (${PROJECT_NAME}::cares_static ALIAS ${LIBNAME}) + IF (NOT TARGET ${PROJECT_NAME}::cares) + # Only use static for the generic alias if shared lib wasn't built. + ADD_LIBRARY (${PROJECT_NAME}::cares ALIAS ${LIBNAME}) + ENDIF () +ENDIF () + + + + diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am new file mode 100644 index 0000000..c918667 --- /dev/null +++ b/src/lib/Makefile.am @@ -0,0 +1,72 @@ +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. + +AM_CPPFLAGS = -I$(top_builddir)/include \ + -I$(top_builddir)/src/lib \ + -I$(top_srcdir)/include + +lib_LTLIBRARIES = libcares.la + +man_MANS = $(MANPAGES) + +# adig and ahost are just sample programs and thus not mentioned with the +# regular sources and headers +EXTRA_DIST = Makefile.inc config-win32.h CMakeLists.txt \ + ares_config.h.in ares_config.h.cmake cares.rc \ + $(CSOURCES) $(HHEADERS) config-dos.h + +DISTCLEANFILES = ares_config.h + +DIST_SUBDIRS = + +AM_LDFLAGS = + +libcares_la_LDFLAGS_EXTRA = + +if CARES_LT_SHLIB_USE_VERSION_INFO +libcares_la_LDFLAGS_EXTRA += -version-info @CARES_VERSION_INFO@ +endif + +if CARES_LT_SHLIB_USE_NO_UNDEFINED +libcares_la_LDFLAGS_EXTRA += -no-undefined +endif + +if CARES_LT_SHLIB_USE_MIMPURE_TEXT +libcares_la_LDFLAGS_EXTRA += -mimpure-text +endif + +libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA) + +# Add -Werror if defined +CFLAGS += @CARES_CFLAG_EXTRAS@ + +if USE_CPPFLAG_CARES_STATICLIB +AM_CPPFLAGS += $(CPPFLAG_CARES_STATICLIB) +endif + +libcares_la_CFLAGS_EXTRA = + +libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY + +if DOING_CARES_SYMBOL_HIDING +libcares_la_CFLAGS_EXTRA += $(CFLAG_CARES_SYMBOL_HIDING) +libcares_la_CPPFLAGS_EXTRA += -DCARES_SYMBOL_HIDING +endif + +@CODE_COVERAGE_RULES@ +libcares_la_LDFLAGS += $(CODE_COVERAGE_LDFLAGS) +libcares_la_CFLAGS_EXTRA += $(CODE_COVERAGE_CFLAGS) + +libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA) + +libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA) + +# Makefile.inc provides the CSOURCES and HHEADERS defines +include Makefile.inc + +libcares_la_SOURCES = $(CSOURCES) $(HHEADERS) diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in new file mode 100644 index 0000000..6ef01f4 --- /dev/null +++ b/src/lib/Makefile.in @@ -0,0 +1,1596 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +@CARES_LT_SHLIB_USE_VERSION_INFO_TRUE@am__append_1 = -version-info @CARES_VERSION_INFO@ +@CARES_LT_SHLIB_USE_NO_UNDEFINED_TRUE@am__append_2 = -no-undefined +@CARES_LT_SHLIB_USE_MIMPURE_TEXT_TRUE@am__append_3 = -mimpure-text +@USE_CPPFLAG_CARES_STATICLIB_TRUE@am__append_4 = $(CPPFLAG_CARES_STATICLIB) +@DOING_CARES_SYMBOL_HIDING_TRUE@am__append_5 = $(CFLAG_CARES_SYMBOL_HIDING) +@DOING_CARES_SYMBOL_HIDING_TRUE@am__append_6 = -DCARES_SYMBOL_HIDING +subdir = src/lib +SUBDIRS = +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/m4/cares-compilers.m4 \ + $(top_srcdir)/m4/cares-confopts.m4 \ + $(top_srcdir)/m4/cares-functions.m4 \ + $(top_srcdir)/m4/cares-override.m4 \ + $(top_srcdir)/m4/cares-reentrant.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = ares_config.h $(top_builddir)/include/ares_build.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; +am__vpath_adj = case $$p in \ + $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ + *) f=$$p;; \ + esac; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' +am__uninstall_files_from_dir = { \ + test -z "$$files" \ + || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \ + || { echo " ( cd '$$dir' && rm -f" $$files ")"; \ + $(am__cd) "$$dir" && rm -f $$files; }; \ + } +am__installdirs = "$(DESTDIR)$(libdir)" +LTLIBRARIES = $(lib_LTLIBRARIES) +libcares_la_LIBADD = +am__objects_1 = libcares_la-ares__close_sockets.lo \ + libcares_la-ares__get_hostent.lo \ + libcares_la-ares__parse_into_addrinfo.lo \ + libcares_la-ares__readaddrinfo.lo \ + libcares_la-ares__sortaddrinfo.lo \ + libcares_la-ares__read_line.lo libcares_la-ares__timeval.lo \ + libcares_la-ares_android.lo libcares_la-ares_cancel.lo \ + libcares_la-ares_data.lo libcares_la-ares_destroy.lo \ + libcares_la-ares_expand_name.lo \ + libcares_la-ares_expand_string.lo libcares_la-ares_fds.lo \ + libcares_la-ares_free_hostent.lo \ + libcares_la-ares_free_string.lo \ + libcares_la-ares_freeaddrinfo.lo \ + libcares_la-ares_getaddrinfo.lo libcares_la-ares_getenv.lo \ + libcares_la-ares_gethostbyaddr.lo \ + libcares_la-ares_gethostbyname.lo \ + libcares_la-ares_getnameinfo.lo libcares_la-ares_getsock.lo \ + libcares_la-ares_init.lo libcares_la-ares_library_init.lo \ + libcares_la-ares_llist.lo libcares_la-ares_mkquery.lo \ + libcares_la-ares_create_query.lo libcares_la-ares_nowarn.lo \ + libcares_la-ares_options.lo libcares_la-ares_parse_a_reply.lo \ + libcares_la-ares_parse_aaaa_reply.lo \ + libcares_la-ares_parse_caa_reply.lo \ + libcares_la-ares_parse_mx_reply.lo \ + libcares_la-ares_parse_naptr_reply.lo \ + libcares_la-ares_parse_ns_reply.lo \ + libcares_la-ares_parse_ptr_reply.lo \ + libcares_la-ares_parse_soa_reply.lo \ + libcares_la-ares_parse_srv_reply.lo \ + libcares_la-ares_parse_txt_reply.lo \ + libcares_la-ares_platform.lo libcares_la-ares_process.lo \ + libcares_la-ares_query.lo libcares_la-ares_search.lo \ + libcares_la-ares_send.lo libcares_la-ares_strcasecmp.lo \ + libcares_la-ares_strdup.lo libcares_la-ares_strerror.lo \ + libcares_la-ares_strsplit.lo libcares_la-ares_timeout.lo \ + libcares_la-ares_version.lo libcares_la-ares_writev.lo \ + libcares_la-bitncmp.lo libcares_la-inet_net_pton.lo \ + libcares_la-inet_ntop.lo libcares_la-windows_port.lo +am__objects_2 = +am_libcares_la_OBJECTS = $(am__objects_1) $(am__objects_2) +libcares_la_OBJECTS = $(am_libcares_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +libcares_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libcares_la_CFLAGS) \ + $(CFLAGS) $(libcares_la_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo \ + ./$(DEPDIR)/libcares_la-ares__get_hostent.Plo \ + ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares__read_line.Plo \ + ./$(DEPDIR)/libcares_la-ares__readaddrinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares__timeval.Plo \ + ./$(DEPDIR)/libcares_la-ares_android.Plo \ + ./$(DEPDIR)/libcares_la-ares_cancel.Plo \ + ./$(DEPDIR)/libcares_la-ares_create_query.Plo \ + ./$(DEPDIR)/libcares_la-ares_data.Plo \ + ./$(DEPDIR)/libcares_la-ares_destroy.Plo \ + ./$(DEPDIR)/libcares_la-ares_expand_name.Plo \ + ./$(DEPDIR)/libcares_la-ares_expand_string.Plo \ + ./$(DEPDIR)/libcares_la-ares_fds.Plo \ + ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo \ + ./$(DEPDIR)/libcares_la-ares_free_string.Plo \ + ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares_getaddrinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares_getenv.Plo \ + ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo \ + ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo \ + ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo \ + ./$(DEPDIR)/libcares_la-ares_getsock.Plo \ + ./$(DEPDIR)/libcares_la-ares_init.Plo \ + ./$(DEPDIR)/libcares_la-ares_library_init.Plo \ + ./$(DEPDIR)/libcares_la-ares_llist.Plo \ + ./$(DEPDIR)/libcares_la-ares_mkquery.Plo \ + ./$(DEPDIR)/libcares_la-ares_nowarn.Plo \ + ./$(DEPDIR)/libcares_la-ares_options.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo \ + ./$(DEPDIR)/libcares_la-ares_platform.Plo \ + ./$(DEPDIR)/libcares_la-ares_process.Plo \ + ./$(DEPDIR)/libcares_la-ares_query.Plo \ + ./$(DEPDIR)/libcares_la-ares_search.Plo \ + ./$(DEPDIR)/libcares_la-ares_send.Plo \ + ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo \ + ./$(DEPDIR)/libcares_la-ares_strdup.Plo \ + ./$(DEPDIR)/libcares_la-ares_strerror.Plo \ + ./$(DEPDIR)/libcares_la-ares_strsplit.Plo \ + ./$(DEPDIR)/libcares_la-ares_timeout.Plo \ + ./$(DEPDIR)/libcares_la-ares_version.Plo \ + ./$(DEPDIR)/libcares_la-ares_writev.Plo \ + ./$(DEPDIR)/libcares_la-bitncmp.Plo \ + ./$(DEPDIR)/libcares_la-inet_net_pton.Plo \ + ./$(DEPDIR)/libcares_la-inet_ntop.Plo \ + ./$(DEPDIR)/libcares_la-windows_port.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libcares_la_SOURCES) +DIST_SOURCES = $(libcares_la_SOURCES) +RECURSIVE_TARGETS = all-recursive check-recursive cscopelist-recursive \ + ctags-recursive dvi-recursive html-recursive info-recursive \ + install-data-recursive install-dvi-recursive \ + install-exec-recursive install-html-recursive \ + install-info-recursive install-pdf-recursive \ + install-ps-recursive install-recursive installcheck-recursive \ + installdirs-recursive pdf-recursive ps-recursive \ + tags-recursive uninstall-recursive +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \ + distclean-recursive maintainer-clean-recursive +am__recursive_targets = \ + $(RECURSIVE_TARGETS) \ + $(RECURSIVE_CLEAN_TARGETS) \ + $(am__extra_recursive_targets) +AM_RECURSIVE_TARGETS = $(am__recursive_targets:-recursive=) TAGS CTAGS \ + distdir distdir-am +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + ares_config.h.in +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ + $(srcdir)/ares_config.h.in $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +am__relativize = \ + dir0=`pwd`; \ + sed_first='s,^\([^/]*\)/.*$$,\1,'; \ + sed_rest='s,^[^/]*/*,,'; \ + sed_last='s,^.*/\([^/]*\)$$,\1,'; \ + sed_butlast='s,/*[^/]*$$,,'; \ + while test -n "$$dir1"; do \ + first=`echo "$$dir1" | sed -e "$$sed_first"`; \ + if test "$$first" != "."; then \ + if test "$$first" = ".."; then \ + dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \ + dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \ + else \ + first2=`echo "$$dir2" | sed -e "$$sed_first"`; \ + if test "$$first2" = "$$first"; then \ + dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \ + else \ + dir2="../$$dir2"; \ + fi; \ + dir0="$$dir0"/"$$first"; \ + fi; \ + fi; \ + dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \ + done; \ + reldir="$$dir2" +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ +CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ +CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ + +# Add -Werror if defined +CFLAGS = @CFLAGS@ @CARES_CFLAG_EXTRAS@ +CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I m4 --install + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +AM_CPPFLAGS = -I$(top_builddir)/include -I$(top_builddir)/src/lib \ + -I$(top_srcdir)/include $(am__append_4) +lib_LTLIBRARIES = libcares.la +man_MANS = $(MANPAGES) + +# adig and ahost are just sample programs and thus not mentioned with the +# regular sources and headers +EXTRA_DIST = Makefile.inc config-win32.h CMakeLists.txt \ + ares_config.h.in ares_config.h.cmake cares.rc \ + $(CSOURCES) $(HHEADERS) config-dos.h + +DISTCLEANFILES = ares_config.h +DIST_SUBDIRS = +AM_LDFLAGS = +libcares_la_LDFLAGS_EXTRA = $(am__append_1) $(am__append_2) \ + $(am__append_3) +libcares_la_LDFLAGS = $(AM_LDFLAGS) $(libcares_la_LDFLAGS_EXTRA) \ + $(CODE_COVERAGE_LDFLAGS) +libcares_la_CFLAGS_EXTRA = $(am__append_5) $(CODE_COVERAGE_CFLAGS) +libcares_la_CPPFLAGS_EXTRA = -DCARES_BUILDING_LIBRARY $(am__append_6) +libcares_la_CFLAGS = $(AM_CFLAGS) $(libcares_la_CFLAGS_EXTRA) +libcares_la_CPPFLAGS = $(AM_CPPFLAGS) $(libcares_la_CPPFLAGS_EXTRA) +CSOURCES = ares__close_sockets.c \ + ares__get_hostent.c \ + ares__parse_into_addrinfo.c \ + ares__readaddrinfo.c \ + ares__sortaddrinfo.c \ + ares__read_line.c \ + ares__timeval.c \ + ares_android.c \ + ares_cancel.c \ + ares_data.c \ + ares_destroy.c \ + ares_expand_name.c \ + ares_expand_string.c \ + ares_fds.c \ + ares_free_hostent.c \ + ares_free_string.c \ + ares_freeaddrinfo.c \ + ares_getaddrinfo.c \ + ares_getenv.c \ + ares_gethostbyaddr.c \ + ares_gethostbyname.c \ + ares_getnameinfo.c \ + ares_getsock.c \ + ares_init.c \ + ares_library_init.c \ + ares_llist.c \ + ares_mkquery.c \ + ares_create_query.c \ + ares_nowarn.c \ + ares_options.c \ + ares_parse_a_reply.c \ + ares_parse_aaaa_reply.c \ + ares_parse_caa_reply.c \ + ares_parse_mx_reply.c \ + ares_parse_naptr_reply.c \ + ares_parse_ns_reply.c \ + ares_parse_ptr_reply.c \ + ares_parse_soa_reply.c \ + ares_parse_srv_reply.c \ + ares_parse_txt_reply.c \ + ares_platform.c \ + ares_process.c \ + ares_query.c \ + ares_search.c \ + ares_send.c \ + ares_strcasecmp.c \ + ares_strdup.c \ + ares_strerror.c \ + ares_strsplit.c \ + ares_timeout.c \ + ares_version.c \ + ares_writev.c \ + bitncmp.c \ + inet_net_pton.c \ + inet_ntop.c \ + windows_port.c + +HHEADERS = ares_android.h \ + ares_data.h \ + ares_getenv.h \ + ares_inet_net_pton.h \ + ares_iphlpapi.h \ + ares_ipv6.h \ + ares_library_init.h \ + ares_llist.h \ + ares_nowarn.h \ + ares_platform.h \ + ares_private.h \ + ares_strcasecmp.h \ + ares_strdup.h \ + ares_strsplit.h \ + ares_writev.h \ + bitncmp.h \ + nameser.h \ + ares_setup.h \ + setup_once.h + + +# Makefile.inc provides the CSOURCES and HHEADERS defines +libcares_la_SOURCES = $(CSOURCES) $(HHEADERS) +all: ares_config.h + $(MAKE) $(AM_MAKEFLAGS) all-recursive + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/lib/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/lib/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(srcdir)/Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +ares_config.h: stamp-h1 + @test -f $@ || rm -f stamp-h1 + @test -f $@ || $(MAKE) $(AM_MAKEFLAGS) stamp-h1 + +stamp-h1: $(srcdir)/ares_config.h.in $(top_builddir)/config.status + @rm -f stamp-h1 + cd $(top_builddir) && $(SHELL) ./config.status src/lib/ares_config.h +$(srcdir)/ares_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + ($(am__cd) $(top_srcdir) && $(AUTOHEADER)) + rm -f stamp-h1 + touch $@ + +distclean-hdr: + -rm -f ares_config.h stamp-h1 + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ + if test -f $$p; then \ + list2="$$list2 $$p"; \ + else :; fi; \ + done; \ + test -z "$$list2" || { \ + echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \ + $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ + done + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + @list='$(lib_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libcares.la: $(libcares_la_OBJECTS) $(libcares_la_DEPENDENCIES) $(EXTRA_libcares_la_DEPENDENCIES) + $(AM_V_CCLD)$(libcares_la_LINK) -rpath $(libdir) $(libcares_la_OBJECTS) $(libcares_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__close_sockets.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__get_hostent.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__read_line.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__readaddrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares__timeval.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_android.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_cancel.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_create_query.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_data.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_destroy.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_name.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_expand_string.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_fds.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_hostent.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_free_string.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getaddrinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getenv.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_getsock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_init.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_library_init.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_llist.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_mkquery.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_nowarn.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_options.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_platform.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_process.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_query.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_search.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_send.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strdup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strerror.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_strsplit.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_timeout.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_version.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-ares_writev.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-bitncmp.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_net_pton.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-inet_ntop.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libcares_la-windows_port.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +libcares_la-ares__close_sockets.lo: ares__close_sockets.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__close_sockets.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__close_sockets.Tpo -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__close_sockets.Tpo $(DEPDIR)/libcares_la-ares__close_sockets.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__close_sockets.c' object='libcares_la-ares__close_sockets.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__close_sockets.lo `test -f 'ares__close_sockets.c' || echo '$(srcdir)/'`ares__close_sockets.c + +libcares_la-ares__get_hostent.lo: ares__get_hostent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__get_hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__get_hostent.Tpo -c -o libcares_la-ares__get_hostent.lo `test -f 'ares__get_hostent.c' || echo '$(srcdir)/'`ares__get_hostent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__get_hostent.Tpo $(DEPDIR)/libcares_la-ares__get_hostent.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__get_hostent.c' object='libcares_la-ares__get_hostent.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__get_hostent.lo `test -f 'ares__get_hostent.c' || echo '$(srcdir)/'`ares__get_hostent.c + +libcares_la-ares__parse_into_addrinfo.lo: ares__parse_into_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__parse_into_addrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Tpo -c -o libcares_la-ares__parse_into_addrinfo.lo `test -f 'ares__parse_into_addrinfo.c' || echo '$(srcdir)/'`ares__parse_into_addrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Tpo $(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__parse_into_addrinfo.c' object='libcares_la-ares__parse_into_addrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__parse_into_addrinfo.lo `test -f 'ares__parse_into_addrinfo.c' || echo '$(srcdir)/'`ares__parse_into_addrinfo.c + +libcares_la-ares__readaddrinfo.lo: ares__readaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__readaddrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__readaddrinfo.Tpo -c -o libcares_la-ares__readaddrinfo.lo `test -f 'ares__readaddrinfo.c' || echo '$(srcdir)/'`ares__readaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__readaddrinfo.Tpo $(DEPDIR)/libcares_la-ares__readaddrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__readaddrinfo.c' object='libcares_la-ares__readaddrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__readaddrinfo.lo `test -f 'ares__readaddrinfo.c' || echo '$(srcdir)/'`ares__readaddrinfo.c + +libcares_la-ares__sortaddrinfo.lo: ares__sortaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__sortaddrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__sortaddrinfo.Tpo -c -o libcares_la-ares__sortaddrinfo.lo `test -f 'ares__sortaddrinfo.c' || echo '$(srcdir)/'`ares__sortaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__sortaddrinfo.Tpo $(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__sortaddrinfo.c' object='libcares_la-ares__sortaddrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__sortaddrinfo.lo `test -f 'ares__sortaddrinfo.c' || echo '$(srcdir)/'`ares__sortaddrinfo.c + +libcares_la-ares__read_line.lo: ares__read_line.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__read_line.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__read_line.Tpo -c -o libcares_la-ares__read_line.lo `test -f 'ares__read_line.c' || echo '$(srcdir)/'`ares__read_line.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__read_line.Tpo $(DEPDIR)/libcares_la-ares__read_line.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__read_line.c' object='libcares_la-ares__read_line.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__read_line.lo `test -f 'ares__read_line.c' || echo '$(srcdir)/'`ares__read_line.c + +libcares_la-ares__timeval.lo: ares__timeval.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares__timeval.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares__timeval.Tpo -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares__timeval.Tpo $(DEPDIR)/libcares_la-ares__timeval.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares__timeval.c' object='libcares_la-ares__timeval.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares__timeval.lo `test -f 'ares__timeval.c' || echo '$(srcdir)/'`ares__timeval.c + +libcares_la-ares_android.lo: ares_android.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_android.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_android.Tpo -c -o libcares_la-ares_android.lo `test -f 'ares_android.c' || echo '$(srcdir)/'`ares_android.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_android.Tpo $(DEPDIR)/libcares_la-ares_android.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_android.c' object='libcares_la-ares_android.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_android.lo `test -f 'ares_android.c' || echo '$(srcdir)/'`ares_android.c + +libcares_la-ares_cancel.lo: ares_cancel.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_cancel.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_cancel.Tpo -c -o libcares_la-ares_cancel.lo `test -f 'ares_cancel.c' || echo '$(srcdir)/'`ares_cancel.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_cancel.Tpo $(DEPDIR)/libcares_la-ares_cancel.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_cancel.c' object='libcares_la-ares_cancel.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_cancel.lo `test -f 'ares_cancel.c' || echo '$(srcdir)/'`ares_cancel.c + +libcares_la-ares_data.lo: ares_data.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_data.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_data.Tpo -c -o libcares_la-ares_data.lo `test -f 'ares_data.c' || echo '$(srcdir)/'`ares_data.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_data.Tpo $(DEPDIR)/libcares_la-ares_data.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_data.c' object='libcares_la-ares_data.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_data.lo `test -f 'ares_data.c' || echo '$(srcdir)/'`ares_data.c + +libcares_la-ares_destroy.lo: ares_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_destroy.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_destroy.Tpo -c -o libcares_la-ares_destroy.lo `test -f 'ares_destroy.c' || echo '$(srcdir)/'`ares_destroy.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_destroy.Tpo $(DEPDIR)/libcares_la-ares_destroy.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_destroy.c' object='libcares_la-ares_destroy.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_destroy.lo `test -f 'ares_destroy.c' || echo '$(srcdir)/'`ares_destroy.c + +libcares_la-ares_expand_name.lo: ares_expand_name.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_name.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_name.Tpo -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_name.Tpo $(DEPDIR)/libcares_la-ares_expand_name.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_name.c' object='libcares_la-ares_expand_name.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_name.lo `test -f 'ares_expand_name.c' || echo '$(srcdir)/'`ares_expand_name.c + +libcares_la-ares_expand_string.lo: ares_expand_string.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_expand_string.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_expand_string.Tpo -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_expand_string.Tpo $(DEPDIR)/libcares_la-ares_expand_string.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_expand_string.c' object='libcares_la-ares_expand_string.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_expand_string.lo `test -f 'ares_expand_string.c' || echo '$(srcdir)/'`ares_expand_string.c + +libcares_la-ares_fds.lo: ares_fds.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_fds.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_fds.Tpo -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_fds.Tpo $(DEPDIR)/libcares_la-ares_fds.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_fds.c' object='libcares_la-ares_fds.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_fds.lo `test -f 'ares_fds.c' || echo '$(srcdir)/'`ares_fds.c + +libcares_la-ares_free_hostent.lo: ares_free_hostent.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_free_hostent.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_free_hostent.Tpo -c -o libcares_la-ares_free_hostent.lo `test -f 'ares_free_hostent.c' || echo '$(srcdir)/'`ares_free_hostent.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_free_hostent.Tpo $(DEPDIR)/libcares_la-ares_free_hostent.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_free_hostent.c' object='libcares_la-ares_free_hostent.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_free_hostent.lo `test -f 'ares_free_hostent.c' || echo '$(srcdir)/'`ares_free_hostent.c + +libcares_la-ares_free_string.lo: ares_free_string.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_free_string.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_free_string.Tpo -c -o libcares_la-ares_free_string.lo `test -f 'ares_free_string.c' || echo '$(srcdir)/'`ares_free_string.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_free_string.Tpo $(DEPDIR)/libcares_la-ares_free_string.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_free_string.c' object='libcares_la-ares_free_string.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_free_string.lo `test -f 'ares_free_string.c' || echo '$(srcdir)/'`ares_free_string.c + +libcares_la-ares_freeaddrinfo.lo: ares_freeaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_freeaddrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_freeaddrinfo.Tpo -c -o libcares_la-ares_freeaddrinfo.lo `test -f 'ares_freeaddrinfo.c' || echo '$(srcdir)/'`ares_freeaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_freeaddrinfo.Tpo $(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_freeaddrinfo.c' object='libcares_la-ares_freeaddrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_freeaddrinfo.lo `test -f 'ares_freeaddrinfo.c' || echo '$(srcdir)/'`ares_freeaddrinfo.c + +libcares_la-ares_getaddrinfo.lo: ares_getaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getaddrinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getaddrinfo.Tpo -c -o libcares_la-ares_getaddrinfo.lo `test -f 'ares_getaddrinfo.c' || echo '$(srcdir)/'`ares_getaddrinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getaddrinfo.Tpo $(DEPDIR)/libcares_la-ares_getaddrinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getaddrinfo.c' object='libcares_la-ares_getaddrinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getaddrinfo.lo `test -f 'ares_getaddrinfo.c' || echo '$(srcdir)/'`ares_getaddrinfo.c + +libcares_la-ares_getenv.lo: ares_getenv.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getenv.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getenv.Tpo -c -o libcares_la-ares_getenv.lo `test -f 'ares_getenv.c' || echo '$(srcdir)/'`ares_getenv.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getenv.Tpo $(DEPDIR)/libcares_la-ares_getenv.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getenv.c' object='libcares_la-ares_getenv.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getenv.lo `test -f 'ares_getenv.c' || echo '$(srcdir)/'`ares_getenv.c + +libcares_la-ares_gethostbyaddr.lo: ares_gethostbyaddr.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_gethostbyaddr.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_gethostbyaddr.Tpo -c -o libcares_la-ares_gethostbyaddr.lo `test -f 'ares_gethostbyaddr.c' || echo '$(srcdir)/'`ares_gethostbyaddr.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_gethostbyaddr.Tpo $(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_gethostbyaddr.c' object='libcares_la-ares_gethostbyaddr.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_gethostbyaddr.lo `test -f 'ares_gethostbyaddr.c' || echo '$(srcdir)/'`ares_gethostbyaddr.c + +libcares_la-ares_gethostbyname.lo: ares_gethostbyname.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_gethostbyname.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_gethostbyname.Tpo -c -o libcares_la-ares_gethostbyname.lo `test -f 'ares_gethostbyname.c' || echo '$(srcdir)/'`ares_gethostbyname.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_gethostbyname.Tpo $(DEPDIR)/libcares_la-ares_gethostbyname.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_gethostbyname.c' object='libcares_la-ares_gethostbyname.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_gethostbyname.lo `test -f 'ares_gethostbyname.c' || echo '$(srcdir)/'`ares_gethostbyname.c + +libcares_la-ares_getnameinfo.lo: ares_getnameinfo.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getnameinfo.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getnameinfo.Tpo -c -o libcares_la-ares_getnameinfo.lo `test -f 'ares_getnameinfo.c' || echo '$(srcdir)/'`ares_getnameinfo.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getnameinfo.Tpo $(DEPDIR)/libcares_la-ares_getnameinfo.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getnameinfo.c' object='libcares_la-ares_getnameinfo.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getnameinfo.lo `test -f 'ares_getnameinfo.c' || echo '$(srcdir)/'`ares_getnameinfo.c + +libcares_la-ares_getsock.lo: ares_getsock.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_getsock.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_getsock.Tpo -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_getsock.Tpo $(DEPDIR)/libcares_la-ares_getsock.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getsock.c' object='libcares_la-ares_getsock.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_getsock.lo `test -f 'ares_getsock.c' || echo '$(srcdir)/'`ares_getsock.c + +libcares_la-ares_init.lo: ares_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_init.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_init.Tpo -c -o libcares_la-ares_init.lo `test -f 'ares_init.c' || echo '$(srcdir)/'`ares_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_init.Tpo $(DEPDIR)/libcares_la-ares_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_init.c' object='libcares_la-ares_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_init.lo `test -f 'ares_init.c' || echo '$(srcdir)/'`ares_init.c + +libcares_la-ares_library_init.lo: ares_library_init.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_library_init.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_library_init.Tpo -c -o libcares_la-ares_library_init.lo `test -f 'ares_library_init.c' || echo '$(srcdir)/'`ares_library_init.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_library_init.Tpo $(DEPDIR)/libcares_la-ares_library_init.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_library_init.c' object='libcares_la-ares_library_init.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_library_init.lo `test -f 'ares_library_init.c' || echo '$(srcdir)/'`ares_library_init.c + +libcares_la-ares_llist.lo: ares_llist.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_llist.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_llist.Tpo -c -o libcares_la-ares_llist.lo `test -f 'ares_llist.c' || echo '$(srcdir)/'`ares_llist.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_llist.Tpo $(DEPDIR)/libcares_la-ares_llist.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_llist.c' object='libcares_la-ares_llist.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_llist.lo `test -f 'ares_llist.c' || echo '$(srcdir)/'`ares_llist.c + +libcares_la-ares_mkquery.lo: ares_mkquery.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_mkquery.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_mkquery.Tpo -c -o libcares_la-ares_mkquery.lo `test -f 'ares_mkquery.c' || echo '$(srcdir)/'`ares_mkquery.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_mkquery.Tpo $(DEPDIR)/libcares_la-ares_mkquery.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_mkquery.c' object='libcares_la-ares_mkquery.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_mkquery.lo `test -f 'ares_mkquery.c' || echo '$(srcdir)/'`ares_mkquery.c + +libcares_la-ares_create_query.lo: ares_create_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_create_query.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_create_query.Tpo -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_create_query.Tpo $(DEPDIR)/libcares_la-ares_create_query.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_create_query.c' object='libcares_la-ares_create_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_create_query.lo `test -f 'ares_create_query.c' || echo '$(srcdir)/'`ares_create_query.c + +libcares_la-ares_nowarn.lo: ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_nowarn.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_nowarn.Tpo -c -o libcares_la-ares_nowarn.lo `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_nowarn.Tpo $(DEPDIR)/libcares_la-ares_nowarn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_nowarn.c' object='libcares_la-ares_nowarn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_nowarn.lo `test -f 'ares_nowarn.c' || echo '$(srcdir)/'`ares_nowarn.c + +libcares_la-ares_options.lo: ares_options.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_options.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_options.Tpo -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_options.Tpo $(DEPDIR)/libcares_la-ares_options.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_options.c' object='libcares_la-ares_options.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_options.lo `test -f 'ares_options.c' || echo '$(srcdir)/'`ares_options.c + +libcares_la-ares_parse_a_reply.lo: ares_parse_a_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_a_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_a_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_a_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_a_reply.c' object='libcares_la-ares_parse_a_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_a_reply.lo `test -f 'ares_parse_a_reply.c' || echo '$(srcdir)/'`ares_parse_a_reply.c + +libcares_la-ares_parse_aaaa_reply.lo: ares_parse_aaaa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_aaaa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_aaaa_reply.c' object='libcares_la-ares_parse_aaaa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_aaaa_reply.lo `test -f 'ares_parse_aaaa_reply.c' || echo '$(srcdir)/'`ares_parse_aaaa_reply.c + +libcares_la-ares_parse_caa_reply.lo: ares_parse_caa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_caa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo -c -o libcares_la-ares_parse_caa_reply.lo `test -f 'ares_parse_caa_reply.c' || echo '$(srcdir)/'`ares_parse_caa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_caa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_caa_reply.c' object='libcares_la-ares_parse_caa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_caa_reply.lo `test -f 'ares_parse_caa_reply.c' || echo '$(srcdir)/'`ares_parse_caa_reply.c + +libcares_la-ares_parse_mx_reply.lo: ares_parse_mx_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_mx_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_mx_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_mx_reply.c' object='libcares_la-ares_parse_mx_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_mx_reply.lo `test -f 'ares_parse_mx_reply.c' || echo '$(srcdir)/'`ares_parse_mx_reply.c + +libcares_la-ares_parse_naptr_reply.lo: ares_parse_naptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_naptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_naptr_reply.c' object='libcares_la-ares_parse_naptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_naptr_reply.lo `test -f 'ares_parse_naptr_reply.c' || echo '$(srcdir)/'`ares_parse_naptr_reply.c + +libcares_la-ares_parse_ns_reply.lo: ares_parse_ns_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ns_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ns_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ns_reply.c' object='libcares_la-ares_parse_ns_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ns_reply.lo `test -f 'ares_parse_ns_reply.c' || echo '$(srcdir)/'`ares_parse_ns_reply.c + +libcares_la-ares_parse_ptr_reply.lo: ares_parse_ptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_ptr_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_ptr_reply.c' object='libcares_la-ares_parse_ptr_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_ptr_reply.lo `test -f 'ares_parse_ptr_reply.c' || echo '$(srcdir)/'`ares_parse_ptr_reply.c + +libcares_la-ares_parse_soa_reply.lo: ares_parse_soa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_soa_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_soa_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_soa_reply.c' object='libcares_la-ares_parse_soa_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_soa_reply.lo `test -f 'ares_parse_soa_reply.c' || echo '$(srcdir)/'`ares_parse_soa_reply.c + +libcares_la-ares_parse_srv_reply.lo: ares_parse_srv_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_srv_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_srv_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_srv_reply.c' object='libcares_la-ares_parse_srv_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_srv_reply.lo `test -f 'ares_parse_srv_reply.c' || echo '$(srcdir)/'`ares_parse_srv_reply.c + +libcares_la-ares_parse_txt_reply.lo: ares_parse_txt_reply.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_parse_txt_reply.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_parse_txt_reply.Tpo $(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_parse_txt_reply.c' object='libcares_la-ares_parse_txt_reply.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_parse_txt_reply.lo `test -f 'ares_parse_txt_reply.c' || echo '$(srcdir)/'`ares_parse_txt_reply.c + +libcares_la-ares_platform.lo: ares_platform.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_platform.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_platform.Tpo -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_platform.Tpo $(DEPDIR)/libcares_la-ares_platform.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_platform.c' object='libcares_la-ares_platform.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_platform.lo `test -f 'ares_platform.c' || echo '$(srcdir)/'`ares_platform.c + +libcares_la-ares_process.lo: ares_process.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_process.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_process.Tpo -c -o libcares_la-ares_process.lo `test -f 'ares_process.c' || echo '$(srcdir)/'`ares_process.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_process.Tpo $(DEPDIR)/libcares_la-ares_process.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_process.c' object='libcares_la-ares_process.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_process.lo `test -f 'ares_process.c' || echo '$(srcdir)/'`ares_process.c + +libcares_la-ares_query.lo: ares_query.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_query.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_query.Tpo -c -o libcares_la-ares_query.lo `test -f 'ares_query.c' || echo '$(srcdir)/'`ares_query.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_query.Tpo $(DEPDIR)/libcares_la-ares_query.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_query.c' object='libcares_la-ares_query.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_query.lo `test -f 'ares_query.c' || echo '$(srcdir)/'`ares_query.c + +libcares_la-ares_search.lo: ares_search.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_search.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_search.Tpo -c -o libcares_la-ares_search.lo `test -f 'ares_search.c' || echo '$(srcdir)/'`ares_search.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_search.Tpo $(DEPDIR)/libcares_la-ares_search.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_search.c' object='libcares_la-ares_search.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_search.lo `test -f 'ares_search.c' || echo '$(srcdir)/'`ares_search.c + +libcares_la-ares_send.lo: ares_send.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_send.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_send.Tpo -c -o libcares_la-ares_send.lo `test -f 'ares_send.c' || echo '$(srcdir)/'`ares_send.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_send.Tpo $(DEPDIR)/libcares_la-ares_send.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_send.c' object='libcares_la-ares_send.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_send.lo `test -f 'ares_send.c' || echo '$(srcdir)/'`ares_send.c + +libcares_la-ares_strcasecmp.lo: ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strcasecmp.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strcasecmp.Tpo $(DEPDIR)/libcares_la-ares_strcasecmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strcasecmp.c' object='libcares_la-ares_strcasecmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strcasecmp.lo `test -f 'ares_strcasecmp.c' || echo '$(srcdir)/'`ares_strcasecmp.c + +libcares_la-ares_strdup.lo: ares_strdup.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strdup.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strdup.Tpo -c -o libcares_la-ares_strdup.lo `test -f 'ares_strdup.c' || echo '$(srcdir)/'`ares_strdup.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strdup.Tpo $(DEPDIR)/libcares_la-ares_strdup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strdup.c' object='libcares_la-ares_strdup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strdup.lo `test -f 'ares_strdup.c' || echo '$(srcdir)/'`ares_strdup.c + +libcares_la-ares_strerror.lo: ares_strerror.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strerror.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strerror.Tpo -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strerror.Tpo $(DEPDIR)/libcares_la-ares_strerror.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strerror.c' object='libcares_la-ares_strerror.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strerror.lo `test -f 'ares_strerror.c' || echo '$(srcdir)/'`ares_strerror.c + +libcares_la-ares_strsplit.lo: ares_strsplit.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_strsplit.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_strsplit.Tpo -c -o libcares_la-ares_strsplit.lo `test -f 'ares_strsplit.c' || echo '$(srcdir)/'`ares_strsplit.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_strsplit.Tpo $(DEPDIR)/libcares_la-ares_strsplit.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_strsplit.c' object='libcares_la-ares_strsplit.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_strsplit.lo `test -f 'ares_strsplit.c' || echo '$(srcdir)/'`ares_strsplit.c + +libcares_la-ares_timeout.lo: ares_timeout.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_timeout.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_timeout.Tpo -c -o libcares_la-ares_timeout.lo `test -f 'ares_timeout.c' || echo '$(srcdir)/'`ares_timeout.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_timeout.Tpo $(DEPDIR)/libcares_la-ares_timeout.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_timeout.c' object='libcares_la-ares_timeout.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_timeout.lo `test -f 'ares_timeout.c' || echo '$(srcdir)/'`ares_timeout.c + +libcares_la-ares_version.lo: ares_version.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_version.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_version.Tpo -c -o libcares_la-ares_version.lo `test -f 'ares_version.c' || echo '$(srcdir)/'`ares_version.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_version.Tpo $(DEPDIR)/libcares_la-ares_version.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_version.c' object='libcares_la-ares_version.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_version.lo `test -f 'ares_version.c' || echo '$(srcdir)/'`ares_version.c + +libcares_la-ares_writev.lo: ares_writev.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-ares_writev.lo -MD -MP -MF $(DEPDIR)/libcares_la-ares_writev.Tpo -c -o libcares_la-ares_writev.lo `test -f 'ares_writev.c' || echo '$(srcdir)/'`ares_writev.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-ares_writev.Tpo $(DEPDIR)/libcares_la-ares_writev.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_writev.c' object='libcares_la-ares_writev.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-ares_writev.lo `test -f 'ares_writev.c' || echo '$(srcdir)/'`ares_writev.c + +libcares_la-bitncmp.lo: bitncmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-bitncmp.lo -MD -MP -MF $(DEPDIR)/libcares_la-bitncmp.Tpo -c -o libcares_la-bitncmp.lo `test -f 'bitncmp.c' || echo '$(srcdir)/'`bitncmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-bitncmp.Tpo $(DEPDIR)/libcares_la-bitncmp.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='bitncmp.c' object='libcares_la-bitncmp.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-bitncmp.lo `test -f 'bitncmp.c' || echo '$(srcdir)/'`bitncmp.c + +libcares_la-inet_net_pton.lo: inet_net_pton.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-inet_net_pton.lo -MD -MP -MF $(DEPDIR)/libcares_la-inet_net_pton.Tpo -c -o libcares_la-inet_net_pton.lo `test -f 'inet_net_pton.c' || echo '$(srcdir)/'`inet_net_pton.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-inet_net_pton.Tpo $(DEPDIR)/libcares_la-inet_net_pton.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_net_pton.c' object='libcares_la-inet_net_pton.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-inet_net_pton.lo `test -f 'inet_net_pton.c' || echo '$(srcdir)/'`inet_net_pton.c + +libcares_la-inet_ntop.lo: inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-inet_ntop.lo -MD -MP -MF $(DEPDIR)/libcares_la-inet_ntop.Tpo -c -o libcares_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-inet_ntop.Tpo $(DEPDIR)/libcares_la-inet_ntop.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='inet_ntop.c' object='libcares_la-inet_ntop.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-inet_ntop.lo `test -f 'inet_ntop.c' || echo '$(srcdir)/'`inet_ntop.c + +libcares_la-windows_port.lo: windows_port.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -MT libcares_la-windows_port.lo -MD -MP -MF $(DEPDIR)/libcares_la-windows_port.Tpo -c -o libcares_la-windows_port.lo `test -f 'windows_port.c' || echo '$(srcdir)/'`windows_port.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libcares_la-windows_port.Tpo $(DEPDIR)/libcares_la-windows_port.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='windows_port.c' object='libcares_la-windows_port.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libcares_la_CPPFLAGS) $(CPPFLAGS) $(libcares_la_CFLAGS) $(CFLAGS) -c -o libcares_la-windows_port.lo `test -f 'windows_port.c' || echo '$(srcdir)/'`windows_port.c + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +# This directory's subdirectories are mostly independent; you can cd +# into them and run 'make' without going through this Makefile. +# To change the values of 'make' variables: instead of editing Makefiles, +# (1) if the variable is set in 'config.status', edit 'config.status' +# (which will cause the Makefiles to be regenerated when you run 'make'); +# (2) otherwise, pass the desired values on the 'make' command line. +$(am__recursive_targets): + @fail=; \ + if $(am__make_keepgoing); then \ + failcom='fail=yes'; \ + else \ + failcom='exit 1'; \ + fi; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + case "$@" in \ + distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \ + *) list='$(SUBDIRS)' ;; \ + esac; \ + for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || eval $$failcom; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-recursive +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \ + include_option=--etags-include; \ + empty_fix=.; \ + else \ + include_option=--include; \ + empty_fix=; \ + fi; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test ! -f $$subdir/TAGS || \ + set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \ + fi; \ + done; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-recursive + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-recursive + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done + @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + $(am__make_dryrun) \ + || test -d "$(distdir)/$$subdir" \ + || $(MKDIR_P) "$(distdir)/$$subdir" \ + || exit 1; \ + dir1=$$subdir; dir2="$(distdir)/$$subdir"; \ + $(am__relativize); \ + new_distdir=$$reldir; \ + dir1=$$subdir; dir2="$(top_distdir)"; \ + $(am__relativize); \ + new_top_distdir=$$reldir; \ + echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \ + echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \ + ($(am__cd) $$subdir && \ + $(MAKE) $(AM_MAKEFLAGS) \ + top_distdir="$$new_top_distdir" \ + distdir="$$new_distdir" \ + am__remove_distdir=: \ + am__skip_length_check=: \ + am__skip_mode_fix=: \ + distdir) \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-recursive +all-am: Makefile $(LTLIBRARIES) ares_config.h +installdirs: installdirs-recursive +installdirs-am: + for dir in "$(DESTDIR)$(libdir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ + done +install: install-recursive +install-exec: install-exec-recursive +install-data: install-data-recursive +uninstall: uninstall-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-recursive +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-recursive + +clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ + mostlyclean-am + +distclean: distclean-recursive + -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__get_hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__read_line.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__readaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__timeval.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_android.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_cancel.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_data.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_destroy.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_expand_name.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_expand_string.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_fds.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_free_string.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getenv.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getsock.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_init.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_library_init.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_llist.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_mkquery.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_nowarn.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_options.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_search.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_send.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strdup.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strerror.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strsplit.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_timeout.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_version.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_writev.Plo + -rm -f ./$(DEPDIR)/libcares_la-bitncmp.Plo + -rm -f ./$(DEPDIR)/libcares_la-inet_net_pton.Plo + -rm -f ./$(DEPDIR)/libcares_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcares_la-windows_port.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-hdr distclean-tags + +dvi: dvi-recursive + +dvi-am: + +html: html-recursive + +html-am: + +info: info-recursive + +info-am: + +install-data-am: + +install-dvi: install-dvi-recursive + +install-dvi-am: + +install-exec-am: install-libLTLIBRARIES + +install-html: install-html-recursive + +install-html-am: + +install-info: install-info-recursive + +install-info-am: + +install-man: + +install-pdf: install-pdf-recursive + +install-pdf-am: + +install-ps: install-ps-recursive + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-recursive + -rm -f ./$(DEPDIR)/libcares_la-ares__close_sockets.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__get_hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__parse_into_addrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__read_line.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__readaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__sortaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares__timeval.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_android.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_cancel.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_create_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_data.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_destroy.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_expand_name.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_expand_string.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_fds.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_free_hostent.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_free_string.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_freeaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getaddrinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getenv.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyaddr.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_gethostbyname.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getnameinfo.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_getsock.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_init.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_library_init.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_llist.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_mkquery.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_nowarn.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_options.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_a_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_aaaa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_caa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_mx_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_naptr_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ns_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_ptr_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_soa_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_srv_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_parse_txt_reply.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_platform.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_process.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_query.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_search.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_send.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strcasecmp.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strdup.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strerror.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_strsplit.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_timeout.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_version.Plo + -rm -f ./$(DEPDIR)/libcares_la-ares_writev.Plo + -rm -f ./$(DEPDIR)/libcares_la-bitncmp.Plo + -rm -f ./$(DEPDIR)/libcares_la-inet_net_pton.Plo + -rm -f ./$(DEPDIR)/libcares_la-inet_ntop.Plo + -rm -f ./$(DEPDIR)/libcares_la-windows_port.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-recursive + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-recursive + +pdf-am: + +ps: ps-recursive + +ps-am: + +uninstall-am: uninstall-libLTLIBRARIES + +.MAKE: $(am__recursive_targets) all install-am install-strip + +.PHONY: $(am__recursive_targets) CTAGS GTAGS TAGS all all-am \ + am--depfiles check check-am clean clean-generic \ + clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \ + ctags-am distclean distclean-compile distclean-generic \ + distclean-hdr distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-libLTLIBRARIES \ + install-man install-pdf install-pdf-am install-ps \ + install-ps-am install-strip installcheck installcheck-am \ + installdirs installdirs-am maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am uninstall-libLTLIBRARIES + +.PRECIOUS: Makefile + + +@CODE_COVERAGE_RULES@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc new file mode 100644 index 0000000..4695e11 --- /dev/null +++ b/src/lib/Makefile.inc @@ -0,0 +1,79 @@ + +CSOURCES = ares__close_sockets.c \ + ares__get_hostent.c \ + ares__parse_into_addrinfo.c \ + ares__readaddrinfo.c \ + ares__sortaddrinfo.c \ + ares__read_line.c \ + ares__timeval.c \ + ares_android.c \ + ares_cancel.c \ + ares_data.c \ + ares_destroy.c \ + ares_expand_name.c \ + ares_expand_string.c \ + ares_fds.c \ + ares_free_hostent.c \ + ares_free_string.c \ + ares_freeaddrinfo.c \ + ares_getaddrinfo.c \ + ares_getenv.c \ + ares_gethostbyaddr.c \ + ares_gethostbyname.c \ + ares_getnameinfo.c \ + ares_getsock.c \ + ares_init.c \ + ares_library_init.c \ + ares_llist.c \ + ares_mkquery.c \ + ares_create_query.c \ + ares_nowarn.c \ + ares_options.c \ + ares_parse_a_reply.c \ + ares_parse_aaaa_reply.c \ + ares_parse_caa_reply.c \ + ares_parse_mx_reply.c \ + ares_parse_naptr_reply.c \ + ares_parse_ns_reply.c \ + ares_parse_ptr_reply.c \ + ares_parse_soa_reply.c \ + ares_parse_srv_reply.c \ + ares_parse_txt_reply.c \ + ares_platform.c \ + ares_process.c \ + ares_query.c \ + ares_search.c \ + ares_send.c \ + ares_strcasecmp.c \ + ares_strdup.c \ + ares_strerror.c \ + ares_strsplit.c \ + ares_timeout.c \ + ares_version.c \ + ares_writev.c \ + bitncmp.c \ + inet_net_pton.c \ + inet_ntop.c \ + windows_port.c + +HHEADERS = ares_android.h \ + ares_data.h \ + ares_getenv.h \ + ares_inet_net_pton.h \ + ares_iphlpapi.h \ + ares_ipv6.h \ + ares_library_init.h \ + ares_llist.h \ + ares_nowarn.h \ + ares_platform.h \ + ares_private.h \ + ares_strcasecmp.h \ + ares_strdup.h \ + ares_strsplit.h \ + ares_writev.h \ + bitncmp.h \ + nameser.h \ + ares_setup.h \ + setup_once.h + + diff --git a/ares__close_sockets.c b/src/lib/ares__close_sockets.c similarity index 94% rename from ares__close_sockets.c rename to src/lib/ares__close_sockets.c index 6c66483..0477174 100644 --- a/ares__close_sockets.c +++ b/src/lib/ares__close_sockets.c @@ -48,14 +48,14 @@ void ares__close_sockets(ares_channel channel, struct server_state *server) if (server->tcp_socket != ARES_SOCKET_BAD) { SOCK_STATE_CALLBACK(channel, server->tcp_socket, 0, 0); - sclose(server->tcp_socket); + ares__close_socket(channel, server->tcp_socket); server->tcp_socket = ARES_SOCKET_BAD; server->tcp_connection_generation = ++channel->tcp_connection_generation; } if (server->udp_socket != ARES_SOCKET_BAD) { SOCK_STATE_CALLBACK(channel, server->udp_socket, 0, 0); - sclose(server->udp_socket); + ares__close_socket(channel, server->udp_socket); server->udp_socket = ARES_SOCKET_BAD; } } diff --git a/ares__get_hostent.c b/src/lib/ares__get_hostent.c similarity index 98% rename from ares__get_hostent.c rename to src/lib/ares__get_hostent.c index d2f9503..367f390 100644 --- a/ares__get_hostent.c +++ b/src/lib/ares__get_hostent.c @@ -138,8 +138,7 @@ int ares__get_hostent(FILE *fp, int family, struct hostent **host) addr.addrV4.s_addr = INADDR_NONE; if ((family == AF_INET) || (family == AF_UNSPEC)) { - addr.addrV4.s_addr = inet_addr(txtaddr); - if (addr.addrV4.s_addr != INADDR_NONE) + if (ares_inet_pton(AF_INET, txtaddr, &addr.addrV4) > 0) { /* Actual network address family and length. */ addr.family = AF_INET; diff --git a/src/lib/ares__parse_into_addrinfo.c b/src/lib/ares__parse_into_addrinfo.c new file mode 100644 index 0000000..b080163 --- /dev/null +++ b/src/lib/ares__parse_into_addrinfo.c @@ -0,0 +1,266 @@ +/* Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#ifdef HAVE_STRINGS_H +# include +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" + +int ares__parse_into_addrinfo2(const unsigned char *abuf, + int alen, + char **question_hostname, + struct ares_addrinfo *ai) +{ + unsigned int qdcount, ancount; + int status, i, rr_type, rr_class, rr_len, rr_ttl; + int got_a = 0, got_aaaa = 0, got_cname = 0; + long len; + const unsigned char *aptr; + char *hostname, *rr_name = NULL, *rr_data; + struct ares_addrinfo_cname *cname, *cnames = NULL; + struct ares_addrinfo_node *node, *nodes = NULL; + struct sockaddr_in *sin; + struct sockaddr_in6 *sin6; + + *question_hostname = NULL; + + /* Give up if abuf doesn't have room for a header. */ + if (alen < HFIXEDSZ) + return ARES_EBADRESP; + + /* Fetch the question and answer count from the header. */ + qdcount = DNS_HEADER_QDCOUNT(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + if (qdcount != 1) + return ARES_EBADRESP; + + + /* Expand the name from the question, and skip past the question. */ + aptr = abuf + HFIXEDSZ; + status = ares__expand_name_for_response(aptr, abuf, alen, question_hostname, &len); + if (status != ARES_SUCCESS) + return status; + if (aptr + len + QFIXEDSZ > abuf + alen) + { + return ARES_EBADRESP; + } + + hostname = *question_hostname; + + aptr += len + QFIXEDSZ; + + /* Examine each answer resource record (RR) in turn. */ + for (i = 0; i < (int)ancount; i++) + { + /* Decode the RR up to the data field. */ + status = ares__expand_name_for_response(aptr, abuf, alen, &rr_name, &len); + if (status != ARES_SUCCESS) + { + rr_name = NULL; + goto failed_stat; + } + + aptr += len; + if (aptr + RRFIXEDSZ > abuf + alen) + { + status = ARES_EBADRESP; + goto failed_stat; + } + rr_type = DNS_RR_TYPE(aptr); + rr_class = DNS_RR_CLASS(aptr); + rr_len = DNS_RR_LEN(aptr); + rr_ttl = DNS_RR_TTL(aptr); + aptr += RRFIXEDSZ; + if (aptr + rr_len > abuf + alen) + { + status = ARES_EBADRESP; + goto failed_stat; + } + + if (rr_class == C_IN && rr_type == T_A + && rr_len == sizeof(struct in_addr) + && strcasecmp(rr_name, hostname) == 0) + { + got_a = 1; + if (aptr + sizeof(struct in_addr) > abuf + alen) + { /* LCOV_EXCL_START: already checked above */ + status = ARES_EBADRESP; + goto failed_stat; + } /* LCOV_EXCL_STOP */ + + node = ares__append_addrinfo_node(&nodes); + if (!node) + { + status = ARES_ENOMEM; + goto failed_stat; + } + + sin = ares_malloc(sizeof(struct sockaddr_in)); + if (!sin) + { + status = ARES_ENOMEM; + goto failed_stat; + } + memset(sin, 0, sizeof(struct sockaddr_in)); + memcpy(&sin->sin_addr.s_addr, aptr, sizeof(struct in_addr)); + sin->sin_family = AF_INET; + + node->ai_addr = (struct sockaddr *)sin; + node->ai_family = AF_INET; + node->ai_addrlen = sizeof(struct sockaddr_in); + + node->ai_ttl = rr_ttl; + + status = ARES_SUCCESS; + } + else if (rr_class == C_IN && rr_type == T_AAAA + && rr_len == sizeof(struct ares_in6_addr) + && strcasecmp(rr_name, hostname) == 0) + { + got_aaaa = 1; + if (aptr + sizeof(struct ares_in6_addr) > abuf + alen) + { /* LCOV_EXCL_START: already checked above */ + status = ARES_EBADRESP; + goto failed_stat; + } /* LCOV_EXCL_STOP */ + + node = ares__append_addrinfo_node(&nodes); + if (!node) + { + status = ARES_ENOMEM; + goto failed_stat; + } + + sin6 = ares_malloc(sizeof(struct sockaddr_in6)); + if (!sin6) + { + status = ARES_ENOMEM; + goto failed_stat; + } + + memset(sin6, 0, sizeof(struct sockaddr_in6)); + memcpy(&sin6->sin6_addr.s6_addr, aptr, sizeof(struct ares_in6_addr)); + sin6->sin6_family = AF_INET6; + + node->ai_addr = (struct sockaddr *)sin6; + node->ai_family = AF_INET6; + node->ai_addrlen = sizeof(struct sockaddr_in6); + + node->ai_ttl = rr_ttl; + + status = ARES_SUCCESS; + } + + if (rr_class == C_IN && rr_type == T_CNAME) + { + got_cname = 1; + status = ares__expand_name_for_response(aptr, abuf, alen, &rr_data, + &len); + if (status != ARES_SUCCESS) + { + goto failed_stat; + } + + /* Decode the RR data and replace the hostname with it. */ + /* SA: Seems wrong as it introduses order dependency. */ + hostname = rr_data; + + cname = ares__append_addrinfo_cname(&cnames); + if (!cname) + { + status = ARES_ENOMEM; + ares_free(rr_data); + goto failed_stat; + } + cname->ttl = rr_ttl; + cname->alias = rr_name; + cname->name = rr_data; + } + else + { + ares_free(rr_name); + } + + + aptr += rr_len; + if (aptr > abuf + alen) + { /* LCOV_EXCL_START: already checked above */ + status = ARES_EBADRESP; + goto failed_stat; + } /* LCOV_EXCL_STOP */ + } + + if (status == ARES_SUCCESS) + { + ares__addrinfo_cat_nodes(&ai->nodes, nodes); + if (got_cname) + { + ares__addrinfo_cat_cnames(&ai->cnames, cnames); + return status; + } + else if (got_a == 0 && got_aaaa == 0) + { + /* the check for naliases to be zero is to make sure CNAME responses + don't get caught here */ + status = ARES_ENODATA; + } + } + + return status; + +failed_stat: + ares_free(rr_name); + ares__freeaddrinfo_cnames(cnames); + ares__freeaddrinfo_nodes(nodes); + return status; +} + +int ares__parse_into_addrinfo(const unsigned char *abuf, + int alen, + struct ares_addrinfo *ai) +{ + int status; + char *question_hostname; + status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, ai); + ares_free(question_hostname); + return status; +} diff --git a/ares__read_line.c b/src/lib/ares__read_line.c similarity index 100% rename from ares__read_line.c rename to src/lib/ares__read_line.c diff --git a/src/lib/ares__readaddrinfo.c b/src/lib/ares__readaddrinfo.c new file mode 100644 index 0000000..2b5bb40 --- /dev/null +++ b/src/lib/ares__readaddrinfo.c @@ -0,0 +1,264 @@ +/* Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif + +#include "ares.h" +#include "ares_inet_net_pton.h" +#include "ares_nowarn.h" +#include "ares_private.h" + +#define MAX_ALIASES 40 + +int ares__readaddrinfo(FILE *fp, + const char *name, + unsigned short port, + const struct ares_addrinfo_hints *hints, + struct ares_addrinfo *ai) +{ + char *line = NULL, *p, *q; + char *txtaddr, *txthost, *txtalias; + char *aliases[MAX_ALIASES]; + unsigned int i, alias_count; + int status; + size_t linesize; + ares_sockaddr addr; + struct ares_addrinfo_cname *cname = NULL, *cnames = NULL; + struct ares_addrinfo_node *node = NULL, *nodes = NULL; + int match_with_alias, match_with_canonical; + int want_cname = hints->ai_flags & ARES_AI_CANONNAME; + + /* Validate family */ + switch (hints->ai_family) { + case AF_INET: + case AF_INET6: + case AF_UNSPEC: + break; + default: + return ARES_EBADFAMILY; + } + + + while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) + { + match_with_alias = 0; + match_with_canonical = 0; + alias_count = 0; + /* Trim line comment. */ + p = line; + while (*p && (*p != '#')) + p++; + *p = '\0'; + + /* Trim trailing whitespace. */ + q = p - 1; + while ((q >= line) && ISSPACE(*q)) + q--; + *++q = '\0'; + + /* Skip leading whitespace. */ + p = line; + while (*p && ISSPACE(*p)) + p++; + if (!*p) + /* Ignore line if empty. */ + continue; + + /* Pointer to start of IPv4 or IPv6 address part. */ + txtaddr = p; + + /* Advance past address part. */ + while (*p && !ISSPACE(*p)) + p++; + if (!*p) + /* Ignore line if reached end of line. */ + continue; + + /* Null terminate address part. */ + *p = '\0'; + + /* Advance to host name */ + p++; + while (*p && ISSPACE(*p)) + p++; + if (!*p) + /* Ignore line if reached end of line. */ + continue; /* LCOV_EXCL_LINE: trailing whitespace already stripped */ + + /* Pointer to start of host name. */ + txthost = p; + + /* Advance past host name. */ + while (*p && !ISSPACE(*p)) + p++; + + /* Pointer to start of first alias. */ + txtalias = NULL; + if (*p) + { + q = p + 1; + while (*q && ISSPACE(*q)) + q++; + if (*q) + txtalias = q; + } + + /* Null terminate host name. */ + *p = '\0'; + + /* Find out if host name matches with canonical host name. */ + if (strcasecmp(txthost, name) == 0) + { + match_with_canonical = 1; + } + + /* Find out if host name matches with one of the aliases. */ + while (txtalias) + { + p = txtalias; + while (*p && !ISSPACE(*p)) + p++; + q = p; + while (*q && ISSPACE(*q)) + q++; + *p = '\0'; + if (strcasecmp(txtalias, name) == 0) + { + match_with_alias = 1; + if (!want_cname) + break; + } + if (alias_count < MAX_ALIASES) + { + aliases[alias_count++] = txtalias; + } + txtalias = *q ? q : NULL; + } + + /* Try next line if host does not match. */ + if (!match_with_alias && !match_with_canonical) + { + continue; + } + + /* Zero-out 'addr' struct, as there are members that we may not set, especially + * for ipv6. We don't want garbage data */ + memset(&addr, 0, sizeof(addr)); + + /* + * Convert address string to network address for the requested families. + * Actual address family possible values are AF_INET and AF_INET6 only. + */ + if ((hints->ai_family == AF_INET) || (hints->ai_family == AF_UNSPEC)) + { + addr.sa4.sin_port = htons(port); + if (ares_inet_pton(AF_INET, txtaddr, &addr.sa4.sin_addr) > 0) + { + node = ares__append_addrinfo_node(&nodes); + if(!node) + { + goto enomem; + } + + node->ai_family = addr.sa.sa_family = AF_INET; + node->ai_addrlen = sizeof(addr.sa4); + node->ai_addr = ares_malloc(sizeof(addr.sa4)); + if (!node->ai_addr) + { + goto enomem; + } + memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4)); + } + } + if ((hints->ai_family == AF_INET6) || (hints->ai_family == AF_UNSPEC)) + { + addr.sa6.sin6_port = htons(port); + if (ares_inet_pton(AF_INET6, txtaddr, &addr.sa6.sin6_addr) > 0) + { + node = ares__append_addrinfo_node(&nodes); + if (!node) + { + goto enomem; + } + + node->ai_family = addr.sa.sa_family = AF_INET6; + node->ai_addrlen = sizeof(addr.sa6); + node->ai_addr = ares_malloc(sizeof(addr.sa6)); + if (!node->ai_addr) + { + goto enomem; + } + memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6)); + } + } + if (!node) + /* Ignore line if invalid address string for the requested family. */ + continue; + + if (want_cname) + { + for (i = 0; i < alias_count; ++i) + { + cname = ares__append_addrinfo_cname(&cnames); + if (!cname) + { + goto enomem; + } + cname->alias = ares_strdup(aliases[i]); + cname->name = ares_strdup(txthost); + } + /* No aliases, cname only. */ + if(!alias_count) + { + cname = ares__append_addrinfo_cname(&cnames); + if (!cname) + { + goto enomem; + } + cname->name = ares_strdup(txthost); + } + } + } + + /* Last read failed. */ + if (status == ARES_ENOMEM) + { + goto enomem; + } + + /* Free line buffer. */ + ares_free(line); + + ares__addrinfo_cat_cnames(&ai->cnames, cnames); + ares__addrinfo_cat_nodes(&ai->nodes, nodes); + + return node ? ARES_SUCCESS : ARES_ENOTFOUND; + +enomem: + ares_free(line); + ares__freeaddrinfo_cnames(cnames); + ares__freeaddrinfo_nodes(nodes); + return ARES_ENOMEM; +} diff --git a/src/lib/ares__sortaddrinfo.c b/src/lib/ares__sortaddrinfo.c new file mode 100644 index 0000000..0ad3a5b --- /dev/null +++ b/src/lib/ares__sortaddrinfo.c @@ -0,0 +1,495 @@ +/* + * Original file name getaddrinfo.c + * Lifted from the 'Android Bionic' project with the BSD license. + */ + +/* + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. + * Copyright (C) 2018 The Android Open Source Project + * Copyright (C) 2019 by Andrew Selivanov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the project 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 PROJECT 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 PROJECT OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_STRINGS_H +# include +#endif + +#include +#include + +#include "ares.h" +#include "ares_private.h" + +struct addrinfo_sort_elem +{ + struct ares_addrinfo_node *ai; + int has_src_addr; + ares_sockaddr src_addr; + int original_order; +}; + +#define ARES_IPV6_ADDR_MC_SCOPE(a) ((a)->s6_addr[1] & 0x0f) + +#define ARES_IPV6_ADDR_SCOPE_NODELOCAL 0x01 +#define ARES_IPV6_ADDR_SCOPE_INTFACELOCAL 0x01 +#define ARES_IPV6_ADDR_SCOPE_LINKLOCAL 0x02 +#define ARES_IPV6_ADDR_SCOPE_SITELOCAL 0x05 +#define ARES_IPV6_ADDR_SCOPE_ORGLOCAL 0x08 +#define ARES_IPV6_ADDR_SCOPE_GLOBAL 0x0e + +#define ARES_IN_LOOPBACK(a) ((((long int)(a)) & 0xff000000) == 0x7f000000) + +/* RFC 4193. */ +#define ARES_IN6_IS_ADDR_ULA(a) (((a)->s6_addr[0] & 0xfe) == 0xfc) + +/* These macros are modelled after the ones in . */ +/* RFC 4380, section 2.6 */ +#define ARES_IN6_IS_ADDR_TEREDO(a) \ + ((*(const unsigned int *)(const void *)(&(a)->s6_addr[0]) == ntohl(0x20010000))) +/* RFC 3056, section 2. */ +#define ARES_IN6_IS_ADDR_6TO4(a) \ + (((a)->s6_addr[0] == 0x20) && ((a)->s6_addr[1] == 0x02)) +/* 6bone testing address area (3ffe::/16), deprecated in RFC 3701. */ +#define ARES_IN6_IS_ADDR_6BONE(a) \ + (((a)->s6_addr[0] == 0x3f) && ((a)->s6_addr[1] == 0xfe)) + + +static int get_scope(const struct sockaddr *addr) +{ + if (addr->sa_family == AF_INET6) + { + const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); + if (IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)) + { + return ARES_IPV6_ADDR_MC_SCOPE(&addr6->sin6_addr); + } + else if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr) || + IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)) + { + /* + * RFC 4291 section 2.5.3 says loopback is to be treated as having + * link-local scope. + */ + return ARES_IPV6_ADDR_SCOPE_LINKLOCAL; + } + else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) + { + return ARES_IPV6_ADDR_SCOPE_SITELOCAL; + } + else + { + return ARES_IPV6_ADDR_SCOPE_GLOBAL; + } + } + else if (addr->sa_family == AF_INET) + { + const struct sockaddr_in *addr4 = CARES_INADDR_CAST(const struct sockaddr_in *, addr); + unsigned long int na = ntohl(addr4->sin_addr.s_addr); + if (ARES_IN_LOOPBACK(na) || /* 127.0.0.0/8 */ + (na & 0xffff0000) == 0xa9fe0000) /* 169.254.0.0/16 */ + { + return ARES_IPV6_ADDR_SCOPE_LINKLOCAL; + } + else + { + /* + * RFC 6724 section 3.2. Other IPv4 addresses, including private + * addresses and shared addresses (100.64.0.0/10), are assigned global + * scope. + */ + return ARES_IPV6_ADDR_SCOPE_GLOBAL; + } + } + else + { + /* + * This should never happen. + * Return a scope with low priority as a last resort. + */ + return ARES_IPV6_ADDR_SCOPE_NODELOCAL; + } +} + +static int get_label(const struct sockaddr *addr) +{ + if (addr->sa_family == AF_INET) + { + return 4; + } + else if (addr->sa_family == AF_INET6) + { + const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); + if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) + { + return 0; + } + else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) + { + return 4; + } + else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) + { + return 2; + } + else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) + { + return 5; + } + else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr)) + { + return 13; + } + else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr)) + { + return 3; + } + else if (IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)) + { + return 11; + } + else if (ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) + { + return 12; + } + else + { + /* All other IPv6 addresses, including global unicast addresses. */ + return 1; + } + } + else + { + /* + * This should never happen. + * Return a semi-random label as a last resort. + */ + return 1; + } +} + +/* + * Get the precedence for a given IPv4/IPv6 address. + * RFC 6724, section 2.1. + */ +static int get_precedence(const struct sockaddr *addr) +{ + if (addr->sa_family == AF_INET) + { + return 35; + } + else if (addr->sa_family == AF_INET6) + { + const struct sockaddr_in6 *addr6 = CARES_INADDR_CAST(const struct sockaddr_in6 *, addr); + if (IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)) + { + return 50; + } + else if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) + { + return 35; + } + else if (ARES_IN6_IS_ADDR_6TO4(&addr6->sin6_addr)) + { + return 30; + } + else if (ARES_IN6_IS_ADDR_TEREDO(&addr6->sin6_addr)) + { + return 5; + } + else if (ARES_IN6_IS_ADDR_ULA(&addr6->sin6_addr)) + { + return 3; + } + else if (IN6_IS_ADDR_V4COMPAT(&addr6->sin6_addr) || + IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr) || + ARES_IN6_IS_ADDR_6BONE(&addr6->sin6_addr)) + { + return 1; + } + else + { + /* All other IPv6 addresses, including global unicast addresses. */ + return 40; + } + } + else + { + return 1; + } +} + +/* + * Find number of matching initial bits between the two addresses a1 and a2. + */ +static int common_prefix_len(const struct in6_addr *a1, + const struct in6_addr *a2) +{ + const char *p1 = (const char *)a1; + const char *p2 = (const char *)a2; + unsigned i; + for (i = 0; i < sizeof(*a1); ++i) + { + int x, j; + if (p1[i] == p2[i]) + { + continue; + } + x = p1[i] ^ p2[i]; + for (j = 0; j < CHAR_BIT; ++j) + { + if (x & (1 << (CHAR_BIT - 1))) + { + return i * CHAR_BIT + j; + } + x <<= 1; + } + } + return sizeof(*a1) * CHAR_BIT; +} + +/* + * Compare two source/destination address pairs. + * RFC 6724, section 6. + */ +static int rfc6724_compare(const void *ptr1, const void *ptr2) +{ + const struct addrinfo_sort_elem *a1 = (const struct addrinfo_sort_elem *)ptr1; + const struct addrinfo_sort_elem *a2 = (const struct addrinfo_sort_elem *)ptr2; + int scope_src1, scope_dst1, scope_match1; + int scope_src2, scope_dst2, scope_match2; + int label_src1, label_dst1, label_match1; + int label_src2, label_dst2, label_match2; + int precedence1, precedence2; + int prefixlen1, prefixlen2; + + /* Rule 1: Avoid unusable destinations. */ + if (a1->has_src_addr != a2->has_src_addr) + { + return a2->has_src_addr - a1->has_src_addr; + } + + /* Rule 2: Prefer matching scope. */ + scope_src1 = get_scope(&a1->src_addr.sa); + scope_dst1 = get_scope(a1->ai->ai_addr); + scope_match1 = (scope_src1 == scope_dst1); + + scope_src2 = get_scope(&a2->src_addr.sa); + scope_dst2 = get_scope(a2->ai->ai_addr); + scope_match2 = (scope_src2 == scope_dst2); + + if (scope_match1 != scope_match2) + { + return scope_match2 - scope_match1; + } + + /* Rule 3: Avoid deprecated addresses. */ + + /* Rule 4: Prefer home addresses. */ + + /* Rule 5: Prefer matching label. */ + label_src1 = get_label(&a1->src_addr.sa); + label_dst1 = get_label(a1->ai->ai_addr); + label_match1 = (label_src1 == label_dst1); + + label_src2 = get_label(&a2->src_addr.sa); + label_dst2 = get_label(a2->ai->ai_addr); + label_match2 = (label_src2 == label_dst2); + + if (label_match1 != label_match2) + { + return label_match2 - label_match1; + } + + /* Rule 6: Prefer higher precedence. */ + precedence1 = get_precedence(a1->ai->ai_addr); + precedence2 = get_precedence(a2->ai->ai_addr); + if (precedence1 != precedence2) + { + return precedence2 - precedence1; + } + + /* Rule 7: Prefer native transport. */ + + /* Rule 8: Prefer smaller scope. */ + if (scope_dst1 != scope_dst2) + { + return scope_dst1 - scope_dst2; + } + + /* Rule 9: Use longest matching prefix. */ + if (a1->has_src_addr && a1->ai->ai_addr->sa_family == AF_INET6 && + a2->has_src_addr && a2->ai->ai_addr->sa_family == AF_INET6) + { + const struct sockaddr_in6 *a1_src = &a1->src_addr.sa6; + const struct sockaddr_in6 *a1_dst = + CARES_INADDR_CAST(const struct sockaddr_in6 *, a1->ai->ai_addr); + const struct sockaddr_in6 *a2_src = &a2->src_addr.sa6; + const struct sockaddr_in6 *a2_dst = + CARES_INADDR_CAST(const struct sockaddr_in6 *, a2->ai->ai_addr); + prefixlen1 = common_prefix_len(&a1_src->sin6_addr, &a1_dst->sin6_addr); + prefixlen2 = common_prefix_len(&a2_src->sin6_addr, &a2_dst->sin6_addr); + if (prefixlen1 != prefixlen2) + { + return prefixlen2 - prefixlen1; + } + } + + /* + * Rule 10: Leave the order unchanged. + * We need this since qsort() is not necessarily stable. + */ + return a1->original_order - a2->original_order; +} + +/* + * Find the source address that will be used if trying to connect to the given + * address. + * + * Returns 1 if a source address was found, 0 if the address is unreachable, + * and -1 if a fatal error occurred. If 0 or 1, the contents of src_addr are + * undefined. + */ +static int find_src_addr(ares_channel channel, + const struct sockaddr *addr, + struct sockaddr *src_addr) +{ + ares_socket_t sock; + int ret; + ares_socklen_t len; + + switch (addr->sa_family) + { + case AF_INET: + len = sizeof(struct sockaddr_in); + break; + case AF_INET6: + len = sizeof(struct sockaddr_in6); + break; + default: + /* No known usable source address for non-INET families. */ + return 0; + } + + sock = ares__open_socket(channel, addr->sa_family, SOCK_DGRAM, IPPROTO_UDP); + if (sock == ARES_SOCKET_BAD) + { + if (errno == EAFNOSUPPORT) + { + return 0; + } + else + { + return -1; + } + } + + do + { + ret = ares__connect_socket(channel, sock, addr, len); + } + while (ret == -1 && errno == EINTR); + + if (ret == -1) + { + ares__close_socket(channel, sock); + return 0; + } + + if (getsockname(sock, src_addr, &len) != 0) + { + ares__close_socket(channel, sock); + return -1; + } + ares__close_socket(channel, sock); + return 1; +} + +/* + * Sort the linked list starting at sentinel->ai_next in RFC6724 order. + * Will leave the list unchanged if an error occurs. + */ +int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *list_sentinel) +{ + struct ares_addrinfo_node *cur; + int nelem = 0, i; + int has_src_addr; + struct addrinfo_sort_elem *elems; + + cur = list_sentinel->ai_next; + while (cur) + { + ++nelem; + cur = cur->ai_next; + } + elems = (struct addrinfo_sort_elem *)ares_malloc( + nelem * sizeof(struct addrinfo_sort_elem)); + if (!elems) + { + return ARES_ENOMEM; + } + + /* + * Convert the linked list to an array that also contains the candidate + * source address for each destination address. + */ + for (i = 0, cur = list_sentinel->ai_next; i < nelem; ++i, cur = cur->ai_next) + { + assert(cur != NULL); + elems[i].ai = cur; + elems[i].original_order = i; + has_src_addr = find_src_addr(channel, cur->ai_addr, &elems[i].src_addr.sa); + if (has_src_addr == -1) + { + ares_free(elems); + return ARES_ENOTFOUND; + } + elems[i].has_src_addr = has_src_addr; + } + + /* Sort the addresses, and rearrange the linked list so it matches the sorted + * order. */ + qsort((void *)elems, nelem, sizeof(struct addrinfo_sort_elem), + rfc6724_compare); + + list_sentinel->ai_next = elems[0].ai; + for (i = 0; i < nelem - 1; ++i) + { + elems[i].ai->ai_next = elems[i + 1].ai; + } + elems[nelem - 1].ai->ai_next = NULL; + + ares_free(elems); + return ARES_SUCCESS; +} diff --git a/ares__timeval.c b/src/lib/ares__timeval.c similarity index 100% rename from ares__timeval.c rename to src/lib/ares__timeval.c diff --git a/src/lib/ares_android.c b/src/lib/ares_android.c new file mode 100644 index 0000000..5b00b80 --- /dev/null +++ b/src/lib/ares_android.c @@ -0,0 +1,444 @@ +/* Copyright (C) 2017 by John Schember + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ +#if defined(ANDROID) || defined(__ANDROID__) + +#include + +#include "ares_setup.h" +#include "ares.h" +#include "ares_android.h" +#include "ares_private.h" + +static JavaVM *android_jvm = NULL; +static jobject android_connectivity_manager = NULL; + +/* ConnectivityManager.getActiveNetwork */ +static jmethodID android_cm_active_net_mid = NULL; +/* ConnectivityManager.getLinkProperties */ +static jmethodID android_cm_link_props_mid = NULL; +/* LinkProperties.getDnsServers */ +static jmethodID android_lp_dns_servers_mid = NULL; +/* LinkProperties.getDomains */ +static jmethodID android_lp_domains_mid = NULL; +/* List.size */ +static jmethodID android_list_size_mid = NULL; +/* List.get */ +static jmethodID android_list_get_mid = NULL; +/* InetAddress.getHostAddress */ +static jmethodID android_ia_host_addr_mid = NULL; + +static jclass jni_get_class(JNIEnv *env, const char *path) +{ + jclass cls = NULL; + + if (env == NULL || path == NULL || *path == '\0') + return NULL; + + cls = (*env)->FindClass(env, path); + if ((*env)->ExceptionOccurred(env)) { + (*env)->ExceptionClear(env); + return NULL; + } + return cls; +} + +static jmethodID jni_get_method_id(JNIEnv *env, jclass cls, + const char *func_name, const char *signature) +{ + jmethodID mid = NULL; + + if (env == NULL || cls == NULL || func_name == NULL || *func_name == '\0' || + signature == NULL || *signature == '\0') + { + return NULL; + } + + mid = (*env)->GetMethodID(env, cls, func_name, signature); + if ((*env)->ExceptionOccurred(env)) + { + (*env)->ExceptionClear(env); + return NULL; + } + + return mid; +} + +void ares_library_init_jvm(JavaVM *jvm) +{ + android_jvm = jvm; +} + +int ares_library_init_android(jobject connectivity_manager) +{ + JNIEnv *env = NULL; + int need_detatch = 0; + int res; + int ret = ARES_ENOTINITIALIZED; + jclass obj_cls = NULL; + + if (android_jvm == NULL) + goto cleanup; + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + goto cleanup; + + android_connectivity_manager = + (*env)->NewGlobalRef(env, connectivity_manager); + if (android_connectivity_manager == NULL) + goto cleanup; + + /* Initialization has succeeded. Now attempt to cache the methods that will be + * called by ares_get_android_server_list. */ + ret = ARES_SUCCESS; + + /* ConnectivityManager in API 1. */ + obj_cls = jni_get_class(env, "android/net/ConnectivityManager"); + if (obj_cls == NULL) + goto cleanup; + + /* ConnectivityManager.getActiveNetwork in API 23. */ + android_cm_active_net_mid = + jni_get_method_id(env, obj_cls, "getActiveNetwork", + "()Landroid/net/Network;"); + if (android_cm_active_net_mid == NULL) + goto cleanup; + + /* ConnectivityManager.getLinkProperties in API 21. */ + android_cm_link_props_mid = + jni_get_method_id(env, obj_cls, "getLinkProperties", + "(Landroid/net/Network;)Landroid/net/LinkProperties;"); + if (android_cm_link_props_mid == NULL) + goto cleanup; + + /* LinkProperties in API 21. */ + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "android/net/LinkProperties"); + if (obj_cls == NULL) + goto cleanup; + + /* getDnsServers in API 21. */ + android_lp_dns_servers_mid = jni_get_method_id(env, obj_cls, "getDnsServers", + "()Ljava/util/List;"); + if (android_lp_dns_servers_mid == NULL) + goto cleanup; + + /* getDomains in API 21. */ + android_lp_domains_mid = jni_get_method_id(env, obj_cls, "getDomains", + "()Ljava/lang/String;"); + if (android_lp_domains_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "java/util/List"); + if (obj_cls == NULL) + goto cleanup; + + android_list_size_mid = jni_get_method_id(env, obj_cls, "size", "()I"); + if (android_list_size_mid == NULL) + goto cleanup; + + android_list_get_mid = jni_get_method_id(env, obj_cls, "get", + "(I)Ljava/lang/Object;"); + if (android_list_get_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + obj_cls = jni_get_class(env, "java/net/InetAddress"); + if (obj_cls == NULL) + goto cleanup; + + android_ia_host_addr_mid = jni_get_method_id(env, obj_cls, "getHostAddress", + "()Ljava/lang/String;"); + if (android_ia_host_addr_mid == NULL) + goto cleanup; + + (*env)->DeleteLocalRef(env, obj_cls); + goto done; + +cleanup: + if (obj_cls != NULL) + (*env)->DeleteLocalRef(env, obj_cls); + + android_cm_active_net_mid = NULL; + android_cm_link_props_mid = NULL; + android_lp_dns_servers_mid = NULL; + android_lp_domains_mid = NULL; + android_list_size_mid = NULL; + android_list_get_mid = NULL; + android_ia_host_addr_mid = NULL; + +done: + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); + + return ret; +} + +int ares_library_android_initialized(void) +{ + if (android_jvm == NULL || android_connectivity_manager == NULL) + return ARES_ENOTINITIALIZED; + return ARES_SUCCESS; +} + +void ares_library_cleanup_android(void) +{ + JNIEnv *env = NULL; + int need_detatch = 0; + int res; + + if (android_jvm == NULL || android_connectivity_manager == NULL) + return; + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + return; + + android_cm_active_net_mid = NULL; + android_cm_link_props_mid = NULL; + android_lp_dns_servers_mid = NULL; + android_lp_domains_mid = NULL; + android_list_size_mid = NULL; + android_list_get_mid = NULL; + android_ia_host_addr_mid = NULL; + + (*env)->DeleteGlobalRef(env, android_connectivity_manager); + android_connectivity_manager = NULL; + + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); +} + +char **ares_get_android_server_list(size_t max_servers, + size_t *num_servers) +{ + JNIEnv *env = NULL; + jobject active_network = NULL; + jobject link_properties = NULL; + jobject server_list = NULL; + jobject server = NULL; + jstring str = NULL; + jint nserv; + const char *ch_server_address; + int res; + size_t i; + char **dns_list = NULL; + int need_detatch = 0; + + if (android_jvm == NULL || android_connectivity_manager == NULL || + max_servers == 0 || num_servers == NULL) + { + return NULL; + } + + if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL || + android_lp_dns_servers_mid == NULL || android_list_size_mid == NULL || + android_list_get_mid == NULL || android_ia_host_addr_mid == NULL) + { + return NULL; + } + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + goto done; + + /* JNI below is equivalent to this Java code. + import android.content.Context; + import android.net.ConnectivityManager; + import android.net.LinkProperties; + import android.net.Network; + import java.net.InetAddress; + import java.util.List; + + ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + Network an = cm.getActiveNetwork(); + LinkProperties lp = cm.getLinkProperties(an); + List dns = lp.getDnsServers(); + for (InetAddress ia: dns) { + String ha = ia.getHostAddress(); + } + + Note: The JNI ConnectivityManager object and all method IDs were previously + initialized in ares_library_init_android. + */ + + active_network = (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_active_net_mid); + if (active_network == NULL) + goto done; + + link_properties = + (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_link_props_mid, active_network); + if (link_properties == NULL) + goto done; + + server_list = (*env)->CallObjectMethod(env, link_properties, + android_lp_dns_servers_mid); + if (server_list == NULL) + goto done; + + nserv = (*env)->CallIntMethod(env, server_list, android_list_size_mid); + if (nserv > (jint)max_servers) + nserv = (jint)max_servers; + if (nserv <= 0) + goto done; + *num_servers = (size_t)nserv; + + dns_list = ares_malloc(sizeof(*dns_list)*(*num_servers)); + for (i=0; i<*num_servers; i++) + { + server = (*env)->CallObjectMethod(env, server_list, android_list_get_mid, + (jint)i); + dns_list[i] = ares_malloc(64); + dns_list[i][0] = 0; + if (server == NULL) + { + continue; + } + str = (*env)->CallObjectMethod(env, server, android_ia_host_addr_mid); + ch_server_address = (*env)->GetStringUTFChars(env, str, 0); + strncpy(dns_list[i], ch_server_address, 64); + (*env)->ReleaseStringUTFChars(env, str, ch_server_address); + (*env)->DeleteLocalRef(env, str); + (*env)->DeleteLocalRef(env, server); + } + +done: + if ((*env)->ExceptionOccurred(env)) + (*env)->ExceptionClear(env); + + if (server_list != NULL) + (*env)->DeleteLocalRef(env, server_list); + if (link_properties != NULL) + (*env)->DeleteLocalRef(env, link_properties); + if (active_network != NULL) + (*env)->DeleteLocalRef(env, active_network); + + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); + return dns_list; +} + +char *ares_get_android_search_domains_list(void) +{ + JNIEnv *env = NULL; + jobject active_network = NULL; + jobject link_properties = NULL; + jstring domains = NULL; + const char *domain; + int res; + char *domain_list = NULL; + int need_detatch = 0; + + if (android_jvm == NULL || android_connectivity_manager == NULL) + { + return NULL; + } + + if (android_cm_active_net_mid == NULL || android_cm_link_props_mid == NULL || + android_lp_domains_mid == NULL) + { + return NULL; + } + + res = (*android_jvm)->GetEnv(android_jvm, (void **)&env, JNI_VERSION_1_6); + if (res == JNI_EDETACHED) + { + env = NULL; + res = (*android_jvm)->AttachCurrentThread(android_jvm, &env, NULL); + need_detatch = 1; + } + if (res != JNI_OK || env == NULL) + goto done; + + /* JNI below is equivalent to this Java code. + import android.content.Context; + import android.net.ConnectivityManager; + import android.net.LinkProperties; + + ConnectivityManager cm = (ConnectivityManager)this.getApplicationContext() + .getSystemService(Context.CONNECTIVITY_SERVICE); + Network an = cm.getActiveNetwork(); + LinkProperties lp = cm.getLinkProperties(an); + String domains = lp.getDomains(); + for (String domain: domains.split(",")) { + String d = domain; + } + + Note: The JNI ConnectivityManager object and all method IDs were previously + initialized in ares_library_init_android. + */ + + active_network = (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_active_net_mid); + if (active_network == NULL) + goto done; + + link_properties = + (*env)->CallObjectMethod(env, android_connectivity_manager, + android_cm_link_props_mid, active_network); + if (link_properties == NULL) + goto done; + + /* Get the domains. It is a common separated list of domains to search. */ + domains = (*env)->CallObjectMethod(env, link_properties, + android_lp_domains_mid); + if (domains == NULL) + goto done; + + /* Split on , */ + domain = (*env)->GetStringUTFChars(env, domains, 0); + domain_list = ares_strdup(domain); + (*env)->ReleaseStringUTFChars(env, domains, domain); + (*env)->DeleteLocalRef(env, domains); + +done: + if ((*env)->ExceptionOccurred(env)) + (*env)->ExceptionClear(env); + + if (link_properties != NULL) + (*env)->DeleteLocalRef(env, link_properties); + if (active_network != NULL) + (*env)->DeleteLocalRef(env, active_network); + + if (need_detatch) + (*android_jvm)->DetachCurrentThread(android_jvm); + return domain_list; +} +#else +/* warning: ISO C forbids an empty translation unit */ +typedef int dummy_make_iso_compilers_happy; +#endif diff --git a/src/lib/ares_android.h b/src/lib/ares_android.h new file mode 100644 index 0000000..93fb75f --- /dev/null +++ b/src/lib/ares_android.h @@ -0,0 +1,27 @@ +/* Copyright (C) 2017 by John Schember + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#ifndef __ARES_ANDROID_H__ +#define __ARES_ANDROID_H__ + +#if defined(ANDROID) || defined(__ANDROID__) + +char **ares_get_android_server_list(size_t max_servers, size_t *num_servers); +char *ares_get_android_search_domains_list(void); +void ares_library_cleanup_android(void); + +#endif + +#endif /* __ARES_ANDROID_H__ */ diff --git a/ares_cancel.c b/src/lib/ares_cancel.c similarity index 100% rename from ares_cancel.c rename to src/lib/ares_cancel.c diff --git a/src/lib/ares_config.h.cmake b/src/lib/ares_config.h.cmake new file mode 100644 index 0000000..b76acc1 --- /dev/null +++ b/src/lib/ares_config.h.cmake @@ -0,0 +1,432 @@ +/* Generated from ares_config.h.cmake*/ + +/* Define if building universal (internal helper macro) */ +#undef AC_APPLE_UNIVERSAL_BUILD + +/* define this if ares is built for a big endian system */ +#undef ARES_BIG_ENDIAN + +/* when building as static part of libcurl */ +#undef BUILDING_LIBCURL + +/* Defined for build that exposes internal static functions for testing. */ +#undef CARES_EXPOSE_STATICS + +/* Defined for build with symbol hiding. */ +#undef CARES_SYMBOL_HIDING + +/* Definition to make a library symbol externally visible. */ +#undef CARES_SYMBOL_SCOPE_EXTERN + +/* Use resolver library to configure cares */ +#cmakedefine CARES_USE_LIBRESOLV + +/* if a /etc/inet dir is being used */ +#undef ETC_INET + +/* Define to the type of arg 2 for gethostname. */ +#define GETHOSTNAME_TYPE_ARG2 @GETHOSTNAME_TYPE_ARG2@ + +/* Define to the type qualifier of arg 1 for getnameinfo. */ +#define GETNAMEINFO_QUAL_ARG1 @GETNAMEINFO_QUAL_ARG1@ + +/* Define to the type of arg 1 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG1 @GETNAMEINFO_TYPE_ARG1@ + +/* Define to the type of arg 2 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG2 @GETNAMEINFO_TYPE_ARG2@ + +/* Define to the type of args 4 and 6 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG46 @GETNAMEINFO_TYPE_ARG46@ + +/* Define to the type of arg 7 for getnameinfo. */ +#define GETNAMEINFO_TYPE_ARG7 @GETNAMEINFO_TYPE_ARG7@ + +/* Specifies the number of arguments to getservbyport_r */ +#define GETSERVBYPORT_R_ARGS @GETSERVBYPORT_R_ARGS@ + +/* Specifies the number of arguments to getservbyname_r */ +#define GETSERVBYNAME_R_ARGS @GETSERVBYNAME_R_ARGS@ + +/* Define to 1 if you have AF_INET6. */ +#cmakedefine HAVE_AF_INET6 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_INET_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_NAMESER_COMPAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_NAMESER_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ASSERT_H + +/* Define to 1 if you have the `bitncmp' function. */ +#cmakedefine HAVE_BITNCMP + +/* Define to 1 if bool is an available type. */ +#cmakedefine HAVE_BOOL_T + +/* Define to 1 if you have the clock_gettime function and monotonic timer. */ +#cmakedefine HAVE_CLOCK_GETTIME_MONOTONIC + +/* Define to 1 if you have the closesocket function. */ +#cmakedefine HAVE_CLOSESOCKET + +/* Define to 1 if you have the CloseSocket camel case function. */ +#cmakedefine HAVE_CLOSESOCKET_CAMEL + +/* Define to 1 if you have the connect function. */ +#cmakedefine HAVE_CONNECT + +/* define if the compiler supports basic C++11 syntax */ +#cmakedefine HAVE_CXX11 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ERRNO_H + +/* Define to 1 if you have the fcntl function. */ +#cmakedefine HAVE_FCNTL + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H + +/* Define to 1 if you have a working fcntl O_NONBLOCK function. */ +#cmakedefine HAVE_FCNTL_O_NONBLOCK + +/* Define to 1 if you have the freeaddrinfo function. */ +#cmakedefine HAVE_FREEADDRINFO + +/* Define to 1 if you have a working getaddrinfo function. */ +#cmakedefine HAVE_GETADDRINFO + +/* Define to 1 if the getaddrinfo function is threadsafe. */ +#cmakedefine HAVE_GETADDRINFO_THREADSAFE + +/* Define to 1 if you have the getenv function. */ +#cmakedefine HAVE_GETENV + +/* Define to 1 if you have the gethostbyaddr function. */ +#cmakedefine HAVE_GETHOSTBYADDR + +/* Define to 1 if you have the gethostbyname function. */ +#cmakedefine HAVE_GETHOSTBYNAME + +/* Define to 1 if you have the gethostname function. */ +#cmakedefine HAVE_GETHOSTNAME + +/* Define to 1 if you have the getnameinfo function. */ +#cmakedefine HAVE_GETNAMEINFO + +/* Define to 1 if you have the getservbyport_r function. */ +#cmakedefine HAVE_GETSERVBYPORT_R + +/* Define to 1 if you have the getservbyname_r function. */ +#cmakedefine HAVE_GETSERVBYNAME_R + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine HAVE_GETTIMEOFDAY + +/* Define to 1 if you have the `if_indextoname' function. */ +#cmakedefine HAVE_IF_INDEXTONAME + +/* Define to 1 if you have a IPv6 capable working inet_net_pton function. */ +#cmakedefine HAVE_INET_NET_PTON + +/* Define to 1 if you have a IPv6 capable working inet_ntop function. */ +#cmakedefine HAVE_INET_NTOP + +/* Define to 1 if you have a IPv6 capable working inet_pton function. */ +#cmakedefine HAVE_INET_PTON + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H + +/* Define to 1 if you have the ioctl function. */ +#cmakedefine HAVE_IOCTL + +/* Define to 1 if you have the ioctlsocket function. */ +#cmakedefine HAVE_IOCTLSOCKET + +/* Define to 1 if you have the IoctlSocket camel case function. */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL + +/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function. + */ +#cmakedefine HAVE_IOCTLSOCKET_CAMEL_FIONBIO + +/* Define to 1 if you have a working ioctlsocket FIONBIO function. */ +#cmakedefine HAVE_IOCTLSOCKET_FIONBIO + +/* Define to 1 if you have a working ioctl FIONBIO function. */ +#cmakedefine HAVE_IOCTL_FIONBIO + +/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */ +#cmakedefine HAVE_IOCTL_SIOCGIFADDR + +/* Define to 1 if you have the `resolve' library (-lresolve). */ +#cmakedefine HAVE_LIBRESOLV + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_LIMITS_H + +/* if your compiler supports LL */ +#cmakedefine HAVE_LL + +/* Define to 1 if the compiler supports the 'long long' data type. */ +#cmakedefine HAVE_LONGLONG + +/* Define to 1 if you have the malloc.h header file. */ +#cmakedefine HAVE_MALLOC_H + +/* Define to 1 if you have the memory.h header file. */ +#cmakedefine HAVE_MEMORY_H + +/* Define to 1 if you have the MSG_NOSIGNAL flag. */ +#cmakedefine HAVE_MSG_NOSIGNAL + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_TCP_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NET_IF_H + +/* Define to 1 if you have PF_INET6. */ +#cmakedefine HAVE_PF_INET6 + +/* Define to 1 if you have the recv function. */ +#cmakedefine HAVE_RECV + +/* Define to 1 if you have the recvfrom function. */ +#cmakedefine HAVE_RECVFROM + +/* Define to 1 if you have the send function. */ +#cmakedefine HAVE_SEND + +/* Define to 1 if you have the setsockopt function. */ +#cmakedefine HAVE_SETSOCKOPT + +/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */ +#cmakedefine HAVE_SETSOCKOPT_SO_NONBLOCK + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SIGNAL_H + +/* Define to 1 if sig_atomic_t is an available typedef. */ +#cmakedefine HAVE_SIG_ATOMIC_T + +/* Define to 1 if sig_atomic_t is already defined as volatile. */ +#cmakedefine HAVE_SIG_ATOMIC_T_VOLATILE + +/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */ +#cmakedefine HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID + +/* Define to 1 if you have the socket function. */ +#cmakedefine HAVE_SOCKET + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SOCKET_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDBOOL_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H + +/* Define to 1 if you have the strcasecmp function. */ +#cmakedefine HAVE_STRCASECMP + +/* Define to 1 if you have the strcmpi function. */ +#cmakedefine HAVE_STRCMPI + +/* Define to 1 if you have the strdup function. */ +#cmakedefine HAVE_STRDUP + +/* Define to 1 if you have the stricmp function. */ +#cmakedefine HAVE_STRICMP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H + +/* Define to 1 if you have the strncasecmp function. */ +#cmakedefine HAVE_STRNCASECMP + +/* Define to 1 if you have the strncmpi function. */ +#cmakedefine HAVE_STRNCMPI + +/* Define to 1 if you have the strnicmp function. */ +#cmakedefine HAVE_STRNICMP + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STROPTS_H + +/* Define to 1 if you have struct addrinfo. */ +#cmakedefine HAVE_STRUCT_ADDRINFO + +/* Define to 1 if you have struct in6_addr. */ +#cmakedefine HAVE_STRUCT_IN6_ADDR + +/* Define to 1 if you have struct sockaddr_in6. */ +#cmakedefine HAVE_STRUCT_SOCKADDR_IN6 + +/* if struct sockaddr_storage is defined */ +#cmakedefine HAVE_STRUCT_SOCKADDR_STORAGE + +/* Define to 1 if you have the timeval struct. */ +#cmakedefine HAVE_STRUCT_TIMEVAL + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_PARAM_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SELECT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_UIO_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TIME_H + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H + +/* Define to 1 if you have the windows.h header file. */ +#cmakedefine HAVE_WINDOWS_H + +/* Define to 1 if you have the winsock2.h header file. */ +#cmakedefine HAVE_WINSOCK2_H + +/* Define to 1 if you have the winsock.h header file. */ +#cmakedefine HAVE_WINSOCK_H + +/* Define to 1 if you have the writev function. */ +#cmakedefine HAVE_WRITEV + +/* Define to 1 if you have the ws2tcpip.h header file. */ +#cmakedefine HAVE_WS2TCPIP_H + +/* Define to 1 if you have the __system_property_get function */ +#cmakedefine HAVE___SYSTEM_PROPERTY_GET + +/* Define to 1 if you need the malloc.h header file even with stdlib.h */ +#cmakedefine NEED_MALLOC_H + +/* Define to 1 if you need the memory.h header file even with stdlib.h */ +#cmakedefine NEED_MEMORY_H + +/* a suitable file/device to read random data from */ +#cmakedefine RANDOM_FILE + +/* Define to the type qualifier pointed by arg 5 for recvfrom. */ +#define RECVFROM_QUAL_ARG5 @RECVFROM_QUAL_ARG5@ + +/* Define to the type of arg 1 for recvfrom. */ +#define RECVFROM_TYPE_ARG1 @RECVFROM_TYPE_ARG1@ + +/* Define to the type pointed by arg 2 for recvfrom. */ +#define RECVFROM_TYPE_ARG2 @RECVFROM_TYPE_ARG2@ + +/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */ +#cmakedefine01 RECVFROM_TYPE_ARG2_IS_VOID + +/* Define to the type of arg 3 for recvfrom. */ +#define RECVFROM_TYPE_ARG3 @RECVFROM_TYPE_ARG3@ + +/* Define to the type of arg 4 for recvfrom. */ +#define RECVFROM_TYPE_ARG4 @RECVFROM_TYPE_ARG4@ + +/* Define to the type pointed by arg 5 for recvfrom. */ +#define RECVFROM_TYPE_ARG5 @RECVFROM_TYPE_ARG5@ + +/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */ +#cmakedefine01 RECVFROM_TYPE_ARG5_IS_VOID + +/* Define to the type pointed by arg 6 for recvfrom. */ +#define RECVFROM_TYPE_ARG6 @RECVFROM_TYPE_ARG6@ + +/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */ +#cmakedefine01 RECVFROM_TYPE_ARG6_IS_VOID + +/* Define to the function return type for recvfrom. */ +#define RECVFROM_TYPE_RETV @RECVFROM_TYPE_RETV@ + +/* Define to the type of arg 1 for recv. */ +#define RECV_TYPE_ARG1 @RECV_TYPE_ARG1@ + +/* Define to the type of arg 2 for recv. */ +#define RECV_TYPE_ARG2 @RECV_TYPE_ARG2@ + +/* Define to the type of arg 3 for recv. */ +#define RECV_TYPE_ARG3 @RECV_TYPE_ARG3@ + +/* Define to the type of arg 4 for recv. */ +#define RECV_TYPE_ARG4 @RECV_TYPE_ARG4@ + +/* Define to the function return type for recv. */ +#define RECV_TYPE_RETV @RECV_TYPE_RETV@ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE @RETSIGTYPE@ + +/* Define to the type qualifier of arg 2 for send. */ +#define SEND_QUAL_ARG2 @SEND_QUAL_ARG2@ + +/* Define to the type of arg 1 for send. */ +#define SEND_TYPE_ARG1 @SEND_TYPE_ARG1@ + +/* Define to the type of arg 2 for send. */ +#define SEND_TYPE_ARG2 @SEND_TYPE_ARG2@ + +/* Define to the type of arg 3 for send. */ +#define SEND_TYPE_ARG3 @SEND_TYPE_ARG3@ + +/* Define to the type of arg 4 for send. */ +#define SEND_TYPE_ARG4 @SEND_TYPE_ARG4@ + +/* Define to the function return type for send. */ +#define SEND_TYPE_RETV @SEND_TYPE_RETV@ + +/* Define to 1 if you can safely include both and . */ +#cmakedefine TIME_WITH_SYS_TIME + +/* Define to disable non-blocking sockets. */ +#undef USE_BLOCKING_SOCKETS + +/* Define to avoid automatic inclusion of winsock.h */ +#undef WIN32_LEAN_AND_MEAN + +/* Type to use in place of in_addr_t when system does not provide it. */ +#undef in_addr_t + diff --git a/ares_config.h.in b/src/lib/ares_config.h.in similarity index 98% rename from ares_config.h.in rename to src/lib/ares_config.h.in index 721ee45..94dcff0 100644 --- a/ares_config.h.in +++ b/src/lib/ares_config.h.in @@ -1,4 +1,4 @@ -/* ares_config.h.in. Generated from configure.ac by autoheader. */ +/* src/lib/ares_config.h.in. Generated from configure.ac by autoheader. */ /* Define if building universal (internal helper macro) */ #undef AC_APPLE_UNIVERSAL_BUILD @@ -6,9 +6,6 @@ /* define this if ares is built for a big endian system */ #undef ARES_BIG_ENDIAN -/* when building as static part of libcurl */ -#undef BUILDING_LIBCURL - /* Defined for build that exposes internal static functions for testing. */ #undef CARES_EXPOSE_STATICS @@ -18,6 +15,9 @@ /* Definition to make a library symbol externally visible. */ #undef CARES_SYMBOL_SCOPE_EXTERN +/* the signed version of size_t */ +#undef CARES_TYPEOF_ARES_SSIZE_T + /* Use resolver library to configure cares */ #undef CARES_USE_LIBRESOLV @@ -334,6 +334,9 @@ /* Define to 1 if you have the ws2tcpip.h header file. */ #undef HAVE_WS2TCPIP_H +/* Define if __system_property_get exists. */ +#undef HAVE___SYSTEM_PROPERTY_GET + /* Define to the sub-directory where libtool stores uninstalled libraries. */ #undef LT_OBJDIR @@ -496,6 +499,3 @@ /* Define to `unsigned int' if does not define. */ #undef size_t - -/* the signed version of size_t */ -#undef ssize_t diff --git a/ares_create_query.c b/src/lib/ares_create_query.c similarity index 95% rename from ares_create_query.c rename to src/lib/ares_create_query.c index 7f4c52d..9efce17 100644 --- a/ares_create_query.c +++ b/src/lib/ares_create_query.c @@ -98,6 +98,10 @@ int ares_create_query(const char *name, int dnsclass, int type, *buflenp = 0; *bufp = NULL; + /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ + if (ares__is_onion_domain(name)) + return ARES_ENOTFOUND; + /* Allocate a memory area for the maximum size this packet might need. +2 * is for the length byte and zero termination if no dots or ecscaping is * used. @@ -134,7 +138,7 @@ int ares_create_query(const char *name, int dnsclass, int type, while (*name) { if (*name == '.') { - free (buf); + ares_free (buf); return ARES_EBADNAME; } @@ -147,7 +151,7 @@ int ares_create_query(const char *name, int dnsclass, int type, len++; } if (len > MAXLABEL) { - free (buf); + ares_free (buf); return ARES_EBADNAME; } @@ -188,9 +192,9 @@ int ares_create_query(const char *name, int dnsclass, int type, * specified in RFC 1035 ("To simplify implementations, the total length of * a domain name (i.e., label octets and label length octets) is restricted * to 255 octets or less."). */ - if (buflen > (MAXCDNAME + HFIXEDSZ + QFIXEDSZ + + if (buflen > (size_t)(MAXCDNAME + HFIXEDSZ + QFIXEDSZ + (max_udp_size ? EDNSFIXEDSZ : 0))) { - free (buf); + ares_free (buf); return ARES_EBADNAME; } diff --git a/ares_data.c b/src/lib/ares_data.c similarity index 61% rename from ares_data.c rename to src/lib/ares_data.c index f891113..aa925b8 100644 --- a/ares_data.c +++ b/src/lib/ares_data.c @@ -40,10 +40,9 @@ void ares_free_data(void *dataptr) { - struct ares_data *ptr; - - if (!dataptr) - return; + while (dataptr != NULL) { + struct ares_data *ptr; + void *next_data = NULL; #ifdef __INTEL_COMPILER # pragma warning(push) @@ -51,80 +50,92 @@ void ares_free_data(void *dataptr) /* 1684: conversion from pointer to same-sized integral type */ #endif - ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); + ptr = (void *)((char *)dataptr - offsetof(struct ares_data, data)); #ifdef __INTEL_COMPILER # pragma warning(pop) #endif - if (ptr->mark != ARES_DATATYPE_MARK) - return; - - switch (ptr->type) - { - case ARES_DATATYPE_MX_REPLY: - - if (ptr->data.mx_reply.next) - ares_free_data(ptr->data.mx_reply.next); - if (ptr->data.mx_reply.host) - ares_free(ptr->data.mx_reply.host); - break; - - case ARES_DATATYPE_SRV_REPLY: - - if (ptr->data.srv_reply.next) - ares_free_data(ptr->data.srv_reply.next); - if (ptr->data.srv_reply.host) - ares_free(ptr->data.srv_reply.host); - break; - - case ARES_DATATYPE_TXT_REPLY: - case ARES_DATATYPE_TXT_EXT: - - if (ptr->data.txt_reply.next) - ares_free_data(ptr->data.txt_reply.next); - if (ptr->data.txt_reply.txt) - ares_free(ptr->data.txt_reply.txt); - break; - - case ARES_DATATYPE_ADDR_NODE: - - if (ptr->data.addr_node.next) - ares_free_data(ptr->data.addr_node.next); - break; - - case ARES_DATATYPE_ADDR_PORT_NODE: - - if (ptr->data.addr_port_node.next) - ares_free_data(ptr->data.addr_port_node.next); - break; - - case ARES_DATATYPE_NAPTR_REPLY: - - if (ptr->data.naptr_reply.next) - ares_free_data(ptr->data.naptr_reply.next); - if (ptr->data.naptr_reply.flags) - ares_free(ptr->data.naptr_reply.flags); - if (ptr->data.naptr_reply.service) - ares_free(ptr->data.naptr_reply.service); - if (ptr->data.naptr_reply.regexp) - ares_free(ptr->data.naptr_reply.regexp); - if (ptr->data.naptr_reply.replacement) - ares_free(ptr->data.naptr_reply.replacement); - break; - - case ARES_DATATYPE_SOA_REPLY: - if (ptr->data.soa_reply.nsname) - ares_free(ptr->data.soa_reply.nsname); - if (ptr->data.soa_reply.hostmaster) - ares_free(ptr->data.soa_reply.hostmaster); - break; - - default: - return; - } - - ares_free(ptr); + if (ptr->mark != ARES_DATATYPE_MARK) + return; + + switch (ptr->type) + { + case ARES_DATATYPE_MX_REPLY: + + if (ptr->data.mx_reply.next) + next_data = ptr->data.mx_reply.next; + if (ptr->data.mx_reply.host) + ares_free(ptr->data.mx_reply.host); + break; + + case ARES_DATATYPE_SRV_REPLY: + + if (ptr->data.srv_reply.next) + next_data = ptr->data.srv_reply.next; + if (ptr->data.srv_reply.host) + ares_free(ptr->data.srv_reply.host); + break; + + case ARES_DATATYPE_TXT_REPLY: + case ARES_DATATYPE_TXT_EXT: + + if (ptr->data.txt_reply.next) + next_data = ptr->data.txt_reply.next; + if (ptr->data.txt_reply.txt) + ares_free(ptr->data.txt_reply.txt); + break; + + case ARES_DATATYPE_ADDR_NODE: + + if (ptr->data.addr_node.next) + next_data = ptr->data.addr_node.next; + break; + + case ARES_DATATYPE_ADDR_PORT_NODE: + + if (ptr->data.addr_port_node.next) + next_data = ptr->data.addr_port_node.next; + break; + + case ARES_DATATYPE_NAPTR_REPLY: + + if (ptr->data.naptr_reply.next) + next_data = ptr->data.naptr_reply.next; + if (ptr->data.naptr_reply.flags) + ares_free(ptr->data.naptr_reply.flags); + if (ptr->data.naptr_reply.service) + ares_free(ptr->data.naptr_reply.service); + if (ptr->data.naptr_reply.regexp) + ares_free(ptr->data.naptr_reply.regexp); + if (ptr->data.naptr_reply.replacement) + ares_free(ptr->data.naptr_reply.replacement); + break; + + case ARES_DATATYPE_SOA_REPLY: + if (ptr->data.soa_reply.nsname) + ares_free(ptr->data.soa_reply.nsname); + if (ptr->data.soa_reply.hostmaster) + ares_free(ptr->data.soa_reply.hostmaster); + break; + + case ARES_DATATYPE_CAA_REPLY: + + if (ptr->data.caa_reply.next) + next_data = ptr->data.caa_reply.next; + if (ptr->data.caa_reply.property) + ares_free(ptr->data.caa_reply.property); + if (ptr->data.caa_reply.value) + ares_free(ptr->data.caa_reply.value); + break; + + default: + return; + } + + ares_free(ptr); + dataptr = next_data; + } } @@ -173,6 +184,14 @@ void *ares_malloc_data(ares_datatype type) ptr->data.txt_reply.length = 0; break; + case ARES_DATATYPE_CAA_REPLY: + ptr->data.caa_reply.next = NULL; + ptr->data.caa_reply.plength = 0; + ptr->data.caa_reply.property = NULL; + ptr->data.caa_reply.length = 0; + ptr->data.caa_reply.value = NULL; + break; + case ARES_DATATYPE_ADDR_NODE: ptr->data.addr_node.next = NULL; ptr->data.addr_node.family = 0; diff --git a/ares_data.h b/src/lib/ares_data.h similarity index 96% rename from ares_data.h rename to src/lib/ares_data.h index ffee2be..b0182fd 100644 --- a/ares_data.h +++ b/src/lib/ares_data.h @@ -30,6 +30,7 @@ typedef enum { ARES_DATATYPE_OPTIONS, /* struct ares_options */ #endif ARES_DATATYPE_ADDR_PORT_NODE, /* struct ares_addr_port_node - introduced in 1.11.0 */ + ARES_DATATYPE_CAA_REPLY, /* struct ares_caa_reply - introduced in 1.17 */ ARES_DATATYPE_LAST /* not used - introduced in 1.7.0 */ } ares_datatype; @@ -65,6 +66,7 @@ struct ares_data { struct ares_mx_reply mx_reply; struct ares_naptr_reply naptr_reply; struct ares_soa_reply soa_reply; + struct ares_caa_reply caa_reply; } data; }; diff --git a/ares_destroy.c b/src/lib/ares_destroy.c similarity index 95% rename from ares_destroy.c rename to src/lib/ares_destroy.c index 8aa4223..fed2009 100644 --- a/ares_destroy.c +++ b/src/lib/ares_destroy.c @@ -36,6 +36,8 @@ void ares_destroy_options(struct ares_options *options) ares_free(options->sortlist); if(options->lookups) ares_free(options->lookups); + if(options->resolvconf_path) + ares_free(options->resolvconf_path); } void ares_destroy(ares_channel channel) @@ -44,7 +46,7 @@ void ares_destroy(ares_channel channel) struct query *query; struct list_node* list_head; struct list_node* list_node; - + if (!channel) return; @@ -85,6 +87,9 @@ void ares_destroy(ares_channel channel) if (channel->lookups) ares_free(channel->lookups); + if (channel->resolvconf_path) + ares_free(channel->resolvconf_path); + ares_free(channel); } diff --git a/ares_expand_name.c b/src/lib/ares_expand_name.c similarity index 97% rename from ares_expand_name.c rename to src/lib/ares_expand_name.c index 738be8d..3a38e67 100644 --- a/ares_expand_name.c +++ b/src/lib/ares_expand_name.c @@ -32,6 +32,9 @@ #include "ares_nowarn.h" #include "ares_private.h" /* for the memdebug */ +/* Maximum number of indirections allowed for a name */ +#define MAX_INDIRS 50 + static int name_length(const unsigned char *encoded, const unsigned char *abuf, int alen); @@ -66,7 +69,7 @@ int ares_expand_name(const unsigned char *encoded, const unsigned char *abuf, char *q; const unsigned char *p; union { - ssize_t sig; + ares_ssize_t sig; size_t uns; } nlen; @@ -162,7 +165,8 @@ static int name_length(const unsigned char *encoded, const unsigned char *abuf, /* If we've seen more indirects than the message length, * then there's a loop. */ - if (++indir > alen) + ++indir; + if (indir > alen || indir > MAX_INDIRS) return -1; } else if (top == 0x00) diff --git a/ares_expand_string.c b/src/lib/ares_expand_string.c similarity index 98% rename from ares_expand_string.c rename to src/lib/ares_expand_string.c index ed5476b..d35df75 100644 --- a/ares_expand_string.c +++ b/src/lib/ares_expand_string.c @@ -41,7 +41,7 @@ int ares_expand_string(const unsigned char *encoded, { unsigned char *q; union { - ssize_t sig; + ares_ssize_t sig; size_t uns; } elen; diff --git a/ares_fds.c b/src/lib/ares_fds.c similarity index 100% rename from ares_fds.c rename to src/lib/ares_fds.c diff --git a/ares_free_hostent.c b/src/lib/ares_free_hostent.c similarity index 100% rename from ares_free_hostent.c rename to src/lib/ares_free_hostent.c diff --git a/ares_free_string.c b/src/lib/ares_free_string.c similarity index 100% rename from ares_free_string.c rename to src/lib/ares_free_string.c diff --git a/src/lib/ares_freeaddrinfo.c b/src/lib/ares_freeaddrinfo.c new file mode 100644 index 0000000..128f5da --- /dev/null +++ b/src/lib/ares_freeaddrinfo.c @@ -0,0 +1,57 @@ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETDB_H +# include +#endif + +#include "ares.h" +#include "ares_private.h" + +void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *head) +{ + struct ares_addrinfo_cname *current; + while (head) + { + current = head; + head = head->next; + ares_free(current->alias); + ares_free(current->name); + ares_free(current); + } +} + +void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *head) +{ + struct ares_addrinfo_node *current; + while (head) + { + current = head; + head = head->ai_next; + ares_free(current->ai_addr); + ares_free(current); + } +} + +void ares_freeaddrinfo(struct ares_addrinfo *ai) +{ + ares__freeaddrinfo_cnames(ai->cnames); + ares__freeaddrinfo_nodes(ai->nodes); + ares_free(ai); +} diff --git a/src/lib/ares_getaddrinfo.c b/src/lib/ares_getaddrinfo.c new file mode 100644 index 0000000..ecd5dd5 --- /dev/null +++ b/src/lib/ares_getaddrinfo.c @@ -0,0 +1,776 @@ + +/* Copyright 1998, 2011, 2013 by the Massachusetts Institute of Technology. + * Copyright (C) 2017 - 2018 by Christian Ammer + * Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_GETSERVBYNAME_R +# if !defined(GETSERVBYNAME_R_ARGS) || \ + (GETSERVBYNAME_R_ARGS < 4) || (GETSERVBYNAME_R_ARGS > 6) +# error "you MUST specifiy a valid number of arguments for getservbyname_r" +# endif +#endif + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#ifdef HAVE_STRINGS_H +#include +#endif +#include + +#ifdef HAVE_LIMITS_H +#include +#endif + +#include "ares.h" +#include "bitncmp.h" +#include "ares_private.h" + +#ifdef WATT32 +#undef WIN32 +#endif +#ifdef WIN32 +# include "ares_platform.h" +#endif + +struct host_query +{ + ares_channel channel; + char *name; + unsigned short port; /* in host order */ + ares_addrinfo_callback callback; + void *arg; + struct ares_addrinfo_hints hints; + int sent_family; /* this family is what was is being used */ + int timeouts; /* number of timeouts we saw for this request */ + const char *remaining_lookups; /* types of lookup we need to perform ("fb" by + default, file and dns respectively) */ + struct ares_addrinfo *ai; /* store results between lookups */ + int remaining; /* number of DNS answers waiting for */ + int next_domain; /* next search domain to try */ +}; + +static const struct ares_addrinfo_hints default_hints = { + 0, /* ai_flags */ + AF_UNSPEC, /* ai_family */ + 0, /* ai_socktype */ + 0, /* ai_protocol */ +}; + +static const struct ares_addrinfo_cname empty_addrinfo_cname = { + INT_MAX, /* ttl */ + NULL, /* alias */ + NULL, /* name */ + NULL, /* next */ +}; + +static const struct ares_addrinfo_node empty_addrinfo_node = { + 0, /* ai_ttl */ + 0, /* ai_flags */ + 0, /* ai_family */ + 0, /* ai_socktype */ + 0, /* ai_protocol */ + 0, /* ai_addrlen */ + NULL, /* ai_addr */ + NULL /* ai_next */ +}; + +static const struct ares_addrinfo empty_addrinfo = { + NULL, /* cnames */ + NULL /* nodes */ +}; + +/* forward declarations */ +static void host_callback(void *arg, int status, int timeouts, + unsigned char *abuf, int alen); +static int as_is_first(const struct host_query *hquery); +static int next_dns_lookup(struct host_query *hquery); + +struct ares_addrinfo_cname *ares__malloc_addrinfo_cname() +{ + struct ares_addrinfo_cname *cname = ares_malloc(sizeof(struct ares_addrinfo_cname)); + if (!cname) + return NULL; + + *cname = empty_addrinfo_cname; + return cname; +} + +struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **head) +{ + struct ares_addrinfo_cname *tail = ares__malloc_addrinfo_cname(); + struct ares_addrinfo_cname *last = *head; + if (!last) + { + *head = tail; + return tail; + } + + while (last->next) + { + last = last->next; + } + + last->next = tail; + return tail; +} + +void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head, + struct ares_addrinfo_cname *tail) +{ + struct ares_addrinfo_cname *last = *head; + if (!last) + { + *head = tail; + return; + } + + while (last->next) + { + last = last->next; + } + + last->next = tail; +} + +struct ares_addrinfo *ares__malloc_addrinfo() +{ + struct ares_addrinfo *ai = ares_malloc(sizeof(struct ares_addrinfo)); + if (!ai) + return NULL; + + *ai = empty_addrinfo; + return ai; +} + +struct ares_addrinfo_node *ares__malloc_addrinfo_node() +{ + struct ares_addrinfo_node *node = + ares_malloc(sizeof(struct ares_addrinfo_node)); + if (!node) + return NULL; + + *node = empty_addrinfo_node; + return node; +} + +/* Allocate new addrinfo and append to the tail. */ +struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **head) +{ + struct ares_addrinfo_node *tail = ares__malloc_addrinfo_node(); + struct ares_addrinfo_node *last = *head; + if (!last) + { + *head = tail; + return tail; + } + + while (last->ai_next) + { + last = last->ai_next; + } + + last->ai_next = tail; + return tail; +} + +void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head, + struct ares_addrinfo_node *tail) +{ + struct ares_addrinfo_node *last = *head; + if (!last) + { + *head = tail; + return; + } + + while (last->ai_next) + { + last = last->ai_next; + } + + last->ai_next = tail; +} + +/* Resolve service name into port number given in host byte order. + * If not resolved, return 0. + */ +static unsigned short lookup_service(const char *service, int flags) +{ + const char *proto; + struct servent *sep; +#ifdef HAVE_GETSERVBYNAME_R + struct servent se; + char tmpbuf[4096]; +#endif + + if (service) + { + if (flags & ARES_NI_UDP) + proto = "udp"; + else if (flags & ARES_NI_SCTP) + proto = "sctp"; + else if (flags & ARES_NI_DCCP) + proto = "dccp"; + else + proto = "tcp"; +#ifdef HAVE_GETSERVBYNAME_R + memset(&se, 0, sizeof(se)); + sep = &se; + memset(tmpbuf, 0, sizeof(tmpbuf)); +#if GETSERVBYNAME_R_ARGS == 6 + if (getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf), + &sep) != 0) + sep = NULL; /* LCOV_EXCL_LINE: buffer large so this never fails */ +#elif GETSERVBYNAME_R_ARGS == 5 + sep = + getservbyname_r(service, proto, &se, (void *)tmpbuf, sizeof(tmpbuf)); +#elif GETSERVBYNAME_R_ARGS == 4 + if (getservbyname_r(service, proto, &se, (void *)tmpbuf) != 0) + sep = NULL; +#else + /* Lets just hope the OS uses TLS! */ + sep = getservbyname(service, proto); +#endif +#else + /* Lets just hope the OS uses TLS! */ +#if (defined(NETWARE) && !defined(__NOVELL_LIBC__)) + sep = getservbyname(service, (char *)proto); +#else + sep = getservbyname(service, proto); +#endif +#endif + return (sep ? ntohs((unsigned short)sep->s_port) : 0); + } + return 0; +} + +/* If the name looks like an IP address or an error occured, + * fake up a host entry, end the query immediately, and return true. + * Otherwise return false. + */ +static int fake_addrinfo(const char *name, + unsigned short port, + const struct ares_addrinfo_hints *hints, + struct ares_addrinfo *ai, + ares_addrinfo_callback callback, + void *arg) +{ + struct ares_addrinfo_cname *cname; + struct ares_addrinfo_node *node; + ares_sockaddr addr; + size_t addrlen; + int result = 0; + int family = hints->ai_family; + if (family == AF_INET || family == AF_INET6 || family == AF_UNSPEC) + { + /* It only looks like an IP address if it's all numbers and dots. */ + int numdots = 0, valid = 1; + const char *p; + for (p = name; *p; p++) + { + if (!ISDIGIT(*p) && *p != '.') + { + valid = 0; + break; + } + else if (*p == '.') + { + numdots++; + } + } + + memset(&addr, 0, sizeof(addr)); + + /* if we don't have 3 dots, it is illegal + * (although inet_pton doesn't think so). + */ + if (numdots != 3 || !valid) + result = 0; + else + result = + (ares_inet_pton(AF_INET, name, &addr.sa4.sin_addr) < 1 ? 0 : 1); + + if (result) + { + family = addr.sa.sa_family = AF_INET; + addr.sa4.sin_port = htons(port); + addrlen = sizeof(addr.sa4); + } + } + + if (family == AF_INET6 || family == AF_UNSPEC) + { + result = + (ares_inet_pton(AF_INET6, name, &addr.sa6.sin6_addr) < 1 ? 0 : 1); + addr.sa6.sin6_family = AF_INET6; + addr.sa6.sin6_port = htons(port); + addrlen = sizeof(addr.sa6); + } + + if (!result) + return 0; + + node = ares__malloc_addrinfo_node(); + if (!node) + { + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return 1; + } + + ai->nodes = node; + + node->ai_addr = ares_malloc(addrlen); + if (!node->ai_addr) + { + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return 1; + } + + node->ai_addrlen = (unsigned int)addrlen; + node->ai_family = addr.sa.sa_family; + if (addr.sa.sa_family == AF_INET) + memcpy(node->ai_addr, &addr.sa4, sizeof(addr.sa4)); + else + memcpy(node->ai_addr, &addr.sa6, sizeof(addr.sa6)); + + if (hints->ai_flags & ARES_AI_CANONNAME) + { + cname = ares__append_addrinfo_cname(&ai->cnames); + if (!cname) + { + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return 1; + } + + /* Duplicate the name, to avoid a constness violation. */ + cname->name = ares_strdup(name); + if (!cname->name) + { + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return 1; + } + } + + node->ai_socktype = hints->ai_socktype; + node->ai_protocol = hints->ai_protocol; + + callback(arg, ARES_SUCCESS, 0, ai); + return 1; +} + +static void end_hquery(struct host_query *hquery, int status) +{ + struct ares_addrinfo_node sentinel; + struct ares_addrinfo_node *next; + if (status == ARES_SUCCESS) + { + if (!(hquery->hints.ai_flags & ARES_AI_NOSORT)) + { + sentinel.ai_next = hquery->ai->nodes; + ares__sortaddrinfo(hquery->channel, &sentinel); + hquery->ai->nodes = sentinel.ai_next; + } + next = hquery->ai->nodes; + /* Set port into each address (resolved separately). */ + while (next) + { + next->ai_socktype = hquery->hints.ai_socktype; + next->ai_protocol = hquery->hints.ai_protocol; + if (next->ai_family == AF_INET) + { + (CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr))->sin_port = htons(hquery->port); + } + else + { + (CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr))->sin6_port = htons(hquery->port); + } + next = next->ai_next; + } + } + else + { + /* Clean up what we have collected by so far. */ + ares_freeaddrinfo(hquery->ai); + hquery->ai = NULL; + } + + hquery->callback(hquery->arg, status, hquery->timeouts, hquery->ai); + ares_free(hquery->name); + ares_free(hquery); +} + +static int file_lookup(struct host_query *hquery) +{ + FILE *fp; + int error; + int status; + const char *path_hosts = NULL; + + if (hquery->hints.ai_flags & ARES_AI_ENVHOSTS) + { + path_hosts = getenv("CARES_HOSTS"); + } + + if (!path_hosts) + { +#ifdef WIN32 + char PATH_HOSTS[MAX_PATH]; + win_platform platform; + + PATH_HOSTS[0] = '\0'; + + platform = ares__getplatform(); + + if (platform == WIN_NT) + { + char tmp[MAX_PATH]; + HKEY hkeyHosts; + + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + &hkeyHosts) == ERROR_SUCCESS) + { + DWORD dwLength = MAX_PATH; + RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, + &dwLength); + ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); + RegCloseKey(hkeyHosts); + } + } + else if (platform == WIN_9X) + GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH); + else + return ARES_ENOTFOUND; + + strcat(PATH_HOSTS, WIN_PATH_HOSTS); + path_hosts = PATH_HOSTS; + +#elif defined(WATT32) + const char *PATH_HOSTS = _w32_GetHostsFile(); + + if (!PATH_HOSTS) + return ARES_ENOTFOUND; +#endif + path_hosts = PATH_HOSTS; + } + + fp = fopen(path_hosts, "r"); + if (!fp) + { + error = ERRNO; + switch (error) + { + case ENOENT: + case ESRCH: + return ARES_ENOTFOUND; + default: + DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", error, + strerror(error))); + DEBUGF(fprintf(stderr, "Error opening file: %s\n", path_hosts)); + return ARES_EFILE; + } + } + status = ares__readaddrinfo(fp, hquery->name, hquery->port, &hquery->hints, hquery->ai); + fclose(fp); + return status; +} + +static void next_lookup(struct host_query *hquery, int status) +{ + switch (*hquery->remaining_lookups) + { + case 'b': + /* DNS lookup */ + if (next_dns_lookup(hquery)) + break; + hquery->remaining_lookups++; + next_lookup(hquery, status); + break; + + case 'f': + /* Host file lookup */ + if (file_lookup(hquery) == ARES_SUCCESS) + { + end_hquery(hquery, ARES_SUCCESS); + break; + } + hquery->remaining_lookups++; + next_lookup(hquery, status); + break; + default: + /* No lookup left */ + end_hquery(hquery, status); + break; + } +} + +static void host_callback(void *arg, int status, int timeouts, + unsigned char *abuf, int alen) +{ + struct host_query *hquery = (struct host_query*)arg; + int addinfostatus = ARES_SUCCESS; + hquery->timeouts += timeouts; + hquery->remaining--; + + if (status == ARES_SUCCESS) + { + addinfostatus = ares__parse_into_addrinfo(abuf, alen, hquery->ai); + } + else if (status == ARES_EDESTRUCTION) + { + end_hquery(hquery, status); + return; + } + + if (!hquery->remaining) + { + if (addinfostatus != ARES_SUCCESS) + { + /* error in parsing result e.g. no memory */ + end_hquery(hquery, addinfostatus); + } + else if (hquery->ai->nodes) + { + /* at least one query ended with ARES_SUCCESS */ + end_hquery(hquery, ARES_SUCCESS); + } + else if (status == ARES_ENOTFOUND) + { + next_lookup(hquery, status); + } + else + { + end_hquery(hquery, status); + } + } + + /* at this point we keep on waiting for the next query to finish */ +} + +void ares_getaddrinfo(ares_channel channel, + const char* name, const char* service, + const struct ares_addrinfo_hints* hints, + ares_addrinfo_callback callback, void* arg) +{ + struct host_query *hquery; + unsigned short port = 0; + int family; + struct ares_addrinfo *ai; + + if (!hints) + { + hints = &default_hints; + } + + family = hints->ai_family; + + /* Right now we only know how to look up Internet addresses + and unspec means try both basically. */ + if (family != AF_INET && + family != AF_INET6 && + family != AF_UNSPEC) + { + callback(arg, ARES_ENOTIMP, 0, NULL); + return; + } + + if (ares__is_onion_domain(name)) + { + callback(arg, ARES_ENOTFOUND, 0, NULL); + return; + } + + if (service) + { + if (hints->ai_flags & ARES_AI_NUMERICSERV) + { + port = (unsigned short)strtoul(service, NULL, 0); + if (!port) + { + callback(arg, ARES_ESERVICE, 0, NULL); + return; + } + } + else + { + port = lookup_service(service, 0); + if (!port) + { + port = (unsigned short)strtoul(service, NULL, 0); + if (!port) + { + callback(arg, ARES_ESERVICE, 0, NULL); + return; + } + } + } + } + + ai = ares__malloc_addrinfo(); + if (!ai) + { + callback(arg, ARES_ENOMEM, 0, NULL); + return; + } + + if (fake_addrinfo(name, port, hints, ai, callback, arg)) + { + return; + } + + /* Allocate and fill in the host query structure. */ + hquery = ares_malloc(sizeof(struct host_query)); + if (!hquery) + { + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return; + } + + hquery->name = ares_strdup(name); + if (!hquery->name) + { + ares_free(hquery); + ares_freeaddrinfo(ai); + callback(arg, ARES_ENOMEM, 0, NULL); + return; + } + + hquery->port = port; + hquery->channel = channel; + hquery->hints = *hints; + hquery->sent_family = -1; /* nothing is sent yet */ + hquery->callback = callback; + hquery->arg = arg; + hquery->remaining_lookups = channel->lookups; + hquery->timeouts = 0; + hquery->ai = ai; + hquery->next_domain = -1; + hquery->remaining = 0; + + /* Start performing lookups according to channel->lookups. */ + next_lookup(hquery, ARES_ECONNREFUSED /* initial error code */); +} + +static int next_dns_lookup(struct host_query *hquery) +{ + char *s = NULL; + int is_s_allocated = 0; + int status; + + /* if next_domain == -1 and as_is_first is true, try hquery->name */ + if (hquery->next_domain == -1) + { + if (as_is_first(hquery)) + { + s = hquery->name; + } + hquery->next_domain = 0; + } + + /* if as_is_first is false, try hquery->name at last */ + if (!s && hquery->next_domain == hquery->channel->ndomains) { + if (!as_is_first(hquery)) + { + s = hquery->name; + } + hquery->next_domain++; + } + + if (!s && hquery->next_domain < hquery->channel->ndomains) + { + status = ares__cat_domain( + hquery->name, + hquery->channel->domains[hquery->next_domain++], + &s); + if (status == ARES_SUCCESS) + { + is_s_allocated = 1; + } + } + + if (s) + { + switch (hquery->hints.ai_family) + { + case AF_INET: + hquery->remaining += 1; + ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery); + break; + case AF_INET6: + hquery->remaining += 1; + ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery); + break; + case AF_UNSPEC: + hquery->remaining += 2; + ares_query(hquery->channel, s, C_IN, T_A, host_callback, hquery); + ares_query(hquery->channel, s, C_IN, T_AAAA, host_callback, hquery); + break; + default: break; + } + if (is_s_allocated) + { + ares_free(s); + } + return 1; + } + else + { + assert(!hquery->ai->nodes); + return 0; + } +} + +static int as_is_first(const struct host_query* hquery) +{ + char* p; + int ndots = 0; + size_t nname = strlen(hquery->name); + for (p = hquery->name; *p; p++) + { + if (*p == '.') + { + ndots++; + } + } + if (nname && hquery->name[nname-1] == '.') + { + /* prevent ARES_EBADNAME for valid FQDN, where ndots < channel->ndots */ + return 1; + } + return ndots >= hquery->channel->ndots; +} diff --git a/ares_getenv.c b/src/lib/ares_getenv.c similarity index 97% rename from ares_getenv.c rename to src/lib/ares_getenv.c index 1b2e85d..f6e4dc2 100644 --- a/ares_getenv.c +++ b/src/lib/ares_getenv.c @@ -22,9 +22,7 @@ char *ares_getenv(const char *name) { -#ifdef _WIN32_WCE return NULL; -#endif } #endif diff --git a/ares_getenv.h b/src/lib/ares_getenv.h similarity index 100% rename from ares_getenv.h rename to src/lib/ares_getenv.h diff --git a/ares_gethostbyaddr.c b/src/lib/ares_gethostbyaddr.c similarity index 96% rename from ares_gethostbyaddr.c rename to src/lib/ares_gethostbyaddr.c index 9258919..54eb599 100644 --- a/ares_gethostbyaddr.c +++ b/src/lib/ares_gethostbyaddr.c @@ -157,7 +157,7 @@ static void addr_callback(void *arg, int status, int timeouts, } end_aquery(aquery, status, host); } - else if (status == ARES_EDESTRUCTION) + else if (status == ARES_EDESTRUCTION || status == ARES_ECANCELLED) end_aquery(aquery, status, NULL); else next_lookup(aquery); @@ -190,25 +190,24 @@ static int file_lookup(struct ares_addr *addr, struct hostent **host) char tmp[MAX_PATH]; HKEY hkeyHosts; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; - RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, + RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); - ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); + ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) - GetWindowsDirectory(PATH_HOSTS, MAX_PATH); + GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; strcat(PATH_HOSTS, WIN_PATH_HOSTS); #elif defined(WATT32) - extern const char *_w32_GetHostsFile (void); const char *PATH_HOSTS = _w32_GetHostsFile(); if (!PATH_HOSTS) diff --git a/ares_gethostbyname.c b/src/lib/ares_gethostbyname.c similarity index 92% rename from ares_gethostbyname.c rename to src/lib/ares_gethostbyname.c index caab6ae..4e41898 100644 --- a/ares_gethostbyname.c +++ b/src/lib/ares_gethostbyname.c @@ -95,6 +95,13 @@ void ares_gethostbyname(ares_channel channel, const char *name, int family, return; } + /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ + if (ares__is_onion_domain(name)) + { + callback(arg, ARES_ENOTFOUND, 0, NULL); + return; + } + if (fake_hostent(name, family, callback, arg)) return; @@ -204,6 +211,13 @@ static void host_callback(void *arg, int status, int timeouts, if (host && channel->nsort) sort6_addresses(host, channel->sortlist, channel->nsort); } + if (status == ARES_SUCCESS && host && host->h_addr_list[0] == NULL) + { + /* The query returned something but had no A/AAAA record + (even after potentially retrying AAAA with A) + so we should treat this as an error */ + status = ARES_ENODATA; + } end_hquery(hquery, status, host); } else if ((status == ARES_ENODATA || status == ARES_EBADRESP || @@ -244,7 +258,7 @@ static int fake_hostent(const char *name, int family, struct in_addr in; struct ares_in6_addr in6; - if (family == AF_INET || family == AF_INET6) + if (family == AF_INET || family == AF_UNSPEC) { /* It only looks like an IP address if it's all numbers and dots. */ int numdots = 0, valid = 1; @@ -260,15 +274,19 @@ static int fake_hostent(const char *name, int family, } /* if we don't have 3 dots, it is illegal - * (although inet_addr doesn't think so). + * (although inet_pton doesn't think so). */ - if (numdots != 3 || !valid) + if (numdots != 3 || !valid) { result = 0; - else - result = ((in.s_addr = inet_addr(name)) == INADDR_NONE ? 0 : 1); + } else { + result = (ares_inet_pton(AF_INET, name, &in) < 1 ? 0 : 1); + } - if (result) - family = AF_INET; + /* + * Set address family in case of failure, + * as we will try to convert it later afterwards + */ + family = result ? AF_INET : AF_INET6; } if (family == AF_INET6) result = (ares_inet_pton(AF_INET6, name, &in6) < 1 ? 0 : 1); @@ -351,31 +369,35 @@ static int file_lookup(const char *name, int family, struct hostent **host) char tmp[MAX_PATH]; HKEY hkeyHosts; - if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hkeyHosts) == ERROR_SUCCESS) { DWORD dwLength = MAX_PATH; - RegQueryValueEx(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, + RegQueryValueExA(hkeyHosts, DATABASEPATH, NULL, NULL, (LPBYTE)tmp, &dwLength); - ExpandEnvironmentStrings(tmp, PATH_HOSTS, MAX_PATH); + ExpandEnvironmentStringsA(tmp, PATH_HOSTS, MAX_PATH); RegCloseKey(hkeyHosts); } } else if (platform == WIN_9X) - GetWindowsDirectory(PATH_HOSTS, MAX_PATH); + GetWindowsDirectoryA(PATH_HOSTS, MAX_PATH); else return ARES_ENOTFOUND; strcat(PATH_HOSTS, WIN_PATH_HOSTS); #elif defined(WATT32) - extern const char *_w32_GetHostsFile (void); const char *PATH_HOSTS = _w32_GetHostsFile(); if (!PATH_HOSTS) return ARES_ENOTFOUND; #endif + /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ + if (ares__is_onion_domain(name)) + return ARES_ENOTFOUND; + + fp = fopen(PATH_HOSTS, "r"); if (!fp) { diff --git a/ares_getnameinfo.c b/src/lib/ares_getnameinfo.c similarity index 92% rename from ares_getnameinfo.c rename to src/lib/ares_getnameinfo.c index 4516112..53f91ca 100644 --- a/ares_getnameinfo.c +++ b/src/lib/ares_getnameinfo.c @@ -92,13 +92,13 @@ void ares_getnameinfo(ares_channel channel, const struct sockaddr *sa, if ((sa->sa_family == AF_INET) && (salen == sizeof(struct sockaddr_in))) { - addr = (struct sockaddr_in *)sa; + addr = CARES_INADDR_CAST(struct sockaddr_in *, sa); port = addr->sin_port; } else if ((sa->sa_family == AF_INET6) && (salen == sizeof(struct sockaddr_in6))) { - addr6 = (struct sockaddr_in6 *)sa; + addr6 = CARES_INADDR_CAST(struct sockaddr_in6 *, sa); port = addr6->sin6_port; } else @@ -356,12 +356,9 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, #ifdef HAVE_IF_INDEXTONAME int is_ll, is_mcll; #endif - static const char fmt_u[] = "%u"; - static const char fmt_lu[] = "%lu"; char tmpbuf[IF_NAMESIZE + 2]; size_t bufl; - const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))? - fmt_lu:fmt_u; + int is_scope_long = sizeof(addr6->sin6_scope_id) > sizeof(unsigned int); tmpbuf[0] = '%'; @@ -371,15 +368,38 @@ static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags, if ((flags & ARES_NI_NUMERICSCOPE) || (!is_ll && !is_mcll)) { - sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); + if (is_scope_long) + { + sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + } + else + { + sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + } } else { if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL) - sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); + { + if (is_scope_long) + { + sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + } + else + { + sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + } + } } #else - sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id); + if (is_scope_long) + { + sprintf(&tmpbuf[1], "%lu", (unsigned long)addr6->sin6_scope_id); + } + else + { + sprintf(&tmpbuf[1], "%u", (unsigned int)addr6->sin6_scope_id); + } (void) flags; #endif tmpbuf[IF_NAMESIZE + 1] = '\0'; @@ -420,3 +440,14 @@ STATIC_TESTABLE char *ares_striendstr(const char *s1, const char *s2) } return (char *)c1_begin; } + +int ares__is_onion_domain(const char *name) +{ + if (ares_striendstr(name, ".onion")) + return 1; + + if (ares_striendstr(name, ".onion.")) + return 1; + + return 0; +} diff --git a/ares_getsock.c b/src/lib/ares_getsock.c similarity index 100% rename from ares_getsock.c rename to src/lib/ares_getsock.c diff --git a/ares_inet_net_pton.h b/src/lib/ares_inet_net_pton.h similarity index 100% rename from ares_inet_net_pton.h rename to src/lib/ares_inet_net_pton.h diff --git a/ares_init.c b/src/lib/ares_init.c similarity index 73% rename from ares_init.c rename to src/lib/ares_init.c index f557947..92187e4 100644 --- a/ares_init.c +++ b/src/lib/ares_init.c @@ -44,6 +44,7 @@ #if defined(ANDROID) || defined(__ANDROID__) #include +#include "ares_android.h" /* From the Bionic sources */ #define DNS_PROP_NAME_PREFIX "net.dns" #define MAX_DNS_PROPERTIES 8 @@ -84,7 +85,7 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, const char *str); static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat); -static int ip_addr(const char *s, ssize_t len, struct in_addr *addr); +static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr); static void natural_mask(struct apattern *pat); #if !defined(WIN32) && !defined(WATT32) && \ !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV) @@ -114,20 +115,6 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, int status = ARES_SUCCESS; struct timeval now; -#ifdef CURLDEBUG - const char *env = getenv("CARES_MEMDEBUG"); - - if (env) - curl_memdebug(env); - env = getenv("CARES_MEMLIMIT"); - if (env) { - char *endptr; - long num = strtol(env, &endptr, 10); - if((endptr != env) && (endptr == env + strlen(env)) && (num > 0)) - curl_memlimit(num); - } -#endif - if (ares_library_initialized() != ARES_SUCCESS) return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */ @@ -166,6 +153,9 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options, channel->sock_create_cb_data = NULL; channel->sock_config_cb = NULL; channel->sock_config_cb_data = NULL; + channel->sock_funcs = NULL; + channel->sock_func_cb_data = NULL; + channel->resolvconf_path = NULL; channel->last_server = 0; channel->last_timeout_processed = (time_t)now.tv_sec; @@ -233,16 +223,14 @@ done: /* Something failed; clean up memory we may have allocated. */ if (channel->servers) ares_free(channel->servers); - if (channel->domains) - { - for (i = 0; i < channel->ndomains; i++) - ares_free(channel->domains[i]); - ares_free(channel->domains); - } + if (channel->ndomains != -1) + ares_strsplit_free(channel->domains, channel->ndomains); if (channel->sortlist) ares_free(channel->sortlist); if(channel->lookups) ares_free(channel->lookups); + if(channel->resolvconf_path) + ares_free(channel->resolvconf_path); ares_free(channel); return status; } @@ -292,9 +280,11 @@ int ares_dup(ares_channel *dest, ares_channel src) (*dest)->sock_create_cb_data = src->sock_create_cb_data; (*dest)->sock_config_cb = src->sock_config_cb; (*dest)->sock_config_cb_data = src->sock_config_cb_data; + (*dest)->sock_funcs = src->sock_funcs; + (*dest)->sock_func_cb_data = src->sock_func_cb_data; strncpy((*dest)->local_dev_name, src->local_dev_name, - sizeof(src->local_dev_name)); + sizeof((*dest)->local_dev_name)); (*dest)->local_ip4 = src->local_ip4; memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6)); @@ -349,6 +339,9 @@ int ares_save_options(ares_channel channel, struct ares_options *options, ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS); (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE); + if (channel->resolvconf_path) + (*optmask) |= ARES_OPT_RESOLVCONF; + /* Copy easy stuff */ options->flags = channel->flags; @@ -421,6 +414,13 @@ int ares_save_options(ares_channel channel, struct ares_options *options, } options->nsort = channel->nsort; + /* copy path for resolv.conf file */ + if (channel->resolvconf_path) { + options->resolvconf_path = ares_strdup(channel->resolvconf_path); + if (!options->resolvconf_path) + return ARES_ENOMEM; + } + return ARES_SUCCESS; } @@ -529,6 +529,14 @@ static int init_by_options(ares_channel channel, channel->nsort = options->nsort; } + /* Set path for resolv.conf file, if given. */ + if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path) + { + channel->resolvconf_path = ares_strdup(options->resolvconf_path); + if (!channel->resolvconf_path && options->resolvconf_path) + return ARES_ENOMEM; + } + channel->optmask = optmask; return ARES_SUCCESS; @@ -581,7 +589,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) *outptr = NULL; /* Find out size of string stored in registry */ - res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size); + res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; @@ -592,7 +600,7 @@ static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr) return 0; /* Get the value for real */ - res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, + res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { @@ -623,7 +631,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) *outptr = NULL; /* Find out size of string stored in registry */ - res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size); + res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size); if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size) return 0; @@ -634,7 +642,7 @@ static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr) return 0; /* Get the value for real */ - res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, + res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, (unsigned char *)*outptr, &size); if ((res != ERROR_SUCCESS) || (size == 1)) { @@ -679,11 +687,11 @@ static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName, for(;;) { enumKeyNameBuffSize = sizeof(enumKeyName); - res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName, + res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName, &enumKeyNameBuffSize, 0, NULL, NULL, NULL); if (res != ERROR_SUCCESS) break; - res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE, + res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE, &hKeyEnum); if (res != ERROR_SUCCESS) continue; @@ -714,7 +722,7 @@ static int get_DNS_Registry_9X(char **outptr) *outptr = NULL; - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ, &hKey_VxD_MStcp); if (res != ERROR_SUCCESS) return 0; @@ -746,7 +754,7 @@ static int get_DNS_Registry_NT(char **outptr) *outptr = NULL; - res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, + res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ, &hKey_Tcpip_Parameters); if (res != ERROR_SUCCESS) return 0; @@ -768,7 +776,7 @@ static int get_DNS_Registry_NT(char **outptr) goto done; /* Try adapter specific parameters */ - res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0, + res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, &hKey_Interfaces); if (res != ERROR_SUCCESS) @@ -828,6 +836,24 @@ static int get_DNS_Registry(char **outptr) return 1; } +static void commanjoin(char** dst, const char* const src, const size_t len) +{ + char *newbuf; + size_t newsize; + + /* 1 for terminating 0 and 2 for , and terminating 0 */ + newsize = len + (*dst ? (strlen(*dst) + 2) : 1); + newbuf = ares_realloc(*dst, newsize); + if (!newbuf) + return; + if (*dst == NULL) + *newbuf = '\0'; + *dst = newbuf; + if (strlen(*dst) != 0) + strcat(*dst, ","); + strncat(*dst, src, len); +} + /* * commajoin() * @@ -835,24 +861,7 @@ static int get_DNS_Registry(char **outptr) */ static void commajoin(char **dst, const char *src) { - char *tmp; - - if (*dst) - { - tmp = ares_malloc(strlen(*dst) + strlen(src) + 2); - if (!tmp) - return; - sprintf(tmp, "%s,%s", *dst, src); - ares_free(*dst); - *dst = tmp; - } - else - { - *dst = ares_malloc(strlen(src) + 1); - if (!*dst) - return; - strcpy(*dst, src); - } + commanjoin(dst, src, strlen(src)); } /* @@ -939,6 +948,131 @@ done: return 1; } +static BOOL ares_IsWindowsVistaOrGreater(void) +{ + OSVERSIONINFO vinfo; + memset(&vinfo, 0, sizeof(vinfo)); + vinfo.dwOSVersionInfoSize = sizeof(vinfo); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */ +#endif + if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6) + return FALSE; + return TRUE; +#ifdef _MSC_VER +#pragma warning(pop) +#endif +} + +/* A structure to hold the string form of IPv4 and IPv6 addresses so we can + * sort them by a metric. + */ +typedef struct +{ + /* The metric we sort them by. */ + ULONG metric; + + /* Original index of the item, used as a secondary sort parameter to make + * qsort() stable if the metrics are equal */ + size_t orig_idx; + + /* Room enough for the string form of any IPv4 or IPv6 address that + * ares_inet_ntop() will create. Based on the existing c-ares practice. + */ + char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; +} Address; + +/* Sort Address values \a left and \a right by metric, returning the usual + * indicators for qsort(). + */ +static int compareAddresses(const void *arg1, + const void *arg2) +{ + const Address * const left = arg1; + const Address * const right = arg2; + /* Lower metric the more preferred */ + if(left->metric < right->metric) return -1; + if(left->metric > right->metric) return 1; + /* If metrics are equal, lower original index more preferred */ + if(left->orig_idx < right->orig_idx) return -1; + if(left->orig_idx > right->orig_idx) return 1; + return 0; +} + +/* There can be multiple routes to "the Internet". And there can be different + * DNS servers associated with each of the interfaces that offer those routes. + * We have to assume that any DNS server can serve any request. But, some DNS + * servers may only respond if requested over their associated interface. But + * we also want to use "the preferred route to the Internet" whenever possible + * (and not use DNS servers on a non-preferred route even by forcing request + * to go out on the associated non-preferred interface). i.e. We want to use + * the DNS servers associated with the same interface that we would use to + * make a general request to anything else. + * + * But, Windows won't sort the DNS servers by the metrics associated with the + * routes and interfaces _even_ though it obviously sends IP packets based on + * those same routes and metrics. So, we must do it ourselves. + * + * So, we sort the DNS servers by the same metric values used to determine how + * an outgoing IP packet will go, thus effectively using the DNS servers + * associated with the interface that the DNS requests themselves will + * travel. This gives us optimal routing and avoids issues where DNS servers + * won't respond to requests that don't arrive via some specific subnetwork + * (and thus some specific interface). + * + * This function computes the metric we use to sort. On the interface + * identified by \a luid, it determines the best route to \a dest and combines + * that route's metric with \a interfaceMetric to compute a metric for the + * destination address on that interface. This metric can be used as a weight + * to sort the DNS server addresses associated with each interface (lower is + * better). + * + * Note that by restricting the route search to the specific interface with + * which the DNS servers are associated, this function asks the question "What + * is the metric for sending IP packets to this DNS server?" which allows us + * to sort the DNS servers correctly. + */ +static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */ + const SOCKADDR_INET * const dest, + const ULONG interfaceMetric) +{ + /* On this interface, get the best route to that destination. */ + MIB_IPFORWARD_ROW2 row; + SOCKADDR_INET ignored; + if(!ares_fpGetBestRoute2 || + ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are + * passing a LUID. + */ + luid, 0, + /* No specific source address. */ + NULL, + /* Our destination address. */ + dest, + /* No options. */ + 0, + /* The route row. */ + &row, + /* The best source address, which we don't need. */ + &ignored) != NO_ERROR + /* If the metric is "unused" (-1) or too large for us to add the two + * metrics, use the worst possible, thus sorting this last. + */ + || row.Metric == (ULONG)-1 + || row.Metric > ((ULONG)-1) - interfaceMetric) { + /* Return the worst possible metric. */ + return (ULONG)-1; + } + + /* Return the metric value from that row, plus the interface metric. + * + * See + * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx + * which describes the combination as a "sum". + */ + return row.Metric + interfaceMetric; +} + /* * get_DNS_AdaptersAddresses() * @@ -965,14 +1099,19 @@ static int get_DNS_AdaptersAddresses(char **outptr) int trying = IPAA_MAX_TRIES; int res; + /* The capacity of addresses, in elements. */ + size_t addressesSize; + /* The number of elements in addresses. */ + size_t addressesIndex = 0; + /* The addresses we will sort. */ + Address *addresses; + union { struct sockaddr *sa; struct sockaddr_in *sa4; struct sockaddr_in6 *sa6; } namesrvr; - char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")]; - *outptr = NULL; /* Verify run-time availability of GetAdaptersAddresses() */ @@ -983,6 +1122,17 @@ static int get_DNS_AdaptersAddresses(char **outptr) if (!ipaa) return 0; + /* Start with enough room for a few DNS server addresses and we'll grow it + * as we encounter more. + */ + addressesSize = 4; + addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize); + if(addresses == NULL) { + /* We need room for at least some addresses to function. */ + ares_free(ipaa); + return 0; + } + /* Usually this call suceeds with initial buffer size */ res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL, ipaa, &ReqBufsz); @@ -1012,6 +1162,12 @@ static int get_DNS_AdaptersAddresses(char **outptr) if(ipaaEntry->OperStatus != IfOperStatusUp) continue; + /* For each interface, find any associated DNS servers as IPv4 or IPv6 + * addresses. For each found address, find the best route to that DNS + * server address _on_ _that_ _interface_ (at this moment in time) and + * compute the resulting total metric, just as Windows routing will do. + * Then, sort all the addresses found by the metric. + */ for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress; ipaDNSAddr; ipaDNSAddr = ipaDNSAddr->Next) @@ -1023,35 +1179,124 @@ static int get_DNS_AdaptersAddresses(char **outptr) if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) || (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE)) continue; + + /* Allocate room for another address, if necessary, else skip. */ + if(addressesIndex == addressesSize) { + const size_t newSize = addressesSize + 4; + Address * const newMem = + (Address*)ares_realloc(addresses, sizeof(Address) * newSize); + if(newMem == NULL) { + continue; + } + addresses = newMem; + addressesSize = newSize; + } + + /* Vista required for Luid or Ipv4Metric */ + if (ares_IsWindowsVistaOrGreater()) + { + /* Save the address as the next element in addresses. */ + addresses[addressesIndex].metric = + getBestRouteMetric(&ipaaEntry->Luid, + (SOCKADDR_INET*)(namesrvr.sa), + ipaaEntry->Ipv4Metric); + } + else + { + addresses[addressesIndex].metric = (ULONG)-1; + } + + /* Record insertion index to make qsort stable */ + addresses[addressesIndex].orig_idx = addressesIndex; + if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr, - txtaddr, sizeof(txtaddr))) + addresses[addressesIndex].text, + sizeof(addresses[0].text))) { continue; + } + ++addressesIndex; } else if (namesrvr.sa->sa_family == AF_INET6) { if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any, sizeof(namesrvr.sa6->sin6_addr)) == 0) continue; + + /* Allocate room for another address, if necessary, else skip. */ + if(addressesIndex == addressesSize) { + const size_t newSize = addressesSize + 4; + Address * const newMem = + (Address*)ares_realloc(addresses, sizeof(Address) * newSize); + if(newMem == NULL) { + continue; + } + addresses = newMem; + addressesSize = newSize; + } + + /* Vista required for Luid or Ipv4Metric */ + if (ares_IsWindowsVistaOrGreater()) + { + /* Save the address as the next element in addresses. */ + addresses[addressesIndex].metric = + getBestRouteMetric(&ipaaEntry->Luid, + (SOCKADDR_INET*)(namesrvr.sa), + ipaaEntry->Ipv6Metric); + } + else + { + addresses[addressesIndex].metric = (ULONG)-1; + } + + /* Record insertion index to make qsort stable */ + addresses[addressesIndex].orig_idx = addressesIndex; + if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr, - txtaddr, sizeof(txtaddr))) + addresses[addressesIndex].text, + sizeof(addresses[0].text))) { continue; + } + ++addressesIndex; } - else + else { + /* Skip non-IPv4/IPv6 addresses completely. */ continue; + } + } + } - commajoin(outptr, txtaddr); + /* Sort all of the textual addresses by their metric (and original index if + * metrics are equal). */ + qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses); - if (!*outptr) - goto done; + /* Join them all into a single string, removing duplicates. */ + { + size_t i; + for(i = 0; i < addressesIndex; ++i) { + size_t j; + /* Look for this address text appearing previously in the results. */ + for(j = 0; j < i; ++j) { + if(strcmp(addresses[j].text, addresses[i].text) == 0) { + break; + } + } + /* Iff we didn't emit this address already, emit it now. */ + if(j == i) { + /* Add that to outptr (if we can). */ + commajoin(outptr, addresses[i].text); + } } } done: + ares_free(addresses); + if (ipaa) ares_free(ipaa); - if (!*outptr) + if (!*outptr) { return 0; + } return 1; } @@ -1072,23 +1317,126 @@ done: */ static int get_DNS_Windows(char **outptr) { - /* - Use GetNetworkParams First in case of - multiple adapter is enabled on this machine. - GetAdaptersAddresses will retrive dummy dns servers. - That will slowing DNS lookup. - */ - /* Try using IP helper API GetNetworkParams() */ - if (get_DNS_NetworkParams(outptr)) + /* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts + * DNS servers by interface route metrics to try to use the best DNS server. */ + if (get_DNS_AdaptersAddresses(outptr)) return 1; - /* Try using IP helper API GetAdaptersAddresses() */ - if (get_DNS_AdaptersAddresses(outptr)) + /* Try using IP helper API GetNetworkParams(). IPv4 only. */ + if (get_DNS_NetworkParams(outptr)) return 1; /* Fall-back to registry information */ return get_DNS_Registry(outptr); } + +/* + * get_SuffixList_Windows() + * + * Reads the "DNS Suffix Search List" from registry and writes the list items + * whitespace separated to outptr. If the Search List is empty, the + * "Primary Dns Suffix" is written to outptr. + * + * Returns 0 and nullifies *outptr upon inability to return the suffix list. + * + * Returns 1 and sets *outptr when returning a dynamically allocated string. + * + * Implementation supports Windows Server 2003 and newer + */ +static int get_SuffixList_Windows(char **outptr) +{ + HKEY hKey, hKeyEnum; + char keyName[256]; + DWORD keyNameBuffSize; + DWORD keyIdx = 0; + char *p = NULL; + + *outptr = NULL; + + if (ares__getplatform() != WIN_NT) + return 0; + + /* 1. Global DNS Suffix Search List */ + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, + KEY_READ, &hKey) == ERROR_SUCCESS) + { + get_REG_SZ(hKey, SEARCHLIST_KEY, outptr); + if (get_REG_SZ(hKey, DOMAIN_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + RegCloseKey(hKey); + } + + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0, + KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + RegCloseKey(hKey); + } + + /* 2. Connection Specific Search List composed of: + * a. Primary DNS Suffix */ + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0, + KEY_READ, &hKey) == ERROR_SUCCESS) + { + if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + RegCloseKey(hKey); + } + + /* b. Interface SearchList, Domain, DhcpDomain */ + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0, + KEY_READ, &hKey) == ERROR_SUCCESS) + { + for(;;) + { + keyNameBuffSize = sizeof(keyName); + if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize, + 0, NULL, NULL, NULL) + != ERROR_SUCCESS) + break; + if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum) + != ERROR_SUCCESS) + continue; + /* p can be comma separated (SearchList) */ + if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p)) + { + commajoin(outptr, p); + ares_free(p); + p = NULL; + } + RegCloseKey(hKeyEnum); + } + RegCloseKey(hKey); + } + + return *outptr != NULL; +} + #endif static int init_by_resolv_conf(ares_channel channel) @@ -1112,6 +1460,12 @@ static int init_by_resolv_conf(ares_channel channel) ares_free(line); } + if (channel->ndomains == -1 && get_SuffixList_Windows(&line)) + { + status = set_search(channel, line); + ares_free(line); + } + if (status == ARES_SUCCESS) status = ARES_EOF; else @@ -1175,20 +1529,64 @@ static int init_by_resolv_conf(ares_channel channel) #elif defined(ANDROID) || defined(__ANDROID__) unsigned int i; - char propname[PROP_NAME_MAX]; - char propvalue[PROP_VALUE_MAX]=""; + char **dns_servers; + char *domains; + size_t num_servers; + + /* Use the Android connectivity manager to get a list + * of DNS servers. As of Android 8 (Oreo) net.dns# + * system properties are no longer available. Google claims this + * improves privacy. Apps now need the ACCESS_NETWORK_STATE + * permission and must use the ConnectivityManager which + * is Java only. */ + dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers); + if (dns_servers != NULL) + { + for (i = 0; i < num_servers; i++) + { + status = config_nameserver(&servers, &nservers, dns_servers[i]); + if (status != ARES_SUCCESS) + break; + status = ARES_EOF; + } + for (i = 0; i < num_servers; i++) + { + ares_free(dns_servers[i]); + } + ares_free(dns_servers); + } + if (channel->ndomains == -1) + { + domains = ares_get_android_search_domains_list(); + set_search(channel, domains); + ares_free(domains); + } - for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { - snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); - if (__system_property_get(propname, propvalue) < 1) { +# ifdef HAVE___SYSTEM_PROPERTY_GET + /* Old way using the system property still in place as + * a fallback. Older android versions can still use this. + * it's possible for older apps not not have added the new + * permission and we want to try to avoid breaking those. + * + * We'll only run this if we don't have any dns servers + * because this will get the same ones (if it works). */ + if (status != ARES_EOF) { + char propname[PROP_NAME_MAX]; + char propvalue[PROP_VALUE_MAX]=""; + for (i = 1; i <= MAX_DNS_PROPERTIES; i++) { + snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i); + if (__system_property_get(propname, propvalue) < 1) { + status = ARES_EOF; + break; + } + + status = config_nameserver(&servers, &nservers, propvalue); + if (status != ARES_SUCCESS) + break; status = ARES_EOF; - break; } - status = config_nameserver(&servers, &nservers, propvalue); - if (status != ARES_SUCCESS) - break; - status = ARES_EOF; } +# endif /* HAVE___SYSTEM_PROPERTY_GET */ #elif defined(CARES_USE_LIBRESOLV) struct __res_state res; memset(&res, 0, sizeof(res)); @@ -1199,7 +1597,8 @@ static int init_by_resolv_conf(ares_channel channel) if (channel->nservers == -1) { union res_sockaddr_union addr[MAXNS]; int nscount = res_getservers(&res, addr, MAXNS); - for (int i = 0; i < nscount; ++i) { + int i; + for (i = 0; i < nscount; ++i) { char str[INET6_ADDRSTRLEN]; int config_status; sa_family_t family = addr[i].sin.sin_family; @@ -1227,8 +1626,9 @@ static int init_by_resolv_conf(ares_channel channel) if (!channel->domains) { status = ARES_ENOMEM; } else { + int i; channel->ndomains = entries; - for (int i = 0; i < channel->ndomains; ++i) { + for (i = 0; i < channel->ndomains; ++i) { channel->domains[i] = ares_strdup(res.dnsrch[i]); if (!channel->domains[i]) status = ARES_ENOMEM; @@ -1253,6 +1653,7 @@ static int init_by_resolv_conf(ares_channel channel) size_t linesize; int error; int update_domains; + const char *resolvconf_path; /* Don't read resolv.conf and friends if we don't have to */ if (ARES_CONFIG_CHECK(channel)) @@ -1261,7 +1662,14 @@ static int init_by_resolv_conf(ares_channel channel) /* Only update search domains if they're not already specified */ update_domains = (channel->ndomains == -1); - fp = fopen(PATH_RESOLV_CONF, "r"); + /* Support path for resolvconf filename set by ares_init_options */ + if(channel->resolvconf_path) { + resolvconf_path = channel->resolvconf_path; + } else { + resolvconf_path = PATH_RESOLV_CONF; + } + + fp = fopen(resolvconf_path, "r"); if (fp) { while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS) { @@ -1272,10 +1680,10 @@ static int init_by_resolv_conf(ares_channel channel) else if ((p = try_config(line, "search", ';')) && update_domains) status = set_search(channel, p); else if ((p = try_config(line, "nameserver", ';')) && - channel->nservers == -1) + channel->nservers == -1) status = config_nameserver(&servers, &nservers, p); else if ((p = try_config(line, "sortlist", ';')) && - channel->nsort == -1) + channel->nsort == -1) status = config_sortlist(&sortlist, &nsort, p); else if ((p = try_config(line, "options", ';'))) status = set_options(channel, p); @@ -1295,7 +1703,7 @@ static int init_by_resolv_conf(ares_channel channel) break; default: DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n", - error, strerror(error))); + error, strerror(error))); DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF)); status = ARES_EFILE; } @@ -1508,8 +1916,10 @@ static int init_by_defaults(ares_channel channel) continue; } else if(res) { - rc = ARES_EBADNAME; - goto error; + /* Lets not treat a gethostname failure as critical, since we + * are ok if gethostname doesn't even exist */ + *hostname = '\0'; + break; } } while (res != 0); @@ -1561,6 +1971,11 @@ static int init_by_defaults(ares_channel channel) ares_free(channel->lookups); channel->lookups = NULL; } + + if(channel->resolvconf_path) { + ares_free(channel->resolvconf_path); + channel->resolvconf_path = NULL; + } } if(hostname) @@ -1597,6 +2012,7 @@ static int config_lookup(ares_channel channel, const char *str, { char lookups[3], *l; const char *vqualifier p; + int found; if (altbindch == NULL) altbindch = bindch; @@ -1607,17 +2023,21 @@ static int config_lookup(ares_channel channel, const char *str, */ l = lookups; p = str; + found = 0; while (*p) { if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) { if (*p == *bindch || *p == *altbindch) *l++ = 'b'; else *l++ = 'f'; + found = 1; } while (*p && !ISSPACE(*p) && (*p != ',')) p++; while (*p && (ISSPACE(*p) || (*p == ','))) p++; } + if (!found) + return ARES_ENOTINITIALIZED; *l = '\0'; channel->lookups = ares_strdup(lookups); return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM; @@ -1625,6 +2045,76 @@ static int config_lookup(ares_channel channel, const char *str, #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */ #ifndef WATT32 +/* Validate that the ip address matches the subnet (network base and network + * mask) specified. Addresses are specified in standard Network Byte Order as + * 16 bytes, and the netmask is 0 to 128 (bits). + */ +static int ares_ipv6_subnet_matches(const unsigned char netbase[16], + unsigned char netmask, + const unsigned char ipaddr[16]) +{ + unsigned char mask[16] = { 0 }; + unsigned char i; + + /* Misuse */ + if (netmask > 128) + return 0; + + /* Quickly set whole bytes */ + memset(mask, 0xFF, netmask / 8); + + /* Set remaining bits */ + if(netmask % 8) { + mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8))); + } + + for (i=0; i<16; i++) { + if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i])) + return 0; + } + + return 1; +} + +/* Return true iff the IPv6 ipaddr is blacklisted. */ +static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16]) +{ + /* A list of blacklisted IPv6 subnets. */ + const struct { + const unsigned char netbase[16]; + unsigned char netmask; + } blacklist[] = { + /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a + * Site-Local scoped address prefix. These are never valid DNS servers, + * but are known to be returned at least sometimes on Windows and Android. + */ + { + { + 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }, + 10 + } + }; + size_t i; + + /* See if ipaddr matches any of the entries in the blacklist. */ + for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) { + if (ares_ipv6_subnet_matches( + blacklist[i].netbase, blacklist[i].netmask, ipaddr)) + return 1; + } + return 0; +} + +/* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the + * servers list, updating servers and nservers as required. + * + * This will silently ignore blacklisted IPv6 nameservers as detected by + * ares_ipv6_server_blacklisted(). + * + * Returns an error code on failure, else ARES_SUCCESS. + */ static int config_nameserver(struct server_state **servers, int *nservers, char *str) { @@ -1659,7 +2149,10 @@ static int config_nameserver(struct server_state **servers, int *nservers, /* Convert textual address to binary format. */ if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1) host.family = AF_INET; - else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1) + else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1 + /* Silently skip blacklisted IPv6 servers. */ + && !ares_ipv6_server_blacklisted( + (const unsigned char *)&host.addrV6)) host.family = AF_INET6; else continue; @@ -1782,61 +2275,22 @@ static int config_sortlist(struct apattern **sortlist, int *nsort, static int set_search(ares_channel channel, const char *str) { - int n; - const char *p, *q; + size_t cnt; if(channel->ndomains != -1) { /* LCOV_EXCL_START: all callers check ndomains == -1 */ /* if we already have some domains present, free them first */ - for(n=0; n < channel->ndomains; n++) - ares_free(channel->domains[n]); - ares_free(channel->domains); + ares_strsplit_free(channel->domains, channel->ndomains); channel->domains = NULL; channel->ndomains = -1; } /* LCOV_EXCL_STOP */ - /* Count the domains given. */ - n = 0; - p = str; - while (*p) - { - while (*p && !ISSPACE(*p)) - p++; - while (ISSPACE(*p)) - p++; - n++; - } - - if (!n) - { - channel->ndomains = 0; - return ARES_SUCCESS; - } - - channel->domains = ares_malloc(n * sizeof(char *)); - if (!channel->domains) - return ARES_ENOMEM; - - /* Now copy the domains. */ - n = 0; - p = str; - while (*p) - { - channel->ndomains = n; - q = p; - while (*q && !ISSPACE(*q)) - q++; - channel->domains[n] = ares_malloc(q - p + 1); - if (!channel->domains[n]) - return ARES_ENOMEM; - memcpy(channel->domains[n], p, q - p); - channel->domains[n][q - p] = 0; - p = q; - while (ISSPACE(*p)) - p++; - n++; - } - channel->ndomains = n; + channel->domains = ares_strsplit(str, ", ", 1, &cnt); + channel->ndomains = (int)cnt; + if (channel->domains == NULL || channel->ndomains == 0) { + channel->domains = NULL; + channel->ndomains = -1; + } return ARES_SUCCESS; } @@ -1950,16 +2404,16 @@ static char *try_config(char *s, const char *opt, char scc) } #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */ -static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr) +static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr) { /* Four octets and three periods yields at most 15 characters. */ if (len > 15) return -1; - addr->s_addr = inet_addr(ipbuf); - if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0) + if (ares_inet_pton(AF_INET, ipbuf, addr) < 1) return -1; + return 0; } @@ -2103,6 +2557,14 @@ void ares_set_socket_configure_callback(ares_channel channel, channel->sock_config_cb_data = data; } +void ares_set_socket_functions(ares_channel channel, + const struct ares_socket_functions * funcs, + void *data) +{ + channel->sock_funcs = funcs; + channel->sock_func_cb_data = data; +} + int ares_set_sortlist(ares_channel channel, const char *sortstr) { int nsort = 0; diff --git a/ares_iphlpapi.h b/src/lib/ares_iphlpapi.h similarity index 100% rename from ares_iphlpapi.h rename to src/lib/ares_iphlpapi.h diff --git a/ares_ipv6.h b/src/lib/ares_ipv6.h similarity index 94% rename from ares_ipv6.h rename to src/lib/ares_ipv6.h index b0017f1..fdbc21f 100644 --- a/ares_ipv6.h +++ b/src/lib/ares_ipv6.h @@ -32,6 +32,13 @@ struct sockaddr_in6 }; #endif +typedef union +{ + struct sockaddr sa; + struct sockaddr_in sa4; + struct sockaddr_in6 sa6; +} ares_sockaddr; + #ifndef HAVE_STRUCT_ADDRINFO struct addrinfo { diff --git a/ares_library_init.c b/src/lib/ares_library_init.c similarity index 79% rename from ares_library_init.c rename to src/lib/ares_library_init.c index c885a16..6756349 100644 --- a/ares_library_init.c +++ b/src/lib/ares_library_init.c @@ -27,6 +27,11 @@ fpGetNetworkParams_t ares_fpGetNetworkParams = ZERO_NULL; fpSystemFunction036_t ares_fpSystemFunction036 = ZERO_NULL; fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses = ZERO_NULL; +fpGetBestRoute2_t ares_fpGetBestRoute2 = ZERO_NULL; +#endif + +#if defined(ANDROID) || defined(__ANDROID__) +#include "ares_android.h" #endif /* library-private global vars with source visibility restricted to this file */ @@ -35,9 +40,19 @@ static unsigned int ares_initialized; static int ares_init_flags; /* library-private global vars with visibility across the whole library */ -void *(*ares_malloc)(size_t size) = malloc; -void *(*ares_realloc)(void *ptr, size_t size) = realloc; -void (*ares_free)(void *ptr) = free; +#if defined(WIN32) +/* We need indirections to handle Windows DLL rules. */ +static void *default_malloc(size_t size) { return malloc(size); } +static void *default_realloc(void *p, size_t size) { return realloc(p, size); } +static void default_free(void *p) { free(p); } +#else +# define default_malloc malloc +# define default_realloc realloc +# define default_free free +#endif +void *(*ares_malloc)(size_t size) = default_malloc; +void *(*ares_realloc)(void *ptr, size_t size) = default_realloc; +void (*ares_free)(void *ptr) = default_free; #ifdef USE_WINSOCK static HMODULE hnd_iphlpapi; @@ -71,6 +86,15 @@ static int ares_win32_init(void) support Windows 2000 anymore */ } + ares_fpGetBestRoute2 = (fpGetBestRoute2_t) + GetProcAddress(hnd_iphlpapi, "GetBestRoute2"); + if (!ares_fpGetBestRoute2) + { + /* This can happen on clients before Vista, I don't + think it should be an error, unless we don't want to + support Windows XP anymore */ + } + /* * When advapi32.dll is unavailable or advapi32.dll has no SystemFunction036, * also known as RtlGenRandom, which is the case for Windows versions prior @@ -150,6 +174,10 @@ void ares_library_cleanup(void) if (ares_init_flags & ARES_LIB_INIT_WIN32) ares_win32_cleanup(); +#if defined(ANDROID) || defined(__ANDROID__) + ares_library_cleanup_android(); +#endif + ares_init_flags = ARES_LIB_INIT_NONE; ares_malloc = malloc; ares_realloc = realloc; diff --git a/ares_library_init.h b/src/lib/ares_library_init.h similarity index 87% rename from ares_library_init.h rename to src/lib/ares_library_init.h index 59e5cc5..2a2ba11 100644 --- a/ares_library_init.h +++ b/src/lib/ares_library_init.h @@ -28,13 +28,14 @@ typedef DWORD (WINAPI *fpGetNetworkParams_t) (FIXED_INFO*, DWORD*); typedef BOOLEAN (APIENTRY *fpSystemFunction036_t) (void*, ULONG); typedef ULONG (WINAPI *fpGetAdaptersAddresses_t) ( ULONG, ULONG, void*, IP_ADAPTER_ADDRESSES*, ULONG* ); - +typedef NETIO_STATUS (WINAPI *fpGetBestRoute2_t) ( NET_LUID *, NET_IFINDEX, const SOCKADDR_INET *, const SOCKADDR_INET *, ULONG, PMIB_IPFORWARD_ROW2, SOCKADDR_INET * ); /* Forward-declaration of variables defined in ares_library_init.c */ /* that are global and unique instances for whole c-ares library. */ extern fpGetNetworkParams_t ares_fpGetNetworkParams; extern fpSystemFunction036_t ares_fpSystemFunction036; extern fpGetAdaptersAddresses_t ares_fpGetAdaptersAddresses; +extern fpGetBestRoute2_t ares_fpGetBestRoute2; #endif /* USE_WINSOCK */ diff --git a/ares_llist.c b/src/lib/ares_llist.c similarity index 100% rename from ares_llist.c rename to src/lib/ares_llist.c diff --git a/ares_llist.h b/src/lib/ares_llist.h similarity index 100% rename from ares_llist.h rename to src/lib/ares_llist.h diff --git a/ares_mkquery.c b/src/lib/ares_mkquery.c similarity index 100% rename from ares_mkquery.c rename to src/lib/ares_mkquery.c diff --git a/ares_nowarn.c b/src/lib/ares_nowarn.c similarity index 95% rename from ares_nowarn.c rename to src/lib/ares_nowarn.c index 7f9035c..f63d913 100644 --- a/ares_nowarn.c +++ b/src/lib/ares_nowarn.c @@ -151,10 +151,10 @@ int aresx_sltosi(long slnum) } /* -** signed ssize_t to signed int +** signed ares_ssize_t to signed int */ -int aresx_sztosi(ssize_t sznum) +int aresx_sztosi(ares_ssize_t sznum) { #ifdef __INTEL_COMPILER # pragma warning(push) @@ -162,7 +162,7 @@ int aresx_sztosi(ssize_t sznum) #endif DEBUGASSERT(sznum >= 0); - return (int)(sznum & (ssize_t) CARES_MASK_SINT); + return (int)(sznum & (ares_ssize_t) CARES_MASK_SINT); #ifdef __INTEL_COMPILER # pragma warning(pop) @@ -170,10 +170,10 @@ int aresx_sztosi(ssize_t sznum) } /* -** signed ssize_t to unsigned int +** signed ares_ssize_t to unsigned int */ -unsigned int aresx_sztoui(ssize_t sznum) +unsigned int aresx_sztoui(ares_ssize_t sznum) { #ifdef __INTEL_COMPILER # pragma warning(push) @@ -181,7 +181,7 @@ unsigned int aresx_sztoui(ssize_t sznum) #endif DEBUGASSERT(sznum >= 0); - return (unsigned int)(sznum & (ssize_t) CARES_MASK_UINT); + return (unsigned int)(sznum & (ares_ssize_t) CARES_MASK_UINT); #ifdef __INTEL_COMPILER # pragma warning(pop) diff --git a/ares_nowarn.h b/src/lib/ares_nowarn.h similarity index 95% rename from ares_nowarn.h rename to src/lib/ares_nowarn.h index 9b76d66..505e622 100644 --- a/ares_nowarn.h +++ b/src/lib/ares_nowarn.h @@ -25,9 +25,9 @@ short aresx_sitoss(int sinum); int aresx_sltosi(long slnum); -int aresx_sztosi(ssize_t sznum); +int aresx_sztosi(ares_ssize_t sznum); -unsigned int aresx_sztoui(ssize_t sznum); +unsigned int aresx_sztoui(ares_ssize_t sznum); unsigned short aresx_sitous(int sinum); diff --git a/ares_options.c b/src/lib/ares_options.c similarity index 98% rename from ares_options.c rename to src/lib/ares_options.c index c3cbd1d..de49de4 100644 --- a/ares_options.c +++ b/src/lib/ares_options.c @@ -153,6 +153,9 @@ int ares_set_servers(ares_channel channel, if (!channel) return ARES_ENODATA; + if (!ares__is_list_empty(&channel->all_queries)) + return ARES_ENOTIMP; + ares__destroy_servers_state(channel); for (srvr = servers; srvr; srvr = srvr->next) @@ -202,6 +205,9 @@ int ares_set_servers_ports(ares_channel channel, if (!channel) return ARES_ENODATA; + if (!ares__is_list_empty(&channel->all_queries)) + return ARES_ENOTIMP; + ares__destroy_servers_state(channel); for (srvr = servers; srvr; srvr = srvr->next) @@ -258,8 +264,6 @@ static int set_servers_csv(ares_channel channel, if (!channel) return ARES_ENODATA; - ares__destroy_servers_state(channel); - i = strlen(_csv); if (i == 0) return ARES_SUCCESS; /* blank all servers */ diff --git a/src/lib/ares_parse_a_reply.c b/src/lib/ares_parse_a_reply.c new file mode 100644 index 0000000..e71c993 --- /dev/null +++ b/src/lib/ares_parse_a_reply.c @@ -0,0 +1,215 @@ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#ifdef HAVE_STRINGS_H +# include +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_private.h" + +int ares_parse_a_reply(const unsigned char *abuf, int alen, + struct hostent **host, + struct ares_addrttl *addrttls, int *naddrttls) +{ + struct ares_addrinfo ai; + struct ares_addrinfo_node *next; + struct ares_addrinfo_cname *next_cname; + char **aliases = NULL; + char *question_hostname = NULL; + struct hostent *hostent = NULL; + struct in_addr *addrs = NULL; + int naliases = 0, naddrs = 0, alias = 0, i; + int cname_ttl = INT_MAX; + int status; + + memset(&ai, 0, sizeof(ai)); + + status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai); + if (status != ARES_SUCCESS) + { + ares_free(question_hostname); + + if (naddrttls) + { + *naddrttls = 0; + } + + return status; + } + + hostent = ares_malloc(sizeof(struct hostent)); + if (!hostent) + { + goto enomem; + } + + next = ai.nodes; + while (next) + { + if (next->ai_family == AF_INET) + { + ++naddrs; + } + next = next->ai_next; + } + + next_cname = ai.cnames; + while (next_cname) + { + if(next_cname->alias) + ++naliases; + next_cname = next_cname->next; + } + + aliases = ares_malloc((naliases + 1) * sizeof(char *)); + if (!aliases) + { + goto enomem; + } + + if (naliases) + { + next_cname = ai.cnames; + while (next_cname) + { + if(next_cname->alias) + aliases[alias++] = strdup(next_cname->alias); + if(next_cname->ttl < cname_ttl) + cname_ttl = next_cname->ttl; + next_cname = next_cname->next; + } + } + + aliases[alias] = NULL; + + hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); + if (!hostent->h_addr_list) + { + goto enomem; + } + + for (i = 0; i < naddrs + 1; ++i) + { + hostent->h_addr_list[i] = NULL; + } + + if (ai.cnames) + { + hostent->h_name = strdup(ai.cnames->name); + ares_free(question_hostname); + } + else + { + hostent->h_name = question_hostname; + } + + hostent->h_aliases = aliases; + hostent->h_addrtype = AF_INET; + hostent->h_length = sizeof(struct in_addr); + + if (naddrs) + { + addrs = ares_malloc(naddrs * sizeof(struct in_addr)); + if (!addrs) + { + goto enomem; + } + + i = 0; + next = ai.nodes; + while (next) + { + if (next->ai_family == AF_INET) + { + hostent->h_addr_list[i] = (char *)&addrs[i]; + memcpy(hostent->h_addr_list[i], + &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr), + sizeof(struct in_addr)); + if (naddrttls && i < *naddrttls) + { + if (next->ai_ttl > cname_ttl) + addrttls[i].ttl = cname_ttl; + else + addrttls[i].ttl = next->ai_ttl; + + memcpy(&addrttls[i].ipaddr, + &(CARES_INADDR_CAST(struct sockaddr_in *, next->ai_addr)->sin_addr), + sizeof(struct in_addr)); + } + ++i; + } + next = next->ai_next; + } + if (i == 0) + { + ares_free(addrs); + } + } + + if (host) + { + *host = hostent; + } + else + { + ares_free_hostent(hostent); + } + + if (naddrttls) + { + /* Truncated to at most *naddrttls entries */ + *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs; + } + + ares__freeaddrinfo_cnames(ai.cnames); + ares__freeaddrinfo_nodes(ai.nodes); + return ARES_SUCCESS; + +enomem: + ares_free(aliases); + ares_free(hostent); + ares__freeaddrinfo_cnames(ai.cnames); + ares__freeaddrinfo_nodes(ai.nodes); + ares_free(question_hostname); + return ARES_ENOMEM; +} diff --git a/src/lib/ares_parse_aaaa_reply.c b/src/lib/ares_parse_aaaa_reply.c new file mode 100644 index 0000000..346d430 --- /dev/null +++ b/src/lib/ares_parse_aaaa_reply.c @@ -0,0 +1,218 @@ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * Copyright 2005 Dominick Meglio + * Copyright (C) 2019 by Andrew Selivanov + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#ifdef HAVE_STRINGS_H +# include +#endif + +#ifdef HAVE_LIMITS_H +# include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_inet_net_pton.h" +#include "ares_private.h" + +int ares_parse_aaaa_reply(const unsigned char *abuf, int alen, + struct hostent **host, struct ares_addr6ttl *addrttls, + int *naddrttls) +{ + struct ares_addrinfo ai; + struct ares_addrinfo_node *next; + struct ares_addrinfo_cname *next_cname; + char **aliases = NULL; + char *question_hostname = NULL; + struct hostent *hostent = NULL; + struct ares_in6_addr *addrs = NULL; + int naliases = 0, naddrs = 0, alias = 0, i; + int cname_ttl = INT_MAX; + int status; + + memset(&ai, 0, sizeof(ai)); + + status = ares__parse_into_addrinfo2(abuf, alen, &question_hostname, &ai); + if (status != ARES_SUCCESS) + { + ares_free(question_hostname); + + if (naddrttls) + { + *naddrttls = 0; + } + + return status; + } + + hostent = ares_malloc(sizeof(struct hostent)); + if (!hostent) + { + goto enomem; + } + + next = ai.nodes; + while (next) + { + if(next->ai_family == AF_INET6) + { + ++naddrs; + } + next = next->ai_next; + } + + next_cname = ai.cnames; + while (next_cname) + { + if(next_cname->alias) + ++naliases; + next_cname = next_cname->next; + } + + aliases = ares_malloc((naliases + 1) * sizeof(char *)); + if (!aliases) + { + goto enomem; + } + + if (naliases) + { + next_cname = ai.cnames; + while (next_cname) + { + if(next_cname->alias) + aliases[alias++] = strdup(next_cname->alias); + if(next_cname->ttl < cname_ttl) + cname_ttl = next_cname->ttl; + next_cname = next_cname->next; + } + } + + aliases[alias] = NULL; + + hostent->h_addr_list = ares_malloc((naddrs + 1) * sizeof(char *)); + if (!hostent->h_addr_list) + { + goto enomem; + } + + for (i = 0; i < naddrs + 1; ++i) + { + hostent->h_addr_list[i] = NULL; + } + + if (ai.cnames) + { + hostent->h_name = strdup(ai.cnames->name); + ares_free(question_hostname); + } + else + { + hostent->h_name = question_hostname; + } + + hostent->h_aliases = aliases; + hostent->h_addrtype = AF_INET6; + hostent->h_length = sizeof(struct ares_in6_addr); + + if (naddrs) + { + addrs = ares_malloc(naddrs * sizeof(struct ares_in6_addr)); + if (!addrs) + { + goto enomem; + } + + i = 0; + next = ai.nodes; + while (next) + { + if(next->ai_family == AF_INET6) + { + hostent->h_addr_list[i] = (char*)&addrs[i]; + memcpy(hostent->h_addr_list[i], + &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr), + sizeof(struct ares_in6_addr)); + if (naddrttls && i < *naddrttls) + { + if(next->ai_ttl > cname_ttl) + addrttls[i].ttl = cname_ttl; + else + addrttls[i].ttl = next->ai_ttl; + + memcpy(&addrttls[i].ip6addr, + &(CARES_INADDR_CAST(struct sockaddr_in6 *, next->ai_addr)->sin6_addr), + sizeof(struct ares_in6_addr)); + } + ++i; + } + next = next->ai_next; + } + + if (i == 0) + { + ares_free(addrs); + } + } + + if (host) + { + *host = hostent; + } + else + { + ares_free_hostent(hostent); + } + + if (naddrttls) + { + /* Truncated to at most *naddrttls entries */ + *naddrttls = (naddrs > *naddrttls)?*naddrttls:naddrs; + } + + ares__freeaddrinfo_cnames(ai.cnames); + ares__freeaddrinfo_nodes(ai.nodes); + return ARES_SUCCESS; + +enomem: + ares_free(aliases); + ares_free(hostent); + ares__freeaddrinfo_cnames(ai.cnames); + ares__freeaddrinfo_nodes(ai.nodes); + ares_free(question_hostname); + return ARES_ENOMEM; +} diff --git a/src/lib/ares_parse_caa_reply.c b/src/lib/ares_parse_caa_reply.c new file mode 100644 index 0000000..620f444 --- /dev/null +++ b/src/lib/ares_parse_caa_reply.c @@ -0,0 +1,209 @@ + +/* Copyright 2020 by + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#ifdef HAVE_STRINGS_H +# include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_data.h" +#include "ares_private.h" + +#ifndef T_CAA +# define T_CAA 257 /* Certification Authority Authorization */ +#endif + +int +ares_parse_caa_reply (const unsigned char *abuf, int alen, + struct ares_caa_reply **caa_out) +{ + unsigned int qdcount, ancount, i; + const unsigned char *aptr; + const unsigned char *strptr; + int status, rr_type, rr_class, rr_len; + long len; + char *hostname = NULL, *rr_name = NULL; + struct ares_caa_reply *caa_head = NULL; + struct ares_caa_reply *caa_last = NULL; + struct ares_caa_reply *caa_curr; + + /* Set *caa_out to NULL for all failure cases. */ + *caa_out = NULL; + + /* Give up if abuf doesn't have room for a header. */ + if (alen < HFIXEDSZ) + return ARES_EBADRESP; + + /* Fetch the question and answer count from the header. */ + qdcount = DNS_HEADER_QDCOUNT (abuf); + ancount = DNS_HEADER_ANCOUNT (abuf); + if (qdcount != 1) + return ARES_EBADRESP; + if (ancount == 0) + return ARES_ENODATA; + + /* Expand the name from the question, and skip past the question. */ + aptr = abuf + HFIXEDSZ; + status = ares_expand_name (aptr, abuf, alen, &hostname, &len); + if (status != ARES_SUCCESS) + return status; + + if (aptr + len + QFIXEDSZ > abuf + alen) + { + ares_free (hostname); + return ARES_EBADRESP; + } + aptr += len + QFIXEDSZ; + + /* Examine each answer resource record (RR) in turn. */ + for (i = 0; i < ancount; i++) + { + /* Decode the RR up to the data field. */ + status = ares_expand_name (aptr, abuf, alen, &rr_name, &len); + if (status != ARES_SUCCESS) + { + break; + } + aptr += len; + if (aptr + RRFIXEDSZ > abuf + alen) + { + status = ARES_EBADRESP; + break; + } + rr_type = DNS_RR_TYPE (aptr); + rr_class = DNS_RR_CLASS (aptr); + rr_len = DNS_RR_LEN (aptr); + aptr += RRFIXEDSZ; + if (aptr + rr_len > abuf + alen) + { + status = ARES_EBADRESP; + break; + } + + /* Check if we are really looking at a CAA record */ + if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_CAA) + { + strptr = aptr; + + /* Allocate storage for this CAA answer appending it to the list */ + caa_curr = ares_malloc_data(ARES_DATATYPE_CAA_REPLY); + if (!caa_curr) + { + status = ARES_ENOMEM; + break; + } + if (caa_last) + { + caa_last->next = caa_curr; + } + else + { + caa_head = caa_curr; + } + caa_last = caa_curr; + if (rr_len < 2) + { + status = ARES_EBADRESP; + break; + } + caa_curr->critical = (int)*strptr++; + caa_curr->plength = (int)*strptr++; + if (caa_curr->plength <= 0 || (int)caa_curr->plength >= rr_len - 2) + { + status = ARES_EBADRESP; + break; + } + caa_curr->property = ares_malloc (caa_curr->plength + 1/* Including null byte */); + if (caa_curr->property == NULL) + { + status = ARES_ENOMEM; + break; + } + memcpy ((char *) caa_curr->property, strptr, caa_curr->plength); + /* Make sure we NULL-terminate */ + caa_curr->property[caa_curr->plength] = 0; + strptr += caa_curr->plength; + + caa_curr->length = rr_len - caa_curr->plength - 2; + if (caa_curr->length <= 0) + { + status = ARES_EBADRESP; + break; + } + caa_curr->value = ares_malloc (caa_curr->length + 1/* Including null byte */); + if (caa_curr->value == NULL) + { + status = ARES_ENOMEM; + break; + } + memcpy ((char *) caa_curr->value, strptr, caa_curr->length); + /* Make sure we NULL-terminate */ + caa_curr->value[caa_curr->length] = 0; + } + + /* Propagate any failures */ + if (status != ARES_SUCCESS) + { + break; + } + + /* Don't lose memory in the next iteration */ + ares_free (rr_name); + rr_name = NULL; + + /* Move on to the next record */ + aptr += rr_len; + } + + if (hostname) + ares_free (hostname); + if (rr_name) + ares_free (rr_name); + + /* clean up on error */ + if (status != ARES_SUCCESS) + { + if (caa_head) + ares_free_data (caa_head); + return status; + } + + /* everything looks fine, return the data */ + *caa_out = caa_head; + + return ARES_SUCCESS; +} diff --git a/ares_parse_mx_reply.c b/src/lib/ares_parse_mx_reply.c similarity index 100% rename from ares_parse_mx_reply.c rename to src/lib/ares_parse_mx_reply.c diff --git a/ares_parse_naptr_reply.c b/src/lib/ares_parse_naptr_reply.c similarity index 96% rename from ares_parse_naptr_reply.c rename to src/lib/ares_parse_naptr_reply.c index 91836f9..6216ca7 100644 --- a/ares_parse_naptr_reply.c +++ b/src/lib/ares_parse_naptr_reply.c @@ -122,6 +122,13 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen, { /* parse the NAPTR record itself */ + /* RR must contain at least 7 bytes = 2 x int16 + 3 x name */ + if (rr_len < 7) + { + status = ARES_EBADRESP; + break; + } + /* Allocate storage for this NAPTR answer appending it to the list */ naptr_curr = ares_malloc_data(ARES_DATATYPE_NAPTR_REPLY); if (!naptr_curr) @@ -191,4 +198,3 @@ ares_parse_naptr_reply (const unsigned char *abuf, int alen, return ARES_SUCCESS; } - diff --git a/ares_parse_ns_reply.c b/src/lib/ares_parse_ns_reply.c similarity index 100% rename from ares_parse_ns_reply.c rename to src/lib/ares_parse_ns_reply.c diff --git a/ares_parse_ptr_reply.c b/src/lib/ares_parse_ptr_reply.c similarity index 97% rename from ares_parse_ptr_reply.c rename to src/lib/ares_parse_ptr_reply.c index 976a531..29e22cb 100644 --- a/ares_parse_ptr_reply.c +++ b/src/lib/ares_parse_ptr_reply.c @@ -52,6 +52,7 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, int aliascnt = 0; int alias_alloc = 8; char ** aliases; + size_t rr_data_len; /* Set *host to NULL for all failure cases. */ *host = NULL; @@ -124,14 +125,15 @@ int ares_parse_ptr_reply(const unsigned char *abuf, int alen, const void *addr, if (hostname) ares_free(hostname); hostname = rr_data; - aliases[aliascnt] = ares_malloc((strlen(rr_data)+1) * sizeof(char)); + rr_data_len = strlen(rr_data)+1; + aliases[aliascnt] = ares_malloc(rr_data_len * sizeof(char)); if (!aliases[aliascnt]) { ares_free(rr_name); status = ARES_ENOMEM; break; } - strncpy(aliases[aliascnt], rr_data, strlen(rr_data)+1); + strncpy(aliases[aliascnt], rr_data, rr_data_len); aliascnt++; if (aliascnt >= alias_alloc) { char **ptr; diff --git a/src/lib/ares_parse_soa_reply.c b/src/lib/ares_parse_soa_reply.c new file mode 100644 index 0000000..7cfaed2 --- /dev/null +++ b/src/lib/ares_parse_soa_reply.c @@ -0,0 +1,185 @@ + +/* Copyright 1998 by the Massachusetts Institute of Technology. + * Copyright (C) 2012 Marko Kreen + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +#ifdef HAVE_NETINET_IN_H +# include +#endif +#ifdef HAVE_NETDB_H +# include +#endif +#ifdef HAVE_ARPA_INET_H +# include +#endif +#ifdef HAVE_ARPA_NAMESER_H +# include +#else +# include "nameser.h" +#endif +#ifdef HAVE_ARPA_NAMESER_COMPAT_H +# include +#endif + +#include "ares.h" +#include "ares_dns.h" +#include "ares_data.h" +#include "ares_private.h" + +int +ares_parse_soa_reply(const unsigned char *abuf, int alen, + struct ares_soa_reply **soa_out) +{ + const unsigned char *aptr; + long len; + char *qname = NULL, *rr_name = NULL; + struct ares_soa_reply *soa = NULL; + int qdcount, ancount, qclass; + int status, i, rr_type, rr_class, rr_len; + + if (alen < HFIXEDSZ) + return ARES_EBADRESP; + + /* parse message header */ + qdcount = DNS_HEADER_QDCOUNT(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + + if (qdcount != 1) + return ARES_EBADRESP; + if (ancount == 0) + return ARES_EBADRESP; + + aptr = abuf + HFIXEDSZ; + + /* query name */ + status = ares__expand_name_for_response(aptr, abuf, alen, &qname, &len); + if (status != ARES_SUCCESS) + goto failed_stat; + + if (alen <= len + HFIXEDSZ + 1) + goto failed; + aptr += len; + + qclass = DNS_QUESTION_TYPE(aptr); + + /* skip qtype & qclass */ + if (aptr + QFIXEDSZ > abuf + alen) + goto failed; + aptr += QFIXEDSZ; + + /* qclass of SOA with multiple answers */ + if (qclass == T_SOA && ancount > 1) + goto failed; + + /* examine all the records, break and return if found soa */ + for (i = 0; i < ancount; i++) + { + rr_name = NULL; + status = ares__expand_name_for_response (aptr, abuf, alen, &rr_name, &len); + if (status != ARES_SUCCESS) + { + ares_free(rr_name); + goto failed_stat; + } + + aptr += len; + if ( aptr + RRFIXEDSZ > abuf + alen ) + { + ares_free(rr_name); + status = ARES_EBADRESP; + goto failed_stat; + } + rr_type = DNS_RR_TYPE( aptr ); + rr_class = DNS_RR_CLASS( aptr ); + rr_len = DNS_RR_LEN( aptr ); + aptr += RRFIXEDSZ; + if (aptr + rr_len > abuf + alen) + { + ares_free(rr_name); + status = ARES_EBADRESP; + goto failed_stat; + } + if ( rr_class == C_IN && rr_type == T_SOA ) + { + /* allocate result struct */ + soa = ares_malloc_data(ARES_DATATYPE_SOA_REPLY); + if (!soa) + { + ares_free(rr_name); + status = ARES_ENOMEM; + goto failed_stat; + } + + /* nsname */ + status = ares__expand_name_for_response(aptr, abuf, alen, &soa->nsname, + &len); + if (status != ARES_SUCCESS) + { + ares_free(rr_name); + goto failed_stat; + } + aptr += len; + + /* hostmaster */ + status = ares__expand_name_for_response(aptr, abuf, alen, + &soa->hostmaster, &len); + if (status != ARES_SUCCESS) + { + ares_free(rr_name); + goto failed_stat; + } + aptr += len; + + /* integer fields */ + if (aptr + 5 * 4 > abuf + alen) + { + ares_free(rr_name); + goto failed; + } + soa->serial = DNS__32BIT(aptr + 0 * 4); + soa->refresh = DNS__32BIT(aptr + 1 * 4); + soa->retry = DNS__32BIT(aptr + 2 * 4); + soa->expire = DNS__32BIT(aptr + 3 * 4); + soa->minttl = DNS__32BIT(aptr + 4 * 4); + + ares_free(qname); + ares_free(rr_name); + + *soa_out = soa; + + return ARES_SUCCESS; + } + aptr += rr_len; + + ares_free(rr_name); + + if (aptr > abuf + alen) + goto failed_stat; + } + /* no SOA record found */ + status = ARES_EBADRESP; + goto failed_stat; +failed: + status = ARES_EBADRESP; + +failed_stat: + if (soa) + ares_free_data(soa); + if (qname) + ares_free(qname); + return status; +} diff --git a/ares_parse_srv_reply.c b/src/lib/ares_parse_srv_reply.c similarity index 100% rename from ares_parse_srv_reply.c rename to src/lib/ares_parse_srv_reply.c diff --git a/ares_parse_txt_reply.c b/src/lib/ares_parse_txt_reply.c similarity index 98% rename from ares_parse_txt_reply.c rename to src/lib/ares_parse_txt_reply.c index 4856b4c..3f47e23 100644 --- a/ares_parse_txt_reply.c +++ b/src/lib/ares_parse_txt_reply.c @@ -113,7 +113,7 @@ ares__parse_txt_reply (const unsigned char *abuf, int alen, } /* Check if we are really looking at a TXT record */ - if (rr_class == C_IN && rr_type == T_TXT) + if ((rr_class == C_IN || rr_class == C_CHAOS) && rr_type == T_TXT) { /* * There may be multiple substrings in a single TXT record. Each diff --git a/ares_platform.c b/src/lib/ares_platform.c similarity index 99% rename from ares_platform.c rename to src/lib/ares_platform.c index c200615..6c749dc 100644 --- a/ares_platform.c +++ b/src/lib/ares_platform.c @@ -36,6 +36,10 @@ win_platform ares__getplatform(void) memset(&OsvEx, 0, sizeof(OsvEx)); OsvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */ +#endif if (!GetVersionEx((void *)&OsvEx)) { memset(&OsvEx, 0, sizeof(OsvEx)); @@ -43,6 +47,9 @@ win_platform ares__getplatform(void) if (!GetVersionEx((void *)&OsvEx)) return WIN_UNKNOWN; } +#ifdef _MSC_VER +#pragma warning(pop) +#endif switch(OsvEx.dwPlatformId) { diff --git a/ares_platform.h b/src/lib/ares_platform.h similarity index 100% rename from ares_platform.h rename to src/lib/ares_platform.h diff --git a/ares_private.h b/src/lib/ares_private.h similarity index 74% rename from ares_private.h rename to src/lib/ares_private.h index 33a23e7..50b2ba0 100644 --- a/ares_private.h +++ b/src/lib/ares_private.h @@ -50,18 +50,31 @@ #define STATIC_TESTABLE static #endif +/* By using a double cast, we can get rid of the bogus warning of + * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align] + */ +#define CARES_INADDR_CAST(type, var) ((type)((void *)var)) + #if defined(WIN32) && !defined(WATT32) -#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" -#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" -#define NAMESERVER "NameServer" -#define DHCPNAMESERVER "DhcpNameServer" -#define DATABASEPATH "DatabasePath" -#define WIN_PATH_HOSTS "\\hosts" +#define WIN_NS_9X "System\\CurrentControlSet\\Services\\VxD\\MSTCP" +#define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters" +#define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient" +#define WIN_NT_DNSCLIENT "Software\\Policies\\Microsoft\\Windows NT\\DNSClient" +#define NAMESERVER "NameServer" +#define DHCPNAMESERVER "DhcpNameServer" +#define DATABASEPATH "DatabasePath" +#define WIN_PATH_HOSTS "\\hosts" +#define SEARCHLIST_KEY "SearchList" +#define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix" +#define INTERFACES_KEY "Interfaces" +#define DOMAIN_KEY "Domain" +#define DHCPDOMAIN_KEY "DhcpDomain" #elif defined(WATT32) #define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf" +W32_FUNC const char *_w32_GetHostsFile (void); #elif defined(NETWARE) @@ -94,6 +107,7 @@ #endif #include "ares_strdup.h" +#include "ares_strsplit.h" #ifndef HAVE_STRCASECMP # include "ares_strcasecmp.h" @@ -314,8 +328,17 @@ struct ares_channeldata { ares_sock_config_callback sock_config_cb; void *sock_config_cb_data; + + const struct ares_socket_functions * sock_funcs; + void *sock_func_cb_data; + + /* Path for resolv.conf file, configurable via ares_options */ + char *resolvconf_path; }; +/* Does the domain end in ".onion" or ".onion."? Case-insensitive. */ +int ares__is_onion_domain(const char *name); + /* Memory management functions */ extern void *(*ares_malloc)(size_t size); extern void *(*ares_realloc)(void *ptr, size_t size); @@ -338,10 +361,52 @@ int ares__expand_name_for_response(const unsigned char *encoded, char **s, long *enclen); void ares__init_servers_state(ares_channel channel); void ares__destroy_servers_state(ares_channel channel); +int ares__parse_qtype_reply(const unsigned char* abuf, int alen, int* qtype); +int ares__single_domain(ares_channel channel, const char *name, char **s); +int ares__cat_domain(const char *name, const char *domain, char **s); +int ares__sortaddrinfo(ares_channel channel, struct ares_addrinfo_node *ai_node); +int ares__readaddrinfo(FILE *fp, const char *name, unsigned short port, + const struct ares_addrinfo_hints *hints, + struct ares_addrinfo *ai); + +struct ares_addrinfo *ares__malloc_addrinfo(void); + +struct ares_addrinfo_node *ares__malloc_addrinfo_node(void); +void ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node); + +struct ares_addrinfo_node *ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node); +void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head, + struct ares_addrinfo_node *tail); + +struct ares_addrinfo_cname *ares__malloc_addrinfo_cname(void); +void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname); + +struct ares_addrinfo_cname *ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname); + +void ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head, + struct ares_addrinfo_cname *tail); + +int ares__parse_into_addrinfo(const unsigned char *abuf, + int alen, + struct ares_addrinfo *ai); + +int ares__parse_into_addrinfo2(const unsigned char *abuf, + int alen, + char **question_hostname, + struct ares_addrinfo *ai); + #if 0 /* Not used */ long ares__tvdiff(struct timeval t1, struct timeval t2); #endif +ares_socket_t ares__open_socket(ares_channel channel, + int af, int type, int protocol); +void ares__close_socket(ares_channel, ares_socket_t); +int ares__connect_socket(ares_channel channel, + ares_socket_t sockfd, + const struct sockaddr *addr, + ares_socklen_t addrlen); + #define ARES_SWAP_BYTE(a,b) \ { unsigned char swapByte = *(a); *(a) = *(b); *(b) = swapByte; } @@ -351,13 +416,4 @@ long ares__tvdiff(struct timeval t1, struct timeval t2); (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \ } WHILE_FALSE -#ifdef CURLDEBUG -/* This is low-level hard-hacking memory leak tracking and similar. Using the - libcurl lowlevel code from within library is ugly and only works when - c-ares is built and linked with a similarly curldebug-enabled libcurl, - but we do this anyway for convenience. */ -#define HEADER_CURL_SETUP_ONCE_H -#include "../lib/memdebug.h" -#endif - #endif /* __ARES_PRIVATE_H */ diff --git a/ares_process.c b/src/lib/ares_process.c similarity index 84% rename from ares_process.c rename to src/lib/ares_process.c index 1d1e7b8..65c1b7f 100644 --- a/ares_process.c +++ b/src/lib/ares_process.c @@ -1,6 +1,6 @@ /* Copyright 1998 by the Massachusetts Institute of Technology. - * Copyright (C) 2004-2016 by Daniel Stenberg + * Copyright (C) 2004-2017 by Daniel Stenberg * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without @@ -29,15 +29,18 @@ #ifdef HAVE_NETDB_H # include #endif +#ifdef HAVE_ARPA_INET_H +# include +#endif #ifdef HAVE_ARPA_NAMESER_H # include -#else -# include "nameser.h" #endif #ifdef HAVE_ARPA_NAMESER_COMPAT_H # include #endif +#include "nameser.h" + #ifdef HAVE_STRINGS_H # include #endif @@ -50,6 +53,7 @@ #include #include +#include #include "ares.h" #include "ares_dns.h" @@ -65,7 +69,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, static void read_udp_packets(ares_channel channel, fd_set *read_fds, ares_socket_t read_fd, struct timeval *now); static void advance_tcp_send_queue(ares_channel channel, int whichserver, - ssize_t num_bytes); + ares_ssize_t num_bytes); static void process_timeouts(ares_channel channel, struct timeval *now); static void process_broken_connections(ares_channel channel, struct timeval *now); @@ -83,6 +87,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server); static int same_questions(const unsigned char *qbuf, int qlen, const unsigned char *abuf, int alen); static int same_address(struct sockaddr *sa, struct ares_addr *aa); +static int has_opt_rr(const unsigned char *abuf, int alen); static void end_query(ares_channel channel, struct query *query, int status, unsigned char *abuf, int alen); @@ -175,6 +180,26 @@ static int try_again(int errnum) return 0; } +static ares_ssize_t socket_writev(ares_channel channel, ares_socket_t s, const struct iovec * vec, int len) +{ + if (channel->sock_funcs) + return channel->sock_funcs->asendv(s, vec, len, channel->sock_func_cb_data); + + return writev(s, vec, len); +} + +static ares_ssize_t socket_write(ares_channel channel, ares_socket_t s, const void * data, size_t len) +{ + if (channel->sock_funcs) + { + struct iovec vec; + vec.iov_base = (void*)data; + vec.iov_len = len; + return channel->sock_funcs->asendv(s, &vec, 1, channel->sock_func_cb_data); + } + return swrite(s, data, len); +} + /* If any TCP sockets select true for writing, write out queued data * we have for them. */ @@ -187,8 +212,8 @@ static void write_tcp_data(ares_channel channel, struct send_request *sendreq; struct iovec *vec; int i; - ssize_t scount; - ssize_t wcount; + ares_ssize_t scount; + ares_ssize_t wcount; size_t n; if(!write_fds && (write_fd == ARES_SOCKET_BAD)) @@ -238,7 +263,7 @@ static void write_tcp_data(ares_channel channel, vec[n].iov_len = sendreq->len; n++; } - wcount = (ssize_t)writev(server->tcp_socket, vec, (int)n); + wcount = socket_writev(channel, server->tcp_socket, vec, (int)n); ares_free(vec); if (wcount < 0) { @@ -255,7 +280,7 @@ static void write_tcp_data(ares_channel channel, /* Can't allocate iovecs; just send the first request. */ sendreq = server->qhead; - scount = swrite(server->tcp_socket, sendreq->data, sendreq->len); + scount = socket_write(channel, server->tcp_socket, sendreq->data, sendreq->len); if (scount < 0) { if (!try_again(SOCKERRNO)) @@ -271,7 +296,7 @@ static void write_tcp_data(ares_channel channel, /* Consume the given number of bytes from the head of the TCP send queue. */ static void advance_tcp_send_queue(ares_channel channel, int whichserver, - ssize_t num_bytes) + ares_ssize_t num_bytes) { struct send_request *sendreq; struct server_state *server = &channel->servers[whichserver]; @@ -299,6 +324,38 @@ static void advance_tcp_send_queue(ares_channel channel, int whichserver, } } +static ares_ssize_t socket_recvfrom(ares_channel channel, + ares_socket_t s, + void * data, + size_t data_len, + int flags, + struct sockaddr *from, + ares_socklen_t *from_len) +{ + if (channel->sock_funcs) + return channel->sock_funcs->arecvfrom(s, data, data_len, + flags, from, from_len, + channel->sock_func_cb_data); + +#ifdef HAVE_RECVFROM + return recvfrom(s, data, data_len, flags, from, from_len); +#else + return sread(s, data, data_len); +#endif +} + +static ares_ssize_t socket_recv(ares_channel channel, + ares_socket_t s, + void * data, + size_t data_len) +{ + if (channel->sock_funcs) + return channel->sock_funcs->arecvfrom(s, data, data_len, 0, 0, 0, + channel->sock_func_cb_data); + + return sread(s, data, data_len); +} + /* If any TCP socket selects true for reading, read some data, * allocate a buffer if we finish reading the length word, and process * a packet if we finish reading one. @@ -308,7 +365,7 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, { struct server_state *server; int i; - ssize_t count; + ares_ssize_t count; if(!read_fds && (read_fd == ARES_SOCKET_BAD)) /* no possible action */ @@ -343,9 +400,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, /* We haven't yet read a length word, so read that (or * what's left to read of it). */ - count = sread(server->tcp_socket, - server->tcp_lenbuf + server->tcp_lenbuf_pos, - 2 - server->tcp_lenbuf_pos); + count = socket_recv(channel, server->tcp_socket, + server->tcp_lenbuf + server->tcp_lenbuf_pos, + 2 - server->tcp_lenbuf_pos); if (count <= 0) { if (!(count == -1 && try_again(SOCKERRNO))) @@ -373,9 +430,9 @@ static void read_tcp_data(ares_channel channel, fd_set *read_fds, else { /* Read data into the allocated buffer. */ - count = sread(server->tcp_socket, - server->tcp_buffer + server->tcp_buffer_pos, - server->tcp_length - server->tcp_buffer_pos); + count = socket_recv(channel, server->tcp_socket, + server->tcp_buffer + server->tcp_buffer_pos, + server->tcp_length - server->tcp_buffer_pos); if (count <= 0) { if (!(count == -1 && try_again(SOCKERRNO))) @@ -406,7 +463,7 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, { struct server_state *server; int i; - ssize_t count; + ares_ssize_t count; unsigned char buf[MAXENDSSZ + 1]; #ifdef HAVE_RECVFROM ares_socklen_t fromlen; @@ -453,16 +510,12 @@ static void read_udp_packets(ares_channel channel, fd_set *read_fds, count = 0; else { -#ifdef HAVE_RECVFROM if (server->addr.family == AF_INET) fromlen = sizeof(from.sa4); else fromlen = sizeof(from.sa6); - count = (ssize_t)recvfrom(server->udp_socket, (void *)buf, - sizeof(buf), 0, &from.sa, &fromlen); -#else - count = sread(server->udp_socket, buf, sizeof(buf)); -#endif + count = socket_recvfrom(channel, server->udp_socket, (void *)buf, + sizeof(buf), 0, &from.sa, &fromlen); } if (count == -1 && try_again(SOCKERRNO)) @@ -556,14 +609,14 @@ static void process_answer(ares_channel channel, unsigned char *abuf, return; packetsz = PACKETSZ; - /* If we use EDNS and server answers with one of these RCODES, the protocol + /* If we use EDNS and server answers with FORMERR without an OPT RR, the protocol * extension is not understood by the responder. We must retry the query * without EDNS enabled. */ if (channel->flags & ARES_FLAG_EDNS) { packetsz = channel->ednspsz; - if (rcode == NOTIMP || rcode == FORMERR || rcode == SERVFAIL) + if (rcode == FORMERR && has_opt_rr(abuf, alen) != 1) { int qlen = (query->tcplen - 2) - EDNSFIXEDSZ; channel->flags ^= ARES_FLAG_EDNS; @@ -812,7 +865,7 @@ void ares__send_query(ares_channel channel, struct query *query, return; } } - if (swrite(server->udp_socket, query->qbuf, query->qlen) == -1) + if (socket_write(channel, server->udp_socket, query->qbuf, query->qlen) == -1) { /* FIXME: Handle EAGAIN here since it likely can happen. */ skip_server(channel, query, query->server); @@ -820,8 +873,32 @@ void ares__send_query(ares_channel channel, struct query *query, return; } } - timeplus = channel->timeout << (query->try_count / channel->nservers); - timeplus = (timeplus * (9 + (rand () & 7))) / 16; + + /* For each trip through the entire server list, double the channel's + * assigned timeout, avoiding overflow. If channel->timeout is negative, + * leave it as-is, even though that should be impossible here. + */ + timeplus = channel->timeout; + { + /* How many times do we want to double it? Presume sane values here. */ + const int shift = query->try_count / channel->nservers; + + /* Is there enough room to shift timeplus left that many times? + * + * To find out, confirm that all of the bits we'll shift away are zero. + * Stop considering a shift if we get to the point where we could shift + * a 1 into the sign bit (i.e. when shift is within two of the bit + * count). + * + * This has the side benefit of leaving negative numbers unchanged. + */ + if(shift <= (int)(sizeof(int) * CHAR_BIT - 1) + && (timeplus >> (sizeof(int) * CHAR_BIT - 1 - shift)) == 0) + { + timeplus <<= shift; + } + } + query->timeout = *now; timeadd(&query->timeout, timeplus); /* Keep track of queries bucketed by timeout, so we can process @@ -904,6 +981,10 @@ static int configure_socket(ares_socket_t s, int family, ares_channel channel) struct sockaddr_in6 sa6; } local; + /* do not set options for user-managed sockets */ + if (channel->sock_funcs) + return 0; + (void)setsocknonblock(s, TRUE); #if defined(FD_CLOEXEC) && !defined(MSDOS) @@ -1003,14 +1084,14 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) } /* Acquire a socket. */ - s = socket(server->addr.family, SOCK_STREAM, 0); + s = ares__open_socket(channel, server->addr.family, SOCK_STREAM, 0); if (s == ARES_SOCKET_BAD) return -1; /* Configure it. */ if (configure_socket(s, server->addr.family, channel) < 0) { - sclose(s); + ares__close_socket(channel, s); return -1; } @@ -1022,10 +1103,12 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) * so batching isn't very interesting. */ opt = 1; - if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, - (void *)&opt, sizeof(opt)) == -1) + if (channel->sock_funcs == 0 + && + setsockopt(s, IPPROTO_TCP, TCP_NODELAY, + (void *)&opt, sizeof(opt)) == -1) { - sclose(s); + ares__close_socket(channel, s); return -1; } #endif @@ -1036,19 +1119,19 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) channel->sock_config_cb_data); if (err < 0) { - sclose(s); + ares__close_socket(channel, s); return err; } } /* Connect to the server. */ - if (connect(s, sa, salen) == -1) + if (ares__connect_socket(channel, s, sa, salen) == -1) { int err = SOCKERRNO; if (err != EINPROGRESS && err != EWOULDBLOCK) { - sclose(s); + ares__close_socket(channel, s); return -1; } } @@ -1059,7 +1142,7 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) channel->sock_create_cb_data); if (err < 0) { - sclose(s); + ares__close_socket(channel, s); return err; } } @@ -1114,14 +1197,14 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) } /* Acquire a socket. */ - s = socket(server->addr.family, SOCK_DGRAM, 0); + s = ares__open_socket(channel, server->addr.family, SOCK_DGRAM, 0); if (s == ARES_SOCKET_BAD) return -1; /* Set the socket non-blocking. */ if (configure_socket(s, server->addr.family, channel) < 0) { - sclose(s); + ares__close_socket(channel, s); return -1; } @@ -1131,19 +1214,19 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) channel->sock_config_cb_data); if (err < 0) { - sclose(s); + ares__close_socket(channel, s); return err; } } /* Connect to the server. */ - if (connect(s, sa, salen) == -1) + if (ares__connect_socket(channel, s, sa, salen) == -1) { int err = SOCKERRNO; if (err != EINPROGRESS && err != EWOULDBLOCK) { - sclose(s); + ares__close_socket(channel, s); return -1; } } @@ -1154,7 +1237,7 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) channel->sock_create_cb_data); if (err < 0) { - sclose(s); + ares__close_socket(channel, s); return err; } } @@ -1255,13 +1338,13 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa) { case AF_INET: addr1 = &aa->addrV4; - addr2 = &((struct sockaddr_in *)sa)->sin_addr; + addr2 = &(CARES_INADDR_CAST(struct sockaddr_in *, sa))->sin_addr; if (memcmp(addr1, addr2, sizeof(aa->addrV4)) == 0) return 1; /* match */ break; case AF_INET6: addr1 = &aa->addrV6; - addr2 = &((struct sockaddr_in6 *)sa)->sin6_addr; + addr2 = &(CARES_INADDR_CAST(struct sockaddr_in6 *, sa))->sin6_addr; if (memcmp(addr1, addr2, sizeof(aa->addrV6)) == 0) return 1; /* match */ break; @@ -1272,6 +1355,85 @@ static int same_address(struct sockaddr *sa, struct ares_addr *aa) return 0; /* different */ } +/* search for an OPT RR in the response */ +static int has_opt_rr(const unsigned char *abuf, int alen) +{ + unsigned int qdcount, ancount, nscount, arcount, i; + const unsigned char *aptr; + int status; + + if (alen < HFIXEDSZ) + return -1; + + /* Parse the answer header. */ + qdcount = DNS_HEADER_QDCOUNT(abuf); + ancount = DNS_HEADER_ANCOUNT(abuf); + nscount = DNS_HEADER_NSCOUNT(abuf); + arcount = DNS_HEADER_ARCOUNT(abuf); + + aptr = abuf + HFIXEDSZ; + + /* skip the questions */ + for (i = 0; i < qdcount; i++) + { + char* name; + long len; + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return -1; + ares_free_string(name); + if (aptr + len + QFIXEDSZ > abuf + alen) + return -1; + aptr += len + QFIXEDSZ; + } + + /* skip the ancount and nscount */ + for (i = 0; i < ancount + nscount; i++) + { + char* name; + long len; + int dlen; + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return -1; + ares_free_string(name); + if (aptr + len + RRFIXEDSZ > abuf + alen) + return -1; + aptr += len; + dlen = DNS_RR_LEN(aptr); + aptr += RRFIXEDSZ; + if (aptr + dlen > abuf + alen) + return -1; + aptr += dlen; + } + + /* search for rr type (41) - opt */ + for (i = 0; i < arcount; i++) + { + char* name; + long len; + int dlen; + status = ares_expand_name(aptr, abuf, alen, &name, &len); + if (status != ARES_SUCCESS) + return -1; + ares_free_string(name); + if (aptr + len + RRFIXEDSZ > abuf + alen) + return -1; + aptr += len; + + if (DNS_RR_TYPE(aptr) == T_OPT) + return 1; + + dlen = DNS_RR_LEN(aptr); + aptr += RRFIXEDSZ; + if (aptr + dlen > abuf + alen) + return -1; + aptr += dlen; + } + + return 0; +} + static void end_query (ares_channel channel, struct query *query, int status, unsigned char *abuf, int alen) { @@ -1357,3 +1519,37 @@ void ares__free_query(struct query *query) ares_free(query->server_info); ares_free(query); } + +ares_socket_t ares__open_socket(ares_channel channel, + int af, int type, int protocol) +{ + if (channel->sock_funcs) + return channel->sock_funcs->asocket(af, + type, + protocol, + channel->sock_func_cb_data); + else + return socket(af, type, protocol); +} + +int ares__connect_socket(ares_channel channel, + ares_socket_t sockfd, + const struct sockaddr *addr, + ares_socklen_t addrlen) +{ + if (channel->sock_funcs) + return channel->sock_funcs->aconnect(sockfd, + addr, + addrlen, + channel->sock_func_cb_data); + else + return connect(sockfd, addr, addrlen); +} + +void ares__close_socket(ares_channel channel, ares_socket_t s) +{ + if (channel->sock_funcs) + channel->sock_funcs->aclose(s, channel->sock_func_cb_data); + else + sclose(s); +} diff --git a/ares_query.c b/src/lib/ares_query.c similarity index 99% rename from ares_query.c rename to src/lib/ares_query.c index b38b8a6..5bbb2f5 100644 --- a/ares_query.c +++ b/src/lib/ares_query.c @@ -45,7 +45,7 @@ static void rc4(rc4_key* key, unsigned char *buffer_ptr, int buffer_len) unsigned char y; unsigned char* state; unsigned char xorIndex; - short counter; + int counter; x = key->x; y = key->y; diff --git a/ares_search.c b/src/lib/ares_search.c similarity index 94% rename from ares_search.c rename to src/lib/ares_search.c index 68e8525..c4b0424 100644 --- a/ares_search.c +++ b/src/lib/ares_search.c @@ -43,8 +43,6 @@ static void search_callback(void *arg, int status, int timeouts, unsigned char *abuf, int alen); static void end_squery(struct search_query *squery, int status, unsigned char *abuf, int alen); -static int cat_domain(const char *name, const char *domain, char **s); -STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s); void ares_search(ares_channel channel, const char *name, int dnsclass, int type, ares_callback callback, void *arg) @@ -54,10 +52,17 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, const char *p; int status, ndots; + /* Per RFC 7686, reject queries for ".onion" domain names with NXDOMAIN. */ + if (ares__is_onion_domain(name)) + { + callback(arg, ARES_ENOTFOUND, 0, NULL, 0); + return; + } + /* If name only yields one domain to search, then we don't have * to keep extra state, so just do an ares_query(). */ - status = single_domain(channel, name, &s); + status = ares__single_domain(channel, name, &s); if (status != ARES_SUCCESS) { callback(arg, status, 0, NULL, 0); @@ -119,7 +124,7 @@ void ares_search(ares_channel channel, const char *name, int dnsclass, /* Try the name as-is last; start with the first search domain. */ squery->next_domain = 1; squery->trying_as_is = 0; - status = cat_domain(name, channel->domains[0], &s); + status = ares__cat_domain(name, channel->domains[0], &s); if (status == ARES_SUCCESS) { ares_query(channel, s, dnsclass, type, search_callback, squery); @@ -167,7 +172,7 @@ static void search_callback(void *arg, int status, int timeouts, if (squery->next_domain < channel->ndomains) { /* Try the next domain. */ - status = cat_domain(squery->name, + status = ares__cat_domain(squery->name, channel->domains[squery->next_domain], &s); if (status != ARES_SUCCESS) end_squery(squery, status, NULL, 0); @@ -206,7 +211,7 @@ static void end_squery(struct search_query *squery, int status, } /* Concatenate two domains. */ -static int cat_domain(const char *name, const char *domain, char **s) +int ares__cat_domain(const char *name, const char *domain, char **s) { size_t nlen = strlen(name); size_t dlen = strlen(domain); @@ -225,7 +230,7 @@ static int cat_domain(const char *name, const char *domain, char **s) * the string we should query, in an allocated buffer. If not, set *s * to NULL. */ -STATIC_TESTABLE int single_domain(ares_channel channel, const char *name, char **s) +int ares__single_domain(ares_channel channel, const char *name, char **s) { size_t len = strlen(name); const char *hostaliases; diff --git a/ares_send.c b/src/lib/ares_send.c similarity index 96% rename from ares_send.c rename to src/lib/ares_send.c index 88c0035..f4f1f95 100644 --- a/ares_send.c +++ b/src/lib/ares_send.c @@ -60,6 +60,12 @@ void ares_send(ares_channel channel, const unsigned char *qbuf, int qlen, callback(arg, ARES_ENOMEM, 0, NULL, 0); return; } + if (channel->nservers < 1) + { + ares_free(query); + callback(arg, ARES_ESERVFAIL, 0, NULL, 0); + return; + } query->server_info = ares_malloc(channel->nservers * sizeof(query->server_info[0])); if (!query->server_info) diff --git a/ares_setup.h b/src/lib/ares_setup.h similarity index 100% rename from ares_setup.h rename to src/lib/ares_setup.h diff --git a/ares_strcasecmp.c b/src/lib/ares_strcasecmp.c similarity index 100% rename from ares_strcasecmp.c rename to src/lib/ares_strcasecmp.c diff --git a/ares_strcasecmp.h b/src/lib/ares_strcasecmp.h similarity index 100% rename from ares_strcasecmp.h rename to src/lib/ares_strcasecmp.h diff --git a/ares_strdup.c b/src/lib/ares_strdup.c similarity index 100% rename from ares_strdup.c rename to src/lib/ares_strdup.c diff --git a/ares_strdup.h b/src/lib/ares_strdup.h similarity index 100% rename from ares_strdup.h rename to src/lib/ares_strdup.h diff --git a/ares_strerror.c b/src/lib/ares_strerror.c similarity index 100% rename from ares_strerror.c rename to src/lib/ares_strerror.c diff --git a/src/lib/ares_strsplit.c b/src/lib/ares_strsplit.c new file mode 100644 index 0000000..b57a30f --- /dev/null +++ b/src/lib/ares_strsplit.c @@ -0,0 +1,174 @@ +/* Copyright (C) 2018 by John Schember + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" +#include "ares_strsplit.h" +#include "ares.h" +#include "ares_private.h" + +static int list_contains(char * const *list, size_t num_elem, const char *str, int insensitive) +{ + size_t len; + size_t i; + + len = strlen(str); + for (i=0; i + * + * Permission to use, copy, modify, and distribute this + * software and its documentation for any purpose and without + * fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting + * documentation, and that the name of M.I.T. not be used in + * advertising or publicity pertaining to distribution of the + * software without specific, written prior permission. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" + * without express or implied warranty. + */ + +#include "ares_setup.h" + +/* Split a string on delem skipping empty elements. + * + * param in String to split. + * param delims String of characters to treat as a delimitor. + * Each character in the string is a delimitor so + * there can be multiple delimitors to split on. + * E.g. ", " will split on all comma's and spaces. + * param make_set Have the list be a Set where there are no + * duplicate entries. 1 for true, 0 or false. + * param num_elm Return parameter of the number of elements + * in the result array. + * + * returns an allocated array of allocated string elements. + * + */ +char **ares_strsplit(const char *in, const char *delms, int make_set, size_t *num_elm); + +/* Frees the result returned from ares_strsplit(). */ +void ares_strsplit_free(char **elms, size_t num_elm); + + +#endif /* HEADER_CARES_STRSPLIT_H */ + diff --git a/ares_timeout.c b/src/lib/ares_timeout.c similarity index 100% rename from ares_timeout.c rename to src/lib/ares_timeout.c diff --git a/ares_version.c b/src/lib/ares_version.c similarity index 100% rename from ares_version.c rename to src/lib/ares_version.c diff --git a/ares_writev.c b/src/lib/ares_writev.c similarity index 94% rename from ares_writev.c rename to src/lib/ares_writev.c index 008efdd..e812c09 100644 --- a/ares_writev.c +++ b/src/lib/ares_writev.c @@ -25,12 +25,12 @@ #include "ares_private.h" #ifndef HAVE_WRITEV -ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) +ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt) { char *buffer, *bp; int i; size_t bytes = 0; - ssize_t result; + ares_ssize_t result; /* Validate iovcnt */ if (iovcnt <= 0) diff --git a/ares_writev.h b/src/lib/ares_writev.h similarity index 92% rename from ares_writev.h rename to src/lib/ares_writev.h index 1a23a0f..65cea87 100644 --- a/ares_writev.h +++ b/src/lib/ares_writev.h @@ -29,7 +29,7 @@ struct iovec size_t iov_len; /* Length of data. */ }; -extern ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt); +extern ares_ssize_t ares_writev(ares_socket_t s, const struct iovec *iov, int iovcnt); #endif diff --git a/bitncmp.c b/src/lib/bitncmp.c similarity index 100% rename from bitncmp.c rename to src/lib/bitncmp.c diff --git a/bitncmp.h b/src/lib/bitncmp.h similarity index 100% rename from bitncmp.h rename to src/lib/bitncmp.h diff --git a/cares.rc b/src/lib/cares.rc similarity index 98% rename from cares.rc rename to src/lib/cares.rc index 76ec06c..7da7e11 100644 --- a/cares.rc +++ b/src/lib/cares.rc @@ -15,7 +15,7 @@ */ #include -#include "ares_version.h" +#include "../../include/ares_version.h" LANGUAGE 0x09,0x01 diff --git a/config-dos.h b/src/lib/config-dos.h similarity index 94% rename from config-dos.h rename to src/lib/config-dos.h index b895987..b241d69 100644 --- a/config-dos.h +++ b/src/lib/config-dos.h @@ -28,6 +28,7 @@ #define HAVE_SYS_TYPES_H 1 #define HAVE_TIME_H 1 #define HAVE_UNISTD_H 1 +#define HAVE_WRITEV 1 #define NEED_MALLOC_H 1 @@ -60,14 +61,12 @@ #define BSD -#if defined(__HIGHC__) || \ - (defined(__GNUC__) && (__GNUC__ < 4)) - #define ssize_t int -#endif - /* Target HAVE_x section */ #if defined(DJGPP) + #undef _SSIZE_T + #include /* For 'ssize_t' */ + #define HAVE_STRCASECMP 1 #define HAVE_STRNCASECMP 1 #define HAVE_SYS_TIME_H 1 @@ -104,6 +103,9 @@ #define HAVE_SYS_UIO_H 1 #define NS_INADDRSZ 4 #define HAVE_STRUCT_SOCKADDR_IN6 1 + + #define HAVE_GETSERVBYPORT_R 1 + #define GETSERVBYPORT_R_ARGS 5 #endif #undef word diff --git a/config-win32.h b/src/lib/config-win32.h similarity index 88% rename from config-win32.h rename to src/lib/config-win32.h index dd95525..cc8e443 100644 --- a/config-win32.h +++ b/src/lib/config-win32.h @@ -216,20 +216,6 @@ #define HAVE_BOOL_T #endif -/* Define if ssize_t is not an available 'typedefed' type. */ -#ifndef _SSIZE_T_DEFINED -# if (defined(__WATCOMC__) && (__WATCOMC__ >= 1240)) || \ - defined(__POCC__) || \ - defined(__MINGW32__) -# elif defined(_WIN64) -# define _SSIZE_T_DEFINED -# define ssize_t __int64 -# else -# define _SSIZE_T_DEFINED -# define ssize_t int -# endif -#endif - /* ---------------------------------------------------------------- */ /* TYPE SIZES */ /* ---------------------------------------------------------------- */ @@ -259,31 +245,19 @@ # define _CRT_NONSTDC_NO_DEPRECATE 1 #endif -/* Officially, Microsoft's Windows SDK versions 6.X do not support Windows - 2000 as a supported build target. VS2008 default installations provide - an embedded Windows SDK v6.0A along with the claim that Windows 2000 is - a valid build target for VS2008. Popular belief is that binaries built - with VS2008 using Windows SDK versions 6.X and Windows 2000 as a build - target are functional. */ -#if defined(_MSC_VER) && (_MSC_VER >= 1500) -# define VS2008_MIN_TARGET 0x0500 -#endif - -/* When no build target is specified VS2008 default build target is Windows - Vista, which leaves out even Winsows XP. If no build target has been given - for VS2008 we will target the minimum Officially supported build target, - which happens to be Windows XP. */ +/* Set the Target to Vista. However, any symbols required above Win2000 + * should be loaded via LoadLibrary() */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) -# define VS2008_DEF_TARGET 0x0501 +# define VS2008_MIN_TARGET 0x0600 #endif /* VS2008 default target settings and minimum build target check. */ #if defined(_MSC_VER) && (_MSC_VER >= 1500) # ifndef _WIN32_WINNT -# define _WIN32_WINNT VS2008_DEF_TARGET +# define _WIN32_WINNT VS2008_MIN_TARGET # endif # ifndef WINVER -# define WINVER VS2008_DEF_TARGET +# define WINVER VS2008_MIN_TARGET # endif # if (_WIN32_WINNT < VS2008_MIN_TARGET) || (WINVER < VS2008_MIN_TARGET) # error VS2008 does not support Windows build targets prior to Windows 2000 @@ -291,13 +265,13 @@ #endif /* When no build target is specified Pelles C 5.00 and later default build - target is Windows Vista. We override default target to be Windows 2000. */ + target is Windows Vista. */ #if defined(__POCC__) && (__POCC__ >= 500) # ifndef _WIN32_WINNT -# define _WIN32_WINNT 0x0500 +# define _WIN32_WINNT 0x0600 # endif # ifndef WINVER -# define WINVER 0x0500 +# define WINVER 0x0600 # endif #endif diff --git a/inet_net_pton.c b/src/lib/inet_net_pton.c similarity index 99% rename from inet_net_pton.c rename to src/lib/inet_net_pton.c index b64fc5b..af1a534 100644 --- a/inet_net_pton.c +++ b/src/lib/inet_net_pton.c @@ -357,8 +357,8 @@ inet_net_pton_ipv6(const char *src, unsigned char *dst, size_t size) * Since some memmove()'s erroneously fail to handle * overlapping regions, we'll do the shift by hand. */ - const ssize_t n = tp - colonp; - ssize_t i; + const ares_ssize_t n = tp - colonp; + ares_ssize_t i; if (tp == endp) goto enoent; diff --git a/inet_ntop.c b/src/lib/inet_ntop.c similarity index 97% rename from inet_ntop.c rename to src/lib/inet_ntop.c index 9420f6c..1935a87 100644 --- a/inet_ntop.c +++ b/src/lib/inet_ntop.c @@ -54,7 +54,7 @@ static const char *inet_ntop6(const unsigned char *src, char *dst, size_t size); * On Windows we store the error in the thread errno, not * in the winsock error code. This is to avoid loosing the * actual last winsock error. So use macro ERRNO to fetch the - * errno this funtion sets when returning NULL, not SOCKERRNO. + * errno this function sets when returning NULL, not SOCKERRNO. * author: * Paul Vixie, 1996. */ @@ -180,8 +180,7 @@ inet_ntop6(const unsigned char *src, char *dst, size_t size) tp += sprintf(tp, "%x", words[i]); } /* Was it a trailing run of 0x00's? */ - if (best.base != -1 && (best.base + best.len) == - (NS_IN6ADDRSZ / NS_INT16SZ)) + if (best.base != -1 && (best.base + best.len) == (NS_IN6ADDRSZ / NS_INT16SZ)) *tp++ = ':'; *tp++ = '\0'; diff --git a/nameser.h b/src/lib/nameser.h similarity index 97% rename from nameser.h rename to src/lib/nameser.h index a0302fd..5c1acce 100644 --- a/nameser.h +++ b/src/lib/nameser.h @@ -88,6 +88,7 @@ typedef enum __ns_type { ns_t_maila = 254, /* Transfer mail agent records. */ ns_t_any = 255, /* Wildcard match. */ ns_t_zxfr = 256, /* BIND-specific, nonstandard. */ + ns_t_caa = 257, /* Certification Authority Authorization. */ ns_t_max = 65536 } ns_type; @@ -204,8 +205,14 @@ typedef enum __ns_rcode { #define T_AXFR ns_t_axfr #define T_MAILB ns_t_mailb #define T_MAILA ns_t_maila +#define T_CAA ns_t_caa #define T_ANY ns_t_any #endif /* HAVE_ARPA_NAMESER_COMPAT_H */ +/* Android's bionic arpa/nameser_compat.h, nor glibc versions prior to 2.25 have T_OPT defined */ +#ifndef T_OPT +# define T_OPT ns_t_opt +#endif + #endif /* ARES_NAMESER_H */ diff --git a/setup_once.h b/src/lib/setup_once.h similarity index 97% rename from setup_once.h rename to src/lib/setup_once.h index 25b144a..a8cfe6b 100644 --- a/setup_once.h +++ b/src/lib/setup_once.h @@ -131,7 +131,7 @@ struct timeval { #if defined(__minix) /* Minix doesn't support recv on TCP sockets */ -#define sread(x,y,z) (ssize_t)read((RECV_TYPE_ARG1)(x), \ +#define sread(x,y,z) (ares_ssize_t)read((RECV_TYPE_ARG1)(x), \ (RECV_TYPE_ARG2)(y), \ (RECV_TYPE_ARG3)(z)) @@ -167,7 +167,7 @@ struct timeval { Error Missing_definition_of_return_and_arguments_types_of_recv /* */ #else -#define sread(x,y,z) (ssize_t)recv((RECV_TYPE_ARG1)(x), \ +#define sread(x,y,z) (ares_ssize_t)recv((RECV_TYPE_ARG1)(x), \ (RECV_TYPE_ARG2)(y), \ (RECV_TYPE_ARG3)(z), \ (RECV_TYPE_ARG4)(0)) @@ -183,7 +183,7 @@ struct timeval { #if defined(__minix) /* Minix doesn't support send on TCP sockets */ -#define swrite(x,y,z) (ssize_t)write((SEND_TYPE_ARG1)(x), \ +#define swrite(x,y,z) (ares_ssize_t)write((SEND_TYPE_ARG1)(x), \ (SEND_TYPE_ARG2)(y), \ (SEND_TYPE_ARG3)(z)) @@ -198,7 +198,7 @@ struct timeval { Error Missing_definition_of_return_and_arguments_types_of_send /* */ #else -#define swrite(x,y,z) (ssize_t)send((SEND_TYPE_ARG1)(x), \ +#define swrite(x,y,z) (ares_ssize_t)send((SEND_TYPE_ARG1)(x), \ (SEND_TYPE_ARG2)(y), \ (SEND_TYPE_ARG3)(z), \ (SEND_TYPE_ARG4)(SEND_4TH_ARG)) @@ -228,7 +228,7 @@ struct timeval { Error Missing_definition_of_return_and_arguments_types_of_recvfrom /* */ #else -#define sreadfrom(s,b,bl,f,fl) (ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ +#define sreadfrom(s,b,bl,f,fl) (ares_ssize_t)recvfrom((RECVFROM_TYPE_ARG1) (s), \ (RECVFROM_TYPE_ARG2 *)(b), \ (RECVFROM_TYPE_ARG3) (bl), \ (RECVFROM_TYPE_ARG4) (0), \ diff --git a/windows_port.c b/src/lib/windows_port.c similarity index 100% rename from windows_port.c rename to src/lib/windows_port.c diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..0c44216 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,55 @@ +IF (CARES_BUILD_TOOLS) + # Transform Makefile.inc + transform_makefile_inc("Makefile.inc" "${PROJECT_BINARY_DIR}/src/tools/Makefile.inc.cmake") + include(${PROJECT_BINARY_DIR}/src/tools/Makefile.inc.cmake) + + # Build ahost + ADD_EXECUTABLE (ahost ahost.c ${SAMPLESOURCES}) + TARGET_INCLUDE_DIRECTORIES (ahost + PUBLIC "$" + "$" + "$" + "$" + "$" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" + ) + TARGET_COMPILE_DEFINITIONS (ahost PRIVATE HAVE_CONFIG_H=1) + TARGET_LINK_LIBRARIES (ahost PRIVATE ${PROJECT_NAME}) + IF (CARES_INSTALL) + INSTALL (TARGETS ahost COMPONENT Tools ${TARGETS_INST_DEST}) + ENDIF () + + + # Build adig + ADD_EXECUTABLE (adig adig.c ${SAMPLESOURCES}) + TARGET_INCLUDE_DIRECTORIES (adig + PUBLIC "$" + "$" + "$" + "$" + "$" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" + ) + TARGET_COMPILE_DEFINITIONS (adig PRIVATE HAVE_CONFIG_H=1) + TARGET_LINK_LIBRARIES (adig PRIVATE ${PROJECT_NAME}) + IF (CARES_INSTALL) + INSTALL (TARGETS adig COMPONENT Tools ${TARGETS_INST_DEST}) + ENDIF () + + + # Build acountry + ADD_EXECUTABLE (acountry acountry.c ${SAMPLESOURCES}) + TARGET_INCLUDE_DIRECTORIES (acountry + PUBLIC "$" + "$" + "$" + "$" + "$" + PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}" + ) + TARGET_COMPILE_DEFINITIONS (acountry PRIVATE HAVE_CONFIG_H=1) + TARGET_LINK_LIBRARIES (acountry PRIVATE ${PROJECT_NAME}) + IF (CARES_INSTALL) + INSTALL (TARGETS acountry COMPONENT Tools ${TARGETS_INST_DEST}) + ENDIF () +ENDIF () diff --git a/src/tools/Makefile.am b/src/tools/Makefile.am new file mode 100644 index 0000000..3fe2814 --- /dev/null +++ b/src/tools/Makefile.am @@ -0,0 +1,32 @@ +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +PROGS = ahost adig acountry + +EXTRA_DIST = CMakeLists.txt Makefile.inc + +noinst_PROGRAMS =$(PROGS) + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. + +AM_CPPFLAGS = -I$(top_builddir)/include \ + -I$(top_builddir)/src/lib \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/lib + +include Makefile.inc + +LDADD = $(top_builddir)/src/lib/libcares.la + +ahost_SOURCES = ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +ahost_CFLAGS = $(AM_CFLAGS) +ahost_CPPFLAGS = $(AM_CPPFLAGS) + +adig_SOURCES = adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +adig_CFLAGS = $(AM_CFLAGS) +adig_CPPFLAGS = $(AM_CPPFLAGS) + +acountry_SOURCES = acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +acountry_CFLAGS = $(AM_CFLAGS) +acountry_CPPFLAGS = $(AM_CPPFLAGS) diff --git a/src/tools/Makefile.in b/src/tools/Makefile.in new file mode 100644 index 0000000..38b7cc6 --- /dev/null +++ b/src/tools/Makefile.in @@ -0,0 +1,937 @@ +# Makefile.in generated by automake 1.16.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2020 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +noinst_PROGRAMS = $(am__EXEEXT_1) +subdir = src/tools +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/ax_code_coverage.m4 \ + $(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \ + $(top_srcdir)/m4/cares-compilers.m4 \ + $(top_srcdir)/m4/cares-confopts.m4 \ + $(top_srcdir)/m4/cares-functions.m4 \ + $(top_srcdir)/m4/cares-override.m4 \ + $(top_srcdir)/m4/cares-reentrant.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 \ + $(top_srcdir)/m4/xc-am-iface.m4 \ + $(top_srcdir)/m4/xc-cc-check.m4 \ + $(top_srcdir)/m4/xc-lt-iface.m4 \ + $(top_srcdir)/m4/xc-translit.m4 \ + $(top_srcdir)/m4/xc-val-flgs.m4 \ + $(top_srcdir)/m4/zz40-xc-ovr.m4 \ + $(top_srcdir)/m4/zz50-xc-ovr.m4 \ + $(top_srcdir)/m4/zz60-xc-ovr.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/src/lib/ares_config.h \ + $(top_builddir)/include/ares_build.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +am__EXEEXT_1 = ahost$(EXEEXT) adig$(EXEEXT) acountry$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +am__dirstamp = $(am__leading_dot)dirstamp +am__objects_1 = acountry-ares_getopt.$(OBJEXT) \ + ../lib/acountry-ares_nowarn.$(OBJEXT) \ + ../lib/acountry-ares_strcasecmp.$(OBJEXT) +am__objects_2 = +am_acountry_OBJECTS = acountry-acountry.$(OBJEXT) $(am__objects_1) \ + $(am__objects_2) +acountry_OBJECTS = $(am_acountry_OBJECTS) +acountry_LDADD = $(LDADD) +acountry_DEPENDENCIES = $(top_builddir)/src/lib/libcares.la +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +acountry_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(acountry_CFLAGS) \ + $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__objects_3 = adig-ares_getopt.$(OBJEXT) \ + ../lib/adig-ares_nowarn.$(OBJEXT) \ + ../lib/adig-ares_strcasecmp.$(OBJEXT) +am_adig_OBJECTS = adig-adig.$(OBJEXT) $(am__objects_3) \ + $(am__objects_2) +adig_OBJECTS = $(am_adig_OBJECTS) +adig_LDADD = $(LDADD) +adig_DEPENDENCIES = $(top_builddir)/src/lib/libcares.la +adig_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(adig_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +am__objects_4 = ahost-ares_getopt.$(OBJEXT) \ + ../lib/ahost-ares_nowarn.$(OBJEXT) \ + ../lib/ahost-ares_strcasecmp.$(OBJEXT) +am_ahost_OBJECTS = ahost-ahost.$(OBJEXT) $(am__objects_4) \ + $(am__objects_2) +ahost_OBJECTS = $(am_ahost_OBJECTS) +ahost_LDADD = $(LDADD) +ahost_DEPENDENCIES = $(top_builddir)/src/lib/libcares.la +ahost_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(ahost_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ../lib/$(DEPDIR)/acountry-ares_nowarn.Po \ + ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po \ + ../lib/$(DEPDIR)/adig-ares_nowarn.Po \ + ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po \ + ../lib/$(DEPDIR)/ahost-ares_nowarn.Po \ + ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po \ + ./$(DEPDIR)/acountry-acountry.Po \ + ./$(DEPDIR)/acountry-ares_getopt.Po ./$(DEPDIR)/adig-adig.Po \ + ./$(DEPDIR)/adig-ares_getopt.Po ./$(DEPDIR)/ahost-ahost.Po \ + ./$(DEPDIR)/ahost-ares_getopt.Po +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(acountry_SOURCES) $(adig_SOURCES) $(ahost_SOURCES) +DIST_SOURCES = $(acountry_SOURCES) $(adig_SOURCES) $(ahost_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +ETAGS = etags +CTAGS = ctags +am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ + $(top_srcdir)/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_SUBDIRS = @BUILD_SUBDIRS@ +CARES_CFLAG_EXTRAS = @CARES_CFLAG_EXTRAS@ +CARES_PRIVATE_LIBS = @CARES_PRIVATE_LIBS@ +CARES_VERSION_INFO = @CARES_VERSION_INFO@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CFLAG_CARES_SYMBOL_HIDING = @CFLAG_CARES_SYMBOL_HIDING@ +CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ +CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ +CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CPPFLAG_CARES_STATICLIB = @CPPFLAG_CARES_STATICLIB@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GCOV = @GCOV@ +GENHTML = @GENHTML@ +GREP = @GREP@ +HAVE_CXX11 = @HAVE_CXX11@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LCOV = @LCOV@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANDOM_FILE = @RANDOM_FILE@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +subdirs = @subdirs@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +PROGS = ahost adig acountry +EXTRA_DIST = CMakeLists.txt Makefile.inc + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +AM_CPPFLAGS = -I$(top_builddir)/include \ + -I$(top_builddir)/src/lib \ + -I$(top_srcdir)/include \ + -I$(top_srcdir)/src/lib + +SAMPLESOURCES = ares_getopt.c \ + ../lib/ares_nowarn.c \ + ../lib/ares_strcasecmp.c + +SAMPLEHEADERS = ares_getopt.h \ + ../lib/ares_nowarn.h \ + ../lib/ares_strcasecmp.h + +LDADD = $(top_builddir)/src/lib/libcares.la +ahost_SOURCES = ahost.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +ahost_CFLAGS = $(AM_CFLAGS) +ahost_CPPFLAGS = $(AM_CPPFLAGS) +adig_SOURCES = adig.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +adig_CFLAGS = $(AM_CFLAGS) +adig_CPPFLAGS = $(AM_CPPFLAGS) +acountry_SOURCES = acountry.c $(SAMPLESOURCES) $(SAMPLEHEADERS) +acountry_CFLAGS = $(AM_CFLAGS) +acountry_CPPFLAGS = $(AM_CPPFLAGS) +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(srcdir)/Makefile.inc $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/tools/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign src/tools/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; +$(srcdir)/Makefile.inc $(am__empty): + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list +../lib/$(am__dirstamp): + @$(MKDIR_P) ../lib + @: > ../lib/$(am__dirstamp) +../lib/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ../lib/$(DEPDIR) + @: > ../lib/$(DEPDIR)/$(am__dirstamp) +../lib/acountry-ares_nowarn.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) +../lib/acountry-ares_strcasecmp.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) + +acountry$(EXEEXT): $(acountry_OBJECTS) $(acountry_DEPENDENCIES) $(EXTRA_acountry_DEPENDENCIES) + @rm -f acountry$(EXEEXT) + $(AM_V_CCLD)$(acountry_LINK) $(acountry_OBJECTS) $(acountry_LDADD) $(LIBS) +../lib/adig-ares_nowarn.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) +../lib/adig-ares_strcasecmp.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) + +adig$(EXEEXT): $(adig_OBJECTS) $(adig_DEPENDENCIES) $(EXTRA_adig_DEPENDENCIES) + @rm -f adig$(EXEEXT) + $(AM_V_CCLD)$(adig_LINK) $(adig_OBJECTS) $(adig_LDADD) $(LIBS) +../lib/ahost-ares_nowarn.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) +../lib/ahost-ares_strcasecmp.$(OBJEXT): ../lib/$(am__dirstamp) \ + ../lib/$(DEPDIR)/$(am__dirstamp) + +ahost$(EXEEXT): $(ahost_OBJECTS) $(ahost_DEPENDENCIES) $(EXTRA_ahost_DEPENDENCIES) + @rm -f ahost$(EXEEXT) + $(AM_V_CCLD)$(ahost_LINK) $(ahost_OBJECTS) $(ahost_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + -rm -f ../lib/*.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/acountry-ares_nowarn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/adig-ares_nowarn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/adig-ares_strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/ahost-ares_nowarn.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-acountry.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/acountry-ares_getopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-adig.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/adig-ares_getopt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ahost.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ahost-ares_getopt.Po@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +acountry-acountry.o: acountry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-acountry.o -MD -MP -MF $(DEPDIR)/acountry-acountry.Tpo -c -o acountry-acountry.o `test -f 'acountry.c' || echo '$(srcdir)/'`acountry.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-acountry.Tpo $(DEPDIR)/acountry-acountry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acountry.c' object='acountry-acountry.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-acountry.o `test -f 'acountry.c' || echo '$(srcdir)/'`acountry.c + +acountry-acountry.obj: acountry.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-acountry.obj -MD -MP -MF $(DEPDIR)/acountry-acountry.Tpo -c -o acountry-acountry.obj `if test -f 'acountry.c'; then $(CYGPATH_W) 'acountry.c'; else $(CYGPATH_W) '$(srcdir)/acountry.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-acountry.Tpo $(DEPDIR)/acountry-acountry.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='acountry.c' object='acountry-acountry.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-acountry.obj `if test -f 'acountry.c'; then $(CYGPATH_W) 'acountry.c'; else $(CYGPATH_W) '$(srcdir)/acountry.c'; fi` + +acountry-ares_getopt.o: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_getopt.o -MD -MP -MF $(DEPDIR)/acountry-ares_getopt.Tpo -c -o acountry-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_getopt.Tpo $(DEPDIR)/acountry-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='acountry-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c + +acountry-ares_getopt.obj: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT acountry-ares_getopt.obj -MD -MP -MF $(DEPDIR)/acountry-ares_getopt.Tpo -c -o acountry-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/acountry-ares_getopt.Tpo $(DEPDIR)/acountry-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='acountry-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o acountry-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` + +../lib/acountry-ares_nowarn.o: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT ../lib/acountry-ares_nowarn.o -MD -MP -MF ../lib/$(DEPDIR)/acountry-ares_nowarn.Tpo -c -o ../lib/acountry-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/acountry-ares_nowarn.Tpo ../lib/$(DEPDIR)/acountry-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/acountry-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o ../lib/acountry-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c + +../lib/acountry-ares_nowarn.obj: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT ../lib/acountry-ares_nowarn.obj -MD -MP -MF ../lib/$(DEPDIR)/acountry-ares_nowarn.Tpo -c -o ../lib/acountry-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/acountry-ares_nowarn.Tpo ../lib/$(DEPDIR)/acountry-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/acountry-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o ../lib/acountry-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` + +../lib/acountry-ares_strcasecmp.o: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT ../lib/acountry-ares_strcasecmp.o -MD -MP -MF ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Tpo -c -o ../lib/acountry-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/acountry-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o ../lib/acountry-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c + +../lib/acountry-ares_strcasecmp.obj: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -MT ../lib/acountry-ares_strcasecmp.obj -MD -MP -MF ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Tpo -c -o ../lib/acountry-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/acountry-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(acountry_CPPFLAGS) $(CPPFLAGS) $(acountry_CFLAGS) $(CFLAGS) -c -o ../lib/acountry-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` + +adig-adig.o: adig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-adig.o -MD -MP -MF $(DEPDIR)/adig-adig.Tpo -c -o adig-adig.o `test -f 'adig.c' || echo '$(srcdir)/'`adig.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-adig.Tpo $(DEPDIR)/adig-adig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adig.c' object='adig-adig.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-adig.o `test -f 'adig.c' || echo '$(srcdir)/'`adig.c + +adig-adig.obj: adig.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-adig.obj -MD -MP -MF $(DEPDIR)/adig-adig.Tpo -c -o adig-adig.obj `if test -f 'adig.c'; then $(CYGPATH_W) 'adig.c'; else $(CYGPATH_W) '$(srcdir)/adig.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-adig.Tpo $(DEPDIR)/adig-adig.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='adig.c' object='adig-adig.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-adig.obj `if test -f 'adig.c'; then $(CYGPATH_W) 'adig.c'; else $(CYGPATH_W) '$(srcdir)/adig.c'; fi` + +adig-ares_getopt.o: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_getopt.o -MD -MP -MF $(DEPDIR)/adig-ares_getopt.Tpo -c -o adig-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_getopt.Tpo $(DEPDIR)/adig-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='adig-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c + +adig-ares_getopt.obj: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT adig-ares_getopt.obj -MD -MP -MF $(DEPDIR)/adig-ares_getopt.Tpo -c -o adig-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/adig-ares_getopt.Tpo $(DEPDIR)/adig-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='adig-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o adig-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` + +../lib/adig-ares_nowarn.o: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_nowarn.o -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_nowarn.Tpo -c -o ../lib/adig-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_nowarn.Tpo ../lib/$(DEPDIR)/adig-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/adig-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c + +../lib/adig-ares_nowarn.obj: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_nowarn.obj -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_nowarn.Tpo -c -o ../lib/adig-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_nowarn.Tpo ../lib/$(DEPDIR)/adig-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/adig-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` + +../lib/adig-ares_strcasecmp.o: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_strcasecmp.o -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/adig-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/adig-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c + +../lib/adig-ares_strcasecmp.obj: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -MT ../lib/adig-ares_strcasecmp.obj -MD -MP -MF ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo -c -o ../lib/adig-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/adig-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/adig-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(adig_CPPFLAGS) $(CPPFLAGS) $(adig_CFLAGS) $(CFLAGS) -c -o ../lib/adig-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` + +ahost-ahost.o: ahost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ahost.o -MD -MP -MF $(DEPDIR)/ahost-ahost.Tpo -c -o ahost-ahost.o `test -f 'ahost.c' || echo '$(srcdir)/'`ahost.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ahost.Tpo $(DEPDIR)/ahost-ahost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ahost.c' object='ahost-ahost.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ahost.o `test -f 'ahost.c' || echo '$(srcdir)/'`ahost.c + +ahost-ahost.obj: ahost.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ahost.obj -MD -MP -MF $(DEPDIR)/ahost-ahost.Tpo -c -o ahost-ahost.obj `if test -f 'ahost.c'; then $(CYGPATH_W) 'ahost.c'; else $(CYGPATH_W) '$(srcdir)/ahost.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ahost.Tpo $(DEPDIR)/ahost-ahost.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ahost.c' object='ahost-ahost.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ahost.obj `if test -f 'ahost.c'; then $(CYGPATH_W) 'ahost.c'; else $(CYGPATH_W) '$(srcdir)/ahost.c'; fi` + +ahost-ares_getopt.o: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_getopt.o -MD -MP -MF $(DEPDIR)/ahost-ares_getopt.Tpo -c -o ahost-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_getopt.Tpo $(DEPDIR)/ahost-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='ahost-ares_getopt.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_getopt.o `test -f 'ares_getopt.c' || echo '$(srcdir)/'`ares_getopt.c + +ahost-ares_getopt.obj: ares_getopt.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ahost-ares_getopt.obj -MD -MP -MF $(DEPDIR)/ahost-ares_getopt.Tpo -c -o ahost-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/ahost-ares_getopt.Tpo $(DEPDIR)/ahost-ares_getopt.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='ares_getopt.c' object='ahost-ares_getopt.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ahost-ares_getopt.obj `if test -f 'ares_getopt.c'; then $(CYGPATH_W) 'ares_getopt.c'; else $(CYGPATH_W) '$(srcdir)/ares_getopt.c'; fi` + +../lib/ahost-ares_nowarn.o: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_nowarn.o -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_nowarn.Tpo -c -o ../lib/ahost-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_nowarn.Tpo ../lib/$(DEPDIR)/ahost-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/ahost-ares_nowarn.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_nowarn.o `test -f '../lib/ares_nowarn.c' || echo '$(srcdir)/'`../lib/ares_nowarn.c + +../lib/ahost-ares_nowarn.obj: ../lib/ares_nowarn.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_nowarn.obj -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_nowarn.Tpo -c -o ../lib/ahost-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_nowarn.Tpo ../lib/$(DEPDIR)/ahost-ares_nowarn.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_nowarn.c' object='../lib/ahost-ares_nowarn.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_nowarn.obj `if test -f '../lib/ares_nowarn.c'; then $(CYGPATH_W) '../lib/ares_nowarn.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_nowarn.c'; fi` + +../lib/ahost-ares_strcasecmp.o: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_strcasecmp.o -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/ahost-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/ahost-ares_strcasecmp.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_strcasecmp.o `test -f '../lib/ares_strcasecmp.c' || echo '$(srcdir)/'`../lib/ares_strcasecmp.c + +../lib/ahost-ares_strcasecmp.obj: ../lib/ares_strcasecmp.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -MT ../lib/ahost-ares_strcasecmp.obj -MD -MP -MF ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo -c -o ../lib/ahost-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Tpo ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='../lib/ares_strcasecmp.c' object='../lib/ahost-ares_strcasecmp.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(ahost_CPPFLAGS) $(CPPFLAGS) $(ahost_CFLAGS) $(CFLAGS) -c -o ../lib/ahost-ares_strcasecmp.obj `if test -f '../lib/ares_strcasecmp.c'; then $(CYGPATH_W) '../lib/ares_strcasecmp.c'; else $(CYGPATH_W) '$(srcdir)/../lib/ares_strcasecmp.c'; fi` + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f ../lib/$(DEPDIR)/$(am__dirstamp) + -rm -f ../lib/$(am__dirstamp) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -f ../lib/$(DEPDIR)/acountry-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po + -rm -f ../lib/$(DEPDIR)/adig-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po + -rm -f ../lib/$(DEPDIR)/ahost-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po + -rm -f ./$(DEPDIR)/acountry-acountry.Po + -rm -f ./$(DEPDIR)/acountry-ares_getopt.Po + -rm -f ./$(DEPDIR)/adig-adig.Po + -rm -f ./$(DEPDIR)/adig-ares_getopt.Po + -rm -f ./$(DEPDIR)/ahost-ahost.Po + -rm -f ./$(DEPDIR)/ahost-ares_getopt.Po + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ../lib/$(DEPDIR)/acountry-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/acountry-ares_strcasecmp.Po + -rm -f ../lib/$(DEPDIR)/adig-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/adig-ares_strcasecmp.Po + -rm -f ../lib/$(DEPDIR)/ahost-ares_nowarn.Po + -rm -f ../lib/$(DEPDIR)/ahost-ares_strcasecmp.Po + -rm -f ./$(DEPDIR)/acountry-acountry.Po + -rm -f ./$(DEPDIR)/acountry-ares_getopt.Po + -rm -f ./$(DEPDIR)/adig-adig.Po + -rm -f ./$(DEPDIR)/adig-ares_getopt.Po + -rm -f ./$(DEPDIR)/ahost-ahost.Po + -rm -f ./$(DEPDIR)/ahost-ares_getopt.Po + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS cscopelist-am \ + ctags ctags-am distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/tools/Makefile.inc b/src/tools/Makefile.inc new file mode 100644 index 0000000..7aea8e5 --- /dev/null +++ b/src/tools/Makefile.inc @@ -0,0 +1,7 @@ +SAMPLESOURCES = ares_getopt.c \ + ../lib/ares_nowarn.c \ + ../lib/ares_strcasecmp.c + +SAMPLEHEADERS = ares_getopt.h \ + ../lib/ares_nowarn.h \ + ../lib/ares_strcasecmp.h diff --git a/acountry.c b/src/tools/acountry.c similarity index 90% rename from acountry.c rename to src/tools/acountry.c index aea22c8..a86d7cb 100644 --- a/acountry.c +++ b/src/tools/acountry.c @@ -69,7 +69,12 @@ #define INADDR_NONE 0xffffffff #endif -static const char *usage = "acountry [-vh?] {host|addr} ...\n"; +/* By using a double cast, we can get rid of the bogus warning of + * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *' increases required alignment from 1 to 4 [-Wcast-align] + */ +#define CARES_INADDR_CAST(type, var) ((type)((void *)var)) + +static const char *usage = "acountry [-?hdv] {host|addr} ...\n"; static const char nerd_fmt[] = "%u.%u.%u.%u.zz.countries.nerd.dk"; static const char *nerd_ver1 = nerd_fmt + 14; /* .countries.nerd.dk */ static const char *nerd_ver2 = nerd_fmt + 11; /* .zz.countries.nerd.dk */ @@ -84,6 +89,7 @@ static void wait_ares(ares_channel channel); static void callback(void *arg, int status, int timeouts, struct hostent *host); static void callback2(void *arg, int status, int timeouts, struct hostent *host); static void find_country_from_cname(const char *cname, struct in_addr addr); +static void print_help_info_acountry(void); static void Abort(const char *fmt, ...) { @@ -124,7 +130,11 @@ int main(int argc, char **argv) verbose++; break; case 'h': + print_help_info_acountry(); + break; case '?': + print_help_info_acountry(); + break; default: Abort(usage); } @@ -233,7 +243,7 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host) if (!cname) printf("Failed to get CNAME for %s\n", name); else - find_country_from_cname(cname, *(struct in_addr*)host->h_addr); + find_country_from_cname(cname, *(CARES_INADDR_CAST(struct in_addr *, host->h_addr))); } /* @@ -269,11 +279,11 @@ static const struct search_list *list_lookup(int number, const struct search_lis } /* - * Ref: ftp://ftp.ripe.net/iso3166-countrycodes.txt + * Ref: https://en.wikipedia.org/wiki/ISO_3166-1 */ static const struct search_list country_list[] = { { 4, "af", "Afghanistan" }, - { 248, "ax", "Åland Island" }, + { 248, "ax", "Åland Island" }, { 8, "al", "Albania" }, { 12, "dz", "Algeria" }, { 16, "as", "American Samoa" }, @@ -299,7 +309,8 @@ static const struct search_list country_list[] = { { 60, "bm", "Bermuda" }, { 64, "bt", "Bhutan" }, { 68, "bo", "Bolivia" }, - { 70, "ba", "Bosnia & Herzegowina" }, + { 535, "bq", "Bonaire, Sint Eustatius and Saba" }, /* Formerly 'Bonaire' / 'Netherlands Antilles' */ + { 70, "ba", "Bosnia & Herzegovina" }, { 72, "bw", "Botswana" }, { 74, "bv", "Bouvet Island" }, { 76, "br", "Brazil" }, @@ -328,6 +339,7 @@ static const struct search_list country_list[] = { { 384, "ci", "Cote d'Ivoire" }, { 191, "hr", "Croatia" }, { 192, "cu", "Cuba" }, + { 531, "cw", "Curaçao" }, { 196, "cy", "Cyprus" }, { 203, "cz", "Czech Republic" }, { 208, "dk", "Denmark" }, @@ -340,7 +352,9 @@ static const struct search_list country_list[] = { { 226, "gq", "Equatorial Guinea" }, { 232, "er", "Eritrea" }, { 233, "ee", "Estonia" }, + { 748, "sz", "Eswatini" }, /* Formerly Swaziland */ { 231, "et", "Ethiopia" }, + { 65281, "eu", "European Union" }, /* 127.0.255.1 */ { 238, "fk", "Falkland Islands" }, { 234, "fo", "Faroe Islands" }, { 242, "fj", "Fiji" }, @@ -362,12 +376,13 @@ static const struct search_list country_list[] = { { 312, "gp", "Guadeloupe" }, { 316, "gu", "Guam" }, { 320, "gt", "Guatemala" }, + { 831, "gg", "Guernsey" }, { 324, "gn", "Guinea" }, { 624, "gw", "Guinea-Bissau" }, { 328, "gy", "Guyana" }, { 332, "ht", "Haiti" }, { 334, "hm", "Heard & Mc Donald Islands" }, - { 336, "va", "Vatican City" }, + { 336, "va", "Holy See" }, /* Vatican City */ { 340, "hn", "Honduras" }, { 344, "hk", "Hong kong" }, { 348, "hu", "Hungary" }, @@ -377,16 +392,19 @@ static const struct search_list country_list[] = { { 364, "ir", "Iran" }, { 368, "iq", "Iraq" }, { 372, "ie", "Ireland" }, + { 833, "im", "Isle of Man" }, { 376, "il", "Israel" }, { 380, "it", "Italy" }, { 388, "jm", "Jamaica" }, { 392, "jp", "Japan" }, + { 832, "je", "Jersey" }, { 400, "jo", "Jordan" }, { 398, "kz", "Kazakhstan" }, { 404, "ke", "Kenya" }, { 296, "ki", "Kiribati" }, { 408, "kp", "Korea (north)" }, { 410, "kr", "Korea (south)" }, + { 0, "xk", "Kosovo" }, /* https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2 */ { 414, "kw", "Kuwait" }, { 417, "kg", "Kyrgyzstan" }, { 418, "la", "Laos" }, @@ -399,7 +417,6 @@ static const struct search_list country_list[] = { { 440, "lt", "Lithuania" }, { 442, "lu", "Luxembourg" }, { 446, "mo", "Macao" }, - { 807, "mk", "Macedonia" }, { 450, "mg", "Madagascar" }, { 454, "mw", "Malawi" }, { 458, "my", "Malaysia" }, @@ -416,6 +433,7 @@ static const struct search_list country_list[] = { { 498, "md", "Moldova" }, { 492, "mc", "Monaco" }, { 496, "mn", "Mongolia" }, + { 499, "me", "Montenegro" }, { 500, "ms", "Montserrat" }, { 504, "ma", "Morocco" }, { 508, "mz", "Mozambique" }, @@ -424,7 +442,6 @@ static const struct search_list country_list[] = { { 520, "nr", "Nauru" }, { 524, "np", "Nepal" }, { 528, "nl", "Netherlands" }, - { 530, "an", "Netherlands Antilles" }, { 540, "nc", "New Caledonia" }, { 554, "nz", "New Zealand" }, { 558, "ni", "Nicaragua" }, @@ -432,6 +449,7 @@ static const struct search_list country_list[] = { { 566, "ng", "Nigeria" }, { 570, "nu", "Niue" }, { 574, "nf", "Norfolk Island" }, + { 807, "mk", "North Macedonia" }, /* 'Macedonia' until February 2019 */ { 580, "mp", "Northern Mariana Islands" }, { 578, "no", "Norway" }, { 512, "om", "Oman" }, @@ -450,26 +468,30 @@ static const struct search_list country_list[] = { { 634, "qa", "Qatar" }, { 638, "re", "Reunion" }, { 642, "ro", "Romania" }, - { 643, "ru", "Russia" }, + { 643, "ru", "Russian Federation" }, { 646, "rw", "Rwanda" }, + { 0, "bl", "Saint Barthélemy" }, /* https://en.wikipedia.org/wiki/ISO_3166-2:BL */ { 659, "kn", "Saint Kitts & Nevis" }, { 662, "lc", "Saint Lucia" }, + { 663, "mf", "Saint Martin" }, { 670, "vc", "Saint Vincent" }, { 882, "ws", "Samoa" }, { 674, "sm", "San Marino" }, { 678, "st", "Sao Tome & Principe" }, { 682, "sa", "Saudi Arabia" }, { 686, "sn", "Senegal" }, - { 891, "cs", "Serbia and Montenegro" }, + { 688, "rs", "Serbia" }, { 690, "sc", "Seychelles" }, { 694, "sl", "Sierra Leone" }, { 702, "sg", "Singapore" }, + { 534, "sx", "Sint Maarten" }, { 703, "sk", "Slovakia" }, { 705, "si", "Slovenia" }, { 90, "sb", "Solomon Islands" }, { 706, "so", "Somalia" }, { 710, "za", "South Africa" }, - { 239, "gs", "South Georgia" }, + { 239, "gs", "South Georgia & South Sandwich Is." }, + { 728, "ss", "South Sudan" }, { 724, "es", "Spain" }, { 144, "lk", "Sri Lanka" }, { 654, "sh", "St. Helena" }, @@ -477,15 +499,14 @@ static const struct search_list country_list[] = { { 736, "sd", "Sudan" }, { 740, "sr", "Suriname" }, { 744, "sj", "Svalbard & Jan Mayen Islands" }, - { 748, "sz", "Swaziland" }, { 752, "se", "Sweden" }, { 756, "ch", "Switzerland" }, { 760, "sy", "Syrian Arab Republic" }, - { 626, "tl", "Timor-Leste" }, { 158, "tw", "Taiwan" }, { 762, "tj", "Tajikistan" }, { 834, "tz", "Tanzania" }, { 764, "th", "Thailand" }, + { 626, "tl", "Timor-Leste" }, { 768, "tg", "Togo" }, { 772, "tk", "Tokelau" }, { 776, "to", "Tonga" }, @@ -619,3 +640,13 @@ static void find_country_from_cname(const char *cname, struct in_addr addr) } free(ccopy); } + +/* Information from the man page. Formatting taken from man -h */ +static void print_help_info_acountry(void) { + printf("acountry, version %s \n\n", ARES_VERSION_STR); + printf("usage: acountry [-hdv] {host|addr} ...\n\n" + " d : Print some extra debugging output.\n" + " h : Display this help and exit.\n" + " v : Be more verbose. Print extra information.\n\n"); + exit(0); +} diff --git a/adig.c b/src/tools/adig.c similarity index 78% rename from adig.c rename to src/tools/adig.c index e112dc0..9c3747a 100644 --- a/adig.c +++ b/src/tools/adig.c @@ -83,6 +83,9 @@ #ifndef T_DNSKEY # define T_DNSKEY 48 /* DNS Public Key (RFC4034) */ #endif +#ifndef T_CAA +# define T_CAA 257 /* Certification Authority Authorization */ +#endif struct nv { const char *name; @@ -147,6 +150,7 @@ static const struct nv types[] = { { "RRSIG", T_RRSIG }, { "NSEC", T_NSEC }, { "DNSKEY", T_DNSKEY }, + { "CAA", T_CAA }, { "ANY", T_ANY } }; static const int ntypes = sizeof(types) / sizeof(types[0]); @@ -171,18 +175,21 @@ static const unsigned char *display_question(const unsigned char *aptr, int alen); static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *abuf, int alen); +static int convert_query (char **name, int use_bitstring); static const char *type_name(int type); static const char *class_name(int dnsclass); static void usage(void); static void destroy_addr_list(struct ares_addr_node *head); static void append_addr_list(struct ares_addr_node **head, struct ares_addr_node *node); +static void print_help_info_adig(void); int main(int argc, char **argv) { ares_channel channel; int c, i, optmask = ARES_OPT_FLAGS, dnsclass = C_IN, type = T_A; int status, nfds, count; + int use_ptr_helper = 0; struct ares_options options; struct hostent *hostent; fd_set read_fds, write_fds; @@ -205,7 +212,7 @@ int main(int argc, char **argv) options.flags = ARES_FLAG_NOCHECKRESP; options.servers = NULL; options.nservers = 0; - while ((c = ares_getopt(argc, argv, "df:s:c:t:T:U:")) != -1) + while ((c = ares_getopt(argc, argv, "dh?f:s:c:t:T:U:x")) != -1) { switch (c) { @@ -214,7 +221,12 @@ int main(int argc, char **argv) dbug_init(); #endif break; - + case 'h': + print_help_info_adig(); + break; + case '?': + print_help_info_adig(); + break; case 'f': /* Add a flag. */ for (i = 0; i < nflags; i++) @@ -323,6 +335,10 @@ int main(int argc, char **argv) options.udp_port = (unsigned short)strtol(optarg, NULL, 0); optmask |= ARES_OPT_UDP_PORT; break; + + case 'x': + use_ptr_helper++; + break; } } argc -= optind; @@ -356,12 +372,15 @@ int main(int argc, char **argv) * otherwise, supply the query name as an argument so we can * distinguish responses for the user when printing them out. */ - if (argc == 1) - ares_query(channel, *argv, dnsclass, type, callback, (char *) NULL); - else + for (i = 1; *argv; i++, argv++) { - for (; *argv; argv++) - ares_query(channel, *argv, dnsclass, type, callback, *argv); + char *query = *argv; + + if (type == T_PTR && dnsclass == C_IN && use_ptr_helper) + if (!convert_query (&query, use_ptr_helper >= 2)) + continue; + + ares_query(channel, query, dnsclass, type, callback, i < argc-1 ? (void*)query : NULL); } /* Wait for all queries to complete. */ @@ -529,6 +548,7 @@ static const unsigned char *display_rr(const unsigned char *aptr, const unsigned char *p; int type, dnsclass, ttl, dlen, status; long len; + int vlen; char addr[46]; union { unsigned char * as_uchar; @@ -683,6 +703,35 @@ static const unsigned char *display_rr(const unsigned char *aptr, p += len; } break; + + case T_CAA: + + p = aptr; + + /* Flags */ + printf(" %u", (int)*p); + p += 1; + + /* Remainder of record */ + vlen = (int)dlen - ((char)*p) - 2; + + /* The Property identifier, one of: + - "issue", + - "iodef", or + - "issuewild" */ + status = ares_expand_string(p, abuf, alen, &name.as_uchar, &len); + if (status != ARES_SUCCESS) + return NULL; + printf(" %s", name.as_char); + ares_free_string(name.as_char); + p += len; + + if (p + vlen > abuf + alen) + return NULL; + + /* A sequence of octets representing the Property Value */ + printf(" %.*s", vlen, p); + break; case T_A: /* The RR data is a four-byte Internet address. */ @@ -769,6 +818,104 @@ static const unsigned char *display_rr(const unsigned char *aptr, return aptr + dlen; } +/* + * With the '-x' (or '-xx') and '-t PTR' options, convert a query for an + * address into a more useful 'T_PTR' type question. + * Like with an input 'query': + * "a.b.c.d" -> "d.c.b.a".in-addr.arpa" for an IPv4 address. + * "a.b.c....x.y.z" -> "z.y.x....c.d.e.IP6.ARPA" for an IPv6 address. + * + * An example from 'dig -x PTR 2001:470:1:1b9::31': + * + * QUESTION SECTION: + * 1.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.b.1.0.1.0.0.0.0.7.4.0.1.0.0.2.IP6.ARPA. IN PTR + * + * ANSWER SECTION: + * 1.3.0.0.0.0.0.0.0.0.0.0.0.0.0.0.9.b.1.0.1.0.0.0.0.7.4.0.1.0.0.2.IP6.ARPA. 254148 IN PTR ipv6.cybernode.com. + * + * If 'use_bitstring == 1', try to use the more compact RFC-2673 bitstring format. + * Thus the above 'dig' query should become: + * [x13000000000000009b10100007401002].IP6.ARPA. IN PTR + */ +static int convert_query (char **name_p, int use_bitstring) +{ +#ifndef MAX_IP6_RR +#define MAX_IP6_RR (16*sizeof(".x.x") + sizeof(".IP6.ARPA") + 1) +#endif + +#ifdef HAVE_INET_PTON + #define ACCEPTED_RETVAL4 1 + #define ACCEPTED_RETVAL6 1 +#else + #define ACCEPTED_RETVAL4 32 + #define ACCEPTED_RETVAL6 128 +#endif + + static char new_name [MAX_IP6_RR]; + static const char hex_chars[] = "0123456789ABCDEF"; + + union { + struct in_addr addr4; + struct ares_in6_addr addr6; + } addr; + + if (ares_inet_pton (AF_INET, *name_p, &addr.addr4) == 1) + { + unsigned long laddr = ntohl(addr.addr4.s_addr); + unsigned long a1 = (laddr >> 24UL) & 0xFFUL; + unsigned long a2 = (laddr >> 16UL) & 0xFFUL; + unsigned long a3 = (laddr >> 8UL) & 0xFFUL; + unsigned long a4 = laddr & 0xFFUL; + + snprintf(new_name, sizeof(new_name), "%lu.%lu.%lu.%lu.in-addr.arpa", a4, a3, a2, a1); + *name_p = new_name; + return (1); + } + + if (ares_inet_pton(AF_INET6, *name_p, &addr.addr6) == 1) + { + char *c = new_name; + const unsigned char *ip = (const unsigned char*) &addr.addr6; + int max_i = (int)sizeof(addr.addr6) - 1; + int i, hi, lo; + + /* Use the more compact RFC-2673 notation? + * Currently doesn't work or unsupported by the DNS-servers I've tested against. + */ + if (use_bitstring) + { + *c++ = '\\'; + *c++ = '['; + *c++ = 'x'; + for (i = max_i; i >= 0; i--) + { + hi = ip[i] >> 4; + lo = ip[i] & 15; + *c++ = hex_chars [lo]; + *c++ = hex_chars [hi]; + } + strcpy (c, "].IP6.ARPA"); + } + else + { + for (i = max_i; i >= 0; i--) + { + hi = ip[i] >> 4; + lo = ip[i] & 15; + *c++ = hex_chars [lo]; + *c++ = '.'; + *c++ = hex_chars [hi]; + *c++ = '.'; + } + strcpy (c, "IP6.ARPA"); + } + *name_p = new_name; + return (1); + } + printf("Address %s was not legal for this query.\n", *name_p); + return (0); +} + static const char *type_name(int type) { int i; @@ -795,8 +942,8 @@ static const char *class_name(int dnsclass) static void usage(void) { - fprintf(stderr, "usage: adig [-f flag] [-s server] [-c class] " - "[-t type] [-p port] name ...\n"); + fprintf(stderr, "usage: adig [-h] [-d] [-f flag] [-s server] [-c class] " + "[-t type] [-T|U port] [-x|-xx] name ...\n"); exit(1); } @@ -825,3 +972,29 @@ static void append_addr_list(struct ares_addr_node **head, else *head = node; } + + +/* Information from the man page. Formatting taken from man -h */ +static void print_help_info_adig(void) { + printf("adig, version %s \n\n", ARES_VERSION_STR); + printf("usage: adig [-h] [-d] [-f flag] [-s server] [-c class] [-t type] [-T|U port] [-x | -xx] name ...\n\n" + " d : Print some extra debugging output.\n" + " f : Add a flag. Possible values for flag are igntc, noaliases, norecurse, primary, stayopen, usevc.\n" + " h : Display this help and exit.\n\n" + " T port : Use specified TCP port to connect to DNS server.\n" + " U port : Use specified UDP port to connect to DNS server.\n" + " c class : Set the query class. Possible values for class are NY, CHAOS, HS, IN (default).\n" + " s server : Connect to specified DNS server, instead of the system's default one(s).\n" + " t type : Query records of specified type. \n" + " Possible values for type are A \n" + " (default), AAAA, AFSDB, ANY,\n" + " AXFR, CNAME, GPOS, HINFO, ISDN,\n" + " KEY, LOC, MAILA, MAILB, MB, MD,\n" + " MF, MG, MINFO, MR, MX, NAPTR, NS,\n" + " NSAP, NSAP_PTR, NULL, PTR, PX, RP,\n" + " RT, SIG, SOA, SRV, TXT, WKS, X25\n\n" + " -x : For a '-t PTR a.b.c.d' lookup, query for 'd.c.b.a.in-addr.arpa.'\n" + " -xx : As above, but for IPv6, compact the format into a bitstring like\n" + " '[xabcdef00000000000000000000000000].IP6.ARPA.'\n"); + exit(0); +} diff --git a/ahost.c b/src/tools/ahost.c similarity index 79% rename from ahost.c rename to src/tools/ahost.c index 7fbfd64..77ca7cd 100644 --- a/ahost.c +++ b/src/tools/ahost.c @@ -49,6 +49,7 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host); static void usage(void); +static void print_help_info_ahost(void); int main(int argc, char **argv) { @@ -76,7 +77,7 @@ int main(int argc, char **argv) return 1; } - while ((c = ares_getopt(argc,argv,"dt:hs:")) != -1) + while ((c = ares_getopt(argc,argv,"dt:h?s:")) != -1) { switch (c) { @@ -103,6 +104,11 @@ int main(int argc, char **argv) usage(); break; case 'h': + print_help_info_ahost(); + break; + case '?': + print_help_info_ahost(); + break; default: usage(); break; @@ -201,6 +207,25 @@ static void callback(void *arg, int status, int timeouts, struct hostent *host) static void usage(void) { - fprintf(stderr, "usage: ahost [-t {a|aaaa|u}] {host|addr} ...\n"); + fprintf(stderr, "usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ...\n"); exit(1); } + +/* Information from the man page. Formatting taken from man -h */ +static void print_help_info_ahost(void) { + printf("ahost, version %s \n\n", ARES_VERSION_STR); + printf("usage: ahost [-h] [-d] [-s {domain}] [-t {a|aaaa|u}] {host|addr} ...\n\n" + " d : Print some extra debugging output.\n" + " h : Display this help and exit.\n\n" + " s domain : Specify the domain to search instead of \n" + " using the default values from \n" + " /etc/resolv.conf. This option only has an \n" + " effect on platforms that use /etc/resolv.conf\n" + " for DNS configuration; it has no effect on other\n" + " platforms (such as Win32 or Android).\n" + " t type : If type is \"a\", print the A record (default).\n" + " If type is \"aaaa\", print the AAAA record. If\n" + " type is \"u\", look for either AAAA or A record\n" + " (in that order).\n\n"); + exit(0); +} diff --git a/ares_getopt.c b/src/tools/ares_getopt.c similarity index 100% rename from ares_getopt.c rename to src/tools/ares_getopt.c diff --git a/ares_getopt.h b/src/tools/ares_getopt.h similarity index 100% rename from ares_getopt.h rename to src/tools/ares_getopt.h diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..15a9bfa --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,73 @@ +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED TRUE) +set(CMAKE_CXX_EXTENSIONS FALSE) + +enable_language(CXX) + +find_package(Threads) + +# create target to access and use internal cares library +add_library(caresinternal INTERFACE) +target_compile_definitions(caresinternal INTERFACE HAVE_CONFIG_H=1) + +target_include_directories(caresinternal + INTERFACE "${PROJECT_BINARY_DIR}" + "${PROJECT_SOURCE_DIR}" + "${PROJECT_SOURCE_DIR}/src/lib" + "${CARES_TOPLEVEL_DIR}/include" + "${CMAKE_INSTALL_INCLUDEDIR}" +) + +target_link_libraries(caresinternal INTERFACE ${PROJECT_NAME}::cares_static) + +# Google Test and Mock +set(GMOCK_DIR gmock-1.8.0) +add_library(gmock STATIC + ${GMOCK_DIR}/gmock-gtest-all.cc + ${GMOCK_DIR}/gmock/gmock.h + ${GMOCK_DIR}/gtest/gtest.h +) +target_include_directories(gmock PUBLIC SYSTEM ${GMOCK_DIR}) +target_link_libraries(gmock PRIVATE ${CMAKE_THREAD_LIBS_INIT}) + +# test targets + +transform_makefile_inc("Makefile.inc" "${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake") +include(${CMAKE_CURRENT_BINARY_DIR}/Makefile.inc.cmake) + +configure_file(${CARES_TOPLEVEL_DIR}/src/lib/ares_config.h.cmake config.h) + +add_executable(arestest ${TESTSOURCES} ${TESTHEADERS}) +target_include_directories(arestest PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(arestest PRIVATE caresinternal gmock) + +IF (CARES_BUILD_CONTAINER_TESTS) + target_compile_definitions(arestest PRIVATE HAVE_USER_NAMESPACE HAVE_UTS_NAMESPACE) +ENDIF () + +add_executable(aresfuzz ${FUZZSOURCES}) +target_link_libraries(aresfuzz PRIVATE caresinternal) + +add_executable(aresfuzzname ${FUZZNAMESOURCES}) +target_link_libraries(aresfuzzname PRIVATE caresinternal) + +add_executable(dnsdump ${DUMPSOURCES}) +target_link_libraries(dnsdump PRIVATE caresinternal) + +# register tests + +add_test(NAME arestest COMMAND $) + +file(GLOB_RECURSE FUZZINPUT_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/fuzzinput" "fuzzinput/*") +add_test( + NAME aresfuzz + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fuzzinput" + COMMAND $ ${FUZZINPUT_FILES} +) + +file(GLOB_RECURSE FUZZNAMES_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}/fuzznames" "fuzznames/*") +add_test( + NAME aresfuzzname + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/fuzznames" + COMMAND $ ${FUZZNAMES_FILES} +) diff --git a/test/Makefile.am b/test/Makefile.am index da771ab..add7224 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -1,39 +1,51 @@ -# Where to find the c-ares source code; needed because the tests use library-internal headers -ARES_SRC_DIR = .. -# Where to find the built c-ares static library -ARES_BLD_DIR = .. -AUTOMAKE_OPTIONS = foreign -ACLOCAL_AMFLAGS = -I ../m4 -GMOCK_DIR = gmock-1.7.0 -GTEST_DIR = $(GMOCK_DIR)/gtest +ARES_BLD_DIR = $(top_builddir)/.. +ARES_SRC_DIR = $(top_srcdir)/.. + +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I ../m4 --install + # Note use of -isystem to force use of local gMock/gTest even if there's an installed version. -CPPFLAGS += -I$(ARES_SRC_DIR) -isystem $(GTEST_DIR)/include -isystem $(GMOCK_DIR)/include +CPPFLAGS += -I$(ARES_BLD_DIR)/include \ + -I$(ARES_BLD_DIR)/src/lib \ + -I$(ARES_SRC_DIR)/include \ + -I$(ARES_SRC_DIR)/src/lib \ + -I$(top_builddir) \ + -isystem $(srcdir)/gmock-1.8.0 CXXFLAGS += -Wall $(PTHREAD_CFLAGS) -# Makefile.inc provides the TESTSOURCES, TESTHEADERS and FUZZSOURCES defines +# Makefile.inc provides the various *SOURCES and *HEADERS defines include Makefile.inc TESTS = arestest fuzzcheck.sh -noinst_PROGRAMS = arestest aresfuzz dnsdump +noinst_LTLIBRARIES = libgmock.la + +libgmock_la_SOURCES = \ + gmock-1.8.0/gmock-gtest-all.cc \ + gmock-1.8.0/gmock/gmock.h \ + gmock-1.8.0/gtest/gtest.h + +libgmock_la_CPPFLAGS = -isystem $(srcdir)/gmock-1.8.0 + + +noinst_PROGRAMS = arestest aresfuzz aresfuzzname dnsdump +EXTRA_DIST = fuzzcheck.sh CMakeLists.txt Makefile.m32 Makefile.msvc README.md buildconf arestest_SOURCES = $(TESTSOURCES) $(TESTHEADERS) -arestest_LDADD = libgmock.la libgtest.la $(ARES_BLD_DIR)/libcares.la $(PTHREAD_LIBS) +arestest_LDADD = libgmock.la $(ARES_BLD_DIR)/src/lib/libcares.la $(PTHREAD_LIBS) # Not interested in coverage of test code, but linking the test binary needs the coverage option @CODE_COVERAGE_RULES@ arestest_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) -noinst_LTLIBRARIES = libgmock.la libgtest.la -libgmock_la_SOURCES = $(GMOCK_DIR)/src/gmock-all.cc -libgmock_la_CPPFLAGS = -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -isystem $(GMOCK_DIR)/include -I$(GMOCK_DIR) -libgtest_la_SOURCES = $(GTEST_DIR)/src/gtest-all.cc -libgtest_la_CPPFLAGS = -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -isystem $(GMOCK_DIR)/include -I$(GMOCK_DIR) aresfuzz_SOURCES = $(FUZZSOURCES) -aresfuzz_LDADD = $(ARES_BLD_DIR)/libcares.la +aresfuzz_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la + +aresfuzzname_SOURCES = $(FUZZNAMESOURCES) +aresfuzzname_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la dnsdump_SOURCES = $(DUMPSOURCES) -dnsdump_LDADD = $(ARES_BLD_DIR)/libcares.la +dnsdump_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la test: check diff --git a/test/Makefile.in b/test/Makefile.in index f558f0c..7f19ca0 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15 from Makefile.am. +# Makefile.in generated by automake 1.16.2 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2014 Free Software Foundation, Inc. +# Copyright (C) 1994-2020 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -90,7 +90,8 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ TESTS = arestest$(EXEEXT) fuzzcheck.sh -noinst_PROGRAMS = arestest$(EXEEXT) aresfuzz$(EXEEXT) dnsdump$(EXEEXT) +noinst_PROGRAMS = arestest$(EXEEXT) aresfuzz$(EXEEXT) \ + aresfuzzname$(EXEEXT) dnsdump$(EXEEXT) subdir = . ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/../m4/ax_check_user_namespace.m4 \ @@ -109,49 +110,54 @@ DIST_COMMON = $(srcdir)/Makefile.am $(top_srcdir)/configure \ $(am__configure_deps) $(am__DIST_COMMON) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ configure.lineno config.status.lineno -mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = config.h CONFIG_CLEAN_FILES = CONFIG_CLEAN_VPATH_FILES = +PROGRAMS = $(noinst_PROGRAMS) LTLIBRARIES = $(noinst_LTLIBRARIES) libgmock_la_LIBADD = -am_libgmock_la_OBJECTS = libgmock_la-gmock-all.lo +am__dirstamp = $(am__leading_dot)dirstamp +am_libgmock_la_OBJECTS = gmock-1.8.0/libgmock_la-gmock-gtest-all.lo libgmock_la_OBJECTS = $(am_libgmock_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) am__v_lt_0 = --silent am__v_lt_1 = -libgtest_la_LIBADD = -am_libgtest_la_OBJECTS = libgtest_la-gtest-all.lo -libgtest_la_OBJECTS = $(am_libgtest_la_OBJECTS) -PROGRAMS = $(noinst_PROGRAMS) am__objects_1 = ares-test-fuzz.$(OBJEXT) ares-fuzz.$(OBJEXT) am_aresfuzz_OBJECTS = $(am__objects_1) aresfuzz_OBJECTS = $(am_aresfuzz_OBJECTS) -aresfuzz_DEPENDENCIES = $(ARES_BLD_DIR)/libcares.la -am__objects_2 = ares-test-main.$(OBJEXT) ares-test-init.$(OBJEXT) \ +aresfuzz_DEPENDENCIES = $(ARES_BLD_DIR)/src/lib/libcares.la +am__objects_2 = ares-test-fuzz-name.$(OBJEXT) ares-fuzz.$(OBJEXT) +am_aresfuzzname_OBJECTS = $(am__objects_2) +aresfuzzname_OBJECTS = $(am_aresfuzzname_OBJECTS) +aresfuzzname_DEPENDENCIES = $(ARES_BLD_DIR)/src/lib/libcares.la +am__objects_3 = ares-test-main.$(OBJEXT) ares-test-init.$(OBJEXT) \ ares-test.$(OBJEXT) ares-test-ns.$(OBJEXT) \ ares-test-parse.$(OBJEXT) ares-test-parse-a.$(OBJEXT) \ - ares-test-parse-aaaa.$(OBJEXT) ares-test-parse-mx.$(OBJEXT) \ - ares-test-parse-naptr.$(OBJEXT) ares-test-parse-ns.$(OBJEXT) \ - ares-test-parse-ptr.$(OBJEXT) ares-test-parse-soa.$(OBJEXT) \ + ares-test-parse-aaaa.$(OBJEXT) ares-test-parse-caa.$(OBJEXT) \ + ares-test-parse-mx.$(OBJEXT) ares-test-parse-naptr.$(OBJEXT) \ + ares-test-parse-ns.$(OBJEXT) ares-test-parse-ptr.$(OBJEXT) \ + ares-test-parse-soa.$(OBJEXT) \ + ares-test-parse-soa-any.$(OBJEXT) \ ares-test-parse-srv.$(OBJEXT) ares-test-parse-txt.$(OBJEXT) \ ares-test-misc.$(OBJEXT) ares-test-live.$(OBJEXT) \ - ares-test-mock.$(OBJEXT) ares-test-internal.$(OBJEXT) \ - dns-proto.$(OBJEXT) dns-proto-test.$(OBJEXT) -am__objects_3 = -am_arestest_OBJECTS = $(am__objects_2) $(am__objects_3) + ares-test-mock.$(OBJEXT) ares-test-mock-ai.$(OBJEXT) \ + ares-test-internal.$(OBJEXT) dns-proto.$(OBJEXT) \ + dns-proto-test.$(OBJEXT) +am__objects_4 = +am_arestest_OBJECTS = $(am__objects_3) $(am__objects_4) arestest_OBJECTS = $(am_arestest_OBJECTS) am__DEPENDENCIES_1 = -arestest_DEPENDENCIES = libgmock.la libgtest.la \ - $(ARES_BLD_DIR)/libcares.la $(am__DEPENDENCIES_1) +arestest_DEPENDENCIES = libgmock.la \ + $(ARES_BLD_DIR)/src/lib/libcares.la $(am__DEPENDENCIES_1) arestest_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ $(CXXFLAGS) $(arestest_LDFLAGS) $(LDFLAGS) -o $@ -am__objects_4 = dns-proto.$(OBJEXT) dns-dump.$(OBJEXT) -am_dnsdump_OBJECTS = $(am__objects_4) +am__objects_5 = dns-proto.$(OBJEXT) dns-dump.$(OBJEXT) +am_dnsdump_OBJECTS = $(am__objects_5) dnsdump_OBJECTS = $(am_dnsdump_OBJECTS) -dnsdump_DEPENDENCIES = $(ARES_BLD_DIR)/libcares.la +dnsdump_DEPENDENCIES = $(ARES_BLD_DIR)/src/lib/libcares.la AM_V_P = $(am__v_P_@AM_V@) am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) am__v_P_0 = false @@ -164,9 +170,31 @@ AM_V_at = $(am__v_at_@AM_V@) am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) am__v_at_0 = @ am__v_at_1 = -DEFAULT_INCLUDES = -I.@am__isrc@ -depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +DEFAULT_INCLUDES = +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/ares-fuzz.Po \ + ./$(DEPDIR)/ares-test-fuzz-name.Po \ + ./$(DEPDIR)/ares-test-fuzz.Po ./$(DEPDIR)/ares-test-init.Po \ + ./$(DEPDIR)/ares-test-internal.Po \ + ./$(DEPDIR)/ares-test-live.Po ./$(DEPDIR)/ares-test-main.Po \ + ./$(DEPDIR)/ares-test-misc.Po ./$(DEPDIR)/ares-test-mock-ai.Po \ + ./$(DEPDIR)/ares-test-mock.Po ./$(DEPDIR)/ares-test-ns.Po \ + ./$(DEPDIR)/ares-test-parse-a.Po \ + ./$(DEPDIR)/ares-test-parse-aaaa.Po \ + ./$(DEPDIR)/ares-test-parse-caa.Po \ + ./$(DEPDIR)/ares-test-parse-mx.Po \ + ./$(DEPDIR)/ares-test-parse-naptr.Po \ + ./$(DEPDIR)/ares-test-parse-ns.Po \ + ./$(DEPDIR)/ares-test-parse-ptr.Po \ + ./$(DEPDIR)/ares-test-parse-soa-any.Po \ + ./$(DEPDIR)/ares-test-parse-soa.Po \ + ./$(DEPDIR)/ares-test-parse-srv.Po \ + ./$(DEPDIR)/ares-test-parse-txt.Po \ + ./$(DEPDIR)/ares-test-parse.Po ./$(DEPDIR)/ares-test.Po \ + ./$(DEPDIR)/dns-dump.Po ./$(DEPDIR)/dns-proto-test.Po \ + ./$(DEPDIR)/dns-proto.Po \ + gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -204,17 +232,17 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = -SOURCES = $(libgmock_la_SOURCES) $(libgtest_la_SOURCES) \ - $(aresfuzz_SOURCES) $(arestest_SOURCES) $(dnsdump_SOURCES) -DIST_SOURCES = $(libgmock_la_SOURCES) $(libgtest_la_SOURCES) \ - $(aresfuzz_SOURCES) $(arestest_SOURCES) $(dnsdump_SOURCES) +SOURCES = $(libgmock_la_SOURCES) $(aresfuzz_SOURCES) \ + $(aresfuzzname_SOURCES) $(arestest_SOURCES) $(dnsdump_SOURCES) +DIST_SOURCES = $(libgmock_la_SOURCES) $(aresfuzz_SOURCES) \ + $(aresfuzzname_SOURCES) $(arestest_SOURCES) $(dnsdump_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ *) (install-info --version) >/dev/null 2>&1;; \ esac -am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \ - $(LISP)config.h.in +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \ + config.h.in # Read a list of newline-separated strings from the standard input, # and print each of them once, without duplicates. Input order is # *not* preserved. @@ -420,7 +448,7 @@ am__set_TESTS_bases = \ RECHECK_LOGS = $(TEST_LOGS) TEST_SUITE_LOG = test-suite.log TEST_EXTENSIONS = @EXEEXT@ .test -LOG_DRIVER = $(SHELL) $(top_srcdir)/../test-driver +LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS) am__set_b = \ case '$@' in \ @@ -435,15 +463,12 @@ am__set_b = \ am__test_logs1 = $(TESTS:=.log) am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log) TEST_LOGS = $(am__test_logs2:.test.log=.log) -TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/../test-driver +TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \ $(TEST_LOG_FLAGS) am__DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.inc \ - $(srcdir)/config.h.in $(top_srcdir)/../compile \ - $(top_srcdir)/../config.guess $(top_srcdir)/../config.sub \ - $(top_srcdir)/../depcomp $(top_srcdir)/../install-sh \ - $(top_srcdir)/../ltmain.sh $(top_srcdir)/../missing \ - $(top_srcdir)/../mkinstalldirs $(top_srcdir)/../test-driver + $(srcdir)/config.h.in compile config.guess config.sub depcomp \ + install-sh ltmain.sh missing test-driver DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) distdir = $(PACKAGE)-$(VERSION) top_distdir = $(distdir) @@ -476,9 +501,12 @@ CODE_COVERAGE_CFLAGS = @CODE_COVERAGE_CFLAGS@ CODE_COVERAGE_ENABLED = @CODE_COVERAGE_ENABLED@ CODE_COVERAGE_LDFLAGS = @CODE_COVERAGE_LDFLAGS@ CPP = @CPP@ + # Note use of -isystem to force use of local gMock/gTest even if there's an installed version. -CPPFLAGS = @CPPFLAGS@ -I$(ARES_SRC_DIR) -isystem $(GTEST_DIR)/include \ - -isystem $(GMOCK_DIR)/include +CPPFLAGS = @CPPFLAGS@ -I$(ARES_BLD_DIR)/include \ + -I$(ARES_BLD_DIR)/src/lib -I$(ARES_SRC_DIR)/include \ + -I$(ARES_SRC_DIR)/src/lib -I$(top_builddir) -isystem \ + $(srcdir)/gmock-1.8.0 CXX = @CXX@ CXXCPP = @CXXCPP@ CXXDEPMODE = @CXXDEPMODE@ @@ -596,15 +624,10 @@ target_alias = @target_alias@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ - -# Where to find the c-ares source code; needed because the tests use library-internal headers -ARES_SRC_DIR = .. -# Where to find the built c-ares static library -ARES_BLD_DIR = .. -AUTOMAKE_OPTIONS = foreign -ACLOCAL_AMFLAGS = -I ../m4 -GMOCK_DIR = gmock-1.7.0 -GTEST_DIR = $(GMOCK_DIR)/gtest +ARES_BLD_DIR = $(top_builddir)/.. +ARES_SRC_DIR = $(top_srcdir)/.. +AUTOMAKE_OPTIONS = foreign subdir-objects nostdinc 1.9.6 +ACLOCAL_AMFLAGS = -I ../m4 --install TESTSOURCES = ares-test-main.cc \ ares-test-init.cc \ ares-test.cc \ @@ -612,41 +635,53 @@ TESTSOURCES = ares-test-main.cc \ ares-test-parse.cc \ ares-test-parse-a.cc \ ares-test-parse-aaaa.cc \ + ares-test-parse-caa.cc \ ares-test-parse-mx.cc \ ares-test-parse-naptr.cc \ ares-test-parse-ns.cc \ ares-test-parse-ptr.cc \ ares-test-parse-soa.cc \ + ares-test-parse-soa-any.cc \ ares-test-parse-srv.cc \ ares-test-parse-txt.cc \ ares-test-misc.cc \ ares-test-live.cc \ ares-test-mock.cc \ + ares-test-mock-ai.cc \ ares-test-internal.cc \ dns-proto.cc \ dns-proto-test.cc TESTHEADERS = ares-test.h \ - dns-proto.h + dns-proto.h \ + ares-test-ai.h FUZZSOURCES = ares-test-fuzz.c \ ares-fuzz.c +FUZZNAMESOURCES = ares-test-fuzz-name.c \ + ares-fuzz.c + DUMPSOURCES = dns-proto.cc \ dns-dump.cc +noinst_LTLIBRARIES = libgmock.la +libgmock_la_SOURCES = \ + gmock-1.8.0/gmock-gtest-all.cc \ + gmock-1.8.0/gmock/gmock.h \ + gmock-1.8.0/gtest/gtest.h + +libgmock_la_CPPFLAGS = -isystem $(srcdir)/gmock-1.8.0 +EXTRA_DIST = fuzzcheck.sh CMakeLists.txt Makefile.m32 Makefile.msvc README.md buildconf arestest_SOURCES = $(TESTSOURCES) $(TESTHEADERS) -arestest_LDADD = libgmock.la libgtest.la $(ARES_BLD_DIR)/libcares.la $(PTHREAD_LIBS) +arestest_LDADD = libgmock.la $(ARES_BLD_DIR)/src/lib/libcares.la $(PTHREAD_LIBS) arestest_LDFLAGS = $(CODE_COVERAGE_LDFLAGS) -noinst_LTLIBRARIES = libgmock.la libgtest.la -libgmock_la_SOURCES = $(GMOCK_DIR)/src/gmock-all.cc -libgmock_la_CPPFLAGS = -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -isystem $(GMOCK_DIR)/include -I$(GMOCK_DIR) -libgtest_la_SOURCES = $(GTEST_DIR)/src/gtest-all.cc -libgtest_la_CPPFLAGS = -isystem $(GTEST_DIR)/include -I$(GTEST_DIR) -isystem $(GMOCK_DIR)/include -I$(GMOCK_DIR) aresfuzz_SOURCES = $(FUZZSOURCES) -aresfuzz_LDADD = $(ARES_BLD_DIR)/libcares.la +aresfuzz_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la +aresfuzzname_SOURCES = $(FUZZNAMESOURCES) +aresfuzzname_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la dnsdump_SOURCES = $(DUMPSOURCES) -dnsdump_LDADD = $(ARES_BLD_DIR)/libcares.la +dnsdump_LDADD = $(ARES_BLD_DIR)/src/lib/libcares.la all: config.h $(MAKE) $(AM_MAKEFLAGS) all-am @@ -673,8 +708,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(srcdir)/Makefile.inc $(am__empty): @@ -702,6 +737,15 @@ $(srcdir)/config.h.in: $(am__configure_deps) distclean-hdr: -rm -f config.h stamp-h1 +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list + clean-noinstLTLIBRARIES: -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) @list='$(noinst_LTLIBRARIES)'; \ @@ -712,26 +756,27 @@ clean-noinstLTLIBRARIES: echo rm -f $${locs}; \ rm -f $${locs}; \ } +gmock-1.8.0/$(am__dirstamp): + @$(MKDIR_P) gmock-1.8.0 + @: > gmock-1.8.0/$(am__dirstamp) +gmock-1.8.0/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) gmock-1.8.0/$(DEPDIR) + @: > gmock-1.8.0/$(DEPDIR)/$(am__dirstamp) +gmock-1.8.0/libgmock_la-gmock-gtest-all.lo: \ + gmock-1.8.0/$(am__dirstamp) \ + gmock-1.8.0/$(DEPDIR)/$(am__dirstamp) libgmock.la: $(libgmock_la_OBJECTS) $(libgmock_la_DEPENDENCIES) $(EXTRA_libgmock_la_DEPENDENCIES) $(AM_V_CXXLD)$(CXXLINK) $(libgmock_la_OBJECTS) $(libgmock_la_LIBADD) $(LIBS) -libgtest.la: $(libgtest_la_OBJECTS) $(libgtest_la_DEPENDENCIES) $(EXTRA_libgtest_la_DEPENDENCIES) - $(AM_V_CXXLD)$(CXXLINK) $(libgtest_la_OBJECTS) $(libgtest_la_LIBADD) $(LIBS) - -clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ - echo " rm -f" $$list; \ - rm -f $$list || exit $$?; \ - test -n "$(EXEEXT)" || exit 0; \ - list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f" $$list; \ - rm -f $$list - aresfuzz$(EXEEXT): $(aresfuzz_OBJECTS) $(aresfuzz_DEPENDENCIES) $(EXTRA_aresfuzz_DEPENDENCIES) @rm -f aresfuzz$(EXEEXT) $(AM_V_CCLD)$(LINK) $(aresfuzz_OBJECTS) $(aresfuzz_LDADD) $(LIBS) +aresfuzzname$(EXEEXT): $(aresfuzzname_OBJECTS) $(aresfuzzname_DEPENDENCIES) $(EXTRA_aresfuzzname_DEPENDENCIES) + @rm -f aresfuzzname$(EXEEXT) + $(AM_V_CCLD)$(LINK) $(aresfuzzname_OBJECTS) $(aresfuzzname_LDADD) $(LIBS) + arestest$(EXEEXT): $(arestest_OBJECTS) $(arestest_DEPENDENCIES) $(EXTRA_arestest_DEPENDENCIES) @rm -f arestest$(EXEEXT) $(AM_V_CXXLD)$(arestest_LINK) $(arestest_OBJECTS) $(arestest_LDADD) $(LIBS) @@ -742,97 +787,108 @@ dnsdump$(EXEEXT): $(dnsdump_OBJECTS) $(dnsdump_DEPENDENCIES) $(EXTRA_dnsdump_DEP mostlyclean-compile: -rm -f *.$(OBJEXT) + -rm -f gmock-1.8.0/*.$(OBJEXT) + -rm -f gmock-1.8.0/*.lo distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-fuzz.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-fuzz.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-init.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-internal.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-live.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-main.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-misc.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-mock.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-ns.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-a.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-aaaa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-mx.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-naptr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-ns.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-ptr.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-soa.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-srv.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-txt.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-dump.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-proto-test.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-proto.Po@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgmock_la-gmock-all.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgtest_la-gtest-all.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-fuzz.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-fuzz-name.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-fuzz.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-init.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-internal.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-live.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-main.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-misc.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-mock-ai.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-mock.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-ns.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-a.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-aaaa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-caa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-mx.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-naptr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-ns.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-ptr.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-soa-any.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-soa.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-srv.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse-txt.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test-parse.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ares-test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-dump.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-proto-test.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns-proto.Po@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< .c.obj: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .c.lo: -@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCC_TRUE@ $(AM_V_CC)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCC_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< .cc.o: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< .cc.obj: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.obj$$||'`;\ +@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ `$(CYGPATH_W) '$<'` &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` .cc.lo: -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ +@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ +@am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< -libgmock_la-gmock-all.lo: $(GMOCK_DIR)/src/gmock-all.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgmock_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libgmock_la-gmock-all.lo -MD -MP -MF $(DEPDIR)/libgmock_la-gmock-all.Tpo -c -o libgmock_la-gmock-all.lo `test -f '$(GMOCK_DIR)/src/gmock-all.cc' || echo '$(srcdir)/'`$(GMOCK_DIR)/src/gmock-all.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgmock_la-gmock-all.Tpo $(DEPDIR)/libgmock_la-gmock-all.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GMOCK_DIR)/src/gmock-all.cc' object='libgmock_la-gmock-all.lo' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgmock_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libgmock_la-gmock-all.lo `test -f '$(GMOCK_DIR)/src/gmock-all.cc' || echo '$(srcdir)/'`$(GMOCK_DIR)/src/gmock-all.cc - -libgtest_la-gtest-all.lo: $(GTEST_DIR)/src/gtest-all.cc -@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT libgtest_la-gtest-all.lo -MD -MP -MF $(DEPDIR)/libgtest_la-gtest-all.Tpo -c -o libgtest_la-gtest-all.lo `test -f '$(GTEST_DIR)/src/gtest-all.cc' || echo '$(srcdir)/'`$(GTEST_DIR)/src/gtest-all.cc -@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libgtest_la-gtest-all.Tpo $(DEPDIR)/libgtest_la-gtest-all.Plo -@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$(GTEST_DIR)/src/gtest-all.cc' object='libgtest_la-gtest-all.lo' libtool=yes @AMDEPBACKSLASH@ +gmock-1.8.0/libgmock_la-gmock-gtest-all.lo: gmock-1.8.0/gmock-gtest-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgmock_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gmock-1.8.0/libgmock_la-gmock-gtest-all.lo -MD -MP -MF gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Tpo -c -o gmock-1.8.0/libgmock_la-gmock-gtest-all.lo `test -f 'gmock-1.8.0/gmock-gtest-all.cc' || echo '$(srcdir)/'`gmock-1.8.0/gmock-gtest-all.cc +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Tpo gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Plo +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gmock-1.8.0/gmock-gtest-all.cc' object='gmock-1.8.0/libgmock_la-gmock-gtest-all.lo' libtool=yes @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgtest_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o libgtest_la-gtest-all.lo `test -f '$(GTEST_DIR)/src/gtest-all.cc' || echo '$(srcdir)/'`$(GTEST_DIR)/src/gtest-all.cc +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libgmock_la_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gmock-1.8.0/libgmock_la-gmock-gtest-all.lo `test -f 'gmock-1.8.0/gmock-gtest-all.cc' || echo '$(srcdir)/'`gmock-1.8.0/gmock-gtest-all.cc mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs + -rm -rf gmock-1.8.0/.libs gmock-1.8.0/_libs distclean-libtool: -rm -f libtool config.lt @@ -1016,7 +1072,7 @@ $(TEST_SUITE_LOG): $(TEST_LOGS) fi; \ $$success || exit 1 -check-TESTS: +check-TESTS: @list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list @list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list @test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG) @@ -1066,7 +1122,10 @@ fuzzcheck.sh.log: fuzzcheck.sh @am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \ @am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT) -distdir: $(DISTFILES) +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) $(am__remove_distdir) test -d "$(distdir)" || mkdir "$(distdir)" @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ @@ -1106,7 +1165,7 @@ distdir: $(DISTFILES) ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \ || chmod -R a+r "$(distdir)" dist-gzip: distdir - tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz + tardir=$(distdir) && $(am__tar) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).tar.gz $(am__post_remove_distdir) dist-bzip2: distdir @@ -1121,6 +1180,10 @@ dist-xz: distdir tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz $(am__post_remove_distdir) +dist-zstd: distdir + tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst + $(am__post_remove_distdir) + dist-tarZ: distdir @echo WARNING: "Support for distribution archives compressed with" \ "legacy program 'compress' is deprecated." >&2 @@ -1132,7 +1195,7 @@ dist-shar: distdir @echo WARNING: "Support for shar distribution archives is" \ "deprecated." >&2 @echo WARNING: "It will be removed altogether in Automake 2.0" >&2 - shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz + shar $(distdir) | eval GZIP= gzip $(GZIP_ENV) -c >$(distdir).shar.gz $(am__post_remove_distdir) dist-zip: distdir @@ -1150,7 +1213,7 @@ dist dist-all: distcheck: dist case '$(DIST_ARCHIVES)' in \ *.tar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).tar.gz | $(am__untar) ;;\ *.tar.bz2*) \ bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\ *.tar.lz*) \ @@ -1160,9 +1223,11 @@ distcheck: dist *.tar.Z*) \ uncompress -c $(distdir).tar.Z | $(am__untar) ;;\ *.shar.gz*) \ - GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\ + eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\ *.zip*) \ unzip $(distdir).zip ;;\ + *.tar.zst*) \ + zstd -dc $(distdir).tar.zst | $(am__untar) ;;\ esac chmod -R a-w $(distdir) chmod u+w $(distdir) @@ -1232,7 +1297,7 @@ distcleancheck: distclean check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) config.h +all-am: Makefile $(PROGRAMS) $(LTLIBRARIES) config.h installdirs: install: install-am install-exec: install-exec-am @@ -1263,6 +1328,8 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + -rm -f gmock-1.8.0/$(DEPDIR)/$(am__dirstamp) + -rm -f gmock-1.8.0/$(am__dirstamp) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -1274,7 +1341,34 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ distclean: distclean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/ares-fuzz.Po + -rm -f ./$(DEPDIR)/ares-test-fuzz-name.Po + -rm -f ./$(DEPDIR)/ares-test-fuzz.Po + -rm -f ./$(DEPDIR)/ares-test-init.Po + -rm -f ./$(DEPDIR)/ares-test-internal.Po + -rm -f ./$(DEPDIR)/ares-test-live.Po + -rm -f ./$(DEPDIR)/ares-test-main.Po + -rm -f ./$(DEPDIR)/ares-test-misc.Po + -rm -f ./$(DEPDIR)/ares-test-mock-ai.Po + -rm -f ./$(DEPDIR)/ares-test-mock.Po + -rm -f ./$(DEPDIR)/ares-test-ns.Po + -rm -f ./$(DEPDIR)/ares-test-parse-a.Po + -rm -f ./$(DEPDIR)/ares-test-parse-aaaa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-caa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-mx.Po + -rm -f ./$(DEPDIR)/ares-test-parse-naptr.Po + -rm -f ./$(DEPDIR)/ares-test-parse-ns.Po + -rm -f ./$(DEPDIR)/ares-test-parse-ptr.Po + -rm -f ./$(DEPDIR)/ares-test-parse-soa-any.Po + -rm -f ./$(DEPDIR)/ares-test-parse-soa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-srv.Po + -rm -f ./$(DEPDIR)/ares-test-parse-txt.Po + -rm -f ./$(DEPDIR)/ares-test-parse.Po + -rm -f ./$(DEPDIR)/ares-test.Po + -rm -f ./$(DEPDIR)/dns-dump.Po + -rm -f ./$(DEPDIR)/dns-proto-test.Po + -rm -f ./$(DEPDIR)/dns-proto.Po + -rm -f gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -1322,7 +1416,34 @@ installcheck-am: maintainer-clean: maintainer-clean-am -rm -f $(am__CONFIG_DISTCLEAN_FILES) -rm -rf $(top_srcdir)/autom4te.cache - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/ares-fuzz.Po + -rm -f ./$(DEPDIR)/ares-test-fuzz-name.Po + -rm -f ./$(DEPDIR)/ares-test-fuzz.Po + -rm -f ./$(DEPDIR)/ares-test-init.Po + -rm -f ./$(DEPDIR)/ares-test-internal.Po + -rm -f ./$(DEPDIR)/ares-test-live.Po + -rm -f ./$(DEPDIR)/ares-test-main.Po + -rm -f ./$(DEPDIR)/ares-test-misc.Po + -rm -f ./$(DEPDIR)/ares-test-mock-ai.Po + -rm -f ./$(DEPDIR)/ares-test-mock.Po + -rm -f ./$(DEPDIR)/ares-test-ns.Po + -rm -f ./$(DEPDIR)/ares-test-parse-a.Po + -rm -f ./$(DEPDIR)/ares-test-parse-aaaa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-caa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-mx.Po + -rm -f ./$(DEPDIR)/ares-test-parse-naptr.Po + -rm -f ./$(DEPDIR)/ares-test-parse-ns.Po + -rm -f ./$(DEPDIR)/ares-test-parse-ptr.Po + -rm -f ./$(DEPDIR)/ares-test-parse-soa-any.Po + -rm -f ./$(DEPDIR)/ares-test-parse-soa.Po + -rm -f ./$(DEPDIR)/ares-test-parse-srv.Po + -rm -f ./$(DEPDIR)/ares-test-parse-txt.Po + -rm -f ./$(DEPDIR)/ares-test-parse.Po + -rm -f ./$(DEPDIR)/ares-test.Po + -rm -f ./$(DEPDIR)/dns-dump.Po + -rm -f ./$(DEPDIR)/dns-proto-test.Po + -rm -f ./$(DEPDIR)/dns-proto.Po + -rm -f gmock-1.8.0/$(DEPDIR)/libgmock_la-gmock-gtest-all.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -1343,23 +1464,23 @@ uninstall-am: .MAKE: all check-am install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am am--refresh check check-TESTS \ - check-am clean clean-cscope clean-generic clean-libtool \ - clean-noinstLTLIBRARIES clean-noinstPROGRAMS cscope \ - cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles am--refresh check \ + check-TESTS check-am clean clean-cscope clean-generic \ + clean-libtool clean-noinstLTLIBRARIES clean-noinstPROGRAMS \ + cscope cscopelist-am ctags ctags-am dist dist-all dist-bzip2 \ dist-gzip dist-lzip dist-shar dist-tarZ dist-xz dist-zip \ - distcheck distclean distclean-compile distclean-generic \ - distclean-hdr distclean-libtool distclean-tags distcleancheck \ - distdir distuninstallcheck dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am recheck tags tags-am \ - uninstall uninstall-am + dist-zstd distcheck distclean distclean-compile \ + distclean-generic distclean-hdr distclean-libtool \ + distclean-tags distcleancheck distdir distuninstallcheck dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + recheck tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff --git a/test/Makefile.inc b/test/Makefile.inc index 2fa98b1..2c2769d 100644 --- a/test/Makefile.inc +++ b/test/Makefile.inc @@ -5,25 +5,32 @@ TESTSOURCES = ares-test-main.cc \ ares-test-parse.cc \ ares-test-parse-a.cc \ ares-test-parse-aaaa.cc \ + ares-test-parse-caa.cc \ ares-test-parse-mx.cc \ ares-test-parse-naptr.cc \ ares-test-parse-ns.cc \ ares-test-parse-ptr.cc \ ares-test-parse-soa.cc \ + ares-test-parse-soa-any.cc \ ares-test-parse-srv.cc \ ares-test-parse-txt.cc \ ares-test-misc.cc \ ares-test-live.cc \ ares-test-mock.cc \ + ares-test-mock-ai.cc \ ares-test-internal.cc \ dns-proto.cc \ dns-proto-test.cc TESTHEADERS = ares-test.h \ - dns-proto.h + dns-proto.h \ + ares-test-ai.h FUZZSOURCES = ares-test-fuzz.c \ ares-fuzz.c +FUZZNAMESOURCES = ares-test-fuzz-name.c \ + ares-fuzz.c + DUMPSOURCES = dns-proto.cc \ dns-dump.cc diff --git a/test/Makefile.m32 b/test/Makefile.m32 new file mode 100644 index 0000000..1b308c4 --- /dev/null +++ b/test/Makefile.m32 @@ -0,0 +1,61 @@ +############################################################# +# +## Makefile for building arestest.exe with MingW32 (GCC-3.2) +## Use: make -f Makefile.m32 +# +######################################################## +CXX = g++ +CC = gcc +LD = g++ + +# Where to find the c-ares source code; needed because the tests use library-internal headers +ARES_SRC_DIR = .. +# Where to find the built c-ares static library +ARES_BLD_DIR = .. +ARESLIB = $(ARES_BLD_DIR)/src/lib/libcares.a +GMOCK_DIR = gmock-1.8.0 +CPPFLAGS = -I$(ARES_SRC_DIR)/include -I$(ARES_SRC_DIR)/src/lib -I$(GMOCK_DIR) -DCARES_STATICLIB +CXXFLAGS = -Wall $(PTHREAD_CFLAGS) -std=gnu++11 +LDFLAGS = +LDLIBS = -lwsock32 + +# Makefile.inc provides the TESTSOURCES and TESTHEADERS defines +include Makefile.inc + +OBJS := $(patsubst %.cc,%.o,$(strip $(TESTSOURCES))) +FUZZOBJS := $(patsubst %.c,%.o,$(strip $(FUZZSOURCES))) +FUZZNAMEOBJS := $(patsubst %.c,%.o,$(strip $(FUZZNAMESOURCES))) +DNSDUMPOBJS := $(patsubst %.cc,%.o,$(strip $(DUMPSOURCES))) + +all: arestest.exe aresfuzz.exe aresfuzzname.exe dnsdump.exe + +arestest.exe: $(OBJS) gmock-gtest-all.o + $(LD) $(LDFLAGS) -o $@ $^ -L$(ARES_BLD_DIR)/src/lib -lcares $(LDLIBS) + +aresfuzz.exe: $(FUZZOBJS) + $(LD) $(LDFLAGS) -o $@ $^ -L$(ARES_BLD_DIR)/src/lib -lcares $(LDLIBS) + +aresfuzzname.exe: $(FUZZNAMEOBJS) + $(LD) $(LDFLAGS) -o $@ $^ -L$(ARES_BLD_DIR)/src/lib -lcares $(LDLIBS) + +dnsdump.exe: $(DNSDUMPOBJS) + $(LD) $(LDFLAGS) -o $@ $^ -L$(ARES_BLD_DIR)/src/lib -lcares $(LDLIBS) + +$(OBJS): $(TESTHEADERS) + +.cc.o: + $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< +.c.o: + $(CC) $(CPPFLAGS) $(CFLAGS) -c $< +gmock-gtest-all.o: $(GMOCK_DIR)/gmock-gtest-all.cc + $(CXX) -I$(GMOCK_DIR) $(CPPFLAGS) $(CXXFLAGS) -c $< + +test: arestest.exe + ./arestest.exe +vtest: arestest.exe + ./arestest.exe -v + +clean: + $(RM) $(OBJS) gmock-gtest-all.o arestest.exe aresfuzz.exe aresfuzzname.exe dnsdump.exe + + diff --git a/test/Makefile.msvc b/test/Makefile.msvc new file mode 100644 index 0000000..e0337db --- /dev/null +++ b/test/Makefile.msvc @@ -0,0 +1,340 @@ +# Permission to use, copy, modify, and distribute this +# software and its documentation for any purpose and without +# fee is hereby granted, provided that the above copyright +# notice appear in all copies and that both that copyright +# notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in +# advertising or publicity pertaining to distribution of the +# software without specific, written prior permission. +# M.I.T. makes no representations about the suitability of +# this software for any purpose. It is provided "as is" +# without express or implied warranty. + +# ------------------------------------------------------------------------------ +# +# Makefile for building c-ares test suite with MSVC. +# +# Usage: nmake /f makefile.msvc CFG= +# +# can be one of: [ lib-release | lib-debug | dll-release | dll-debug } +# can be one of: [ all | arestest | clean } +# +# If is not specified then all targets are built. +# If is not specified then lib-debug will be assumed. +# +# This makefile must be processed from the subdir where it is located. +# +# All results are generated below a subdirectory named msvcXXX. +# +# ------------------------------------------------------------------------------ + + +# ------------------------------------------------ +# c-ares static and dynamic libraries common base +# file names for release and debug configurations +# ------------------------------------------------ + +LIBNAME = cares +STA_LIB_REL = lib$(LIBNAME) +DYN_LIB_REL = $(LIBNAME) +STA_LIB_DBG = $(STA_LIB_REL)d +DYN_LIB_DBG = $(DYN_LIB_REL)d + +# ------------------------------------------- +# Base names for c-ares DLL import libraries +# ------------------------------------------- + +IMP_LIB_REL = $(DYN_LIB_REL) +IMP_LIB_DBG = $(DYN_LIB_DBG) + +# -------------------------- +# Runtime library selection +# -------------------------- + +RTLIB = /MD +RTLIBD = /MDd + +!IF "$(RTLIBCFG)" == "static" +RTLIB = /MT +RTLIBD = /MTd +!ENDIF + +# -------------------------------------------------------- +# Detect compiler version. +# -------------------------------------------------------- +!INCLUDE ..\msvc_ver.inc + +# --------------------------------------------------------- +# Verify that current subdir is below the c-ares source one +# --------------------------------------------------------- + +!IF ! EXIST(..\src\lib\ares_init.c) +! MESSAGE Can not process Makefile.msvc from outside of c-ares test subdirectory. +! MESSAGE Change to the subdirectory where Makefile.msvc is found, and try again. +! ERROR See previous message. +!ENDIF + +# ------------------------------------------------------------------ +# Base subdir is the common root from which other subdirs will hang, +# the name depends on MSVC version being used when building c-ares. +# ------------------------------------------------------------------ + +BASE_DIR = .\msvc +# Look for a built library of the same configuration in the directory above. +LIB_BASE_DIR = ..\msvc + +# ---------------------------------------- +# Subdir holding sources for all projects +# ---------------------------------------- + +SRCDIR = . + +# ------------------------- +# Configuration validation +# ------------------------- + +!IF "$(CFG)" == "" +CFG = lib-debug +!ENDIF + +VALID_CFGSET = FALSE +!IF "$(CFG)" == "lib-release" || "$(CFG)" == "lib-debug" || \ + "$(CFG)" == "dll-release" || "$(CFG)" == "dll-debug" +VALID_CFGSET = TRUE +!ENDIF + +!IF "$(VALID_CFGSET)" == "FALSE" +! MESSAGE MSVC c-ares makefile +! MESSAGE +! MESSAGE Usage: nmake /f makefile.msvc CFG= +! MESSAGE +! MESSAGE can be one of: [ lib-release | lib-debug | dll-release | dll-debug } +! MESSAGE can be one of: [ all | arestest | aresfuzz | aresfuzzname | dnsdump | clean } +! MESSAGE +! MESSAGE If is not specified then all targets are built. +! MESSAGE If is not specified then lib-debug will be assumed. +! MESSAGE +! ERROR Choose a valid configuration. +!ENDIF + +# -------------------------------------------------------- +# Project subdirs independent of configuration being used +# -------------------------------------------------------- + +PROG_DIR = $(BASE_DIR)\arestest +LIB_DIR = $(LIB_BASE_DIR)\cares + +GMOCK_DIR = gmock-1.8.0 + +# --------------------------------------------------- +# Subdirs which are configuration dependent are only +# defined when a valid configuration has been given. +# --------------------------------------------------- + +PROG_OUTDIR = $(PROG_DIR)\$(CFG) +PROG_OBJDIR = $(PROG_OUTDIR)\obj +LIB_OUTDIR = $(LIB_DIR)\$(CFG) + + +# ------------------------------------- +# TCP/IP stack settings +# ------------------------------------- +CFLAGS = /DWIN32 +EX_LIBS_REL = ws2_32.lib advapi32.lib kernel32.lib +EX_LIBS_DBG = ws2_32.lib advapi32.lib kernel32.lib + +# ------------------------------------------------- +# Switches that depend on ancient compiler versions +# ------------------------------------------------- + +!IF $(CC_VERS_NUM) == 60 +PDB_NONE = /pdb:none +PDBTYPE_CONSOLIDATE = /pdbtype:consolidate +!ELSE +!UNDEF PDB_NONE +!UNDEF PDBTYPE_CONSOLIDATE +!ENDIF + +!IF $(CC_VERS_NUM) <= 70 +RT_ERROR_CHECKING = /GZ +!ELSE +RT_ERROR_CHECKING = /RTCsu +!ENDIF + +# ---------------------------- +# Assorted commands and flags +# ---------------------------- + +CC_CMD_REL = cl.exe /nologo $(RTLIB) /DNDEBUG /O2 /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS +CC_CMD_DBG = cl.exe /nologo $(RTLIBD) /D_DEBUG /Od /Zi /D_CRT_NONSTDC_NO_DEPRECATE /D_CRT_SECURE_NO_WARNINGS $(RT_ERROR_CHECKING) +CC_CFLAGS = $(CFLAGS) /I. /I../src/lib /I../include /I $(GMOCK_DIR) /W3 /EHsc /FD + +RC_CMD_REL = rc.exe /l 0x409 /d "NDEBUG" +RC_CMD_DBG = rc.exe /l 0x409 /d "_DEBUG" + +LINK_CMD_LIB = link.exe /lib /nologo +LINK_CMD_DLL = link.exe /dll /nologo /incremental:no /fixed:no +LINK_CMD_EXE = link.exe /nologo /incremental:no /fixed:no /subsystem:console + +LINK_CMD_EXE_REL = $(LINK_CMD_EXE) /release $(PDB_NONE) +LINK_CMD_EXE_DBG = $(LINK_CMD_EXE) /debug $(PDBTYPE_CONSOLIDATE) + +# --------------------------------- +# Configuration dependent settings +# --------------------------------- + +!IF "$(CFG)" == "lib-release" +CARES_TARGET = $(STA_LIB_REL).lib +CARES_CFLAGS = /DCARES_BUILDING_LIBRARY /DCARES_STATICLIB +CARES_LFLAGS = +SPROG_CFLAGS = /DCARES_STATICLIB +SPROG_LFLAGS = /libpath:$(LIB_OUTDIR) $(EX_LIBS_REL) $(STA_LIB_REL).lib +CARES_LINK = $(LINK_CMD_LIB) +SPROG_LINK = $(LINK_CMD_EXE_REL) +CC_CMD = $(CC_CMD_REL) +!ENDIF + +!IF "$(CFG)" == "lib-debug" +CARES_TARGET = $(STA_LIB_DBG).lib +CARES_CFLAGS = /DCARES_BUILDING_LIBRARY /DCARES_STATICLIB /DDEBUGBUILD +CARES_LFLAGS = +SPROG_CFLAGS = /DCARES_STATICLIB +SPROG_LFLAGS = /libpath:$(LIB_OUTDIR) $(EX_LIBS_DBG) $(STA_LIB_DBG).lib +CARES_LINK = $(LINK_CMD_LIB) +SPROG_LINK = $(LINK_CMD_EXE_DBG) +CC_CMD = $(CC_CMD_DBG) +!ENDIF + +!IF "$(CFG)" == "dll-release" +CARES_TARGET = $(DYN_LIB_REL).dll +CARES_CFLAGS = /DCARES_BUILDING_LIBRARY +CARES_LFLAGS = /release $(EX_LIBS_REL) /implib:$(PROG_OUTDIR)\$(IMP_LIB_REL).lib $(PDB_NONE) +SPROG_CFLAGS = +SPROG_LFLAGS = /libpath:$(LIB_OUTDIR) $(EX_LIBS_REL) $(IMP_LIB_REL).lib +CARES_LINK = $(LINK_CMD_DLL) +SPROG_LINK = $(LINK_CMD_EXE_REL) +CC_CMD = $(CC_CMD_REL) +USE_RES_FILE = TRUE +RC_CMD = $(RC_CMD_REL) +!ENDIF + +!IF "$(CFG)" == "dll-debug" +CARES_TARGET = $(DYN_LIB_DBG).dll +CARES_CFLAGS = /DCARES_BUILDING_LIBRARY /DDEBUGBUILD +CARES_LFLAGS = /debug $(EX_LIBS_DBG) /implib:$(PROG_OUTDIR)\$(IMP_LIB_DBG).lib /pdb:$(PROG_OUTDIR)\$(DYN_LIB_DBG).pdb $(PDBTYPE_CONSOLIDATE) +SPROG_CFLAGS = +SPROG_LFLAGS = /libpath:$(LIB_OUTDIR) $(EX_LIBS_DBG) $(IMP_LIB_DBG).lib +CARES_LINK = $(LINK_CMD_DLL) +SPROG_LINK = $(LINK_CMD_EXE_DBG) +CC_CMD = $(CC_CMD_DBG) +USE_RES_FILE = TRUE +RC_CMD = $(RC_CMD_DBG) +!ENDIF + +# -------------------------------------------- +# Makefile.inc provides lists of source files +# -------------------------------------------- + +!INCLUDE .\Makefile.inc + +# ---------------------------- +# Build lists of object files +# ---------------------------- + +!IF [ECHO PROG_OBJS=^$(PROG_OBJDIR)\$(TESTSOURCES: = $(PROG_OBJDIR^)\) > .\prog_objs.inc] == 0 +!INCLUDE .\prog_objs.inc +!IF [DEL .\prog_objs.inc] +!ENDIF +!ELSE +!ERROR Problem generating PROG_OBJS list. +!ENDIF +PROG_OBJS = $(PROG_OBJS:.cc=.obj) + +!IF [ECHO FUZZ_OBJS=^$(PROG_OBJDIR)\$(FUZZSOURCES: = $(PROG_OBJDIR^)\) > .\fuzz_objs.inc] == 0 +!INCLUDE .\fuzz_objs.inc +!IF [DEL .\fuzz_objs.inc] +!ENDIF +!ELSE +!ERROR Problem generating FUZZ_OBJS list. +!ENDIF +FUZZ_OBJS = $(FUZZ_OBJS:.c=.obj) + +!IF [ECHO FUZZNAME_OBJS=^$(PROG_OBJDIR)\$(FUZZNAMESOURCES: = $(PROG_OBJDIR^)\) > .\fuzzname_objs.inc] == 0 +!INCLUDE .\fuzzname_objs.inc +!IF [DEL .\fuzzname_objs.inc] +!ENDIF +!ELSE +!ERROR Problem generating FUZZNAME_OBJS list. +!ENDIF +FUZZNAME_OBJS = $(FUZZNAME_OBJS:.c=.obj) + +!IF [ECHO DNSDUMP_OBJS=^$(PROG_OBJDIR)\$(DUMPSOURCES: = $(PROG_OBJDIR^)\) > .\dnsdump_objs.inc] == 0 +!INCLUDE .\dnsdump_objs.inc +!IF [DEL .\dnsdump_objs.inc] +!ENDIF +!ELSE +!ERROR Problem generating DNSDUMP_OBJS list. +!ENDIF +DNSDUMP_OBJS = $(DNSDUMP_OBJS:.cc=.obj) + +GMOCK_GTEST_OBJ = $(PROG_OBJDIR)\gmock-gtest-all.obj + +# -------------------------------- +# Only our custom inference rules +# -------------------------------- + +.SUFFIXES: +.SUFFIXES: .cc .c + +{$(SRCDIR)}.cc{$(PROG_OBJDIR)}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< +{$(SRCDIR)}.c{$(PROG_OBJDIR)}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /Fo$@ /Fd$(@D)\ /c $< +{$(GMOCK_DIR)}.cc{$(PROG_OBJDIR)}.obj: + $(CC_CMD) $(CC_CFLAGS) $(SPROG_CFLAGS) /I $(GMOCK_DIR) /Fo$@ /Fd$(@D)\ /c $< + + +# --------------------------------------------------------------------- +# Main targets +# --------------------------------------------------------------------- + +ALL: arestest aresfuzz aresfuzzname dnsdump + @ + +test: arestest + $(PROG_OUTDIR)\arestest +vtest: arestest + $(PROG_OUTDIR)\arestest -v + +arestest: $(TESTSOURCES) $(PROG_OUTDIR) $(PROG_OBJDIR) $(PROG_OBJS) $(GMOCK_GTEST_OBJ) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG_OUTDIR)\arestest.exe $(PROG_OBJS) $(GMOCK_GTEST_OBJ) + @if exist $(PROG_OUTDIR)\arestest.exe.manifest mt -nologo -manifest $(PROG_OUTDIR)\arestest.exe.manifest -outputresource:$(PROG_OUTDIR)\arestest.exe;1 + +aresfuzz: $(FUZZSOURCES) $(PROG_OUTDIR) $(PROG_OBJDIR) $(FUZZ_OBJS) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG_OUTDIR)\aresfuzz.exe $(FUZZ_OBJS) + @if exist $(PROG_OUTDIR)\aresfuzz.exe.manifest mt -nologo -manifest $(PROG_OUTDIR)\aresfuzz.exe.manifest -outputresource:$(PROG_OUTDIR)\aresfuzz.exe;1 + +aresfuzzname: $(FUZZNAMESOURCES) $(PROG_OUTDIR) $(PROG_OBJDIR) $(FUZZNAME_OBJS) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG_OUTDIR)\aresfuzzname.exe $(FUZZNAME_OBJS) + @if exist $(PROG_OUTDIR)\aresfuzzname.exe.manifest mt -nologo -manifest $(PROG_OUTDIR)\aresfuzzname.exe.manifest -outputresource:$(PROG_OUTDIR)\aresfuzzname.exe;1 + +dnsdump: $(DUMPSOURCES) $(PROG_OUTDIR) $(PROG_OBJDIR) $(DNSDUMP_OBJS) + $(SPROG_LINK) $(SPROG_LFLAGS) /out:$(PROG_OUTDIR)\dnsdump.exe $(DNSDUMP_OBJS) + @if exist $(PROG_OUTDIR)\dnsdump.exe.manifest mt -nologo -manifest $(PROG_OUTDIR)\dnsdump.exe.manifest -outputresource:$(PROG_OUTDIR)\dnsdump.exe;1 + +$(PROG_OUTDIR): $(PROG_DIR) + @if not exist $(PROG_OUTDIR) mkdir $(PROG_OUTDIR) + +$(PROG_OBJDIR): $(PROG_OUTDIR) + @if not exist $(PROG_OBJDIR) mkdir $(PROG_OBJDIR) + +clean: + @-RMDIR /S /Q $(PROG_OUTDIR) >NUL 2>&1 + +$(BASE_DIR): + @if not exist $(BASE_DIR) mkdir $(BASE_DIR) + +$(PROG_DIR): $(BASE_DIR) + @if not exist $(PROG_DIR) mkdir $(PROG_DIR) + +# End of Makefile.msvc diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..9881446 --- /dev/null +++ b/test/README.md @@ -0,0 +1,153 @@ +c-ares Unit Test Suite +====================== + + +This directory holds unit tests for the c-ares library. To build the tests: + + - Build the main c-ares library first, in the directory above this. To + enable tests of internal functions, configure the library build to expose + hidden symbols with `./configure --disable-symbol-hiding`. + - Generate a `configure` file by running `autoreconf -iv` (which requires + a local installation of + [autotools](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html)). + - `./configure` + - `make` + - Run the tests with `./arestest`, or `./arestest -v` for extra debug info. + +Points to note: + + - The tests are written in C++11, and so need a C++ compiler that supports + this. To avoid adding this as a requirement for the library, the + configuration and build of the tests is independent from the library. + - The tests include some live queries, which will fail when run on a machine + without internet connectivity. To skip live tests, run with + `./arestest --gtest_filter=-*.Live*`. + - The tests include queries of a mock DNS server. This server listens on port + 5300 by default, but the port can be changed with the `-p 5300` option to + `arestest`. + + +Test Types +---------- + +The test suite includes various different types of test. + + - There are live tests (`ares-test-live.cc`), which assume that the + current machine has a valid DNS setup and connection to the + internet; these tests issue queries for real domains but don't + particularly check what gets returned. The tests will fail on + an offline machine. + - There are some mock tests (`ares-test-mock.cc`) that set up a fake DNS + server and inject its port into the c-ares library configuration. + These tests allow specific response messages to be crafted and + injected, and so are likely to be used for many more tests in + future. + - To make this generation/injection easier, the `dns-proto.h` + file includes C++ helper classes for building DNS packets. + - Other library entrypoints that don't require network activity + (e.g. `ares_parse_*_reply`) are tested directly. + - A couple of the tests use a helper method of the test fixture to + inject memory allocation failures, using a recent change to the + c-ares library that allows override of `malloc`/`free`. + - There are some tests of the internal entrypoints of the library + (`ares-test-internal.c`), but these are only enabled if the library + was configured with `--disable-symbol-hiding` and/or + `--enable-expose-statics`. + - There is also an entrypoint to allow Clang's + [libfuzzer](http://llvm.org/docs/LibFuzzer.html) to drive + the packet parsing code in `ares_parse_*_reply`, together with a + standalone wrapper for it (`./aresfuzz`) to allow use of command + line fuzzers (such as [afl-fuzz](http://lcamtuf.coredump.cx/afl/)) + for further [fuzz testing](#fuzzing). + + +Code Coverage Information +------------------------- + +To generate code coverage information: + + - Configure both the library and the tests with `./configure + --enable-code-coverage` before building. This requires the relevant code + coverage tools ([gcov](https://gcc.gnu.org/onlinedocs/gcc/Gcov.html), + [lcov](http://ltp.sourceforge.net/coverage/lcov.php)) to be installed locally. + - Run the tests with `test/arestest`. + - Generate code coverage output with `make code-coverage-capture` in the + library directory (i.e. not in `test/`). + + +Fuzzing +------- + +### libFuzzer + +To fuzz the packet parsing code with libFuzzer, follow the main +[libFuzzer instructions](http://llvm.org/docs/LibFuzzer.html): + + - Configure the c-ares library and test suite with a recent Clang and a sanitizer, for example: + + ```console + % export CFLAGS="-fsanitize=fuzzer-no-link,address" + % export CC=clang + % ./configure --disable-shared && make + ``` + - Link each of the fuzzer entrypoints in with `ares-fuzz.cc`: + + ``` + % clang -I.. -c ares-test-fuzz.c + % clang -I.. -c ares-test-fuzz-name.c + % clang++ -fsanitize=fuzzer,address ares-test-fuzz.o ../.libs/libcares.a -o ares-libfuzzer + % clang++ -fsanitize=fuzzer,address ares-test-fuzz-name.o ../.libs/libcares.a -o ares-libfuzzer-name + ``` + - Run the fuzzer using the starting corpus with: + + ```console + % ./ares-libfuzzer fuzzinput/ # OR + % ./ares-libfuzzer-name fuzznames/ + ``` + +### AFL + +To fuzz using AFL, follow the +[AFL quick start guide](http://lcamtuf.coredump.cx/afl/QuickStartGuide.txt): + + - Download and build AFL. + - Configure the c-ares library and test tool to use AFL's compiler wrappers: + + ```console + % export CC=$AFLDIR/afl-gcc + % ./configure --disable-shared && make + % cd test && ./configure && make aresfuzz aresfuzzname + ``` + + - Run the AFL fuzzer against the starting corpus: + + ```console + % mkdir fuzzoutput + % $AFLDIR/afl-fuzz -i fuzzinput -o fuzzoutput -- ./aresfuzz # OR + % $AFLDIR/afl-fuzz -i fuzznames -o fuzzoutput -- ./aresfuzzname + ``` + +### AFL Persistent Mode + +If a recent version of Clang is available, AFL can use its built-in compiler +instrumentation; this configuration also allows the use of a (much) faster +persistent mode, where multiple fuzz inputs are run for each process invocation. + + - Download and build a recent AFL, and run `make` in the `llvm_mode` + subdirectory to ensure that `afl-clang-fast` gets built. + - Configure the c-ares library and test tool to use AFL's clang wrappers that + use compiler instrumentation: + + ```console + % export CC=$AFLDIR/afl-clang-fast + % ./configure --disable-shared && make + % cd test && ./configure && make aresfuzz + ``` + + - Run the AFL fuzzer (in persistent mode) against the starting corpus: + + ```console + % mkdir fuzzoutput + % $AFLDIR/afl-fuzz -i fuzzinput -o fuzzoutput -- ./aresfuzz + ``` + diff --git a/test/aclocal.m4 b/test/aclocal.m4 index ecf72b4..d8d4c2d 100644 --- a/test/aclocal.m4 +++ b/test/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15 -*- Autoconf -*- +# generated automatically by aclocal 1.16.2 -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2014 Free Software Foundation, Inc. +# Copyright (C) 2002-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15], [], +m4_if([$1], [1.16.2], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15])dnl +[AM_AUTOMAKE_VERSION([1.16.2])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -110,7 +110,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -141,7 +141,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -332,13 +332,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -346,49 +345,43 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE="gmake" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -397,18 +390,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -495,8 +487,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -563,7 +555,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -605,7 +597,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -626,7 +618,7 @@ if test x"${install_sh+set}" != xset; then fi AC_SUBST([install_sh])]) -# Copyright (C) 2003-2014 Free Software Foundation, Inc. +# Copyright (C) 2003-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -647,7 +639,7 @@ AC_SUBST([am__leading_dot])]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -655,49 +647,42 @@ AC_SUBST([am__leading_dot])]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2014 Free Software Foundation, Inc. +# Copyright (C) 1997-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -736,7 +721,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -765,7 +750,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# Copyright (C) 1999-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -812,7 +797,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -831,7 +816,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2014 Free Software Foundation, Inc. +# Copyright (C) 1996-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -912,7 +897,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2014 Free Software Foundation, Inc. +# Copyright (C) 2009-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -972,7 +957,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2014 Free Software Foundation, Inc. +# Copyright (C) 2001-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1000,7 +985,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2014 Free Software Foundation, Inc. +# Copyright (C) 2006-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1019,7 +1004,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2014 Free Software Foundation, Inc. +# Copyright (C) 2004-2020 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/test/ares-fuzz.c b/test/ares-fuzz.c index 9276128..5526f46 100644 --- a/test/ares-fuzz.c +++ b/test/ares-fuzz.c @@ -8,7 +8,11 @@ #include #include #include +#ifdef WIN32 +#include +#else #include +#endif #define kMaxAflInputSize (1 << 20) static unsigned char afl_buffer[kMaxAflInputSize]; @@ -21,16 +25,17 @@ static unsigned char afl_buffer[kMaxAflInputSize]; #define KEEP_FUZZING(count) ((count) < 1) #endif -/* In ares-test-fuzz.c: */ +/* In ares-test-fuzz.c and ares-test-fuzz-name.c: */ int LLVMFuzzerTestOneInput(const unsigned char *data, unsigned long size); static void ProcessFile(int fd) { - ssize_t count = read(fd, afl_buffer, kMaxAflInputSize); + int count = read(fd, afl_buffer, kMaxAflInputSize); /* * Make a copy of the data so that it's not part of a larger * buffer (where buffer overflows would go unnoticed). */ unsigned char *copied_data = (unsigned char *)malloc(count); + memcpy(copied_data, afl_buffer, count); LLVMFuzzerTestOneInput(copied_data, count); free(copied_data); } diff --git a/test/ares-test-ai.h b/test/ares-test-ai.h new file mode 100644 index 0000000..7cf27e3 --- /dev/null +++ b/test/ares-test-ai.h @@ -0,0 +1,57 @@ +#ifndef ARES_TEST_AI_H +#define ARES_TEST_AI_H + +#include +#include "gtest/gtest.h" +#include "gmock/gmock.h" +#include "ares-test.h" + +namespace ares { +namespace test { + +class MockChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair > { + public: + MockChannelTestAI() : MockChannelOptsTest(1, GetParam().first, GetParam().second, nullptr, 0) {} +}; + +class MockUDPChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface { + public: + MockUDPChannelTestAI() : MockChannelOptsTest(1, GetParam(), false, nullptr, 0) {} +}; + +class MockTCPChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface { + public: + MockTCPChannelTestAI() : MockChannelOptsTest(1, GetParam(), true, nullptr, 0) {} +}; + + +// Test fixture that uses a default channel. +class DefaultChannelTestAI : public LibraryTest { + public: + DefaultChannelTestAI() : channel_(nullptr) { + EXPECT_EQ(ARES_SUCCESS, ares_init(&channel_)); + EXPECT_NE(nullptr, channel_); + } + + ~DefaultChannelTestAI() { + ares_destroy(channel_); + channel_ = nullptr; + } + + // Process all pending work on ares-owned file descriptors. + void Process(); + + protected: + ares_channel channel_; +}; + +} +} + +#endif diff --git a/test/ares-test-fuzz-name.c b/test/ares-test-fuzz-name.c new file mode 100644 index 0000000..378da37 --- /dev/null +++ b/test/ares-test-fuzz-name.c @@ -0,0 +1,23 @@ +#include +#include +#include + +#include "ares.h" +// Include ares internal file for DNS protocol constants +#include "nameser.h" + +// Entrypoint for Clang's libfuzzer, exercising query creation. +int LLVMFuzzerTestOneInput(const unsigned char *data, + unsigned long size) { + // Null terminate the data. + char *name = malloc(size + 1); + name[size] = '\0'; + memcpy(name, data, size); + + unsigned char *buf = NULL; + int buflen = 0; + ares_create_query(name, ns_c_in, ns_t_aaaa, 1234, 0, &buf, &buflen, 1024); + free(buf); + free(name); + return 0; +} diff --git a/test/ares-test-fuzz.c b/test/ares-test-fuzz.c index 528e76c..d7f54fc 100644 --- a/test/ares-test-fuzz.c +++ b/test/ares-test-fuzz.c @@ -4,7 +4,7 @@ // Entrypoint for Clang's libfuzzer int LLVMFuzzerTestOneInput(const unsigned char *data, - unsigned long size) { + unsigned long size) { // Feed the data into each of the ares_parse_*_reply functions. struct hostent *host = NULL; struct ares_addrttl info[5]; @@ -42,5 +42,14 @@ int LLVMFuzzerTestOneInput(const unsigned char *data, struct ares_soa_reply* soa = NULL; ares_parse_soa_reply(data, size, &soa); if (soa) ares_free_data(soa); + + struct ares_naptr_reply* naptr = NULL; + ares_parse_naptr_reply(data, size, &naptr); + if (naptr) ares_free_data(naptr); + + struct ares_caa_reply* caa = NULL; + ares_parse_caa_reply(data, size, &caa); + if (caa) ares_free_data(caa); + return 0; } diff --git a/test/ares-test-init.cc b/test/ares-test-init.cc index 66570ac..ff6c6c6 100644 --- a/test/ares-test-init.cc +++ b/test/ares-test-init.cc @@ -86,6 +86,8 @@ TEST_F(LibraryTest, OptionsChannelInit) { opts.lookups = strdup("b"); optmask |= ARES_OPT_LOOKUPS; optmask |= ARES_OPT_ROTATE; + opts.resolvconf_path = strdup("/etc/resolv.conf"); + optmask |= ARES_OPT_RESOLVCONF; ares_channel channel = nullptr; EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask)); @@ -112,6 +114,7 @@ TEST_F(LibraryTest, OptionsChannelInit) { EXPECT_EQ(std::string(opts.domains[0]), std::string(opts2.domains[0])); EXPECT_EQ(std::string(opts.domains[1]), std::string(opts2.domains[1])); EXPECT_EQ(std::string(opts.lookups), std::string(opts2.lookups)); + EXPECT_EQ(std::string(opts.resolvconf_path), std::string(opts2.resolvconf_path)); ares_destroy_options(&opts); ares_destroy_options(&opts2); @@ -169,6 +172,8 @@ TEST_F(LibraryTest, OptionsChannelAllocFail) { opts.lookups = strdup("b"); optmask |= ARES_OPT_LOOKUPS; optmask |= ARES_OPT_ROTATE; + opts.resolvconf_path = strdup("/etc/resolv.conf"); + optmask |= ARES_OPT_RESOLVCONF; ares_channel channel = nullptr; for (int ii = 1; ii <= 8; ii++) { @@ -396,6 +401,35 @@ CONTAINED_TEST_F(LibraryTest, ContainerFullResolvInit, return HasFailure(); } +// Allow path for resolv.conf to be configurable +NameContentList myresolvconf = { + {"/tmp/myresolv.cnf", " nameserver 1.2.3.4 \n" + "search first.com second.com\n" + "lookup bind\n" + "options debug ndots:5\n" + "sortlist 1.2.3.4/16 2.3.4.5\n"}}; +CONTAINED_TEST_F(LibraryTest, ContainerMyResolvConfInit, + "myhostname", "mydomain.org", myresolvconf) { + char filename[] = "/tmp/myresolv.cnf"; + ares_channel channel = nullptr; + struct ares_options options = {0}; + options.resolvconf_path = strdup(filename); + int optmask = ARES_OPT_RESOLVCONF; + EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &options, optmask)); + + optmask = 0; + free(options.resolvconf_path); + options.resolvconf_path = NULL; + + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel, &options, &optmask)); + EXPECT_EQ(ARES_OPT_RESOLVCONF, (optmask & ARES_OPT_RESOLVCONF)); + EXPECT_EQ(std::string(filename), std::string(options.resolvconf_path)); + + ares_destroy_options(&options); + ares_destroy(channel); + return HasFailure(); +} + NameContentList hostconf = { {"/etc/resolv.conf", "nameserver 1.2.3.4\n" "sortlist1.2.3.4\n" // malformed line @@ -435,6 +469,24 @@ CONTAINED_TEST_F(LibraryTest, ContainerSvcConfInit, return HasFailure(); } +NameContentList malformedresolvconflookup = { + {"/etc/resolv.conf", "nameserver 1.2.3.4\n" + "lookup garbage\n"}}; // malformed line +CONTAINED_TEST_F(LibraryTest, ContainerMalformedResolvConfLookup, + "myhostname", "mydomainname.org", malformedresolvconflookup) { + ares_channel channel = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_init(&channel)); + + struct ares_options opts; + int optmask = 0; + ares_save_options(channel, &opts, &optmask); + EXPECT_EQ(std::string("fb"), std::string(opts.lookups)); + ares_destroy_options(&opts); + + ares_destroy(channel); + return HasFailure(); +} + // Failures when expected config filenames are inaccessible. class MakeUnreadable { public: @@ -525,6 +577,36 @@ CONTAINED_TEST_F(LibraryTest, ContainerRotateOverride, return HasFailure(); } +// Test that blacklisted IPv6 resolves are ignored. They're filtered from any +// source, so resolv.conf is as good as any. +NameContentList blacklistedIpv6 = { + {"/etc/resolv.conf", " nameserver 254.192.1.1\n" // 0xfe.0xc0.0x01.0x01 + " nameserver fec0::dead\n" // Blacklisted + " nameserver ffc0::c001\n" // Not blacklisted + " domain first.com\n"}, + {"/etc/nsswitch.conf", "hosts: files\n"}}; +CONTAINED_TEST_F(LibraryTest, ContainerBlacklistedIpv6, + "myhostname", "mydomainname.org", blacklistedIpv6) { + ares_channel channel = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_init(&channel)); + std::vector actual = GetNameServers(channel); + std::vector expected = { + "254.192.1.1", + "ffc0:0000:0000:0000:0000:0000:0000:c001" + }; + EXPECT_EQ(expected, actual); + + struct ares_options opts; + int optmask = 0; + ares_save_options(channel, &opts, &optmask); + EXPECT_EQ(1, opts.ndomains); + EXPECT_EQ(std::string("first.com"), std::string(opts.domains[0])); + ares_destroy_options(&opts); + + ares_destroy(channel); + return HasFailure(); +} + NameContentList multiresolv = { {"/etc/resolv.conf", " nameserver 1::2 ; ;;\n" " domain first.com\n"}, diff --git a/test/ares-test-internal.cc b/test/ares-test-internal.cc index 91a5646..96d4ede 100644 --- a/test/ares-test-internal.cc +++ b/test/ares-test-internal.cc @@ -3,6 +3,11 @@ #include +#ifdef HAVE_UNISTD_H +#include +#endif +#include + extern "C" { // Remove command-line defines of package variables for the test project... #undef PACKAGE_NAME @@ -20,6 +25,9 @@ extern "C" { #ifdef HAVE_ARPA_INET_H #include #endif +#ifdef HAVE_SYS_UIO_H +# include +#endif } #include @@ -178,11 +186,22 @@ TEST_F(LibraryTest, FreeCorruptData) { } #ifndef CARES_SYMBOL_HIDING +TEST_F(LibraryTest, FreeLongChain) { + struct ares_addr_node *data = nullptr; + for (int ii = 0; ii < 100000; ii++) { + struct ares_addr_node *prev = (struct ares_addr_node*)ares_malloc_data(ARES_DATATYPE_ADDR_NODE); + prev->next = data; + data = prev; + } + + ares_free_data(data); +} + TEST(LibraryInit, StrdupFailures) { EXPECT_EQ(ARES_SUCCESS, ares_library_init(ARES_LIB_INIT_ALL)); char* copy = ares_strdup("string"); EXPECT_NE(nullptr, copy); - free(copy); + ares_free(copy); ares_library_cleanup(); } @@ -222,7 +241,7 @@ TEST(Misc, Bitncmp) { } TEST_F(LibraryTest, Casts) { - ssize_t ssz = 100; + ares_ssize_t ssz = 100; unsigned int u = 100; int i = 100; long l = 100; @@ -240,7 +259,7 @@ TEST_F(LibraryTest, ReadLine) { TempFile temp("abcde\n0123456789\nXYZ\n012345678901234567890\n\n"); FILE *fp = fopen(temp.filename(), "r"); size_t bufsize = 4; - char *buf = (char *)malloc(bufsize); + char *buf = (char *)ares_malloc(bufsize); EXPECT_EQ(ARES_SUCCESS, ares__read_line(fp, &buf, &bufsize)); EXPECT_EQ("abcde", std::string(buf)); @@ -253,7 +272,7 @@ TEST_F(LibraryTest, ReadLine) { EXPECT_EQ(nullptr, buf); fclose(fp); - free(buf); + ares_free(buf); } TEST_F(LibraryTest, ReadLineNoBuf) { @@ -275,7 +294,7 @@ TEST_F(LibraryTest, ReadLineNoBuf) { EXPECT_EQ("012345678901234567890", std::string(buf)); fclose(fp); - free(buf); + ares_free(buf); } TEST(Misc, GetHostent) { @@ -336,6 +355,118 @@ TEST_F(LibraryTest, GetHostentAllocFail) { } fclose(fp); } + +TEST_F(DefaultChannelTest, GetAddrInfoHostsPositive) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{example.com addr=[1.2.3.4]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsSpaces) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "google.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsByALias) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www2.google.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{www.google.com->google.com, www2.google.com->google.com addr=[2.3.4.5]}", ss.str()); +} + +TEST_F(DefaultChannelTest, GetAddrInfoHostsIPV6) { + TempFile hostsfile("1.2.3.4 example.com \n" + " 2.3.4.5\tgoogle.com www.google.com\twww2.google.com\n" + "#comment\n" + "4.5.6.7\n" + "1.3.5.7 \n" + "::1 ipv6.com"); + EnvValue with_env("CARES_HOSTS", hostsfile.filename()); + struct ares_addrinfo_hints hints = {}; + AddrInfoResult result = {}; + hints.ai_family = AF_INET6; + hints.ai_flags = ARES_AI_CANONNAME | ARES_AI_ENVHOSTS | ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "ipv6.com", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{ipv6.com addr=[[0000:0000:0000:0000:0000:0000:0000:0001]]}", ss.str()); +} + +TEST_F(LibraryTest, GetAddrInfoAllocFail) { + TempFile hostsfile("1.2.3.4 example.com alias1 alias2\n"); + struct ares_addrinfo_hints hints; + unsigned short port = 80; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; + + FILE *fp = fopen(hostsfile.filename(), "r"); + ASSERT_NE(nullptr, fp); + + for (int ii = 1; ii <= 3; ii++) { + rewind(fp); + ClearFails(); + SetAllocFail(ii); + struct ares_addrinfo ai; + EXPECT_EQ(ARES_ENOMEM, ares__readaddrinfo(fp, "example.com", port, &hints, &ai)) << ii; + } + fclose(fp); +} + +TEST(Misc, OnionDomain) { + EXPECT_EQ(0, ares__is_onion_domain("onion.no")); + EXPECT_EQ(0, ares__is_onion_domain(".onion.no")); + EXPECT_EQ(1, ares__is_onion_domain(".onion")); + EXPECT_EQ(1, ares__is_onion_domain(".onion.")); + EXPECT_EQ(1, ares__is_onion_domain("yes.onion")); + EXPECT_EQ(1, ares__is_onion_domain("yes.onion.")); + EXPECT_EQ(1, ares__is_onion_domain("YES.ONION")); + EXPECT_EQ(1, ares__is_onion_domain("YES.ONION.")); +} #endif #ifdef CARES_EXPOSE_STATICS @@ -353,23 +484,23 @@ TEST_F(LibraryTest, Striendstr) { const char *str = "plugh"; EXPECT_NE(nullptr, ares_striendstr(str, str)); } -extern "C" int single_domain(ares_channel, const char*, char**); +extern "C" int ares__single_domain(ares_channel, const char*, char**); TEST_F(DefaultChannelTest, SingleDomain) { TempFile aliases("www www.google.com\n"); EnvValue with_env("HOSTALIASES", aliases.filename()); SetAllocSizeFail(128); char *ptr = nullptr; - EXPECT_EQ(ARES_ENOMEM, single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); channel_->flags |= ARES_FLAG_NOSEARCH|ARES_FLAG_NOALIASES; - EXPECT_EQ(ARES_SUCCESS, single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_SUCCESS, ares__single_domain(channel_, "www", &ptr)); EXPECT_EQ("www", std::string(ptr)); - free(ptr); + ares_free(ptr); ptr = nullptr; SetAllocFail(1); - EXPECT_EQ(ARES_ENOMEM, single_domain(channel_, "www", &ptr)); + EXPECT_EQ(ARES_ENOMEM, ares__single_domain(channel_, "www", &ptr)); EXPECT_EQ(nullptr, ptr); } #endif @@ -383,5 +514,78 @@ TEST_F(DefaultChannelTest, SaveInvalidChannel) { channel_->nservers = saved; } +// Need to put this in own function due to nested lambda bug +// in VS2013. (C2888) +static int configure_socket(ares_socket_t s) { + // transposed from ares-process, simplified non-block setter. +#if defined(USE_BLOCKING_SOCKETS) + return 0; /* returns success */ +#elif defined(HAVE_FCNTL_O_NONBLOCK) + /* most recent unix versions */ + int flags; + flags = fcntl(s, F_GETFL, 0); + return fcntl(s, F_SETFL, flags | O_NONBLOCK); +#elif defined(HAVE_IOCTL_FIONBIO) + /* older unix versions */ + int flags = 1; + return ioctl(s, FIONBIO, &flags); +#elif defined(HAVE_IOCTLSOCKET_FIONBIO) +#ifdef WATT32 + char flags = 1; +#else + /* Windows */ + unsigned long flags = 1UL; +#endif + return ioctlsocket(s, FIONBIO, &flags); +#elif defined(HAVE_IOCTLSOCKET_CAMEL_FIONBIO) + /* Amiga */ + long flags = 1L; + return IoctlSocket(s, FIONBIO, flags); +#elif defined(HAVE_SETSOCKOPT_SO_NONBLOCK) + /* BeOS */ + long b = 1L; + return setsockopt(s, SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b)); +#else +# error "no non-blocking method was found/used/set" +#endif +} + +// TODO: This should not really be in this file, but we need ares config +// flags, and here they are available. +const struct ares_socket_functions VirtualizeIO::default_functions = { + [](int af, int type, int protocol, void *) -> ares_socket_t { + auto s = ::socket(af, type, protocol); + if (s == ARES_SOCKET_BAD) { + return s; + } + if (configure_socket(s) != 0) { + sclose(s); + return ares_socket_t(-1); + } + return s; + }, + [](ares_socket_t s, void * p) { + return :: sclose(s); + }, + [](ares_socket_t s, const struct sockaddr * addr, socklen_t len, void *) { + return ::connect(s, addr, len); + }, + [](ares_socket_t s, void * dst, size_t len, int flags, struct sockaddr * addr, socklen_t * alen, void *) -> ares_ssize_t { +#ifdef HAVE_RECVFROM + return ::recvfrom(s, reinterpret_cast(dst), len, flags, addr, alen); +#else + return sread(s, dst, len); +#endif + }, + [](ares_socket_t s, const struct iovec * vec, int len, void *) { +#ifndef HAVE_WRITEV + return ares_writev(s, vec, len); +#else + return :: writev(s, vec, len); +#endif + } +}; + + } // namespace test } // namespace ares diff --git a/test/ares-test-live.cc b/test/ares-test-live.cc index b8ff8eb..542cbc1 100644 --- a/test/ares-test-live.cc +++ b/test/ares-test-live.cc @@ -18,7 +18,71 @@ unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08}; unsigned char gdns_addr6[16] = {0x20, 0x01, 0x48, 0x60, 0x48, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x88}; -TEST_F(DefaultChannelTest, LiveGetHostByNameV4) { +MATCHER_P(IncludesAtLeastNumAddresses, n, "") { + if(!arg) + return false; + int cnt = 0; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + cnt++; + return cnt >= n; +} + +MATCHER_P(OnlyIncludesAddrType, addrtype, "") { + if(!arg) + return false; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + if (ai->ai_family != addrtype) + return false; + return true; +} + +MATCHER_P(IncludesAddrType, addrtype, "") { + if(!arg) + return false; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + if (ai->ai_family == addrtype) + return true; + return false; +} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV4) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_INET; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); + //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET)); +//} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoV6) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_INET6; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(1)); + //EXPECT_THAT(result.ai_, OnlyIncludesAddrType(AF_INET6)); +//} + +//VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetAddrInfoUnspec) { + //struct ares_addrinfo_hints hints = {}; + //hints.ai_family = AF_UNSPEC; + //AddrInfoResult result; + //ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + //Process(); + //EXPECT_TRUE(result.done_); + //EXPECT_EQ(ARES_SUCCESS, result.status_); + //EXPECT_THAT(result.ai_, IncludesAtLeastNumAddresses(2)); + //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET6)); + //EXPECT_THAT(result.ai_, IncludesAddrType(AF_INET)); +//} + +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByNameV4) { HostResult result; ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); Process(); @@ -28,7 +92,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByNameV4) { EXPECT_EQ(AF_INET, result.host_.addrtype_); } -TEST_F(DefaultChannelTest, LiveGetHostByNameV6) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByNameV6) { HostResult result; ares_gethostbyname(channel_, "www.google.com.", AF_INET6, HostCallback, &result); Process(); @@ -38,7 +102,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByNameV6) { EXPECT_EQ(AF_INET6, result.host_.addrtype_); } -TEST_F(DefaultChannelTest, LiveGetHostByAddrV4) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByAddrV4) { HostResult result; ares_gethostbyaddr(channel_, gdns_addr4, sizeof(gdns_addr4), AF_INET, HostCallback, &result); Process(); @@ -48,7 +112,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByAddrV4) { EXPECT_EQ(AF_INET, result.host_.addrtype_); } -TEST_F(DefaultChannelTest, LiveGetHostByAddrV6) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByAddrV6) { HostResult result; ares_gethostbyaddr(channel_, gdns_addr6, sizeof(gdns_addr6), AF_INET6, HostCallback, &result); Process(); @@ -58,7 +122,7 @@ TEST_F(DefaultChannelTest, LiveGetHostByAddrV6) { EXPECT_EQ(AF_INET6, result.host_.addrtype_); } -TEST_F(DefaultChannelTest, LiveGetHostByNameFile) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetHostByNameFile) { struct hostent *host = nullptr; // Still need a channel even to query /etc/hosts. @@ -150,8 +214,11 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV4) { EXPECT_EQ(ARES_SUCCESS, result.status_); EXPECT_LT(0, (int)result.host_.addrs_.size()); EXPECT_EQ(AF_INET, result.host_.addrtype_); - EXPECT_NE(std::string::npos, - result.host_.name_.find("localhost")); + // oddly, travis does not resolve to localhost, but a random hostname starting with travis-job + if (result.host_.name_.find("travis-job") == std::string::npos) { + EXPECT_NE(std::string::npos, + result.host_.name_.find("localhost")); + } } } @@ -167,8 +234,9 @@ TEST_P(DefaultChannelModeTest, LiveGetLocalhostByAddrV6) { EXPECT_EQ(ARES_SUCCESS, result.status_); EXPECT_LT(0, (int)result.host_.addrs_.size()); EXPECT_EQ(AF_INET6, result.host_.addrtype_); - EXPECT_NE(std::string::npos, - result.host_.name_.find("localhost")); + const std::string& name = result.host_.name_; + EXPECT_TRUE(std::string::npos != name.find("localhost") || + std::string::npos != name.find("ip6-loopback")); } } @@ -203,7 +271,7 @@ TEST_P(DefaultChannelModeTest, LiveGetHostByAddrFailAlloc) { INSTANTIATE_TEST_CASE_P(Modes, DefaultChannelModeTest, ::testing::Values("f", "b", "fb", "bf")); -TEST_F(DefaultChannelTest, LiveSearchA) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchA) { SearchResult result; ares_search(channel_, "www.youtube.com.", ns_c_in, ns_t_a, SearchCallback, &result); @@ -212,7 +280,7 @@ TEST_F(DefaultChannelTest, LiveSearchA) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchEmptyA) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchEmptyA) { SearchResult result; ares_search(channel_, "", ns_c_in, ns_t_a, SearchCallback, &result); @@ -221,7 +289,7 @@ TEST_F(DefaultChannelTest, LiveSearchEmptyA) { EXPECT_NE(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchNS) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchNS) { SearchResult result; ares_search(channel_, "google.com.", ns_c_in, ns_t_ns, SearchCallback, &result); @@ -230,7 +298,7 @@ TEST_F(DefaultChannelTest, LiveSearchNS) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchMX) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchMX) { SearchResult result; ares_search(channel_, "google.com.", ns_c_in, ns_t_mx, SearchCallback, &result); @@ -239,7 +307,7 @@ TEST_F(DefaultChannelTest, LiveSearchMX) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchTXT) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchTXT) { SearchResult result; ares_search(channel_, "google.com.", ns_c_in, ns_t_txt, SearchCallback, &result); @@ -248,7 +316,7 @@ TEST_F(DefaultChannelTest, LiveSearchTXT) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchSOA) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchSOA) { SearchResult result; ares_search(channel_, "google.com.", ns_c_in, ns_t_soa, SearchCallback, &result); @@ -257,7 +325,7 @@ TEST_F(DefaultChannelTest, LiveSearchSOA) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchSRV) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchSRV) { SearchResult result; ares_search(channel_, "_imap._tcp.gmail.com.", ns_c_in, ns_t_srv, SearchCallback, &result); @@ -266,7 +334,7 @@ TEST_F(DefaultChannelTest, LiveSearchSRV) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveSearchANY) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveSearchANY) { SearchResult result; ares_search(channel_, "google.com.", ns_c_in, ns_t_any, SearchCallback, &result); @@ -275,7 +343,7 @@ TEST_F(DefaultChannelTest, LiveSearchANY) { EXPECT_EQ(ARES_SUCCESS, result.status_); } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -291,7 +359,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4) { if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4NoPort) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NoPort) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -307,7 +375,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4NoPort) { if (verbose) std::cerr << "8.8.8.8:0 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4UnassignedPort) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4UnassignedPort) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -323,7 +391,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4UnassignedPort) { if (verbose) std::cerr << "8.8.8.8:4 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV6Both) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Both) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -339,7 +407,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV6Both) { if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV6Neither) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Neither) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -355,7 +423,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV6Neither) { if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4Numeric) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4Numeric) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -372,7 +440,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4Numeric) { if (verbose) std::cerr << "8.8.8.8:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV6Numeric) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6Numeric) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -389,7 +457,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV6Numeric) { if (verbose) std::cerr << "[2001:4860:4860::8888]:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV6LinkLocal) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6LinkLocal) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -408,7 +476,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV6LinkLocal) { if (verbose) std::cerr << "[fe80:102:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFound) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFound) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -426,7 +494,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFound) { if (verbose) std::cerr << "192.0.2.0:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFoundFail) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFoundFail) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -442,7 +510,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV4NotFoundFail) { EXPECT_EQ(ARES_ENOTFOUND, result.status_); } -TEST_F(DefaultChannelTest, LiveGetNameInfoV6NotFound) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoV6NotFound) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -462,7 +530,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoV6NotFound) { if (verbose) std::cerr << "[2001:db8:102::304]:53 => " << result.node_ << "/" << result.service_ << std::endl; } -TEST_F(DefaultChannelTest, LiveGetNameInvalidFamily) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFamily) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -477,7 +545,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInvalidFamily) { EXPECT_EQ(ARES_ENOTIMP, result.status_); } -TEST_F(DefaultChannelTest, LiveGetNameInvalidFlags) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInvalidFlags) { NameInfoResult result; struct sockaddr_in6 sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -493,7 +561,7 @@ TEST_F(DefaultChannelTest, LiveGetNameInvalidFlags) { EXPECT_EQ(ARES_EBADFLAGS, result.status_); } -TEST_F(DefaultChannelTest, LiveGetServiceInfo) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfo) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -510,7 +578,7 @@ TEST_F(DefaultChannelTest, LiveGetServiceInfo) { EXPECT_EQ("", result.node_); } -TEST_F(DefaultChannelTest, LiveGetServiceInfoNumeric) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetServiceInfoNumeric) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -528,7 +596,7 @@ TEST_F(DefaultChannelTest, LiveGetServiceInfoNumeric) { EXPECT_EQ("53", result.service_); } -TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) { +VIRT_NONVIRT_TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) { NameInfoResult result; struct sockaddr_in sockaddr; memset(&sockaddr, 0, sizeof(sockaddr)); @@ -544,8 +612,8 @@ TEST_F(DefaultChannelTest, LiveGetNameInfoAllocFail) { EXPECT_EQ(ARES_ENOMEM, result.status_); } -TEST_F(DefaultChannelTest, GetSock) { - ares_socket_t socks[3] = {-1, -1, -1}; +VIRT_NONVIRT_TEST_F(DefaultChannelTest, GetSock) { + ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; int bitmask = ares_getsock(channel_, socks, 3); EXPECT_EQ(0, bitmask); bitmask = ares_getsock(channel_, nullptr, 0); @@ -571,7 +639,7 @@ TEST_F(LibraryTest, GetTCPSock) { EXPECT_EQ(ARES_SUCCESS, ares_init_options(&channel, &opts, optmask)); EXPECT_NE(nullptr, channel); - ares_socket_t socks[3] = {-1, -1, -1}; + ares_socket_t socks[3] = {ARES_SOCKET_BAD, ARES_SOCKET_BAD, ARES_SOCKET_BAD}; int bitmask = ares_getsock(channel, socks, 3); EXPECT_EQ(0, bitmask); bitmask = ares_getsock(channel, nullptr, 0); @@ -590,5 +658,92 @@ TEST_F(LibraryTest, GetTCPSock) { ares_destroy(channel); } +TEST_F(DefaultChannelTest, VerifySocketFunctionCallback) { + VirtualizeIO vio(channel_); + + auto my_functions = VirtualizeIO::default_functions; + size_t count = 0; + + my_functions.asocket = [](int af, int type, int protocol, void * p) { + EXPECT_NE(nullptr, p); + (*reinterpret_cast(p))++; + return ::socket(af, type, protocol); + }; + + ares_set_socket_functions(channel_, &my_functions, &count); + + { + count = 0; + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_NE(0, count); + } + + { + count = 0; + ares_channel copy; + EXPECT_EQ(ARES_SUCCESS, ares_dup(©, channel_)); + + HostResult result; + ares_gethostbyname(copy, "www.google.com.", AF_INET, HostCallback, &result); + ProcessWork(copy, NoExtraFDs, nullptr); + EXPECT_TRUE(result.done_); + ares_destroy(copy); + EXPECT_NE(0, count); + } + +} + +TEST_F(DefaultChannelTest, LiveSetServers) { + struct ares_addr_node server1; + struct ares_addr_node server2; + server1.next = &server2; + server1.family = AF_INET; + server1.addr.addr4.s_addr = htonl(0x01020304); + server2.next = nullptr; + server2.family = AF_INET; + server2.addr.addr4.s_addr = htonl(0x02030405); + + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers(channel_, &server1)); + ares_cancel(channel_); +} + +TEST_F(DefaultChannelTest, LiveSetServersPorts) { + struct ares_addr_port_node server1; + struct ares_addr_port_node server2; + server1.next = &server2; + server1.family = AF_INET; + server1.addr.addr4.s_addr = htonl(0x01020304); + server1.udp_port = 111; + server1.tcp_port = 111; + server2.next = nullptr; + server2.family = AF_INET; + server2.addr.addr4.s_addr = htonl(0x02030405); + server2.udp_port = 0; + server2.tcp_port = 0;; + EXPECT_EQ(ARES_ENODATA, ares_set_servers_ports(nullptr, &server1)); + + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports(channel_, &server1)); + ares_cancel(channel_); +} + +TEST_F(DefaultChannelTest, LiveSetServersCSV) { + // Change not allowed while request is pending + HostResult result; + ares_gethostbyname(channel_, "www.google.com.", AF_INET, HostCallback, &result); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_csv(channel_, "1.2.3.4,2.3.4.5")); + EXPECT_EQ(ARES_ENOTIMP, ares_set_servers_ports_csv(channel_, "1.2.3.4:56,2.3.4.5:67")); + ares_cancel(channel_); +} + + } // namespace test } // namespace ares diff --git a/test/ares-test-main.cc b/test/ares-test-main.cc index f7e90cb..86ac96a 100644 --- a/test/ares-test-main.cc +++ b/test/ares-test-main.cc @@ -11,6 +11,12 @@ int main(int argc, char* argv[]) { } else if ((strcmp(argv[ii], "-p") == 0) && (ii + 1 < argc)) { ii++; ares::test::mock_port = atoi(argv[ii]); + } else if (strcmp(argv[ii], "-4") == 0) { + ares::test::families = ares::test::ipv4_family; + ares::test::families_modes = ares::test::ipv4_family_both_modes; + } else if (strcmp(argv[ii], "-6") == 0) { + ares::test::families = ares::test::ipv6_family; + ares::test::families_modes = ares::test::ipv6_family_both_modes; } else { gtest_argv.push_back(argv[ii]); } diff --git a/test/ares-test-misc.cc b/test/ares-test-misc.cc index 5e5bc0b..6fc28a8 100644 --- a/test/ares-test-misc.cc +++ b/test/ares-test-misc.cc @@ -206,6 +206,18 @@ TEST_F(LibraryTest, CreateQueryTrailingEscapedDot) { EXPECT_EQ("REQ QRY Q:{'example.com\\.' IN A}", actual); } +TEST_F(LibraryTest, CreateQueryNameTooLong) { + byte* p; + int len; + EXPECT_EQ(ARES_EBADNAME, + ares_create_query( + "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789." + "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789." + "a1234567890123456789.b1234567890123456789.c1234567890123456789.d1234567890123456789." + "x1234567890123456789.y1234567890123456789.", + ns_c_in, ns_t_a, 0x1234, 0, &p, &len, 0)); +} + TEST_F(LibraryTest, CreateQueryFailures) { byte* p; int len; @@ -244,6 +256,47 @@ TEST_F(LibraryTest, CreateQueryFailures) { if (p) ares_free_string(p); } +TEST_F(LibraryTest, CreateQueryOnionDomain) { + byte* p; + int len; + EXPECT_EQ(ARES_ENOTFOUND, + ares_create_query("dontleak.onion", ns_c_in, ns_t_a, 0x1234, 0, + &p, &len, 0)); +} + +TEST_F(DefaultChannelTest, HostByNameOnionDomain) { + HostResult result; + ares_gethostbyname(channel_, "dontleak.onion", AF_INET, HostCallback, &result); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTFOUND, result.status_); +} + +TEST_F(DefaultChannelTest, HostByNameFileOnionDomain) { + struct hostent *h; + EXPECT_EQ(ARES_ENOTFOUND, + ares_gethostbyname_file(channel_, "dontleak.onion", AF_INET, &h)); +} + +TEST_F(DefaultChannelTest, GetAddrinfoOnionDomain) { + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + ares_getaddrinfo(channel_, "dontleak.onion", NULL, &hints, AddrInfoCallback, &result); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTFOUND, result.status_); +} + +// Interesting question: should tacking on a search domain let the query +// through? It seems safer to reject it because "supersecret.onion.search" +// still leaks information about the query to malicious resolvers. +TEST_F(DefaultChannelTest, SearchOnionDomain) { + SearchResult result; + ares_search(channel_, "dontleak.onion", ns_c_in, ns_t_a, + SearchCallback, &result); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTFOUND, result.status_); +} + TEST_F(DefaultChannelTest, SendFailure) { unsigned char buf[2]; SearchResult result; @@ -264,7 +317,7 @@ std::string ExpandName(const std::vector& data, int offset, } else { result = ""; } - free(name); + ares_free_string(name); return result; } @@ -455,7 +508,7 @@ TEST_F(LibraryTest, ExpandString) { (unsigned char**)&result, &len)); EXPECT_EQ("abc", std::string(result)); EXPECT_EQ(1 + 3, len); // amount of data consumed includes 1 byte len - free(result); + ares_free_string(result); result = nullptr; EXPECT_EQ(ARES_EBADSTR, ares_expand_string(s1.data() + 1, s1.data(), s1.size(), diff --git a/test/ares-test-mock-ai.cc b/test/ares-test-mock-ai.cc new file mode 100644 index 0000000..733a085 --- /dev/null +++ b/test/ares-test-mock-ai.cc @@ -0,0 +1,777 @@ +#include "ares-test-ai.h" +#include "dns-proto.h" + +#ifdef HAVE_NETINET_IN_H +#include +#endif + +#include +#include + +using testing::InvokeWithoutArgs; +using testing::DoAll; + +namespace ares { +namespace test { + +MATCHER_P(IncludesNumAddresses, n, "") { + if(!arg) + return false; + int cnt = 0; + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) + cnt++; + return n == cnt; +} + +MATCHER_P(IncludesV4Address, address, "") { + if(!arg) + return false; + in_addr addressnum = {}; + if (!ares_inet_pton(AF_INET, address, &addressnum)) + return false; // wrong number format? + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET) + continue; + if (reinterpret_cast(ai->ai_addr)->sin_addr.s_addr == + addressnum.s_addr) + return true; // found + } + return false; +} + +MATCHER_P(IncludesV6Address, address, "") { + if(!arg) + return false; + in6_addr addressnum = {}; + if (!ares_inet_pton(AF_INET6, address, &addressnum)) { + return false; // wrong number format? + } + for (const ares_addrinfo_node* ai = arg->nodes; ai != NULL; ai = ai->ai_next) { + if (ai->ai_family != AF_INET6) + continue; + if (!memcmp( + reinterpret_cast(ai->ai_addr)->sin6_addr.s6_addr, + addressnum.s6_addr, sizeof(addressnum.s6_addr))) + return true; // found + } + return false; +} + +// UDP only so mock server doesn't get confused by concatenated requests +TEST_P(MockUDPChannelTestAI, GetAddrInfoParallelLookups) { + DNSPacket rsp1; + rsp1.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp1)); + DNSPacket rsp2; + rsp2.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {1, 2, 3, 4})); + ON_CALL(server_, OnRequest("www.example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp2)); + + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + AddrInfoResult result1; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result1); + AddrInfoResult result2; + ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result2); + AddrInfoResult result3; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result3); + Process(); + + EXPECT_TRUE(result1.done_); + EXPECT_EQ(result1.status_, ARES_SUCCESS); + EXPECT_THAT(result1.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result1.ai_, IncludesV4Address("2.3.4.5")); + + EXPECT_TRUE(result2.done_); + EXPECT_EQ(result2.status_, ARES_SUCCESS); + EXPECT_THAT(result2.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result2.ai_, IncludesV4Address("1.2.3.4")); + + EXPECT_TRUE(result3.done_); + EXPECT_EQ(result3.status_, ARES_SUCCESS); + EXPECT_THAT(result3.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result3.ai_, IncludesV4Address("2.3.4.5")); +} + +// UDP to TCP specific test +TEST_P(MockUDPChannelTestAI, TruncationRetry) { + DNSPacket rsptruncated; + rsptruncated.set_response().set_aa().set_tc() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + DNSPacket rspok; + rspok.set_response() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsptruncated)) + .WillOnce(SetReply(&server_, &rspok)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(result.status_, ARES_SUCCESS); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); +} + +// TCP only to prevent retries +TEST_P(MockTCPChannelTestAI, MalformedResponse) { + std::vector one = {0x01}; + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReplyData(&server_, one)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ETIMEOUT, result.status_); +} + +TEST_P(MockTCPChannelTestAI, FormErrResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_formerr); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_EFORMERR, result.status_); +} + +TEST_P(MockTCPChannelTestAI, ServFailResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_servfail); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so SERVFAIL consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, NotImplResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_notimpl); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so NOTIMPL consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, RefusedResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_refused); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + // ARES_FLAG_NOCHECKRESP not set, so REFUSED consumed + EXPECT_EQ(ARES_ECONNREFUSED, result.status_); +} + +TEST_P(MockTCPChannelTestAI, YXDomainResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_yxdomain); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENODATA, result.status_); +} + +class MockExtraOptsTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair > { + public: + MockExtraOptsTestAI() + : MockChannelOptsTest(1, GetParam().first, GetParam().second, + FillOptions(&opts_), + ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF) {} + static struct ares_options* FillOptions(struct ares_options * opts) { + memset(opts, 0, sizeof(struct ares_options)); + // Set a few options that affect socket communications + opts->socket_send_buffer_size = 514; + opts->socket_receive_buffer_size = 514; + return opts; + } + private: + struct ares_options opts_; +}; + +TEST_P(MockExtraOptsTestAI, SimpleQuery) { + ares_set_local_ip4(channel_, 0x7F000001); + byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + ares_set_local_ip6(channel_, addr6); + ares_set_local_dev(channel_, "dummy"); + + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_SUCCESS, result.status_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +class MockExtraOptsNDotsTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair > { + public: + MockExtraOptsNDotsTestAI(int ndots) + : MockChannelOptsTest(1, GetParam().first, GetParam().second, + FillOptions(&opts_, ndots), + ARES_OPT_SOCK_SNDBUF|ARES_OPT_SOCK_RCVBUF|ARES_OPT_NDOTS) {} + static struct ares_options* FillOptions(struct ares_options * opts, int ndots) { + memset(opts, 0, sizeof(struct ares_options)); + // Set a few options that affect socket communications + opts->socket_send_buffer_size = 514; + opts->socket_receive_buffer_size = 514; + opts->ndots = ndots; + return opts; + } + private: + struct ares_options opts_; +}; + +class MockExtraOptsNDots5TestAI : public MockExtraOptsNDotsTestAI { + public: + MockExtraOptsNDots5TestAI() : MockExtraOptsNDotsTestAI(5) {} +}; + +TEST_P(MockExtraOptsNDots5TestAI, SimpleQuery) { + ares_set_local_ip4(channel_, 0x7F000001); + byte addr6[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}; + ares_set_local_ip6(channel_, addr6); + ares_set_local_dev(channel_, "dummy"); + + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("dynamodb.us-east-1.amazonaws.com", ns_t_a)) + .add_answer(new DNSARR("dynamodb.us-east-1.amazonaws.com", 100, {123, 45, 67, 8})); + ON_CALL(server_, OnRequest("dynamodb.us-east-1.amazonaws.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "dynamodb.us-east-1.amazonaws.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_SUCCESS, result.status_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("123.45.67.8")); +} + +class MockFlagsChannelOptsTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair > { + public: + MockFlagsChannelOptsTestAI(int flags) + : MockChannelOptsTest(1, GetParam().first, GetParam().second, + FillOptions(&opts_, flags), ARES_OPT_FLAGS) {} + static struct ares_options* FillOptions(struct ares_options * opts, int flags) { + memset(opts, 0, sizeof(struct ares_options)); + opts->flags = flags; + return opts; + } + private: + struct ares_options opts_; +}; + +class MockNoCheckRespChannelTestAI : public MockFlagsChannelOptsTestAI { + public: + MockNoCheckRespChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_NOCHECKRESP) {} +}; + +TEST_P(MockNoCheckRespChannelTestAI, ServFailResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_servfail); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ESERVFAIL, result.status_); +} + +TEST_P(MockNoCheckRespChannelTestAI, NotImplResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_notimpl); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENOTIMP, result.status_); +} + +TEST_P(MockNoCheckRespChannelTestAI, RefusedResponse) { + DNSPacket rsp; + rsp.set_response().set_aa() + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + rsp.set_rcode(ns_r_refused); + ON_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_EREFUSED, result.status_); +} + +TEST_P(MockChannelTestAI, FamilyV6) { + DNSPacket rsp6; + rsp6.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_aaaa)) + .add_answer(new DNSAaaaRR("example.com", 100, + {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); + ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &rsp6)); + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET6; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); +} + +TEST_P(MockChannelTestAI, FamilyV4) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +TEST_P(MockChannelTestAI, FamilyV4_MultipleAddresses) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})) + .add_answer(new DNSARR("example.com", 100, {7, 8, 9, 0})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{addr=[2.3.4.5], addr=[7.8.9.0]}", ss.str()); +} + +TEST_P(MockChannelTestAI, FamilyUnspecified) { + DNSPacket rsp6; + rsp6.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_aaaa)) + .add_answer(new DNSAaaaRR("example.com", 100, + {0x21, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03})); + ON_CALL(server_, OnRequest("example.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &rsp6)); + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com.", NULL, &hints, + AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(2)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); + EXPECT_THAT(result.ai_, IncludesV6Address("2121:0000:0000:0000:0000:0000:0000:0303")); +} + +class MockEDNSChannelTestAI : public MockFlagsChannelOptsTestAI { + public: + MockEDNSChannelTestAI() : MockFlagsChannelOptsTestAI(ARES_FLAG_EDNS) {} +}; + +TEST_P(MockEDNSChannelTestAI, RetryWithoutEDNS) { + DNSPacket rspfail; + rspfail.set_response().set_aa().set_rcode(ns_r_formerr) + .add_question(new DNSQuestion("www.google.com", ns_t_a)); + DNSPacket rspok; + rspok.set_response() + .add_question(new DNSQuestion("www.google.com", ns_t_a)) + .add_answer(new DNSARR("www.google.com", 100, {1, 2, 3, 4})); + EXPECT_CALL(server_, OnRequest("www.google.com", ns_t_a)) + .WillOnce(SetReply(&server_, &rspfail)) + .WillOnce(SetReply(&server_, &rspok)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.google.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("1.2.3.4")); +} + +TEST_P(MockChannelTestAI, SearchDomains) { + DNSPacket nofirst; + nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_a)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &nofirst)); + DNSPacket nosecond; + nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.second.org", ns_t_a)); + ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) + .WillByDefault(SetReply(&server_, &nosecond)); + DNSPacket yesthird; + yesthird.set_response().set_aa() + .add_question(new DNSQuestion("www.third.gov", ns_t_a)) + .add_answer(new DNSARR("www.third.gov", 0x0200, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) + .WillByDefault(SetReply(&server_, &yesthird)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +TEST_P(MockChannelTestAI, SearchDomainsServFailOnAAAA) { + DNSPacket nofirst; + nofirst.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &nofirst)); + DNSPacket nofirst4; + nofirst4.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.first.com", ns_t_a)); + ON_CALL(server_, OnRequest("www.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &nofirst4)); + + DNSPacket nosecond; + nosecond.set_response().set_aa().set_rcode(ns_r_nxdomain) + .add_question(new DNSQuestion("www.second.org", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.second.org", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &nosecond)); + DNSPacket yessecond4; + yessecond4.set_response().set_aa() + .add_question(new DNSQuestion("www.second.org", ns_t_a)) + .add_answer(new DNSARR("www.second.org", 0x0200, {2, 3, 4, 5})); + ON_CALL(server_, OnRequest("www.second.org", ns_t_a)) + .WillByDefault(SetReply(&server_, &yessecond4)); + + DNSPacket failthird; + failthird.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.third.gov", ns_t_aaaa)); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_aaaa)) + .WillByDefault(SetReply(&server_, &failthird)); + DNSPacket failthird4; + failthird4.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.third.gov", ns_t_a)); + ON_CALL(server_, OnRequest("www.third.gov", ns_t_a)) + .WillByDefault(SetReply(&server_, &failthird4)); + + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_UNSPEC; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); +} + +class MockMultiServerChannelTestAI + : public MockChannelOptsTest, + public ::testing::WithParamInterface< std::pair > { + public: + MockMultiServerChannelTestAI(bool rotate) + : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {} + void CheckExample() { + AddrInfoResult result; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "www.example.com.", NULL, &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(result.status_, ARES_SUCCESS); + EXPECT_THAT(result.ai_, IncludesNumAddresses(1)); + EXPECT_THAT(result.ai_, IncludesV4Address("2.3.4.5")); + } +}; + +class RotateMultiMockTestAI : public MockMultiServerChannelTestAI { + public: + RotateMultiMockTestAI() : MockMultiServerChannelTestAI(true) {} +}; + +class NoRotateMultiMockTestAI : public MockMultiServerChannelTestAI { + public: + NoRotateMultiMockTestAI() : MockMultiServerChannelTestAI(false) {} +}; + + +TEST_P(RotateMultiMockTestAI, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + + DNSPacket servfailrsp; + servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket notimplrsp; + notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket okrsp; + okrsp.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); + + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Second time around, starts from server [1]. + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), &servfailrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), ¬implrsp)); + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &okrsp)); + CheckExample(); + + // Third time around, starts from server [2]. + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &servfailrsp)); + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), ¬implrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), &okrsp)); + CheckExample(); +} + +TEST_P(NoRotateMultiMockTestAI, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + + DNSPacket servfailrsp; + servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket notimplrsp; + notimplrsp.set_response().set_aa().set_rcode(ns_r_notimpl) + .add_question(new DNSQuestion("www.example.com", ns_t_a)); + DNSPacket okrsp; + okrsp.set_response().set_aa() + .add_question(new DNSQuestion("www.example.com", ns_t_a)) + .add_answer(new DNSARR("www.example.com", 100, {2,3,4,5})); + + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Second time around, still starts from server [0]. + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); + + // Third time around, still starts from server [0]. + EXPECT_CALL(*servers_[0], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[0].get(), &servfailrsp)); + EXPECT_CALL(*servers_[1], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[1].get(), ¬implrsp)); + EXPECT_CALL(*servers_[2], OnRequest("www.example.com", ns_t_a)) + .WillOnce(SetReply(servers_[2].get(), &okrsp)); + CheckExample(); +} + +TEST_P(MockChannelTestAI, FamilyV4ServiceName) { + DNSPacket rsp4; + rsp4.set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_a)) + .add_answer(new DNSARR("example.com", 100, {1, 1, 1, 1})) + .add_answer(new DNSARR("example.com", 100, {2, 2, 2, 2})); + ON_CALL(server_, OnRequest("example.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &rsp4)); + AddrInfoResult result = {}; + struct ares_addrinfo_hints hints = {}; + hints.ai_family = AF_INET; + hints.ai_flags = ARES_AI_NOSORT; + ares_getaddrinfo(channel_, "example.com", "http", &hints, AddrInfoCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + std::stringstream ss; + ss << result.ai_; + EXPECT_EQ("{addr=[1.1.1.1:80], addr=[2.2.2.2:80]}", ss.str()); +} + +// force-tcp does currently not work, possibly test DNS server swallows +// bytes from second query +//INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, +// ::testing::ValuesIn(ares::test::families_modes)); +//const std::vector> both_families_udponly = { +// std::make_pair(AF_INET, false), +// std::make_pair(AF_INET6, false) +//}; +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockChannelTestAI, + ::testing::Values(std::make_pair(AF_INET, false))); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockUDPChannelTestAI, + ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockTCPChannelTestAI, + ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockExtraOptsNDots5TestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockNoCheckRespChannelTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamiliesAI, MockEDNSChannelTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(TransportModesAI, RotateMultiMockTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(TransportModesAI, NoRotateMultiMockTestAI, + ::testing::ValuesIn(ares::test::families_modes)); + + +} // namespace test +} // namespace ares diff --git a/test/ares-test-mock.cc b/test/ares-test-mock.cc index 2cbe6b4..d2c579f 100644 --- a/test/ares-test-mock.cc +++ b/test/ares-test-mock.cc @@ -51,7 +51,7 @@ TEST_P(MockChannelTest, Basic) { } // UDP only so mock server doesn't get confused by concatenated requests -TEST_P(MockUDPChannelTest, ParallelLookups) { +TEST_P(MockUDPChannelTest, GetHostByNameParallelLookups) { DNSPacket rsp1; rsp1.set_response().set_aa() .add_question(new DNSQuestion("www.google.com", ns_t_a)) @@ -395,7 +395,7 @@ class MockEDNSChannelTest : public MockFlagsChannelOptsTest { TEST_P(MockEDNSChannelTest, RetryWithoutEDNS) { DNSPacket rspfail; - rspfail.set_response().set_aa().set_rcode(ns_r_servfail) + rspfail.set_response().set_aa().set_rcode(ns_r_formerr) .add_question(new DNSQuestion("www.google.com", ns_t_a)); DNSPacket rspok; rspok.set_response() @@ -883,6 +883,18 @@ TEST_P(MockChannelTest, CancelImmediate) { EXPECT_EQ(0, result.timeouts_); } +TEST_P(MockChannelTest, CancelImmediateGetHostByAddr) { + HostResult result; + struct in_addr addr; + addr.s_addr = htonl(0x08080808); + + ares_gethostbyaddr(channel_, &addr, sizeof(addr), AF_INET, HostCallback, &result); + ares_cancel(channel_); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ECANCELLED, result.status_); + EXPECT_EQ(0, result.timeouts_); +} + // Relies on retries so is UDP-only TEST_P(MockUDPChannelTest, CancelLater) { std::vector nothing; @@ -924,6 +936,21 @@ TEST_P(MockChannelTest, GetHostByNameDestroyRelative) { EXPECT_EQ(0, result.timeouts_); } +TEST_P(MockChannelTest, GetHostByNameCNAMENoData) { + DNSPacket response; + response.set_response().set_aa() + .add_question(new DNSQuestion("cname.first.com", ns_t_a)) + .add_answer(new DNSCnameRR("cname.first.com", 100, "a.first.com")); + ON_CALL(server_, OnRequest("cname.first.com", ns_t_a)) + .WillByDefault(SetReply(&server_, &response)); + + HostResult result; + ares_gethostbyname(channel_, "cname.first.com", AF_INET, HostCallback, &result); + Process(); + EXPECT_TRUE(result.done_); + EXPECT_EQ(ARES_ENODATA, result.status_); +} + TEST_P(MockChannelTest, GetHostByAddrDestroy) { unsigned char gdns_addr4[4] = {0x08, 0x08, 0x08, 0x08}; HostResult result; @@ -1013,7 +1040,7 @@ class MockMultiServerChannelTest public ::testing::WithParamInterface< std::pair > { public: MockMultiServerChannelTest(bool rotate) - : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : 0) {} + : MockChannelOptsTest(3, GetParam().first, GetParam().second, nullptr, rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE) {} void CheckExample() { HostResult result; ares_gethostbyname(channel_, "www.example.com.", AF_INET, HostCallback, &result); @@ -1037,6 +1064,12 @@ class NoRotateMultiMockTest : public MockMultiServerChannelTest { TEST_P(RotateMultiMockTest, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(0, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + DNSPacket servfailrsp; servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) .add_question(new DNSQuestion("www.example.com", ns_t_a)); @@ -1076,6 +1109,12 @@ TEST_P(RotateMultiMockTest, ThirdServer) { } TEST_P(NoRotateMultiMockTest, ThirdServer) { + struct ares_options opts = {0}; + int optmask = 0; + EXPECT_EQ(ARES_SUCCESS, ares_save_options(channel_, &opts, &optmask)); + EXPECT_EQ(ARES_OPT_NOROTATE, (optmask & ARES_OPT_NOROTATE)); + ares_destroy_options(&opts); + DNSPacket servfailrsp; servfailrsp.set_response().set_aa().set_rcode(ns_r_servfail) .add_question(new DNSQuestion("www.example.com", ns_t_a)); @@ -1114,48 +1153,21 @@ TEST_P(NoRotateMultiMockTest, ThirdServer) { CheckExample(); } +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, ::testing::ValuesIn(ares::test::families)); + +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, ::testing::ValuesIn(ares::test::families_modes)); + +INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes)); -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockChannelTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); - -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockUDPChannelTest, - ::testing::Values(AF_INET, AF_INET6)); - -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockTCPChannelTest, - ::testing::Values(AF_INET, AF_INET6)); - -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockExtraOptsTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); - -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockNoCheckRespChannelTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); - -INSTANTIATE_TEST_CASE_P(AddressFamilies, MockEDNSChannelTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); - -INSTANTIATE_TEST_CASE_P(TransportModes, RotateMultiMockTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); - -INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, - ::testing::Values(std::make_pair(AF_INET, false), - std::make_pair(AF_INET, true), - std::make_pair(AF_INET6, false), - std::make_pair(AF_INET6, true))); +INSTANTIATE_TEST_CASE_P(TransportModes, NoRotateMultiMockTest, ::testing::ValuesIn(ares::test::families_modes)); } // namespace test } // namespace ares diff --git a/test/ares-test-parse-a.cc b/test/ares-test-parse-a.cc index 77d9591..7f6a987 100644 --- a/test/ares-test-parse-a.cc +++ b/test/ares-test-parse-a.cc @@ -11,13 +11,14 @@ TEST_F(LibraryTest, ParseAReplyOK) { DNSPacket pkt; pkt.set_qid(0x1234).set_response().set_aa() .add_question(new DNSQuestion("example.com", ns_t_a)) - .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})); + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) + .add_answer(new DNSAaaaRR("example.com", 0x01020304, {0,0,0,0,0,0,0,0,0,0,0,0,2,3,4,5})); std::vector data = { 0x12, 0x34, // qid 0x84, // response + query + AA + not-TC + not-RD 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError 0x00, 0x01, // num questions - 0x00, 0x01, // num answer RRs + 0x00, 0x02, // num answer RRs 0x00, 0x00, // num authority RRs 0x00, 0x00, // num additional RRs // Question @@ -35,6 +36,15 @@ TEST_F(LibraryTest, ParseAReplyOK) { 0x01, 0x02, 0x03, 0x04, // TTL 0x00, 0x04, // rdata length 0x02, 0x03, 0x04, 0x05, + // Answer 2 + 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 0x03, 'c', 'o', 'm', + 0x00, + 0x00, 0x1c, // RR type + 0x00, 0x01, // class IN + 0x01, 0x02, 0x03, 0x04, // TTL + 0x00, 0x10, // rdata length + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x04, 0x05, }; EXPECT_EQ(data, pkt.data()); struct hostent *host = nullptr; @@ -68,7 +78,7 @@ TEST_F(LibraryTest, ParseMalformedAReply) { 0x84, // [2] response + query + AA + not-TC + not-RD 0x00, // [3] not-RA + not-Z + not-AD + not-CD + rc=NoError 0x00, 0x01, // [4:6) num questions - 0x00, 0x01, // [6:8) num answer RRs + 0x00, 0x02, // [6:8) num answer RRs 0x00, 0x00, // [8:10) num authority RRs 0x00, 0x00, // [10:12) num additional RRs // Question @@ -121,10 +131,16 @@ TEST_F(LibraryTest, ParseAReplyNoData) { // Again but with a CNAME. pkt.add_answer(new DNSCnameRR("example.com", 200, "c.example.com")); - EXPECT_EQ(ARES_ENODATA, ares_parse_a_reply(data.data(), data.size(), + data = pkt.data(); + // Expect success as per https://github.com/c-ares/c-ares/commit/2c63440127feed70ccefb148b8f938a2df6c15f8 + EXPECT_EQ(ARES_SUCCESS, ares_parse_a_reply(data.data(), data.size(), &host, info, &count)); EXPECT_EQ(0, count); - EXPECT_EQ(nullptr, host); + EXPECT_NE(nullptr, host); + std::stringstream ss; + ss << HostEnt(host); + EXPECT_EQ("{'c.example.com' aliases=[example.com] addrs=[]}", ss.str()); + ares_free_hostent(host); } TEST_F(LibraryTest, ParseAReplyVariantA) { diff --git a/test/ares-test-parse-aaaa.cc b/test/ares-test-parse-aaaa.cc index 9d0457e..1314c83 100644 --- a/test/ares-test-parse-aaaa.cc +++ b/test/ares-test-parse-aaaa.cc @@ -13,7 +13,8 @@ TEST_F(LibraryTest, ParseAaaaReplyOK) { .add_question(new DNSQuestion("example.com", ns_t_aaaa)) .add_answer(new DNSAaaaRR("example.com", 100, {0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, - 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04})); + 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04})) + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})); std::vector data = pkt.data(); struct hostent *host = nullptr; struct ares_addr6ttl info[5]; diff --git a/test/ares-test-parse-caa.cc b/test/ares-test-parse-caa.cc new file mode 100644 index 0000000..99903ed --- /dev/null +++ b/test/ares-test-parse-caa.cc @@ -0,0 +1,113 @@ +#include "ares-test.h" +#include "dns-proto.h" + +#include +#include + +namespace ares { +namespace test { + +TEST_F(LibraryTest, ParseCaaReplyMultipleOK) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x09, 0x77, 0x69, 0x6B, // '............wik + 0x69, 0x70, 0x65, 0x64, 0x69, 0x61, 0x03, 0x6F, 0x72, 0x67, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, // ipedia.org...... + 0x0C, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x23, 0x00, 0x15, 0x00, 0x05, 0x69, 0x73, 0x73, // ........#....iss + 0x75, 0x65, 0x67, 0x6C, 0x6F, 0x62, 0x61, 0x6C, 0x73, 0x69, 0x67, 0x6E, 0x2E, 0x63, 0x6F, 0x6D, // ueglobalsign.com + 0xC0, 0x0C, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x23, 0x00, 0x13, 0x00, 0x05, 0x69, 0x73, // .........#....is + 0x73, 0x75, 0x65, 0x64, 0x69, 0x67, 0x69, 0x63, 0x65, 0x72, 0x74, 0x2E, 0x63, 0x6F, 0x6D, 0xC0, // suedigicert.com. + 0x0C, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x23, 0x00, 0x16, 0x00, 0x05, 0x69, 0x73, 0x73, // ........#....iss + 0x75, 0x65, 0x6C, 0x65, 0x74, 0x73, 0x65, 0x6E, 0x63, 0x72, 0x79, 0x70, 0x74, 0x2E, 0x6F, 0x72, // ueletsencrypt.or + 0x67, 0xC0, 0x0C, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x02, 0x23, 0x00, 0x25, 0x00, 0x05, 0x69, // g.........#.%..i + 0x6F, 0x64, 0x65, 0x66, 0x6D, 0x61, 0x69, 0x6C, 0x74, 0x6F, 0x3A, 0x64, 0x6E, 0x73, 0x2D, 0x61, // odefmailto:dns-a + 0x64, 0x6D, 0x69, 0x6E, 0x40, 0x77, 0x69, 0x6B, 0x69, 0x6D, 0x65, 0x64, 0x69, 0x61, 0x2E, 0x6F, // dmin@wikimedia.o + 0x72, 0x67 // rg + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_NE(nullptr, caa); + ASSERT_NE(nullptr, caa->next); + ASSERT_NE(nullptr, caa->next->next); + ASSERT_NE(nullptr, caa->next->next->next); + + ares_free_data(caa); +} + +TEST_F(LibraryTest, ParseCaaReplySingleOK) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, // '............goo + 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, 0x0C, 0x01, 0x01, // gle.com......... + 0x00, 0x01, 0x00, 0x01, 0x43, 0xBE, 0x00, 0x0F, 0x00, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x70, // ....C.....issuep + 0x6B, 0x69, 0x2E, 0x67, 0x6F, 0x6F, 0x67 // ki.goog + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_NE(nullptr, caa); + + EXPECT_EQ(caa->critical, 0); + EXPECT_EQ(caa->plength, 5); + EXPECT_STREQ((char *)caa->property, "issue"); + EXPECT_EQ(caa->length, 8); + EXPECT_STREQ((char *)caa->value, "pki.goog"); + + ares_free_data(caa); +} + +TEST_F(LibraryTest, ParseCaaBogusReply1) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, // '............goo + 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, 0x0C, 0x01, 0x01, // gle.com......... + 0x00, 0x01, 0x00, 0x01, 0x43, 0xBE, 0x00, 0x0F, 0x00, 0x00, 0x69, 0x73, 0x73, 0x75, 0x65, 0x70, // ....C.....issuep + 0x6B, 0x69, 0x2E, 0x67, 0x6F, 0x6F, 0x67 // ki.goog + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_EBADRESP, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_EQ(nullptr, caa); +} + +TEST_F(LibraryTest, ParseCaaBogusReply2) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, // '............goo + 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, 0x0C, 0x01, 0x01, // gle.com......... + 0x00, 0x01, 0x00, 0x01, 0x43, 0xBE, 0x00, 0x0F, 0x00, 0x0e, 0x69, 0x73, 0x73, 0x75, 0x65, 0x70, // ....C.....issuep + 0x6B, 0x69, 0x2E, 0x67, 0x6F, 0x6F, 0x67 // ki.goog + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_EBADRESP, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_EQ(nullptr, caa); +} + +TEST_F(LibraryTest, ParseCaaBogusReply3) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x06, 0x67, 0x6F, 0x6F, // '............goo + 0x67, 0x6C, 0x65, 0x03, 0x63, 0x6F, 0x6D, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, 0x0C, 0x01, 0x01, // gle.com......... + 0x00, 0x01, 0x00, 0x01, 0x43, 0xBE, 0x00, 0x10, 0x00, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x70, // ....C.....issuep + 0x6B, 0x69, 0x2E, 0x67, 0x6F, 0x6F, 0x67 // ki.goog + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_EBADRESP, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_EQ(nullptr, caa); +} + +TEST_F(LibraryTest, ParseCaaEmptyReply) { + std::vector data = { + 0x27, 0x86, 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x09, 0x77, 0x69, 0x6B, // '............wik + 0x69, 0x70, 0x65, 0x64, 0x69, 0x61, 0x02, 0x64, 0x65, 0x00, 0x01, 0x01, 0x00, 0x01, 0xC0, 0x0C, // ipedia.de....... + 0x00, 0x06, 0x00, 0x01, 0x00, 0x00, 0x02, 0x58, 0x00, 0x3B, 0x04, 0x6E, 0x73, 0x38, 0x31, 0x0D, // .......X.;.ns81. + 0x64, 0x6F, 0x6D, 0x61, 0x69, 0x6E, 0x63, 0x6F, 0x6E, 0x74, 0x72, 0x6F, 0x6C, 0x03, 0x63, 0x6F, // domaincontrol.co + 0x6D, 0x00, 0x03, 0x64, 0x6E, 0x73, 0x05, 0x6A, 0x6F, 0x6D, 0x61, 0x78, 0x03, 0x6E, 0x65, 0x74, // m..dns.jomax.net + 0x00, 0x78, 0x67, 0xFE, 0x34, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x09, 0x3A, // .xg.4..p.... ..: + 0x80, 0x00, 0x00, 0x02, 0x58 // ....X + }; + + struct ares_caa_reply* caa = nullptr; + EXPECT_EQ(ARES_ENODATA, ares_parse_caa_reply(data.data(), data.size(), &caa)); + ASSERT_EQ(nullptr, caa); +} + +} // namespace test +} // namespace ares diff --git a/test/ares-test-parse-naptr.cc b/test/ares-test-parse-naptr.cc index 40013cb..3238a19 100644 --- a/test/ares-test-parse-naptr.cc +++ b/test/ares-test-parse-naptr.cc @@ -97,6 +97,35 @@ TEST_F(LibraryTest, ParseNaptrReplyErrors) { } } +TEST_F(LibraryTest, ParseNaptrReplyTooShort) { + std::vector data = { + 0x12, 0x34, // qid + 0x84, // response + query + AA + not-TC + not-RD + 0x00, // not-RA + not-Z + not-AD + not-CD + rc=NoError + 0x00, 0x01, // num questions + 0x00, 0x01, // num answer RRs + 0x00, 0x00, // num authority RRs + 0x00, 0x00, // num additional RRs + // Question + 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 0x03, 'c', 'o', 'm', + 0x00, + 0x00, 0x23, // type NAPTR + 0x00, 0x01, // class IN + // Answer 1 + 0x07, 'e', 'x', 'a', 'm', 'p', 'l', 'e', + 0x03, 'c', 'o', 'm', + 0x00, + 0x00, 0x23, // RR type + 0x00, 0x01, // class IN + 0x01, 0x02, 0x03, 0x04, // TTL + 0x00, 0x01, // rdata length + 0x00, // Too short: expect 2 x int16 and 3 x name (min 1 byte each) + }; + struct ares_naptr_reply* naptr = nullptr; + EXPECT_EQ(ARES_EBADRESP, ares_parse_naptr_reply(data.data(), data.size(), &naptr)); +} + TEST_F(LibraryTest, ParseNaptrReplyAllocFail) { DNSPacket pkt; pkt.set_qid(0x1234).set_response().set_aa() diff --git a/test/ares-test-parse-soa-any.cc b/test/ares-test-parse-soa-any.cc new file mode 100644 index 0000000..804c6a0 --- /dev/null +++ b/test/ares-test-parse-soa-any.cc @@ -0,0 +1,111 @@ +#include "ares-test.h" +#include "dns-proto.h" + +#include +#include + +namespace ares { +namespace test { + +TEST_F(LibraryTest, ParseSoaAnyReplyOK) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any))\ + .add_answer(new DNSARR("example.com", 0x01020304, {2,3,4,5})) + .add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")) + .add_answer(new DNSMxRR("example.com", 100, 200, "mx2.example.com")) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector data = pkt.data(); + + struct ares_soa_reply* soa = nullptr; + EXPECT_EQ(ARES_SUCCESS, ares_parse_soa_reply(data.data(), data.size(), &soa)); + ASSERT_NE(nullptr, soa); + EXPECT_EQ("soa1.example.com", std::string(soa->nsname)); + EXPECT_EQ("fred.example.com", std::string(soa->hostmaster)); + EXPECT_EQ(1, soa->serial); + EXPECT_EQ(2, soa->refresh); + EXPECT_EQ(3, soa->retry); + EXPECT_EQ(4, soa->expire); + EXPECT_EQ(5, soa->minttl); + ares_free_data(soa); +} + +TEST_F(LibraryTest, ParseSoaAnyReplyErrors) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any)) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector data; + struct ares_soa_reply* soa = nullptr; + + // No question. + pkt.questions_.clear(); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + +#ifdef DISABLED + // Question != answer + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("Axample.com", ns_t_any)); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); +#endif + + // Two questions + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.questions_.clear(); + pkt.add_question(new DNSQuestion("example.com", ns_t_any)); + + // Wrong sort of answer. + pkt.answers_.clear(); + pkt.add_answer(new DNSMxRR("example.com", 100, 100, "mx1.example.com")); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.answers_.clear(); + pkt.add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + + // No answer. + pkt.answers_.clear(); + data = pkt.data(); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); + pkt.add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + + // Truncated packets. + data = pkt.data(); + for (size_t len = 1; len < data.size(); len++) { + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), len, &soa)); + } +} + +TEST_F(LibraryTest, ParseSoaAnyReplyAllocFail) { + DNSPacket pkt; + pkt.set_qid(0x1234).set_response().set_aa() + .add_question(new DNSQuestion("example.com", ns_t_any)) + .add_answer(new DNSSoaRR("example.com", 100, + "soa1.example.com", "fred.example.com", + 1, 2, 3, 4, 5)); + std::vector data = pkt.data(); + struct ares_soa_reply* soa = nullptr; + + for (int ii = 1; ii <= 5; ii++) { + ClearFails(); + SetAllocFail(ii); + EXPECT_EQ(ARES_ENOMEM, ares_parse_soa_reply(data.data(), data.size(), &soa)) << ii; + } +} + +} // namespace test +} // namespace ares diff --git a/test/ares-test-parse-soa.cc b/test/ares-test-parse-soa.cc index afa4b7a..c0ffaae 100644 --- a/test/ares-test-parse-soa.cc +++ b/test/ares-test-parse-soa.cc @@ -50,7 +50,7 @@ TEST_F(LibraryTest, ParseSoaReplyErrors) { pkt.questions_.clear(); pkt.add_question(new DNSQuestion("Axample.com", ns_t_soa)); data = pkt.data(); - EXPECT_EQ(ARES_ENODATA, ares_parse_soa_reply(data.data(), data.size(), &soa)); + EXPECT_EQ(ARES_EBADRESP, ares_parse_soa_reply(data.data(), data.size(), &soa)); pkt.questions_.clear(); pkt.add_question(new DNSQuestion("example.com", ns_t_soa)); #endif diff --git a/test/ares-test.cc b/test/ares-test.cc index b86cba4..9cfb64b 100644 --- a/test/ares-test.cc +++ b/test/ares-test.cc @@ -1,4 +1,5 @@ #include "ares-test.h" +#include "ares-test-ai.h" #include "dns-proto.h" // Include ares internal files for DNS protocol details @@ -19,11 +20,9 @@ #ifdef WIN32 #define BYTE_CAST (char *) -#define sclose(x) closesocket(x) #define mkdir_(d, p) mkdir(d) #else #define BYTE_CAST -#define sclose(x) close(x) #define mkdir_(d, p) mkdir(d, p) #endif @@ -31,7 +30,31 @@ namespace ares { namespace test { bool verbose = false; -int mock_port = 5300; +static constexpr int dynamic_port = 0; +int mock_port = dynamic_port; + +const std::vector both_families = {AF_INET, AF_INET6}; +const std::vector ipv4_family = {AF_INET}; +const std::vector ipv6_family = {AF_INET6}; + +const std::vector> both_families_both_modes = { + std::make_pair(AF_INET, false), + std::make_pair(AF_INET, true), + std::make_pair(AF_INET6, false), + std::make_pair(AF_INET6, true) +}; +const std::vector> ipv4_family_both_modes = { + std::make_pair(AF_INET, false), + std::make_pair(AF_INET, true) +}; +const std::vector> ipv6_family_both_modes = { + std::make_pair(AF_INET6, false), + std::make_pair(AF_INET6, true) +}; + +// Which parameters to use in tests +std::vector families = both_families; +std::vector> families_modes = both_families_both_modes; unsigned long long LibraryTest::fails_ = 0; std::map LibraryTest::size_fails_; @@ -147,8 +170,8 @@ void DefaultChannelModeTest::Process() { ProcessWork(channel_, NoExtraFDs, nullptr); } -MockServer::MockServer(int family, int port, int tcpport) - : udpport_(port), tcpport_(tcpport ? tcpport : udpport_), qid_(-1) { +MockServer::MockServer(int family, int port) + : udpport_(port), tcpport_(port), qid_(-1) { // Create a TCP socket to receive data on. tcpfd_ = socket(family, SOCK_STREAM, 0); EXPECT_NE(-1, tcpfd_); @@ -175,6 +198,21 @@ MockServer::MockServer(int family, int port, int tcpport) addr.sin_port = htons(udpport_); int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr)); EXPECT_EQ(0, udprc) << "Failed to bind AF_INET to UDP port " << udpport_; + // retrieve system-assigned port + if (udpport_ == dynamic_port) { + ares_socklen_t len = sizeof(addr); + auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len); + EXPECT_EQ(0, result); + udpport_ = ntohs(addr.sin_port); + EXPECT_NE(dynamic_port, udpport_); + } + if (tcpport_ == dynamic_port) { + ares_socklen_t len = sizeof(addr); + auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len); + EXPECT_EQ(0, result); + tcpport_ = ntohs(addr.sin_port); + EXPECT_NE(dynamic_port, tcpport_); + } } else { EXPECT_EQ(AF_INET6, family); struct sockaddr_in6 addr; @@ -187,6 +225,21 @@ MockServer::MockServer(int family, int port, int tcpport) addr.sin6_port = htons(udpport_); int udprc = bind(udpfd_, (struct sockaddr*)&addr, sizeof(addr)); EXPECT_EQ(0, udprc) << "Failed to bind AF_INET6 to UDP port " << udpport_; + // retrieve system-assigned port + if (udpport_ == dynamic_port) { + ares_socklen_t len = sizeof(addr); + auto result = getsockname(udpfd_, (struct sockaddr*)&addr, &len); + EXPECT_EQ(0, result); + udpport_ = ntohs(addr.sin6_port); + EXPECT_NE(dynamic_port, udpport_); + } + if (tcpport_ == dynamic_port) { + ares_socklen_t len = sizeof(addr); + auto result = getsockname(tcpfd_, (struct sockaddr*)&addr, &len); + EXPECT_EQ(0, result); + tcpport_ = ntohs(addr.sin6_port); + EXPECT_NE(dynamic_port, tcpport_); + } } if (verbose) std::cerr << "Configured " << (family == AF_INET ? "IPv4" : "IPv6") @@ -282,7 +335,7 @@ void MockServer::ProcessFD(int fd) { qlen -= enclen; question += enclen; std::string namestr(name); - free(name); + ares_free_string(name); if (qlen < 4) { std::cerr << "Unexpected question size (" << qlen @@ -359,7 +412,8 @@ MockChannelOptsTest::NiceMockServers MockChannelOptsTest::BuildServers(int count NiceMockServers servers; assert(count > 0); for (int ii = 0; ii < count; ii++) { - std::unique_ptr server(new NiceMockServer(family, base_port + ii)); + int port = base_port == dynamic_port ? dynamic_port : base_port + ii; + std::unique_ptr server(new NiceMockServer(family, port)); servers.push_back(std::move(server)); } return servers; @@ -381,9 +435,9 @@ MockChannelOptsTest::MockChannelOptsTest(int count, } // Point the library at the first mock server by default (overridden below). - opts.udp_port = mock_port; + opts.udp_port = server_.udpport(); optmask |= ARES_OPT_UDP_PORT; - opts.tcp_port = mock_port; + opts.tcp_port = server_.tcpport(); optmask |= ARES_OPT_TCP_PORT; // If not already overridden, set short-ish timeouts. @@ -543,6 +597,79 @@ void HostCallback(void *data, int status, int timeouts, if (verbose) std::cerr << "HostCallback(" << *result << ")" << std::endl; } +std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result) { + os << '{'; + if (result.done_ && result.ai_) { + os << StatusToString(result.status_) << " " << result.ai_; + } else { + os << "(incomplete)"; + } + os << '}'; + return os; +} + +std::ostream& operator<<(std::ostream& os, const AddrInfo& ai) { + os << '{'; + if (ai == nullptr) { + os << "nullptr}"; + return os; + } + + struct ares_addrinfo_cname *next_cname = ai->cnames; + while(next_cname) { + if(next_cname->alias) { + os << next_cname->alias << "->"; + } + if(next_cname->name) { + os << next_cname->name; + } + if((next_cname = next_cname->next)) + os << ", "; + else + os << " "; + } + + struct ares_addrinfo_node *next = ai->nodes; + while(next) { + //if(next->ai_canonname) { + //os << "'" << next->ai_canonname << "' "; + //} + unsigned short port = 0; + os << "addr=["; + if(next->ai_family == AF_INET) { + sockaddr_in* sin = (sockaddr_in*)next->ai_addr; + port = ntohs(sin->sin_port); + os << AddressToString(&sin->sin_addr, 4); + } + else if (next->ai_family == AF_INET6) { + sockaddr_in6* sin = (sockaddr_in6*)next->ai_addr; + port = ntohs(sin->sin6_port); + os << "[" << AddressToString(&sin->sin6_addr, 16) << "]"; + } + else + os << "unknown family"; + if(port) { + os << ":" << port; + } + os << "]"; + if((next = next->ai_next)) + os << ", "; + } + os << '}'; + return os; +} + +void AddrInfoCallback(void *data, int status, int timeouts, + struct ares_addrinfo *ai) { + EXPECT_NE(nullptr, data); + AddrInfoResult* result = reinterpret_cast(data); + result->done_ = true; + result->status_ = status; + result->timeouts_= timeouts; + result->ai_ = AddrInfo(ai); + if (verbose) std::cerr << "AddrInfoCallback(" << *result << ")" << std::endl; +} + std::ostream& operator<<(std::ostream& os, const SearchResult& result) { os << '{'; if (result.done_) { @@ -663,5 +790,15 @@ TempFile::TempFile(const std::string& contents) } +VirtualizeIO::VirtualizeIO(ares_channel c) + : channel_(c) +{ + ares_set_socket_functions(channel_, &default_functions, 0); +} + +VirtualizeIO::~VirtualizeIO() { + ares_set_socket_functions(channel_, 0, 0); +} + } // namespace test } // namespace ares diff --git a/test/ares-test.h b/test/ares-test.h index a00e53a..e92bf3b 100644 --- a/test/ares-test.h +++ b/test/ares-test.h @@ -2,13 +2,13 @@ #ifndef ARES_TEST_H #define ARES_TEST_H -#include "ares.h" - #include "dns-proto.h" - // Include ares internal file for DNS protocol constants #include "nameser.h" +#include "ares_setup.h" +#include "ares.h" + #include "gtest/gtest.h" #include "gmock/gmock.h" @@ -36,6 +36,17 @@ namespace test { extern bool verbose; extern int mock_port; +extern const std::vector both_families; +extern const std::vector ipv4_family; +extern const std::vector ipv6_family; + +extern const std::vector> both_families_both_modes; +extern const std::vector> ipv4_family_both_modes; +extern const std::vector> ipv6_family_both_modes; + +// Which parameters to use in tests +extern std::vector families; +extern std::vector> families_modes; // Process all pending work on ares-owned file descriptors, plus // optionally the given set-of-FDs + work function. @@ -125,7 +136,7 @@ class DefaultChannelModeTest // Mock DNS server to allow responses to be scripted by tests. class MockServer { public: - MockServer(int family, int port, int tcpport = 0); + MockServer(int family, int port); ~MockServer(); // Mock method indicating the processing of a particular @@ -268,6 +279,30 @@ struct NameInfoResult { }; std::ostream& operator<<(std::ostream& os, const NameInfoResult& result); +struct AddrInfoDeleter { + void operator() (ares_addrinfo *ptr) { + if (ptr) ares_freeaddrinfo(ptr); + } +}; + +// C++ wrapper for struct ares_addrinfo. +using AddrInfo = std::unique_ptr; + +std::ostream& operator<<(std::ostream& os, const AddrInfo& result); + +// Structure that describes the result of an ares_addrinfo_callback invocation. +struct AddrInfoResult { + AddrInfoResult() : done_(false), status_(-1), timeouts_(0) {} + // Whether the callback has been invoked. + bool done_; + // Explicitly provided result information. + int status_; + int timeouts_; + // Contents of the ares_addrinfo structure, if provided. + AddrInfo ai_; +}; +std::ostream& operator<<(std::ostream& os, const AddrInfoResult& result); + // Standard implementation of ares callbacks that fill out the corresponding // structures. void HostCallback(void *data, int status, int timeouts, @@ -276,6 +311,8 @@ void SearchCallback(void *data, int status, int timeouts, unsigned char *abuf, int alen); void NameInfoCallback(void *data, int status, int timeouts, char *node, char *service); +void AddrInfoCallback(void *data, int status, int timeouts, + struct ares_addrinfo *res); // Retrieve the name servers used by a channel. std::vector GetNameServers(ares_channel channel); @@ -311,7 +348,40 @@ class TempFile : public TransientFile { const char* filename() const { return filename_.c_str(); } }; -#ifndef WIN32 +#ifdef _WIN32 +extern "C" { + +static int setenv(const char *name, const char *value, int overwrite) +{ + char *buffer; + size_t buf_size; + + if (name == NULL) + return -1; + + if (value == NULL) + value = ""; /* For unset */ + + if (!overwrite && getenv(name) != NULL) { + return -1; + } + + buf_size = strlen(name) + strlen(value) + 1 /* = */ + 1 /* NULL */; + buffer = (char *)malloc(buf_size); + _snprintf(buffer, buf_size, "%s=%s", name, value); + _putenv(buffer); + free(buffer); + return 0; +} + +static int unsetenv(const char *name) +{ + return setenv(name, NULL, 1); +} + +} /* extern "C" */ +#endif + // RAII class for a temporary environment variable value. class EnvValue { public: @@ -335,7 +405,6 @@ class EnvValue { bool restore_; std::string original_; }; -#endif #ifdef HAVE_CONTAINER @@ -377,6 +446,46 @@ int RunInContainer(ContainerFilesystem* fs, const std::string& hostname, #endif +/* Assigns virtual IO functions to a channel. These functions simply call + * the actual system functions. + */ +class VirtualizeIO { +public: + VirtualizeIO(ares_channel); + ~VirtualizeIO(); + + static const ares_socket_functions default_functions; +private: + ares_channel channel_; +}; + +/* + * Slightly white-box macro to generate two runs for a given test case: + * One with no modifications, and one with all IO functions set to use + * the virtual io structure. + * Since no magic socket setup or anything is done in the latter case + * this should probably only be used for test with very vanilla IO + * requirements. + */ +#define VCLASS_NAME(casename, testname) Virt##casename##_##testname +#define VIRT_NONVIRT_TEST_F(casename, testname) \ + class VCLASS_NAME(casename, testname) : public casename { \ + public: \ + VCLASS_NAME(casename, testname)() {} \ + void InnerTestBody(); \ + }; \ + GTEST_TEST_(casename, testname, VCLASS_NAME(casename, testname), \ + ::testing::internal::GetTypeId()) { \ + InnerTestBody(); \ + } \ + GTEST_TEST_(casename, testname##_virtualized, \ + VCLASS_NAME(casename, testname), \ + ::testing::internal::GetTypeId()) { \ + VirtualizeIO vio(channel_); \ + InnerTestBody(); \ + } \ + void VCLASS_NAME(casename, testname)::InnerTestBody() + } // namespace test } // namespace ares diff --git a/test/buildconf b/test/buildconf new file mode 100755 index 0000000..5a9d7a3 --- /dev/null +++ b/test/buildconf @@ -0,0 +1,2 @@ +#!/bin/sh +autoreconf -iv \ No newline at end of file diff --git a/test/compile b/test/compile new file mode 100755 index 0000000..23fcba0 --- /dev/null +++ b/test/compile @@ -0,0 +1,348 @@ +#! /bin/sh +# Wrapper for compilers which do not understand '-c -o'. + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. +# Written by Tom Tromey . +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# This file is maintained in Automake, please report +# bugs to or send patches to +# . + +nl=' +' + +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent tools from complaining about whitespace usage. +IFS=" "" $nl" + +file_conv= + +# func_file_conv build_file lazy +# Convert a $build file to $host form and store it in $file +# Currently only supports Windows hosts. If the determined conversion +# type is listed in (the comma separated) LAZY, no conversion will +# take place. +func_file_conv () +{ + file=$1 + case $file in + / | /[!/]*) # absolute file, and not a UNC file + if test -z "$file_conv"; then + # lazily determine how to convert abs files + case `uname -s` in + MINGW*) + file_conv=mingw + ;; + CYGWIN* | MSYS*) + file_conv=cygwin + ;; + *) + file_conv=wine + ;; + esac + fi + case $file_conv/,$2, in + *,$file_conv,*) + ;; + mingw/*) + file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'` + ;; + cygwin/* | msys/*) + file=`cygpath -m "$file" || echo "$file"` + ;; + wine/*) + file=`winepath -w "$file" || echo "$file"` + ;; + esac + ;; + esac +} + +# func_cl_dashL linkdir +# Make cl look for libraries in LINKDIR +func_cl_dashL () +{ + func_file_conv "$1" + if test -z "$lib_path"; then + lib_path=$file + else + lib_path="$lib_path;$file" + fi + linker_opts="$linker_opts -LIBPATH:$file" +} + +# func_cl_dashl library +# Do a library search-path lookup for cl +func_cl_dashl () +{ + lib=$1 + found=no + save_IFS=$IFS + IFS=';' + for dir in $lib_path $LIB + do + IFS=$save_IFS + if $shared && test -f "$dir/$lib.dll.lib"; then + found=yes + lib=$dir/$lib.dll.lib + break + fi + if test -f "$dir/$lib.lib"; then + found=yes + lib=$dir/$lib.lib + break + fi + if test -f "$dir/lib$lib.a"; then + found=yes + lib=$dir/lib$lib.a + break + fi + done + IFS=$save_IFS + + if test "$found" != yes; then + lib=$lib.lib + fi +} + +# func_cl_wrapper cl arg... +# Adjust compile command to suit cl +func_cl_wrapper () +{ + # Assume a capable shell + lib_path= + shared=: + linker_opts= + for arg + do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + eat=1 + case $2 in + *.o | *.[oO][bB][jJ]) + func_file_conv "$2" + set x "$@" -Fo"$file" + shift + ;; + *) + func_file_conv "$2" + set x "$@" -Fe"$file" + shift + ;; + esac + ;; + -I) + eat=1 + func_file_conv "$2" mingw + set x "$@" -I"$file" + shift + ;; + -I*) + func_file_conv "${1#-I}" mingw + set x "$@" -I"$file" + shift + ;; + -l) + eat=1 + func_cl_dashl "$2" + set x "$@" "$lib" + shift + ;; + -l*) + func_cl_dashl "${1#-l}" + set x "$@" "$lib" + shift + ;; + -L) + eat=1 + func_cl_dashL "$2" + ;; + -L*) + func_cl_dashL "${1#-L}" + ;; + -static) + shared=false + ;; + -Wl,*) + arg=${1#-Wl,} + save_ifs="$IFS"; IFS=',' + for flag in $arg; do + IFS="$save_ifs" + linker_opts="$linker_opts $flag" + done + IFS="$save_ifs" + ;; + -Xlinker) + eat=1 + linker_opts="$linker_opts $2" + ;; + -*) + set x "$@" "$1" + shift + ;; + *.cc | *.CC | *.cxx | *.CXX | *.[cC]++) + func_file_conv "$1" + set x "$@" -Tp"$file" + shift + ;; + *.c | *.cpp | *.CPP | *.lib | *.LIB | *.Lib | *.OBJ | *.obj | *.[oO]) + func_file_conv "$1" mingw + set x "$@" "$file" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift + done + if test -n "$linker_opts"; then + linker_opts="-link$linker_opts" + fi + exec "$@" $linker_opts + exit 1 +} + +eat= + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: compile [--help] [--version] PROGRAM [ARGS] + +Wrapper for compilers which do not understand '-c -o'. +Remove '-o dest.o' from ARGS, run PROGRAM with the remaining +arguments, and rename the output as expected. + +If you are trying to build a whole package this is not the +right script to run: please start by reading the file 'INSTALL'. + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "compile $scriptversion" + exit $? + ;; + cl | *[/\\]cl | cl.exe | *[/\\]cl.exe | \ + icl | *[/\\]icl | icl.exe | *[/\\]icl.exe ) + func_cl_wrapper "$@" # Doesn't return... + ;; +esac + +ofile= +cfile= + +for arg +do + if test -n "$eat"; then + eat= + else + case $1 in + -o) + # configure might choose to run compile as 'compile cc -o foo foo.c'. + # So we strip '-o arg' only if arg is an object. + eat=1 + case $2 in + *.o | *.obj) + ofile=$2 + ;; + *) + set x "$@" -o "$2" + shift + ;; + esac + ;; + *.c) + cfile=$1 + set x "$@" "$1" + shift + ;; + *) + set x "$@" "$1" + shift + ;; + esac + fi + shift +done + +if test -z "$ofile" || test -z "$cfile"; then + # If no '-o' option was seen then we might have been invoked from a + # pattern rule where we don't need one. That is ok -- this is a + # normal compilation that the losing compiler can handle. If no + # '.c' file was seen then we are probably linking. That is also + # ok. + exec "$@" +fi + +# Name of file we expect compiler to create. +cofile=`echo "$cfile" | sed 's|^.*[\\/]||; s|^[a-zA-Z]:||; s/\.c$/.o/'` + +# Create the lock directory. +# Note: use '[/\\:.-]' here to ensure that we don't use the same name +# that we are using for the .o file. Also, base the name on the expected +# object file name, since that is what matters with a parallel build. +lockdir=`echo "$cofile" | sed -e 's|[/\\:.-]|_|g'`.d +while true; do + if mkdir "$lockdir" >/dev/null 2>&1; then + break + fi + sleep 1 +done +# FIXME: race condition here if user kills between mkdir and trap. +trap "rmdir '$lockdir'; exit 1" 1 2 15 + +# Run the compile. +"$@" +ret=$? + +if test -f "$cofile"; then + test "$cofile" = "$ofile" || mv "$cofile" "$ofile" +elif test -f "${cofile}bj"; then + test "${cofile}bj" = "$ofile" || mv "${cofile}bj" "$ofile" +fi + +rmdir "$lockdir" +exit $ret + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/test/config.guess b/test/config.guess new file mode 100755 index 0000000..f50dcdb --- /dev/null +++ b/test/config.guess @@ -0,0 +1,1480 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-24' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). +# +# Originally written by Per Bothner; maintained since 2000 by Ben Elliston. +# +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess +# +# Please send patches to . + + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + +trap 'exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. Note that the use of a +# compiler to aid in system detection is discouraged as it requires +# temporary files to be created and, as you can see below, it is a +# headache to deal with in a portable fashion. + +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +# Portable tmp directory creation inspired by the Autoconf team. + +set_cc_for_build=' +trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; +trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; +: ${TMPDIR=/tmp} ; + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || + { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || + { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; +dummy=$tmp/dummy ; +tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int x;" > "$dummy.c" ; + for c in cc gcc c89 c99 ; do + if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then + CC_FOR_BUILD="$c"; break ; + fi ; + done ; + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found ; + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac ; set_cc_for_build= ;' + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 1994-08-24) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +case "$UNAME_SYSTEM" in +Linux|GNU|GNU/*) + # If the system lacks a compiler, then just pick glibc. + # We could probably try harder. + LIBC=gnu + + eval "$set_cc_for_build" + cat <<-EOF > "$dummy.c" + #include + #if defined(__UCLIBC__) + LIBC=uclibc + #elif defined(__dietlibc__) + LIBC=dietlibc + #else + LIBC=gnu + #endif + EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`" + + # If ldd exists, use it to detect musl libc. + if command -v ldd >/dev/null && \ + ldd --version 2>&1 | grep -q ^musl + then + LIBC=musl + fi + ;; +esac + +# Note: order is significant - the case branches are not exclusive. + +case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in + *:NetBSD:*:*) + # NetBSD (nbsd) targets should (where applicable) match one or + # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # + # Note: NetBSD doesn't particularly care about the vendor + # portion of the name. We always set it to "unknown". + sysctl="sysctl -n hw.machine_arch" + UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \ + "/sbin/$sysctl" 2>/dev/null || \ + "/usr/sbin/$sysctl" 2>/dev/null || \ + echo unknown)` + case "$UNAME_MACHINE_ARCH" in + armeb) machine=armeb-unknown ;; + arm*) machine=arm-unknown ;; + sh3el) machine=shl-unknown ;; + sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; + earmv*) + arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'` + endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'` + machine="${arch}${endian}"-unknown + ;; + *) machine="$UNAME_MACHINE_ARCH"-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently (or will in the future) and ABI. + case "$UNAME_MACHINE_ARCH" in + earm*) + os=netbsdelf + ;; + arm*|i386|m68k|ns32k|sh3*|sparc|vax) + eval "$set_cc_for_build" + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ELF__ + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # Determine ABI tags. + case "$UNAME_MACHINE_ARCH" in + earm*) + expr='s/^earmv[0-9]/-eabi/;s/eb$//' + abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"` + ;; + esac + # The OS release + # Debian GNU/NetBSD machines have a different userland, and + # thus, need a distinct triplet. However, they do not need + # kernel version information, so it can be replaced with a + # suitable tag, in the style of linux-gnu. + case "$UNAME_VERSION" in + Debian*) + release='-gnu' + ;; + *) + release=`echo "$UNAME_RELEASE" | sed -e 's/[-_].*//' | cut -d. -f1,2` + ;; + esac + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "$machine-${os}${release}${abi}" + exit ;; + *:Bitrig:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE" + exit ;; + *:OpenBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE" + exit ;; + *:LibertyBSD:*:*) + UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'` + echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE" + exit ;; + *:MidnightBSD:*:*) + echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE" + exit ;; + *:ekkoBSD:*:*) + echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE" + exit ;; + *:SolidBSD:*:*) + echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE" + exit ;; + macppc:MirBSD:*:*) + echo powerpc-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:MirBSD:*:*) + echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE" + exit ;; + *:Sortix:*:*) + echo "$UNAME_MACHINE"-unknown-sortix + exit ;; + *:Redox:*:*) + echo "$UNAME_MACHINE"-unknown-redox + exit ;; + mips:OSF1:*.*) + echo mips-dec-osf1 + exit ;; + alpha:OSF1:*:*) + case $UNAME_RELEASE in + *4.0) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + ;; + *5.*) + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` + ;; + esac + # According to Compaq, /usr/sbin/psrinfo has been available on + # OSF/1 and Tru64 systems produced since 1995. I hope that + # covers most systems running today. This code pipes the CPU + # types through head -n 1, so we only detect the type of CPU 0. + ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` + case "$ALPHA_CPU_TYPE" in + "EV4 (21064)") + UNAME_MACHINE=alpha ;; + "EV4.5 (21064)") + UNAME_MACHINE=alpha ;; + "LCA4 (21066/21068)") + UNAME_MACHINE=alpha ;; + "EV5 (21164)") + UNAME_MACHINE=alphaev5 ;; + "EV5.6 (21164A)") + UNAME_MACHINE=alphaev56 ;; + "EV5.6 (21164PC)") + UNAME_MACHINE=alphapca56 ;; + "EV5.7 (21164PC)") + UNAME_MACHINE=alphapca57 ;; + "EV6 (21264)") + UNAME_MACHINE=alphaev6 ;; + "EV6.7 (21264A)") + UNAME_MACHINE=alphaev67 ;; + "EV6.8CB (21264C)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8AL (21264B)") + UNAME_MACHINE=alphaev68 ;; + "EV6.8CX (21264D)") + UNAME_MACHINE=alphaev68 ;; + "EV6.9A (21264/EV69A)") + UNAME_MACHINE=alphaev69 ;; + "EV7 (21364)") + UNAME_MACHINE=alphaev7 ;; + "EV7.9 (21364A)") + UNAME_MACHINE=alphaev79 ;; + esac + # A Pn.n version is a patched version. + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`" + # Reset EXIT trap before exiting to avoid spurious non-zero exit code. + exitcode=$? + trap '' 0 + exit $exitcode ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-amigaos + exit ;; + *:[Mm]orph[Oo][Ss]:*:*) + echo "$UNAME_MACHINE"-unknown-morphos + exit ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit ;; + *:z/VM:*:*) + echo s390-ibm-zvmoe + exit ;; + *:OS400:*:*) + echo powerpc-ibm-os400 + exit ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix"$UNAME_RELEASE" + exit ;; + arm*:riscos:*:*|arm*:RISCOS:*:*) + echo arm-unknown-riscos + exit ;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit ;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit ;; + DRS?6000:unix:4.0:6*) + echo sparc-icl-nx6 + exit ;; + DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) + case `/usr/bin/uname -p` in + sparc) echo sparc-icl-nx7; exit ;; + esac ;; + s390x:SunOS:*:*) + echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`" + exit ;; + i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*) + echo i386-pc-auroraux"$UNAME_RELEASE" + exit ;; + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) + eval "$set_cc_for_build" + SUN_ARCH=i386 + # If there is a compiler, see if it is configured for 64-bit objects. + # Note that the Sun cc does not turn __LP64__ into 1 like gcc does. + # This test works for both compilers. + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + SUN_ARCH=x86_64 + fi + fi + echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`" + exit ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos"$UNAME_RELEASE" + exit ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos"$UNAME_RELEASE" + ;; + sun4) + echo sparc-sun-sunos"$UNAME_RELEASE" + ;; + esac + exit ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos"$UNAME_RELEASE" + exit ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint"$UNAME_RELEASE" + exit ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint"$UNAME_RELEASE" + exit ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint"$UNAME_RELEASE" + exit ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint"$UNAME_RELEASE" + exit ;; + m68k:machten:*:*) + echo m68k-apple-machten"$UNAME_RELEASE" + exit ;; + powerpc:machten:*:*) + echo powerpc-apple-machten"$UNAME_RELEASE" + exit ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix"$UNAME_RELEASE" + exit ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix"$UNAME_RELEASE" + exit ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix"$UNAME_RELEASE" + exit ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && + dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` && + SYSTEM_NAME=`"$dummy" "$dummyarg"` && + { echo "$SYSTEM_NAME"; exit; } + echo mips-mips-riscos"$UNAME_RELEASE" + exit ;; + Motorola:PowerMAX_OS:*:*) + echo powerpc-motorola-powermax + exit ;; + Motorola:*:4.3:PL8-*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) + echo powerpc-harris-powermax + exit ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ] + then + if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \ + [ "$TARGET_BINARY_INTERFACE"x = x ] + then + echo m88k-dg-dgux"$UNAME_RELEASE" + else + echo m88k-dg-dguxbcs"$UNAME_RELEASE" + fi + else + echo i586-dg-dgux"$UNAME_RELEASE" + fi + exit ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit ;; + *:IRIX*:*:*) + echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`" + exit ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i*86:AIX:*:*) + echo i386-ibm-aix + exit ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` + then + echo "$SYSTEM_NAME" + else + echo rs6000-ibm-aix3.2.5 + fi + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit ;; + *:AIX:*:[4567]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` + if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/lslpp ] ; then + IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | + awk -F: '{ print $3 }' | sed s/[0-9]*$/0/` + else + IBM_REV="$UNAME_VERSION.$UNAME_RELEASE" + fi + echo "$IBM_ARCH"-ibm-aix"$IBM_REV" + exit ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit ;; + ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*) + echo romp-ibm-bsd4.4 + exit ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd"$UNAME_RELEASE" # 4.3 with uname added to + exit ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + case "$UNAME_MACHINE" in + 9000/31?) HP_ARCH=m68000 ;; + 9000/[34]??) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "$sc_cpu_version" in + 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0 + 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "$sc_kernel_bits" in + 32) HP_ARCH=hppa2.0n ;; + 64) HP_ARCH=hppa2.0w ;; + '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20 + esac ;; + esac + fi + if [ "$HP_ARCH" = "" ]; then + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS="" $CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null) && HP_ARCH=`"$dummy"` + test -z "$HP_ARCH" && HP_ARCH=hppa + fi ;; + esac + if [ "$HP_ARCH" = hppa2.0w ] + then + eval "$set_cc_for_build" + + # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating + # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler + # generating 64-bit code. GNU and HP use different nomenclature: + # + # $ CC_FOR_BUILD=cc ./config.guess + # => hppa2.0w-hp-hpux11.23 + # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess + # => hppa64-hp-hpux11.23 + + if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | + grep -q __LP64__ + then + HP_ARCH=hppa2.0w + else + HP_ARCH=hppa64 + fi + fi + echo "$HP_ARCH"-hp-hpux"$HPUX_REV" + exit ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux"$HPUX_REV" + exit ;; + 3050*:HI-UX:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` && + { echo "$SYSTEM_NAME"; exit; } + echo unknown-hitachi-hiuxwe2 + exit ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*) + echo hppa1.1-hp-bsd + exit ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit ;; + *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*) + echo hppa1.1-hp-osf + exit ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit ;; + i*86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo "$UNAME_MACHINE"-unknown-osf1mk + else + echo "$UNAME_MACHINE"-unknown-osf1 + fi + exit ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*[A-Z]90:*:*:*) + echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ + -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + *:UNICOS/mp:*:*) + echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/' + exit ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz` + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + 5000:UNIX_System_V:4.*:*) + FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'` + FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'` + echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit ;; + i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE" + exit ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:BSD/OS:*:*) + echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE" + exit ;; + *:FreeBSD:*:*) + UNAME_PROCESSOR=`/usr/bin/uname -p` + case "$UNAME_PROCESSOR" in + amd64) + UNAME_PROCESSOR=x86_64 ;; + i386) + UNAME_PROCESSOR=i586 ;; + esac + echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + i*:CYGWIN*:*) + echo "$UNAME_MACHINE"-pc-cygwin + exit ;; + *:MINGW64*:*) + echo "$UNAME_MACHINE"-pc-mingw64 + exit ;; + *:MINGW*:*) + echo "$UNAME_MACHINE"-pc-mingw32 + exit ;; + *:MSYS*:*) + echo "$UNAME_MACHINE"-pc-msys + exit ;; + i*:PW*:*) + echo "$UNAME_MACHINE"-pc-pw32 + exit ;; + *:Interix*:*) + case "$UNAME_MACHINE" in + x86) + echo i586-pc-interix"$UNAME_RELEASE" + exit ;; + authenticamd | genuineintel | EM64T) + echo x86_64-unknown-interix"$UNAME_RELEASE" + exit ;; + IA64) + echo ia64-unknown-interix"$UNAME_RELEASE" + exit ;; + esac ;; + i*:UWIN*:*) + echo "$UNAME_MACHINE"-pc-uwin + exit ;; + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) + echo x86_64-unknown-cygwin + exit ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`" + exit ;; + *:GNU:*:*) + # the GNU system + echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`" + exit ;; + *:GNU/*:*:*) + # other systems with GNU libc and userland + echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC" + exit ;; + i*86:Minix:*:*) + echo "$UNAME_MACHINE"-pc-minix + exit ;; + aarch64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + aarch64_be:Linux:*:*) + UNAME_MACHINE=aarch64_be + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + alpha:Linux:*:*) + case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in + EV5) UNAME_MACHINE=alphaev5 ;; + EV56) UNAME_MACHINE=alphaev56 ;; + PCA56) UNAME_MACHINE=alphapca56 ;; + PCA57) UNAME_MACHINE=alphapca56 ;; + EV6) UNAME_MACHINE=alphaev6 ;; + EV67) UNAME_MACHINE=alphaev67 ;; + EV68*) UNAME_MACHINE=alphaev68 ;; + esac + objdump --private-headers /bin/sh | grep -q ld.so.1 + if test "$?" = 0 ; then LIBC=gnulibc1 ; fi + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arc:Linux:*:* | arceb:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + arm*:Linux:*:*) + eval "$set_cc_for_build" + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + else + if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_PCS_VFP + then + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi + else + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf + fi + fi + exit ;; + avr32*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + cris:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + crisv32:Linux:*:*) + echo "$UNAME_MACHINE"-axis-linux-"$LIBC" + exit ;; + e2k:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + frv:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + hexagon:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:Linux:*:*) + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + exit ;; + ia64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + k1om:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m32r*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + m68*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + mips:Linux:*:* | mips64:Linux:*:*) + eval "$set_cc_for_build" + sed 's/^ //' << EOF > "$dummy.c" + #undef CPU + #undef ${UNAME_MACHINE} + #undef ${UNAME_MACHINE}el + #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) + CPU=${UNAME_MACHINE}el + #else + #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) + CPU=${UNAME_MACHINE} + #else + CPU= + #endif + #endif +EOF + eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`" + test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; } + ;; + mips64el:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + openrisc*:Linux:*:*) + echo or1k-unknown-linux-"$LIBC" + exit ;; + or32:Linux:*:* | or1k*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + padre:Linux:*:*) + echo sparc-unknown-linux-"$LIBC" + exit ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-"$LIBC" + exit ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;; + PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;; + *) echo hppa-unknown-linux-"$LIBC" ;; + esac + exit ;; + ppc64:Linux:*:*) + echo powerpc64-unknown-linux-"$LIBC" + exit ;; + ppc:Linux:*:*) + echo powerpc-unknown-linux-"$LIBC" + exit ;; + ppc64le:Linux:*:*) + echo powerpc64le-unknown-linux-"$LIBC" + exit ;; + ppcle:Linux:*:*) + echo powerpcle-unknown-linux-"$LIBC" + exit ;; + riscv32:Linux:*:* | riscv64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo "$UNAME_MACHINE"-ibm-linux-"$LIBC" + exit ;; + sh64*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sh*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + sparc:Linux:*:* | sparc64:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + tile*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + vax:Linux:*:*) + echo "$UNAME_MACHINE"-dec-linux-"$LIBC" + exit ;; + x86_64:Linux:*:*) + if objdump -f /bin/sh | grep -q elf32-x86-64; then + echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32 + else + echo "$UNAME_MACHINE"-pc-linux-"$LIBC" + fi + exit ;; + xtensa*:Linux:*:*) + echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" + exit ;; + i*86:DYNIX/ptx:4*:*) + # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. + # earlier versions are messed up and put the nodename in both + # sysname and nodename. + echo i386-sequent-sysv4 + exit ;; + i*86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION" + exit ;; + i*86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo "$UNAME_MACHINE"-pc-os2-emx + exit ;; + i*86:XTS-300:*:STOP) + echo "$UNAME_MACHINE"-unknown-stop + exit ;; + i*86:atheos:*:*) + echo "$UNAME_MACHINE"-unknown-atheos + exit ;; + i*86:syllable:*:*) + echo "$UNAME_MACHINE"-pc-syllable + exit ;; + i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*) + echo i386-unknown-lynxos"$UNAME_RELEASE" + exit ;; + i*86:*DOS:*:*) + echo "$UNAME_MACHINE"-pc-msdosdjgpp + exit ;; + i*86:*:4.*:*) + UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL" + fi + exit ;; + i*86:*:5:[678]*) + # UnixWare 7.x, OpenUNIX and OpenServer 6. + case `/bin/uname -X | grep "^Machine"` in + *486*) UNAME_MACHINE=i486 ;; + *Pentium) UNAME_MACHINE=i586 ;; + *Pent*|*Celeron) UNAME_MACHINE=i686 ;; + esac + echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}" + exit ;; + i*86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` + (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL" + else + echo "$UNAME_MACHINE"-pc-sysv32 + fi + exit ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i586. + # Note: whatever this is, it MUST be the same as what config.sub + # prints for the "djgpp" host, or else GDB configure will decide that + # this is a cross-build. + echo i586-pc-msdosdjgpp + exit ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv"$UNAME_RELEASE" # Unknown i860-SVR4 + fi + exit ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit ;; + mc68k:UNIX:SYSTEM5:3.51m) + echo m68k-convergent-sysv + exit ;; + M680?0:D-NIX:5.3:*) + echo m68k-diab-dnix + exit ;; + M68*:*:R3V[5678]*:*) + test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; + 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4; exit; } ;; + NCR*:*:4.2:* | MPRAS*:*:4.2:*) + OS_REL='.3' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && { echo i486-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } + /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \ + && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;; + m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) + echo m68k-unknown-lynxos"$UNAME_RELEASE" + exit ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos"$UNAME_RELEASE" + exit ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*) + echo powerpc-unknown-lynxos"$UNAME_RELEASE" + exit ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv"$UNAME_RELEASE" + exit ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo "$UNAME_MACHINE"-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit ;; + PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit ;; + i*86:VOS:*:*) + # From Paul.Green@stratus.com. + echo "$UNAME_MACHINE"-stratus-vos + exit ;; + *:VOS:*:*) + # From Paul.Green@stratus.com. + echo hppa1.1-stratus-vos + exit ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux"$UNAME_RELEASE" + exit ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv"$UNAME_RELEASE" + else + echo mips-unknown-sysv"$UNAME_RELEASE" + fi + exit ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; + x86_64:Haiku:*:*) + echo x86_64-unknown-haiku + exit ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux"$UNAME_RELEASE" + exit ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux"$UNAME_RELEASE" + exit ;; + SX-6:SUPER-UX:*:*) + echo sx6-nec-superux"$UNAME_RELEASE" + exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux"$UNAME_RELEASE" + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux"$UNAME_RELEASE" + exit ;; + SX-ACE:SUPER-UX:*:*) + echo sxace-nec-superux"$UNAME_RELEASE" + exit ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Rhapsody:*:*) + echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE" + exit ;; + *:Darwin:*:*) + UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown + eval "$set_cc_for_build" + if test "$UNAME_PROCESSOR" = unknown ; then + UNAME_PROCESSOR=powerpc + fi + if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then + if [ "$CC_FOR_BUILD" != no_compiler_found ]; then + if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_64BIT_ARCH >/dev/null + then + case $UNAME_PROCESSOR in + i386) UNAME_PROCESSOR=x86_64 ;; + powerpc) UNAME_PROCESSOR=powerpc64 ;; + esac + fi + # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc + if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \ + (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \ + grep IS_PPC >/dev/null + then + UNAME_PROCESSOR=powerpc + fi + fi + elif test "$UNAME_PROCESSOR" = i386 ; then + # Avoid executing cc on OS X 10.9, as it ships with a stub + # that puts up a graphical alert prompting to install + # developer tools. Any system running Mac OS X 10.7 or + # later (Darwin 11 and later) is required to have a 64-bit + # processor. This is not true of the ARM version of Darwin + # that Apple uses in portable devices. + UNAME_PROCESSOR=x86_64 + fi + echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE" + exit ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + UNAME_PROCESSOR=`uname -p` + if test "$UNAME_PROCESSOR" = x86; then + UNAME_PROCESSOR=i386 + UNAME_MACHINE=pc + fi + echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE" + exit ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit ;; + NEO-*:NONSTOP_KERNEL:*:*) + echo neo-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSE-*:NONSTOP_KERNEL:*:*) + echo nse-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSR-*:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSV-*:NONSTOP_KERNEL:*:*) + echo nsv-tandem-nsk"$UNAME_RELEASE" + exit ;; + NSX-*:NONSTOP_KERNEL:*:*) + echo nsx-tandem-nsk"$UNAME_RELEASE" + exit ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit ;; + DS/*:UNIX_System_V:*:*) + echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE" + exit ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = 386; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo "$UNAME_MACHINE"-unknown-plan9 + exit ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit ;; + SEI:*:*:SEIUX) + echo mips-sei-seiux"$UNAME_RELEASE" + exit ;; + *:DragonFly:*:*) + echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`" + exit ;; + *:*VMS:*:*) + UNAME_MACHINE=`(uname -p) 2>/dev/null` + case "$UNAME_MACHINE" in + A*) echo alpha-dec-vms ; exit ;; + I*) echo ia64-dec-vms ; exit ;; + V*) echo vax-dec-vms ; exit ;; + esac ;; + *:XENIX:*:SysV) + echo i386-pc-xenix + exit ;; + i*86:skyos:*:*) + echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`" + exit ;; + i*86:rdos:*:*) + echo "$UNAME_MACHINE"-pc-rdos + exit ;; + i*86:AROS:*:*) + echo "$UNAME_MACHINE"-pc-aros + exit ;; + x86_64:VMkernel:*:*) + echo "$UNAME_MACHINE"-unknown-esx + exit ;; + amd64:Isilon\ OneFS:*:*) + echo x86_64-unknown-onefs + exit ;; +esac + +echo "$0: unable to guess system type" >&2 + +case "$UNAME_MACHINE:$UNAME_SYSTEM" in + mips:Linux | mips64:Linux) + # If we got here on MIPS GNU/Linux, output extra information. + cat >&2 <&2 </dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = "$UNAME_MACHINE" +UNAME_RELEASE = "$UNAME_RELEASE" +UNAME_SYSTEM = "$UNAME_SYSTEM" +UNAME_VERSION = "$UNAME_VERSION" +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/test/config.sub b/test/config.sub new file mode 100755 index 0000000..1d8e98b --- /dev/null +++ b/test/config.sub @@ -0,0 +1,1801 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright 1992-2018 Free Software Foundation, Inc. + +timestamp='2018-02-22' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, see . +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that +# program. This Exception is an additional permission under section 7 +# of the GNU General Public License, version 3 ("GPLv3"). + + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# You can get the latest version of this script from: +# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS or ALIAS + +Canonicalize a configuration name. + +Options: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright 1992-2018 Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit ;; + --version | -v ) + echo "$version" ; exit ;; + --help | --h* | -h ) + echo "$usage"; exit ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo "$1" + exit ;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \ + linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \ + knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \ + kopensolaris*-gnu* | cloudabi*-eabi* | \ + storm-chaos* | os2-emx* | rtmk-nova*) + os=-$maybe_os + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + android-linux) + os=-linux-android + basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown + ;; + *) + basic_machine=`echo "$1" | sed 's/-[^-]*$//'` + if [ "$basic_machine" != "$1" ] + then os=`echo "$1" | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis | -knuth | -cray | -microblaze*) + os= + basic_machine=$1 + ;; + -bluegene*) + os=-cnk + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -chorusos*) + os=-chorusos + basic_machine=$1 + ;; + -chorusrdb) + os=-chorusrdb + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco6) + os=-sco5v6 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*178) + os=-lynxos178 + ;; + -lynx*5) + os=-lynxos5 + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + 1750a | 580 \ + | a29k \ + | aarch64 | aarch64_be \ + | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ + | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ + | am33_2.0 \ + | arc | arceb \ + | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \ + | avr | avr32 \ + | ba \ + | be32 | be64 \ + | bfin \ + | c4x | c8051 | clipper \ + | d10v | d30v | dlx | dsp16xx \ + | e2k | epiphany \ + | fido | fr30 | frv | ft32 \ + | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ + | hexagon \ + | i370 | i860 | i960 | ia16 | ia64 \ + | ip2k | iq2000 \ + | k1om \ + | le32 | le64 \ + | lm32 \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | microblazeel | mcore | mep | metag \ + | mips | mipsbe | mipseb | mipsel | mipsle \ + | mips16 \ + | mips64 | mips64el \ + | mips64octeon | mips64octeonel \ + | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ + | mips64vr4100 | mips64vr4100el \ + | mips64vr4300 | mips64vr4300el \ + | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ + | mipsisa32 | mipsisa32el \ + | mipsisa32r2 | mipsisa32r2el \ + | mipsisa32r6 | mipsisa32r6el \ + | mipsisa64 | mipsisa64el \ + | mipsisa64r2 | mipsisa64r2el \ + | mipsisa64r6 | mipsisa64r6el \ + | mipsisa64sb1 | mipsisa64sb1el \ + | mipsisa64sr71k | mipsisa64sr71kel \ + | mipsr5900 | mipsr5900el \ + | mipstx39 | mipstx39el \ + | mn10200 | mn10300 \ + | moxie \ + | mt \ + | msp430 \ + | nds32 | nds32le | nds32be \ + | nios | nios2 | nios2eb | nios2el \ + | ns16k | ns32k \ + | open8 | or1k | or1knd | or32 \ + | pdp10 | pj | pjl \ + | powerpc | powerpc64 | powerpc64le | powerpcle \ + | pru \ + | pyramid \ + | riscv32 | riscv64 \ + | rl78 | rx \ + | score \ + | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ + | sh64 | sh64le \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu \ + | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \ + | ubicom32 \ + | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \ + | visium \ + | wasm32 \ + | x86 | xc16x | xstormy16 | xtensa \ + | z8k | z80) + basic_machine=$basic_machine-unknown + ;; + c54x) + basic_machine=tic54x-unknown + ;; + c55x) + basic_machine=tic55x-unknown + ;; + c6x) + basic_machine=tic6x-unknown + ;; + leon|leon[3-9]) + basic_machine=sparc-$basic_machine + ;; + m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip) + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65) + ;; + ms1) + basic_machine=mt-unknown + ;; + + strongarm | thumb | xscale) + basic_machine=arm-unknown + ;; + xgate) + basic_machine=$basic_machine-unknown + os=-none + ;; + xscaleeb) + basic_machine=armeb-unknown + ;; + + xscaleel) + basic_machine=armel-unknown + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i*86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + 580-* \ + | a29k-* \ + | aarch64-* | aarch64_be-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ + | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ + | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \ + | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ + | avr-* | avr32-* \ + | ba-* \ + | be32-* | be64-* \ + | bfin-* | bs2000-* \ + | c[123]* | c30-* | [cjt]90-* | c4x-* \ + | c8051-* | clipper-* | craynv-* | cydra-* \ + | d10v-* | d30v-* | dlx-* \ + | e2k-* | elxsi-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ + | h8300-* | h8500-* \ + | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ + | hexagon-* \ + | i*86-* | i860-* | i960-* | ia16-* | ia64-* \ + | ip2k-* | iq2000-* \ + | k1om-* \ + | le32-* | le64-* \ + | lm32-* \ + | m32c-* | m32r-* | m32rle-* \ + | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ + | microblaze-* | microblazeel-* \ + | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ + | mips16-* \ + | mips64-* | mips64el-* \ + | mips64octeon-* | mips64octeonel-* \ + | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ + | mips64vr4100-* | mips64vr4100el-* \ + | mips64vr4300-* | mips64vr4300el-* \ + | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ + | mipsisa32-* | mipsisa32el-* \ + | mipsisa32r2-* | mipsisa32r2el-* \ + | mipsisa32r6-* | mipsisa32r6el-* \ + | mipsisa64-* | mipsisa64el-* \ + | mipsisa64r2-* | mipsisa64r2el-* \ + | mipsisa64r6-* | mipsisa64r6el-* \ + | mipsisa64sb1-* | mipsisa64sb1el-* \ + | mipsisa64sr71k-* | mipsisa64sr71kel-* \ + | mipsr5900-* | mipsr5900el-* \ + | mipstx39-* | mipstx39el-* \ + | mmix-* \ + | mt-* \ + | msp430-* \ + | nds32-* | nds32le-* | nds32be-* \ + | nios-* | nios2-* | nios2eb-* | nios2el-* \ + | none-* | np1-* | ns16k-* | ns32k-* \ + | open8-* \ + | or1k*-* \ + | orion-* \ + | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ + | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \ + | pru-* \ + | pyramid-* \ + | riscv32-* | riscv64-* \ + | rl78-* | romp-* | rs6000-* | rx-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ + | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ + | sparclite-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \ + | tahoe-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tile*-* \ + | tron-* \ + | ubicom32-* \ + | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \ + | vax-* \ + | visium-* \ + | wasm32-* \ + | we32k-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* \ + | xstormy16-* | xtensa*-* \ + | ymp-* \ + | z8k-* | z80-*) + ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-pc + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + abacus) + basic_machine=abacus-unknown + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amd64) + basic_machine=x86_64-pc + ;; + amd64-*) + basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aros) + basic_machine=i386-pc + os=-aros + ;; + asmjs) + basic_machine=asmjs-unknown + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + bluegene*) + basic_machine=powerpc-ibm + os=-cnk + ;; + c54x-*) + basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c55x-*) + basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c6x-*) + basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + c90) + basic_machine=c90-cray + os=-unicos + ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | j90) + basic_machine=j90-cray + os=-unicos + ;; + craynv) + basic_machine=craynv-cray + os=-unicosmp + ;; + cr16 | cr16-*) + basic_machine=cr16-unknown + os=-elf + ;; + crds | unos) + basic_machine=m68k-crds + ;; + crisv32 | crisv32-* | etraxfs*) + basic_machine=crisv32-axis + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + crx) + basic_machine=crx-unknown + os=-elf + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + decsystem10* | dec10*) + basic_machine=pdp10-dec + os=-tops10 + ;; + decsystem20* | dec20*) + basic_machine=pdp10-dec + os=-tops20 + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; + djgpp) + basic_machine=i586-pc + os=-msdosdjgpp + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2*) + basic_machine=m68k-bull + os=-sysv3 + ;; + e500v[12]) + basic_machine=powerpc-unknown + os=$os"spe" + ;; + e500v[12]-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=$os"spe" + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; + i*86v32) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i*86v4*) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i*86v) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i*86sol2) + basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + leon-*|leon[3-9]-*) + basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'` + ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + microblaze*) + basic_machine=microblaze-xilinx + ;; + mingw64) + basic_machine=x86_64-pc + os=-mingw64 + ;; + mingw32) + basic_machine=i686-pc + os=-mingw32 + ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mips3*-*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + morphos) + basic_machine=powerpc-unknown + os=-morphos + ;; + moxiebox) + basic_machine=moxie-unknown + os=-moxiebox + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + ms1-*) + basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'` + ;; + msys) + basic_machine=i686-pc + os=-msys + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + nacl) + basic_machine=le32-unknown + os=-nacl + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + neo-tandem) + basic_machine=neo-tandem + ;; + nse-tandem) + basic_machine=nse-tandem + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + nsv-tandem) + basic_machine=nsv-tandem + ;; + nsx-tandem) + basic_machine=nsx-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + openrisc | openrisc-*) + basic_machine=or32-unknown + ;; + os400) + basic_machine=powerpc-ibm + os=-os400 + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'` + os=-linux + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium | p5 | k5 | k6 | nexgen | viac3) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon | athlon_*) + basic_machine=i686-pc + ;; + pentiumii | pentium2 | pentiumiii | pentium3) + basic_machine=i686-pc + ;; + pentium4) + basic_machine=i786-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) + basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) + basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pentium4-*) + basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc | ppcbe) basic_machine=powerpc-unknown + ;; + ppc-* | ppcbe-*) + basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64) basic_machine=powerpc64-unknown + ;; + ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ppc64le | powerpc64little) + basic_machine=powerpc64le-unknown + ;; + ppc64le-* | powerpc64little-*) + basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rdos | rdos64) + basic_machine=x86_64-pc + os=-rdos + ;; + rdos32) + basic_machine=i386-pc + os=-rdos + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + s390 | s390-*) + basic_machine=s390-ibm + ;; + s390x | s390x-*) + basic_machine=s390x-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sb1) + basic_machine=mipsisa64sb1-unknown + ;; + sb1el) + basic_machine=mipsisa64sb1el-unknown + ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; + sei) + basic_machine=mips-sei + os=-seiux + ;; + sequent) + basic_machine=i386-sequent + ;; + sh5el) + basic_machine=sh5le-unknown + ;; + simso-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + strongarm-* | thumb-*) + basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'` + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=alphaev5-cray + os=-unicos + ;; + t90) + basic_machine=t90-cray + os=-unicos + ;; + tile*) + basic_machine=$basic_machine-unknown + os=-linux-gnu + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + toad1) + basic_machine=pdp10-xkl + os=-tops20 + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + tpf) + basic_machine=s390x-ibm + os=-tpf + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + x64) + basic_machine=x86_64-pc + ;; + xbox) + basic_machine=i686-pc + os=-mingw32 + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + xscale-* | xscalee[bl]-*) + basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'` + ;; + ymp) + basic_machine=ymp-cray + os=-unicos + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + romp) + basic_machine=romp-ibm + ;; + mmix) + basic_machine=mmix-knuth + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele) + basic_machine=sh-unknown + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + *-unknown) + # Make sure to match an already-canonicalized machine name. + ;; + *) + echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases that might get confused + # with valid system types. + # -solaris* is a basic system type, with this one exception. + -auroraux) + os=-auroraux + ;; + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # es1800 is here to avoid being matched by es* (a different OS) + -es1800*) + os=-ose + ;; + # Now accept the basic system types. + # The portable systems comes first. + # Each alternative MUST end in a * to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \ + | -sym* | -kopensolaris* | -plan9* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* | -aros* | -cloudabi* | -sortix* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \ + | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \ + | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ + | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \ + | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \ + | -linux-newlib* | -linux-musl* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \ + | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ + | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ + | -morphos* | -superux* | -rtmk* | -windiss* \ + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \ + | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \ + | -midnightbsd*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i*86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto-qnx*) + ;; + -nto*) + os=`echo $os | sed -e 's|nto|nto-qnx|'` + ;; + -sim | -xray | -os68k* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo "$os" | sed -e 's|mac|macos|'` + ;; + -linux-dietlibc) + os=-linux-dietlibc + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo "$os" | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo "$os" | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -os400*) + os=-os400 + ;; + -wince*) + os=-wince + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -atheos*) + os=-atheos + ;; + -syllable*) + os=-syllable + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -nova*) + os=-rtmk-nova + ;; + -ns2) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -tpf*) + os=-tpf + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4*) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -zvmoe) + os=-zvmoe + ;; + -dicos*) + os=-dicos + ;; + -pikeos*) + # Until real need of OS specific support for + # particular features comes up, bare metal + # configurations are quite functional. + case $basic_machine in + arm*) + os=-eabi + ;; + *) + os=-elf + ;; + esac + ;; + -nacl*) + ;; + -ios) + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + c4x-* | tic4x-*) + os=-coff + ;; + c8051-*) + os=-elf + ;; + hexagon-*) + os=-elf + ;; + tic54x-*) + os=-coff + ;; + tic55x-*) + os=-coff + ;; + tic6x-*) + os=-coff + ;; + # This must come before the *-dec entry. + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + ;; + m68*-cisco) + os=-aout + ;; + mep-*) + os=-elf + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + or32-*) + os=-coff + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + pru-*) + os=-elf + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-knuth) + os=-mmixware + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -cnk*|-aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -os400*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -tpf*) + vendor=ibm + ;; + -vxsim* | -vxworks* | -windiss*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + -vos*) + vendor=stratus + ;; + esac + basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"` + ;; +esac + +echo "$basic_machine$os" +exit + +# Local variables: +# eval: (add-hook 'write-file-functions 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/test/configure b/test/configure index a6c2aae..27b91a0 100755 --- a/test/configure +++ b/test/configure @@ -695,7 +695,6 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR OBJEXT @@ -770,7 +769,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -2378,7 +2378,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu -am__api_version='1.15' +am__api_version='1.16' ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do @@ -2914,8 +2914,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -2966,7 +2966,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -3527,45 +3527,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -6294,7 +6294,7 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cru} +: ${AR_FLAGS=cr} @@ -6795,11 +6795,8 @@ _LT_EOF test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -6859,7 +6856,7 @@ static const void *lt_preloaded_setup() { #endif _LT_EOF # Now try linking the two files. - mv -f conftest.$ac_objext conftstm.$ac_objext + mv conftest.$ac_objext conftstm.$ac_objext lt_globsym_save_LIBS=$LIBS lt_globsym_save_CFLAGS=$CFLAGS LIBS=conftstm.$ac_objext @@ -8018,8 +8015,8 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 + echo "$AR cr libconftest.a conftest.o" >&5 + $AR cr libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF @@ -9158,6 +9155,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + # flang / f18. f95 an alias for gfortran or flang on Debian + flang* | f18* | f95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -10410,9 +10413,9 @@ fi hpux9*) if test yes = "$GCC"; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' fi hardcode_libdir_flag_spec='$wl+b $wl$libdir' hardcode_libdir_separator=: @@ -13100,7 +13103,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else GXX=no @@ -13583,7 +13586,7 @@ fi ld_shlibs_CXX=no ;; aCC*) - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -13592,11 +13595,11 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then - archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv -f $output_objdir/$soname $lib' + archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag $wl+b $wl$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test "x$output_objdir/$soname" = "x$lib" || mv $output_objdir/$soname $lib' else # FIXME: insert proper C++ library support ld_shlibs_CXX=no @@ -13657,7 +13660,7 @@ fi # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " \-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -13732,8 +13735,8 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' - archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv -f \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' + archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib $wl-retain-symbols-file,$export_symbols; mv \$templib $lib' # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. @@ -13931,7 +13934,7 @@ fi # KCC will only create a shared library if the output file # ends with ".so" (or ".sl" for HP-UX), so rename the library # to its proper name (with version) after linking. - archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv -f \$templib $lib' + archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\$tempext\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib' hardcode_libdir_flag_spec_CXX='$wl-rpath,$libdir' hardcode_libdir_separator_CXX=: @@ -13996,7 +13999,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # FIXME: insert proper C++ library support @@ -14080,7 +14083,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -14091,7 +14094,7 @@ fi # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " \-L"' fi hardcode_libdir_flag_spec_CXX='$wl-R $wl$libdir' @@ -16622,7 +16625,7 @@ fi fi # List of supported lcov versions. - lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11" + lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.13" # Extract the first word of "lcov", so it can be a program name with args. set dummy lcov; ac_word=$2 @@ -17734,7 +17737,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # # INIT-COMMANDS # -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -18728,29 +18731,35 @@ $as_echo "$as_me: executing $ac_file commands" >&6;} # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -18768,53 +18777,50 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. If GNU make was not used, consider + re-running the configure script with MAKE=\"gmake\" (or whatever is + necessary). You can also try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "libtool":C) @@ -18832,7 +18838,6 @@ $as_echo X"$file" | cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. diff --git a/test/depcomp b/test/depcomp new file mode 100755 index 0000000..6b39162 --- /dev/null +++ b/test/depcomp @@ -0,0 +1,791 @@ +#! /bin/sh +# depcomp - compile a program generating dependencies as side-effects + +scriptversion=2018-03-07.03; # UTC + +# Copyright (C) 1999-2020 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Originally written by Alexandre Oliva . + +case $1 in + '') + echo "$0: No command. Try '$0 --help' for more information." 1>&2 + exit 1; + ;; + -h | --h*) + cat <<\EOF +Usage: depcomp [--help] [--version] PROGRAM [ARGS] + +Run PROGRAMS ARGS to compile a file, generating dependencies +as side-effects. + +Environment variables: + depmode Dependency tracking mode. + source Source file read by 'PROGRAMS ARGS'. + object Object file output by 'PROGRAMS ARGS'. + DEPDIR directory where to store dependencies. + depfile Dependency file to output. + tmpdepfile Temporary file to use when outputting dependencies. + libtool Whether libtool is used (yes/no). + +Report bugs to . +EOF + exit $? + ;; + -v | --v*) + echo "depcomp $scriptversion" + exit $? + ;; +esac + +# Get the directory component of the given path, and save it in the +# global variables '$dir'. Note that this directory component will +# be either empty or ending with a '/' character. This is deliberate. +set_dir_from () +{ + case $1 in + */*) dir=`echo "$1" | sed -e 's|/[^/]*$|/|'`;; + *) dir=;; + esac +} + +# Get the suffix-stripped basename of the given path, and save it the +# global variable '$base'. +set_base_from () +{ + base=`echo "$1" | sed -e 's|^.*/||' -e 's/\.[^.]*$//'` +} + +# If no dependency file was actually created by the compiler invocation, +# we still have to create a dummy depfile, to avoid errors with the +# Makefile "include basename.Plo" scheme. +make_dummy_depfile () +{ + echo "#dummy" > "$depfile" +} + +# Factor out some common post-processing of the generated depfile. +# Requires the auxiliary global variable '$tmpdepfile' to be set. +aix_post_process_depfile () +{ + # If the compiler actually managed to produce a dependency file, + # post-process it. + if test -f "$tmpdepfile"; then + # Each line is of the form 'foo.o: dependency.h'. + # Do two passes, one to just change these to + # $object: dependency.h + # and one to simply output + # dependency.h: + # which is needed to avoid the deleted-header problem. + { sed -e "s,^.*\.[$lower]*:,$object:," < "$tmpdepfile" + sed -e "s,^.*\.[$lower]*:[$tab ]*,," -e 's,$,:,' < "$tmpdepfile" + } > "$depfile" + rm -f "$tmpdepfile" + else + make_dummy_depfile + fi +} + +# A tabulation character. +tab=' ' +# A newline character. +nl=' +' +# Character ranges might be problematic outside the C locale. +# These definitions help. +upper=ABCDEFGHIJKLMNOPQRSTUVWXYZ +lower=abcdefghijklmnopqrstuvwxyz +digits=0123456789 +alpha=${upper}${lower} + +if test -z "$depmode" || test -z "$source" || test -z "$object"; then + echo "depcomp: Variables source, object and depmode must be set" 1>&2 + exit 1 +fi + +# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. +depfile=${depfile-`echo "$object" | + sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} +tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} + +rm -f "$tmpdepfile" + +# Avoid interferences from the environment. +gccflag= dashmflag= + +# Some modes work just like other modes, but use different flags. We +# parameterize here, but still list the modes in the big case below, +# to make depend.m4 easier to write. Note that we *cannot* use a case +# here, because this file can only contain one case statement. +if test "$depmode" = hp; then + # HP compiler uses -M and no extra arg. + gccflag=-M + depmode=gcc +fi + +if test "$depmode" = dashXmstdout; then + # This is just like dashmstdout with a different argument. + dashmflag=-xM + depmode=dashmstdout +fi + +cygpath_u="cygpath -u -f -" +if test "$depmode" = msvcmsys; then + # This is just like msvisualcpp but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvisualcpp +fi + +if test "$depmode" = msvc7msys; then + # This is just like msvc7 but w/o cygpath translation. + # Just convert the backslash-escaped backslashes to single forward + # slashes to satisfy depend.m4 + cygpath_u='sed s,\\\\,/,g' + depmode=msvc7 +fi + +if test "$depmode" = xlc; then + # IBM C/C++ Compilers xlc/xlC can output gcc-like dependency information. + gccflag=-qmakedep=gcc,-MF + depmode=gcc +fi + +case "$depmode" in +gcc3) +## gcc 3 implements dependency tracking that does exactly what +## we want. Yay! Note: for some reason libtool 1.4 doesn't like +## it if -MD -MP comes after the -MF stuff. Hmm. +## Unfortunately, FreeBSD c89 acceptance of flags depends upon +## the command line argument order; so add the flags where they +## appear in depend2.am. Note that the slowdown incurred here +## affects only configure: in makefiles, %FASTDEP% shortcuts this. + for arg + do + case $arg in + -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; + *) set fnord "$@" "$arg" ;; + esac + shift # fnord + shift # $arg + done + "$@" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + mv "$tmpdepfile" "$depfile" + ;; + +gcc) +## Note that this doesn't just cater to obsosete pre-3.x GCC compilers. +## but also to in-use compilers like IMB xlc/xlC and the HP C compiler. +## (see the conditional assignment to $gccflag above). +## There are various ways to get dependency output from gcc. Here's +## why we pick this rather obscure method: +## - Don't want to use -MD because we'd like the dependencies to end +## up in a subdir. Having to rename by hand is ugly. +## (We might end up doing this anyway to support other compilers.) +## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like +## -MM, not -M (despite what the docs say). Also, it might not be +## supported by the other compilers which use the 'gcc' depmode. +## - Using -M directly means running the compiler twice (even worse +## than renaming). + if test -z "$gccflag"; then + gccflag=-MD, + fi + "$@" -Wp,"$gccflag$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The second -e expression handles DOS-style file names with drive + # letters. + sed -e 's/^[^:]*: / /' \ + -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" +## This next piece of magic avoids the "deleted header file" problem. +## The problem is that when a header file which appears in a .P file +## is deleted, the dependency causes make to die (because there is +## typically no way to rebuild the header). We avoid this by adding +## dummy dependencies for each header file. Too bad gcc doesn't do +## this for us directly. +## Some versions of gcc put a space before the ':'. On the theory +## that the space means something, we add a space to the output as +## well. hp depmode also adds that space, but also prefixes the VPATH +## to the object. Take care to not repeat it in the output. +## Some versions of the HPUX 10.20 sed can't process this invocation +## correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e "s|.*$object$||" -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +sgi) + if test "$libtool" = yes; then + "$@" "-Wp,-MDupdate,$tmpdepfile" + else + "$@" -MDupdate "$tmpdepfile" + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + + if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files + echo "$object : \\" > "$depfile" + # Clip off the initial element (the dependent). Don't try to be + # clever and replace this with sed code, as IRIX sed won't handle + # lines with more than a fixed number of characters (4096 in + # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; + # the IRIX cc adds comments like '#:fec' to the end of the + # dependency line. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' \ + | tr "$nl" ' ' >> "$depfile" + echo >> "$depfile" + # The second pass generates a dummy entry for each header file. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ + >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" + ;; + +xlc) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +aix) + # The C for AIX Compiler uses -M and outputs the dependencies + # in a .u file. In older versions, this file always lives in the + # current directory. Also, the AIX compiler puts '$object:' at the + # start of each line; $object doesn't have directory information. + # Version 6 uses the directory in both cases. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.u + tmpdepfile2=$base.u + tmpdepfile3=$dir.libs/$base.u + "$@" -Wc,-M + else + tmpdepfile1=$dir$base.u + tmpdepfile2=$dir$base.u + tmpdepfile3=$dir$base.u + "$@" -M + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + aix_post_process_depfile + ;; + +tcc) + # tcc (Tiny C Compiler) understand '-MD -MF file' since version 0.9.26 + # FIXME: That version still under development at the moment of writing. + # Make that this statement remains true also for stable, released + # versions. + # It will wrap lines (doesn't matter whether long or short) with a + # trailing '\', as in: + # + # foo.o : \ + # foo.c \ + # foo.h \ + # + # It will put a trailing '\' even on the last line, and will use leading + # spaces rather than leading tabs (at least since its commit 0394caf7 + # "Emit spaces for -MD"). + "$@" -MD -MF "$tmpdepfile" + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each non-empty line is of the form 'foo.o : \' or ' dep.h \'. + # We have to change lines of the first kind to '$object: \'. + sed -e "s|.*:|$object :|" < "$tmpdepfile" > "$depfile" + # And for each line of the second kind, we have to emit a 'dep.h:' + # dummy dependency, to avoid the deleted-header problem. + sed -n -e 's|^ *\(.*\) *\\$|\1:|p' < "$tmpdepfile" >> "$depfile" + rm -f "$tmpdepfile" + ;; + +## The order of this option in the case statement is important, since the +## shell code in configure will try each of these formats in the order +## listed in this file. A plain '-MD' option would be understood by many +## compilers, so we must ensure this comes after the gcc and icc options. +pgcc) + # Portland's C compiler understands '-MD'. + # Will always output deps to 'file.d' where file is the root name of the + # source file under compilation, even if file resides in a subdirectory. + # The object file name does not affect the name of the '.d' file. + # pgcc 10.2 will output + # foo.o: sub/foo.c sub/foo.h + # and will wrap long lines using '\' : + # foo.o: sub/foo.c ... \ + # sub/foo.h ... \ + # ... + set_dir_from "$object" + # Use the source, not the object, to determine the base name, since + # that's sadly what pgcc will do too. + set_base_from "$source" + tmpdepfile=$base.d + + # For projects that build the same source file twice into different object + # files, the pgcc approach of using the *source* file root name can cause + # problems in parallel builds. Use a locking strategy to avoid stomping on + # the same $tmpdepfile. + lockdir=$base.d-lock + trap " + echo '$0: caught signal, cleaning up...' >&2 + rmdir '$lockdir' + exit 1 + " 1 2 13 15 + numtries=100 + i=$numtries + while test $i -gt 0; do + # mkdir is a portable test-and-set. + if mkdir "$lockdir" 2>/dev/null; then + # This process acquired the lock. + "$@" -MD + stat=$? + # Release the lock. + rmdir "$lockdir" + break + else + # If the lock is being held by a different process, wait + # until the winning process is done or we timeout. + while test -d "$lockdir" && test $i -gt 0; do + sleep 1 + i=`expr $i - 1` + done + fi + i=`expr $i - 1` + done + trap - 1 2 13 15 + if test $i -le 0; then + echo "$0: failed to acquire lock after $numtries attempts" >&2 + echo "$0: check lockdir '$lockdir'" >&2 + exit 1 + fi + + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + # Each line is of the form `foo.o: dependent.h', + # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. + # Do two passes, one to just change these to + # `$object: dependent.h' and one to simply `dependent.h:'. + sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +hp2) + # The "hp" stanza above does not work with aCC (C++) and HP's ia64 + # compilers, which have integrated preprocessors. The correct option + # to use with these is +Maked; it writes dependencies to a file named + # 'foo.d', which lands next to the object file, wherever that + # happens to be. + # Much of this is similar to the tru64 case; see comments there. + set_dir_from "$object" + set_base_from "$object" + if test "$libtool" = yes; then + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir.libs/$base.d + "$@" -Wc,+Maked + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + "$@" +Maked + fi + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" + do + test -f "$tmpdepfile" && break + done + if test -f "$tmpdepfile"; then + sed -e "s,^.*\.[$lower]*:,$object:," "$tmpdepfile" > "$depfile" + # Add 'dependent.h:' lines. + sed -ne '2,${ + s/^ *// + s/ \\*$// + s/$/:/ + p + }' "$tmpdepfile" >> "$depfile" + else + make_dummy_depfile + fi + rm -f "$tmpdepfile" "$tmpdepfile2" + ;; + +tru64) + # The Tru64 compiler uses -MD to generate dependencies as a side + # effect. 'cc -MD -o foo.o ...' puts the dependencies into 'foo.o.d'. + # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put + # dependencies in 'foo.d' instead, so we check for that too. + # Subdirectories are respected. + set_dir_from "$object" + set_base_from "$object" + + if test "$libtool" = yes; then + # Libtool generates 2 separate objects for the 2 libraries. These + # two compilations output dependencies in $dir.libs/$base.o.d and + # in $dir$base.o.d. We have to check for both files, because + # one of the two compilations can be disabled. We should prefer + # $dir$base.o.d over $dir.libs/$base.o.d because the latter is + # automatically cleaned when .libs/ is deleted, while ignoring + # the former would cause a distcleancheck panic. + tmpdepfile1=$dir$base.o.d # libtool 1.5 + tmpdepfile2=$dir.libs/$base.o.d # Likewise. + tmpdepfile3=$dir.libs/$base.d # Compaq CCC V6.2-504 + "$@" -Wc,-MD + else + tmpdepfile1=$dir$base.d + tmpdepfile2=$dir$base.d + tmpdepfile3=$dir$base.d + "$@" -MD + fi + + stat=$? + if test $stat -ne 0; then + rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + exit $stat + fi + + for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" + do + test -f "$tmpdepfile" && break + done + # Same post-processing that is required for AIX mode. + aix_post_process_depfile + ;; + +msvc7) + if test "$libtool" = yes; then + showIncludes=-Wc,-showIncludes + else + showIncludes=-showIncludes + fi + "$@" $showIncludes > "$tmpdepfile" + stat=$? + grep -v '^Note: including file: ' "$tmpdepfile" + if test $stat -ne 0; then + rm -f "$tmpdepfile" + exit $stat + fi + rm -f "$depfile" + echo "$object : \\" > "$depfile" + # The first sed program below extracts the file names and escapes + # backslashes for cygpath. The second sed program outputs the file + # name when reading, but also accumulates all include files in the + # hold buffer in order to output them again at the end. This only + # works with sed implementations that can handle large buffers. + sed < "$tmpdepfile" -n ' +/^Note: including file: *\(.*\)/ { + s//\1/ + s/\\/\\\\/g + p +}' | $cygpath_u | sort -u | sed -n ' +s/ /\\ /g +s/\(.*\)/'"$tab"'\1 \\/p +s/.\(.*\) \\/\1:/ +H +$ { + s/.*/'"$tab"'/ + G + p +}' >> "$depfile" + echo >> "$depfile" # make sure the fragment doesn't end with a backslash + rm -f "$tmpdepfile" + ;; + +msvc7msys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +#nosideeffect) + # This comment above is used by automake to tell side-effect + # dependency tracking mechanisms from slower ones. + +dashmstdout) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout, regardless of -o. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + test -z "$dashmflag" && dashmflag=-M + # Require at least two characters before searching for ':' + # in the target name. This is to cope with DOS-style filenames: + # a dependency such as 'c:/foo/bar' could be seen as target 'c' otherwise. + "$@" $dashmflag | + sed "s|^[$tab ]*[^:$tab ][^:][^:]*:[$tab ]*|$object: |" > "$tmpdepfile" + rm -f "$depfile" + cat < "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process this sed invocation + # correctly. Breaking it into two sed invocations is a workaround. + tr ' ' "$nl" < "$tmpdepfile" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +dashXmstdout) + # This case only exists to satisfy depend.m4. It is never actually + # run, as this mode is specially recognized in the preamble. + exit 1 + ;; + +makedepend) + "$@" || exit $? + # Remove any Libtool call + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + # X makedepend + shift + cleared=no eat=no + for arg + do + case $cleared in + no) + set ""; shift + cleared=yes ;; + esac + if test $eat = yes; then + eat=no + continue + fi + case "$arg" in + -D*|-I*) + set fnord "$@" "$arg"; shift ;; + # Strip any option that makedepend may not understand. Remove + # the object too, otherwise makedepend will parse it as a source file. + -arch) + eat=yes ;; + -*|$object) + ;; + *) + set fnord "$@" "$arg"; shift ;; + esac + done + obj_suffix=`echo "$object" | sed 's/^.*\././'` + touch "$tmpdepfile" + ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" + rm -f "$depfile" + # makedepend may prepend the VPATH from the source file name to the object. + # No need to regex-escape $object, excess matching of '.' is harmless. + sed "s|^.*\($object *:\)|\1|" "$tmpdepfile" > "$depfile" + # Some versions of the HPUX 10.20 sed can't process the last invocation + # correctly. Breaking it into two sed invocations is a workaround. + sed '1,2d' "$tmpdepfile" \ + | tr ' ' "$nl" \ + | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' \ + | sed -e 's/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" "$tmpdepfile".bak + ;; + +cpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + # Remove '-o $object'. + IFS=" " + for arg + do + case $arg in + -o) + shift + ;; + $object) + shift + ;; + *) + set fnord "$@" "$arg" + shift # fnord + shift # $arg + ;; + esac + done + + "$@" -E \ + | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ + | sed '$ s: \\$::' > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + cat < "$tmpdepfile" >> "$depfile" + sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvisualcpp) + # Important note: in order to support this mode, a compiler *must* + # always write the preprocessed file to stdout. + "$@" || exit $? + + # Remove the call to Libtool. + if test "$libtool" = yes; then + while test "X$1" != 'X--mode=compile'; do + shift + done + shift + fi + + IFS=" " + for arg + do + case "$arg" in + -o) + shift + ;; + $object) + shift + ;; + "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") + set fnord "$@" + shift + shift + ;; + *) + set fnord "$@" "$arg" + shift + shift + ;; + esac + done + "$@" -E 2>/dev/null | + sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile" + rm -f "$depfile" + echo "$object : \\" > "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::'"$tab"'\1 \\:p' >> "$depfile" + echo "$tab" >> "$depfile" + sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile" + rm -f "$tmpdepfile" + ;; + +msvcmsys) + # This case exists only to let depend.m4 do its work. It works by + # looking at the text of this script. This case will never be run, + # since it is checked for above. + exit 1 + ;; + +none) + exec "$@" + ;; + +*) + echo "Unknown depmode $depmode" 1>&2 + exit 1 + ;; +esac + +exit 0 + +# Local Variables: +# mode: shell-script +# sh-indentation: 2 +# eval: (add-hook 'before-save-hook 'time-stamp) +# time-stamp-start: "scriptversion=" +# time-stamp-format: "%:y-%02m-%02d.%02H" +# time-stamp-time-zone: "UTC0" +# time-stamp-end: "; # UTC" +# End: diff --git a/test/dns-dump.cc b/test/dns-dump.cc index 023de36..f00a2d4 100644 --- a/test/dns-dump.cc +++ b/test/dns-dump.cc @@ -1,6 +1,10 @@ #include #include -#include +#ifdef _MSC_VER +# include +#else +# include +#endif #include #include @@ -31,5 +35,6 @@ int main(int argc, char* argv[]) { for (int ii = 1; ii < argc; ++ii) { ares::ShowFile(argv[ii]); } + return 0; } diff --git a/test/dns-proto.cc b/test/dns-proto.cc index 8eb7f2e..d2fa8b1 100644 --- a/test/dns-proto.cc +++ b/test/dns-proto.cc @@ -1,6 +1,7 @@ #include "dns-proto.h" // Include ares internal file for DNS protocol details +#include "ares_setup.h" #include "ares.h" #include "ares_dns.h" @@ -247,7 +248,7 @@ std::string QuestionToString(const std::vector& packet, *len -= enclen; *data += enclen; ss << "'" << name << "' "; - free(name); + ares_free_string(name); if (*len < NS_QFIXEDSZ) { ss << "(too short, len left " << *len << ")"; return ss.str(); @@ -283,7 +284,7 @@ std::string RRToString(const std::vector& packet, *len -= enclen; *data += enclen; ss << "'" << name << "' "; - free(name); + ares_free_string(name); name = nullptr; if (*len < NS_RRFIXEDSZ) { @@ -335,7 +336,7 @@ std::string RRToString(const std::vector& packet, break; } ss << " '" << name << "'"; - free(name); + ares_free_string(name); break; } case ns_t_mx: @@ -346,7 +347,7 @@ std::string RRToString(const std::vector& packet, break; } ss << " " << DNS__16BIT(*data) << " '" << name << "'"; - free(name); + ares_free_string(name); } else { ss << "(RR too short)"; } @@ -364,7 +365,7 @@ std::string RRToString(const std::vector& packet, break; } ss << prio << " " << weight << " " << port << " '" << name << "'"; - free(name); + ares_free_string(name); } else { ss << "(RR too short)"; } @@ -378,7 +379,7 @@ std::string RRToString(const std::vector& packet, break; } ss << " '" << name << "'"; - free(name); + ares_free_string(name); p += enclen; rc = ares_expand_name(p, packet.data(), packet.size(), &name, &enclen); if (rc != ARES_SUCCESS) { @@ -386,7 +387,7 @@ std::string RRToString(const std::vector& packet, break; } ss << " '" << name << "'"; - free(name); + ares_free_string(name); p += enclen; if ((p + 20) <= (*data + rdatalen)) { unsigned long serial = DNS__32BIT(p); @@ -429,7 +430,7 @@ std::string RRToString(const std::vector& packet, break; } ss << " '" << name << "'"; - free(name); + ares_free_string(name); } else { ss << "(RR too short)"; } diff --git a/test/fuzzcheck.sh b/test/fuzzcheck.sh new file mode 100755 index 0000000..3a13766 --- /dev/null +++ b/test/fuzzcheck.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -e +# Check that all of the base fuzzing corpus parse without errors +./aresfuzz fuzzinput/* +./aresfuzzname fuzznames/* diff --git a/test/gmock-1.7.0/gtest/src/gtest-all.cc b/test/gmock-1.7.0/gtest/src/gtest-all.cc deleted file mode 100644 index 0a9cee5..0000000 --- a/test/gmock-1.7.0/gtest/src/gtest-all.cc +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2008, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Author: mheule@google.com (Markus Heule) -// -// Google C++ Testing Framework (Google Test) -// -// Sometimes it's desirable to build Google Test by compiling a single file. -// This file serves this purpose. - -// This line ensures that gtest.h can be compiled on its own, even -// when it's fused. -#include "gtest/gtest.h" - -// The following lines pull in the real gtest *.cc files. -#include "src/gtest.cc" -#include "src/gtest-death-test.cc" -#include "src/gtest-filepath.cc" -#include "src/gtest-port.cc" -#include "src/gtest-printers.cc" -#include "src/gtest-test-part.cc" -#include "src/gtest-typed-test.cc" diff --git a/test/gmock-1.7.0/src/gmock-all.cc b/test/gmock-1.7.0/src/gmock-all.cc deleted file mode 100644 index 7aebce7..0000000 --- a/test/gmock-1.7.0/src/gmock-all.cc +++ /dev/null @@ -1,47 +0,0 @@ -// 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) -// -// Google C++ Mocking Framework (Google Mock) -// -// This file #includes all Google Mock implementation .cc files. The -// purpose is to allow a user to build Google Mock by compiling this -// file alone. - -// This line ensures that gmock.h can be compiled on its own, even -// when it's fused. -#include "gmock/gmock.h" - -// The following lines pull in the real gmock *.cc files. -#include "src/gmock-cardinalities.cc" -#include "src/gmock-internal-utils.cc" -#include "src/gmock-matchers.cc" -#include "src/gmock-spec-builders.cc" -#include "src/gmock.cc" diff --git a/test/gmock-1.8.0/gmock-gtest-all.cc b/test/gmock-1.8.0/gmock-gtest-all.cc new file mode 100644 index 0000000..b3d980b --- /dev/null +++ b/test/gmock-1.8.0/gmock-gtest-all.cc @@ -0,0 +1,12265 @@ +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include // NOLINT +#include +#include + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include // NOLINT +# include // NOLINT +# include // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include // NOLINT +# undef min + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# undef min + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include // NOLINT +# include // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +# include // NOLINT +# include // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// If this file is included from the user's code, just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include +#endif // !_WIN32_WCE +#include +#include // For strtoll/_strtoul64/malloc/free. +#include // For memmove. + +#include +#include +#include + + +#if GTEST_CAN_STREAM_RESULTS_ +# include // NOLINT +# include // NOLINT +#endif + +#if GTEST_OS_WINDOWS +# include // NOLINT +#endif // GTEST_OS_WINDOWS + + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; +const char kFlagfileFlag[] = "flagfile"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Converts the given time in milliseconds to a date string in the ISO 8601 +// format, without the timezone information. N.B.: due to the use the +// non-reentrant localtime() function, this function is not thread safe. Do +// not use it in any code that can be called from multiple threads. +GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast(GetTimeInMillis()) : + static_cast(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +GTEST_API_ std::string CodePointToUtf8(UInt32 code_point); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ std::string WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template +inline E GetElementOr(const std::vector& v, int i, E default_value) { + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector* v) { + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template +inline void Shuffle(internal::Random* random, std::vector* v) { + ShuffleRange(random, 0, static_cast(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return test_property.key() == key_; + } + + private: + std::string key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() {} + + virtual string CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + std::string message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ std::string GetLastErrnoDescription(); + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) { + test_result->RecordProperty(xml_element, property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class GTEST_API_ StreamingListener : public EmptyTestEventListener { + public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter { + public: + virtual ~AbstractSocketWriter() {} + + // Sends a string to the socket. + virtual void Send(const string& message) = 0; + + // Closes the socket. + virtual void CloseConnection() {} + + // Sends a string and a newline to the socket. + void SendLn(const string& message) { + Send(message + "\n"); + } + }; + + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + } + + virtual ~SocketWriter() { + if (sockfd_ != -1) + CloseConnection(); + } + + // Sends a string to the socket. + virtual void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter + + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } + + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + SendLn("event=TestProgramStart"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } + + void OnTestCaseStart(const TestCase& test_case) { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } + + void OnTestCaseEnd(const TestCase& test_case) { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + + "ms"); + } + + void OnTestStart(const TestInfo& test_info) { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } + + void OnTestEnd(const TestInfo& test_info) { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } + + private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } + + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + + string FormatBool(bool value) { return value ? "1" : "0"; } + + const scoped_ptr socket_writer_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +#endif // GTEST_CAN_STREAM_RESULTS_ + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +static const char* GetDefaultFilter() { +#ifdef GTEST_TEST_FILTER_ENV_VAR_ + const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_); + if (testbridge_test_only != NULL) { + return testbridge_test_only; + } +#endif // GTEST_TEST_FILTER_ENV_VAR_ + return kUniversalFilter; +} + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +GTEST_DEFINE_string_( + flagfile, + internal::StringFromGTestEnv("flagfile", ""), + "This flag specifies the flagfile to read command-line flags from."); +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +static bool GTestIsInitialized() { return GetArgvs().size() > 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector g_argvs; + +const ::std::vector& GetArgvs() { +#if defined(GTEST_CUSTOM_GET_ARGVS_) + return GTEST_CUSTOM_GET_ARGVS_(); +#else // defined(GTEST_CUSTOM_GET_ARGVS_) + return g_argvs; +#endif // defined(GTEST_CUSTOM_GET_ARGVS_) +} + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(GetArgvs()[0]).RemoveExtension("exe")); +#else + result.Set(FilePath(GetArgvs()[0])); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +std::string UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + std::string(gtest_output_flag) : + std::string(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +std::string UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).string(); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.string(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter( + const std::string& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, + const std::string &test_name) { + const std::string& full_name = test_case_name + "." + test_name.c_str(); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } else { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const std::string expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTestImpl::reportable_disabled_test_count() const { + return SumOverTestCaseList(test_cases_, + &TestCase::reportable_disabled_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTestImpl::reportable_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + return os_stack_trace_getter()->CurrentStackTrace( + static_cast(GTEST_FLAG(stack_trace_depth)), + skip_count + 1 + // Skips the user-specified number of frames plus this function + // itself. + ); // NOLINT +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) + _ftime64(&now); + GTEST_DISABLE_MSC_WARNINGS_POP_() + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String. + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +} // namespace internal + +// Constructs an empty Message. +// We allocate the stringstream separately because otherwise each use of +// ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's +// stack frame leading to huge stack frames in some cases; gcc does not reuse +// the stack space. +Message::Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +} + +// These two overloads allow streaming a wide C string to a Message +// using the UTF-8 encoding. +Message& Message::operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} +Message& Message::operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); +} + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Gets the text streamed to this object so far as an std::string. +// Each '\0' character in the buffer is replaced with "\\0". +std::string Message::GetString() const { + return internal::StringStreamToString(ss_.get()); +} + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +namespace edit_distance { +std::vector CalculateOptimalEdits(const std::vector& left, + const std::vector& right) { + std::vector > costs( + left.size() + 1, std::vector(right.size() + 1)); + std::vector > best_move( + left.size() + 1, std::vector(right.size() + 1)); + + // Populate for empty right. + for (size_t l_i = 0; l_i < costs.size(); ++l_i) { + costs[l_i][0] = static_cast(l_i); + best_move[l_i][0] = kRemove; + } + // Populate for empty left. + for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { + costs[0][r_i] = static_cast(r_i); + best_move[0][r_i] = kAdd; + } + + for (size_t l_i = 0; l_i < left.size(); ++l_i) { + for (size_t r_i = 0; r_i < right.size(); ++r_i) { + if (left[l_i] == right[r_i]) { + // Found a match. Consume it. + costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; + best_move[l_i + 1][r_i + 1] = kMatch; + continue; + } + + const double add = costs[l_i + 1][r_i]; + const double remove = costs[l_i][r_i + 1]; + const double replace = costs[l_i][r_i]; + if (add < remove && add < replace) { + costs[l_i + 1][r_i + 1] = add + 1; + best_move[l_i + 1][r_i + 1] = kAdd; + } else if (remove < add && remove < replace) { + costs[l_i + 1][r_i + 1] = remove + 1; + best_move[l_i + 1][r_i + 1] = kRemove; + } else { + // We make replace a little more expensive than add/remove to lower + // their priority. + costs[l_i + 1][r_i + 1] = replace + 1.00001; + best_move[l_i + 1][r_i + 1] = kReplace; + } + } + } + + // Reconstruct the best path. We do it in reverse order. + std::vector best_path; + for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { + EditType move = best_move[l_i][r_i]; + best_path.push_back(move); + l_i -= move != kAdd; + r_i -= move != kRemove; + } + std::reverse(best_path.begin(), best_path.end()); + return best_path; +} + +namespace { + +// Helper class to convert string into ids with deduplication. +class InternalStrings { + public: + size_t GetId(const std::string& str) { + IdMap::iterator it = ids_.find(str); + if (it != ids_.end()) return it->second; + size_t id = ids_.size(); + return ids_[str] = id; + } + + private: + typedef std::map IdMap; + IdMap ids_; +}; + +} // namespace + +std::vector CalculateOptimalEdits( + const std::vector& left, + const std::vector& right) { + std::vector left_ids, right_ids; + { + InternalStrings intern_table; + for (size_t i = 0; i < left.size(); ++i) { + left_ids.push_back(intern_table.GetId(left[i])); + } + for (size_t i = 0; i < right.size(); ++i) { + right_ids.push_back(intern_table.GetId(right[i])); + } + } + return CalculateOptimalEdits(left_ids, right_ids); +} + +namespace { + +// Helper class that holds the state for one hunk and prints it out to the +// stream. +// It reorders adds/removes when possible to group all removes before all +// adds. It also adds the hunk header before printint into the stream. +class Hunk { + public: + Hunk(size_t left_start, size_t right_start) + : left_start_(left_start), + right_start_(right_start), + adds_(), + removes_(), + common_() {} + + void PushLine(char edit, const char* line) { + switch (edit) { + case ' ': + ++common_; + FlushEdits(); + hunk_.push_back(std::make_pair(' ', line)); + break; + case '-': + ++removes_; + hunk_removes_.push_back(std::make_pair('-', line)); + break; + case '+': + ++adds_; + hunk_adds_.push_back(std::make_pair('+', line)); + break; + } + } + + void PrintTo(std::ostream* os) { + PrintHeader(os); + FlushEdits(); + for (std::list >::const_iterator it = + hunk_.begin(); + it != hunk_.end(); ++it) { + *os << it->first << it->second << "\n"; + } + } + + bool has_edits() const { return adds_ || removes_; } + + private: + void FlushEdits() { + hunk_.splice(hunk_.end(), hunk_removes_); + hunk_.splice(hunk_.end(), hunk_adds_); + } + + // Print a unified diff header for one hunk. + // The format is + // "@@ -, +, @@" + // where the left/right parts are ommitted if unnecessary. + void PrintHeader(std::ostream* ss) const { + *ss << "@@ "; + if (removes_) { + *ss << "-" << left_start_ << "," << (removes_ + common_); + } + if (removes_ && adds_) { + *ss << " "; + } + if (adds_) { + *ss << "+" << right_start_ << "," << (adds_ + common_); + } + *ss << " @@\n"; + } + + size_t left_start_, right_start_; + size_t adds_, removes_, common_; + std::list > hunk_, hunk_adds_, hunk_removes_; +}; + +} // namespace + +// Create a list of diff hunks in Unified diff format. +// Each hunk has a header generated by PrintHeader above plus a body with +// lines prefixed with ' ' for no change, '-' for deletion and '+' for +// addition. +// 'context' represents the desired unchanged prefix/suffix around the diff. +// If two hunks are close enough that their contexts overlap, then they are +// joined into one hunk. +std::string CreateUnifiedDiff(const std::vector& left, + const std::vector& right, + size_t context) { + const std::vector edits = CalculateOptimalEdits(left, right); + + size_t l_i = 0, r_i = 0, edit_i = 0; + std::stringstream ss; + while (edit_i < edits.size()) { + // Find first edit. + while (edit_i < edits.size() && edits[edit_i] == kMatch) { + ++l_i; + ++r_i; + ++edit_i; + } + + // Find the first line to include in the hunk. + const size_t prefix_context = std::min(l_i, context); + Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); + for (size_t i = prefix_context; i > 0; --i) { + hunk.PushLine(' ', left[l_i - i].c_str()); + } + + // Iterate the edits until we found enough suffix for the hunk or the input + // is over. + size_t n_suffix = 0; + for (; edit_i < edits.size(); ++edit_i) { + if (n_suffix >= context) { + // Continue only if the next hunk is very close. + std::vector::const_iterator it = edits.begin() + edit_i; + while (it != edits.end() && *it == kMatch) ++it; + if (it == edits.end() || (it - edits.begin()) - edit_i >= context) { + // There is no next edit or it is too far away. + break; + } + } + + EditType edit = edits[edit_i]; + // Reset count when a non match is found. + n_suffix = edit == kMatch ? n_suffix + 1 : 0; + + if (edit == kMatch || edit == kRemove || edit == kReplace) { + hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); + } + if (edit == kAdd || edit == kReplace) { + hunk.PushLine('+', right[r_i].c_str()); + } + + // Advance indices, depending on edit type. + l_i += edit != kAdd; + r_i += edit != kRemove; + } + + if (!hunk.has_edits()) { + // We are done. We don't want this hunk. + break; + } + + hunk.PrintTo(&ss); + } + return ss.str(); +} + +} // namespace edit_distance + +namespace { + +// The string representation of the values received in EqFailure() are already +// escaped. Split them on escaped '\n' boundaries. Leave all other escaped +// characters the same. +std::vector SplitEscapedString(const std::string& str) { + std::vector lines; + size_t start = 0, end = str.size(); + if (end > 2 && str[0] == '"' && str[end - 1] == '"') { + ++start; + --end; + } + bool escaped = false; + for (size_t i = start; i + 1 < end; ++i) { + if (escaped) { + escaped = false; + if (str[i] == 'n') { + lines.push_back(str.substr(start, i - start - 1)); + start = i + 1; + } + } else { + escaped = str[i] == '\\'; + } + } + lines.push_back(str.substr(start, end - start)); + return lines; +} + +} // namespace + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// lhs_expression: "foo" +// rhs_expression: "bar" +// lhs_value: "5" +// rhs_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string "Ignoring case" will +// be inserted into the message. +AssertionResult EqFailure(const char* lhs_expression, + const char* rhs_expression, + const std::string& lhs_value, + const std::string& rhs_value, + bool ignoring_case) { + Message msg; + msg << " Expected: " << lhs_expression; + if (lhs_value != lhs_expression) { + msg << "\n Which is: " << lhs_value; + } + msg << "\nTo be equal to: " << rhs_expression; + if (rhs_value != rhs_expression) { + msg << "\n Which is: " << rhs_value; + } + + if (ignoring_case) { + msg << "\nIgnoring case"; + } + + if (!lhs_value.empty() && !rhs_value.empty()) { + const std::vector lhs_lines = + SplitEscapedString(lhs_value); + const std::vector rhs_lines = + SplitEscapedString(rhs_value); + if (lhs_lines.size() > 1 || rhs_lines.size() > 1) { + msg << "\nWith diff:\n" + << edit_distance::CreateUnifiedDiff(lhs_lines, rhs_lines); + } + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +std::string GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* lhs_expression, + const char* rhs_expression, + BiggestInt lhs, + BiggestInt rhs) { + if (lhs == rhs) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + FormatForComparisonFailureMessage(lhs, rhs), + FormatForComparisonFailureMessage(rhs, lhs), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* lhs_expression, + const char* rhs_expression, + const char* lhs, + const char* rhs) { + if (String::CStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* lhs_expression, + const char* rhs_expression, + const char* lhs, + const char* rhs) { + if (String::CaseInsensitiveCStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted +// to "(Invalid Unicode 0xXXXXXXXX)". +std::string CodePointToUtf8(UInt32 code_point) { + if (code_point > kMaxCodePoint4) { + return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; + } + + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } else { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +std::string WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast(str[i]); + } + + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to an std::string using the UTF-8 encoding. +// NULL will be converted to "(null)". +std::string String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return "(null)"; + + return internal::WideStringToUtf8(wide_c_str, -1); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* lhs_expression, + const char* rhs_expression, + const wchar_t* lhs, + const wchar_t* rhs) { + if (String::WideCStringEquals(lhs, rhs)) { + return AssertionSuccess(); + } + + return EqFailure(lhs_expression, + rhs_expression, + PrintToString(lhs), + PrintToString(rhs), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Returns true iff str ends with the given suffix, ignoring case. +// Any string is considered to end with an empty suffix. +bool String::EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix) { + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); +} + +// Formats an int value as "%02d". +std::string String::FormatIntWidth2(int value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); +} + +// Formats an int value as "%X". +std::string String::FormatHexInt(int value) { + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); +} + +// Formats a byte as "%02X". +std::string String::FormatByte(unsigned char value) { + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); +} + +// Converts the buffer in a stringstream to an std::string, converting NUL +// bytes to "\\0" along the way. +std::string StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + result += "\\0"; // Replaces NUL with "\\0"; + } else { + result += *ch; + } + } + + return result; +} + +// Appends the user-supplied message to the Google-Test-generated message. +std::string AppendUserMessage(const std::string& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + return gtest_msg + "\n" + user_msg_string; +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const std::string& xml_element, + const TestProperty& test_property) { + if (!ValidateTestProperty(xml_element, test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuitesAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp" +}; + +// The list of reserved attributes used in the element of XML +// output. +static const char* const kReservedTestSuiteAttributes[] = { + "disabled", + "errors", + "failures", + "name", + "tests", + "time" +}; + +// The list of reserved attributes used in the element of XML output. +static const char* const kReservedTestCaseAttributes[] = { + "classname", + "name", + "status", + "time", + "type_param", + "value_param" +}; + +template +std::vector ArrayAsVector(const char* const (&array)[kSize]) { + return std::vector(array, array + kSize); +} + +static std::vector GetReservedAttributesForElement( + const std::string& xml_element) { + if (xml_element == "testsuites") { + return ArrayAsVector(kReservedTestSuitesAttributes); + } else if (xml_element == "testsuite") { + return ArrayAsVector(kReservedTestSuiteAttributes); + } else if (xml_element == "testcase") { + return ArrayAsVector(kReservedTestCaseAttributes); + } else { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); +} + +static std::string FormatWordList(const std::vector& words) { + Message word_list; + for (size_t i = 0; i < words.size(); ++i) { + if (i > 0 && words.size() > 2) { + word_list << ", "; + } + if (i == words.size() - 1) { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); +} + +bool ValidateTestPropertyName(const std::string& property_name, + const std::vector& reserved_names) { + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Adds a failure if the key is a reserved attribute of the element named +// xml_element. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property) { + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the states of all flags. +Test::Test() + : gtest_flag_saver_(new GTEST_FLAG_SAVER_) { +} + +// The d'tor restores the states of all flags. The actual work is +// done by the d'tor of the gtest_flag_saver_ field, and thus not +// visible here. +Test::~Test() { +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, const std::string& value) { + UnitTest::GetInstance()->RecordProperty(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const std::string& key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const std::string& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // Both TEST and TEST_F appear in same test case, which is incorrect. + // Tell the user how to fix this. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // Two fixture classes with the same name appear in two different + // namespaces, which is not allowed. Tell the user how to fix this. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static std::string* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new std::string(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +namespace internal { + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static std::string FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result); + +GoogleTestFailureException::GoogleTestFailureException( + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + +#endif // GTEST_HAS_EXCEPTIONS + +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const internal::GoogleTestFailureException&) { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +TestInfo::TestInfo(const std::string& a_test_case_name, + const std::string& a_name, + const char* a_type_param, + const char* a_value_param, + internal::CodeLocation a_code_location, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + location_(a_code_location), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// code_location: code location where the test is defined +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + CodeLocation code_location, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + code_location, fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + CodeLocation code_location) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && test_info->name() == name_; + } + + private: + std::string name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +// Gets the number of disabled tests that will be reported in the XML report. +int TestCase::reportable_disabled_test_count() const { + return CountIf(test_info_list_, TestReportableDisabled); +} + +// Gets the number of disabled tests in this test case. +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Gets the number of tests to be printed in the XML report. +int TestCase::reportable_test_count() const { + return CountIf(test_info_list_, TestReportable); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static std::string FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static std::string FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static std::string FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +namespace internal { + +// Prints a TestPartResult to an std::string. +static std::string PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "tmux") || + String::CStringEquals(term, "tmux-256color") || + String::CStringEquals(term, "rxvt-unicode") || + String::CStringEquals(term, "rxvt-unicode-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \ + GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + const bool use_color = AlwaysFalse(); +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +// Text printed in Google Test's text output and --gunit_list_tests +// output to label the type parameter and value parameter for a test. +static const char kTypeParamLabel[] = "TypeParam"; +static const char kValueParamLabel[] = "GetParam()"; + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("%s = %s", kValueParamLabel, value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) { + return EscapeXml(str, false); + } + + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(::std::ostream* stream, + const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const std::string output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +std::string XmlUnitTestResultPrinter::EscapeXml( + const std::string& str, bool is_attribute) { + Message m; + + for (size_t i = 0; i < str.size(); ++i) { + const char ch = str[i]; + switch (ch) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( + const std::string& str) { + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <-- corresponds to a UnitTest object +// <-- corresponds to a TestCase object +// <-- corresponds to a TestInfo object +// ... +// ... +// ... +// <-- individual assertion failures +// +// +// + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << (static_cast(ms) * 1e-3); + return ss.str(); +} + +static bool PortableLocaltime(time_t seconds, struct tm* out) { +#if defined(_MSC_VER) + return localtime_s(out, &seconds) == 0; +#elif defined(__MINGW32__) || defined(__MINGW64__) + // MINGW provides neither localtime_r nor localtime_s, but uses + // Windows' localtime(), which has a thread-local tm buffer. + struct tm* tm_ptr = localtime(&seconds); // NOLINT + if (tm_ptr == NULL) + return false; + *out = *tm_ptr; + return true; +#else + return localtime_r(&seconds, out) != NULL; +#endif +} + +// Converts the given epoch time in milliseconds to a date string in the ISO +// 8601 format, without the timezone information. +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { + struct tm time_struct; + if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) + return ""; + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << ""); + if (next_segment != NULL) { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +void XmlUnitTestResultPrinter::OutputXmlAttribute( + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) { + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); + + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; + + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; + + *stream << " \n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, + const TestCase& test_case) { + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_case.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_case.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_case.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) + << ">\n"; + + for (int i = 0; i < test_case.total_test_count(); ++i) { + if (test_case.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + *stream << " \n"; +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, + const UnitTest& unit_test) { + const std::string kTestsuites = "testsuites"; + + *stream << "\n"; + *stream << "<" << kTestsuites; + + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + + if (GTEST_FLAG(shuffle)) { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } + + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) + PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); + } + *stream << "\n"; +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::SocketWriter::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +ScopedTrace::~ScopedTrace() + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +const char* const OsStackTraceGetterInterface::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/, + int /*skip_count*/) { + return ""; +} + +void OsStackTraceGetter::UponLeavingGTest() {} + +// A helper class that creates the premature-exit file in its +// constructor and deletes the file in its destructor. +class ScopedPrematureExitFile { + public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath) { + // If a path to the premature-exit file is specified... + if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } + + ~ScopedPrematureExitFile() { + if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { + remove(premature_exit_filepath_); + } + } + + private: + const char* const premature_exit_filepath_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); +}; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest* UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests that will be reported in the XML report. +int UnitTest::reportable_disabled_test_count() const { + return impl()->reportable_disabled_test_count(); +} + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of tests to be printed in the XML report. +int UnitTest::reportable_test_count() const { + return impl()->reportable_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the time of the test program start, in ms from the start of the +// UNIX epoch. +internal::TimeInMillis UnitTest::start_timestamp() const { + return impl()->start_timestamp(); +} + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Returns the TestResult containing information on test failures and +// properties logged outside of individual test cases. +const TestResult& UnitTest::ad_hoc_test_result() const { + return *impl()->ad_hoc_test_result(); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +void UnitTest::AddTestPartResult( + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw internal::GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Adds a TestProperty to the current TestResult object when invoked from +// inside a test, to current TestCase's ad_hoc_test_result_ when invoked +// from SetUpTestCase or TearDownTestCase, or to the global property set +// when invoked elsewhere. If the result already contains a property with +// the same key, the value will be updated. +void UnitTest::RecordProperty(const std::string& key, + const std::string& value) { + impl_->RecordProperty(TestProperty(key, value)); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. + + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process ? + NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { +# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +const TestCase* UnitTest::current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +const TestInfo* UnitTest::current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +void UnitTest::PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), + GTEST_DISABLE_MSC_WARNINGS_POP_() + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); + + // Deletes every Environment. + ForEach(environments_, internal::Delete); + + delete os_stack_trace_getter_; +} + +// Adds a TestProperty to the current TestResult object when invoked in a +// context of a test, to current test case's ad_hoc_test_result when invoke +// from SetUpTestCase/TearDownTestCase, or to the global property set +// otherwise. If the result already contains a property with the same key, +// the value will be updated. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) { + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. + + if (current_test_info_ != NULL) { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } else if (current_test_case_ != NULL) { + xml_element = "testsuite"; + test_result = &(current_test_case_->ad_hoc_test_result_); + } else { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in string form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != std::string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + // Register to send notifications about key process state changes. + listeners()->Append(new GTEST_CUSTOM_TEST_EVENT_LISTENER_()); +#endif // defined(GTEST_CUSTOM_TEST_EVENT_LISTENER_) + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + std::string name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +# if defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) + if (in_subprocess_for_death_test) { + GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_(); + } +# endif // defined(GTEST_EXTRA_DEATH_TEST_CHILD_SETUP_) +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const std::string &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the given C-string on a single line by replacing all '\n' +// characters with string "\\n". If the output takes more than +// max_length characters, only prints the first max_length characters +// and "...". +static void PrintOnOneLine(const char* str, int max_length) { + if (str != NULL) { + for (int i = 0; *str != '\0'; ++str) { + if (i >= max_length) { + printf("..."); + break; + } + if (*str == '\n') { + printf("\\n"); + i += 2; + } else { + printf("%c", *str); + ++i; + } + } + } +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; + + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.", test_case->name()); + if (test_case->type_param() != NULL) { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_case->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != NULL) { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { +#ifdef GTEST_OS_STACK_TRACE_GETTER_ + os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; +#else + os_stack_trace_getter_ = new OsStackTraceGetter; +#endif // GTEST_OS_STACK_TRACE_GETTER_ + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } +} + +// Returns the current OS stack trace as an std::string. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, std::string* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", std::string(str, p).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +bool ParseGoogleTestFlag(const char* const arg) { + return ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)); +} + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +void LoadFlagsFromFile(const std::string& path) { + FILE* flagfile = posix::FOpen(path.c_str(), "r"); + if (!flagfile) { + fprintf(stderr, + "Unable to open file \"%s\"\n", + GTEST_FLAG(flagfile).c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::string contents(ReadEntireFile(flagfile)); + posix::FClose(flagfile); + std::vector lines; + SplitString(contents, '\n', &lines); + for (size_t i = 0; i < lines.size(); ++i) { + if (lines[i].empty()) + continue; + if (!ParseGoogleTestFlag(lines[i].c_str())) + g_help_flag = true; + } +} +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + bool remove_flag = false; + if (ParseGoogleTestFlag(arg)) { + remove_flag = true; +#if GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { + LoadFlagsFromFile(GTEST_FLAG(flagfile)); + remove_flag = true; +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + + if (remove_flag) { + // Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleTestImpl(int* argc, CharType** argv) { + // We don't want to run the initialization code twice. + if (GTestIsInitialized()) return; + + if (*argc <= 0) return; + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { +#if defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_(argc, argv); +#else // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) + internal::InitGoogleTestImpl(argc, argv); +#endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) +} + +} // namespace testing +// Copyright 2005, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include +# endif // GTEST_OS_MAC + +# include +# include +# include + +# if GTEST_OS_LINUX +# include +# endif // GTEST_OS_LINUX + +# include + +# if GTEST_OS_WINDOWS +# include +# else +# include +# include +# endif // GTEST_OS_WINDOWS + +# if GTEST_OS_QNX +# include +# endif // GTEST_OS_QNX + +#endif // GTEST_HAS_DEATH_TEST + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +namespace internal { + +// Valid only for fast death tests. Indicates the code is running in the +// child process of a fast style death test. +# if !GTEST_OS_WINDOWS +static bool g_in_fast_death_test_child = false; +# endif + +// Returns a Boolean value indicating whether the caller is currently +// executing in the context of the death test child process. Tools such as +// Valgrind heap checkers may need this to modify their behavior in death +// tests. IMPORTANT: This is an internal utility. Using it may break the +// implementation of death tests. User code MUST NOT use it. +bool InDeathTestChild() { +# if GTEST_OS_WINDOWS + + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; +#endif +} + +} // namespace internal + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { +# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + { + bool result; + if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { + return result; + } + } +# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static std::string ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static std::string DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const std::string& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ + + ::testing::internal::StreamableToString(__LINE__) + ": " \ + + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +std::string GetLastErrnoDescription() { + return errno == 0 ? "" : posix::StrError(errno); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const std::string& message) { + last_death_test_message_ = message; +} + +std::string DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const std::string error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + static ::std::vector + GetArgvsForDeathTestChildProcess() { + ::std::vector args = GetInjectableArgvs(); +# if defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) + ::std::vector extra_args = + GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_(); + args.insert(args.end(), extra_args.begin(), extra_args.end()); +# endif // defined(GTEST_EXTRA_DEATH_TEST_COMMAND_LINE_ARGS_) + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template + void AddArguments(const ::std::vector& arguments) { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + + private: + std::vector args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +# if !GTEST_OS_QNX +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; +} +# endif // !GTEST_OS_QNX + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; +void StackLowerThanAddress(const void* ptr, bool* result) { + int dummy; + *result = (&dummy < ptr); +} + +// Make sure AddressSanitizer does not tamper with the stack here. +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +bool StackGrowsDown() { + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; +} + +// Spawns a child process with the same executable as the current process in +// a thread-safe manner and instructs it to run the death test. The +// implementation uses fork(2) + exec. On systems where clone(2) is +// available, it is used instead, being slightly more thread-safe. On QNX, +// fork supports only single-threaded environments, so this function uses +// spawn(2) there instead. The function dies with an error message if +// anything goes wrong. +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } + + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + +# else // GTEST_OS_QNX +# if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +# endif // GTEST_OS_LINUX + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } +# endif // GTEST_OS_QNX +# if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +# endif // GTEST_OS_LINUX + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + + ") somehow exceeded expected maximum (" + + StreamableToString(flag->index()) + ")"); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + + "\" encountered"); + return false; + } + + return true; +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Authors: keith.ray@gmail.com (Keith Ray) + + +#include + +#if GTEST_OS_WINDOWS_MOBILE +# include +#elif GTEST_OS_WINDOWS +# include +# include +#elif GTEST_OS_SYMBIAN +// Symbian OpenC has PATH_MAX in sys/syslimits.h +# include +#else +# include +# include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + char* result = getcwd(cwd, sizeof(cwd)); +# if GTEST_OS_NACL + // getcwd will likely fail in NaCl due to the sandbox, so return something + // reasonable. The user may have provided a shim implementation for getcwd, + // however, so fallback only when failure is detected. + return FilePath(result == NULL ? kCurrentDirectoryString : cwd); +# endif // GTEST_OS_NACL + return FilePath(result == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + std::string file; + if (number == 0) { + file = base_name.string() + "." + extension; + } else { + file = base_name.string() + "_" + StreamableToString(number) + + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +#include +#include +#include +#include +#include + +#if GTEST_OS_WINDOWS +# include +# include +# include +# include // Used in ThreadLocal. +#else +# include +#endif // GTEST_OS_WINDOWS + +#if GTEST_OS_MAC +# include +# include +# include +#endif // GTEST_OS_MAC + +#if GTEST_OS_QNX +# include +# include +# include +#endif // GTEST_OS_QNX + +#if GTEST_OS_AIX +# include +# include +#endif // GTEST_OS_AIX + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_LINUX + +namespace { +template +T ReadProcFileField(const string& filename, int field) { + std::string dummy; + std::ifstream file(filename.c_str()); + while (field-- > 0) { + file >> dummy; + } + T output = 0; + file >> output; + return output; +} +} // namespace + +// Returns the number of active threads, or 0 when there is an error. +size_t GetThreadCount() { + const string filename = + (Message() << "/proc/" << getpid() << "/stat").GetString(); + return ReadProcFileField(filename, 19); +} + +#elif GTEST_OS_MAC + +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } else { + return 0; + } +} + +#elif GTEST_OS_QNX + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) { + return static_cast(process_info.num_threads); + } else { + return 0; + } +} + +#elif GTEST_OS_AIX + +size_t GetThreadCount() { + struct procentry64 entry; + pid_t pid = getpid(); + int status = getprocs64(&entry, sizeof(entry), NULL, 0, &pid, 1); + if (status == 1) { + return entry.pi_thcount; + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_LINUX + +#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +void SleepMilliseconds(int n) { + ::Sleep(n); +} + +AutoHandle::AutoHandle() + : handle_(INVALID_HANDLE_VALUE) {} + +AutoHandle::AutoHandle(Handle handle) + : handle_(handle) {} + +AutoHandle::~AutoHandle() { + Reset(); +} + +AutoHandle::Handle AutoHandle::Get() const { + return handle_; +} + +void AutoHandle::Reset() { + Reset(INVALID_HANDLE_VALUE); +} + +void AutoHandle::Reset(HANDLE handle) { + // Resetting with the same handle we already own is invalid. + if (handle_ != handle) { + if (IsCloseable()) { + ::CloseHandle(handle_); + } + handle_ = handle; + } else { + GTEST_CHECK_(!IsCloseable()) + << "Resetting a valid handle to itself is likely a programmer error " + "and thus not allowed."; + } +} + +bool AutoHandle::IsCloseable() const { + // Different Windows APIs may use either of these values to represent an + // invalid handle. + return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; +} + +Notification::Notification() + : event_(::CreateEvent(NULL, // Default security attributes. + TRUE, // Do not reset automatically. + FALSE, // Initially unset. + NULL)) { // Anonymous event. + GTEST_CHECK_(event_.Get() != NULL); +} + +void Notification::Notify() { + GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); +} + +void Notification::WaitForNotification() { + GTEST_CHECK_( + ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); +} + +Mutex::Mutex() + : owner_thread_id_(0), + type_(kDynamic), + critical_section_init_phase_(0), + critical_section_(new CRITICAL_SECTION) { + ::InitializeCriticalSection(critical_section_); +} + +Mutex::~Mutex() { + // Static mutexes are leaked intentionally. It is not thread-safe to try + // to clean them up. + // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires + // nothing to clean it up but is available only on Vista and later. + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx + if (type_ == kDynamic) { + ::DeleteCriticalSection(critical_section_); + delete critical_section_; + critical_section_ = NULL; + } +} + +void Mutex::Lock() { + ThreadSafeLazyInit(); + ::EnterCriticalSection(critical_section_); + owner_thread_id_ = ::GetCurrentThreadId(); +} + +void Mutex::Unlock() { + ThreadSafeLazyInit(); + // We don't protect writing to owner_thread_id_ here, as it's the + // caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_thread_id_ = 0; + ::LeaveCriticalSection(critical_section_); +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void Mutex::AssertHeld() { + ThreadSafeLazyInit(); + GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) + << "The current thread is not holding the mutex @" << this; +} + +// Initializes owner_thread_id_ and critical_section_ in static mutexes. +void Mutex::ThreadSafeLazyInit() { + // Dynamic mutexes are initialized in the constructor. + if (type_ == kStatic) { + switch ( + ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { + case 0: + // If critical_section_init_phase_ was 0 before the exchange, we + // are the first to test it and need to perform the initialization. + owner_thread_id_ = 0; + critical_section_ = new CRITICAL_SECTION; + ::InitializeCriticalSection(critical_section_); + // Updates the critical_section_init_phase_ to 2 to signal + // initialization complete. + GTEST_CHECK_(::InterlockedCompareExchange( + &critical_section_init_phase_, 2L, 1L) == + 1L); + break; + case 1: + // Somebody else is already initializing the mutex; spin until they + // are done. + while (::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, + 2L) != 2L) { + // Possibly yields the rest of the thread's time slice to other + // threads. + ::Sleep(0); + } + break; + + case 2: + break; // The mutex is already initialized and ready for use. + + default: + GTEST_CHECK_(false) + << "Unexpected value of critical_section_init_phase_ " + << "while initializing a static mutex."; + } + } +} + +namespace { + +class ThreadWithParamSupport : public ThreadWithParamBase { + public: + static HANDLE CreateThread(Runnable* runnable, + Notification* thread_can_start) { + ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); + DWORD thread_id; + // TODO(yukawa): Consider to use _beginthreadex instead. + HANDLE thread_handle = ::CreateThread( + NULL, // Default security. + 0, // Default stack size. + &ThreadWithParamSupport::ThreadMain, + param, // Parameter to ThreadMainStatic + 0x0, // Default creation flags. + &thread_id); // Need a valid pointer for the call to work under Win98. + GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " + << ::GetLastError() << "."; + if (thread_handle == NULL) { + delete param; + } + return thread_handle; + } + + private: + struct ThreadMainParam { + ThreadMainParam(Runnable* runnable, Notification* thread_can_start) + : runnable_(runnable), + thread_can_start_(thread_can_start) { + } + scoped_ptr runnable_; + // Does not own. + Notification* thread_can_start_; + }; + + static DWORD WINAPI ThreadMain(void* ptr) { + // Transfers ownership. + scoped_ptr param(static_cast(ptr)); + if (param->thread_can_start_ != NULL) + param->thread_can_start_->WaitForNotification(); + param->runnable_->Run(); + return 0; + } + + // Prohibit instantiation. + ThreadWithParamSupport(); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); +}; + +} // namespace + +ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, + Notification* thread_can_start) + : thread_(ThreadWithParamSupport::CreateThread(runnable, + thread_can_start)) { +} + +ThreadWithParamBase::~ThreadWithParamBase() { + Join(); +} + +void ThreadWithParamBase::Join() { + GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) + << "Failed to join the thread with error " << ::GetLastError() << "."; +} + +// Maps a thread to a set of ThreadIdToThreadLocals that have values +// instantiated on that thread and notifies them when the thread exits. A +// ThreadLocal instance is expected to persist until all threads it has +// values on have terminated. +class ThreadLocalRegistryImpl { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + DWORD current_thread = ::GetCurrentThreadId(); + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(current_thread); + if (thread_local_pos == thread_to_thread_locals->end()) { + thread_local_pos = thread_to_thread_locals->insert( + std::make_pair(current_thread, ThreadLocalValues())).first; + StartWatcherThreadFor(current_thread); + } + ThreadLocalValues& thread_local_values = thread_local_pos->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos == thread_local_values.end()) { + value_pos = + thread_local_values + .insert(std::make_pair( + thread_local_instance, + linked_ptr( + thread_local_instance->NewValueForCurrentThread()))) + .first; + } + return value_pos->second.get(); + } + + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + std::vector > value_holders; + // Clean up the ThreadLocalValues data structure while holding the lock, but + // defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + for (ThreadIdToThreadLocals::iterator it = + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); + ++it) { + ThreadLocalValues& thread_local_values = it->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos != thread_local_values.end()) { + value_holders.push_back(value_pos->second); + thread_local_values.erase(value_pos); + // This 'if' can only be successful at most once, so theoretically we + // could break out of the loop here, but we don't bother doing so. + } + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + static void OnThreadExit(DWORD thread_id) { + GTEST_CHECK_(thread_id != 0) << ::GetLastError(); + std::vector > value_holders; + // Clean up the ThreadIdToThreadLocals data structure while holding the + // lock, but defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(thread_id); + if (thread_local_pos != thread_to_thread_locals->end()) { + ThreadLocalValues& thread_local_values = thread_local_pos->second; + for (ThreadLocalValues::iterator value_pos = + thread_local_values.begin(); + value_pos != thread_local_values.end(); + ++value_pos) { + value_holders.push_back(value_pos->second); + } + thread_to_thread_locals->erase(thread_local_pos); + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + private: + // In a particular thread, maps a ThreadLocal object to its value. + typedef std::map > ThreadLocalValues; + // Stores all ThreadIdToThreadLocals having values in a thread, indexed by + // thread's ID. + typedef std::map ThreadIdToThreadLocals; + + // Holds the thread id and thread handle that we pass from + // StartWatcherThreadFor to WatcherThreadFunc. + typedef std::pair ThreadIdAndHandle; + + static void StartWatcherThreadFor(DWORD thread_id) { + // The returned handle will be kept in thread_map and closed by + // watcher_thread in WatcherThreadFunc. + HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, + FALSE, + thread_id); + GTEST_CHECK_(thread != NULL); + // We need to to pass a valid thread ID pointer into CreateThread for it + // to work correctly under Win98. + DWORD watcher_thread_id; + HANDLE watcher_thread = ::CreateThread( + NULL, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), + CREATE_SUSPENDED, + &watcher_thread_id); + GTEST_CHECK_(watcher_thread != NULL); + // Give the watcher thread the same priority as ours to avoid being + // blocked by it. + ::SetThreadPriority(watcher_thread, + ::GetThreadPriority(::GetCurrentThread())); + ::ResumeThread(watcher_thread); + ::CloseHandle(watcher_thread); + } + + // Monitors exit from a given thread and notifies those + // ThreadIdToThreadLocals about thread termination. + static DWORD WINAPI WatcherThreadFunc(LPVOID param) { + const ThreadIdAndHandle* tah = + reinterpret_cast(param); + GTEST_CHECK_( + ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + OnThreadExit(tah->first); + ::CloseHandle(tah->second); + delete tah; + return 0; + } + + // Returns map of thread local instances. + static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { + mutex_.AssertHeld(); + static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; + return map; + } + + // Protects access to GetThreadLocalsMapLocked() and its return value. + static Mutex mutex_; + // Protects access to GetThreadMapLocked() and its return value. + static Mutex thread_map_mutex_; +}; + +Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); +Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); + +ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + return ThreadLocalRegistryImpl::GetValueOnCurrentThread( + thread_local_instance); +} + +void ThreadLocalRegistry::OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); +} + +#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in , these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +std::string FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) { + return file_name + ":"; + } +#ifdef _MSC_VER + return file_name + "(" + StreamableToString(line) + "):"; +#else + return file_name + ":" + StreamableToString(line) + ":"; +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const std::string file_name(file == NULL ? kUnknownFile : file); + + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); +} + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +# if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +# else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +# endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + std::string GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +GTEST_DISABLE_MSC_WARNINGS_POP_() + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +std::string GetCapturedStream(CapturedStream** captured_stream) { + const std::string content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +std::string GetCapturedStdout() { + return GetCapturedStream(&g_captured_stdout); +} + +// Stops capturing stderr and returns the captured string. +std::string GetCapturedStderr() { + return GetCapturedStream(&g_captured_stderr); +} + +#endif // GTEST_HAS_STREAM_REDIRECTION + +std::string TempDir() { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +size_t GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +std::string ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +#if GTEST_HAS_DEATH_TEST + +static const ::std::vector* g_injected_test_argvs = + NULL; // Owned. + +void SetInjectableArgvs(const ::std::vector* argvs) { + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; +} + +const ::std::vector& GetInjectableArgvs() { + if (g_injected_test_argvs != NULL) { + return *g_injected_test_argvs; + } + return GetArgvs(); +} +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static std::string FlagToEnvVar(const char* flag) { + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { +#if defined(GTEST_GET_BOOL_FROM_ENV_) + return GTEST_GET_BOOL_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_BOOL_FROM_ENV_) + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { +#if defined(GTEST_GET_INT32_FROM_ENV_) + return GTEST_GET_INT32_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_INT32_FROM_ENV_) + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +std::string StringFromGTestEnv(const char* flag, const char* default_value) { +#if defined(GTEST_GET_STRING_FROM_ENV_) + return GTEST_GET_STRING_FROM_ENV_(flag, default_value); +#endif // defined(GTEST_GET_STRING_FROM_ENV_) + const std::string env_var = FlagToEnvVar(flag); + const char* value = posix::GetEnv(env_var.c_str()); + if (value != NULL) { + return value; + } + + // As a special case for the 'output' flag, if GTEST_OUTPUT is not + // set, we look for XML_OUTPUT_FILE, which is set by the Bazel build + // system. The value of XML_OUTPUT_FILE is a filename without the + // "xml:" prefix of GTEST_OUTPUT. + // + // The net priority order after flag processing is thus: + // --gtest_output command line flag + // GTEST_OUTPUT environment variable + // XML_OUTPUT_FILE environment variable + // 'default_value' + if (strcmp(flag, "output") == 0) { + value = posix::GetEnv("XML_OUTPUT_FILE"); + if (value != NULL) { + return std::string("xml:") + value; + } + } + return default_value; +} + +} // namespace internal +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include +#include +#include +#include // NOLINT +#include + +namespace testing { + +namespace { + +using ::std::ostream; + +// Prints a segment of bytes in the given object. +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast(c); + return kAsIs; + } else { + *os << "\\x" + String::FormatHexInt(static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a wchar_t c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo(wc, os); +} + +// Prints the given array of characters to the ostream. CharType must be either +// char or wchar_t. +// The array starts at begin, the length is len, it may include '\0' characters +// and may not be NUL-terminated. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static void PrintCharsAsStringTo( + const CharType* begin, size_t len, ostream* os) { + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char/wchar_t array of 'len' elements, starting at address +// 'begin'. CharType must be either char or wchar_t. +template +GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +static void UniversalPrintCharArray( + const CharType* begin, size_t len, ostream* os) { + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } + + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints a (const) wchar_t array of 'len' elements, starting at address +// 'begin'. +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { + UniversalPrintCharArray(begin, len, os); +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, std::wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. +#define GTEST_IMPLEMENTATION_ 1 +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +std::string TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : + std::string(message, stack_trace); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing +// Copyright 2008 Google Inc. +// All Rights Reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +static std::vector SplitIntoTestNames(const char* src) { + std::vector name_vec; + src = SkipSpaces(src); + for (; src != NULL; src = SkipComma(src)) { + name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); + } + return name_vec; +} + +// Verifies that registered_tests match the test names in +// registered_tests_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef RegisteredTestsMap::const_iterator RegisteredTestIter; + registered_ = true; + + std::vector name_vec = SplitIntoTestNames(registered_tests); + + Message errors; + + std::set tests; + for (std::vector::const_iterator name_it = name_vec.begin(); + name_it != name_vec.end(); ++name_it) { + const std::string& name = *name_it; + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); + ++it) { + if (name == it->first) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); + ++it) { + if (tests.count(it->first) == 0) { + errors << "You forgot to list test " << it->first << ".\n"; + } + } + + const std::string& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing +// 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) +// +// Google C++ Mocking Framework (Google Mock) +// +// This file #includes all Google Mock implementation .cc files. The +// purpose is to allow a user to build Google Mock by compiling this +// file alone. + +// This line ensures that gmock.h can be compiled on its own, even +// when it's fused. +#include "gmock/gmock.h" + +// The following lines pull in the real gmock *.cc files. +// 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 cardinalities. + + +#include +#include // NOLINT +#include +#include + +namespace testing { + +namespace { + +// Implements the Between(m, n) cardinality. +class BetweenCardinalityImpl : public CardinalityInterface { + public: + BetweenCardinalityImpl(int min, int max) + : min_(min >= 0 ? min : 0), + max_(max >= min_ ? max : min_) { + std::stringstream ss; + if (min < 0) { + ss << "The invocation lower bound must be >= 0, " + << "but is actually " << min << "."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } else if (max < 0) { + ss << "The invocation upper bound must be >= 0, " + << "but is actually " << max << "."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } else if (min > max) { + ss << "The invocation upper bound (" << max + << ") must be >= the invocation lower bound (" << min + << ")."; + internal::Expect(false, __FILE__, __LINE__, ss.str()); + } + } + + // Conservative estimate on the lower/upper bound of the number of + // calls allowed. + virtual int ConservativeLowerBound() const { return min_; } + virtual int ConservativeUpperBound() const { return max_; } + + virtual bool IsSatisfiedByCallCount(int call_count) const { + return min_ <= call_count && call_count <= max_; + } + + virtual bool IsSaturatedByCallCount(int call_count) const { + return call_count >= max_; + } + + virtual void DescribeTo(::std::ostream* os) const; + + private: + const int min_; + const int max_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(BetweenCardinalityImpl); +}; + +// Formats "n times" in a human-friendly way. +inline internal::string FormatTimes(int n) { + if (n == 1) { + return "once"; + } else if (n == 2) { + return "twice"; + } else { + std::stringstream ss; + ss << n << " times"; + return ss.str(); + } +} + +// Describes the Between(m, n) cardinality in human-friendly text. +void BetweenCardinalityImpl::DescribeTo(::std::ostream* os) const { + if (min_ == 0) { + if (max_ == 0) { + *os << "never called"; + } else if (max_ == INT_MAX) { + *os << "called any number of times"; + } else { + *os << "called at most " << FormatTimes(max_); + } + } else if (min_ == max_) { + *os << "called " << FormatTimes(min_); + } else if (max_ == INT_MAX) { + *os << "called at least " << FormatTimes(min_); + } else { + // 0 < min_ < max_ < INT_MAX + *os << "called between " << min_ << " and " << max_ << " times"; + } +} + +} // Unnamed namespace + +// Describes the given call count to an ostream. +void Cardinality::DescribeActualCallCountTo(int actual_call_count, + ::std::ostream* os) { + if (actual_call_count > 0) { + *os << "called " << FormatTimes(actual_call_count); + } else { + *os << "never called"; + } +} + +// Creates a cardinality that allows at least n calls. +GTEST_API_ Cardinality AtLeast(int n) { return Between(n, INT_MAX); } + +// Creates a cardinality that allows at most n calls. +GTEST_API_ Cardinality AtMost(int n) { return Between(0, n); } + +// Creates a cardinality that allows any number of calls. +GTEST_API_ Cardinality AnyNumber() { return AtLeast(0); } + +// Creates a cardinality that allows between min and max calls. +GTEST_API_ Cardinality Between(int min, int max) { + return Cardinality(new BetweenCardinalityImpl(min, max)); +} + +// Creates a cardinality that allows exactly n calls. +GTEST_API_ Cardinality Exactly(int n) { return Between(n, n); } + +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Mock - a framework for writing C++ mock classes. +// +// This file defines some utilities useful for implementing Google +// Mock. They are subject to change without notice, so please DO NOT +// USE THEM IN USER CODE. + + +#include +#include // NOLINT +#include + +namespace testing { +namespace internal { + +// Converts an identifier name to a space-separated list of lower-case +// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is +// treated as one word. For example, both "FooBar123" and +// "foo_bar_123" are converted to "foo bar 123". +GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name) { + string result; + char prev_char = '\0'; + for (const char* p = id_name; *p != '\0'; prev_char = *(p++)) { + // We don't care about the current locale as the input is + // guaranteed to be a valid C++ identifier name. + const bool starts_new_word = IsUpper(*p) || + (!IsAlpha(prev_char) && IsLower(*p)) || + (!IsDigit(prev_char) && IsDigit(*p)); + + if (IsAlNum(*p)) { + if (starts_new_word && result != "") + result += ' '; + result += ToLower(*p); + } + } + return result; +} + +// This class reports Google Mock failures as Google Test failures. A +// user can define another class in a similar fashion if he intends to +// use Google Mock with a testing framework other than Google Test. +class GoogleTestFailureReporter : public FailureReporterInterface { + public: + virtual void ReportFailure(FailureType type, const char* file, int line, + const string& message) { + AssertHelper(type == kFatal ? + TestPartResult::kFatalFailure : + TestPartResult::kNonFatalFailure, + file, + line, + message.c_str()) = Message(); + if (type == kFatal) { + posix::Abort(); + } + } +}; + +// Returns the global failure reporter. Will create a +// GoogleTestFailureReporter and return it the first time called. +GTEST_API_ FailureReporterInterface* GetFailureReporter() { + // Points to the global failure reporter used by Google Mock. gcc + // guarantees that the following use of failure_reporter is + // thread-safe. We may need to add additional synchronization to + // protect failure_reporter if we port Google Mock to other + // compilers. + static FailureReporterInterface* const failure_reporter = + new GoogleTestFailureReporter(); + return failure_reporter; +} + +// Protects global resources (stdout in particular) used by Log(). +static GTEST_DEFINE_STATIC_MUTEX_(g_log_mutex); + +// Returns true iff a log with the given severity is visible according +// to the --gmock_verbose flag. +GTEST_API_ bool LogIsVisible(LogSeverity severity) { + if (GMOCK_FLAG(verbose) == kInfoVerbosity) { + // Always show the log if --gmock_verbose=info. + return true; + } else if (GMOCK_FLAG(verbose) == kErrorVerbosity) { + // Always hide it if --gmock_verbose=error. + return false; + } else { + // If --gmock_verbose is neither "info" nor "error", we treat it + // as "warning" (its default value). + return severity == kWarning; + } +} + +// Prints the given message to stdout iff 'severity' >= the level +// specified by the --gmock_verbose flag. If stack_frames_to_skip >= +// 0, also prints the stack trace excluding the top +// stack_frames_to_skip frames. In opt mode, any positive +// stack_frames_to_skip is treated as 0, since we don't know which +// function calls will be inlined by the compiler and need to be +// conservative. +GTEST_API_ void Log(LogSeverity severity, + const string& message, + int stack_frames_to_skip) { + if (!LogIsVisible(severity)) + return; + + // Ensures that logs from different threads don't interleave. + MutexLock l(&g_log_mutex); + + // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is a + // macro. + + if (severity == kWarning) { + // Prints a GMOCK WARNING marker to make the warnings easily searchable. + std::cout << "\nGMOCK WARNING:"; + } + // Pre-pends a new-line to message if it doesn't start with one. + if (message.empty() || message[0] != '\n') { + std::cout << "\n"; + } + std::cout << message; + if (stack_frames_to_skip >= 0) { +#ifdef NDEBUG + // In opt mode, we have to be conservative and skip no stack frame. + const int actual_to_skip = 0; +#else + // In dbg mode, we can do what the caller tell us to do (plus one + // for skipping this function's stack frame). + const int actual_to_skip = stack_frames_to_skip + 1; +#endif // NDEBUG + + // Appends a new-line to message if it doesn't end with one. + if (!message.empty() && *message.rbegin() != '\n') { + std::cout << "\n"; + } + std::cout << "Stack trace:\n" + << ::testing::internal::GetCurrentOsStackTraceExceptTop( + ::testing::UnitTest::GetInstance(), actual_to_skip); + } + std::cout << ::std::flush; +} + +} // namespace internal +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements Matcher, Matcher, and +// utilities for defining matchers. + + +#include +#include +#include + +namespace testing { + +// Constructs a matcher that matches a const string& whose value is +// equal to s. +Matcher::Matcher(const internal::string& s) { + *this = Eq(s); +} + +// Constructs a matcher that matches a const string& whose value is +// equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(internal::string(s)); +} + +// Constructs a matcher that matches a string whose value is equal to s. +Matcher::Matcher(const internal::string& s) { *this = Eq(s); } + +// Constructs a matcher that matches a string whose value is equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(internal::string(s)); +} + +#if GTEST_HAS_STRING_PIECE_ +// Constructs a matcher that matches a const StringPiece& whose value is +// equal to s. +Matcher::Matcher(const internal::string& s) { + *this = Eq(s); +} + +// Constructs a matcher that matches a const StringPiece& whose value is +// equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(internal::string(s)); +} + +// Constructs a matcher that matches a const StringPiece& whose value is +// equal to s. +Matcher::Matcher(StringPiece s) { + *this = Eq(s.ToString()); +} + +// Constructs a matcher that matches a StringPiece whose value is equal to s. +Matcher::Matcher(const internal::string& s) { + *this = Eq(s); +} + +// Constructs a matcher that matches a StringPiece whose value is equal to s. +Matcher::Matcher(const char* s) { + *this = Eq(internal::string(s)); +} + +// Constructs a matcher that matches a StringPiece whose value is equal to s. +Matcher::Matcher(StringPiece s) { + *this = Eq(s.ToString()); +} +#endif // GTEST_HAS_STRING_PIECE_ + +namespace internal { + +// Joins a vector of strings as if they are fields of a tuple; returns +// the joined string. +GTEST_API_ string JoinAsTuple(const Strings& fields) { + switch (fields.size()) { + case 0: + return ""; + case 1: + return fields[0]; + default: + string result = "(" + fields[0]; + for (size_t i = 1; i < fields.size(); i++) { + result += ", "; + result += fields[i]; + } + result += ")"; + return result; + } +} + +// Returns the description for a matcher defined using the MATCHER*() +// macro where the user-supplied description string is "", if +// 'negation' is false; otherwise returns the description of the +// negation of the matcher. 'param_values' contains a list of strings +// that are the print-out of the matcher's parameters. +GTEST_API_ string FormatMatcherDescription(bool negation, + const char* matcher_name, + const Strings& param_values) { + string result = ConvertIdentifierNameToWords(matcher_name); + if (param_values.size() >= 1) + result += " " + JoinAsTuple(param_values); + return negation ? "not (" + result + ")" : result; +} + +// FindMaxBipartiteMatching and its helper class. +// +// Uses the well-known Ford-Fulkerson max flow method to find a maximum +// bipartite matching. Flow is considered to be from left to right. +// There is an implicit source node that is connected to all of the left +// nodes, and an implicit sink node that is connected to all of the +// right nodes. All edges have unit capacity. +// +// Neither the flow graph nor the residual flow graph are represented +// explicitly. Instead, they are implied by the information in 'graph' and +// a vector called 'left_' whose elements are initialized to the +// value kUnused. This represents the initial state of the algorithm, +// where the flow graph is empty, and the residual flow graph has the +// following edges: +// - An edge from source to each left_ node +// - An edge from each right_ node to sink +// - An edge from each left_ node to each right_ node, if the +// corresponding edge exists in 'graph'. +// +// When the TryAugment() method adds a flow, it sets left_[l] = r for some +// nodes l and r. This induces the following changes: +// - The edges (source, l), (l, r), and (r, sink) are added to the +// flow graph. +// - The same three edges are removed from the residual flow graph. +// - The reverse edges (l, source), (r, l), and (sink, r) are added +// to the residual flow graph, which is a directional graph +// representing unused flow capacity. +// +// When the method augments a flow (moving left_[l] from some r1 to some +// other r2), this can be thought of as "undoing" the above steps with +// respect to r1 and "redoing" them with respect to r2. +// +// It bears repeating that the flow graph and residual flow graph are +// never represented explicitly, but can be derived by looking at the +// information in 'graph' and in left_. +// +// As an optimization, there is a second vector called right_ which +// does not provide any new information. Instead, it enables more +// efficient queries about edges entering or leaving the right-side nodes +// of the flow or residual flow graphs. The following invariants are +// maintained: +// +// left[l] == kUnused or right[left[l]] == l +// right[r] == kUnused or left[right[r]] == r +// +// . [ source ] . +// . ||| . +// . ||| . +// . ||\--> left[0]=1 ---\ right[0]=-1 ----\ . +// . || | | . +// . |\---> left[1]=-1 \--> right[1]=0 ---\| . +// . | || . +// . \----> left[2]=2 ------> right[2]=2 --\|| . +// . ||| . +// . elements matchers vvv . +// . [ sink ] . +// +// See Also: +// [1] Cormen, et al (2001). "Section 26.2: The Ford-Fulkerson method". +// "Introduction to Algorithms (Second ed.)", pp. 651-664. +// [2] "Ford-Fulkerson algorithm", Wikipedia, +// 'http://en.wikipedia.org/wiki/Ford%E2%80%93Fulkerson_algorithm' +class MaxBipartiteMatchState { + public: + explicit MaxBipartiteMatchState(const MatchMatrix& graph) + : graph_(&graph), + left_(graph_->LhsSize(), kUnused), + right_(graph_->RhsSize(), kUnused) { + } + + // Returns the edges of a maximal match, each in the form {left, right}. + ElementMatcherPairs Compute() { + // 'seen' is used for path finding { 0: unseen, 1: seen }. + ::std::vector seen; + // Searches the residual flow graph for a path from each left node to + // the sink in the residual flow graph, and if one is found, add flow + // to the graph. It's okay to search through the left nodes once. The + // edge from the implicit source node to each previously-visited left + // node will have flow if that left node has any path to the sink + // whatsoever. Subsequent augmentations can only add flow to the + // network, and cannot take away that previous flow unit from the source. + // Since the source-to-left edge can only carry one flow unit (or, + // each element can be matched to only one matcher), there is no need + // to visit the left nodes more than once looking for augmented paths. + // The flow is known to be possible or impossible by looking at the + // node once. + for (size_t ilhs = 0; ilhs < graph_->LhsSize(); ++ilhs) { + // Reset the path-marking vector and try to find a path from + // source to sink starting at the left_[ilhs] node. + GTEST_CHECK_(left_[ilhs] == kUnused) + << "ilhs: " << ilhs << ", left_[ilhs]: " << left_[ilhs]; + // 'seen' initialized to 'graph_->RhsSize()' copies of 0. + seen.assign(graph_->RhsSize(), 0); + TryAugment(ilhs, &seen); + } + ElementMatcherPairs result; + for (size_t ilhs = 0; ilhs < left_.size(); ++ilhs) { + size_t irhs = left_[ilhs]; + if (irhs == kUnused) continue; + result.push_back(ElementMatcherPair(ilhs, irhs)); + } + return result; + } + + private: + static const size_t kUnused = static_cast(-1); + + // Perform a depth-first search from left node ilhs to the sink. If a + // path is found, flow is added to the network by linking the left and + // right vector elements corresponding each segment of the path. + // Returns true if a path to sink was found, which means that a unit of + // flow was added to the network. The 'seen' vector elements correspond + // to right nodes and are marked to eliminate cycles from the search. + // + // Left nodes will only be explored at most once because they + // are accessible from at most one right node in the residual flow + // graph. + // + // Note that left_[ilhs] is the only element of left_ that TryAugment will + // potentially transition from kUnused to another value. Any other + // left_ element holding kUnused before TryAugment will be holding it + // when TryAugment returns. + // + bool TryAugment(size_t ilhs, ::std::vector* seen) { + for (size_t irhs = 0; irhs < graph_->RhsSize(); ++irhs) { + if ((*seen)[irhs]) + continue; + if (!graph_->HasEdge(ilhs, irhs)) + continue; + // There's an available edge from ilhs to irhs. + (*seen)[irhs] = 1; + // Next a search is performed to determine whether + // this edge is a dead end or leads to the sink. + // + // right_[irhs] == kUnused means that there is residual flow from + // right node irhs to the sink, so we can use that to finish this + // flow path and return success. + // + // Otherwise there is residual flow to some ilhs. We push flow + // along that path and call ourselves recursively to see if this + // ultimately leads to sink. + if (right_[irhs] == kUnused || TryAugment(right_[irhs], seen)) { + // Add flow from left_[ilhs] to right_[irhs]. + left_[ilhs] = irhs; + right_[irhs] = ilhs; + return true; + } + } + return false; + } + + const MatchMatrix* graph_; // not owned + // Each element of the left_ vector represents a left hand side node + // (i.e. an element) and each element of right_ is a right hand side + // node (i.e. a matcher). The values in the left_ vector indicate + // outflow from that node to a node on the the right_ side. The values + // in the right_ indicate inflow, and specify which left_ node is + // feeding that right_ node, if any. For example, left_[3] == 1 means + // there's a flow from element #3 to matcher #1. Such a flow would also + // be redundantly represented in the right_ vector as right_[1] == 3. + // Elements of left_ and right_ are either kUnused or mutually + // referent. Mutually referent means that left_[right_[i]] = i and + // right_[left_[i]] = i. + ::std::vector left_; + ::std::vector right_; + + GTEST_DISALLOW_ASSIGN_(MaxBipartiteMatchState); +}; + +const size_t MaxBipartiteMatchState::kUnused; + +GTEST_API_ ElementMatcherPairs +FindMaxBipartiteMatching(const MatchMatrix& g) { + return MaxBipartiteMatchState(g).Compute(); +} + +static void LogElementMatcherPairVec(const ElementMatcherPairs& pairs, + ::std::ostream* stream) { + typedef ElementMatcherPairs::const_iterator Iter; + ::std::ostream& os = *stream; + os << "{"; + const char *sep = ""; + for (Iter it = pairs.begin(); it != pairs.end(); ++it) { + os << sep << "\n (" + << "element #" << it->first << ", " + << "matcher #" << it->second << ")"; + sep = ","; + } + os << "\n}"; +} + +// Tries to find a pairing, and explains the result. +GTEST_API_ bool FindPairing(const MatchMatrix& matrix, + MatchResultListener* listener) { + ElementMatcherPairs matches = FindMaxBipartiteMatching(matrix); + + size_t max_flow = matches.size(); + bool result = (max_flow == matrix.RhsSize()); + + if (!result) { + if (listener->IsInterested()) { + *listener << "where no permutation of the elements can " + "satisfy all matchers, and the closest match is " + << max_flow << " of " << matrix.RhsSize() + << " matchers with the pairings:\n"; + LogElementMatcherPairVec(matches, listener->stream()); + } + return false; + } + + if (matches.size() > 1) { + if (listener->IsInterested()) { + const char *sep = "where:\n"; + for (size_t mi = 0; mi < matches.size(); ++mi) { + *listener << sep << " - element #" << matches[mi].first + << " is matched by matcher #" << matches[mi].second; + sep = ",\n"; + } + } + } + return true; +} + +bool MatchMatrix::NextGraph() { + for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { + for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { + char& b = matched_[SpaceIndex(ilhs, irhs)]; + if (!b) { + b = 1; + return true; + } + b = 0; + } + } + return false; +} + +void MatchMatrix::Randomize() { + for (size_t ilhs = 0; ilhs < LhsSize(); ++ilhs) { + for (size_t irhs = 0; irhs < RhsSize(); ++irhs) { + char& b = matched_[SpaceIndex(ilhs, irhs)]; + b = static_cast(rand() & 1); // NOLINT + } + } +} + +string MatchMatrix::DebugString() const { + ::std::stringstream ss; + const char *sep = ""; + for (size_t i = 0; i < LhsSize(); ++i) { + ss << sep; + for (size_t j = 0; j < RhsSize(); ++j) { + ss << HasEdge(i, j); + } + sep = ";"; + } + return ss.str(); +} + +void UnorderedElementsAreMatcherImplBase::DescribeToImpl( + ::std::ostream* os) const { + if (matcher_describers_.empty()) { + *os << "is empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "has " << Elements(1) << " and that element "; + matcher_describers_[0]->DescribeTo(os); + return; + } + *os << "has " << Elements(matcher_describers_.size()) + << " and there exists some permutation of elements such that:\n"; + const char* sep = ""; + for (size_t i = 0; i != matcher_describers_.size(); ++i) { + *os << sep << " - element #" << i << " "; + matcher_describers_[i]->DescribeTo(os); + sep = ", and\n"; + } +} + +void UnorderedElementsAreMatcherImplBase::DescribeNegationToImpl( + ::std::ostream* os) const { + if (matcher_describers_.empty()) { + *os << "isn't empty"; + return; + } + if (matcher_describers_.size() == 1) { + *os << "doesn't have " << Elements(1) + << ", or has " << Elements(1) << " that "; + matcher_describers_[0]->DescribeNegationTo(os); + return; + } + *os << "doesn't have " << Elements(matcher_describers_.size()) + << ", or there exists no permutation of elements such that:\n"; + const char* sep = ""; + for (size_t i = 0; i != matcher_describers_.size(); ++i) { + *os << sep << " - element #" << i << " "; + matcher_describers_[i]->DescribeTo(os); + sep = ", and\n"; + } +} + +// Checks that all matchers match at least one element, and that all +// elements match at least one matcher. This enables faster matching +// and better error reporting. +// Returns false, writing an explanation to 'listener', if and only +// if the success criteria are not met. +bool UnorderedElementsAreMatcherImplBase:: +VerifyAllElementsAndMatchersAreMatched( + const ::std::vector& element_printouts, + const MatchMatrix& matrix, + MatchResultListener* listener) const { + bool result = true; + ::std::vector element_matched(matrix.LhsSize(), 0); + ::std::vector matcher_matched(matrix.RhsSize(), 0); + + for (size_t ilhs = 0; ilhs < matrix.LhsSize(); ilhs++) { + for (size_t irhs = 0; irhs < matrix.RhsSize(); irhs++) { + char matched = matrix.HasEdge(ilhs, irhs); + element_matched[ilhs] |= matched; + matcher_matched[irhs] |= matched; + } + } + + { + const char* sep = + "where the following matchers don't match any elements:\n"; + for (size_t mi = 0; mi < matcher_matched.size(); ++mi) { + if (matcher_matched[mi]) + continue; + result = false; + if (listener->IsInterested()) { + *listener << sep << "matcher #" << mi << ": "; + matcher_describers_[mi]->DescribeTo(listener->stream()); + sep = ",\n"; + } + } + } + + { + const char* sep = + "where the following elements don't match any matchers:\n"; + const char* outer_sep = ""; + if (!result) { + outer_sep = "\nand "; + } + for (size_t ei = 0; ei < element_matched.size(); ++ei) { + if (element_matched[ei]) + continue; + result = false; + if (listener->IsInterested()) { + *listener << outer_sep << sep << "element #" << ei << ": " + << element_printouts[ei]; + sep = ",\n"; + outer_sep = ""; + } + } + } + return result; +} + +} // namespace internal +} // namespace testing +// Copyright 2007, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Mock - a framework for writing C++ mock classes. +// +// This file implements the spec builder syntax (ON_CALL and +// EXPECT_CALL). + + +#include +#include // NOLINT +#include +#include +#include + +#if GTEST_OS_CYGWIN || GTEST_OS_LINUX || GTEST_OS_MAC +# include // NOLINT +#endif + +namespace testing { +namespace internal { + +// Protects the mock object registry (in class Mock), all function +// mockers, and all expectations. +GTEST_API_ GTEST_DEFINE_STATIC_MUTEX_(g_gmock_mutex); + +// Logs a message including file and line number information. +GTEST_API_ void LogWithLocation(testing::internal::LogSeverity severity, + const char* file, int line, + const string& message) { + ::std::ostringstream s; + s << file << ":" << line << ": " << message << ::std::endl; + Log(severity, s.str(), 0); +} + +// Constructs an ExpectationBase object. +ExpectationBase::ExpectationBase(const char* a_file, + int a_line, + const string& a_source_text) + : file_(a_file), + line_(a_line), + source_text_(a_source_text), + cardinality_specified_(false), + cardinality_(Exactly(1)), + call_count_(0), + retired_(false), + extra_matcher_specified_(false), + repeated_action_specified_(false), + retires_on_saturation_(false), + last_clause_(kNone), + action_count_checked_(false) {} + +// Destructs an ExpectationBase object. +ExpectationBase::~ExpectationBase() {} + +// Explicitly specifies the cardinality of this expectation. Used by +// the subclasses to implement the .Times() clause. +void ExpectationBase::SpecifyCardinality(const Cardinality& a_cardinality) { + cardinality_specified_ = true; + cardinality_ = a_cardinality; +} + +// Retires all pre-requisites of this expectation. +void ExpectationBase::RetireAllPreRequisites() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + if (is_retired()) { + // We can take this short-cut as we never retire an expectation + // until we have retired all its pre-requisites. + return; + } + + for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); + it != immediate_prerequisites_.end(); ++it) { + ExpectationBase* const prerequisite = it->expectation_base().get(); + if (!prerequisite->is_retired()) { + prerequisite->RetireAllPreRequisites(); + prerequisite->Retire(); + } + } +} + +// Returns true iff all pre-requisites of this expectation have been +// satisfied. +bool ExpectationBase::AllPrerequisitesAreSatisfied() const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); + it != immediate_prerequisites_.end(); ++it) { + if (!(it->expectation_base()->IsSatisfied()) || + !(it->expectation_base()->AllPrerequisitesAreSatisfied())) + return false; + } + return true; +} + +// Adds unsatisfied pre-requisites of this expectation to 'result'. +void ExpectationBase::FindUnsatisfiedPrerequisites(ExpectationSet* result) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + for (ExpectationSet::const_iterator it = immediate_prerequisites_.begin(); + it != immediate_prerequisites_.end(); ++it) { + if (it->expectation_base()->IsSatisfied()) { + // If *it is satisfied and has a call count of 0, some of its + // pre-requisites may not be satisfied yet. + if (it->expectation_base()->call_count_ == 0) { + it->expectation_base()->FindUnsatisfiedPrerequisites(result); + } + } else { + // Now that we know *it is unsatisfied, we are not so interested + // in whether its pre-requisites are satisfied. Therefore we + // don't recursively call FindUnsatisfiedPrerequisites() here. + *result += *it; + } + } +} + +// Describes how many times a function call matching this +// expectation has occurred. +void ExpectationBase::DescribeCallCountTo(::std::ostream* os) const + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + + // Describes how many times the function is expected to be called. + *os << " Expected: to be "; + cardinality().DescribeTo(os); + *os << "\n Actual: "; + Cardinality::DescribeActualCallCountTo(call_count(), os); + + // Describes the state of the expectation (e.g. is it satisfied? + // is it active?). + *os << " - " << (IsOverSaturated() ? "over-saturated" : + IsSaturated() ? "saturated" : + IsSatisfied() ? "satisfied" : "unsatisfied") + << " and " + << (is_retired() ? "retired" : "active"); +} + +// Checks the action count (i.e. the number of WillOnce() and +// WillRepeatedly() clauses) against the cardinality if this hasn't +// been done before. Prints a warning if there are too many or too +// few actions. +void ExpectationBase::CheckActionCountIfNotDone() const + GTEST_LOCK_EXCLUDED_(mutex_) { + bool should_check = false; + { + MutexLock l(&mutex_); + if (!action_count_checked_) { + action_count_checked_ = true; + should_check = true; + } + } + + if (should_check) { + if (!cardinality_specified_) { + // The cardinality was inferred - no need to check the action + // count against it. + return; + } + + // The cardinality was explicitly specified. + const int action_count = static_cast(untyped_actions_.size()); + const int upper_bound = cardinality().ConservativeUpperBound(); + const int lower_bound = cardinality().ConservativeLowerBound(); + bool too_many; // True if there are too many actions, or false + // if there are too few. + if (action_count > upper_bound || + (action_count == upper_bound && repeated_action_specified_)) { + too_many = true; + } else if (0 < action_count && action_count < lower_bound && + !repeated_action_specified_) { + too_many = false; + } else { + return; + } + + ::std::stringstream ss; + DescribeLocationTo(&ss); + ss << "Too " << (too_many ? "many" : "few") + << " actions specified in " << source_text() << "...\n" + << "Expected to be "; + cardinality().DescribeTo(&ss); + ss << ", but has " << (too_many ? "" : "only ") + << action_count << " WillOnce()" + << (action_count == 1 ? "" : "s"); + if (repeated_action_specified_) { + ss << " and a WillRepeatedly()"; + } + ss << "."; + Log(kWarning, ss.str(), -1); // -1 means "don't print stack trace". + } +} + +// Implements the .Times() clause. +void ExpectationBase::UntypedTimes(const Cardinality& a_cardinality) { + if (last_clause_ == kTimes) { + ExpectSpecProperty(false, + ".Times() cannot appear " + "more than once in an EXPECT_CALL()."); + } else { + ExpectSpecProperty(last_clause_ < kTimes, + ".Times() cannot appear after " + ".InSequence(), .WillOnce(), .WillRepeatedly(), " + "or .RetiresOnSaturation()."); + } + last_clause_ = kTimes; + + SpecifyCardinality(a_cardinality); +} + +// Points to the implicit sequence introduced by a living InSequence +// object (if any) in the current thread or NULL. +GTEST_API_ ThreadLocal g_gmock_implicit_sequence; + +// Reports an uninteresting call (whose description is in msg) in the +// manner specified by 'reaction'. +void ReportUninterestingCall(CallReaction reaction, const string& msg) { + // Include a stack trace only if --gmock_verbose=info is specified. + const int stack_frames_to_skip = + GMOCK_FLAG(verbose) == kInfoVerbosity ? 3 : -1; + switch (reaction) { + case kAllow: + Log(kInfo, msg, stack_frames_to_skip); + break; + case kWarn: + Log(kWarning, + msg + + "\nNOTE: You can safely ignore the above warning unless this " + "call should not happen. Do not suppress it by blindly adding " + "an EXPECT_CALL() if you don't mean to enforce the call. " + "See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#" + "knowing-when-to-expect for details.\n", + stack_frames_to_skip); + break; + default: // FAIL + Expect(false, NULL, -1, msg); + } +} + +UntypedFunctionMockerBase::UntypedFunctionMockerBase() + : mock_obj_(NULL), name_("") {} + +UntypedFunctionMockerBase::~UntypedFunctionMockerBase() {} + +// Sets the mock object this mock method belongs to, and registers +// this information in the global mock registry. Will be called +// whenever an EXPECT_CALL() or ON_CALL() is executed on this mock +// method. +void UntypedFunctionMockerBase::RegisterOwner(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + { + MutexLock l(&g_gmock_mutex); + mock_obj_ = mock_obj; + } + Mock::Register(mock_obj, this); +} + +// Sets the mock object this mock method belongs to, and sets the name +// of the mock function. Will be called upon each invocation of this +// mock function. +void UntypedFunctionMockerBase::SetOwnerAndName(const void* mock_obj, + const char* name) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + // We protect name_ under g_gmock_mutex in case this mock function + // is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + mock_obj_ = mock_obj; + name_ = name; +} + +// Returns the name of the function being mocked. Must be called +// after RegisterOwner() or SetOwnerAndName() has been called. +const void* UntypedFunctionMockerBase::MockObject() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const void* mock_obj; + { + // We protect mock_obj_ under g_gmock_mutex in case this mock + // function is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + Assert(mock_obj_ != NULL, __FILE__, __LINE__, + "MockObject() must not be called before RegisterOwner() or " + "SetOwnerAndName() has been called."); + mock_obj = mock_obj_; + } + return mock_obj; +} + +// Returns the name of this mock method. Must be called after +// SetOwnerAndName() has been called. +const char* UntypedFunctionMockerBase::Name() const + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + const char* name; + { + // We protect name_ under g_gmock_mutex in case this mock + // function is called from two threads concurrently. + MutexLock l(&g_gmock_mutex); + Assert(name_ != NULL, __FILE__, __LINE__, + "Name() must not be called before SetOwnerAndName() has " + "been called."); + name = name_; + } + return name; +} + +// Calculates the result of invoking this mock function with the given +// arguments, prints it, and returns it. The caller is responsible +// for deleting the result. +UntypedActionResultHolderBase* +UntypedFunctionMockerBase::UntypedInvokeWith(const void* const untyped_args) + GTEST_LOCK_EXCLUDED_(g_gmock_mutex) { + if (untyped_expectations_.size() == 0) { + // No expectation is set on this mock method - we have an + // uninteresting call. + + // We must get Google Mock's reaction on uninteresting calls + // made on this mock object BEFORE performing the action, + // because the action may DELETE the mock object and make the + // following expression meaningless. + const CallReaction reaction = + Mock::GetReactionOnUninterestingCalls(MockObject()); + + // True iff we need to print this call's arguments and return + // value. This definition must be kept in sync with + // the behavior of ReportUninterestingCall(). + const bool need_to_report_uninteresting_call = + // If the user allows this uninteresting call, we print it + // only when he wants informational messages. + reaction == kAllow ? LogIsVisible(kInfo) : + // If the user wants this to be a warning, we print it only + // when he wants to see warnings. + reaction == kWarn ? LogIsVisible(kWarning) : + // Otherwise, the user wants this to be an error, and we + // should always print detailed information in the error. + true; + + if (!need_to_report_uninteresting_call) { + // Perform the action without printing the call information. + return this->UntypedPerformDefaultAction(untyped_args, ""); + } + + // Warns about the uninteresting call. + ::std::stringstream ss; + this->UntypedDescribeUninterestingCall(untyped_args, &ss); + + // Calculates the function result. + UntypedActionResultHolderBase* const result = + this->UntypedPerformDefaultAction(untyped_args, ss.str()); + + // Prints the function result. + if (result != NULL) + result->PrintAsActionResult(&ss); + + ReportUninterestingCall(reaction, ss.str()); + return result; + } + + bool is_excessive = false; + ::std::stringstream ss; + ::std::stringstream why; + ::std::stringstream loc; + const void* untyped_action = NULL; + + // The UntypedFindMatchingExpectation() function acquires and + // releases g_gmock_mutex. + const ExpectationBase* const untyped_expectation = + this->UntypedFindMatchingExpectation( + untyped_args, &untyped_action, &is_excessive, + &ss, &why); + const bool found = untyped_expectation != NULL; + + // True iff we need to print the call's arguments and return value. + // This definition must be kept in sync with the uses of Expect() + // and Log() in this function. + const bool need_to_report_call = + !found || is_excessive || LogIsVisible(kInfo); + if (!need_to_report_call) { + // Perform the action without printing the call information. + return + untyped_action == NULL ? + this->UntypedPerformDefaultAction(untyped_args, "") : + this->UntypedPerformAction(untyped_action, untyped_args); + } + + ss << " Function call: " << Name(); + this->UntypedPrintArgs(untyped_args, &ss); + + // In case the action deletes a piece of the expectation, we + // generate the message beforehand. + if (found && !is_excessive) { + untyped_expectation->DescribeLocationTo(&loc); + } + + UntypedActionResultHolderBase* const result = + untyped_action == NULL ? + this->UntypedPerformDefaultAction(untyped_args, ss.str()) : + this->UntypedPerformAction(untyped_action, untyped_args); + if (result != NULL) + result->PrintAsActionResult(&ss); + ss << "\n" << why.str(); + + if (!found) { + // No expectation matches this call - reports a failure. + Expect(false, NULL, -1, ss.str()); + } else if (is_excessive) { + // We had an upper-bound violation and the failure message is in ss. + Expect(false, untyped_expectation->file(), + untyped_expectation->line(), ss.str()); + } else { + // We had an expected call and the matching expectation is + // described in ss. + Log(kInfo, loc.str() + ss.str(), 2); + } + + return result; +} + +// Returns an Expectation object that references and co-owns exp, +// which must be an expectation on this mock function. +Expectation UntypedFunctionMockerBase::GetHandleOf(ExpectationBase* exp) { + for (UntypedExpectations::const_iterator it = + untyped_expectations_.begin(); + it != untyped_expectations_.end(); ++it) { + if (it->get() == exp) { + return Expectation(*it); + } + } + + Assert(false, __FILE__, __LINE__, "Cannot find expectation."); + return Expectation(); + // The above statement is just to make the code compile, and will + // never be executed. +} + +// Verifies that all expectations on this mock function have been +// satisfied. Reports one or more Google Test non-fatal failures +// and returns false if not. +bool UntypedFunctionMockerBase::VerifyAndClearExpectationsLocked() + GTEST_EXCLUSIVE_LOCK_REQUIRED_(g_gmock_mutex) { + g_gmock_mutex.AssertHeld(); + bool expectations_met = true; + for (UntypedExpectations::const_iterator it = + untyped_expectations_.begin(); + it != untyped_expectations_.end(); ++it) { + ExpectationBase* const untyped_expectation = it->get(); + if (untyped_expectation->IsOverSaturated()) { + // There was an upper-bound violation. Since the error was + // already reported when it occurred, there is no need to do + // anything here. + expectations_met = false; + } else if (!untyped_expectation->IsSatisfied()) { + expectations_met = false; + ::std::stringstream ss; + ss << "Actual function call count doesn't match " + << untyped_expectation->source_text() << "...\n"; + // No need to show the source file location of the expectation + // in the description, as the Expect() call that follows already + // takes care of it. + untyped_expectation->MaybeDescribeExtraMatcherTo(&ss); + untyped_expectation->DescribeCallCountTo(&ss); + Expect(false, untyped_expectation->file(), + untyped_expectation->line(), ss.str()); + } + } + + // Deleting our expectations may trigger other mock objects to be deleted, for + // example if an action contains a reference counted smart pointer to that + // mock object, and that is the last reference. So if we delete our + // expectations within the context of the global mutex we may deadlock when + // this method is called again. Instead, make a copy of the set of + // expectations to delete, clear our set within the mutex, and then clear the + // copied set outside of it. + UntypedExpectations expectations_to_delete; + untyped_expectations_.swap(expectations_to_delete); + + g_gmock_mutex.Unlock(); + expectations_to_delete.clear(); + g_gmock_mutex.Lock(); + + return expectations_met; +} + +} // namespace internal + +// Class Mock. + +namespace { + +typedef std::set FunctionMockers; + +// The current state of a mock object. Such information is needed for +// detecting leaked mock objects and explicitly verifying a mock's +// expectations. +struct MockObjectState { + MockObjectState() + : first_used_file(NULL), first_used_line(-1), leakable(false) {} + + // Where in the source file an ON_CALL or EXPECT_CALL is first + // invoked on this mock object. + const char* first_used_file; + int first_used_line; + ::std::string first_used_test_case; + ::std::string first_used_test; + bool leakable; // true iff it's OK to leak the object. + FunctionMockers function_mockers; // All registered methods of the object. +}; + +// A global registry holding the state of all mock objects that are +// alive. A mock object is added to this registry the first time +// Mock::AllowLeak(), ON_CALL(), or EXPECT_CALL() is called on it. It +// is removed from the registry in the mock object's destructor. +class MockObjectRegistry { + public: + // Maps a mock object (identified by its address) to its state. + typedef std::map StateMap; + + // This destructor will be called when a program exits, after all + // tests in it have been run. By then, there should be no mock + // object alive. Therefore we report any living object as test + // failure, unless the user explicitly asked us to ignore it. + ~MockObjectRegistry() { + // "using ::std::cout;" doesn't work with Symbian's STLport, where cout is + // a macro. + + if (!GMOCK_FLAG(catch_leaked_mocks)) + return; + + int leaked_count = 0; + for (StateMap::const_iterator it = states_.begin(); it != states_.end(); + ++it) { + if (it->second.leakable) // The user said it's fine to leak this object. + continue; + + // TODO(wan@google.com): Print the type of the leaked object. + // This can help the user identify the leaked object. + std::cout << "\n"; + const MockObjectState& state = it->second; + std::cout << internal::FormatFileLocation(state.first_used_file, + state.first_used_line); + std::cout << " ERROR: this mock object"; + if (state.first_used_test != "") { + std::cout << " (used in test " << state.first_used_test_case << "." + << state.first_used_test << ")"; + } + std::cout << " should be deleted but never is. Its address is @" + << it->first << "."; + leaked_count++; + } + if (leaked_count > 0) { + std::cout << "\nERROR: " << leaked_count + << " leaked mock " << (leaked_count == 1 ? "object" : "objects") + << " found at program exit.\n"; + std::cout.flush(); + ::std::cerr.flush(); + // RUN_ALL_TESTS() has already returned when this destructor is + // called. Therefore we cannot use the normal Google Test + // failure reporting mechanism. + _exit(1); // We cannot call exit() as it is not reentrant and + // may already have been called. + } + } + + StateMap& states() { return states_; } + + private: + StateMap states_; +}; + +// Protected by g_gmock_mutex. +MockObjectRegistry g_mock_object_registry; + +// Maps a mock object to the reaction Google Mock should have when an +// uninteresting method is called. Protected by g_gmock_mutex. +std::map g_uninteresting_call_reaction; + +// Sets the reaction Google Mock should have when an uninteresting +// method of the given mock object is called. +void SetReactionOnUninterestingCalls(const void* mock_obj, + internal::CallReaction reaction) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_uninteresting_call_reaction[mock_obj] = reaction; +} + +} // namespace + +// Tells Google Mock to allow uninteresting calls on the given mock +// object. +void Mock::AllowUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kAllow); +} + +// Tells Google Mock to warn the user about uninteresting calls on the +// given mock object. +void Mock::WarnUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kWarn); +} + +// Tells Google Mock to fail uninteresting calls on the given mock +// object. +void Mock::FailUninterestingCalls(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + SetReactionOnUninterestingCalls(mock_obj, internal::kFail); +} + +// Tells Google Mock the given mock object is being destroyed and its +// entry in the call-reaction table should be removed. +void Mock::UnregisterCallReaction(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_uninteresting_call_reaction.erase(mock_obj); +} + +// Returns the reaction Google Mock will have on uninteresting calls +// made on the given mock object. +internal::CallReaction Mock::GetReactionOnUninterestingCalls( + const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + return (g_uninteresting_call_reaction.count(mock_obj) == 0) ? + internal::kDefault : g_uninteresting_call_reaction[mock_obj]; +} + +// Tells Google Mock to ignore mock_obj when checking for leaked mock +// objects. +void Mock::AllowLeak(const void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_mock_object_registry.states()[mock_obj].leakable = true; +} + +// Verifies and clears all expectations on the given mock object. If +// the expectations aren't satisfied, generates one or more Google +// Test non-fatal failures and returns false. +bool Mock::VerifyAndClearExpectations(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + return VerifyAndClearExpectationsLocked(mock_obj); +} + +// Verifies all expectations on the given mock object and clears its +// default actions and expectations. Returns true iff the +// verification was successful. +bool Mock::VerifyAndClear(void* mock_obj) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + ClearDefaultActionsLocked(mock_obj); + return VerifyAndClearExpectationsLocked(mock_obj); +} + +// Verifies and clears all expectations on the given mock object. If +// the expectations aren't satisfied, generates one or more Google +// Test non-fatal failures and returns false. +bool Mock::VerifyAndClearExpectationsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + if (g_mock_object_registry.states().count(mock_obj) == 0) { + // No EXPECT_CALL() was set on the given mock object. + return true; + } + + // Verifies and clears the expectations on each mock method in the + // given mock object. + bool expectations_met = true; + FunctionMockers& mockers = + g_mock_object_registry.states()[mock_obj].function_mockers; + for (FunctionMockers::const_iterator it = mockers.begin(); + it != mockers.end(); ++it) { + if (!(*it)->VerifyAndClearExpectationsLocked()) { + expectations_met = false; + } + } + + // We don't clear the content of mockers, as they may still be + // needed by ClearDefaultActionsLocked(). + return expectations_met; +} + +// Registers a mock object and a mock method it owns. +void Mock::Register(const void* mock_obj, + internal::UntypedFunctionMockerBase* mocker) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + g_mock_object_registry.states()[mock_obj].function_mockers.insert(mocker); +} + +// Tells Google Mock where in the source code mock_obj is used in an +// ON_CALL or EXPECT_CALL. In case mock_obj is leaked, this +// information helps the user identify which object it is. +void Mock::RegisterUseByOnCallOrExpectCall(const void* mock_obj, + const char* file, int line) + GTEST_LOCK_EXCLUDED_(internal::g_gmock_mutex) { + internal::MutexLock l(&internal::g_gmock_mutex); + MockObjectState& state = g_mock_object_registry.states()[mock_obj]; + if (state.first_used_file == NULL) { + state.first_used_file = file; + state.first_used_line = line; + const TestInfo* const test_info = + UnitTest::GetInstance()->current_test_info(); + if (test_info != NULL) { + // TODO(wan@google.com): record the test case name when the + // ON_CALL or EXPECT_CALL is invoked from SetUpTestCase() or + // TearDownTestCase(). + state.first_used_test_case = test_info->test_case_name(); + state.first_used_test = test_info->name(); + } + } +} + +// Unregisters a mock method; removes the owning mock object from the +// registry when the last mock method associated with it has been +// unregistered. This is called only in the destructor of +// FunctionMockerBase. +void Mock::UnregisterLocked(internal::UntypedFunctionMockerBase* mocker) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + for (MockObjectRegistry::StateMap::iterator it = + g_mock_object_registry.states().begin(); + it != g_mock_object_registry.states().end(); ++it) { + FunctionMockers& mockers = it->second.function_mockers; + if (mockers.erase(mocker) > 0) { + // mocker was in mockers and has been just removed. + if (mockers.empty()) { + g_mock_object_registry.states().erase(it); + } + return; + } + } +} + +// Clears all ON_CALL()s set on the given mock object. +void Mock::ClearDefaultActionsLocked(void* mock_obj) + GTEST_EXCLUSIVE_LOCK_REQUIRED_(internal::g_gmock_mutex) { + internal::g_gmock_mutex.AssertHeld(); + + if (g_mock_object_registry.states().count(mock_obj) == 0) { + // No ON_CALL() was set on the given mock object. + return; + } + + // Clears the default actions for each mock method in the given mock + // object. + FunctionMockers& mockers = + g_mock_object_registry.states()[mock_obj].function_mockers; + for (FunctionMockers::const_iterator it = mockers.begin(); + it != mockers.end(); ++it) { + (*it)->ClearDefaultActionsLocked(); + } + + // We don't clear the content of mockers, as they may still be + // needed by VerifyAndClearExpectationsLocked(). +} + +Expectation::Expectation() {} + +Expectation::Expectation( + const internal::linked_ptr& an_expectation_base) + : expectation_base_(an_expectation_base) {} + +Expectation::~Expectation() {} + +// Adds an expectation to a sequence. +void Sequence::AddExpectation(const Expectation& expectation) const { + if (*last_expectation_ != expectation) { + if (last_expectation_->expectation_base() != NULL) { + expectation.expectation_base()->immediate_prerequisites_ + += *last_expectation_; + } + *last_expectation_ = expectation; + } +} + +// Creates the implicit sequence if there isn't one. +InSequence::InSequence() { + if (internal::g_gmock_implicit_sequence.get() == NULL) { + internal::g_gmock_implicit_sequence.set(new Sequence); + sequence_created_ = true; + } else { + sequence_created_ = false; + } +} + +// Deletes the implicit sequence if it was created by the constructor +// of this object. +InSequence::~InSequence() { + if (sequence_created_) { + delete internal::g_gmock_implicit_sequence.get(); + internal::g_gmock_implicit_sequence.set(NULL); + } +} + +} // namespace testing +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: wan@google.com (Zhanyong Wan) + + +namespace testing { + +// TODO(wan@google.com): support using environment variables to +// control the flag values, like what Google Test does. + +GMOCK_DEFINE_bool_(catch_leaked_mocks, true, + "true iff Google Mock should report leaked mock objects " + "as failures."); + +GMOCK_DEFINE_string_(verbose, internal::kWarningVerbosity, + "Controls how verbose Google Mock's output is." + " Valid values:\n" + " info - prints all messages.\n" + " warning - prints warnings and errors.\n" + " error - prints errors only."); + +namespace internal { + +// Parses a string as a command line flag. The string should have the +// format "--gmock_flag=value". When def_optional is true, the +// "=value" part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +static const char* ParseGoogleMockFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--gmock_". + const std::string flag_str = std::string("--gmock_") + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a Google Mock bool flag, in the form of +// "--gmock_flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +static bool ParseGoogleMockBoolFlag(const char* str, const char* flag, + bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseGoogleMockFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for a Google Mock string flag, in the form of +// "--gmock_flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +template +static bool ParseGoogleMockStringFlag(const char* str, const char* flag, + String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseGoogleMockFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// The internal implementation of InitGoogleMock(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template +void InitGoogleMockImpl(int* argc, CharType** argv) { + // Makes sure Google Test is initialized. InitGoogleTest() is + // idempotent, so it's fine if the user has already called it. + InitGoogleTest(argc, argv); + if (*argc <= 0) return; + + for (int i = 1; i != *argc; i++) { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + // Do we see a Google Mock flag? + if (ParseGoogleMockBoolFlag(arg, "catch_leaked_mocks", + &GMOCK_FLAG(catch_leaked_mocks)) || + ParseGoogleMockStringFlag(arg, "verbose", &GMOCK_FLAG(verbose))) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } + } +} + +} // namespace internal + +// Initializes Google Mock. This must be called before running the +// tests. In particular, it parses a command line for the flags that +// Google Mock recognizes. Whenever a Google Mock flag is seen, it is +// removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Mock flag variables are +// updated. +// +// Since Google Test is needed for Google Mock to work, this function +// also initializes Google Test and parses its flags, if that hasn't +// been done. +GTEST_API_ void InitGoogleMock(int* argc, char** argv) { + internal::InitGoogleMockImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleMock(int* argc, wchar_t** argv) { + internal::InitGoogleMockImpl(argc, argv); +} + +} // namespace testing diff --git a/test/gmock-1.8.0/gmock/gmock.h b/test/gmock-1.8.0/gmock/gmock.h new file mode 100644 index 0000000..cd54177 --- /dev/null +++ b/test/gmock-1.8.0/gmock/gmock.h @@ -0,0 +1,14978 @@ +// 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 is the main header file a user should include. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_H_ + +// This file implements the following syntax: +// +// ON_CALL(mock_object.Method(...)) +// .With(...) ? +// .WillByDefault(...); +// +// where With() is optional and WillByDefault() must appear exactly +// once. +// +// EXPECT_CALL(mock_object.Method(...)) +// .With(...) ? +// .Times(...) ? +// .InSequence(...) * +// .WillOnce(...) * +// .WillRepeatedly(...) ? +// .RetiresOnSaturation() ? ; +// +// where all clauses are optional and WillOnce() can be repeated. + +// 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 + +// 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 defines some utilities useful for implementing Google +// Mock. They are subject to change without notice, so please DO NOT +// USE THEM IN USER CODE. + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_H_ + +#include +#include // NOLINT +#include + +// This file was GENERATED by command: +// pump.py gmock-generated-internal-utils.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 contains template meta-programming utility classes needed +// for implementing Google Mock. + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ + +// Copyright 2008, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Author: vadimb@google.com (Vadim Berman) +// +// Low-level types and utilities for porting Google Mock to various +// platforms. All macros ending with _ and symbols defined in an +// internal namespace are subject to change without notice. Code +// outside Google Mock MUST NOT USE THEM DIRECTLY. Macros that don't +// end with _ are part of Google Mock's public API and can be used by +// code outside Google Mock. + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ + +#include +#include +#include + +// Most of the utilities needed for porting Google Mock are also +// required for Google Test and are defined in gtest-port.h. +// +// Note to maintainers: to reduce code duplication, prefer adding +// portability utilities to Google Test's gtest-port.h instead of +// here, as Google Mock depends on Google Test. Only add a utility +// here if it's truly specific to Google Mock. +#include "gtest/gtest.h" +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Injection point for custom user configurations. +// The following macros can be defined: +// +// Flag related macros: +// GMOCK_DECLARE_bool_(name) +// GMOCK_DECLARE_int32_(name) +// GMOCK_DECLARE_string_(name) +// GMOCK_DEFINE_bool_(name, default_val, doc) +// GMOCK_DEFINE_int32_(name, default_val, doc) +// GMOCK_DEFINE_string_(name, default_val, doc) +// +// ** Custom implementation starts here ** + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_PORT_H_ + +// To avoid conditional compilation everywhere, we make it +// gmock-port.h's responsibility to #include the header implementing +// tr1/tuple. gmock-port.h does this via gtest-port.h, which is +// guaranteed to pull in the tuple header. + +// For MS Visual C++, check the compiler version. At least VS 2003 is +// required to compile Google Mock. +#if defined(_MSC_VER) && _MSC_VER < 1310 +# error "At least Visual C++ 2003 (7.1) is required to compile Google Mock." +#endif + +// Macro for referencing flags. This is public as we want the user to +// use this syntax to reference Google Mock flags. +#define GMOCK_FLAG(name) FLAGS_gmock_##name + +#if !defined(GMOCK_DECLARE_bool_) + +// Macros for declaring flags. +#define GMOCK_DECLARE_bool_(name) extern GTEST_API_ bool GMOCK_FLAG(name) +#define GMOCK_DECLARE_int32_(name) \ + extern GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) +#define GMOCK_DECLARE_string_(name) \ + extern GTEST_API_ ::std::string GMOCK_FLAG(name) + +// Macros for defining flags. +#define GMOCK_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GMOCK_FLAG(name) = (default_val) +#define GMOCK_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GMOCK_FLAG(name) = (default_val) +#define GMOCK_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::std::string GMOCK_FLAG(name) = (default_val) + +#endif // !defined(GMOCK_DECLARE_bool_) + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_PORT_H_ + +namespace testing { + +template +class Matcher; + +namespace internal { + +// An IgnoredValue object can be implicitly constructed from ANY value. +// This is used in implementing the IgnoreResult(a) action. +class IgnoredValue { + public: + // This constructor template allows any value to be implicitly + // converted to IgnoredValue. The object has no data member and + // doesn't try to remember anything about the argument. We + // deliberately omit the 'explicit' keyword in order to allow the + // conversion to be implicit. + template + IgnoredValue(const T& /* ignored */) {} // NOLINT(runtime/explicit) +}; + +// MatcherTuple::type is a tuple type where each field is a Matcher +// for the corresponding field in tuple type T. +template +struct MatcherTuple; + +template <> +struct MatcherTuple< ::testing::tuple<> > { + typedef ::testing::tuple< > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, + Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher, Matcher, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher, Matcher, Matcher, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher, Matcher, Matcher, Matcher, Matcher > type; +}; + +template +struct MatcherTuple< ::testing::tuple > { + typedef ::testing::tuple, Matcher, Matcher, Matcher, + Matcher, Matcher, Matcher, Matcher, Matcher, + Matcher > type; +}; + +// Template struct Function, where F must be a function type, contains +// the following typedefs: +// +// Result: the function's return type. +// ArgumentN: the type of the N-th argument, where N starts with 1. +// ArgumentTuple: the tuple type consisting of all parameters of F. +// ArgumentMatcherTuple: the tuple type consisting of Matchers for all +// parameters of F. +// MakeResultVoid: the function type obtained by substituting void +// for the return type of F. +// MakeResultIgnoredValue: +// the function type obtained by substituting Something +// for the return type of F. +template +struct Function; + +template +struct Function { + typedef R Result; + typedef ::testing::tuple<> ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(); + typedef IgnoredValue MakeResultIgnoredValue(); +}; + +template +struct Function + : Function { + typedef A1 Argument1; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1); + typedef IgnoredValue MakeResultIgnoredValue(A1); +}; + +template +struct Function + : Function { + typedef A2 Argument2; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2); +}; + +template +struct Function + : Function { + typedef A3 Argument3; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3); +}; + +template +struct Function + : Function { + typedef A4 Argument4; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4); +}; + +template +struct Function + : Function { + typedef A5 Argument5; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5); +}; + +template +struct Function + : Function { + typedef A6 Argument6; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6); +}; + +template +struct Function + : Function { + typedef A7 Argument7; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7); +}; + +template +struct Function + : Function { + typedef A8 Argument8; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8); +}; + +template +struct Function + : Function { + typedef A9 Argument9; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8, + A9); +}; + +template +struct Function + : Function { + typedef A10 Argument10; + typedef ::testing::tuple ArgumentTuple; + typedef typename MatcherTuple::type ArgumentMatcherTuple; + typedef void MakeResultVoid(A1, A2, A3, A4, A5, A6, A7, A8, A9, A10); + typedef IgnoredValue MakeResultIgnoredValue(A1, A2, A3, A4, A5, A6, A7, A8, + A9, A10); +}; + +} // namespace internal + +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_GENERATED_INTERNAL_UTILS_H_ + +namespace testing { +namespace internal { + +// Converts an identifier name to a space-separated list of lower-case +// words. Each maximum substring of the form [A-Za-z][a-z]*|\d+ is +// treated as one word. For example, both "FooBar123" and +// "foo_bar_123" are converted to "foo bar 123". +GTEST_API_ string ConvertIdentifierNameToWords(const char* id_name); + +// PointeeOf::type is the type of a value pointed to by a +// Pointer, which can be either a smart pointer or a raw pointer. The +// following default implementation is for the case where Pointer is a +// smart pointer. +template +struct PointeeOf { + // Smart pointer classes define type element_type as the type of + // their pointees. + typedef typename Pointer::element_type type; +}; +// This specialization is for the raw pointer case. +template +struct PointeeOf { typedef T type; }; // NOLINT + +// GetRawPointer(p) returns the raw pointer underlying p when p is a +// smart pointer, or returns p itself when p is already a raw pointer. +// The following default implementation is for the smart pointer case. +template +inline const typename Pointer::element_type* GetRawPointer(const Pointer& p) { + return p.get(); +} +// This overloaded version is for the raw pointer case. +template +inline Element* GetRawPointer(Element* p) { return p; } + +// This comparator allows linked_ptr to be stored in sets. +template +struct LinkedPtrLessThan { + bool operator()(const ::testing::internal::linked_ptr& lhs, + const ::testing::internal::linked_ptr& rhs) const { + return lhs.get() < rhs.get(); + } +}; + +// Symbian compilation can be done with wchar_t being either a native +// type or a typedef. Using Google Mock with OpenC without wchar_t +// should require the definition of _STLP_NO_WCHAR_T. +// +// MSVC treats wchar_t as a native type usually, but treats it as the +// same as unsigned short when the compiler option /Zc:wchar_t- is +// specified. It defines _NATIVE_WCHAR_T_DEFINED symbol when wchar_t +// is a native type. +#if (GTEST_OS_SYMBIAN && defined(_STLP_NO_WCHAR_T)) || \ + (defined(_MSC_VER) && !defined(_NATIVE_WCHAR_T_DEFINED)) +// wchar_t is a typedef. +#else +# define GMOCK_WCHAR_T_IS_NATIVE_ 1 +#endif + +// signed wchar_t and unsigned wchar_t are NOT in the C++ standard. +// Using them is a bad practice and not portable. So DON'T use them. +// +// Still, Google Mock is designed to work even if the user uses signed +// wchar_t or unsigned wchar_t (obviously, assuming the compiler +// supports them). +// +// To gcc, +// wchar_t == signed wchar_t != unsigned wchar_t == unsigned int +#ifdef __GNUC__ +// signed/unsigned wchar_t are valid types. +# define GMOCK_HAS_SIGNED_WCHAR_T_ 1 +#endif + +// In what follows, we use the term "kind" to indicate whether a type +// is bool, an integer type (excluding bool), a floating-point type, +// or none of them. This categorization is useful for determining +// when a matcher argument type can be safely converted to another +// type in the implementation of SafeMatcherCast. +enum TypeKind { + kBool, kInteger, kFloatingPoint, kOther +}; + +// KindOf::value is the kind of type T. +template struct KindOf { + enum { value = kOther }; // The default kind. +}; + +// This macro declares that the kind of 'type' is 'kind'. +#define GMOCK_DECLARE_KIND_(type, kind) \ + template <> struct KindOf { enum { value = kind }; } + +GMOCK_DECLARE_KIND_(bool, kBool); + +// All standard integer types. +GMOCK_DECLARE_KIND_(char, kInteger); +GMOCK_DECLARE_KIND_(signed char, kInteger); +GMOCK_DECLARE_KIND_(unsigned char, kInteger); +GMOCK_DECLARE_KIND_(short, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned short, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(int, kInteger); +GMOCK_DECLARE_KIND_(unsigned int, kInteger); +GMOCK_DECLARE_KIND_(long, kInteger); // NOLINT +GMOCK_DECLARE_KIND_(unsigned long, kInteger); // NOLINT + +#if GMOCK_WCHAR_T_IS_NATIVE_ +GMOCK_DECLARE_KIND_(wchar_t, kInteger); +#endif + +// Non-standard integer types. +GMOCK_DECLARE_KIND_(Int64, kInteger); +GMOCK_DECLARE_KIND_(UInt64, kInteger); + +// All standard floating-point types. +GMOCK_DECLARE_KIND_(float, kFloatingPoint); +GMOCK_DECLARE_KIND_(double, kFloatingPoint); +GMOCK_DECLARE_KIND_(long double, kFloatingPoint); + +#undef GMOCK_DECLARE_KIND_ + +// Evaluates to the kind of 'type'. +#define GMOCK_KIND_OF_(type) \ + static_cast< ::testing::internal::TypeKind>( \ + ::testing::internal::KindOf::value) + +// Evaluates to true iff integer type T is signed. +#define GMOCK_IS_SIGNED_(T) (static_cast(-1) < 0) + +// LosslessArithmeticConvertibleImpl::value +// is true iff arithmetic type From can be losslessly converted to +// arithmetic type To. +// +// It's the user's responsibility to ensure that both From and To are +// raw (i.e. has no CV modifier, is not a pointer, and is not a +// reference) built-in arithmetic types, kFromKind is the kind of +// From, and kToKind is the kind of To; the value is +// implementation-defined when the above pre-condition is violated. +template +struct LosslessArithmeticConvertibleImpl : public false_type {}; + +// Converting bool to bool is lossless. +template <> +struct LosslessArithmeticConvertibleImpl + : public true_type {}; // NOLINT + +// Converting bool to any integer type is lossless. +template +struct LosslessArithmeticConvertibleImpl + : public true_type {}; // NOLINT + +// Converting bool to any floating-point type is lossless. +template +struct LosslessArithmeticConvertibleImpl + : public true_type {}; // NOLINT + +// Converting an integer to bool is lossy. +template +struct LosslessArithmeticConvertibleImpl + : public false_type {}; // NOLINT + +// Converting an integer to another non-bool integer is lossless iff +// the target type's range encloses the source type's range. +template +struct LosslessArithmeticConvertibleImpl + : public bool_constant< + // When converting from a smaller size to a larger size, we are + // fine as long as we are not converting from signed to unsigned. + ((sizeof(From) < sizeof(To)) && + (!GMOCK_IS_SIGNED_(From) || GMOCK_IS_SIGNED_(To))) || + // When converting between the same size, the signedness must match. + ((sizeof(From) == sizeof(To)) && + (GMOCK_IS_SIGNED_(From) == GMOCK_IS_SIGNED_(To)))> {}; // NOLINT + +#undef GMOCK_IS_SIGNED_ + +// Converting an integer to a floating-point type may be lossy, since +// the format of a floating-point number is implementation-defined. +template +struct LosslessArithmeticConvertibleImpl + : public false_type {}; // NOLINT + +// Converting a floating-point to bool is lossy. +template +struct LosslessArithmeticConvertibleImpl + : public false_type {}; // NOLINT + +// Converting a floating-point to an integer is lossy. +template +struct LosslessArithmeticConvertibleImpl + : public false_type {}; // NOLINT + +// Converting a floating-point to another floating-point is lossless +// iff the target type is at least as big as the source type. +template +struct LosslessArithmeticConvertibleImpl< + kFloatingPoint, From, kFloatingPoint, To> + : public bool_constant {}; // NOLINT + +// LosslessArithmeticConvertible::value is true iff arithmetic +// type From can be losslessly converted to arithmetic type To. +// +// It's the user's responsibility to ensure that both From and To are +// raw (i.e. has no CV modifier, is not a pointer, and is not a +// reference) built-in arithmetic types; the value is +// implementation-defined when the above pre-condition is violated. +template +struct LosslessArithmeticConvertible + : public LosslessArithmeticConvertibleImpl< + GMOCK_KIND_OF_(From), From, GMOCK_KIND_OF_(To), To> {}; // NOLINT + +// This interface knows how to report a Google Mock failure (either +// non-fatal or fatal). +class FailureReporterInterface { + public: + // The type of a failure (either non-fatal or fatal). + enum FailureType { + kNonfatal, kFatal + }; + + virtual ~FailureReporterInterface() {} + + // Reports a failure that occurred at the given source file location. + virtual void ReportFailure(FailureType type, const char* file, int line, + const string& message) = 0; +}; + +// Returns the failure reporter used by Google Mock. +GTEST_API_ FailureReporterInterface* GetFailureReporter(); + +// Asserts that condition is true; aborts the process with the given +// message if condition is false. We cannot use LOG(FATAL) or CHECK() +// as Google Mock might be used to mock the log sink itself. We +// inline this function to prevent it from showing up in the stack +// trace. +inline void Assert(bool condition, const char* file, int line, + const string& msg) { + if (!condition) { + GetFailureReporter()->ReportFailure(FailureReporterInterface::kFatal, + file, line, msg); + } +} +inline void Assert(bool condition, const char* file, int line) { + Assert(condition, file, line, "Assertion failed."); +} + +// Verifies that condition is true; generates a non-fatal failure if +// condition is false. +inline void Expect(bool condition, const char* file, int line, + const string& msg) { + if (!condition) { + GetFailureReporter()->ReportFailure(FailureReporterInterface::kNonfatal, + file, line, msg); + } +} +inline void Expect(bool condition, const char* file, int line) { + Expect(condition, file, line, "Expectation failed."); +} + +// Severity level of a log. +enum LogSeverity { + kInfo = 0, + kWarning = 1 +}; + +// Valid values for the --gmock_verbose flag. + +// All logs (informational and warnings) are printed. +const char kInfoVerbosity[] = "info"; +// Only warnings are printed. +const char kWarningVerbosity[] = "warning"; +// No logs are printed. +const char kErrorVerbosity[] = "error"; + +// Returns true iff a log with the given severity is visible according +// to the --gmock_verbose flag. +GTEST_API_ bool LogIsVisible(LogSeverity severity); + +// Prints the given message to stdout iff 'severity' >= the level +// specified by the --gmock_verbose flag. If stack_frames_to_skip >= +// 0, also prints the stack trace excluding the top +// stack_frames_to_skip frames. In opt mode, any positive +// stack_frames_to_skip is treated as 0, since we don't know which +// function calls will be inlined by the compiler and need to be +// conservative. +GTEST_API_ void Log(LogSeverity severity, + const string& message, + int stack_frames_to_skip); + +// TODO(wan@google.com): group all type utilities together. + +// Type traits. + +// is_reference::value is non-zero iff T is a reference type. +template struct is_reference : public false_type {}; +template struct is_reference : public true_type {}; + +// type_equals::value is non-zero iff T1 and T2 are the same type. +template struct type_equals : public false_type {}; +template struct type_equals : public true_type {}; + +// remove_reference::type removes the reference from type T, if any. +template struct remove_reference { typedef T type; }; // NOLINT +template struct remove_reference { typedef T type; }; // NOLINT + +// DecayArray::type turns an array type U[N] to const U* and preserves +// other types. Useful for saving a copy of a function argument. +template struct DecayArray { typedef T type; }; // NOLINT +template struct DecayArray { + typedef const T* type; +}; +// Sometimes people use arrays whose size is not available at the use site +// (e.g. extern const char kNamePrefix[]). This specialization covers that +// case. +template struct DecayArray { + typedef const T* type; +}; + +// Disable MSVC warnings for infinite recursion, since in this case the +// the recursion is unreachable. +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable:4717) +#endif + +// Invalid() is usable as an expression of type T, but will terminate +// the program with an assertion failure if actually run. This is useful +// when a value of type T is needed for compilation, but the statement +// will not really be executed (or we don't care if the statement +// crashes). +template +inline T Invalid() { + Assert(false, "", -1, "Internal error: attempt to return invalid value"); + // This statement is unreachable, and would never terminate even if it + // could be reached. It is provided only to placate compiler warnings + // about missing return statements. + return Invalid(); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +// Given a raw type (i.e. having no top-level reference or const +// modifier) RawContainer that's either an STL-style container or a +// native array, class StlContainerView has the +// following members: +// +// - type is a type that provides an STL-style container view to +// (i.e. implements the STL container concept for) RawContainer; +// - const_reference is a type that provides a reference to a const +// RawContainer; +// - ConstReference(raw_container) returns a const reference to an STL-style +// container view to raw_container, which is a RawContainer. +// - Copy(raw_container) returns an STL-style container view of a +// copy of raw_container, which is a RawContainer. +// +// This generic version is used when RawContainer itself is already an +// STL-style container. +template +class StlContainerView { + public: + typedef RawContainer type; + typedef const type& const_reference; + + static const_reference ConstReference(const RawContainer& container) { + // Ensures that RawContainer is not a const type. + testing::StaticAssertTypeEq(); + return container; + } + static type Copy(const RawContainer& container) { return container; } +}; + +// This specialization is used when RawContainer is a native array type. +template +class StlContainerView { + public: + typedef GTEST_REMOVE_CONST_(Element) RawElement; + typedef internal::NativeArray type; + // NativeArray can represent a native array either by value or by + // reference (selected by a constructor argument), so 'const type' + // can be used to reference a const native array. We cannot + // 'typedef const type& const_reference' here, as that would mean + // ConstReference() has to return a reference to a local variable. + typedef const type const_reference; + + static const_reference ConstReference(const Element (&array)[N]) { + // Ensures that Element is not a const type. + testing::StaticAssertTypeEq(); +#if GTEST_OS_SYMBIAN + // The Nokia Symbian compiler confuses itself in template instantiation + // for this call without the cast to Element*: + // function call '[testing::internal::NativeArray].NativeArray( + // {lval} const char *[4], long, testing::internal::RelationToSource)' + // does not match + // 'testing::internal::NativeArray::NativeArray( + // char *const *, unsigned int, testing::internal::RelationToSource)' + // (instantiating: 'testing::internal::ContainsMatcherImpl + // ::Matches(const char * (&)[4]) const') + // (instantiating: 'testing::internal::StlContainerView:: + // ConstReference(const char * (&)[4])') + // (and though the N parameter type is mismatched in the above explicit + // conversion of it doesn't help - only the conversion of the array). + return type(const_cast(&array[0]), N, + RelationToSourceReference()); +#else + return type(array, N, RelationToSourceReference()); +#endif // GTEST_OS_SYMBIAN + } + static type Copy(const Element (&array)[N]) { +#if GTEST_OS_SYMBIAN + return type(const_cast(&array[0]), N, RelationToSourceCopy()); +#else + return type(array, N, RelationToSourceCopy()); +#endif // GTEST_OS_SYMBIAN + } +}; + +// This specialization is used when RawContainer is a native array +// represented as a (pointer, size) tuple. +template +class StlContainerView< ::testing::tuple > { + public: + typedef GTEST_REMOVE_CONST_( + typename internal::PointeeOf::type) RawElement; + typedef internal::NativeArray type; + typedef const type const_reference; + + static const_reference ConstReference( + const ::testing::tuple& array) { + return type(get<0>(array), get<1>(array), RelationToSourceReference()); + } + static type Copy(const ::testing::tuple& array) { + return type(get<0>(array), get<1>(array), RelationToSourceCopy()); + } +}; + +// The following specialization prevents the user from instantiating +// StlContainer with a reference type. +template class StlContainerView; + +// A type transform to remove constness from the first part of a pair. +// Pairs like that are used as the value_type of associative containers, +// and this transform produces a similar but assignable pair. +template +struct RemoveConstFromKey { + typedef T type; +}; + +// Partially specialized to remove constness from std::pair. +template +struct RemoveConstFromKey > { + typedef std::pair type; +}; + +// Mapping from booleans to types. Similar to boost::bool_ and +// std::integral_constant. +template +struct BooleanConstant {}; + +} // namespace internal +} // namespace testing + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_GMOCK_INTERNAL_UTILS_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_ +// 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 + +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_ +// 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_ + + +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. +// This file was GENERATED by command: +// pump.py gmock-generated-actions.h.pump +// DO NOT EDIT BY HAND!!! + +#ifndef GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ +#define GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_INTERNAL_CUSTOM_GMOCK_GENERATED_ACTIONS_H_ + +#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_ +// 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_ + +// 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 the ON_CALL() and EXPECT_CALL() macros. +// +// A user can use the ON_CALL() macro to specify the default action of +// a mock method. The syntax is: +// +// ON_CALL(mock_object, Method(argument-matchers)) +// .With(multi-argument-matcher) +// .WillByDefault(action); +// +// where the .With() clause is optional. +// +// A user can use the EXPECT_CALL() macro to specify an expectation on +// a mock method. The syntax is: +// +// EXPECT_CALL(mock_object, Method(argument-matchers)) +// .With(multi-argument-matchers) +// .Times(cardinality) +// .InSequence(sequences) +// .After(expectations) +// .WillOnce(action) +// .WillRepeatedly(action) +// .RetiresOnSaturation(); +// +// where all clauses are optional, and .InSequence()/.After()/ +// .WillOnce() can appear any number of times. + +#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ +#define GMOCK_INCLUDE_GMOCK_GMOCK_SPEC_BUILDERS_H_ + +#include +#include +#include +#include +#include + +#if GTEST_HAS_EXCEPTIONS +# include // NOLINT +#endif + +// 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 + + +#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. + internal::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 internal::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 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("<(") == 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 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(internal::string(s), listener); + } + + // Matches anything that can convert to internal::string. + // + // This is a template, not just a plain function with const internal::string&, + // because StringPiece has some interfering non-explicit constructors. + template + bool MatchAndExplain(const MatcheeStringType& s, + MatchResultListener* /* listener */) const { + const internal::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 internal::string s1 = listener1.str(); + const internal::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