From 89bc707001b6530a5025f95d5f64b33a34405e10 Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Thu, 21 Jan 2021 22:41:57 +0200 Subject: [PATCH 1/6] Public version 0.3.0 --- .cppinclude.json | 5 +- .cspell.json | 4 +- .gitignore | 6 +- CHANGELOG.md | 20 +- README.md | 224 +++++++- docs/examples/chromium/.cppinclude.json | 146 ++++- docs/examples/chromium/output_unix.txt | 236 ++++---- docs/examples/chromium/output_win.txt | 236 ++++---- docs/examples/clementine/.cppinclude.json | 6 + docs/examples/clementine/output_unix.txt | 4 + docs/examples/clementine/output_win.txt | 4 + docs/examples/cmake/.cppinclude.json | 32 ++ docs/examples/cmake/output_unix.txt | 112 ++++ docs/examples/cmake/run.sh | 8 + docs/examples/cppinclude/.cppinclude.json | 7 + docs/examples/cppinclude/output_unix.txt | 113 ++++ docs/examples/cppinclude/output_win.txt | 113 ++++ docs/examples/cppinclude/run.bat | 1 + docs/examples/cppinclude/run.sh | 3 + docs/examples/gcc/.cppinclude.json | 276 ++++++++- docs/examples/gcc/output_unix.txt | 195 ++++--- docs/examples/gcc/output_win.txt | 198 ++++--- docs/examples/llvm-project/.cppinclude.json | 417 ++++++++++++-- docs/examples/llvm-project/output_unix.txt | 237 ++++---- docs/examples/llvm-project/output_win.txt | 237 ++++---- docs/examples/lua/.cppinclude.json | 5 +- docs/examples/lua/output_unix.txt | 270 ++++++++- docs/examples/lua/output_win.txt | 270 ++++++++- .../notepad-plus-plus/output_unix.txt | 12 + .../examples/notepad-plus-plus/output_win.txt | 12 + .../simple_example_cmake/CMakeLists.txt | 7 + .../simple_example_cmake/base_char.hpp | 12 + .../base_char_factory.hpp | 14 + .../build/compile_commands.json | 27 + docs/examples/simple_example_cmake/char_a.cpp | 6 + docs/examples/simple_example_cmake/char_a.hpp | 10 + .../simple_example_cmake/char_a_factory.cpp | 8 + .../simple_example_cmake/char_a_factory.hpp | 10 + docs/examples/simple_example_cmake/char_b.cpp | 6 + docs/examples/simple_example_cmake/char_b.hpp | 10 + .../simple_example_cmake/char_b_factory.cpp | 9 + .../simple_example_cmake/char_b_factory.hpp | 10 + .../simple_example_cmake/char_kind.hpp | 9 + docs/examples/simple_example_cmake/main.cpp | 49 ++ .../simple_example_cmake/output_unix.txt | 32 ++ .../simple_example_cmake/output_win.txt | 32 ++ docs/examples/simple_example_cmake/run.bat | 5 + docs/examples/simple_example_cmake/run.sh | 9 + .../.cppinclude.json | 3 + .../CMakeLists.txt | 7 + .../base_char.hpp | 12 + .../base_char_factory.hpp | 14 + .../char_a.cpp | 6 + .../char_a.hpp | 10 + .../char_a_factory.cpp | 8 + .../char_a_factory.hpp | 10 + .../char_b.cpp | 6 + .../char_b.hpp | 10 + .../char_b_factory.cpp | 9 + .../char_b_factory.hpp | 10 + .../char_kind.hpp | 9 + .../main.cpp | 49 ++ .../output_unix.txt | 15 + .../output_win.txt | 15 + .../run.bat | 1 + .../run.sh | 4 + .../CMakeLists.txt | 9 + .../build/compile_commands.json | 27 + .../lib/a/char_a.cpp | 6 + .../lib/a/char_a.hpp | 10 + .../lib/a/char_a_factory.cpp | 8 + .../lib/a/char_a_factory.hpp | 10 + .../lib/b/char_b.cpp | 6 + .../lib/b/char_b.hpp | 10 + .../lib/b/char_b_factory.cpp | 9 + .../lib/b/char_b_factory.hpp | 10 + .../lib/base/base_char.hpp | 12 + .../lib/base/base_char_factory.hpp | 14 + .../lib/char_kind.hpp | 9 + .../main.cpp | 49 ++ .../output_unix.txt | 32 ++ .../output_win.txt | 32 ++ .../run.bat | 5 + .../run.sh | 9 + .../.cppinclude.json | 8 + .../CMakeLists.txt | 7 + .../base_char.hpp | 12 + .../base_char_factory.hpp | 14 + .../char_a.cpp | 6 + .../char_a.hpp | 10 + .../char_a_factory.cpp | 8 + .../char_a_factory.hpp | 10 + .../char_b.cpp | 6 + .../char_b.hpp | 10 + .../char_b_factory.cpp | 9 + .../char_b_factory.hpp | 10 + .../char_kind.hpp | 9 + .../config.hpp | 0 .../main.cpp | 49 ++ .../output_unix.txt | 35 ++ .../output_win.txt | 35 ++ .../run.bat | 1 + .../run.sh | 4 + .../settings.hpp | 0 docs/examples/tools/examples_tools.sh | 33 +- .../tools/run_analyze_git_repo_cmake.bat | 10 + docs/examples/tools/run_cmake.bat | 16 + docs/examples/vlc/.cppinclude.json | 337 ++++++++++- docs/examples/vlc/output_unix.txt | 148 ++--- docs/examples/vlc/output_win.txt | 148 ++--- docs/slides/2020_cppcon2020_small_talk.pdf | Bin 0 -> 796116 bytes docs/versions/VERSION_0.3.0.md | 129 +++++ src/3rd-part/std_fs/include/std_fs | 30 +- src/CMakeLists.txt | 2 + src/application/CMakeLists.txt | 13 +- src/application/app_con.cpp | 212 ++++--- src/application/app_con.hpp | 52 +- .../app_cant_create_report_impl.cpp | 17 +- ...pp => app_cant_load_reporter_settings.cpp} | 8 +- ...pp => app_cant_load_reporter_settings.hpp} | 8 +- src/application/exceptions/app_exceptions.hpp | 14 +- .../exceptions/app_incorrect_report_impl.cpp | 53 -- .../resources/app_resources_arguments.cpp | 50 +- .../resources/app_resources_arguments.hpp | 12 +- .../app_resources_configuration_file.cpp | 8 + .../app_resources_configuration_file.hpp | 8 + .../resources/app_resources_exceptions.cpp | 15 +- .../resources/app_resources_exceptions.hpp | 10 +- .../resources/app_resources_version.cpp | 4 +- src/application/test/CMakeLists.txt | 7 +- ...app_test_cmake_project_builder_fixture.cpp | 247 ++++++++ ...app_test_cmake_project_builder_fixture.hpp | 94 +++ .../app_test_configuration_file_fixture.cpp | 85 ++- .../app_test_configuration_file_fixture.hpp | 29 +- .../app_test_parser_wrapper_fixture.cpp | 55 +- .../app_test_parser_wrapper_fixture.hpp | 6 +- .../app_test_project_builder_fixture.cpp | 35 +- .../app_test_project_builder_fixture.hpp | 12 +- ...pp_test_report_settings_loader_fixture.cpp | 235 ++++++++ ...pp_test_report_settings_loader_fixture.hpp | 97 ++++ .../suits/app_test_cmake_project_builder.cpp | 285 +++++++++ .../app_test_configuration_file_suits.cpp | 129 +++++ ...pp_test_parser_arguments_wrapper_suits.cpp | 239 +++----- .../suits/app_test_report_settings_loader.cpp | 205 +++++++ .../tools/app_cmake_project_builder.cpp | 163 ++++++ .../tools/app_cmake_project_builder.hpp | 91 +++ .../tools/app_configuration_file.cpp | 144 ++++- .../tools/app_configuration_file.hpp | 44 ++ .../tools/app_configuration_file_loader.cpp | 81 +++ .../tools/app_configuration_file_loader.hpp | 52 ++ .../tools/app_parser_arg_wrapper.cpp | 83 ++- .../tools/app_parser_arg_wrapper.hpp | 5 + src/application/tools/app_project_builder.cpp | 49 +- src/application/tools/app_project_builder.hpp | 22 +- .../tools/app_report_settings_loader.cpp | 154 +++++ .../tools/app_report_settings_loader.hpp | 77 +++ src/cmake_project/CMakeLists.txt | 15 + src/cmake_project/api/cprj_loader.hpp | 33 ++ src/cmake_project/api/cprj_project.hpp | 36 ++ src/cmake_project/ih/cprj_accessor.hpp | 26 + src/cmake_project/ih/cprj_accessor_impl.cpp | 20 + src/cmake_project/ih/cprj_accessor_impl.hpp | 20 + .../impl/cprj_includes_parser.cpp | 203 +++++++ .../impl/cprj_includes_parser.hpp | 56 ++ .../impl/cprj_includes_parser_context.cpp | 48 ++ .../impl/cprj_includes_parser_context.hpp | 43 ++ src/cmake_project/impl/cprj_loader_impl.cpp | 97 ++++ src/cmake_project/impl/cprj_loader_impl.hpp | 56 ++ src/cmake_project/impl/cprj_project_impl.cpp | 84 +++ src/cmake_project/impl/cprj_project_impl.hpp | 50 ++ src/cmake_project/test/CMakeLists.txt | 15 + src/cmake_project/test/cprj_test_main.cpp | 10 + .../cprj_test_includes_parser_fixture.cpp | 80 +++ .../cprj_test_includes_parser_fixture.hpp | 48 ++ .../fixtures/cprj_test_loader_fixture.cpp | 192 +++++++ .../fixtures/cprj_test_loader_fixture.hpp | 87 +++ .../test/suits/cprj_test_includes_parser.cpp | 172 ++++++ .../test/suits/cprj_test_loader.cpp | 148 +++++ src/compilation_db/CMakeLists.txt | 15 + src/compilation_db/api/cdb_command_object.hpp | 22 + src/compilation_db/api/cdb_database.hpp | 33 ++ src/compilation_db/api/cdb_loader.hpp | 32 ++ src/compilation_db/ih/cdb_accessor.hpp | 25 + src/compilation_db/ih/cdb_accessor_impl.cpp | 20 + src/compilation_db/ih/cdb_accessor_impl.hpp | 20 + .../impl/cdb_command_object_impl.cpp | 44 ++ .../impl/cdb_command_object_impl.hpp | 36 ++ src/compilation_db/impl/cdb_database_impl.cpp | 49 ++ src/compilation_db/impl/cdb_database_impl.hpp | 40 ++ src/compilation_db/impl/cdb_loader_impl.cpp | 99 ++++ src/compilation_db/impl/cdb_loader_impl.hpp | 31 + .../resources/cdb_resources.cpp | 15 + .../resources/cdb_resources.hpp | 15 + src/compilation_db/test/CMakeLists.txt | 14 + src/compilation_db/test/cdb_test_main.cpp | 9 + .../test/fixtures/cdb_test_fixture.cpp | 80 +++ .../test/fixtures/cdb_test_fixture.hpp | 55 ++ .../test/suits/cdb_test_suits.cpp | 116 ++++ src/fs/CMakeLists.txt | 12 +- src/fs/api/{exceptions => }/fs_exceptions.hpp | 1 + .../fs_exception_cant_create_file.hpp | 2 +- .../fs_exception_cant_open_file_impl.hpp | 2 +- .../fs_exception_checking_exist_file_fail.cpp | 37 ++ .../fs_exception_checking_exist_file_fail.hpp | 39 ++ .../impl/physical/fs_physical_file_system.cpp | 8 +- src/fs/resources/fs_resources_exceptions.cpp | 8 + src/fs/resources/fs_resources_exceptions.hpp | 8 + src/json/CMakeLists.txt | 7 +- src/json/api/json_array.hpp | 3 +- src/json/api/json_object.hpp | 1 + src/json/ih/json_accessor.hpp | 3 +- src/json/impl/json_array_impl.hpp | 2 +- src/json/impl/json_object_impl.cpp | 8 + src/json/impl/json_object_impl.hpp | 3 +- src/json/impl/json_value_impl.hpp | 2 +- src/json/test/CMakeLists.txt | 6 +- src/json/test/suits/json_test_suits.cpp | 52 ++ src/model_includes/CMakeLists.txt | 7 +- src/model_includes/api/mi_analyzer.hpp | 11 +- src/model_includes/api/mi_file.hpp | 2 +- .../impl/mi_analyzer_context.cpp | 219 +++++++ .../impl/mi_analyzer_context.hpp | 97 ++++ src/model_includes/impl/mi_analyzer_impl.cpp | 223 ++++--- src/model_includes/impl/mi_analyzer_impl.hpp | 58 +- src/model_includes/impl/mi_file_impl.cpp | 2 +- src/model_includes/impl/mi_file_impl.hpp | 2 +- src/model_includes/impl/mi_resolver.cpp | 153 ++++- src/model_includes/impl/mi_resolver.hpp | 37 +- .../impl/mi_resolver_context.cpp | 63 ++ .../impl/mi_resolver_context.hpp | 61 ++ src/model_includes/test/CMakeLists.txt | 7 +- .../mi_test_model_includes_fixture.cpp | 90 ++- .../mi_test_model_includes_fixture.hpp | 33 +- .../wrappers/mi_test_file_wrapper.cpp | 3 +- .../wrappers/mi_test_file_wrapper.hpp | 4 + .../wrappers/mi_test_include_wrapper.cpp | 12 +- .../wrappers/mi_test_include_wrapper.hpp | 4 + .../wrappers/mi_test_model_wrapper.cpp | 3 +- .../wrappers/mi_test_model_wrapper.hpp | 1 + .../mi_test_analyzer_for_cmake_suits.cpp | 543 ++++++++++++++++++ .../test/suits/mi_test_analyzer_suits.cpp | 140 ++++- .../suits/mi_test_resolver_path_suits.cpp | 182 ++++++ src/parser/CMakeLists.txt | 10 +- src/parser/impl/pr_parser_context.cpp | 15 + src/parser/impl/pr_parser_context.hpp | 10 +- src/parser/impl/pr_parser_impl.cpp | 63 +- src/parser/impl/pr_parser_impl.hpp | 5 + src/parser/test/CMakeLists.txt | 6 +- src/parser/test/suits/pr_test_suits.cpp | 71 +++ src/project/CMakeLists.txt | 6 +- src/project/api/prj_exceptions.hpp | 19 + src/project/api/prj_project.hpp | 1 - .../exceptions/prj_base_exception_impl.hpp | 28 + .../prj_exception_invalid_regex.cpp | 32 ++ .../prj_exception_invalid_regex.hpp | 33 ++ src/project/impl/prj_project_impl.cpp | 38 +- src/project/impl/prj_project_impl.hpp | 7 +- .../resources/prj_resources_exceptions.cpp | 21 + .../resources/prj_resources_exceptions.hpp | 21 + src/project/test/suits/prj_test_suits.cpp | 54 +- src/reporter/CMakeLists.txt | 9 +- src/reporter/api/enums/rp_reporter_kind.hpp | 2 + src/reporter/api/rp_factory.hpp | 6 + src/reporter/api/rp_reporter.hpp | 8 +- src/reporter/api/rp_settings.hpp | 33 ++ .../exceptions/rp_base_exception_impl.hpp | 30 + src/reporter/exceptions/rp_exceptions.hpp | 19 + .../exceptions/rp_incorrect_report_impl.cpp | 69 +++ .../exceptions/rp_incorrect_report_impl.hpp} | 18 +- .../rp_different_type_reporter.cpp | 257 +++++++++ .../rp_different_type_reporter.hpp | 82 +++ .../rp_different_type_reporter_details.cpp | 52 ++ .../rp_different_type_reporter_details.hpp | 31 + .../{ => dump_reporter}/rp_dump_reporter.cpp | 10 +- .../{ => dump_reporter}/rp_dump_reporter.hpp | 4 + .../rp_most_impact_reporter.cpp | 109 ++-- .../rp_most_impact_reporter.hpp | 27 +- .../rp_most_impact_reporter_detail.cpp | 8 +- .../rp_most_impact_reporter_detail.hpp | 10 +- src/reporter/impl/rp_base_reporter_impl.cpp | 148 ++++- src/reporter/impl/rp_base_reporter_impl.hpp | 48 +- src/reporter/impl/rp_factpory_impl.cpp | 47 +- src/reporter/impl/rp_factpory_impl.hpp | 4 + src/reporter/impl/rp_settings_impl.cpp | 70 +++ src/reporter/impl/rp_settings_impl.hpp | 37 ++ src/reporter/impl/tools/rp_file_sorter.cpp | 37 ++ src/reporter/impl/tools/rp_file_sorter.hpp | 25 + .../rp_file_with_count.cpp} | 14 +- .../rp_file_with_count.hpp} | 14 +- .../tools/rp_file_with_count_container.cpp | 76 +++ .../tools/rp_file_with_count_container.hpp | 48 ++ .../impl/tools/rp_file_with_count_sorter.cpp | 30 + .../impl/tools/rp_file_with_count_sorter.hpp | 17 + .../tools/rp_includes_by_source_sorter.cpp | 41 ++ .../tools/rp_includes_by_source_sorter.hpp | 25 + .../rp_sorted_files_by_name_container.cpp | 59 ++ .../rp_sorted_files_by_name_container.hpp | 49 ++ ...rp_sorted_includes_by_source_container.cpp | 58 ++ ...rp_sorted_includes_by_source_container.hpp | 49 ++ .../rp_unincluded_reporter.cpp | 127 ++++ .../rp_unincluded_reporter.hpp | 55 ++ .../rp_unresolved_reporter.cpp | 97 +--- .../rp_unresolved_reporter.hpp | 39 +- .../rp_different_type_report_resources.cpp | 23 + .../rp_different_type_report_resources.hpp | 20 + src/reporter/resources/rp_dump_resources.cpp | 2 + src/reporter/resources/rp_dump_resources.hpp | 2 + ...pp => rp_most_impact_report_resources.cpp} | 6 +- ...pp => rp_most_impact_report_resources.hpp} | 4 +- .../resources/rp_resources_exceptions.cpp | 22 + .../resources/rp_resources_exceptions.hpp | 21 + .../rp_unincluded_report_resources.cpp | 17 + .../rp_unincluded_report_resources.hpp | 17 + ...cpp => rp_unresolved_report_resources.cpp} | 6 +- ...hpp => rp_unresolved_report_resources.hpp} | 4 +- src/reporter/test/CMakeLists.txt | 6 +- .../test/fixture/rp_test_reporter_fixture.cpp | 99 +++- .../test/fixture/rp_test_reporter_fixture.hpp | 26 +- .../rp_test_different_type_reporter_tests.cpp | 238 ++++++++ .../rp_test_most_impact_reporter_suits.cpp | 97 +++- .../rp_test_unincluded_reporter_suits.cpp | 204 +++++++ .../tools/rp_reporter_kind_functins.cpp | 75 +++ .../tools/rp_reporter_kind_functins.hpp | 20 + src/test_tools/CMakeLists.txt | 6 +- src/tools/CMakeLists.txt | 2 +- src/tools/regex.cpp | 41 ++ src/tools/regex.hpp | 31 + 327 files changed, 14366 insertions(+), 1975 deletions(-) create mode 100644 docs/examples/cmake/.cppinclude.json create mode 100644 docs/examples/cmake/output_unix.txt create mode 100755 docs/examples/cmake/run.sh create mode 100644 docs/examples/cppinclude/.cppinclude.json create mode 100644 docs/examples/cppinclude/output_unix.txt create mode 100644 docs/examples/cppinclude/output_win.txt create mode 100644 docs/examples/cppinclude/run.bat create mode 100755 docs/examples/cppinclude/run.sh create mode 100644 docs/examples/simple_example_cmake/CMakeLists.txt create mode 100644 docs/examples/simple_example_cmake/base_char.hpp create mode 100644 docs/examples/simple_example_cmake/base_char_factory.hpp create mode 100644 docs/examples/simple_example_cmake/build/compile_commands.json create mode 100644 docs/examples/simple_example_cmake/char_a.cpp create mode 100644 docs/examples/simple_example_cmake/char_a.hpp create mode 100644 docs/examples/simple_example_cmake/char_a_factory.cpp create mode 100644 docs/examples/simple_example_cmake/char_a_factory.hpp create mode 100644 docs/examples/simple_example_cmake/char_b.cpp create mode 100644 docs/examples/simple_example_cmake/char_b.hpp create mode 100644 docs/examples/simple_example_cmake/char_b_factory.cpp create mode 100644 docs/examples/simple_example_cmake/char_b_factory.hpp create mode 100644 docs/examples/simple_example_cmake/char_kind.hpp create mode 100644 docs/examples/simple_example_cmake/main.cpp create mode 100644 docs/examples/simple_example_cmake/output_unix.txt create mode 100644 docs/examples/simple_example_cmake/output_win.txt create mode 100644 docs/examples/simple_example_cmake/run.bat create mode 100755 docs/examples/simple_example_cmake/run.sh create mode 100644 docs/examples/simple_example_for_different_type_report/.cppinclude.json create mode 100644 docs/examples/simple_example_for_different_type_report/CMakeLists.txt create mode 100644 docs/examples/simple_example_for_different_type_report/base_char.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/base_char_factory.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_a.cpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_a.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_a_factory.cpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_a_factory.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_b.cpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_b.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_b_factory.cpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_b_factory.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/char_kind.hpp create mode 100644 docs/examples/simple_example_for_different_type_report/main.cpp create mode 100644 docs/examples/simple_example_for_different_type_report/output_unix.txt create mode 100644 docs/examples/simple_example_for_different_type_report/output_win.txt create mode 100644 docs/examples/simple_example_for_different_type_report/run.bat create mode 100755 docs/examples/simple_example_for_different_type_report/run.sh create mode 100644 docs/examples/simple_example_with_include_path_cmake/CMakeLists.txt create mode 100644 docs/examples/simple_example_with_include_path_cmake/build/compile_commands.json create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.cpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.cpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.cpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/lib/char_kind.hpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/main.cpp create mode 100644 docs/examples/simple_example_with_include_path_cmake/output_unix.txt create mode 100644 docs/examples/simple_example_with_include_path_cmake/output_win.txt create mode 100644 docs/examples/simple_example_with_include_path_cmake/run.bat create mode 100755 docs/examples/simple_example_with_include_path_cmake/run.sh create mode 100644 docs/examples/simple_example_with_unincluded_headers/.cppinclude.json create mode 100644 docs/examples/simple_example_with_unincluded_headers/CMakeLists.txt create mode 100644 docs/examples/simple_example_with_unincluded_headers/base_char.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_a.cpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_a.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_a_factory.cpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_b.cpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_b.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/char_kind.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/config.hpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/main.cpp create mode 100644 docs/examples/simple_example_with_unincluded_headers/output_unix.txt create mode 100644 docs/examples/simple_example_with_unincluded_headers/output_win.txt create mode 100644 docs/examples/simple_example_with_unincluded_headers/run.bat create mode 100755 docs/examples/simple_example_with_unincluded_headers/run.sh create mode 100644 docs/examples/simple_example_with_unincluded_headers/settings.hpp create mode 100644 docs/examples/tools/run_analyze_git_repo_cmake.bat create mode 100644 docs/examples/tools/run_cmake.bat create mode 100644 docs/slides/2020_cppcon2020_small_talk.pdf create mode 100644 docs/versions/VERSION_0.3.0.md rename src/application/exceptions/{app_cant_create_parser_impl.cpp => app_cant_load_reporter_settings.cpp} (59%) rename src/application/exceptions/{app_cant_create_parser_impl.hpp => app_cant_load_reporter_settings.hpp} (67%) delete mode 100644 src/application/exceptions/app_incorrect_report_impl.cpp create mode 100644 src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp create mode 100644 src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp create mode 100644 src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp create mode 100644 src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp create mode 100644 src/application/test/suits/app_test_cmake_project_builder.cpp create mode 100644 src/application/test/suits/app_test_report_settings_loader.cpp create mode 100644 src/application/tools/app_cmake_project_builder.cpp create mode 100644 src/application/tools/app_cmake_project_builder.hpp create mode 100644 src/application/tools/app_configuration_file_loader.cpp create mode 100644 src/application/tools/app_configuration_file_loader.hpp create mode 100644 src/application/tools/app_report_settings_loader.cpp create mode 100644 src/application/tools/app_report_settings_loader.hpp create mode 100644 src/cmake_project/CMakeLists.txt create mode 100644 src/cmake_project/api/cprj_loader.hpp create mode 100644 src/cmake_project/api/cprj_project.hpp create mode 100644 src/cmake_project/ih/cprj_accessor.hpp create mode 100644 src/cmake_project/ih/cprj_accessor_impl.cpp create mode 100644 src/cmake_project/ih/cprj_accessor_impl.hpp create mode 100644 src/cmake_project/impl/cprj_includes_parser.cpp create mode 100644 src/cmake_project/impl/cprj_includes_parser.hpp create mode 100644 src/cmake_project/impl/cprj_includes_parser_context.cpp create mode 100644 src/cmake_project/impl/cprj_includes_parser_context.hpp create mode 100644 src/cmake_project/impl/cprj_loader_impl.cpp create mode 100644 src/cmake_project/impl/cprj_loader_impl.hpp create mode 100644 src/cmake_project/impl/cprj_project_impl.cpp create mode 100644 src/cmake_project/impl/cprj_project_impl.hpp create mode 100644 src/cmake_project/test/CMakeLists.txt create mode 100644 src/cmake_project/test/cprj_test_main.cpp create mode 100644 src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp create mode 100644 src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp create mode 100644 src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp create mode 100644 src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp create mode 100644 src/cmake_project/test/suits/cprj_test_includes_parser.cpp create mode 100644 src/cmake_project/test/suits/cprj_test_loader.cpp create mode 100644 src/compilation_db/CMakeLists.txt create mode 100644 src/compilation_db/api/cdb_command_object.hpp create mode 100644 src/compilation_db/api/cdb_database.hpp create mode 100644 src/compilation_db/api/cdb_loader.hpp create mode 100644 src/compilation_db/ih/cdb_accessor.hpp create mode 100644 src/compilation_db/ih/cdb_accessor_impl.cpp create mode 100644 src/compilation_db/ih/cdb_accessor_impl.hpp create mode 100644 src/compilation_db/impl/cdb_command_object_impl.cpp create mode 100644 src/compilation_db/impl/cdb_command_object_impl.hpp create mode 100644 src/compilation_db/impl/cdb_database_impl.cpp create mode 100644 src/compilation_db/impl/cdb_database_impl.hpp create mode 100644 src/compilation_db/impl/cdb_loader_impl.cpp create mode 100644 src/compilation_db/impl/cdb_loader_impl.hpp create mode 100644 src/compilation_db/resources/cdb_resources.cpp create mode 100644 src/compilation_db/resources/cdb_resources.hpp create mode 100644 src/compilation_db/test/CMakeLists.txt create mode 100644 src/compilation_db/test/cdb_test_main.cpp create mode 100644 src/compilation_db/test/fixtures/cdb_test_fixture.cpp create mode 100644 src/compilation_db/test/fixtures/cdb_test_fixture.hpp create mode 100644 src/compilation_db/test/suits/cdb_test_suits.cpp rename src/fs/api/{exceptions => }/fs_exceptions.hpp (91%) create mode 100644 src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp create mode 100644 src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp create mode 100644 src/model_includes/impl/mi_analyzer_context.cpp create mode 100644 src/model_includes/impl/mi_analyzer_context.hpp create mode 100644 src/model_includes/impl/mi_resolver_context.cpp create mode 100644 src/model_includes/impl/mi_resolver_context.hpp create mode 100644 src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp create mode 100644 src/project/api/prj_exceptions.hpp create mode 100644 src/project/impl/exceptions/prj_base_exception_impl.hpp create mode 100644 src/project/impl/exceptions/prj_exception_invalid_regex.cpp create mode 100644 src/project/impl/exceptions/prj_exception_invalid_regex.hpp create mode 100644 src/project/resources/prj_resources_exceptions.cpp create mode 100644 src/project/resources/prj_resources_exceptions.hpp create mode 100644 src/reporter/api/rp_settings.hpp create mode 100644 src/reporter/exceptions/rp_base_exception_impl.hpp create mode 100644 src/reporter/exceptions/rp_exceptions.hpp create mode 100644 src/reporter/exceptions/rp_incorrect_report_impl.cpp rename src/{application/exceptions/app_incorrect_report_impl.hpp => reporter/exceptions/rp_incorrect_report_impl.hpp} (54%) create mode 100644 src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp create mode 100644 src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp create mode 100644 src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp create mode 100644 src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp rename src/reporter/impl/{ => dump_reporter}/rp_dump_reporter.cpp (96%) rename src/reporter/impl/{ => dump_reporter}/rp_dump_reporter.hpp (95%) rename src/reporter/impl/{ => most_impact_reporter}/rp_most_impact_reporter.cpp (68%) rename src/reporter/impl/{ => most_impact_reporter}/rp_most_impact_reporter.hpp (76%) rename src/reporter/impl/{impact_reporter => most_impact_reporter}/rp_most_impact_reporter_detail.cpp (81%) rename src/reporter/impl/{impact_reporter => most_impact_reporter}/rp_most_impact_reporter_detail.hpp (78%) create mode 100644 src/reporter/impl/rp_settings_impl.cpp create mode 100644 src/reporter/impl/rp_settings_impl.hpp create mode 100644 src/reporter/impl/tools/rp_file_sorter.cpp create mode 100644 src/reporter/impl/tools/rp_file_sorter.hpp rename src/reporter/impl/{impact_reporter/rp_file_info.cpp => tools/rp_file_with_count.cpp} (64%) rename src/reporter/impl/{impact_reporter/rp_file_info.hpp => tools/rp_file_with_count.hpp} (75%) create mode 100644 src/reporter/impl/tools/rp_file_with_count_container.cpp create mode 100644 src/reporter/impl/tools/rp_file_with_count_container.hpp create mode 100644 src/reporter/impl/tools/rp_file_with_count_sorter.cpp create mode 100644 src/reporter/impl/tools/rp_file_with_count_sorter.hpp create mode 100644 src/reporter/impl/tools/rp_includes_by_source_sorter.cpp create mode 100644 src/reporter/impl/tools/rp_includes_by_source_sorter.hpp create mode 100644 src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp create mode 100644 src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp create mode 100644 src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp create mode 100644 src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp create mode 100644 src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp create mode 100644 src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp rename src/reporter/impl/{ => unresolved_reporter}/rp_unresolved_reporter.cpp (69%) rename src/reporter/impl/{ => unresolved_reporter}/rp_unresolved_reporter.hpp (79%) create mode 100644 src/reporter/resources/rp_different_type_report_resources.cpp create mode 100644 src/reporter/resources/rp_different_type_report_resources.hpp rename src/reporter/resources/{rp_most_impact_reporter_resources.cpp => rp_most_impact_report_resources.cpp} (78%) rename src/reporter/resources/{rp_most_impact_reporter_resources.hpp => rp_most_impact_report_resources.hpp} (84%) create mode 100644 src/reporter/resources/rp_resources_exceptions.cpp create mode 100644 src/reporter/resources/rp_resources_exceptions.hpp create mode 100644 src/reporter/resources/rp_unincluded_report_resources.cpp create mode 100644 src/reporter/resources/rp_unincluded_report_resources.hpp rename src/reporter/resources/{rp_unresolved_reporter_resources.cpp => rp_unresolved_report_resources.cpp} (75%) rename src/reporter/resources/{rp_unresolved_reporter_resources.hpp => rp_unresolved_report_resources.hpp} (83%) create mode 100644 src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp create mode 100644 src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp create mode 100644 src/reporter/tools/rp_reporter_kind_functins.cpp create mode 100644 src/reporter/tools/rp_reporter_kind_functins.hpp create mode 100644 src/tools/regex.cpp create mode 100644 src/tools/regex.hpp diff --git a/.cppinclude.json b/.cppinclude.json index 8bd2d8b..d7ae070 100644 --- a/.cppinclude.json +++ b/.cppinclude.json @@ -1,6 +1,7 @@ { "project_dir" : "./src", "file_extentions" : ["*.cpp", "*.hpp"], - "include_dirs" : [".", "/usr/include/", "./3rd-part/cpp-std-fwd-master/"], - "ignore_dirs" : ["./3rd-part"] + "include_dirs" : ["."], + "ignore_dirs" : ["./3rd-part"], + "ignore_system_includes" : true } diff --git a/.cspell.json b/.cspell.json index 8b3bcaa..51e9863 100644 --- a/.cspell.json +++ b/.cspell.json @@ -20,6 +20,8 @@ "words": [ "nlohmann", "ccomplex", - "stdfs" + "stdfs", + "cmake", + "unincluded" ], } diff --git a/.gitignore b/.gitignore index 5f84bd8..fb72670 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ *.user -build/ -cppinclude -cppinclude.exe +/build/ +/cppinclude +/cppinclude.exe diff --git a/CHANGELOG.md b/CHANGELOG.md index 83b9ee9..c3c4009 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,22 @@ # Changelog +## [v0.3.0](docs/versions/VERSION_0.3.0.md) + +### Added (v0.3.0) + +* Support CMake ( JSON Compilation Database, compile_commands.json ) +* Analyze unincluded headers +* Analyze headers that are included in different ways ( #include "..." and #include <...> ) +* All arguments in configuration file + +### Fixed (v0.3.0) + +* Fixed bug in analyzing raw C++ strings +* Fixed bug in analyzing comments after #include + ## [v0.2.1](docs/versions/VERSION_0.2.1.md) -### Fixed +### Fixed (v0.2.1) * Fixed build for: * CentOS 7 @@ -12,12 +26,12 @@ ## [v0.2.0](docs/versions/VERSION_0.2.0.md) -### Added +### Added (v0.2.0) * New parameter *analyze_without_extension* * New argument *show_std_files* -### Fixed +### Fixed (v0.2.0) * Fixed bug in multiline comments * Fixed bug in multiline string diff --git a/README.md b/README.md index 3979ace..31b19ce 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,13 @@ include the file will be recompiled and sometime it takes a lot of time. * [Examples](#examples) * [Settings](#setting) * [All arguments](#all-arguments) + * [report](#report) + * [unresolved](#unresolved) + * [most_impact](#most_impact) + * [unincluded](#unincluded) + * [different_type](#different_type) * [configuration_file](#configuration_file) + * [compile_commands](#compile_commands) * [project_dir](#project_dir) * [file_extensions](#file_extensions) * [analyze_without_extension](#analyze_without_extension) @@ -17,11 +23,10 @@ include the file will be recompiled and sometime it takes a lot of time. * [ignore_dirs](#ignore_dirs) * [ignore_system_includes](#ignore_system_includes) * [ignore_files](#ignore_files) - * [report](#report) * [report_limit](#report_limit) * [report_details_limit](#report_details_limit) * [Build](#build) -* [Presentations](#presentation) +* [Presentations](#presentations) * [Tips for optimization includes](#tips-for-optimization-includes) * [Third-party libraries](#third-party-libraries) * [Support](#support) @@ -97,7 +102,9 @@ See more examples in [docs/examples/](docs/examples/) Name|Short description ------------ | ------------- +--[report](#report)=name1,name2,...|List reports. Name of reports: [unresolved](#unresolved), [most_impact](#most_impact), [unincluded](#unincluded), [different_type](#different_type) (default: [unresolved](#unresolved),[most_impact](#most_impact),[unincluded](#unincluded)) --[configuration_file](#configuration_file)=file|Path to configuration file (default: .cppinclude.json) +--[compile_commands](#compile_commands)=file|Path to JSON Compilation Database (default: compile_commands.json) --[project_dir](#project_dir)=dir|Project directory --[file_extensions](#file_extensions)=arg1,arg2,...|Extensions C++ files (default: \*.cpp, \*.hpp,\*.c,\*.h,\*.cxx,\*.hxx) --[analyze_without_extension](#analyze_without_extension)=true|Analyze files without extension (default: false) @@ -105,7 +112,6 @@ Name|Short description --[ignore_dirs](#ignore_dirs)=dir1,dir2,...|Directories that will be ignored --[ignore_system_includes](#ignore_system_includes)=true|Ignore headers in \<\> (default: false) --[ignore_files](#ignore_files)=regexp1,regexp2,...|Files will be ignored by regexp ---[report](#report)=name1,name2,...|List reports (default: unresolved,most_impact) --[report_limit](#report_limit)=42|Maximum elements in report, 0 - unlimited (default: 10) --[report_details_limit](#report_details_limit)=42|Maximum details in report, 0 - unlimited (default: 10) --[show_std_files](#show_std_files)|Show standard library headers in output (default: false) @@ -125,6 +131,27 @@ For example: [Back to top](#cppinclude) +### compile_commands + +Path to generated *compile_commands.json* file by CMake with argument +*-DCMAKE_EXPORT_COMPILE_COMMANDS=ON*, for example: + +`cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON` + +You can set path in configuration file: + +```json +{ + "compile_commands" : "build/compile_commands.json" +} +``` + +or in arguments: + +`cppinclude --compile_commands=build/compile_commands.json` + +[Back to top](#cppinclude) + ### project_dir Path to folder with sources. Often source files are located in *src* or @@ -252,9 +279,9 @@ or in arguments: Name of report. Possible values: * *unresolved* -- show included files that are not found in project folder; -* *most_impact* -- show files that most impact on other files. - -This report show how many files will be recompiled if the file is changes +* *most_impact* -- show files that most impact on other files; +* *unincluded* -- show unincluded headers; +* *different_type* -- show headers that are included in #include <...> and #include "..." . ``` cppinclude --report=unresolved @@ -262,6 +289,162 @@ cppinclude --report=most_impact cppinclude --report=unresolved,most_impact ``` +Also you can set in configuration file: + +```json +{ + "report" : [ "unresolved", "most_impact"] +} +``` + +[Back to top](#cppinclude) + +#### unresolved + +Show files that are found in includes but didn't found in file system. +One of the resean is missing includes files, for example: +There is file *main.cpp*, folder *include* that store file *header.hpp* : + +``` +tree +. +├── include +│   └── header.hpp +└── main.cpp + +``` + +If run *cppinclude* result will be: + +``` +cppinclude --report=unresolved +Start initialization project ... +Start analyze sources ... +Start report results ... +Unresolved files: +1. "header.hpp" isn't resolved in: + 1. "main.cpp" line: 1 + +``` + +But if add folder *include* to *include_dirs* resultat will be empty: + +``` +cppinclude --report=unresolved --include_dirs=include +``` + +[Back to top](#cppinclude) + +#### most_impact + +Show how many files will be recompiled with header will be changed. +Example from [docs/examples/simple_example/](docs/examples/simple_example/) + +``` +cppinclude --report=most_impact +... +Most impact files: +1 : "char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "base_char.hpp" line 3, impact on 10 file(s) +2 : "base_char.hpp" impact on 10 file(s) +Included by: + 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "char_a.hpp" line 3, impact on 2 file(s) + 3 : "char_b.hpp" line 3, impact on 2 file(s) +3 : "base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) +... +``` + +It means if file char_kind.hpp will be changed 11 files are recompiled. + +[Back to top](#cppinclude) + +#### unincluded + +Show files that are found in file system but didn't found in includes. +It often happens after refactoring when file that include header was deleted. +Example from [docs/examples/simple_example_with_unincluded_headers/](docs/examples/simple_example_with_unincluded_headers/) + +``` +cppinclude --report=unincluded +Start initialization project ... +Start analyze sources ... +Start report results ... +Unincluded headers: +1 : "config.hpp" +2 : "settings.hpp" + +``` + +**Limitations:** + +* Header with same names: + +If headers have same name but are located in different folders will be found +only first header and other will be unincluded. +For example: *lib1/header.hpp*, *lib2/header.hpp* and +*main.cpp* : + +```c++ +#include "header.hpp" +... +``` +Result will be: + +``` +cppinclude --include_dirs=lib1,lib2 --report=unincluded + +Start initialization project ... +Start analyze sources ... +Start report results ... +Unincluded headers: +1 : "lib2/header.hpp" + +``` + +* Empty result for CMake project: + +If analyze CMake project ( generated file compile_commands.json ) +result will be empty. Because in current implementation *cppinclude* analyze +source files on file system or files from compile_commands.json + +* Header files are files that have extension started with *h* letter + +***All limitations will be fixed in future releases *** + + +[Back to top](#cppinclude) + +#### different_type + +Show headers that are included in different ways. +It helps to follow code style in project, +for example include third party libraries in <...> and project header in "...". +Example from [docs/examples/simple_example_for_different_type_report/](docs/examples/simple_example_for_different_type_report/) + +``` +cppinclude --report=different_type +Start initialization project ... +Start analyze sources ... +Start report results ... +Files that are included by different ways: +1. base_char.hpp +With double quotation marks ( #include "..." ) in files: + 1. base_char_factory.hpp line 3 + 2. char_b.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a.hpp line 3 +2. base_char_factory.hpp +With double quotation marks ( #include "..." ) in files: + 1. char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a_factory.hpp line 3 +``` + [Back to top](#cppinclude) ### report_limit @@ -271,6 +454,14 @@ only 5 unresolved files will be in report: `cppinclude --report=unresolved --report_limit=5` +Also you can set in configuration file: + +```json +{ + "report_limit" : 5 +} +``` + [Back to top](#cppinclude) ### report_details_limit @@ -280,14 +471,30 @@ For example, only 3 files will be in report that include unresolved file `cppinclude --report=unresolved --report_details_limit=3` +Also you can set in configuration file: + +```json +{ + "report_details_limit" : 3 +} +``` + [Back to top](#cppinclude) ### show_std_files -Show standard library headers in output. +Enable showing standard library headers in output. `cppinclude --show_std_files=true` +Also you can set in configuration file: + +```json +{ + "show_std_files" : true +} +``` + [Back to top](#cppinclude) ## Build @@ -319,6 +526,9 @@ on Unix: ## Presentations +* 2020, Lightning Talk on CppCon 2020, cppinclude - Tool for analyzing includes in C++ + * Video : [https://www.youtube.com/watch?v=DXil_ahLTyg](https://www.youtube.com/watch?v=DXil_ahLTyg) + * Slides: [2020_cppcon2020_small_talk.pdf](docs/slides/2020_cppcon2020_small_talk.pdf) * 2020, internal talk - [2020_internal_talk.pdf](docs/slides/2020_internal_talk.pdf) [Back to top](#cppinclude) diff --git a/docs/examples/chromium/.cppinclude.json b/docs/examples/chromium/.cppinclude.json index db72af6..5ef6d86 100644 --- a/docs/examples/chromium/.cppinclude.json +++ b/docs/examples/chromium/.cppinclude.json @@ -1,6 +1,15 @@ { "project_dir" : "chromium", "ignore_system_includes" : true, + "file_extensions" : [ + "*.cpp", + "*.hpp", + "*.c", + "*.h", + "*.cxx", + "*.cc", + "*.hxx" + ], "include_dirs" : [ ".", @@ -16,10 +25,16 @@ "chromecast/public/", "components/cronet/native/generated/", "third_party/protobuf/src/", - "tools/clang/stack_maps/", - "gpu/command_buffer/", + "third_party/win_build_output/mc/", "third_party/wtl/include/", - "tools/traceline/traceline/" + "gpu/command_buffer/", + "tools/clang/stack_maps/", + "tools/traceline/traceline/", + "testing/gtest/include/", + "third_party/libxml/src/include/", + "third_party/crashpad/crashpad/compat/win/", + "gpu/", + "ui/views/controls/" ], @@ -127,6 +142,129 @@ "json_reader.cpp", "stddef.h", - "whatever/whocares/ok.h" + "whatever/whocares/ok.h", + + "generated_resources.h", + "strings.h", + "vector_icons.h", + "browser_resources.h", + "theme_resources.h", + "ui_resources.h", + "ui_chromeos_resources.h", + "ui_chromeos_strings.h", + "chromeos_strings.h", + "components_resources.h", + "components_chromium_strings.h", + "chrome_unscaled_resources.h", + "components_scaled_resources.h", + "extensions_strings.h", + "extensions_browser_resources.h", + "webui_resources.h", + "views_examples_resources.h", + "dev_ui_browser_resources.h", + "dev_ui_components_resources.h", + "version_info_values.h", + "locale_settings.h", + "dwmapi.h", + + "^chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h", + "^chrome/browser/chromeos/net/wake_on_wifi_connection_observer.h", + "^chrome/browser/metrics/variations/ui_string_overrider_factory.h", + "^chrome/browser/search/local_ntp_js_integrity.h", + "^chrome/browser/metrics/expired_histograms_array.h", + "^chromecast/bindings/grit/resources.h", + "^chrome/chrome_cleaner/constants/chrome_cleanup_tool_branding.h", + "^chrome/chrome_cleaner/constants/software_reporter_tool_branding.h", + "^chrome/grit/.*.h", + "^chrome/test/chromedriver/chrome/js.h", + "^chrome/test/base/perf/.*.h", + "^chrome/test/chromedriver/chrome/user_data_dir.h", + "^chrome/renderer/app_categorizer.h", + "^chrome/services/soda/internal/soda_client.h", + + "^chromecast/android/cast_shell_jni_registration.h", + "^chromecast/app/grit/chromecast_settings.h", + "^chromecast/internal/shell/browser/cast_content_browser_internal_manifest_overlay.h", + "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay.h", + + "^android_webview/test/android_webview_unittests_jni/.*.h", + "^android_webview/test/webview_instrumentation_test_native_jni/.*.h", + "^ash/public/cpp/assistant/assistant_image_downloader.h", + "^base/containers/any_internal.h", + "^chromeos/ime/input_methods.h", + "^components/certificate_transparency/data/log_list-inc.cc", + "^components/exo/wayland/fuzzer/.*.h", + "^components/metrics/structured/structured_events.h", + "^components/schema_org/.*.h", + "^components/search_engines/prepopulated_engines.h", + "^components/schema_org/schema_org_property_configurations.h", + "^components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator_helper.h", + "^components/variations/field_trial_config/fieldtrial_testing_config.h", + "^native_client/src/public/chrome_main.h", + "^net/http/transport_security_state_static_unittest_default.h", + "^native_client/src/public/.*.h", + "^tools/json_schema_compiler/test/.*.h", + "^base/android/jni_generator/", + "jni_headers/.*.h", + "jni_registration.h", + "chrome_jni", + + "nacl_check.h", + "_strings.h", + "_resources.h", + "_resources_map.h", + "version.h", + "_gen.h", + "_gen.inc", + "generated_.*.h", + "_autogen.h", + "^windows.h", + "^archive_entry.h", + "jni_*.h", + ".inc$", + "-inc.cc$", + + "^testing/gtest/gtest.h", + + "^chrome/services/soda/internal/soda_client.h", + "^chromecast/bindings/grit/resources.h", + "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay.h", + "^chromeos/printing/uri_components.h", + "^components/feed/core/feed_image_manager.h", + "^components/offline_pages/core/downloads/download_notifying_observer.h", + "^components/site_isolation/internal/google_chrome_isolated_origins.h", + "^content/common/mac_helpers.h", + "^content/public/renderer/media_stream_video_sink.h", + "^dummy_classes.h", + "^extensions/shell/common/api/identity.h", + "^extensions/shell/common/api/shell_api_features.h", + "^google_apis/internal/google_chrome_api_keys.h", + "^google_apis/internal/metrics_signing_key.h", + "^headless/embedded_resource_pak.h", + "^json/reader.h", + "^json/writer.h", + "^libunwind.h", + "^link.h", + "^mojo/public/cpp/bindings/tests/extra_cpp_template_unittest.test-mojom-extra_cpp_template_unittest.h", + "^nacl_app/flock.h", + "^native_client/src/trusted/desc/nacl_desc_quota.h", + "^native_client/src/trusted/desc/nacl_desc_quota_interface.h", + "^net/http/transport_security_state_static.h", + "^net/http/transport_security_state_static_unittest1.h", + "^net/http/transport_security_state_static_unittest2.h", + "^net/http/transport_security_state_static_unittest3.h", + "^net/spdy/platform/impl/spdy_unsafe_arena_impl.h", + "^net/traffic_annotation/network_traffic.h", + "^ppapi/c/trusted/ppb_instance_trusted.h", + "test_thunk/simple.h", + "^ppapi/thunk/ppb_display_color_profile_api.h", + "^ppapi/thunk/simple_api.h", + "^sandbox/linux/bpf_dsl/golden/golden_files.h", + "^skia/ext/skia_commit_hash.h", + "^test_output.h", + "^ui/chromeos/colors/cros_colors.h", + "^xdg-shell-server-protocol.h", + "^xdg-shell-unstable-v6-server-protocol.h", + "^zlib.h" ] } diff --git a/docs/examples/chromium/output_unix.txt b/docs/examples/chromium/output_unix.txt index adafb48..bebc2ab 100644 --- a/docs/examples/chromium/output_unix.txt +++ b/docs/examples/chromium/output_unix.txt @@ -2,119 +2,143 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "build/build_config.h" impact on 21394 file(s) +1 : "build/build_config.h" impact on 53601 file(s) Included by: - 1 : "base/compiler_specific.h" line 8, impact on 20668 file(s) - 2 : "base/immediate_crash.h" line 8, impact on 20317 file(s) - 3 : "base/template_util.h" line 15, impact on 19985 file(s) - 4 : "base/strings/string16.h" line 37, impact on 19723 file(s) - 5 : "base/numerics/safe_math_shared_impl.h" line 19, impact on 17993 file(s) - 6 : "base/time/time.h" line 66, impact on 17522 file(s) - 7 : "base/threading/platform_thread.h" line 17, impact on 16313 file(s) - 8 : "base/thread_annotations.h" line 36, impact on 16297 file(s) - 9 : "base/synchronization/lock_impl.h" line 12, impact on 16293 file(s) - 10 : "base/synchronization/lock.h" line 14, impact on 16291 file(s) - ... 10 of 1488 details -2 : "base/base_export.h" impact on 20920 file(s) + 1 : "base/compiler_specific.h" line 8, impact on 52630 file(s) + 2 : "base/immediate_crash.h" line 8, impact on 52115 file(s) + 3 : "base/template_util.h" line 15, impact on 51449 file(s) + 4 : "base/strings/string16.h" line 37, impact on 50734 file(s) + 5 : "base/numerics/safe_math_shared_impl.h" line 19, impact on 47161 file(s) + 6 : "base/time/time.h" line 66, impact on 46267 file(s) + 7 : "base/threading/platform_thread.h" line 17, impact on 43621 file(s) + 8 : "base/thread_annotations.h" line 36, impact on 43570 file(s) + 9 : "base/synchronization/lock_impl.h" line 12, impact on 43565 file(s) + 10 : "base/synchronization/lock.h" line 14, impact on 43561 file(s) + ... 10 of 5797 details +2 : "base/base_export.h" impact on 52947 file(s) Included by: - 1 : "base/check.h" line 10, impact on 20314 file(s) - 2 : "base/strings/string16.h" line 36, impact on 19723 file(s) - 3 : "base/strings/string_piece.h" line 32, impact on 19012 file(s) - 4 : "base/time/time.h" line 60, impact on 17522 file(s) - 5 : "base/threading/platform_thread.h" line 14, impact on 16313 file(s) - 6 : "base/synchronization/lock_impl.h" line 8, impact on 16293 file(s) - 7 : "base/synchronization/lock.h" line 8, impact on 16291 file(s) - 8 : "base/atomicops.h" line 39, impact on 16146 file(s) - 9 : "base/sequence_checker_impl.h" line 10, impact on 15941 file(s) - 10 : "base/threading/thread_collision_warner.h" line 11, impact on 15771 file(s) - ... 10 of 426 details -3 : "base/macros.h" impact on 20745 file(s) + 1 : "base/check.h" line 10, impact on 52108 file(s) + 2 : "base/strings/string16.h" line 36, impact on 50734 file(s) + 3 : "base/strings/string_piece.h" line 32, impact on 49683 file(s) + 4 : "base/time/time.h" line 60, impact on 46267 file(s) + 5 : "base/threading/platform_thread.h" line 14, impact on 43621 file(s) + 6 : "base/synchronization/lock_impl.h" line 8, impact on 43565 file(s) + 7 : "base/synchronization/lock.h" line 8, impact on 43561 file(s) + 8 : "base/atomicops.h" line 39, impact on 43505 file(s) + 9 : "base/sequence_checker_impl.h" line 10, impact on 42643 file(s) + 10 : "base/threading/thread_collision_warner.h" line 11, impact on 42420 file(s) + ... 10 of 424 details +3 : "base/compiler_specific.h" impact on 52630 file(s) Included by: - 1 : "base/threading/platform_thread.h" line 15, impact on 16313 file(s) - 2 : "base/synchronization/lock_impl.h" line 10, impact on 16293 file(s) - 3 : "base/synchronization/lock.h" line 10, impact on 16291 file(s) - 4 : "base/atomicops_internals_x86_msvc.h" line 16, impact on 16147 file(s) - 5 : "base/sequence_checker_impl.h" line 12, impact on 15941 file(s) - 6 : "base/memory/scoped_refptr.h" line 16, impact on 15884 file(s) - 7 : "base/threading/thread_collision_warner.h" line 13, impact on 15771 file(s) - 8 : "base/memory/ref_counted.h" line 17, impact on 15769 file(s) - 9 : "base/callback_internal.h" line 13, impact on 13337 file(s) - 10 : "base/containers/span.h" line 19, impact on 13302 file(s) - ... 10 of 11766 details -4 : "base/compiler_specific.h" impact on 20668 file(s) + 1 : "base/check.h" line 11, impact on 52108 file(s) + 2 : "base/strings/char_traits.h" line 10, impact on 49686 file(s) + 3 : "base/time/time.h" line 62, impact on 46267 file(s) + 4 : "base/sequence_checker_impl.h" line 11, impact on 42643 file(s) + 5 : "base/sequence_checker.h" line 9, impact on 42641 file(s) + 6 : "base/memory/scoped_refptr.h" line 15, impact on 42570 file(s) + 7 : "base/threading/thread_collision_warner.h" line 12, impact on 42420 file(s) + 8 : "base/memory/ref_counted.h" line 15, impact on 42417 file(s) + 9 : "base/mac/scoped_typeref.h" line 9, impact on 33370 file(s) + 10 : "base/bind.h" line 14, impact on 32901 file(s) + ... 10 of 2103 details +4 : "base/dcheck_is_on.h" impact on 52187 file(s) Included by: - 1 : "base/check.h" line 11, impact on 20314 file(s) - 2 : "base/strings/char_traits.h" line 10, impact on 19013 file(s) - 3 : "base/time/time.h" line 62, impact on 17522 file(s) - 4 : "base/sequence_checker_impl.h" line 11, impact on 15941 file(s) - 5 : "base/sequence_checker.h" line 9, impact on 15940 file(s) - 6 : "base/memory/scoped_refptr.h" line 15, impact on 15884 file(s) - 7 : "base/threading/thread_collision_warner.h" line 12, impact on 15771 file(s) - 8 : "base/memory/ref_counted.h" line 15, impact on 15769 file(s) - 9 : "base/mac/scoped_typeref.h" line 9, impact on 10162 file(s) - 10 : "base/bind.h" line 14, impact on 9974 file(s) - ... 10 of 1593 details -5 : "base/dcheck_is_on.h" impact on 20346 file(s) + 1 : "base/check.h" line 12, impact on 52108 file(s) + 2 : "base/win/scoped_handle.h" line 13, impact on 29646 file(s) + 3 : "base/logging.h" line 18, impact on 24516 file(s) + 4 : "components/performance_manager/public/graph/graph.h" line 12, impact on 204 file(s) + 5 : "remoting/base/protobuf_http_request_base.h" line 12, impact on 15 file(s) + 6 : "chrome/app/chrome_main_delegate.cc" line 14 + 7 : "chrome/chrome_cleaner/executables/chrome_cleaner_main.cc" line 16 + 8 : "chrome/chrome_cleaner/executables/chrome_reporter_main.cc" line 17 + 9 : "components/performance_manager/graph/graph.cc" line 7 + 10 : "content/browser/tracing/tracing_controller_impl.cc" line 16 +5 : "base/immediate_crash.h" impact on 52115 file(s) Included by: - 1 : "base/check.h" line 12, impact on 20314 file(s) - 2 : "base/win/scoped_handle.h" line 13, impact on 8218 file(s) - 3 : "base/logging.h" line 18, impact on 5808 file(s) - 4 : "components/performance_manager/public/graph/graph.h" line 12, impact on 55 file(s) - 5 : "remoting/base/protobuf_http_request_base.h" line 12, impact on 2 file(s) -6 : "base/immediate_crash.h" impact on 20317 file(s) + 1 : "base/check.h" line 13, impact on 52108 file(s) + 2 : "base/allocator/malloc_zone_functions_mac.h" line 12, impact on 5 file(s) + 3 : "base/immediate_crash_unittest.cc" line 5 + 4 : "base/test/immediate_crash_test_helper.cc" line 5 + 5 : "base/win/atl_throw.cc" line 11 + 6 : "components/openscreen_platform/logging.cc" line 11 + 7 : "components/services/storage/test_api/test_api.cc" line 8 + 8 : "net/dns/host_resolver.cc" line 11 + 9 : "services/test/echo/echo_service.cc" line 7 +6 : "base/check.h" impact on 52108 file(s) Included by: - 1 : "base/check.h" line 13, impact on 20314 file(s) - 2 : "base/allocator/malloc_zone_functions_mac.h" line 12, impact on 1 file(s) -7 : "base/check.h" impact on 20314 file(s) + 1 : "base/check_op.h" line 11, impact on 50824 file(s) + 2 : "base/optional.h" line 12, impact on 49824 file(s) + 3 : "base/stl_util.h" line 26, impact on 44553 file(s) + 4 : "base/sequence_checker.h" line 8, impact on 42641 file(s) + 5 : "base/memory/scoped_refptr.h" line 14, impact on 42570 file(s) + 6 : "base/notreached.h" line 8, impact on 40938 file(s) + 7 : "base/memory/weak_ptr.h" line 76, impact on 37545 file(s) + 8 : "base/mac/scoped_typeref.h" line 8, impact on 33370 file(s) + 9 : "base/bind_internal.h" line 18, impact on 32901 file(s) + 10 : "base/task_runner.h" line 13, impact on 30221 file(s) + ... 10 of 1523 details +7 : "base/macros.h" impact on 51890 file(s) Included by: - 1 : "base/check_op.h" line 11, impact on 19608 file(s) - 2 : "base/optional.h" line 12, impact on 19129 file(s) - 3 : "base/sequence_checker.h" line 8, impact on 15940 file(s) - 4 : "base/memory/scoped_refptr.h" line 14, impact on 15884 file(s) - 5 : "base/stl_util.h" line 26, impact on 15388 file(s) - 6 : "base/notreached.h" line 8, impact on 14345 file(s) - 7 : "base/memory/weak_ptr.h" line 76, impact on 12861 file(s) - 8 : "base/mac/scoped_typeref.h" line 8, impact on 10162 file(s) - 9 : "base/bind_internal.h" line 18, impact on 9974 file(s) - 10 : "base/task_runner.h" line 13, impact on 8695 file(s) - ... 10 of 166 details -8 : "base/template_util.h" impact on 19985 file(s) + 1 : "base/threading/platform_thread.h" line 15, impact on 43621 file(s) + 2 : "base/synchronization/lock_impl.h" line 10, impact on 43565 file(s) + 3 : "base/synchronization/lock.h" line 10, impact on 43561 file(s) + 4 : "base/atomicops_internals_x86_msvc.h" line 16, impact on 43506 file(s) + 5 : "base/sequence_checker_impl.h" line 12, impact on 42643 file(s) + 6 : "base/memory/scoped_refptr.h" line 16, impact on 42570 file(s) + 7 : "base/threading/thread_collision_warner.h" line 13, impact on 42420 file(s) + 8 : "base/memory/ref_counted.h" line 17, impact on 42417 file(s) + 9 : "base/containers/span.h" line 19, impact on 41006 file(s) + 10 : "base/callback_internal.h" line 13, impact on 38416 file(s) + ... 10 of 15272 details +8 : "base/template_util.h" impact on 51449 file(s) Included by: - 1 : "base/check_op.h" line 12, impact on 19608 file(s) - 2 : "base/optional.h" line 13, impact on 19129 file(s) - 3 : "base/stl_util.h" line 28, impact on 15388 file(s) - 4 : "base/containers/span.h" line 21, impact on 13302 file(s) - 5 : "base/memory/raw_scoped_refptr_mismatch_checker.h" line 10, impact on 9975 file(s) - 6 : "base/bind.h" line 15, impact on 9974 file(s) - 7 : "base/bind_internal.h" line 23, impact on 9974 file(s) - 8 : "base/containers/flat_tree.h" line 15, impact on 8859 file(s) - 9 : "base/containers/flat_map.h" line 14, impact on 8201 file(s) - 10 : "base/containers/circular_deque.h" line 18, impact on 7149 file(s) - ... 10 of 18 details -9 : "base/strings/string16.h" impact on 19723 file(s) + 1 : "base/check_op.h" line 12, impact on 50824 file(s) + 2 : "base/optional.h" line 13, impact on 49824 file(s) + 3 : "base/stl_util.h" line 28, impact on 44553 file(s) + 4 : "base/containers/span.h" line 21, impact on 41006 file(s) + 5 : "base/memory/raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32902 file(s) + 6 : "base/bind.h" line 15, impact on 32901 file(s) + 7 : "base/bind_internal.h" line 23, impact on 32901 file(s) + 8 : "base/containers/flat_tree.h" line 15, impact on 31143 file(s) + 9 : "base/containers/flat_map.h" line 14, impact on 29812 file(s) + 10 : "base/containers/circular_deque.h" line 18, impact on 26264 file(s) + ... 10 of 23 details +9 : "base/check_op.h" impact on 50824 file(s) Included by: - 1 : "base/strings/string_piece_forward.h" line 12, impact on 19171 file(s) - 2 : "base/strings/string_piece.h" line 35, impact on 19012 file(s) - 3 : "base/hash/hash.h" line 17, impact on 11896 file(s) - 4 : "base/files/file_path.h" line 115, impact on 8925 file(s) - 5 : "url/url_canon.h" line 13, impact on 7271 file(s) - 6 : "base/values.h" line 40, impact on 7218 file(s) - 7 : "url/gurl.h" line 16, impact on 6940 file(s) - 8 : "base/strings/string_util.h" line 24, impact on 5270 file(s) - 9 : "base/strings/string_util_win.h" line 19, impact on 5270 file(s) - 10 : "base/pickle.h" line 19, impact on 4056 file(s) - ... 10 of 1399 details -10 : "base/check_op.h" impact on 19608 file(s) + 1 : "base/strings/string_piece.h" line 33, impact on 49683 file(s) + 2 : "base/time/time.h" line 61, impact on 46267 file(s) + 3 : "base/thread_annotations.h" line 35, impact on 43570 file(s) + 4 : "base/synchronization/lock_impl.h" line 9, impact on 43565 file(s) + 5 : "base/synchronization/lock.h" line 9, impact on 43561 file(s) + 6 : "base/memory/ref_counted.h" line 14, impact on 42417 file(s) + 7 : "base/containers/checked_iterators.h" line 12, impact on 41010 file(s) + 8 : "base/containers/span.h" line 17, impact on 41006 file(s) + 9 : "base/win/scoped_handle.h" line 11, impact on 29646 file(s) + 10 : "base/observer_list_internal.h" line 9, impact on 27997 file(s) + ... 10 of 1609 details +10 : "base/strings/string16.h" impact on 50734 file(s) Included by: - 1 : "base/strings/string_piece.h" line 33, impact on 19012 file(s) - 2 : "base/time/time.h" line 61, impact on 17522 file(s) - 3 : "base/thread_annotations.h" line 35, impact on 16297 file(s) - 4 : "base/synchronization/lock_impl.h" line 9, impact on 16293 file(s) - 5 : "base/synchronization/lock.h" line 9, impact on 16291 file(s) - 6 : "base/memory/ref_counted.h" line 14, impact on 15769 file(s) - 7 : "base/containers/checked_iterators.h" line 12, impact on 13304 file(s) - 8 : "base/containers/span.h" line 17, impact on 13302 file(s) - 9 : "base/win/scoped_handle.h" line 11, impact on 8218 file(s) - 10 : "base/observer_list_internal.h" line 9, impact on 7688 file(s) - ... 10 of 172 details -... 10 of 11677 files + 1 : "base/strings/string_piece_forward.h" line 12, impact on 50009 file(s) + 2 : "base/strings/string_piece.h" line 35, impact on 49683 file(s) + 3 : "base/hash/hash.h" line 17, impact on 37370 file(s) + 4 : "base/files/file_path.h" line 115, impact on 31747 file(s) + 5 : "base/values.h" line 40, impact on 27647 file(s) + 6 : "url/url_canon.h" line 13, impact on 24380 file(s) + 7 : "url/gurl.h" line 16, impact on 23762 file(s) + 8 : "base/strings/string_util.h" line 24, impact on 23068 file(s) + 9 : "base/strings/string_util_win.h" line 19, impact on 23068 file(s) + 10 : "base/pickle.h" line 19, impact on 18703 file(s) + ... 10 of 2099 details +... 10 of 26036 files +Unincluded headers: +1 : "ash/accelerators/accelerator_ids.h" +2 : "ash/assistant/model/assistant_screen_context_model_observer.h" +3 : "base/file_version_info_mac.h" +4 : "base/ios/crb_protocol_observers.h" +5 : "base/ios/ns_error_util.h" +6 : "base/ios/weak_nsobject.h" +7 : "base/mac/launch_services_util.h" +8 : "base/mac/objc_release_properties.h" +9 : "base/mac/scoped_aedesc.h" +10 : "base/mac/scoped_objc_class_swizzler.h" +... 10 of 2691 files diff --git a/docs/examples/chromium/output_win.txt b/docs/examples/chromium/output_win.txt index 3fa8075..98e2579 100644 --- a/docs/examples/chromium/output_win.txt +++ b/docs/examples/chromium/output_win.txt @@ -2,119 +2,143 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "build\build_config.h" impact on 21394 file(s) +1 : "build\build_config.h" impact on 53601 file(s) Included by: - 1 : "base\compiler_specific.h" line 8, impact on 20668 file(s) - 2 : "base\immediate_crash.h" line 8, impact on 20317 file(s) - 3 : "base\template_util.h" line 15, impact on 19985 file(s) - 4 : "base\strings\string16.h" line 37, impact on 19723 file(s) - 5 : "base\numerics\safe_math_shared_impl.h" line 19, impact on 17993 file(s) - 6 : "base\time\time.h" line 66, impact on 17522 file(s) - 7 : "base\threading\platform_thread.h" line 17, impact on 16313 file(s) - 8 : "base\thread_annotations.h" line 36, impact on 16297 file(s) - 9 : "base\synchronization\lock_impl.h" line 12, impact on 16293 file(s) - 10 : "base\synchronization\lock.h" line 14, impact on 16291 file(s) - ... 10 of 1488 details -2 : "base\base_export.h" impact on 20920 file(s) + 1 : "base\compiler_specific.h" line 8, impact on 52630 file(s) + 2 : "base\immediate_crash.h" line 8, impact on 52115 file(s) + 3 : "base\template_util.h" line 15, impact on 51449 file(s) + 4 : "base\strings\string16.h" line 37, impact on 50734 file(s) + 5 : "base\numerics\safe_math_shared_impl.h" line 19, impact on 47161 file(s) + 6 : "base\time\time.h" line 66, impact on 46267 file(s) + 7 : "base\threading\platform_thread.h" line 17, impact on 43621 file(s) + 8 : "base\thread_annotations.h" line 36, impact on 43570 file(s) + 9 : "base\synchronization\lock_impl.h" line 12, impact on 43565 file(s) + 10 : "base\synchronization\lock.h" line 14, impact on 43561 file(s) + ... 10 of 5797 details +2 : "base\base_export.h" impact on 52947 file(s) Included by: - 1 : "base\check.h" line 10, impact on 20314 file(s) - 2 : "base\strings\string16.h" line 36, impact on 19723 file(s) - 3 : "base\strings\string_piece.h" line 32, impact on 19012 file(s) - 4 : "base\time\time.h" line 60, impact on 17522 file(s) - 5 : "base\threading\platform_thread.h" line 14, impact on 16313 file(s) - 6 : "base\synchronization\lock_impl.h" line 8, impact on 16293 file(s) - 7 : "base\synchronization\lock.h" line 8, impact on 16291 file(s) - 8 : "base\atomicops.h" line 39, impact on 16146 file(s) - 9 : "base\sequence_checker_impl.h" line 10, impact on 15941 file(s) - 10 : "base\threading\thread_collision_warner.h" line 11, impact on 15771 file(s) - ... 10 of 426 details -3 : "base\macros.h" impact on 20745 file(s) + 1 : "base\check.h" line 10, impact on 52108 file(s) + 2 : "base\strings\string16.h" line 36, impact on 50734 file(s) + 3 : "base\strings\string_piece.h" line 32, impact on 49683 file(s) + 4 : "base\time\time.h" line 60, impact on 46267 file(s) + 5 : "base\threading\platform_thread.h" line 14, impact on 43621 file(s) + 6 : "base\synchronization\lock_impl.h" line 8, impact on 43565 file(s) + 7 : "base\synchronization\lock.h" line 8, impact on 43561 file(s) + 8 : "base\atomicops.h" line 39, impact on 43505 file(s) + 9 : "base\sequence_checker_impl.h" line 10, impact on 42643 file(s) + 10 : "base\threading\thread_collision_warner.h" line 11, impact on 42420 file(s) + ... 10 of 424 details +3 : "base\compiler_specific.h" impact on 52630 file(s) Included by: - 1 : "base\threading\platform_thread.h" line 15, impact on 16313 file(s) - 2 : "base\synchronization\lock_impl.h" line 10, impact on 16293 file(s) - 3 : "base\synchronization\lock.h" line 10, impact on 16291 file(s) - 4 : "base\atomicops_internals_x86_msvc.h" line 16, impact on 16147 file(s) - 5 : "base\sequence_checker_impl.h" line 12, impact on 15941 file(s) - 6 : "base\memory\scoped_refptr.h" line 16, impact on 15884 file(s) - 7 : "base\threading\thread_collision_warner.h" line 13, impact on 15771 file(s) - 8 : "base\memory\ref_counted.h" line 17, impact on 15769 file(s) - 9 : "base\callback_internal.h" line 13, impact on 13337 file(s) - 10 : "base\containers\span.h" line 19, impact on 13302 file(s) - ... 10 of 11766 details -4 : "base\compiler_specific.h" impact on 20668 file(s) + 1 : "base\check.h" line 11, impact on 52108 file(s) + 2 : "base\strings\char_traits.h" line 10, impact on 49686 file(s) + 3 : "base\time\time.h" line 62, impact on 46267 file(s) + 4 : "base\sequence_checker_impl.h" line 11, impact on 42643 file(s) + 5 : "base\sequence_checker.h" line 9, impact on 42641 file(s) + 6 : "base\memory\scoped_refptr.h" line 15, impact on 42570 file(s) + 7 : "base\threading\thread_collision_warner.h" line 12, impact on 42420 file(s) + 8 : "base\memory\ref_counted.h" line 15, impact on 42417 file(s) + 9 : "base\mac\scoped_typeref.h" line 9, impact on 33370 file(s) + 10 : "base\bind.h" line 14, impact on 32901 file(s) + ... 10 of 2103 details +4 : "base\dcheck_is_on.h" impact on 52187 file(s) Included by: - 1 : "base\check.h" line 11, impact on 20314 file(s) - 2 : "base\strings\char_traits.h" line 10, impact on 19013 file(s) - 3 : "base\time\time.h" line 62, impact on 17522 file(s) - 4 : "base\sequence_checker_impl.h" line 11, impact on 15941 file(s) - 5 : "base\sequence_checker.h" line 9, impact on 15940 file(s) - 6 : "base\memory\scoped_refptr.h" line 15, impact on 15884 file(s) - 7 : "base\threading\thread_collision_warner.h" line 12, impact on 15771 file(s) - 8 : "base\memory\ref_counted.h" line 15, impact on 15769 file(s) - 9 : "base\mac\scoped_typeref.h" line 9, impact on 10162 file(s) - 10 : "base\bind.h" line 14, impact on 9974 file(s) - ... 10 of 1593 details -5 : "base\dcheck_is_on.h" impact on 20346 file(s) + 1 : "base\check.h" line 12, impact on 52108 file(s) + 2 : "base\win\scoped_handle.h" line 13, impact on 29646 file(s) + 3 : "base\logging.h" line 18, impact on 24516 file(s) + 4 : "components\performance_manager\public\graph\graph.h" line 12, impact on 204 file(s) + 5 : "remoting\base\protobuf_http_request_base.h" line 12, impact on 15 file(s) + 6 : "chrome\app\chrome_main_delegate.cc" line 14 + 7 : "chrome\chrome_cleaner\executables\chrome_cleaner_main.cc" line 16 + 8 : "chrome\chrome_cleaner\executables\chrome_reporter_main.cc" line 17 + 9 : "components\performance_manager\graph\graph.cc" line 7 + 10 : "content\browser\tracing\tracing_controller_impl.cc" line 16 +5 : "base\immediate_crash.h" impact on 52115 file(s) Included by: - 1 : "base\check.h" line 12, impact on 20314 file(s) - 2 : "base\win\scoped_handle.h" line 13, impact on 8218 file(s) - 3 : "base\logging.h" line 18, impact on 5808 file(s) - 4 : "components\performance_manager\public\graph\graph.h" line 12, impact on 55 file(s) - 5 : "remoting\base\protobuf_http_request_base.h" line 12, impact on 2 file(s) -6 : "base\immediate_crash.h" impact on 20317 file(s) + 1 : "base\check.h" line 13, impact on 52108 file(s) + 2 : "base\allocator\malloc_zone_functions_mac.h" line 12, impact on 5 file(s) + 3 : "base\immediate_crash_unittest.cc" line 5 + 4 : "base\test\immediate_crash_test_helper.cc" line 5 + 5 : "base\win\atl_throw.cc" line 11 + 6 : "components\openscreen_platform\logging.cc" line 11 + 7 : "components\services\storage\test_api\test_api.cc" line 8 + 8 : "net\dns\host_resolver.cc" line 11 + 9 : "services\test\echo\echo_service.cc" line 7 +6 : "base\check.h" impact on 52108 file(s) Included by: - 1 : "base\check.h" line 13, impact on 20314 file(s) - 2 : "base\allocator\malloc_zone_functions_mac.h" line 12, impact on 1 file(s) -7 : "base\check.h" impact on 20314 file(s) + 1 : "base\check_op.h" line 11, impact on 50824 file(s) + 2 : "base\optional.h" line 12, impact on 49824 file(s) + 3 : "base\stl_util.h" line 26, impact on 44553 file(s) + 4 : "base\sequence_checker.h" line 8, impact on 42641 file(s) + 5 : "base\memory\scoped_refptr.h" line 14, impact on 42570 file(s) + 6 : "base\notreached.h" line 8, impact on 40938 file(s) + 7 : "base\memory\weak_ptr.h" line 76, impact on 37545 file(s) + 8 : "base\mac\scoped_typeref.h" line 8, impact on 33370 file(s) + 9 : "base\bind_internal.h" line 18, impact on 32901 file(s) + 10 : "base\task_runner.h" line 13, impact on 30221 file(s) + ... 10 of 1523 details +7 : "base\macros.h" impact on 51890 file(s) Included by: - 1 : "base\check_op.h" line 11, impact on 19608 file(s) - 2 : "base\optional.h" line 12, impact on 19129 file(s) - 3 : "base\sequence_checker.h" line 8, impact on 15940 file(s) - 4 : "base\memory\scoped_refptr.h" line 14, impact on 15884 file(s) - 5 : "base\stl_util.h" line 26, impact on 15388 file(s) - 6 : "base\notreached.h" line 8, impact on 14345 file(s) - 7 : "base\memory\weak_ptr.h" line 76, impact on 12861 file(s) - 8 : "base\mac\scoped_typeref.h" line 8, impact on 10162 file(s) - 9 : "base\bind_internal.h" line 18, impact on 9974 file(s) - 10 : "base\task_runner.h" line 13, impact on 8695 file(s) - ... 10 of 166 details -8 : "base\template_util.h" impact on 19985 file(s) + 1 : "base\threading\platform_thread.h" line 15, impact on 43621 file(s) + 2 : "base\synchronization\lock_impl.h" line 10, impact on 43565 file(s) + 3 : "base\synchronization\lock.h" line 10, impact on 43561 file(s) + 4 : "base\atomicops_internals_x86_msvc.h" line 16, impact on 43506 file(s) + 5 : "base\sequence_checker_impl.h" line 12, impact on 42643 file(s) + 6 : "base\memory\scoped_refptr.h" line 16, impact on 42570 file(s) + 7 : "base\threading\thread_collision_warner.h" line 13, impact on 42420 file(s) + 8 : "base\memory\ref_counted.h" line 17, impact on 42417 file(s) + 9 : "base\containers\span.h" line 19, impact on 41006 file(s) + 10 : "base\callback_internal.h" line 13, impact on 38416 file(s) + ... 10 of 15272 details +8 : "base\template_util.h" impact on 51449 file(s) Included by: - 1 : "base\check_op.h" line 12, impact on 19608 file(s) - 2 : "base\optional.h" line 13, impact on 19129 file(s) - 3 : "base\stl_util.h" line 28, impact on 15388 file(s) - 4 : "base\containers\span.h" line 21, impact on 13302 file(s) - 5 : "base\memory\raw_scoped_refptr_mismatch_checker.h" line 10, impact on 9975 file(s) - 6 : "base\bind.h" line 15, impact on 9974 file(s) - 7 : "base\bind_internal.h" line 23, impact on 9974 file(s) - 8 : "base\containers\flat_tree.h" line 15, impact on 8859 file(s) - 9 : "base\containers\flat_map.h" line 14, impact on 8201 file(s) - 10 : "base\containers\circular_deque.h" line 18, impact on 7149 file(s) - ... 10 of 18 details -9 : "base\strings\string16.h" impact on 19723 file(s) + 1 : "base\check_op.h" line 12, impact on 50824 file(s) + 2 : "base\optional.h" line 13, impact on 49824 file(s) + 3 : "base\stl_util.h" line 28, impact on 44553 file(s) + 4 : "base\containers\span.h" line 21, impact on 41006 file(s) + 5 : "base\memory\raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32902 file(s) + 6 : "base\bind.h" line 15, impact on 32901 file(s) + 7 : "base\bind_internal.h" line 23, impact on 32901 file(s) + 8 : "base\containers\flat_tree.h" line 15, impact on 31143 file(s) + 9 : "base\containers\flat_map.h" line 14, impact on 29812 file(s) + 10 : "base\containers\circular_deque.h" line 18, impact on 26264 file(s) + ... 10 of 23 details +9 : "base\check_op.h" impact on 50824 file(s) Included by: - 1 : "base\strings\string_piece_forward.h" line 12, impact on 19171 file(s) - 2 : "base\strings\string_piece.h" line 35, impact on 19012 file(s) - 3 : "base\hash\hash.h" line 17, impact on 11896 file(s) - 4 : "base\files\file_path.h" line 115, impact on 8925 file(s) - 5 : "url\url_canon.h" line 13, impact on 7271 file(s) - 6 : "base\values.h" line 40, impact on 7218 file(s) - 7 : "url\gurl.h" line 16, impact on 6940 file(s) - 8 : "base\strings\string_util.h" line 24, impact on 5270 file(s) - 9 : "base\strings\string_util_win.h" line 19, impact on 5270 file(s) - 10 : "base\pickle.h" line 19, impact on 4056 file(s) - ... 10 of 1399 details -10 : "base\check_op.h" impact on 19608 file(s) + 1 : "base\strings\string_piece.h" line 33, impact on 49683 file(s) + 2 : "base\time\time.h" line 61, impact on 46267 file(s) + 3 : "base\thread_annotations.h" line 35, impact on 43570 file(s) + 4 : "base\synchronization\lock_impl.h" line 9, impact on 43565 file(s) + 5 : "base\synchronization\lock.h" line 9, impact on 43561 file(s) + 6 : "base\memory\ref_counted.h" line 14, impact on 42417 file(s) + 7 : "base\containers\checked_iterators.h" line 12, impact on 41010 file(s) + 8 : "base\containers\span.h" line 17, impact on 41006 file(s) + 9 : "base\win\scoped_handle.h" line 11, impact on 29646 file(s) + 10 : "base\observer_list_internal.h" line 9, impact on 27997 file(s) + ... 10 of 1609 details +10 : "base\strings\string16.h" impact on 50734 file(s) Included by: - 1 : "base\strings\string_piece.h" line 33, impact on 19012 file(s) - 2 : "base\time\time.h" line 61, impact on 17522 file(s) - 3 : "base\thread_annotations.h" line 35, impact on 16297 file(s) - 4 : "base\synchronization\lock_impl.h" line 9, impact on 16293 file(s) - 5 : "base\synchronization\lock.h" line 9, impact on 16291 file(s) - 6 : "base\memory\ref_counted.h" line 14, impact on 15769 file(s) - 7 : "base\containers\checked_iterators.h" line 12, impact on 13304 file(s) - 8 : "base\containers\span.h" line 17, impact on 13302 file(s) - 9 : "base\win\scoped_handle.h" line 11, impact on 8218 file(s) - 10 : "base\observer_list_internal.h" line 9, impact on 7688 file(s) - ... 10 of 172 details -... 10 of 11677 files + 1 : "base\strings\string_piece_forward.h" line 12, impact on 50009 file(s) + 2 : "base\strings\string_piece.h" line 35, impact on 49683 file(s) + 3 : "base\hash\hash.h" line 17, impact on 37370 file(s) + 4 : "base\files\file_path.h" line 115, impact on 31747 file(s) + 5 : "base\values.h" line 40, impact on 27647 file(s) + 6 : "url\url_canon.h" line 13, impact on 24380 file(s) + 7 : "url\gurl.h" line 16, impact on 23762 file(s) + 8 : "base\strings\string_util.h" line 24, impact on 23068 file(s) + 9 : "base\strings\string_util_win.h" line 19, impact on 23068 file(s) + 10 : "base\pickle.h" line 19, impact on 18703 file(s) + ... 10 of 2099 details +... 10 of 26036 files +Unincluded headers: +1 : "ash\accelerators\accelerator_ids.h" +2 : "ash\assistant\model\assistant_screen_context_model_observer.h" +3 : "base\file_version_info_mac.h" +4 : "base\ios\crb_protocol_observers.h" +5 : "base\ios\ns_error_util.h" +6 : "base\ios\weak_nsobject.h" +7 : "base\mac\launch_services_util.h" +8 : "base\mac\objc_release_properties.h" +9 : "base\mac\scoped_aedesc.h" +10 : "base\mac\scoped_objc_class_swizzler.h" +... 10 of 2691 files diff --git a/docs/examples/clementine/.cppinclude.json b/docs/examples/clementine/.cppinclude.json index 654d047..95a1b94 100644 --- a/docs/examples/clementine/.cppinclude.json +++ b/docs/examples/clementine/.cppinclude.json @@ -1,6 +1,12 @@ { "project_dir" : "Clementine", + "file_extentions" : [ + "*.cpp", + "*.h", + "*.mm" + ], + "ignore_system_includes" : true, "ignore_dirs" : [ "3rdparty", diff --git a/docs/examples/clementine/output_unix.txt b/docs/examples/clementine/output_unix.txt index e59f065..a93a7a5 100644 --- a/docs/examples/clementine/output_unix.txt +++ b/docs/examples/clementine/output_unix.txt @@ -113,3 +113,7 @@ Included by: 7 : "src/widgets/osd_win.cpp" line 18 8 : "src/widgets/osd_x11.cpp" line 18 ... 10 of 376 files +Unincluded headers: +1 : "src/internet/lastfm/lastfmurlhandler.h" +2 : "src/mac/SBSystemPreferences.h" +3 : "tests/mock_sqldriver.h" diff --git a/docs/examples/clementine/output_win.txt b/docs/examples/clementine/output_win.txt index 5c00a5e..7b4b3cb 100644 --- a/docs/examples/clementine/output_win.txt +++ b/docs/examples/clementine/output_win.txt @@ -113,3 +113,7 @@ Included by: 7 : "src\widgets\osd_win.cpp" line 18 8 : "src\widgets\osd_x11.cpp" line 18 ... 10 of 376 files +Unincluded headers: +1 : "src\internet\lastfm\lastfmurlhandler.h" +2 : "src\mac\SBSystemPreferences.h" +3 : "tests\mock_sqldriver.h" diff --git a/docs/examples/cmake/.cppinclude.json b/docs/examples/cmake/.cppinclude.json new file mode 100644 index 0000000..b01dc6c --- /dev/null +++ b/docs/examples/cmake/.cppinclude.json @@ -0,0 +1,32 @@ +{ + + "ignore_system_includes" : true, + "compile_commands" : "build/compile_commands.json", + "ignore_files" : [ + "^android_lf.h", + "^blake2-kat.h", + "^aich.h", + "^cipher.mih", + "^config-.*.h", + "^config.h", + "^dbghelp.h", + "^ed2k.h", + "^edonr.h", + "^gost12.h", + "^gost94.h", + "^has160.h", + "^io.h", + "^md4.h", + "^ripemd-160.h", + "^snefru.h", + "^tiger.h", + "^tth.h", + "^whirlpool.h", + "zstd_legacy.h", + "os390.c" + ], + + "include_dirs" : [ + "CMake/Utilities/cmzlib/" + ] +} diff --git a/docs/examples/cmake/output_unix.txt b/docs/examples/cmake/output_unix.txt new file mode 100644 index 0000000..8576d36 --- /dev/null +++ b/docs/examples/cmake/output_unix.txt @@ -0,0 +1,112 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "build/Source/cmsys/Configure.hxx" impact on 832 file(s) +Included by: + 1 : "build/Source/cmConfigure.h" line 5, impact on 831 file(s) +2 : "build/Source/cmConfigure.h" impact on 831 file(s) +Included by: + 1 : "CMake/Source/cmProcessOutput.h" line 5, impact on 447 file(s) + 2 : "CMake/Source/cmCryptoHash.h" line 5, impact on 436 file(s) + 3 : "CMake/Source/cmSystemTools.h" line 5, impact on 432 file(s) + 4 : "CMake/Source/cmLinkedTree.h" line 5, impact on 370 file(s) + 5 : "CMake/Source/cmStateTypes.h" line 6, impact on 367 file(s) + 6 : "CMake/Source/cmPolicies.h" line 5, impact on 332 file(s) + 7 : "CMake/Source/cmStateSnapshot.h" line 6, impact on 329 file(s) + 8 : "CMake/Source/cmListFileCache.h" line 5, impact on 326 file(s) + 9 : "CMake/Source/cmRange.h" line 5, impact on 321 file(s) + 10 : "CMake/Source/cmStringAlgorithms.h" line 5, impact on 317 file(s) + ... 10 of 393 details +3 : "CMake/Source/cmProcessOutput.h" impact on 447 file(s) +Included by: + 1 : "CMake/Source/cmSystemTools.h" line 19, impact on 432 file(s) + 2 : "CMake/Source/cmCTest.h" line 18, impact on 65 file(s) + 3 : "CMake/Source/cmProcessTools.h" line 11, impact on 19 file(s) + 4 : "CMake/Source/CTest/cmCTestVC.h" line 10, impact on 17 file(s) + 5 : "CMake/Source/CTest/cmProcess.h" line 18, impact on 4 file(s) + 6 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 19, impact on 3 file(s) + 7 : "CMake/Source/CTest/cmCTestBuildHandler.cxx" line 22 + 8 : "CMake/Source/CTest/cmCTestGIT.cxx" line 17 + 9 : "CMake/Source/CTest/cmCTestLaunch.cxx" line 15 + 10 : "CMake/Source/cmCTest.cxx" line 56 + ... 10 of 18 details +4 : "CMake/Source/cmDuration.h" impact on 437 file(s) +Included by: + 1 : "CMake/Source/cmSystemTools.h" line 18, impact on 432 file(s) + 2 : "CMake/Source/cmGlobalGenerator.h" line 22, impact on 115 file(s) + 3 : "CMake/Source/cmCTest.h" line 17, impact on 65 file(s) + 4 : "CMake/Source/CTest/cmCTestTestHandler.h" line 23, impact on 17 file(s) + 5 : "CMake/Source/CTest/cmCTestScriptHandler.h" line 13, impact on 7 file(s) + 6 : "CMake/Source/CTest/cmProcess.h" line 17, impact on 4 file(s) + 7 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 18, impact on 3 file(s) + 8 : "CMake/Source/CTest/cmCTestRunTest.h" line 18, impact on 3 file(s) + 9 : "CMake/Source/CTest/cmCTestBuildAndTestHandler.h" line 14, impact on 2 file(s) + 10 : "CMake/Source/CPack/IFW/cmCPackIFWGenerator.cxx" line 15 + ... 10 of 30 details +5 : "CMake/Source/cmCryptoHash.h" impact on 436 file(s) +Included by: + 1 : "CMake/Source/cmSystemTools.h" line 17, impact on 432 file(s) + 2 : "CMake/Source/cmcmd.h" line 11, impact on 2 file(s) + 3 : "CMake/Source/CPack/cmCPackDebGenerator.cxx" line 19 + 4 : "CMake/Source/CPack/cmCPackGenerator.cxx" line 16 + 5 : "CMake/Source/CTest/cmCTestLaunchReporter.cxx" line 9 + 6 : "CMake/Source/CTest/cmCTestSubmitHandler.cxx" line 20 + 7 : "CMake/Source/cmCryptoHash.cxx" line 3 + 8 : "CMake/Source/cmFileAPI.cxx" line 17 + 9 : "CMake/Source/cmFileAPICodemodel.cxx" line 22 + 10 : "CMake/Source/cmFileCommand.cxx" line 32 + ... 10 of 19 details +6 : "build/Source/cmsys/SystemTools.hxx" impact on 435 file(s) +Included by: + 1 : "CMake/Source/cmSystemTools.h" line 15, impact on 432 file(s) + 2 : "CMake/Source/cmUtils.hxx" line 5, impact on 2 file(s) + 3 : "CMake/Source/cmFileMonitor.cxx" line 12 +7 : "build/Source/cmsys/Process.h" impact on 434 file(s) +Included by: + 1 : "CMake/Source/cmSystemTools.h" line 14, impact on 432 file(s) + 2 : "CMake/Source/CTest/cmCTestBuildAndTestHandler.cxx" line 10 + 3 : "CMake/Source/CTest/cmCTestBuildHandler.cxx" line 14 + 4 : "CMake/Source/CTest/cmCTestCoverageHandler.cxx" line 19 + 5 : "CMake/Source/CTest/cmCTestGIT.cxx" line 13 + 6 : "CMake/Source/CTest/cmCTestLaunch.cxx" line 9 + 7 : "CMake/Source/CTest/cmCTestLaunchReporter.cxx" line 6 + 8 : "CMake/Source/CTest/cmCTestScriptHandler.cxx" line 16 + 9 : "CMake/Source/CTest/cmCTestVC.cxx" line 10 + 10 : "CMake/Source/CTest/cmProcess.cxx" line 12 + ... 10 of 15 details +8 : "CMake/Source/cmSystemTools.h" impact on 432 file(s) +Included by: + 1 : "CMake/Source/cmListFileCache.h" line 17, impact on 326 file(s) + 2 : "CMake/Source/cmGlobalGenerator.h" line 26, impact on 115 file(s) + 3 : "CMake/Source/cmLinkItem.h" line 15, impact on 70 file(s) + 4 : "CMake/Source/CTest/cmCTestGenericHandler.h" line 14, impact on 53 file(s) + 5 : "CMake/Source/CPack/cmCPackGenerator.h" line 15, impact on 33 file(s) + 6 : "CMake/Source/cmTargetPropertyComputer.h" line 13, impact on 3 file(s) + 7 : "CMake/Source/cmFileLockUnix.cxx" line 10, impact on 1 file(s) + 8 : "CMake/Source/cmFileLockWin32.cxx" line 6, impact on 1 file(s) + 9 : "CMake/Source/CPack/IFW/cmCPackIFWCommon.cxx" line 14 + 10 : "CMake/Source/CPack/IFW/cmCPackIFWGenerator.cxx" line 18 + ... 10 of 250 details +9 : "CMake/Source/cmLinkedTree.h" impact on 370 file(s) +Included by: + 1 : "CMake/Source/cmStateTypes.h" line 8, impact on 367 file(s) + 2 : "CMake/Source/cmStateSnapshot.h" line 13, impact on 329 file(s) + 3 : "CMake/Source/cmDefinitions.h" line 14, impact on 123 file(s) + 4 : "CMake/Source/cmStatePrivate.h" line 12, impact on 121 file(s) + 5 : "CMake/Source/cmState.h" line 15, impact on 105 file(s) + 6 : "CMake/Source/cmStateDirectory.h" line 12, impact on 34 file(s) +10 : "CMake/Source/cmStateTypes.h" impact on 367 file(s) +Included by: + 1 : "CMake/Source/cmStateSnapshot.h" line 15, impact on 329 file(s) + 2 : "CMake/Source/cmTarget.h" line 18, impact on 235 file(s) + 3 : "CMake/Source/cmMakefile.h" line 32, impact on 201 file(s) + 4 : "CMake/Source/cmStatePrivate.h" line 17, impact on 121 file(s) + 5 : "CMake/Source/cmState.h" line 22, impact on 105 file(s) + 6 : "CMake/Source/cmake.h" line 27, impact on 75 file(s) + 7 : "CMake/Source/cmGeneratorTarget.h" line 21, impact on 66 file(s) + 8 : "CMake/Source/cmBinUtilsLinker.h" line 8, impact on 18 file(s) + 9 : "CMake/Source/CursesDialog/cmCursesWidget.h" line 10, impact on 17 file(s) + 10 : "CMake/Source/cmExportFileGenerator.h" line 14, impact on 16 file(s) + ... 10 of 104 details +... 10 of 892 files diff --git a/docs/examples/cmake/run.sh b/docs/examples/cmake/run.sh new file mode 100755 index 0000000..99cfcaa --- /dev/null +++ b/docs/examples/cmake/run.sh @@ -0,0 +1,8 @@ +source ../tools/examples_tools.sh + +GIT_URL="https://github.com/Kitware/CMake.git" +TAG_NAME="v3.19.2" +PROJECT_FOLDER="CMake" + +run_analyze_git_repo_cmake $GIT_URL $TAG_NAME $PROJECT_FOLDER + diff --git a/docs/examples/cppinclude/.cppinclude.json b/docs/examples/cppinclude/.cppinclude.json new file mode 100644 index 0000000..cb3e3e3 --- /dev/null +++ b/docs/examples/cppinclude/.cppinclude.json @@ -0,0 +1,7 @@ +{ + "project_dir" : "../../../src", + "file_extentions" : ["*.cpp", "*.hpp"], + "include_dirs" : ["."], + "ignore_dirs" : ["./3rd-part"], + "ignore_system_includes" : true +} diff --git a/docs/examples/cppinclude/output_unix.txt b/docs/examples/cppinclude/output_unix.txt new file mode 100644 index 0000000..041d078 --- /dev/null +++ b/docs/examples/cppinclude/output_unix.txt @@ -0,0 +1,113 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "exception/api/exc_exception.hpp" impact on 86 file(s) +Included by: + 1 : "exception/ih/exc_exception_impl.hpp" line 3, impact on 79 file(s) + 2 : "application/exceptions/app_exceptions.hpp" line 3, impact on 12 file(s) + 3 : "fs/api/fs_exceptions.hpp" line 3, impact on 9 file(s) + 4 : "project/api/prj_exceptions.hpp" line 3, impact on 4 file(s) + 5 : "reporter/exceptions/rp_exceptions.hpp" line 3, impact on 4 file(s) +2 : "exception/ih/exc_exception_impl.hpp" impact on 79 file(s) +Included by: + 1 : "exception/ih/exc_internal_error.hpp" line 3, impact on 51 file(s) + 2 : "exception/ih/exc_exception_with_message_impl.hpp" line 3, impact on 10 file(s) + 3 : "fs/impl/exceptions/fs_base_exception_impl.hpp" line 5, impact on 7 file(s) + 4 : "application/exceptions/app_base_exception_impl.hpp" line 3, impact on 3 file(s) + 5 : "project/impl/exceptions/prj_base_exception_impl.hpp" line 5, impact on 3 file(s) + 6 : "reporter/exceptions/rp_base_exception_impl.hpp" line 3, impact on 3 file(s) +3 : "exception/ih/exc_internal_error.hpp" impact on 51 file(s) +Included by: + 1 : "application/exceptions/app_cant_create_report_impl.cpp" line 8 + 2 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 18 + 3 : "application/test/fixtures/app_test_configuration_file_fixture.cpp" line 5 + 4 : "application/test/fixtures/app_test_parser_fixture.cpp" line 5 + 5 : "application/test/fixtures/app_test_parser_wrapper_fixture.cpp" line 9 + 6 : "application/test/fixtures/app_test_project_builder_fixture.cpp" line 19 + 7 : "application/test/fixtures/app_test_report_settings_loader_fixture.cpp" line 11 + 8 : "application/tools/app_cmake_project_builder.cpp" line 14 + 9 : "application/tools/app_configuration_file.cpp" line 5 + 10 : "application/tools/app_configuration_file_loader.cpp" line 9 + ... 10 of 51 details +4 : "reporter/api/enums/rp_reporter_kind.hpp" impact on 19 file(s) +Included by: + 1 : "application/exceptions/app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) + 2 : "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) + 3 : "application/resources/app_resources_arguments.cpp" line 10 + 4 : "application/test/fixtures/app_test_configuration_file_fixture.cpp" line 10 + 5 : "application/test/fixtures/app_test_parser_wrapper_fixture.cpp" line 6 + 6 : "application/test/suits/app_test_parser_arguments_wrapper_suits.cpp" line 6 + 7 : "application/tools/app_parser_arg_wrapper.cpp" line 5 + 8 : "reporter/exceptions/rp_incorrect_report_impl.cpp" line 10 + 9 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 3 + 10 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 3 + ... 10 of 15 details +5 : "model_includes/api/enums/mi_file_type.hpp" impact on 18 file(s) +Included by: + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) + 2 : "model_includes/impl/mi_file_impl.hpp" line 4, impact on 2 file(s) + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 5 + 4 : "model_includes/impl/mi_resolver.cpp" line 5 + 5 : "model_includes/test/fixtures/mi_test_model_includes_fixture.cpp" line 6 + 6 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp" line 7 + 7 : "model_includes/test/suits/mi_test_resolver_file_type_suits.cpp" line 3 + 8 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 13 + 9 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 11 + 10 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 14 + ... 10 of 11 details +6 : "model_includes/api/enums/mi_include_status.hpp" impact on 17 file(s) +Included by: + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 7 + 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 6 + 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 8 + 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 8 + 7 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 9 + 8 : "reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp" line 15 +7 : "model_includes/api/enums/mi_include_type.hpp" impact on 17 file(s) +Included by: + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) + 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 6 + 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 7 + 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 9 + 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 9 + 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 4 + 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 10 +8 : "test_tools/boost_predicate_wrapper.hpp" impact on 17 file(s) +Included by: + 1 : "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) + 3 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 3, impact on 5 file(s) + 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) + 5 : "project/test/fixture/prj_test_ficture.hpp" line 3, impact on 2 file(s) + 6 : "test_tools/boost_predicate_wrapper.cpp" line 1 +9 : "fs/api/fs_file_system.hpp" impact on 16 file(s) +Included by: + 1 : "fs/impl/fs_factory_impl.hpp" line 4, impact on 3 file(s) + 2 : "fs/impl/memory/fs_memory_file_system.hpp" line 3, impact on 2 file(s) + 3 : "fs/impl/physical/fs_physical_file_system.hpp" line 3, impact on 2 file(s) + 4 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 13 + 5 : "application/test/fixtures/app_test_project_builder_fixture.cpp" line 15 + 6 : "application/tools/app_cmake_project_builder.cpp" line 19 + 7 : "application/tools/app_configuration_file_loader.cpp" line 11 + 8 : "application/tools/app_project_builder.cpp" line 9 + 9 : "model_includes/impl/mi_analyzer_impl.cpp" line 16 + 10 : "model_includes/impl/mi_resolver.cpp" line 7 + ... 10 of 12 details +10 : "model_includes/api/mi_include.hpp" impact on 16 file(s) +Included by: + 1 : "model_includes/impl/mi_model_impl.hpp" line 5, impact on 3 file(s) + 2 : "model_includes/impl/mi_include_impl.hpp" line 3, impact on 2 file(s) + 3 : "model_includes/impl/mi_file_impl.cpp" line 3 + 4 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp" line 6 + 5 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 3 + 6 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 11 + 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 3 + 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 8 + 9 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 12 + 10 : "reporter/impl/tools/rp_includes_by_source_sorter.cpp" line 5 + ... 10 of 12 details +... 10 of 163 files diff --git a/docs/examples/cppinclude/output_win.txt b/docs/examples/cppinclude/output_win.txt new file mode 100644 index 0000000..86acf9c --- /dev/null +++ b/docs/examples/cppinclude/output_win.txt @@ -0,0 +1,113 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "exception\api\exc_exception.hpp" impact on 86 file(s) +Included by: + 1 : "exception\ih\exc_exception_impl.hpp" line 3, impact on 79 file(s) + 2 : "application\exceptions\app_exceptions.hpp" line 3, impact on 12 file(s) + 3 : "fs\api\fs_exceptions.hpp" line 3, impact on 9 file(s) + 4 : "project\api\prj_exceptions.hpp" line 3, impact on 4 file(s) + 5 : "reporter\exceptions\rp_exceptions.hpp" line 3, impact on 4 file(s) +2 : "exception\ih\exc_exception_impl.hpp" impact on 79 file(s) +Included by: + 1 : "exception\ih\exc_internal_error.hpp" line 3, impact on 51 file(s) + 2 : "exception\ih\exc_exception_with_message_impl.hpp" line 3, impact on 10 file(s) + 3 : "fs\impl\exceptions\fs_base_exception_impl.hpp" line 5, impact on 7 file(s) + 4 : "application\exceptions\app_base_exception_impl.hpp" line 3, impact on 3 file(s) + 5 : "project\impl\exceptions\prj_base_exception_impl.hpp" line 5, impact on 3 file(s) + 6 : "reporter\exceptions\rp_base_exception_impl.hpp" line 3, impact on 3 file(s) +3 : "exception\ih\exc_internal_error.hpp" impact on 51 file(s) +Included by: + 1 : "application\exceptions\app_cant_create_report_impl.cpp" line 8 + 2 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 18 + 3 : "application\test\fixtures\app_test_configuration_file_fixture.cpp" line 5 + 4 : "application\test\fixtures\app_test_parser_fixture.cpp" line 5 + 5 : "application\test\fixtures\app_test_parser_wrapper_fixture.cpp" line 9 + 6 : "application\test\fixtures\app_test_project_builder_fixture.cpp" line 19 + 7 : "application\test\fixtures\app_test_report_settings_loader_fixture.cpp" line 11 + 8 : "application\tools\app_cmake_project_builder.cpp" line 14 + 9 : "application\tools\app_configuration_file.cpp" line 5 + 10 : "application\tools\app_configuration_file_loader.cpp" line 9 + ... 10 of 51 details +4 : "reporter\api\enums\rp_reporter_kind.hpp" impact on 19 file(s) +Included by: + 1 : "application\exceptions\app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) + 2 : "application\test\fixtures\app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) + 3 : "application\resources\app_resources_arguments.cpp" line 10 + 4 : "application\test\fixtures\app_test_configuration_file_fixture.cpp" line 10 + 5 : "application\test\fixtures\app_test_parser_wrapper_fixture.cpp" line 6 + 6 : "application\test\suits\app_test_parser_arguments_wrapper_suits.cpp" line 6 + 7 : "application\tools\app_parser_arg_wrapper.cpp" line 5 + 8 : "reporter\exceptions\rp_incorrect_report_impl.cpp" line 10 + 9 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 3 + 10 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 3 + ... 10 of 15 details +5 : "model_includes\api\enums\mi_file_type.hpp" impact on 18 file(s) +Included by: + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) + 2 : "model_includes\impl\mi_file_impl.hpp" line 4, impact on 2 file(s) + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 5 + 4 : "model_includes\impl\mi_resolver.cpp" line 5 + 5 : "model_includes\test\fixtures\mi_test_model_includes_fixture.cpp" line 6 + 6 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.cpp" line 7 + 7 : "model_includes\test\suits\mi_test_resolver_file_type_suits.cpp" line 3 + 8 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 13 + 9 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 11 + 10 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 14 + ... 10 of 11 details +6 : "model_includes\api\enums\mi_include_status.hpp" impact on 17 file(s) +Included by: + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 7 + 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 6 + 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 8 + 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 8 + 7 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 9 + 8 : "reporter\impl\unresolved_reporter\rp_unresolved_reporter.cpp" line 15 +7 : "model_includes\api\enums\mi_include_type.hpp" impact on 17 file(s) +Included by: + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) + 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 6 + 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 7 + 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 9 + 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 9 + 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 4 + 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 10 +8 : "test_tools\boost_predicate_wrapper.hpp" impact on 17 file(s) +Included by: + 1 : "model_includes\test\fixtures\mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) + 3 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 3, impact on 5 file(s) + 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) + 5 : "project\test\fixture\prj_test_ficture.hpp" line 3, impact on 2 file(s) + 6 : "test_tools\boost_predicate_wrapper.cpp" line 1 +9 : "fs\api\fs_file_system.hpp" impact on 16 file(s) +Included by: + 1 : "fs\impl\fs_factory_impl.hpp" line 4, impact on 3 file(s) + 2 : "fs\impl\memory\fs_memory_file_system.hpp" line 3, impact on 2 file(s) + 3 : "fs\impl\physical\fs_physical_file_system.hpp" line 3, impact on 2 file(s) + 4 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 13 + 5 : "application\test\fixtures\app_test_project_builder_fixture.cpp" line 15 + 6 : "application\tools\app_cmake_project_builder.cpp" line 19 + 7 : "application\tools\app_configuration_file_loader.cpp" line 11 + 8 : "application\tools\app_project_builder.cpp" line 9 + 9 : "model_includes\impl\mi_analyzer_impl.cpp" line 16 + 10 : "model_includes\impl\mi_resolver.cpp" line 7 + ... 10 of 12 details +10 : "model_includes\api\mi_include.hpp" impact on 16 file(s) +Included by: + 1 : "model_includes\impl\mi_model_impl.hpp" line 5, impact on 3 file(s) + 2 : "model_includes\impl\mi_include_impl.hpp" line 3, impact on 2 file(s) + 3 : "model_includes\impl\mi_file_impl.cpp" line 3 + 4 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.cpp" line 6 + 5 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 3 + 6 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 11 + 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 3 + 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 8 + 9 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 12 + 10 : "reporter\impl\tools\rp_includes_by_source_sorter.cpp" line 5 + ... 10 of 12 details +... 10 of 163 files diff --git a/docs/examples/cppinclude/run.bat b/docs/examples/cppinclude/run.bat new file mode 100644 index 0000000..dcff19d --- /dev/null +++ b/docs/examples/cppinclude/run.bat @@ -0,0 +1 @@ +call ..\tools\run_analyze.bat \ No newline at end of file diff --git a/docs/examples/cppinclude/run.sh b/docs/examples/cppinclude/run.sh new file mode 100755 index 0000000..2285903 --- /dev/null +++ b/docs/examples/cppinclude/run.sh @@ -0,0 +1,3 @@ +source ../tools/examples_tools.sh + +run_analyze diff --git a/docs/examples/gcc/.cppinclude.json b/docs/examples/gcc/.cppinclude.json index 2c8177f..0f59f7e 100644 --- a/docs/examples/gcc/.cppinclude.json +++ b/docs/examples/gcc/.cppinclude.json @@ -1,20 +1,47 @@ { "project_dir" : "gcc", + "file_extensions" : [ + "*.cpp", + "*.hpp", + "*.c", + "*.C", + "*.h", + "*.cxx", + "*.cc", + "*.hxx", + "*.S" + ], "include_dirs" : [ - "include", - "gcc", + "include/", + "gcc/", + "gcc/c/", - "gcc/config/arm/", - "gcc/libstdc++-v3/include/c_compatibility/", - "libstdc++-v3/include/c_compatibility/", - "gcc/fixincludes/tests/base/", - "fixincludes/tests/base/sys/", - "gcc/jit/", "gcc/config/", + "gcc/config/arm/", + "gcc/config/aarch64/", + "gcc/config/s390/", "gcc/config/i386/", "gcc/config/rs6000/", "gcc/config/ia64/", "gcc/config/avr/", + "gcc/config/vxworks/", + "gcc/config/epiphany/", + "gcc/config/frv/", + + "gcc/libstdc++-v3/include/c_compatibility/", + + "libstdc++-v3/include/c_compatibility/", + "libstdc++-v3/include/", + "libstdc++-v3/testsuite/util/", + "libstdc++-v3/testsuite/", + "libstdc++-v3/libsupc++/", + "libstdc++-v3/include/std/", + "libstdc++-v3/include/backward/", + + "fixincludes/tests/base/sys/", + "fixincludes/tests/base/", + "gcc/fixincludes/tests/base/", + "gcc/jit/", "gcc/ginclude/", "gcc/ada/", "gcc/objcp/", @@ -25,12 +52,20 @@ "gcc/config/mips/", "gcc/testsuite/objc-obj-c++-shared/GNUStep/", "gcc/testsuite/objc-obj-c++-shared/GNUStep/GNUstepBase/", + "gcc/testsuite/gcc.dg/cpp/usr/include/", + "gcc/d/dmd/root/", + "gcc/brig/", + + "go/gofrontend/", + "gcc/go/gofrontend/", - "libgfortran/", - "libgfortran/io/", - "libquadmath/", "libsanitizer/", "libsanitizer/include/", + "libsanitizer/include/system", + + "libgfortran/io/", + "libquadmath/", + "libgfortran/", "libgomp/", "libcpp/include/", "libgo/runtime/", @@ -48,12 +83,20 @@ "liboffloadmic/runtime/", "libitm/config/posix/", "libitm/config/generic/", + "liboffloadmic/include/coi/", + "libvtv/", "fixincludes/tests/base/", + "fixincludes/tests/base/rtldef/", "libgomp/config/posix/", - "zlib/" + "zlib/", + "zlib/contrib/minizip/", + "fixincludes/tests/base/netinet/", + + "libffi/src/" + ], - "ignore_system_includes" : true, + "ignore_system_includes" : false, "ignore_files" : [ "gcc/testsuite/gcc.dg/cpp/include6.c", @@ -162,11 +205,216 @@ "gcc/gen.*.c", "gcc/testsuite/objc.dg/gnu-encoding/struct-layout-encoding-1_generate.c", + "libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp", + "libstdc\\+\\+-v3/include/pstl/parallel_backend_tbb.h", + "gcc/testsuite/gcc.dg/cpp/include2.c", "BlocksRuntime/Block.h", "gcc/testsuite/gcc.dg/cpp/pr.*", - "gcc/testsuite/gcc.dg/cpp/include2a.c" + "gcc/testsuite/gcc.dg/cpp/include2a.c", + + "sys/.*.h", + "bits/.*.h", + + "mach/mach.h", + "mach/mach_init.h", + "mach/vm_statistics.h", + "mach-o/getsect.h", + "mach-o/loader.h", + "arpa/inet.h", + "arch/.*.h", + "net/route.h", + "net/ppp_defs.h", + "net/ethernet.h", + "zircon/sanitizer.h", + "asm/.*.h", + "avr/pgmspace.h", + "isl/.*.h", + "linux/fs.h", + "linux/posix_types.h", + "locale/weightwc.h", + "vms/.*.h", + "Carbon/.*.h", + "Foundation/.*.h", + "Kernel/.*.h", + "ObjectiveC2/.*.h", + "altq/.*.h", + "android/api-level.h", + "ev/wscons/.*.h", + "crypto/cryptodev.h", + "experimental/coroutine", + "ext/hash_map", + "ext/hash_set", + "linux/ioctl.h", + "libio/iolibio.h", + "malloc/malloc.h", + "native/task.h", + "netax25/ax25.h", + "netinet/ether.h", + "netipx/ipx.h", + "netpacket/packet.h", + "netrom/netrom.h", + "one/one-includeSubs.h", + "os/lock.h", + "private/moduleLibP.h", + "rtems/rtems/tasks.h", + "rtems/system.h", + "scsi/scsi.h", + "tbb/blocked_range.h", + "xpc/xpc.h", + "zircon/errors.h", + "zircon/threads.h", + + "dev/apm/.*.h", + "dev/bluetooth/.*.h", + "dev/dm/.*.h", + "linux/.*.h", + "locale/.*.h", + "mach/.*.h", + "machine/.*.h", + "mint/.*.h", + "netinet/.*.h", + "tbb/.*.h", + + "dlfcn.h", + "sched.h", + "link.h", + "utime.h", + "dirent.h", + "paired.h", + "process.h", + "termios.h", + "langinfo.h", + "mpfr.h", + "netdb.h", + "iconv.h", + "pwd.h", + "semaphore.h", + "c6x_intrinsics.h", + "cuda_runtime_api.h", + "glob.h", + "ifaddrs.h", + "ip_mroute.h", + "poll.h", + "crt_externs.h", + "cublas_v2.h", + "linux/version.h", + "mpc.h", + "utmpx.h", + "TargetConditionals.h", + "_mingw.h", + "direct.h", + "endian.h", + "envLib.h", + "fstab.h", + "gnu-versions.h", + "constraint.h", + "libgen.h", + "OSAtomic.h", + "link_elf.h", + "osreldate.h", + "spe.h", + "syscall.h", + "syslog.h", + "term.h", + "thread.h", + "chfdef.h", + "winsock2.h", + "xlocale.h", + "syscalls.h", + "dejagnu.h", + "fts.h", + "ftw.h", + "mntent.h", + "nds32_intrinsic.h", + "os2.h", + "sigLib.h", + "soundcard.h", + "stdio_ext.h", + "stringlist.h", + "sysLib.h", + "taskHookLib.h", + "ttyent.h", + "unixio.h", + "util.h", + "vis.h", + "vxLib.h", + "Block.h", + "Rtapi.h", + "_types.h", + "a.out.h", + "accctrl.h", + "aclapi.h", + "ar.h", + "argz.h", + "asl.h", + "ast.h", + "conio.h", + "dir.h", + "errnoLib.h", + "error.h", + "excpt.h", + "fpu_control.h", + "fstream.h", + "hostLib.h", + "intLib.h", + "ioctl.h", + "iv.h", + "kstat.h", + "ldfcn.h", + "lmcons.h", + "memcheck.h", + "mpi.h", + "mqueue.h", + "myo.h", + "myoimpl.h", + "myotypes.h", + "nonexist0.h", + "ossddef.h", + "paths.h", + "pcre.h", + "procfs.h", + "psapi.h", + "memory.h", + "printf.h", + "semLib.h", + "sgidefs.h", + "sgs.h", + "siginfo.h", + "stdfix-avrlibc.h", + "stdfix-gcc.h", + "stk.h", + "strstream.h", + "syidef.h", + "synch.h", + "taskLibCommon.h", + "tickLib.h", + "tlhelp32.h", + "traceloggingprovider.h", + "uwx.h", + "vThreadsData.h", + "valgrind.h", + "versionhelpers.h", + "vfork.h", + "vmLib.h", + "vxAtomicLib.h", + "vxCpuLib.h", + "w32api.h", + "winbase.h", + "wincrypt.h", + "windef.h", + "winsock.h", + "winternl.h", + "xxxxxxxxxxxx.h", + "yvals.h", + "zstd.h", + "^pstl/*", + "execinfo.h", + + "paste12.c", + + "\\\\usr\\\\include\\\\malloc.h" ] } diff --git a/docs/examples/gcc/output_unix.txt b/docs/examples/gcc/output_unix.txt index 5002faf..00ff9eb 100644 --- a/docs/examples/gcc/output_unix.txt +++ b/docs/examples/gcc/output_unix.txt @@ -2,95 +2,126 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "gcc/config/arm/arm_mve_types.h" impact on 2496 file(s) +1 : "libstdc++-v3/include/c_compatibility/stdio.h" impact on 10322 file(s) Included by: - 1 : "gcc/config/arm/arm_mve.h" line 35, impact on 2484 file(s) - 2 : "gcc/config/arm/arm_cde.h" line 140, impact on 10 file(s) -2 : "gcc/config/arm/arm_mve.h" impact on 2484 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 49, impact on 4716 file(s) + 2 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 1, impact on 1799 file(s) + 3 : "include/libiberty.h" line 49, impact on 1152 file(s) + 4 : "gcc/wide-int-print.h" line 23, impact on 1118 file(s) + 5 : "gcc/system.h" line 46, impact on 1060 file(s) + 6 : "libgfortran/libgfortran.h" line 42, impact on 591 file(s) + 7 : "libffi/testsuite/libffi.call/ffitest.h" line 2, impact on 145 file(s) + 8 : "gcc/jit/libgccjit.h" line 23, impact on 139 file(s) + 9 : "gcc/testsuite/gcc.dg/compat/compat-common.h" line 8, impact on 117 file(s) + 10 : "gcc/testsuite/jit.dg/harness.h" line 16, impact on 117 file(s) + ... 10 of 1198 details +2 : "fixincludes/tests/base/unistd.h" impact on 6319 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/asrl.c" line 5 - 2 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/lsll.c" line 5 - 3 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu1.c" line 6 - 4 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fp_fpu2.c" line 6 - 5 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fpu1.c" line 6 - 6 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_fpu2.c" line 6 - 7 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_immediates_1_n.c" line 5 - 8 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_load_from_array.c" line 5 - 9 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_move_gpr_to_gpr.c" line 5 - 10 : "gcc/testsuite/gcc.target/arm/mve/intrinsics/mve_scalar_shifts1.c" line 6 - ... 10 of 2484 details -3 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/test_sve_acle.h" impact on 2405 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 73, impact on 4716 file(s) + 2 : "gcc/system.h" line 294, impact on 1060 file(s) + 3 : "libstdc++-v3/testsuite/util/testsuite_fs.h" line 38, impact on 140 file(s) + 4 : "gcc/testsuite/jit.dg/harness.h" line 17, impact on 117 file(s) + 5 : "gcc/tsystem.h" line 102, impact on 75 file(s) + 6 : "libstdc++-v3/include/ext/stdio_sync_filebuf.h" line 35, impact on 18 file(s) + 7 : "libcpp/system.h" line 222, impact on 14 file(s) + 8 : "include/simple-object.h" line 27, impact on 11 file(s) + 9 : "liboffloadmic/runtime/coi/coi_server.h" line 44, impact on 10 file(s) + 10 : "gcc/testsuite/gcc.dg/guality/guality.h" line 25, impact on 8 file(s) + ... 10 of 294 details +3 : "gcc/ginclude/stdint-gcc.h" impact on 5209 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/aarch64/sve2/acle/asm/test_sve_acle.h" line 1, impact on 842 file(s) - 2 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_f16.c" line 3 - 3 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_f32.c" line 3 - 4 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_f64.c" line 3 - 5 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_s16.c" line 3 - 6 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_s32.c" line 3 - 7 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_s64.c" line 3 - 8 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_s8.c" line 3 - 9 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_u16.c" line 3 - 10 : "gcc/testsuite/gcc.target/aarch64/sve/acle/asm/abd_u32.c" line 3 - ... 10 of 1563 details -4 : "gcc/testsuite/gcc.target/i386/m128-check.h" impact on 1798 file(s) + 1 : "gcc/config/vxworks/stdint.h" line 26, impact on 5208 file(s) +4 : "gcc/config/vxworks/stdint.h" impact on 5208 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/i386/m256-check.h" line 2, impact on 1599 file(s) - 2 : "gcc/testsuite/gcc.target/i386/sse2-check.h" line 3, impact on 146 file(s) - 3 : "gcc/testsuite/gcc.target/i386/sse4_1-check.h" line 4, impact on 26 file(s) - 4 : "gcc/testsuite/gcc.target/i386/sse-check.h" line 2, impact on 17 file(s) - 5 : "gcc/testsuite/g++.target/i386/m128-check.h" line 1 - 6 : "gcc/testsuite/gcc.target/i386/sha1msg1-2.c" line 6 - 7 : "gcc/testsuite/gcc.target/i386/sha1msg2-2.c" line 6 - 8 : "gcc/testsuite/gcc.target/i386/sha1nexte-2.c" line 6 - 9 : "gcc/testsuite/gcc.target/i386/sha1rnds4-2.c" line 6 - 10 : "gcc/testsuite/gcc.target/i386/sha256msg1-2.c" line 6 - ... 10 of 12 details -5 : "gcc/testsuite/gcc.target/i386/m256-check.h" impact on 1599 file(s) + 1 : "gcc/config/arm/arm_mve.h" line 31, impact on 2485 file(s) + 2 : "gcc/system.h" line 524, impact on 1060 file(s) + 3 : "libgcc/gstdint.h" line 6, impact on 659 file(s) + 4 : "gcc/config/arm/arm_fp16.h" line 34, impact on 286 file(s) + 5 : "gcc/config/arm/arm_neon.h" line 43, impact on 282 file(s) + 6 : "include/plugin-api.h" line 30, impact on 235 file(s) + 7 : "include/splay-tree.h" line 40, impact on 162 file(s) + 8 : "libffi/testsuite/libffi.call/ffitest.h" line 9, impact on 145 file(s) + 9 : "liboffloadmic/include/coi/common/COITypes_common.h" line 51, impact on 41 file(s) + 10 : "libbacktrace/backtrace.h" line 43, impact on 34 file(s) + ... 10 of 363 details +5 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" impact on 4716 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/i386/m512-check.h" line 2, impact on 1131 file(s) - 2 : "gcc/testsuite/gcc.target/i386/avx2-check.h" line 3, impact on 228 file(s) - 3 : "gcc/testsuite/gcc.target/i386/avx-check.h" line 3, impact on 206 file(s) - 4 : "gcc/testsuite/gcc.target/i386/xop-check.h" line 4, impact on 9 file(s) - 5 : "gcc/testsuite/gcc.target/i386/f16c-check.h" line 4, impact on 6 file(s) - 6 : "gcc/testsuite/g++.target/i386/m256-check.h" line 1 - 7 : "gcc/testsuite/gcc.target/i386/fma-256-fmaddXX.c" line 8 - 8 : "gcc/testsuite/gcc.target/i386/fma-256-fmaddsubXX.c" line 8 - 9 : "gcc/testsuite/gcc.target/i386/fma-256-fmsubXX.c" line 8 - 10 : "gcc/testsuite/gcc.target/i386/fma-256-fmsubaddXX.c" line 8 - ... 10 of 19 details -6 : "include/ansidecl.h" impact on 1317 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_allocator.h" line 32, impact on 332 file(s) + 2 : "libstdc++-v3/testsuite/util/testsuite_iterators.h" line 30, impact on 326 file(s) + 3 : "libstdc++-v3/testsuite/util/testsuite_tr1.h" line 26, impact on 225 file(s) + 4 : "libstdc++-v3/testsuite/util/testsuite_api.h" line 23, impact on 138 file(s) + 5 : "libstdc++-v3/testsuite/util/debug/checks.h" line 27, impact on 111 file(s) + 6 : "libstdc++-v3/testsuite/util/testsuite_rvalref.h" line 25, impact on 71 file(s) + 7 : "libstdc++-v3/testsuite/util/replacement_memory_operators.h" line 23, impact on 32 file(s) + 8 : "libstdc++-v3/testsuite/util/debug/unordered_checks.h" line 19, impact on 16 file(s) + 9 : "libstdc++-v3/testsuite/util/testsuite_random.h" line 29, impact on 12 file(s) + 10 : "libstdc++-v3/testsuite/util/testsuite_new_operators.h" line 26, impact on 3 file(s) + ... 10 of 4083 details +6 : "gcc/config/i386/mmintrin.h" impact on 4383 file(s) Included by: - 1 : "include/hashtab.h" line 39, impact on 1207 file(s) - 2 : "include/libiberty.h" line 42, impact on 1038 file(s) - 3 : "include/splay-tree.h" line 37, impact on 159 file(s) - 4 : "include/partition.h" line 43, impact on 14 file(s) - 5 : "include/md5.h" line 30, impact on 5 file(s) - 6 : "gcc/brig/brigfrontend/brig-util.h" line 30, impact on 4 file(s) - 7 : "gcc/brig/brigfrontend/brig-function.h" line 27, impact on 3 file(s) - 8 : "gcc/brig/brigfrontend/brig-to-generic.h" line 31, impact on 2 file(s) - 9 : "gcc/go/go-system.h" line 136, impact on 2 file(s) - 10 : "include/floatformat.h" line 23, impact on 1 file(s) - ... 10 of 63 details -7 : "include/hashtab.h" impact on 1207 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 31, impact on 4373 file(s) + 2 : "gcc/config/i386/immintrin.h" line 27, impact on 3236 file(s) + 3 : "gcc/config/i386/mm3dnow.h" line 30, impact on 367 file(s) +7 : "gcc/config/rs6000/mm_malloc.h" impact on 4381 file(s) Included by: - 1 : "include/filenames.h" line 29, impact on 1043 file(s) - 2 : "gcc/hash-table.h" line 249, impact on 1018 file(s) - 3 : "gcc/function-tests.c" line 38 - 4 : "libcpp/files.c" line 29 - 5 : "libcpp/line-map.c" line 27 - 6 : "libiberty/hashtab.c" line 63 -8 : "gcc/testsuite/gcc.target/i386/avx512f-os-support.h" impact on 1131 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 34, impact on 4373 file(s) + 2 : "gcc/config/rs6000/xmmintrin.h" line 82, impact on 5 file(s) + 3 : "gcc/testsuite/gcc.target/i386/sse-23.c" line 5, impact on 2 file(s) + 4 : "gcc/testsuite/gcc.target/i386/sse-13.c" line 5, impact on 1 file(s) + 5 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 6, impact on 1 file(s) + 6 : "gcc/testsuite/gcc.target/i386/avx-1.c" line 5 + 7 : "gcc/testsuite/gcc.target/i386/avx-2.c" line 5 + 8 : "gcc/testsuite/gcc.target/i386/sse-14.c" line 5 + 9 : "liboffloadmic/runtime/offload_common.cpp" line 32 +8 : "gcc/config/i386/emmintrin.h" impact on 4373 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/i386/avx512-check.h" line 4, impact on 1130 file(s) -9 : "gcc/testsuite/gcc.target/i386/m512-check.h" impact on 1131 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 1316, impact on 4373 file(s) + 2 : "gcc/config/i386/pmmintrin.h" line 31, impact on 3491 file(s) + 3 : "gcc/config/i386/wmmintrin.h" line 31, impact on 3251 file(s) + 4 : "gcc/config/i386/immintrin.h" line 31, impact on 3236 file(s) + 5 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 5, impact on 1799 file(s) + 6 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 9, impact on 7 file(s) + 7 : "gcc/testsuite/g++.dg/asan/asan_test.cc" line 686, impact on 1 file(s) + 8 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 141, impact on 1 file(s) + 9 : "gcc/testsuite/gcc.target/i386/sse2-addpd-1.c" line 15, impact on 1 file(s) + 10 : "gcc/testsuite/gcc.target/i386/sse2-addsd-1.c" line 15, impact on 1 file(s) + ... 10 of 350 details +9 : "gcc/config/i386/xmmintrin.h" impact on 4373 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/i386/avx512-check.h" line 3, impact on 1130 file(s) -10 : "gcc/testsuite/gcc.target/i386/avx512-check.h" impact on 1130 file(s) + 1 : "gcc/config/i386/emmintrin.h" line 31, impact on 4373 file(s) + 2 : "gcc/config/i386/immintrin.h" line 29, impact on 3236 file(s) + 3 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 2, impact on 1799 file(s) + 4 : "gcc/testsuite/gcc.target/x86_64/abi/defines.h" line 5, impact on 19 file(s) + 5 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 6, impact on 7 file(s) + 6 : "gcc/testsuite/gcc.dg/compat/union-m128-1.h" line 1, impact on 2 file(s) + 7 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 127, impact on 1 file(s) + 8 : "gcc/testsuite/gcc.target/i386/sse-addps-1.c" line 15, impact on 1 file(s) + 9 : "gcc/testsuite/gcc.target/i386/sse-addss-1.c" line 15, impact on 1 file(s) + 10 : "gcc/testsuite/gcc.target/i386/sse-andnps-1.c" line 15, impact on 1 file(s) + ... 10 of 169 details +10 : "gcc/config/i386/pmmintrin.h" impact on 3491 file(s) Included by: - 1 : "gcc/testsuite/gcc.target/i386/avx512f-helper.h" line 11, impact on 1095 file(s) - 2 : "gcc/testsuite/gcc.target/i386/avx512bw-check.h" line 3, impact on 22 file(s) - 3 : "gcc/testsuite/gcc.target/i386/avx512dq-check.h" line 3, impact on 7 file(s) - 4 : "gcc/testsuite/gcc.target/i386/avx512f-pr88547-2.c" line 5, impact on 1 file(s) - 5 : "gcc/testsuite/gcc.target/i386/avx512vl-check.h" line 4, impact on 1 file(s) - 6 : "gcc/testsuite/gcc.target/i386/avx512dq-pr85918-2.c" line 13 -... 10 of 3166 files + 1 : "gcc/config/i386/tmmintrin.h" line 31, impact on 3451 file(s) + 2 : "gcc/config/i386/immintrin.h" line 33, impact on 3236 file(s) + 3 : "gcc/config/i386/ammintrin.h" line 31, impact on 364 file(s) + 4 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 157, impact on 1 file(s) + 5 : "gcc/testsuite/gcc.target/i386/sse3-addsubpd.c" line 15, impact on 1 file(s) + 6 : "gcc/testsuite/gcc.target/i386/sse3-addsubps.c" line 15, impact on 1 file(s) + 7 : "gcc/testsuite/gcc.target/i386/sse3-haddpd.c" line 14, impact on 1 file(s) + 8 : "gcc/testsuite/gcc.target/i386/sse3-haddps.c" line 15, impact on 1 file(s) + 9 : "gcc/testsuite/gcc.target/i386/sse3-hsubpd.c" line 14, impact on 1 file(s) + 10 : "gcc/testsuite/gcc.target/i386/sse3-hsubps.c" line 14, impact on 1 file(s) + ... 10 of 26 details +... 10 of 3748 files +Unincluded headers: +1 : "fixincludes/system.h" +2 : "fixincludes/tests/base/AvailabilityInternal.h" +3 : "fixincludes/tests/base/X11/ShellP.h" +4 : "fixincludes/tests/base/X11/Xmu.h" +5 : "fixincludes/tests/base/Xm/BaseClassI.h" +6 : "fixincludes/tests/base/Xm/Traversal.h" +7 : "fixincludes/tests/base/ansi/math.h" +8 : "fixincludes/tests/base/assert.h" +9 : "fixincludes/tests/base/bsd/libc.h" +10 : "fixincludes/tests/base/c_asm.h" +... 10 of 823 files diff --git a/docs/examples/gcc/output_win.txt b/docs/examples/gcc/output_win.txt index e6573d6..a70836a 100644 --- a/docs/examples/gcc/output_win.txt +++ b/docs/examples/gcc/output_win.txt @@ -1,99 +1,127 @@ Start initialization project ... Start analyze sources ... Start report results ... -Unresolved files: -1. "\usr\include\malloc.h" isn't resolved in: - 1. "libffi\src\dlmalloc.c" line: 622 Most impact files: -1 : "gcc\config\arm\arm_mve_types.h" impact on 2496 file(s) +1 : "libstdc++-v3\include\c_compatibility\stdio.h" impact on 10322 file(s) Included by: - 1 : "gcc\config\arm\arm_mve.h" line 35, impact on 2484 file(s) - 2 : "gcc\config\arm\arm_cde.h" line 140, impact on 10 file(s) -2 : "gcc\config\arm\arm_mve.h" impact on 2484 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 49, impact on 4716 file(s) + 2 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 1, impact on 1799 file(s) + 3 : "include\libiberty.h" line 49, impact on 1152 file(s) + 4 : "gcc\wide-int-print.h" line 23, impact on 1118 file(s) + 5 : "gcc\system.h" line 46, impact on 1060 file(s) + 6 : "libgfortran\libgfortran.h" line 42, impact on 591 file(s) + 7 : "libffi\testsuite\libffi.call\ffitest.h" line 2, impact on 145 file(s) + 8 : "gcc\jit\libgccjit.h" line 23, impact on 139 file(s) + 9 : "gcc\testsuite\gcc.dg\compat\compat-common.h" line 8, impact on 117 file(s) + 10 : "gcc\testsuite\jit.dg\harness.h" line 16, impact on 117 file(s) + ... 10 of 1198 details +2 : "fixincludes\tests\base\unistd.h" impact on 6319 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\asrl.c" line 5 - 2 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\lsll.c" line 5 - 3 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_fp_fpu1.c" line 6 - 4 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_fp_fpu2.c" line 6 - 5 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_fpu1.c" line 6 - 6 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_fpu2.c" line 6 - 7 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_immediates_1_n.c" line 5 - 8 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_load_from_array.c" line 5 - 9 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_move_gpr_to_gpr.c" line 5 - 10 : "gcc\testsuite\gcc.target\arm\mve\intrinsics\mve_scalar_shifts1.c" line 6 - ... 10 of 2484 details -3 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\test_sve_acle.h" impact on 2405 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 73, impact on 4716 file(s) + 2 : "gcc\system.h" line 294, impact on 1060 file(s) + 3 : "libstdc++-v3\testsuite\util\testsuite_fs.h" line 38, impact on 140 file(s) + 4 : "gcc\testsuite\jit.dg\harness.h" line 17, impact on 117 file(s) + 5 : "gcc\tsystem.h" line 102, impact on 75 file(s) + 6 : "libstdc++-v3\include\ext\stdio_sync_filebuf.h" line 35, impact on 18 file(s) + 7 : "libcpp\system.h" line 222, impact on 14 file(s) + 8 : "include\simple-object.h" line 27, impact on 11 file(s) + 9 : "liboffloadmic\runtime\coi\coi_server.h" line 44, impact on 10 file(s) + 10 : "gcc\testsuite\gcc.dg\guality\guality.h" line 25, impact on 8 file(s) + ... 10 of 294 details +3 : "gcc\ginclude\stdint-gcc.h" impact on 5209 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\aarch64\sve2\acle\asm\test_sve_acle.h" line 1, impact on 842 file(s) - 2 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_f16.c" line 3 - 3 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_f32.c" line 3 - 4 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_f64.c" line 3 - 5 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_s16.c" line 3 - 6 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_s32.c" line 3 - 7 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_s64.c" line 3 - 8 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_s8.c" line 3 - 9 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_u16.c" line 3 - 10 : "gcc\testsuite\gcc.target\aarch64\sve\acle\asm\abd_u32.c" line 3 - ... 10 of 1563 details -4 : "gcc\testsuite\gcc.target\i386\m128-check.h" impact on 1798 file(s) + 1 : "gcc\config\vxworks\stdint.h" line 26, impact on 5208 file(s) +4 : "gcc\config\vxworks\stdint.h" impact on 5208 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\i386\m256-check.h" line 2, impact on 1599 file(s) - 2 : "gcc\testsuite\gcc.target\i386\sse2-check.h" line 3, impact on 146 file(s) - 3 : "gcc\testsuite\gcc.target\i386\sse4_1-check.h" line 4, impact on 26 file(s) - 4 : "gcc\testsuite\gcc.target\i386\sse-check.h" line 2, impact on 17 file(s) - 5 : "gcc\testsuite\g++.target\i386\m128-check.h" line 1 - 6 : "gcc\testsuite\gcc.target\i386\sha1msg1-2.c" line 6 - 7 : "gcc\testsuite\gcc.target\i386\sha1msg2-2.c" line 6 - 8 : "gcc\testsuite\gcc.target\i386\sha1nexte-2.c" line 6 - 9 : "gcc\testsuite\gcc.target\i386\sha1rnds4-2.c" line 6 - 10 : "gcc\testsuite\gcc.target\i386\sha256msg1-2.c" line 6 - ... 10 of 12 details -5 : "gcc\testsuite\gcc.target\i386\m256-check.h" impact on 1599 file(s) + 1 : "gcc\config\arm\arm_mve.h" line 31, impact on 2485 file(s) + 2 : "gcc\system.h" line 524, impact on 1060 file(s) + 3 : "libgcc\gstdint.h" line 6, impact on 659 file(s) + 4 : "gcc\config\arm\arm_fp16.h" line 34, impact on 286 file(s) + 5 : "gcc\config\arm\arm_neon.h" line 43, impact on 282 file(s) + 6 : "include\plugin-api.h" line 30, impact on 235 file(s) + 7 : "include\splay-tree.h" line 40, impact on 162 file(s) + 8 : "libffi\testsuite\libffi.call\ffitest.h" line 9, impact on 145 file(s) + 9 : "liboffloadmic\include\coi\common\COITypes_common.h" line 51, impact on 41 file(s) + 10 : "libbacktrace\backtrace.h" line 43, impact on 34 file(s) + ... 10 of 363 details +5 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" impact on 4716 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\i386\m512-check.h" line 2, impact on 1131 file(s) - 2 : "gcc\testsuite\gcc.target\i386\avx2-check.h" line 3, impact on 228 file(s) - 3 : "gcc\testsuite\gcc.target\i386\avx-check.h" line 3, impact on 206 file(s) - 4 : "gcc\testsuite\gcc.target\i386\xop-check.h" line 4, impact on 9 file(s) - 5 : "gcc\testsuite\gcc.target\i386\f16c-check.h" line 4, impact on 6 file(s) - 6 : "gcc\testsuite\g++.target\i386\m256-check.h" line 1 - 7 : "gcc\testsuite\gcc.target\i386\fma-256-fmaddXX.c" line 8 - 8 : "gcc\testsuite\gcc.target\i386\fma-256-fmaddsubXX.c" line 8 - 9 : "gcc\testsuite\gcc.target\i386\fma-256-fmsubXX.c" line 8 - 10 : "gcc\testsuite\gcc.target\i386\fma-256-fmsubaddXX.c" line 8 - ... 10 of 19 details -6 : "include\ansidecl.h" impact on 1317 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_allocator.h" line 32, impact on 332 file(s) + 2 : "libstdc++-v3\testsuite\util\testsuite_iterators.h" line 30, impact on 326 file(s) + 3 : "libstdc++-v3\testsuite\util\testsuite_tr1.h" line 26, impact on 225 file(s) + 4 : "libstdc++-v3\testsuite\util\testsuite_api.h" line 23, impact on 138 file(s) + 5 : "libstdc++-v3\testsuite\util\debug\checks.h" line 27, impact on 111 file(s) + 6 : "libstdc++-v3\testsuite\util\testsuite_rvalref.h" line 25, impact on 71 file(s) + 7 : "libstdc++-v3\testsuite\util\replacement_memory_operators.h" line 23, impact on 32 file(s) + 8 : "libstdc++-v3\testsuite\util\debug\unordered_checks.h" line 19, impact on 16 file(s) + 9 : "libstdc++-v3\testsuite\util\testsuite_random.h" line 29, impact on 12 file(s) + 10 : "libstdc++-v3\testsuite\util\testsuite_new_operators.h" line 26, impact on 3 file(s) + ... 10 of 4083 details +6 : "gcc\config\i386\mmintrin.h" impact on 4383 file(s) Included by: - 1 : "include\hashtab.h" line 39, impact on 1207 file(s) - 2 : "include\libiberty.h" line 42, impact on 1038 file(s) - 3 : "include\splay-tree.h" line 37, impact on 159 file(s) - 4 : "include\partition.h" line 43, impact on 14 file(s) - 5 : "include\md5.h" line 30, impact on 5 file(s) - 6 : "gcc\brig\brigfrontend\brig-util.h" line 30, impact on 4 file(s) - 7 : "gcc\brig\brigfrontend\brig-function.h" line 27, impact on 3 file(s) - 8 : "gcc\brig\brigfrontend\brig-to-generic.h" line 31, impact on 2 file(s) - 9 : "gcc\go\go-system.h" line 136, impact on 2 file(s) - 10 : "include\floatformat.h" line 23, impact on 1 file(s) - ... 10 of 63 details -7 : "include\hashtab.h" impact on 1207 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 31, impact on 4373 file(s) + 2 : "gcc\config\i386\immintrin.h" line 27, impact on 3236 file(s) + 3 : "gcc\config\i386\mm3dnow.h" line 30, impact on 367 file(s) +7 : "gcc\config\rs6000\mm_malloc.h" impact on 4381 file(s) Included by: - 1 : "include\filenames.h" line 29, impact on 1043 file(s) - 2 : "gcc\hash-table.h" line 249, impact on 1018 file(s) - 3 : "gcc\function-tests.c" line 38 - 4 : "libcpp\files.c" line 29 - 5 : "libcpp\line-map.c" line 27 - 6 : "libiberty\hashtab.c" line 63 -8 : "gcc\testsuite\gcc.target\i386\avx512f-os-support.h" impact on 1131 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 34, impact on 4373 file(s) + 2 : "gcc\config\rs6000\xmmintrin.h" line 82, impact on 5 file(s) + 3 : "gcc\testsuite\gcc.target\i386\sse-23.c" line 5, impact on 2 file(s) + 4 : "gcc\testsuite\gcc.target\i386\sse-13.c" line 5, impact on 1 file(s) + 5 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 6, impact on 1 file(s) + 6 : "gcc\testsuite\gcc.target\i386\avx-1.c" line 5 + 7 : "gcc\testsuite\gcc.target\i386\avx-2.c" line 5 + 8 : "gcc\testsuite\gcc.target\i386\sse-14.c" line 5 + 9 : "liboffloadmic\runtime\offload_common.cpp" line 32 +8 : "gcc\config\i386\emmintrin.h" impact on 4373 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\i386\avx512-check.h" line 4, impact on 1130 file(s) -9 : "gcc\testsuite\gcc.target\i386\m512-check.h" impact on 1131 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 1316, impact on 4373 file(s) + 2 : "gcc\config\i386\pmmintrin.h" line 31, impact on 3491 file(s) + 3 : "gcc\config\i386\wmmintrin.h" line 31, impact on 3251 file(s) + 4 : "gcc\config\i386\immintrin.h" line 31, impact on 3236 file(s) + 5 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 5, impact on 1799 file(s) + 6 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 9, impact on 7 file(s) + 7 : "gcc\testsuite\g++.dg\asan\asan_test.cc" line 686, impact on 1 file(s) + 8 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 141, impact on 1 file(s) + 9 : "gcc\testsuite\gcc.target\i386\sse2-addpd-1.c" line 15, impact on 1 file(s) + 10 : "gcc\testsuite\gcc.target\i386\sse2-addsd-1.c" line 15, impact on 1 file(s) + ... 10 of 350 details +9 : "gcc\config\i386\xmmintrin.h" impact on 4373 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\i386\avx512-check.h" line 3, impact on 1130 file(s) -10 : "gcc\testsuite\gcc.target\i386\avx512-check.h" impact on 1130 file(s) + 1 : "gcc\config\i386\emmintrin.h" line 31, impact on 4373 file(s) + 2 : "gcc\config\i386\immintrin.h" line 29, impact on 3236 file(s) + 3 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 2, impact on 1799 file(s) + 4 : "gcc\testsuite\gcc.target\x86_64\abi\defines.h" line 5, impact on 19 file(s) + 5 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 6, impact on 7 file(s) + 6 : "gcc\testsuite\gcc.dg\compat\union-m128-1.h" line 1, impact on 2 file(s) + 7 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 127, impact on 1 file(s) + 8 : "gcc\testsuite\gcc.target\i386\sse-addps-1.c" line 15, impact on 1 file(s) + 9 : "gcc\testsuite\gcc.target\i386\sse-addss-1.c" line 15, impact on 1 file(s) + 10 : "gcc\testsuite\gcc.target\i386\sse-andnps-1.c" line 15, impact on 1 file(s) + ... 10 of 169 details +10 : "gcc\config\i386\pmmintrin.h" impact on 3491 file(s) Included by: - 1 : "gcc\testsuite\gcc.target\i386\avx512f-helper.h" line 11, impact on 1095 file(s) - 2 : "gcc\testsuite\gcc.target\i386\avx512bw-check.h" line 3, impact on 22 file(s) - 3 : "gcc\testsuite\gcc.target\i386\avx512dq-check.h" line 3, impact on 7 file(s) - 4 : "gcc\testsuite\gcc.target\i386\avx512f-pr88547-2.c" line 5, impact on 1 file(s) - 5 : "gcc\testsuite\gcc.target\i386\avx512vl-check.h" line 4, impact on 1 file(s) - 6 : "gcc\testsuite\gcc.target\i386\avx512dq-pr85918-2.c" line 13 -... 10 of 3166 files + 1 : "gcc\config\i386\tmmintrin.h" line 31, impact on 3451 file(s) + 2 : "gcc\config\i386\immintrin.h" line 33, impact on 3236 file(s) + 3 : "gcc\config\i386\ammintrin.h" line 31, impact on 364 file(s) + 4 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 157, impact on 1 file(s) + 5 : "gcc\testsuite\gcc.target\i386\sse3-addsubpd.c" line 15, impact on 1 file(s) + 6 : "gcc\testsuite\gcc.target\i386\sse3-addsubps.c" line 15, impact on 1 file(s) + 7 : "gcc\testsuite\gcc.target\i386\sse3-haddpd.c" line 14, impact on 1 file(s) + 8 : "gcc\testsuite\gcc.target\i386\sse3-haddps.c" line 15, impact on 1 file(s) + 9 : "gcc\testsuite\gcc.target\i386\sse3-hsubpd.c" line 14, impact on 1 file(s) + 10 : "gcc\testsuite\gcc.target\i386\sse3-hsubps.c" line 14, impact on 1 file(s) + ... 10 of 26 details +... 10 of 3748 files +Unincluded headers: +1 : "fixincludes\system.h" +2 : "fixincludes\tests\base\AvailabilityInternal.h" +3 : "fixincludes\tests\base\X11\ShellP.h" +4 : "fixincludes\tests\base\X11\Xmu.h" +5 : "fixincludes\tests\base\Xm\BaseClassI.h" +6 : "fixincludes\tests\base\Xm\Traversal.h" +7 : "fixincludes\tests\base\ansi\math.h" +8 : "fixincludes\tests\base\assert.h" +9 : "fixincludes\tests\base\bsd\libc.h" +10 : "fixincludes\tests\base\c_asm.h" +... 10 of 823 files diff --git a/docs/examples/llvm-project/.cppinclude.json b/docs/examples/llvm-project/.cppinclude.json index 3e2948a..39c3d5d 100644 --- a/docs/examples/llvm-project/.cppinclude.json +++ b/docs/examples/llvm-project/.cppinclude.json @@ -2,6 +2,7 @@ "project_dir" : "llvm-project", "include_dirs" : [ + "libcxx/", "libcxx/test/support/", "libcxx/include/", "libcxx/utils/google-benchmark/include/", @@ -46,6 +47,7 @@ "llvm/lib/Target/VE/", "llvm/lib/Target/NVPTX/", "llvm/test/tools/llvm-cov/", + "llvm-project/libcxx/", "llgo/third_party/gofrontend/libgo/runtime/", @@ -90,6 +92,7 @@ "lld/include/", "lld/ELF/", + "lldb/include/lldb/Host/windows/", "compiler-rt/lib/builtins/", "compiler-rt/lib/", @@ -125,7 +128,20 @@ "llgo/third_party/gofrontend/libffi/include/", "llgo/third_party/gofrontend/include/", - "LLDB/SBBlock.h" + "LLDB/SBBlock.h", + + "clang-tools-extra/test/clang-tidy/Inputs/bugprone-not-null-terminated-result/", + "llgo/third_party/gofrontend/libbacktrace", + "clang-tools-extra/clang-change-namespace/", + "llvm/tools/llvm-reduce/", + "libclc/generic/include/", + "clang-tools-extra/test/clang-tidy/infrastructure/Inputs/nolint/", + "polly/tools/", + "lldb/source/Plugins/Process/Linux/", + "polly/lib/External/isl/interface/", + "openmp/runtime/src/thirdparty/ittnotify/", + "lldb/include/lldb/Host/windows/", + "lldb/include/lldb/Symbol/" ], "ignore_files" : [ @@ -169,58 +185,58 @@ ".*\\.inc", ".*\\.def", - "foo.h", - "Foo.h", - "a.h", - "a1.h", - "a2.h", - "A.h", - "B.h", - "b.h", - "b1.h", - "b2.h", - "c.h", - "c1.h", - "c2.h", - "d.h", - "D.h", - "d1.h", - "e.h", - "e1.h", - "e2.h", - "f.h", - "foo", - "i.h", - "j.h", - "x.h", - "g.h", - "t.h", - "y.h", - "o.h", - "s.h", - "get-cursor-includes-2.h", - "gitversion.h", - "foo.h", - "bar.h", - "baz.h", - "test.h", - "header.h", - "header1.h", - "header2.h", - "header3.h", - "dummy.h", - "empty.h", - "not_real.h", - "structures.h", - "decls.h", - "device_functions.hpp", - "annotate-comments-preprocessor.h", - "public2.h", + "^foo.h", + "^Foo.h", + "^a.h", + "^a1.h", + "^a2.h", + "^A.h", + "^B.h", + "^b.h", + "^b1.h", + "^b2.h", + "^c.h", + "^c1.h", + "^c2.h", + "^d.h", + "^D.h", + "^d1.h", + "^e.h", + "^e1.h", + "^e2.h", + "^f.h", + "^foo", + "^i.h", + "^j.h", + "^x.h", + "^g.h", + "^t.h", + "^y.h", + "^o.h", + "^s.h", + "^get-cursor-includes-2.h", + "^gitversion.h", + "^foo.h", + "^bar.h", + "^baz.h", + "^test.h", + "^header.h", + "^header1.h", + "^header2.h", + "^header3.h", + "^dummy.h", + "^empty.h", + "^not_real.h", + "^structures.h", + "^decls.h", + "^device_functions.hpp", + "^annotate-comments-preprocessor.h", + "^public2.h", "CASE-INSENSITIVE-INCLUDE.H", "CASE-INSENSITIVE-INCLUDE2.H", - "LibAHeader.h", - "missing1.h", - "missing2.h", + "^LibAHeader.h", + "^missing1.h", + "^missing2.h", "clang_tidy/tests/insert_includes_test_header.h", "clang/test/Frontend/dependency-gen-escaping.c", @@ -230,14 +246,14 @@ "src/libfuzzer/libfuzzer_macro.h", "src/unistd/syscall.h", - "toy/.*", + "^toy/.*", "dispatch/dispatch.h", "caml/memory.h", - "llvm/IR/.*\\.h", - "caml/.*\\.h", - "LLDB/.*\\.h", + "^llvm/IR/.*\\.h", + "^caml/.*\\.h", + "^LLDB/.*\\.h", "Inputs.*success.h", "Subframework/Subframework.h", @@ -249,10 +265,297 @@ "clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp", - "CL/.*" + "^CL/.*", + + "Case-Insensitive-Include.h", + "case-insensitive-include.h", + "cuda.h", + "^cxx_loop_proto.pb.h", + "backtrace.h", + "math_functions.hpp", + "^sm_*_intrinsics.hpp", + "^backtrace-supported.h", + "^Move.h", + "^client/linux/handler/exception_handler.h", + "^cuda_runtime.h", + "^cxx_proto.pb.h", + "^imp.h", + "^missing.h", + "missing-system-header.*", + "compiler-rt/test/asan/TestCases/Windows/*", + "clang/unittests/Frontend/*", + "clang-tools-extra/clangd/unittests/*", + "clang/test/Preprocessor/*", + "analyze_header_input.h", + "clang-tools-extra/test/*", + "clang/test/*", + "^Python.h", + "^crt/*", + "^hwloc.h", + "^intel-pt.h", + "^lua.hpp", + "^mach/machine.h", + "^math_functions_dbl_ptx3", + "^perfmon/perf_event.h", + "^perfmon/pfmlib.h", + "^perfmon/pfmlib_perf_event.h", + "^sm_20_atomic_functions.hpp", + "^sm_20_intrinsics.hpp", + "^sm_32_atomic_functions.hpp", + "^sm_60_atomic_functions.hpp", + "^sm_61_intrinsics.hpp", + "^template.h", + "^texture_indirect_functions.h", + "^unresolved_file.h", + "^unwind-pe.h", + + "^sys/.*.h", + "^linux/.*.h", + "^mach/.*.h", + "^net/.*.h", + "^os/.*.h", + "^CoreFoundationCPP/.*.h", + "^altq/.*.h", + "^android/.*.h", + "^dev/.*.h", + "^pthread.h", + "^fcntl.h", + "^dlfcn.h", + "^io.h", + "^dirent.h", + "^link.h", + "^arpa/inet.h", + "^glob.h", + "^netdb.h", + "^netinet/.*.h", + "^pwd.h", + "^elf.h", + "^semaphore.h", + "^termios.h", + "^zircon/.*.h", + "^CoreFoundation/.*.h", + "^CoreServices/", + "^arch/.*.h", + "^asm/.*.h", + + "^grp.h", + "^pthread_np.h", + "^libgen.h", + "^poll.h", + "^Block_private.h", + "^regex.h", + "^ucontext.h", + "^alloca.h", + "^execinfo.h", + "^psapi.h", + "^spawn.h", + "^strings.h", + "^endian.h", + "^lwp.h", + "^mach-o/dyld.h", + "^malloc/malloc.h", + "^process.h", + "^uuid/uuid.h", + "^getopt.h", + "^isl/stdint.h", + "^winsock2.h", + "^Availability.h", + "^ifaddrs.h", + "^mach-o/loader.h", + "^rpc/xdr.h", + "^xpc/xpc.h", + "^libkern/OSAtomic.h", + "^libproc.h", + "^pet.h", + "^utmp.h", + "^utmpx.h", + "^wordexp.h", + "^AvailabilityMacros.h", + "^dbghelp.h", + "^err.h", + "^features.h", + "^fstab.h", + "^gnuregex.h", + "^machine/endian.h", + "^memory.h", + "^util.h", + "^utime.h", + "^winerror.h", + "^zlib.h", + "^compression.h", + "^crypt.h", + "^direct.h", + "^fts.h", + "^gmp.h", + "^link_elf.h", + "^machine/sysarch.h", + "^mntent.h", + "^ntstatus.h", + "^osreldate.h", + "^stringlist.h", + "^syslog.h", + "^term.h", + "^thread.h", + "^ttyent.h", + "^vis.h", + "^ws2tcpip.h", + "^CrashReporterClient.h", + "^OpenCL/.*.h", + "^asl.h", + "^clean-one.h", + "^cygwin/version.h", + "^emscripten.h", + "^google/protobuf/text_format.h", + "^histedit.h", + "^iconv.h", + "^langinfo.h", + "^lib/sync/mutex.h", + "^libintl.h", + "^libxml/xmlreader.h", + "^mach-o/getsect.h", + "^machine/atomic.h", + "^machine/.*.h", + "^md2.h", + "^md4.h", + "^md5.h", + "^ntverp.h", + "^objbase.h", + "^obstack.h", + "^pty.h", + "^rmd160.h", + "^soundcard.h", + "^sysexits.h", + "^winnt.h", + "^Accelerate/Accelerate.h", + "^BaseTsd.h", + "^Carbon/Carbon.h", + "^MyFramework/MyFramework.h", + "^SpringBoardServices/.*.h", + "^System/pthread_machdep.h", + "^ar.h", + "^argz.h", + "^asm-generic/errno-base.h", + "^ast.h", + "^atlbase.h", + "^basetsd.h", + "^cdbr.h", + "^cdbw.h", + "^comdef.h", + "^copyfile.h", + "^crypto/cryptodev.h", + "^curses.h", + "^cvconst.h", + "^dia2.h", + "^diacreate.h", + "^editline/readline.h", + "^excpt.h", + "^experimental/any", + "^fibersapi.h", + "^fpu_control.h", + "^fs/autofs/autofs_ioctl.h", + "^gelf.h", + "^gmp_compat.h", + "^imath.h", + "^imrat.h", + "^kern/exc_resource.h", + "^kvm.h", + "^lib/fdio/fdio.h", + "^lib/fdio/spawn.h", + "^libc.h", + "^libelf.h", + "^libkern/OSByteOrder.h", + "^libkern/OSCacheControl.h", + "^libutil.h", + "^libxml/.*.h", + "^lzma.h", + "^mach-o/dyld-interposing.h", + "^mach-o/nlist.h", + "^machine/cpu.h", + "^machine/limits.h", + "^mcheck.h", + "^mint/.*.h", + "^mips64/sysarch.h", + "^mqueue.h", + "^nacl/nacl_random.h", + "^netax25/ax25.h", + "^netbt/hci.h", + "^netinet6/.*.h", + "^netipx/ipx.h", + "^netrom/netrom.h", + "^netsmb/smb_dev.h", + "^nl_types.h", + "^notexisting.hpp", + "^ntsecapi.h", + "^nvmm.h", + "^objc/.*.h", + "^opagent.h", + "^os2.h", + "^panel.h", + "^paths.h", + "^plugin-api.h", + "^procfs.h", + "^ptrauth.h", + "^resolv.h", + "^rpc/types.h", + "^rpc.h", + "^rtems/.*.h", + "^sal.h", + "^scsi/scsi.h", + "^search.h", + "^sgidefs.h", + "^sha1.h", + "^sha2.h", + "^share.h", + "^shellapi.h", + "^sound/asound.h", + "^stk.h", + "^sunmedia_types.h", + "^synch.h", + "^syscall.h", + "^tbb/.*.h", + "^time64.h", + "^tr1/memory", + "^traceloggingprovider.h", + "^u.h", + "^uvm/uvm_prot.h", + "^valgrind/valgrind.h", + "^winapifamily.h", + "^wincrypt.h", + "^windef.h", + "^x86/.*.h", + "^xar/xar.h", + "^xlocale.h", + "^xlocinfo.h", + "^ymath.h", + "^z3.h", + "^zxtest/zxtest.h", + + "ffitarget.h", + "ResourceScriptToken.h", + "Passes.h", + "Bar.h", + "libc_header.h", + "gmp_compat.h", + "Lexer.h", + "MLIRGen.h", + "tmmintrin.h", + "commandlineflags.h", + "tgmath.h", + "imrat.h", + "ittnotify_types.h", + "myModule.h", + "ShapeInferenceInterface.h", + "NtStructures.h", + "clc_nextafter.h", + "libc_header.h", + "Formatters.h", + "arraysize.h", + "Lexer.h", + + "\\\\usr\\\\include\\\\malloc.h" ], - "ignore_system_includes" : true + "ignore_system_includes" : false } diff --git a/docs/examples/llvm-project/output_unix.txt b/docs/examples/llvm-project/output_unix.txt index 5dfd0c6..98a6172 100644 --- a/docs/examples/llvm-project/output_unix.txt +++ b/docs/examples/llvm-project/output_unix.txt @@ -2,117 +2,146 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "llvm/include/llvm/Support/Compiler.h" impact on 4791 file(s) +1 : "libcxx/include/__config" impact on 19234 file(s) Included by: - 1 : "llvm/include/llvm/ADT/SmallVector.h" line 18, impact on 4465 file(s) - 2 : "llvm/include/llvm/ADT/Optional.h" line 19, impact on 2562 file(s) - 3 : "llvm/include/llvm/Support/Error.h" line 23, impact on 2427 file(s) - 4 : "llvm/include/llvm/ADT/DenseMap.h" line 19, impact on 2296 file(s) - 5 : "llvm/include/llvm/Support/SwapByteOrder.h" line 17, impact on 2016 file(s) - 6 : "llvm/include/llvm/Support/Endian.h" line 17, impact on 2009 file(s) - 7 : "llvm/include/llvm/ADT/PointerIntPair.h" line 16, impact on 1852 file(s) - 8 : "llvm/include/llvm/Support/Allocator.h" line 26, impact on 1813 file(s) - 9 : "clang/include/clang/AST/NestedNameSpecifier.h" line 21, impact on 548 file(s) - 10 : "clang/include/clang/AST/Decl.h" line 44, impact on 541 file(s) - ... 10 of 301 details -2 : "llvm/include/llvm/ADT/SmallVector.h" impact on 4465 file(s) + 1 : "libcxx/include/math.h" line 294, impact on 17549 file(s) + 2 : "libcxx/include/stdlib.h" line 91, impact on 17549 file(s) + 3 : "libcxx/include/stdint.h" line 106, impact on 11797 file(s) + 4 : "libcxx/include/stddef.h" line 39, impact on 11047 file(s) + 5 : "libcxx/include/inttypes.h" line 238, impact on 9940 file(s) + 6 : "libcxx/include/setjmp.h" line 28, impact on 7916 file(s) + 7 : "libcxx/test/support/test_macros.h" line 18, impact on 5744 file(s) + 8 : "libcxx/include/stdio.h" line 101, impact on 3591 file(s) + 9 : "libcxx/include/string.h" line 54, impact on 1898 file(s) + 10 : "libcxx/include/limits.h" line 40, impact on 1069 file(s) + ... 10 of 48 details +2 : "libcxx/include/type_traits" impact on 17813 file(s) Included by: - 1 : "llvm/include/llvm/Support/raw_ostream.h" line 16, impact on 3651 file(s) - 2 : "llvm/include/llvm/Support/Error.h" line 18, impact on 2427 file(s) - 3 : "llvm/include/llvm/Support/Allocator.h" line 24, impact on 1813 file(s) - 4 : "llvm/include/llvm/Support/SourceMgr.h" line 21, impact on 940 file(s) - 5 : "llvm/include/llvm/Support/VirtualFileSystem.h" line 20, impact on 652 file(s) - 6 : "llvm/include/llvm/ADT/MapVector.h" line 20, impact on 523 file(s) - 7 : "clang/include/clang/AST/Expr.h" line 33, impact on 456 file(s) - 8 : "clang/include/clang/Basic/FileManager.h" line 21, impact on 409 file(s) - 9 : "clang/include/clang/Basic/SourceManager.h" line 46, impact on 382 file(s) - 10 : "llvm/include/llvm/ADT/TinyPtrVector.h" line 15, impact on 381 file(s) - ... 10 of 698 details -3 : "llvm/include/llvm/Support/raw_ostream.h" impact on 3651 file(s) + 1 : "libcxx/include/math.h" line 311, impact on 17549 file(s) + 2 : "llvm/include/llvm/Support/type_traits.h" line 17, impact on 9534 file(s) + 3 : "llvm/include/llvm/ADT/iterator.h" line 16, impact on 9419 file(s) + 4 : "llvm/include/llvm/ADT/STLExtras.h" line 35, impact on 9405 file(s) + 5 : "llvm/include/llvm/Support/SwapByteOrder.h" line 20, impact on 9323 file(s) + 6 : "llvm/include/llvm/ADT/StringRef.h" line 21, impact on 9312 file(s) + 7 : "llvm/include/llvm/Support/MathExtras.h" line 23, impact on 9305 file(s) + 8 : "llvm/include/llvm/ADT/SmallVector.h" line 32, impact on 9242 file(s) + 9 : "llvm/include/llvm/ADT/ArrayRef.h" line 24, impact on 8875 file(s) + 10 : "llvm/include/llvm/Support/PointerLikeTypeTraits.h" line 19, impact on 8498 file(s) + ... 10 of 1373 details +3 : "libcxx/include/limits" impact on 17721 file(s) Included by: - 1 : "llvm/include/llvm/Support/Error.h" line 28, impact on 2427 file(s) - 2 : "lldb/include/lldb/Utility/Stream.h" line 17, impact on 355 file(s) - 3 : "clang/include/clang/AST/Attr.h" line 30, impact on 225 file(s) - 4 : "llvm/include/llvm/Support/EndianStream.h" line 19, impact on 117 file(s) - 5 : "llvm/include/llvm/Support/JSON.h" line 54, impact on 88 file(s) - 6 : "llvm/include/llvm/MC/MCObjectWriter.h" line 17, impact on 85 file(s) - 7 : "llvm/include/llvm/Support/ScopedPrinter.h" line 18, impact on 83 file(s) - 8 : "clang-tools-extra/clangd/Protocol.h" line 31, impact on 64 file(s) - 9 : "llvm/include/llvm/Support/LEB128.h" line 17, impact on 58 file(s) - 10 : "llvm/include/llvm/Support/FormattedStream.h" line 17, impact on 52 file(s) - ... 10 of 1274 details -4 : "llvm/include/llvm/ADT/Optional.h" impact on 2562 file(s) + 1 : "libcxx/include/math.h" line 312, impact on 17549 file(s) + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 32, impact on 9405 file(s) + 3 : "llvm/include/llvm/ADT/StringRef.h" line 19, impact on 9312 file(s) + 4 : "llvm/include/llvm/Support/MathExtras.h" line 22, impact on 9305 file(s) + 5 : "llvm/include/llvm/Support/Alignment.h" line 28, impact on 8063 file(s) + 6 : "llvm/include/llvm/ADT/PointerIntPair.h" line 21, impact on 6760 file(s) + 7 : "clang/include/clang/Basic/Diagnostic.h" line 31, impact on 2055 file(s) + 8 : "llvm/include/llvm/ADT/SmallBitVector.h" line 24, impact on 1103 file(s) + 9 : "llvm/include/llvm/ADT/SparseSet.h" line 28, impact on 746 file(s) + 10 : "clang/include/clang/ASTMatchers/ASTMatchers.h" line 89, impact on 695 file(s) + ... 10 of 379 details +4 : "libcxx/include/math.h" impact on 17549 file(s) Included by: - 1 : "llvm/include/llvm/Support/Allocator.h" line 23, impact on 1813 file(s) - 2 : "llvm/include/llvm/Support/VirtualFileSystem.h" line 19, impact on 652 file(s) - 3 : "clang/include/clang/AST/Decl.h" line 38, impact on 541 file(s) - 4 : "clang/include/clang/Lex/Lexer.h" line 21, impact on 336 file(s) - 5 : "clang/include/clang/AST/ExprCXX.h" line 40, impact on 287 file(s) - 6 : "clang/include/clang/AST/ExprObjC.h" line 29, impact on 260 file(s) - 7 : "clang/include/clang/Lex/Preprocessor.h" line 38, impact on 229 file(s) - 8 : "llvm/include/llvm/MC/MCStreamer.h" line 18, impact on 207 file(s) - 9 : "llvm/include/llvm/ADT/PostOrderIterator.h" line 19, impact on 170 file(s) - 10 : "llvm/include/llvm/Analysis/ScalarEvolution.h" line 29, impact on 107 file(s) - ... 10 of 280 details -5 : "llvm/include/llvm-c/ExternC.h" impact on 2474 file(s) + 1 : "libcxx/include/stdlib.h" line 100, impact on 17549 file(s) + 2 : "llvm/include/llvm-c/DataTypes.h" line 30, impact on 9481 file(s) + 3 : "compiler-rt/lib/builtins/int_math.h" line 27, impact on 66 file(s) + 4 : "openmp/runtime/src/kmp_stats.h" line 30, impact on 18 file(s) + 5 : "compiler-rt/lib/msan/tests/msan_test.cpp" line 41 + 6 : "compiler-rt/test/asan/TestCases/frexp_interceptor.cpp" line 5 + 7 : "compiler-rt/test/builtins/Unit/adddf3vfp_test.c" line 18 + 8 : "compiler-rt/test/builtins/Unit/addsf3vfp_test.c" line 18 + 9 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c" line 19 + 10 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmple_test.c" line 21 + ... 10 of 127 details +5 : "libcxx/include/stdlib.h" impact on 17549 file(s) Included by: - 1 : "llvm/include/llvm-c/Error.h" line 17, impact on 2429 file(s) - 2 : "llvm/include/llvm-c/Disassembler.h" line 19, impact on 18 file(s) - 3 : "llvm/include/llvm-c/Initialization.h" line 19, impact on 12 file(s) - 4 : "llvm/include/llvm-c/BitReader.h" line 22, impact on 5 file(s) - 5 : "llvm/include/llvm-c/Linker.h" line 17, impact on 4 file(s) - 6 : "llvm/include/llvm-c/Transforms/PassManagerBuilder.h" line 17, impact on 4 file(s) - 7 : "llvm/include/llvm-c/Transforms/Scalar.h" line 22, impact on 4 file(s) - 8 : "llvm/include/llvm-c/BitWriter.h" line 22, impact on 3 file(s) - 9 : "llvm/include/llvm-c/IRReader.h" line 17, impact on 3 file(s) - 10 : "llvm/include/llvm-c/Transforms/IPO.h" line 18, impact on 3 file(s) - ... 10 of 11 details -6 : "llvm/include/llvm/Support/ErrorOr.h" impact on 2465 file(s) + 1 : "libcxx/include/math.h" line 301, impact on 17549 file(s) + 2 : "llvm/include/llvm-c/DataTypes.h" line 63, impact on 9481 file(s) + 3 : "llvm/include/llvm/Support/SwapByteOrder.h" line 22, impact on 9323 file(s) + 4 : "clang/lib/Headers/mm_malloc.h" line 13, impact on 7947 file(s) + 5 : "libcxx/test/support/test_macros.h" line 301, impact on 5744 file(s) + 6 : "polly/lib/External/isl/include/isl/arg.h" line 14, impact on 316 file(s) + 7 : "polly/lib/External/isl/include/isl/ctx.h" line 14, impact on 315 file(s) + 8 : "compiler-rt/test/tsan/test.h" line 2, impact on 169 file(s) + 9 : "llgo/third_party/gofrontend/libffi/testsuite/libffi.call/ffitest.h" line 1, impact on 144 file(s) + 10 : "libcxx/test/support/platform_support.h" line 55, impact on 137 file(s) + ... 10 of 1044 details +6 : "libcxx/include/cassert" impact on 14770 file(s) Included by: - 1 : "llvm/include/llvm/Support/Error.h" line 26, impact on 2427 file(s) - 2 : "llvm/include/llvm/Support/FileSystem.h" line 36, impact on 1520 file(s) - 3 : "llvm/include/llvm/Support/MemoryBuffer.h" line 21, impact on 1380 file(s) - 4 : "llvm/include/llvm/Support/VirtualFileSystem.h" line 24, impact on 652 file(s) - 5 : "clang/include/clang/Basic/FileManager.h" line 25, impact on 409 file(s) - 6 : "llvm/include/llvm/Support/Program.h" line 20, impact on 91 file(s) - 7 : "llvm/include/llvm/Bitcode/BitcodeReader.h" line 22, impact on 36 file(s) - 8 : "llvm/tools/dsymutil/DebugMap.h" line 32, impact on 7 file(s) - 9 : "llvm/include/llvm/ProfileData/SampleProfReader.h" line 222, impact on 5 file(s) - 10 : "llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h" line 16, impact on 4 file(s) - ... 10 of 67 details -7 : "llvm/include/llvm-c/Error.h" impact on 2429 file(s) + 1 : "llvm/include/llvm/ADT/Optional.h" line 21, impact on 9448 file(s) + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 25, impact on 9405 file(s) + 3 : "llvm/include/llvm/ADT/StringRef.h" line 16, impact on 9312 file(s) + 4 : "llvm/include/llvm/Support/MathExtras.h" line 19, impact on 9305 file(s) + 5 : "llvm/include/llvm/ADT/SmallVector.h" line 24, impact on 9242 file(s) + 6 : "llvm/include/llvm/ADT/Hashing.h" line 52, impact on 8901 file(s) + 7 : "llvm/include/llvm/ADT/ArrayRef.h" line 19, impact on 8875 file(s) + 8 : "llvm/include/llvm/ADT/Twine.h" line 15, impact on 8386 file(s) + 9 : "llvm/include/llvm/Support/raw_ostream.h" line 18, impact on 8269 file(s) + 10 : "llvm/include/llvm/Support/Alignment.h" line 27, impact on 8063 file(s) + ... 10 of 6044 details +7 : "libcxx/include/cstddef" impact on 11858 file(s) Included by: - 1 : "llvm/include/llvm/Support/Error.h" line 16, impact on 2427 file(s) - 2 : "llvm/tools/llvm-c-test/include-all.c" line 26 - 3 : "llvm/unittests/Support/ErrorTest.cpp" line 10 -8 : "llvm/include/llvm/Support/Error.h" impact on 2427 file(s) + 1 : "llvm/include/llvm-c/DataTypes.h" line 59, impact on 9481 file(s) + 2 : "llvm/include/llvm/ADT/iterator.h" line 14, impact on 9419 file(s) + 3 : "llvm/include/llvm/ADT/STLExtras.h" line 26, impact on 9405 file(s) + 4 : "llvm/include/llvm/Support/SwapByteOrder.h" line 19, impact on 9323 file(s) + 5 : "llvm/include/llvm/ADT/StringRef.h" line 17, impact on 9312 file(s) + 6 : "llvm/include/llvm/Support/AlignOf.h" line 17, impact on 9249 file(s) + 7 : "llvm/include/llvm/ADT/SmallVector.h" line 25, impact on 9242 file(s) + 8 : "llvm/include/llvm/ADT/ArrayRef.h" line 20, impact on 8875 file(s) + 9 : "llvm/include/llvm/Support/raw_ostream.h" line 19, impact on 8269 file(s) + 10 : "llvm/include/llvm/ADT/SmallString.h" line 18, impact on 8032 file(s) + ... 10 of 892 details +8 : "libcxx/include/stdint.h" impact on 11797 file(s) Included by: - 1 : "llvm/include/llvm/Support/FileSystem.h" line 34, impact on 1520 file(s) - 2 : "llvm/include/llvm/Support/DataExtractor.h" line 14, impact on 250 file(s) - 3 : "llvm/include/llvm/MC/MCStreamer.h" line 25, impact on 207 file(s) - 4 : "llvm/include/llvm/Support/FileOutputBuffer.h" line 19, impact on 188 file(s) - 5 : "llvm/include/llvm/Support/BinaryStreamError.h" line 13, impact on 185 file(s) - 6 : "llvm/include/llvm/Support/BinaryStream.h" line 16, impact on 150 file(s) - 7 : "lldb/include/lldb/Symbol/TypeSystem.h" line 21, impact on 145 file(s) - 8 : "clang/include/clang/Frontend/FrontendAction.h" line 26, impact on 142 file(s) - 9 : "lldb/include/lldb/Utility/Reproducer.h" line 14, impact on 130 file(s) - 10 : "llvm/include/llvm/Support/BinaryByteStream.h" line 17, impact on 126 file(s) - ... 10 of 382 details -9 : "llvm/include/llvm/Support/ReverseIteration.h" impact on 2297 file(s) + 1 : "compiler-rt/include/sanitizer/common_interface_defs.h" line 16, impact on 10001 file(s) + 2 : "libcxx/include/inttypes.h" line 255, impact on 9940 file(s) + 3 : "llvm/include/llvm-c/DataTypes.h" line 34, impact on 9481 file(s) + 4 : "lldb/include/lldb/lldb-types.h" line 15, impact on 1725 file(s) + 5 : "llvm/include/llvm/IR/FPEnv.h" line 20, impact on 1196 file(s) + 6 : "lldb/include/lldb/Utility/Status.h" line 18, impact on 1129 file(s) + 7 : "lldb/include/lldb/Utility/FileSpec.h" line 23, impact on 1128 file(s) + 8 : "lldb/include/lldb/Utility/Stream.h" line 21, impact on 983 file(s) + 9 : "lldb/include/lldb/Core/Address.h" line 18, impact on 845 file(s) + 10 : "lldb/include/lldb/Utility/Endian.h" line 14, impact on 751 file(s) + ... 10 of 470 details +9 : "libcxx/include/memory" impact on 11547 file(s) Included by: - 1 : "llvm/include/llvm/ADT/DenseMap.h" line 21, impact on 2296 file(s) - 2 : "llvm/unittests/Support/ReverseIterationTest.cpp" line 13 -10 : "llvm/include/llvm/ADT/DenseMap.h" impact on 2296 file(s) + 1 : "llvm/include/llvm/ADT/Optional.h" line 22, impact on 9448 file(s) + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 33, impact on 9405 file(s) + 3 : "llvm/include/llvm/ADT/SmallVector.h" line 30, impact on 9242 file(s) + 4 : "llvm/include/llvm/ADT/ArrayRef.h" line 23, impact on 8875 file(s) + 5 : "llvm/include/llvm/Support/Casting.h" line 20, impact on 7366 file(s) + 6 : "llvm/include/llvm/Support/Error.h" line 34, impact on 6869 file(s) + 7 : "llvm/include/llvm/Support/FileSystem.h" line 41, impact on 5728 file(s) + 8 : "llvm/include/llvm/ADT/APFloat.h" line 22, impact on 5376 file(s) + 9 : "llvm/include/llvm/Support/MemoryBuffer.h" line 25, impact on 5178 file(s) + 10 : "llvm/include/llvm/Support/SourceMgr.h" line 28, impact on 4601 file(s) + ... 10 of 1326 details +10 : "libcxx/include/cstdlib" impact on 11516 file(s) Included by: - 1 : "llvm/include/llvm/ADT/MapVector.h" line 19, impact on 523 file(s) - 2 : "clang/include/clang/Basic/FileManager.h" line 19, impact on 409 file(s) - 3 : "clang/include/clang/AST/DeclCXX.h" line 39, impact on 396 file(s) - 4 : "clang/include/clang/Basic/SourceManager.h" line 42, impact on 382 file(s) - 5 : "clang/include/clang/AST/DeclObjC.h" line 27, impact on 324 file(s) - 6 : "llvm/include/llvm/MC/MCExpr.h" line 12, impact on 284 file(s) - 7 : "clang/include/clang/Lex/ModuleMap.h" line 22, impact on 252 file(s) - 8 : "clang/include/clang/Lex/Preprocessor.h" line 34, impact on 229 file(s) - 9 : "llvm/include/llvm/MC/MCStreamer.h" line 17, impact on 207 file(s) - 10 : "lldb/include/lldb/Utility/UserIDResolver.h" line 12, impact on 165 file(s) - ... 10 of 390 details -... 10 of 2081 files + 1 : "llvm/include/llvm-c/DataTypes.h" line 60, impact on 9481 file(s) + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 28, impact on 9405 file(s) + 3 : "llvm/include/llvm/Support/MemAlloc.h" line 21, impact on 9243 file(s) + 4 : "llvm/include/llvm/ADT/SmallVector.h" line 26, impact on 9242 file(s) + 5 : "llvm/include/llvm/Support/Allocator.h" line 34, impact on 8025 file(s) + 6 : "llvm/include/llvm/ADT/StringMap.h" line 25, impact on 7738 file(s) + 7 : "llvm/include/llvm/ADT/StringExtras.h" line 23, impact on 6930 file(s) + 8 : "llvm/include/llvm/Support/Error.h" line 32, impact on 6869 file(s) + 9 : "llvm/include/llvm/ADT/SmallPtrSet.h" line 23, impact on 5164 file(s) + 10 : "llvm/include/llvm/ADT/BitVector.h" line 23, impact on 4074 file(s) + ... 10 of 583 details +... 10 of 6002 files +Unincluded headers: +1 : "clang/include/clang/Analysis/AnalysisDiagnostic.h" +2 : "clang/include/clang/Analysis/FlowSensitive/DataflowValues.h" +3 : "clang/include/clang/StaticAnalyzer/Core/PathSensitive/SummaryManager.h" +4 : "clang/lib/Headers/__clang_cuda_runtime_wrapper.h" +5 : "clang/lib/Headers/arm_cmse.h" +6 : "clang/lib/Headers/float.h" +7 : "clang/lib/Headers/htmxlintrin.h" +8 : "clang/lib/Headers/inttypes.h" +9 : "clang/lib/Headers/limits.h" +10 : "clang/lib/Headers/msa.h" +... 10 of 231 files diff --git a/docs/examples/llvm-project/output_win.txt b/docs/examples/llvm-project/output_win.txt index 063453c..4c0ac8c 100644 --- a/docs/examples/llvm-project/output_win.txt +++ b/docs/examples/llvm-project/output_win.txt @@ -2,117 +2,146 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "llvm\include\llvm\Support\Compiler.h" impact on 4791 file(s) +1 : "libcxx\include\__config" impact on 18982 file(s) Included by: - 1 : "llvm\include\llvm\ADT\SmallVector.h" line 18, impact on 4465 file(s) - 2 : "llvm\include\llvm\ADT\Optional.h" line 19, impact on 2562 file(s) - 3 : "llvm\include\llvm\Support\Error.h" line 23, impact on 2427 file(s) - 4 : "llvm\include\llvm\ADT\DenseMap.h" line 19, impact on 2296 file(s) - 5 : "llvm\include\llvm\Support\SwapByteOrder.h" line 17, impact on 2016 file(s) - 6 : "llvm\include\llvm\Support\Endian.h" line 17, impact on 2009 file(s) - 7 : "llvm\include\llvm\ADT\PointerIntPair.h" line 16, impact on 1852 file(s) - 8 : "llvm\include\llvm\Support\Allocator.h" line 26, impact on 1813 file(s) - 9 : "clang\include\clang\AST\NestedNameSpecifier.h" line 21, impact on 548 file(s) - 10 : "clang\include\clang\AST\Decl.h" line 44, impact on 541 file(s) - ... 10 of 301 details -2 : "llvm\include\llvm\ADT\SmallVector.h" impact on 4465 file(s) + 1 : "libcxx\include\math.h" line 294, impact on 17505 file(s) + 2 : "libcxx\include\stdlib.h" line 91, impact on 17505 file(s) + 3 : "libcxx\include\stdint.h" line 106, impact on 11752 file(s) + 4 : "libcxx\include\stddef.h" line 39, impact on 11042 file(s) + 5 : "libcxx\include\inttypes.h" line 238, impact on 9937 file(s) + 6 : "libcxx\include\setjmp.h" line 28, impact on 7910 file(s) + 7 : "libcxx\test\support\test_macros.h" line 18, impact on 5744 file(s) + 8 : "libcxx\include\stdio.h" line 101, impact on 3356 file(s) + 9 : "libcxx\include\string.h" line 54, impact on 1882 file(s) + 10 : "libcxx\include\limits.h" line 40, impact on 1068 file(s) + ... 10 of 48 details +2 : "libcxx\include\type_traits" impact on 17768 file(s) Included by: - 1 : "llvm\include\llvm\Support\raw_ostream.h" line 16, impact on 3651 file(s) - 2 : "llvm\include\llvm\Support\Error.h" line 18, impact on 2427 file(s) - 3 : "llvm\include\llvm\Support\Allocator.h" line 24, impact on 1813 file(s) - 4 : "llvm\include\llvm\Support\SourceMgr.h" line 21, impact on 940 file(s) - 5 : "llvm\include\llvm\Support\VirtualFileSystem.h" line 20, impact on 652 file(s) - 6 : "llvm\include\llvm\ADT\MapVector.h" line 20, impact on 523 file(s) - 7 : "clang\include\clang\AST\Expr.h" line 33, impact on 456 file(s) - 8 : "clang\include\clang\Basic\FileManager.h" line 21, impact on 409 file(s) - 9 : "clang\include\clang\Basic\SourceManager.h" line 46, impact on 382 file(s) - 10 : "llvm\include\llvm\ADT\TinyPtrVector.h" line 15, impact on 381 file(s) - ... 10 of 698 details -3 : "llvm\include\llvm\Support\raw_ostream.h" impact on 3651 file(s) + 1 : "libcxx\include\math.h" line 311, impact on 17505 file(s) + 2 : "llvm\include\llvm\Support\type_traits.h" line 17, impact on 9534 file(s) + 3 : "llvm\include\llvm\ADT\iterator.h" line 16, impact on 9419 file(s) + 4 : "llvm\include\llvm\ADT\STLExtras.h" line 35, impact on 9405 file(s) + 5 : "llvm\include\llvm\Support\SwapByteOrder.h" line 20, impact on 9323 file(s) + 6 : "llvm\include\llvm\ADT\StringRef.h" line 21, impact on 9312 file(s) + 7 : "llvm\include\llvm\Support\MathExtras.h" line 23, impact on 9305 file(s) + 8 : "llvm\include\llvm\ADT\SmallVector.h" line 32, impact on 9242 file(s) + 9 : "llvm\include\llvm\ADT\ArrayRef.h" line 24, impact on 8875 file(s) + 10 : "llvm\include\llvm\Support\PointerLikeTypeTraits.h" line 19, impact on 8498 file(s) + ... 10 of 1372 details +3 : "libcxx\include\limits" impact on 17677 file(s) Included by: - 1 : "llvm\include\llvm\Support\Error.h" line 28, impact on 2427 file(s) - 2 : "lldb\include\lldb\Utility\Stream.h" line 17, impact on 355 file(s) - 3 : "clang\include\clang\AST\Attr.h" line 30, impact on 225 file(s) - 4 : "llvm\include\llvm\Support\EndianStream.h" line 19, impact on 117 file(s) - 5 : "llvm\include\llvm\Support\JSON.h" line 54, impact on 88 file(s) - 6 : "llvm\include\llvm\MC\MCObjectWriter.h" line 17, impact on 85 file(s) - 7 : "llvm\include\llvm\Support\ScopedPrinter.h" line 18, impact on 83 file(s) - 8 : "clang-tools-extra\clangd\Protocol.h" line 31, impact on 64 file(s) - 9 : "llvm\include\llvm\Support\LEB128.h" line 17, impact on 58 file(s) - 10 : "llvm\include\llvm\Support\FormattedStream.h" line 17, impact on 52 file(s) - ... 10 of 1274 details -4 : "llvm\include\llvm\ADT\Optional.h" impact on 2562 file(s) + 1 : "libcxx\include\math.h" line 312, impact on 17505 file(s) + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 32, impact on 9405 file(s) + 3 : "llvm\include\llvm\ADT\StringRef.h" line 19, impact on 9312 file(s) + 4 : "llvm\include\llvm\Support\MathExtras.h" line 22, impact on 9305 file(s) + 5 : "llvm\include\llvm\Support\Alignment.h" line 28, impact on 8063 file(s) + 6 : "llvm\include\llvm\ADT\PointerIntPair.h" line 21, impact on 6760 file(s) + 7 : "clang\include\clang\Basic\Diagnostic.h" line 31, impact on 2055 file(s) + 8 : "llvm\include\llvm\ADT\SmallBitVector.h" line 24, impact on 1103 file(s) + 9 : "llvm\include\llvm\ADT\SparseSet.h" line 28, impact on 746 file(s) + 10 : "clang\include\clang\ASTMatchers\ASTMatchers.h" line 89, impact on 695 file(s) + ... 10 of 379 details +4 : "libcxx\include\math.h" impact on 17505 file(s) Included by: - 1 : "llvm\include\llvm\Support\Allocator.h" line 23, impact on 1813 file(s) - 2 : "llvm\include\llvm\Support\VirtualFileSystem.h" line 19, impact on 652 file(s) - 3 : "clang\include\clang\AST\Decl.h" line 38, impact on 541 file(s) - 4 : "clang\include\clang\Lex\Lexer.h" line 21, impact on 336 file(s) - 5 : "clang\include\clang\AST\ExprCXX.h" line 40, impact on 287 file(s) - 6 : "clang\include\clang\AST\ExprObjC.h" line 29, impact on 260 file(s) - 7 : "clang\include\clang\Lex\Preprocessor.h" line 38, impact on 229 file(s) - 8 : "llvm\include\llvm\MC\MCStreamer.h" line 18, impact on 207 file(s) - 9 : "llvm\include\llvm\ADT\PostOrderIterator.h" line 19, impact on 170 file(s) - 10 : "llvm\include\llvm\Analysis\ScalarEvolution.h" line 29, impact on 107 file(s) - ... 10 of 280 details -5 : "llvm\include\llvm-c\ExternC.h" impact on 2474 file(s) + 1 : "libcxx\include\stdlib.h" line 100, impact on 17505 file(s) + 2 : "llvm\include\llvm-c\DataTypes.h" line 30, impact on 9481 file(s) + 3 : "compiler-rt\lib\builtins\int_math.h" line 27, impact on 66 file(s) + 4 : "openmp\runtime\src\kmp_stats.h" line 30, impact on 18 file(s) + 5 : "compiler-rt\lib\msan\tests\msan_test.cpp" line 41 + 6 : "compiler-rt\test\asan\TestCases\frexp_interceptor.cpp" line 5 + 7 : "compiler-rt\test\builtins\Unit\adddf3vfp_test.c" line 18 + 8 : "compiler-rt\test\builtins\Unit\addsf3vfp_test.c" line 18 + 9 : "compiler-rt\test\builtins\Unit\arm\aeabi_cdcmpeq_test.c" line 19 + 10 : "compiler-rt\test\builtins\Unit\arm\aeabi_cdcmple_test.c" line 21 + ... 10 of 127 details +5 : "libcxx\include\stdlib.h" impact on 17505 file(s) Included by: - 1 : "llvm\include\llvm-c\Error.h" line 17, impact on 2429 file(s) - 2 : "llvm\include\llvm-c\Disassembler.h" line 19, impact on 18 file(s) - 3 : "llvm\include\llvm-c\Initialization.h" line 19, impact on 12 file(s) - 4 : "llvm\include\llvm-c\BitReader.h" line 22, impact on 5 file(s) - 5 : "llvm\include\llvm-c\Linker.h" line 17, impact on 4 file(s) - 6 : "llvm\include\llvm-c\Transforms\PassManagerBuilder.h" line 17, impact on 4 file(s) - 7 : "llvm\include\llvm-c\Transforms\Scalar.h" line 22, impact on 4 file(s) - 8 : "llvm\include\llvm-c\BitWriter.h" line 22, impact on 3 file(s) - 9 : "llvm\include\llvm-c\IRReader.h" line 17, impact on 3 file(s) - 10 : "llvm\include\llvm-c\Transforms\IPO.h" line 18, impact on 3 file(s) - ... 10 of 11 details -6 : "llvm\include\llvm\Support\ErrorOr.h" impact on 2465 file(s) + 1 : "libcxx\include\math.h" line 301, impact on 17505 file(s) + 2 : "llvm\include\llvm-c\DataTypes.h" line 63, impact on 9481 file(s) + 3 : "llvm\include\llvm\Support\SwapByteOrder.h" line 22, impact on 9323 file(s) + 4 : "clang\lib\Headers\mm_malloc.h" line 13, impact on 7943 file(s) + 5 : "libcxx\test\support\test_macros.h" line 301, impact on 5744 file(s) + 6 : "polly\lib\External\isl\include\isl\arg.h" line 14, impact on 316 file(s) + 7 : "polly\lib\External\isl\include\isl\ctx.h" line 14, impact on 315 file(s) + 8 : "compiler-rt\test\tsan\test.h" line 2, impact on 169 file(s) + 9 : "llgo\third_party\gofrontend\libffi\testsuite\libffi.call\ffitest.h" line 1, impact on 144 file(s) + 10 : "libcxx\test\support\platform_support.h" line 55, impact on 137 file(s) + ... 10 of 1003 details +6 : "libcxx\include\cassert" impact on 14768 file(s) Included by: - 1 : "llvm\include\llvm\Support\Error.h" line 26, impact on 2427 file(s) - 2 : "llvm\include\llvm\Support\FileSystem.h" line 36, impact on 1520 file(s) - 3 : "llvm\include\llvm\Support\MemoryBuffer.h" line 21, impact on 1380 file(s) - 4 : "llvm\include\llvm\Support\VirtualFileSystem.h" line 24, impact on 652 file(s) - 5 : "clang\include\clang\Basic\FileManager.h" line 25, impact on 409 file(s) - 6 : "llvm\include\llvm\Support\Program.h" line 20, impact on 91 file(s) - 7 : "llvm\include\llvm\Bitcode\BitcodeReader.h" line 22, impact on 36 file(s) - 8 : "llvm\tools\dsymutil\DebugMap.h" line 32, impact on 7 file(s) - 9 : "llvm\include\llvm\ProfileData\SampleProfReader.h" line 222, impact on 5 file(s) - 10 : "llvm\include\llvm\DebugInfo\CodeView\CVSymbolVisitor.h" line 16, impact on 4 file(s) - ... 10 of 67 details -7 : "llvm\include\llvm-c\Error.h" impact on 2429 file(s) + 1 : "llvm\include\llvm\ADT\Optional.h" line 21, impact on 9448 file(s) + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 25, impact on 9405 file(s) + 3 : "llvm\include\llvm\ADT\StringRef.h" line 16, impact on 9312 file(s) + 4 : "llvm\include\llvm\Support\MathExtras.h" line 19, impact on 9305 file(s) + 5 : "llvm\include\llvm\ADT\SmallVector.h" line 24, impact on 9242 file(s) + 6 : "llvm\include\llvm\ADT\Hashing.h" line 52, impact on 8901 file(s) + 7 : "llvm\include\llvm\ADT\ArrayRef.h" line 19, impact on 8875 file(s) + 8 : "llvm\include\llvm\ADT\Twine.h" line 15, impact on 8386 file(s) + 9 : "llvm\include\llvm\Support\raw_ostream.h" line 18, impact on 8269 file(s) + 10 : "llvm\include\llvm\Support\Alignment.h" line 27, impact on 8063 file(s) + ... 10 of 6042 details +7 : "libcxx\include\cstddef" impact on 11856 file(s) Included by: - 1 : "llvm\include\llvm\Support\Error.h" line 16, impact on 2427 file(s) - 2 : "llvm\tools\llvm-c-test\include-all.c" line 26 - 3 : "llvm\unittests\Support\ErrorTest.cpp" line 10 -8 : "llvm\include\llvm\Support\Error.h" impact on 2427 file(s) + 1 : "llvm\include\llvm-c\DataTypes.h" line 59, impact on 9481 file(s) + 2 : "llvm\include\llvm\ADT\iterator.h" line 14, impact on 9419 file(s) + 3 : "llvm\include\llvm\ADT\STLExtras.h" line 26, impact on 9405 file(s) + 4 : "llvm\include\llvm\Support\SwapByteOrder.h" line 19, impact on 9323 file(s) + 5 : "llvm\include\llvm\ADT\StringRef.h" line 17, impact on 9312 file(s) + 6 : "llvm\include\llvm\Support\AlignOf.h" line 17, impact on 9249 file(s) + 7 : "llvm\include\llvm\ADT\SmallVector.h" line 25, impact on 9242 file(s) + 8 : "llvm\include\llvm\ADT\ArrayRef.h" line 20, impact on 8875 file(s) + 9 : "llvm\include\llvm\Support\raw_ostream.h" line 19, impact on 8269 file(s) + 10 : "llvm\include\llvm\ADT\SmallString.h" line 18, impact on 8032 file(s) + ... 10 of 890 details +8 : "libcxx\include\stdint.h" impact on 11752 file(s) Included by: - 1 : "llvm\include\llvm\Support\FileSystem.h" line 34, impact on 1520 file(s) - 2 : "llvm\include\llvm\Support\DataExtractor.h" line 14, impact on 250 file(s) - 3 : "llvm\include\llvm\MC\MCStreamer.h" line 25, impact on 207 file(s) - 4 : "llvm\include\llvm\Support\FileOutputBuffer.h" line 19, impact on 188 file(s) - 5 : "llvm\include\llvm\Support\BinaryStreamError.h" line 13, impact on 185 file(s) - 6 : "llvm\include\llvm\Support\BinaryStream.h" line 16, impact on 150 file(s) - 7 : "lldb\include\lldb\Symbol\TypeSystem.h" line 21, impact on 145 file(s) - 8 : "clang\include\clang\Frontend\FrontendAction.h" line 26, impact on 142 file(s) - 9 : "lldb\include\lldb\Utility\Reproducer.h" line 14, impact on 130 file(s) - 10 : "llvm\include\llvm\Support\BinaryByteStream.h" line 17, impact on 126 file(s) - ... 10 of 382 details -9 : "llvm\include\llvm\Support\ReverseIteration.h" impact on 2297 file(s) + 1 : "compiler-rt\include\sanitizer\common_interface_defs.h" line 16, impact on 10001 file(s) + 2 : "libcxx\include\inttypes.h" line 255, impact on 9937 file(s) + 3 : "llvm\include\llvm-c\DataTypes.h" line 34, impact on 9481 file(s) + 4 : "lldb\include\lldb\lldb-types.h" line 15, impact on 1722 file(s) + 5 : "llvm\include\llvm\IR\FPEnv.h" line 20, impact on 1196 file(s) + 6 : "lldb\include\lldb\Utility\Status.h" line 18, impact on 1129 file(s) + 7 : "lldb\include\lldb\Utility\FileSpec.h" line 23, impact on 1128 file(s) + 8 : "lldb\include\lldb\Utility\Stream.h" line 21, impact on 983 file(s) + 9 : "lldb\include\lldb\Core\Address.h" line 18, impact on 845 file(s) + 10 : "lldb\include\lldb\Utility\Endian.h" line 14, impact on 751 file(s) + ... 10 of 430 details +9 : "libcxx\include\memory" impact on 11478 file(s) Included by: - 1 : "llvm\include\llvm\ADT\DenseMap.h" line 21, impact on 2296 file(s) - 2 : "llvm\unittests\Support\ReverseIterationTest.cpp" line 13 -10 : "llvm\include\llvm\ADT\DenseMap.h" impact on 2296 file(s) + 1 : "llvm\include\llvm\ADT\Optional.h" line 22, impact on 9448 file(s) + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 33, impact on 9405 file(s) + 3 : "llvm\include\llvm\ADT\SmallVector.h" line 30, impact on 9242 file(s) + 4 : "llvm\include\llvm\ADT\ArrayRef.h" line 23, impact on 8875 file(s) + 5 : "llvm\include\llvm\Support\Casting.h" line 20, impact on 7366 file(s) + 6 : "llvm\include\llvm\Support\Error.h" line 34, impact on 6869 file(s) + 7 : "llvm\include\llvm\Support\FileSystem.h" line 41, impact on 5728 file(s) + 8 : "llvm\include\llvm\ADT\APFloat.h" line 22, impact on 5376 file(s) + 9 : "llvm\include\llvm\Support\MemoryBuffer.h" line 25, impact on 5178 file(s) + 10 : "llvm\include\llvm\Support\SourceMgr.h" line 28, impact on 4601 file(s) + ... 10 of 1310 details +10 : "libcxx\include\cstdlib" impact on 11439 file(s) Included by: - 1 : "llvm\include\llvm\ADT\MapVector.h" line 19, impact on 523 file(s) - 2 : "clang\include\clang\Basic\FileManager.h" line 19, impact on 409 file(s) - 3 : "clang\include\clang\AST\DeclCXX.h" line 39, impact on 396 file(s) - 4 : "clang\include\clang\Basic\SourceManager.h" line 42, impact on 382 file(s) - 5 : "clang\include\clang\AST\DeclObjC.h" line 27, impact on 324 file(s) - 6 : "llvm\include\llvm\MC\MCExpr.h" line 12, impact on 284 file(s) - 7 : "clang\include\clang\Lex\ModuleMap.h" line 22, impact on 252 file(s) - 8 : "clang\include\clang\Lex\Preprocessor.h" line 34, impact on 229 file(s) - 9 : "llvm\include\llvm\MC\MCStreamer.h" line 17, impact on 207 file(s) - 10 : "lldb\include\lldb\Utility\UserIDResolver.h" line 12, impact on 165 file(s) - ... 10 of 390 details -... 10 of 2076 files + 1 : "llvm\include\llvm-c\DataTypes.h" line 60, impact on 9481 file(s) + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 28, impact on 9405 file(s) + 3 : "llvm\include\llvm\Support\MemAlloc.h" line 21, impact on 9243 file(s) + 4 : "llvm\include\llvm\ADT\SmallVector.h" line 26, impact on 9242 file(s) + 5 : "llvm\include\llvm\Support\Allocator.h" line 34, impact on 8025 file(s) + 6 : "llvm\include\llvm\ADT\StringMap.h" line 25, impact on 7738 file(s) + 7 : "llvm\include\llvm\ADT\StringExtras.h" line 23, impact on 6930 file(s) + 8 : "llvm\include\llvm\Support\Error.h" line 32, impact on 6869 file(s) + 9 : "llvm\include\llvm\ADT\SmallPtrSet.h" line 23, impact on 5164 file(s) + 10 : "llvm\include\llvm\ADT\BitVector.h" line 23, impact on 4074 file(s) + ... 10 of 570 details +... 10 of 5975 files +Unincluded headers: +1 : "clang\include\clang\Analysis\AnalysisDiagnostic.h" +2 : "clang\include\clang\Analysis\FlowSensitive\DataflowValues.h" +3 : "clang\include\clang\StaticAnalyzer\Core\PathSensitive\SummaryManager.h" +4 : "clang\lib\Headers\__clang_cuda_runtime_wrapper.h" +5 : "clang\lib\Headers\arm_cmse.h" +6 : "clang\lib\Headers\float.h" +7 : "clang\lib\Headers\htmxlintrin.h" +8 : "clang\lib\Headers\inttypes.h" +9 : "clang\lib\Headers\limits.h" +10 : "clang\lib\Headers\msa.h" +... 10 of 210 files diff --git a/docs/examples/lua/.cppinclude.json b/docs/examples/lua/.cppinclude.json index 970b515..2cc4731 100644 --- a/docs/examples/lua/.cppinclude.json +++ b/docs/examples/lua/.cppinclude.json @@ -8,5 +8,8 @@ "luac.c", "readline/.*", "sys/.*" - ] + ], + + "report_limit" : 30, + "report_details_limit" : 30 } diff --git a/docs/examples/lua/output_unix.txt b/docs/examples/lua/output_unix.txt index ec407e7..151bc8f 100644 --- a/docs/examples/lua/output_unix.txt +++ b/docs/examples/lua/output_unix.txt @@ -18,7 +18,27 @@ Included by: 8 : "lapi.c" line 17, impact on 1 file(s) 9 : "lauxlib.c" line 25, impact on 1 file(s) 10 : "lbaselib.c" line 18, impact on 1 file(s) - ... 10 of 44 details + 11 : "lcode.c" line 17, impact on 1 file(s) + 12 : "lcorolib.c" line 15, impact on 1 file(s) + 13 : "ldblib.c" line 17, impact on 1 file(s) + 14 : "ldebug.c" line 17, impact on 1 file(s) + 15 : "ldo.c" line 17, impact on 1 file(s) + 16 : "ldump.c" line 15, impact on 1 file(s) + 17 : "lfunc.c" line 15, impact on 1 file(s) + 18 : "lgc.c" line 16, impact on 1 file(s) + 19 : "linit.c" line 32, impact on 1 file(s) + 20 : "liolib.c" line 20, impact on 1 file(s) + 21 : "llex.c" line 16, impact on 1 file(s) + 22 : "lmathlib.c" line 19, impact on 1 file(s) + 23 : "lmem.c" line 15, impact on 1 file(s) + 24 : "loadlib.c" line 21, impact on 1 file(s) + 25 : "lobject.c" line 20, impact on 1 file(s) + 26 : "loslib.c" line 19, impact on 1 file(s) + 27 : "lparser.c" line 16, impact on 1 file(s) + 28 : "lstate.c" line 16, impact on 1 file(s) + 29 : "lstring.c" line 15, impact on 1 file(s) + 30 : "lstrlib.c" line 23, impact on 1 file(s) + ... 30 of 44 details 3 : "llimits.h" impact on 40 file(s) Included by: 1 : "lobject.h" line 15, impact on 34 file(s) @@ -41,7 +61,27 @@ Included by: 8 : "ldebug.c" line 10, impact on 1 file(s) 9 : "ldo.c" line 10, impact on 1 file(s) 10 : "ldump.c" line 10, impact on 1 file(s) - ... 10 of 35 details + 11 : "lfunc.c" line 10, impact on 1 file(s) + 12 : "lgc.c" line 10, impact on 1 file(s) + 13 : "linit.c" line 27, impact on 1 file(s) + 14 : "liolib.c" line 10, impact on 1 file(s) + 15 : "llex.c" line 10, impact on 1 file(s) + 16 : "lmathlib.c" line 10, impact on 1 file(s) + 17 : "lmem.c" line 10, impact on 1 file(s) + 18 : "loadlib.c" line 14, impact on 1 file(s) + 19 : "lobject.c" line 10, impact on 1 file(s) + 20 : "lopcodes.c" line 10, impact on 1 file(s) + 21 : "loslib.c" line 10, impact on 1 file(s) + 22 : "lparser.c" line 10, impact on 1 file(s) + 23 : "lstate.c" line 10, impact on 1 file(s) + 24 : "lstring.c" line 10, impact on 1 file(s) + 25 : "lstrlib.c" line 10, impact on 1 file(s) + 26 : "ltable.c" line 10, impact on 1 file(s) + 27 : "ltablib.c" line 10, impact on 1 file(s) + 28 : "ltm.c" line 10, impact on 1 file(s) + 29 : "lua.c" line 9, impact on 1 file(s) + 30 : "lundump.c" line 10, impact on 1 file(s) + ... 30 of 35 details 5 : "lobject.h" impact on 34 file(s) Included by: 1 : "ltm.h" line 11, impact on 27 file(s) @@ -54,7 +94,24 @@ Included by: 8 : "lvm.h" line 12, impact on 9 file(s) 9 : "llex.h" line 10, impact on 8 file(s) 10 : "lparser.h" line 11, impact on 8 file(s) - ... 10 of 28 details + 11 : "lcode.h" line 11, impact on 5 file(s) + 12 : "lundump.h" line 11, impact on 5 file(s) + 13 : "lapi.c" line 25, impact on 1 file(s) + 14 : "lcode.c" line 25, impact on 1 file(s) + 15 : "ldebug.c" line 24, impact on 1 file(s) + 16 : "ldo.c" line 25, impact on 1 file(s) + 17 : "ldump.c" line 17, impact on 1 file(s) + 18 : "lfunc.c" line 22, impact on 1 file(s) + 19 : "lgc.c" line 23, impact on 1 file(s) + 20 : "llex.c" line 23, impact on 1 file(s) + 21 : "lmem.c" line 21, impact on 1 file(s) + 22 : "lobject.c" line 26, impact on 1 file(s) + 23 : "lparser.c" line 24, impact on 1 file(s) + 24 : "lstring.c" line 20, impact on 1 file(s) + 25 : "ltable.c" line 35, impact on 1 file(s) + 26 : "ltm.c" line 20, impact on 1 file(s) + 27 : "lundump.c" line 22, impact on 1 file(s) + 28 : "lvm.c" line 25, impact on 1 file(s) 6 : "ltm.h" impact on 27 file(s) Included by: 1 : "lstate.h" line 13, impact on 26 file(s) @@ -78,7 +135,18 @@ Included by: 8 : "ldo.c" line 28, impact on 1 file(s) 9 : "ldump.c" line 18, impact on 1 file(s) 10 : "lfunc.c" line 23, impact on 1 file(s) - ... 10 of 22 details + 11 : "lgc.c" line 24, impact on 1 file(s) + 12 : "llex.c" line 25, impact on 1 file(s) + 13 : "lmem.c" line 22, impact on 1 file(s) + 14 : "lobject.c" line 27, impact on 1 file(s) + 15 : "lparser.c" line 27, impact on 1 file(s) + 16 : "lstate.c" line 25, impact on 1 file(s) + 17 : "lstring.c" line 21, impact on 1 file(s) + 18 : "ltable.c" line 36, impact on 1 file(s) + 19 : "ltm.c" line 21, impact on 1 file(s) + 20 : "lvm.c" line 27, impact on 1 file(s) + 21 : "lzio.c" line 19, impact on 1 file(s) + 22 : "ltests.c" line 31 8 : "ldo.h" impact on 19 file(s) Included by: 1 : "lvm.h" line 11, impact on 9 file(s) @@ -91,7 +159,14 @@ Included by: 8 : "llex.c" line 20, impact on 1 file(s) 9 : "lmem.c" line 18, impact on 1 file(s) 10 : "lobject.c" line 24, impact on 1 file(s) - ... 10 of 18 details + 11 : "lparser.c" line 20, impact on 1 file(s) + 12 : "lstate.c" line 20, impact on 1 file(s) + 13 : "lstring.c" line 18, impact on 1 file(s) + 14 : "ltable.c" line 32, impact on 1 file(s) + 15 : "ltm.c" line 18, impact on 1 file(s) + 16 : "lundump.c" line 19, impact on 1 file(s) + 17 : "lvm.c" line 22, impact on 1 file(s) + 18 : "ltests.c" line 26 9 : "lgc.h" impact on 19 file(s) Included by: 1 : "lstring.h" line 10, impact on 16 file(s) @@ -104,7 +179,8 @@ Included by: 8 : "lmem.c" line 19, impact on 1 file(s) 9 : "lstate.c" line 22, impact on 1 file(s) 10 : "ltable.c" line 33, impact on 1 file(s) - ... 10 of 12 details + 11 : "ltm.c" line 19, impact on 1 file(s) + 12 : "lvm.c" line 24, impact on 1 file(s) 10 : "lauxlib.h" impact on 18 file(s) Included by: 1 : "lauxlib.c" line 27, impact on 1 file(s) @@ -117,5 +193,183 @@ Included by: 8 : "loadlib.c" line 23, impact on 1 file(s) 9 : "loslib.c" line 21, impact on 1 file(s) 10 : "lstrlib.c" line 25, impact on 1 file(s) - ... 10 of 17 details -... 10 of 59 files + 11 : "ltablib.c" line 19, impact on 1 file(s) + 12 : "lua.c" line 20, impact on 1 file(s) + 13 : "lutf8lib.c" line 20, impact on 1 file(s) + 14 : "ltests.c" line 22 + 15 : "testes/libs/lib1.c" line 2 + 16 : "testes/libs/lib2.c" line 2 + 17 : "testes/libs/lib22.c" line 2 +11 : "ldebug.h" impact on 18 file(s) +Included by: + 1 : "lapi.c" line 20, impact on 1 file(s) + 2 : "lcode.c" line 20, impact on 1 file(s) + 3 : "ldebug.c" line 21, impact on 1 file(s) + 4 : "ldo.c" line 20, impact on 1 file(s) + 5 : "lfunc.c" line 17, impact on 1 file(s) + 6 : "lgc.c" line 18, impact on 1 file(s) + 7 : "llex.c" line 19, impact on 1 file(s) + 8 : "lmem.c" line 17, impact on 1 file(s) + 9 : "lobject.c" line 23, impact on 1 file(s) + 10 : "lparser.c" line 19, impact on 1 file(s) + 11 : "lstate.c" line 19, impact on 1 file(s) + 12 : "lstring.c" line 17, impact on 1 file(s) + 13 : "ltable.c" line 31, impact on 1 file(s) + 14 : "ltm.c" line 17, impact on 1 file(s) + 15 : "lundump.c" line 18, impact on 1 file(s) + 16 : "lvm.c" line 21, impact on 1 file(s) + 17 : "ltests.c" line 25 +12 : "lstring.h" impact on 16 file(s) +Included by: + 1 : "lapi.c" line 27, impact on 1 file(s) + 2 : "lcode.c" line 28, impact on 1 file(s) + 3 : "ldebug.c" line 27, impact on 1 file(s) + 4 : "ldo.c" line 29, impact on 1 file(s) + 5 : "lgc.c" line 25, impact on 1 file(s) + 6 : "llex.c" line 26, impact on 1 file(s) + 7 : "lobject.c" line 28, impact on 1 file(s) + 8 : "lparser.c" line 28, impact on 1 file(s) + 9 : "lstate.c" line 26, impact on 1 file(s) + 10 : "lstring.c" line 22, impact on 1 file(s) + 11 : "ltable.c" line 37, impact on 1 file(s) + 12 : "ltm.c" line 22, impact on 1 file(s) + 13 : "lundump.c" line 23, impact on 1 file(s) + 14 : "lvm.c" line 28, impact on 1 file(s) + 15 : "ltests.c" line 32 +13 : "lmem.h" impact on 15 file(s) +Included by: + 1 : "lapi.c" line 24, impact on 1 file(s) + 2 : "lcode.c" line 24, impact on 1 file(s) + 3 : "ldo.c" line 24, impact on 1 file(s) + 4 : "lfunc.c" line 21, impact on 1 file(s) + 5 : "lgc.c" line 22, impact on 1 file(s) + 6 : "lmem.c" line 20, impact on 1 file(s) + 7 : "lobject.c" line 25, impact on 1 file(s) + 8 : "lparser.c" line 23, impact on 1 file(s) + 9 : "lstate.c" line 24, impact on 1 file(s) + 10 : "lstring.c" line 19, impact on 1 file(s) + 11 : "ltable.c" line 34, impact on 1 file(s) + 12 : "lundump.c" line 21, impact on 1 file(s) + 13 : "lzio.c" line 18, impact on 1 file(s) + 14 : "ltests.c" line 28 +14 : "lualib.h" impact on 14 file(s) +Included by: + 1 : "lbaselib.c" line 21, impact on 1 file(s) + 2 : "lcorolib.c" line 18, impact on 1 file(s) + 3 : "ldblib.c" line 20, impact on 1 file(s) + 4 : "linit.c" line 34, impact on 1 file(s) + 5 : "liolib.c" line 23, impact on 1 file(s) + 6 : "lmathlib.c" line 22, impact on 1 file(s) + 7 : "loadlib.c" line 24, impact on 1 file(s) + 8 : "loslib.c" line 22, impact on 1 file(s) + 9 : "lstrlib.c" line 26, impact on 1 file(s) + 10 : "ltablib.c" line 20, impact on 1 file(s) + 11 : "lua.c" line 21, impact on 1 file(s) + 12 : "lutf8lib.c" line 21, impact on 1 file(s) + 13 : "ltests.c" line 34 +15 : "ltable.h" impact on 13 file(s) +Included by: + 1 : "lapi.c" line 28, impact on 1 file(s) + 2 : "lcode.c" line 29, impact on 1 file(s) + 3 : "ldebug.c" line 28, impact on 1 file(s) + 4 : "ldo.c" line 30, impact on 1 file(s) + 5 : "lgc.c" line 26, impact on 1 file(s) + 6 : "llex.c" line 27, impact on 1 file(s) + 7 : "lparser.c" line 29, impact on 1 file(s) + 8 : "lstate.c" line 27, impact on 1 file(s) + 9 : "ltable.c" line 38, impact on 1 file(s) + 10 : "ltm.c" line 23, impact on 1 file(s) + 11 : "lvm.c" line 29, impact on 1 file(s) + 12 : "ltests.c" line 33 +16 : "lfunc.h" impact on 11 file(s) +Included by: + 1 : "lapi.c" line 22, impact on 1 file(s) + 2 : "ldebug.c" line 23, impact on 1 file(s) + 3 : "ldo.c" line 22, impact on 1 file(s) + 4 : "lfunc.c" line 19, impact on 1 file(s) + 5 : "lgc.c" line 20, impact on 1 file(s) + 6 : "lparser.c" line 21, impact on 1 file(s) + 7 : "lstate.c" line 21, impact on 1 file(s) + 8 : "lundump.c" line 20, impact on 1 file(s) + 9 : "lvm.c" line 23, impact on 1 file(s) + 10 : "ltests.c" line 27 +17 : "lopcodes.h" impact on 9 file(s) +Included by: + 1 : "lcode.h" line 12, impact on 5 file(s) + 2 : "lcode.c" line 26, impact on 1 file(s) + 3 : "ldebug.c" line 25, impact on 1 file(s) + 4 : "ldo.c" line 26, impact on 1 file(s) + 5 : "lopcodes.c" line 13, impact on 1 file(s) + 6 : "lparser.c" line 25, impact on 1 file(s) + 7 : "lvm.c" line 26, impact on 1 file(s) + 8 : "ltests.c" line 29 +18 : "lvm.h" impact on 9 file(s) +Included by: + 1 : "lapi.c" line 31, impact on 1 file(s) + 2 : "lcode.c" line 30, impact on 1 file(s) + 3 : "ldebug.c" line 30, impact on 1 file(s) + 4 : "ldo.c" line 33, impact on 1 file(s) + 5 : "lobject.c" line 29, impact on 1 file(s) + 6 : "ltable.c" line 39, impact on 1 file(s) + 7 : "ltm.c" line 25, impact on 1 file(s) + 8 : "lvm.c" line 31, impact on 1 file(s) +19 : "llex.h" impact on 8 file(s) +Included by: + 1 : "lcode.h" line 10, impact on 5 file(s) + 2 : "lcode.c" line 23, impact on 1 file(s) + 3 : "llex.c" line 22, impact on 1 file(s) + 4 : "lparser.c" line 22, impact on 1 file(s) + 5 : "lstate.c" line 23, impact on 1 file(s) +20 : "lparser.h" impact on 8 file(s) +Included by: + 1 : "lcode.h" line 13, impact on 5 file(s) + 2 : "lcode.c" line 27, impact on 1 file(s) + 3 : "ldo.c" line 27, impact on 1 file(s) + 4 : "llex.c" line 24, impact on 1 file(s) + 5 : "lparser.c" line 26, impact on 1 file(s) +21 : "lapi.h" impact on 6 file(s) +Included by: + 1 : "lapi.c" line 19, impact on 1 file(s) + 2 : "ldebug.c" line 19, impact on 1 file(s) + 3 : "ldo.c" line 19, impact on 1 file(s) + 4 : "lstate.c" line 18, impact on 1 file(s) + 5 : "ltests.c" line 21 +22 : "lcode.h" impact on 5 file(s) +Included by: + 1 : "lcode.c" line 19, impact on 1 file(s) + 2 : "ldebug.c" line 20, impact on 1 file(s) + 3 : "lparser.c" line 18, impact on 1 file(s) + 4 : "ltests.c" line 23 +23 : "lctype.h" impact on 5 file(s) +Included by: + 1 : "lctype.c" line 13, impact on 1 file(s) + 2 : "llex.c" line 18, impact on 1 file(s) + 3 : "lobject.c" line 22, impact on 1 file(s) + 4 : "ltests.c" line 24 +24 : "lundump.h" impact on 5 file(s) +Included by: + 1 : "lapi.c" line 30, impact on 1 file(s) + 2 : "ldo.c" line 32, impact on 1 file(s) + 3 : "ldump.c" line 19, impact on 1 file(s) + 4 : "lundump.c" line 24, impact on 1 file(s) +25 : "ljumptab.h" impact on 2 file(s) +Included by: + 1 : "lvm.c" line 1134, impact on 1 file(s) +26 : "lapi.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 79 +27 : "lauxlib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 82 +28 : "lbaselib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 86 +29 : "lcode.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 69 +30 : "lcorolib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 87 +... 30 of 59 files +Unincluded headers: +1 : "ltests.h" diff --git a/docs/examples/lua/output_win.txt b/docs/examples/lua/output_win.txt index e90a3e9..f55ae49 100644 --- a/docs/examples/lua/output_win.txt +++ b/docs/examples/lua/output_win.txt @@ -18,7 +18,27 @@ Included by: 8 : "lapi.c" line 17, impact on 1 file(s) 9 : "lauxlib.c" line 25, impact on 1 file(s) 10 : "lbaselib.c" line 18, impact on 1 file(s) - ... 10 of 44 details + 11 : "lcode.c" line 17, impact on 1 file(s) + 12 : "lcorolib.c" line 15, impact on 1 file(s) + 13 : "ldblib.c" line 17, impact on 1 file(s) + 14 : "ldebug.c" line 17, impact on 1 file(s) + 15 : "ldo.c" line 17, impact on 1 file(s) + 16 : "ldump.c" line 15, impact on 1 file(s) + 17 : "lfunc.c" line 15, impact on 1 file(s) + 18 : "lgc.c" line 16, impact on 1 file(s) + 19 : "linit.c" line 32, impact on 1 file(s) + 20 : "liolib.c" line 20, impact on 1 file(s) + 21 : "llex.c" line 16, impact on 1 file(s) + 22 : "lmathlib.c" line 19, impact on 1 file(s) + 23 : "lmem.c" line 15, impact on 1 file(s) + 24 : "loadlib.c" line 21, impact on 1 file(s) + 25 : "lobject.c" line 20, impact on 1 file(s) + 26 : "loslib.c" line 19, impact on 1 file(s) + 27 : "lparser.c" line 16, impact on 1 file(s) + 28 : "lstate.c" line 16, impact on 1 file(s) + 29 : "lstring.c" line 15, impact on 1 file(s) + 30 : "lstrlib.c" line 23, impact on 1 file(s) + ... 30 of 44 details 3 : "llimits.h" impact on 40 file(s) Included by: 1 : "lobject.h" line 15, impact on 34 file(s) @@ -41,7 +61,27 @@ Included by: 8 : "ldebug.c" line 10, impact on 1 file(s) 9 : "ldo.c" line 10, impact on 1 file(s) 10 : "ldump.c" line 10, impact on 1 file(s) - ... 10 of 35 details + 11 : "lfunc.c" line 10, impact on 1 file(s) + 12 : "lgc.c" line 10, impact on 1 file(s) + 13 : "linit.c" line 27, impact on 1 file(s) + 14 : "liolib.c" line 10, impact on 1 file(s) + 15 : "llex.c" line 10, impact on 1 file(s) + 16 : "lmathlib.c" line 10, impact on 1 file(s) + 17 : "lmem.c" line 10, impact on 1 file(s) + 18 : "loadlib.c" line 14, impact on 1 file(s) + 19 : "lobject.c" line 10, impact on 1 file(s) + 20 : "lopcodes.c" line 10, impact on 1 file(s) + 21 : "loslib.c" line 10, impact on 1 file(s) + 22 : "lparser.c" line 10, impact on 1 file(s) + 23 : "lstate.c" line 10, impact on 1 file(s) + 24 : "lstring.c" line 10, impact on 1 file(s) + 25 : "lstrlib.c" line 10, impact on 1 file(s) + 26 : "ltable.c" line 10, impact on 1 file(s) + 27 : "ltablib.c" line 10, impact on 1 file(s) + 28 : "ltm.c" line 10, impact on 1 file(s) + 29 : "lua.c" line 9, impact on 1 file(s) + 30 : "lundump.c" line 10, impact on 1 file(s) + ... 30 of 35 details 5 : "lobject.h" impact on 34 file(s) Included by: 1 : "ltm.h" line 11, impact on 27 file(s) @@ -54,7 +94,24 @@ Included by: 8 : "lvm.h" line 12, impact on 9 file(s) 9 : "llex.h" line 10, impact on 8 file(s) 10 : "lparser.h" line 11, impact on 8 file(s) - ... 10 of 28 details + 11 : "lcode.h" line 11, impact on 5 file(s) + 12 : "lundump.h" line 11, impact on 5 file(s) + 13 : "lapi.c" line 25, impact on 1 file(s) + 14 : "lcode.c" line 25, impact on 1 file(s) + 15 : "ldebug.c" line 24, impact on 1 file(s) + 16 : "ldo.c" line 25, impact on 1 file(s) + 17 : "ldump.c" line 17, impact on 1 file(s) + 18 : "lfunc.c" line 22, impact on 1 file(s) + 19 : "lgc.c" line 23, impact on 1 file(s) + 20 : "llex.c" line 23, impact on 1 file(s) + 21 : "lmem.c" line 21, impact on 1 file(s) + 22 : "lobject.c" line 26, impact on 1 file(s) + 23 : "lparser.c" line 24, impact on 1 file(s) + 24 : "lstring.c" line 20, impact on 1 file(s) + 25 : "ltable.c" line 35, impact on 1 file(s) + 26 : "ltm.c" line 20, impact on 1 file(s) + 27 : "lundump.c" line 22, impact on 1 file(s) + 28 : "lvm.c" line 25, impact on 1 file(s) 6 : "ltm.h" impact on 27 file(s) Included by: 1 : "lstate.h" line 13, impact on 26 file(s) @@ -78,7 +135,18 @@ Included by: 8 : "ldo.c" line 28, impact on 1 file(s) 9 : "ldump.c" line 18, impact on 1 file(s) 10 : "lfunc.c" line 23, impact on 1 file(s) - ... 10 of 22 details + 11 : "lgc.c" line 24, impact on 1 file(s) + 12 : "llex.c" line 25, impact on 1 file(s) + 13 : "lmem.c" line 22, impact on 1 file(s) + 14 : "lobject.c" line 27, impact on 1 file(s) + 15 : "lparser.c" line 27, impact on 1 file(s) + 16 : "lstate.c" line 25, impact on 1 file(s) + 17 : "lstring.c" line 21, impact on 1 file(s) + 18 : "ltable.c" line 36, impact on 1 file(s) + 19 : "ltm.c" line 21, impact on 1 file(s) + 20 : "lvm.c" line 27, impact on 1 file(s) + 21 : "lzio.c" line 19, impact on 1 file(s) + 22 : "ltests.c" line 31 8 : "ldo.h" impact on 19 file(s) Included by: 1 : "lvm.h" line 11, impact on 9 file(s) @@ -91,7 +159,14 @@ Included by: 8 : "llex.c" line 20, impact on 1 file(s) 9 : "lmem.c" line 18, impact on 1 file(s) 10 : "lobject.c" line 24, impact on 1 file(s) - ... 10 of 18 details + 11 : "lparser.c" line 20, impact on 1 file(s) + 12 : "lstate.c" line 20, impact on 1 file(s) + 13 : "lstring.c" line 18, impact on 1 file(s) + 14 : "ltable.c" line 32, impact on 1 file(s) + 15 : "ltm.c" line 18, impact on 1 file(s) + 16 : "lundump.c" line 19, impact on 1 file(s) + 17 : "lvm.c" line 22, impact on 1 file(s) + 18 : "ltests.c" line 26 9 : "lgc.h" impact on 19 file(s) Included by: 1 : "lstring.h" line 10, impact on 16 file(s) @@ -104,7 +179,8 @@ Included by: 8 : "lmem.c" line 19, impact on 1 file(s) 9 : "lstate.c" line 22, impact on 1 file(s) 10 : "ltable.c" line 33, impact on 1 file(s) - ... 10 of 12 details + 11 : "ltm.c" line 19, impact on 1 file(s) + 12 : "lvm.c" line 24, impact on 1 file(s) 10 : "lauxlib.h" impact on 18 file(s) Included by: 1 : "lauxlib.c" line 27, impact on 1 file(s) @@ -117,5 +193,183 @@ Included by: 8 : "loadlib.c" line 23, impact on 1 file(s) 9 : "loslib.c" line 21, impact on 1 file(s) 10 : "lstrlib.c" line 25, impact on 1 file(s) - ... 10 of 17 details -... 10 of 59 files + 11 : "ltablib.c" line 19, impact on 1 file(s) + 12 : "lua.c" line 20, impact on 1 file(s) + 13 : "lutf8lib.c" line 20, impact on 1 file(s) + 14 : "ltests.c" line 22 + 15 : "testes\libs\lib1.c" line 2 + 16 : "testes\libs\lib2.c" line 2 + 17 : "testes\libs\lib22.c" line 2 +11 : "ldebug.h" impact on 18 file(s) +Included by: + 1 : "lapi.c" line 20, impact on 1 file(s) + 2 : "lcode.c" line 20, impact on 1 file(s) + 3 : "ldebug.c" line 21, impact on 1 file(s) + 4 : "ldo.c" line 20, impact on 1 file(s) + 5 : "lfunc.c" line 17, impact on 1 file(s) + 6 : "lgc.c" line 18, impact on 1 file(s) + 7 : "llex.c" line 19, impact on 1 file(s) + 8 : "lmem.c" line 17, impact on 1 file(s) + 9 : "lobject.c" line 23, impact on 1 file(s) + 10 : "lparser.c" line 19, impact on 1 file(s) + 11 : "lstate.c" line 19, impact on 1 file(s) + 12 : "lstring.c" line 17, impact on 1 file(s) + 13 : "ltable.c" line 31, impact on 1 file(s) + 14 : "ltm.c" line 17, impact on 1 file(s) + 15 : "lundump.c" line 18, impact on 1 file(s) + 16 : "lvm.c" line 21, impact on 1 file(s) + 17 : "ltests.c" line 25 +12 : "lstring.h" impact on 16 file(s) +Included by: + 1 : "lapi.c" line 27, impact on 1 file(s) + 2 : "lcode.c" line 28, impact on 1 file(s) + 3 : "ldebug.c" line 27, impact on 1 file(s) + 4 : "ldo.c" line 29, impact on 1 file(s) + 5 : "lgc.c" line 25, impact on 1 file(s) + 6 : "llex.c" line 26, impact on 1 file(s) + 7 : "lobject.c" line 28, impact on 1 file(s) + 8 : "lparser.c" line 28, impact on 1 file(s) + 9 : "lstate.c" line 26, impact on 1 file(s) + 10 : "lstring.c" line 22, impact on 1 file(s) + 11 : "ltable.c" line 37, impact on 1 file(s) + 12 : "ltm.c" line 22, impact on 1 file(s) + 13 : "lundump.c" line 23, impact on 1 file(s) + 14 : "lvm.c" line 28, impact on 1 file(s) + 15 : "ltests.c" line 32 +13 : "lmem.h" impact on 15 file(s) +Included by: + 1 : "lapi.c" line 24, impact on 1 file(s) + 2 : "lcode.c" line 24, impact on 1 file(s) + 3 : "ldo.c" line 24, impact on 1 file(s) + 4 : "lfunc.c" line 21, impact on 1 file(s) + 5 : "lgc.c" line 22, impact on 1 file(s) + 6 : "lmem.c" line 20, impact on 1 file(s) + 7 : "lobject.c" line 25, impact on 1 file(s) + 8 : "lparser.c" line 23, impact on 1 file(s) + 9 : "lstate.c" line 24, impact on 1 file(s) + 10 : "lstring.c" line 19, impact on 1 file(s) + 11 : "ltable.c" line 34, impact on 1 file(s) + 12 : "lundump.c" line 21, impact on 1 file(s) + 13 : "lzio.c" line 18, impact on 1 file(s) + 14 : "ltests.c" line 28 +14 : "lualib.h" impact on 14 file(s) +Included by: + 1 : "lbaselib.c" line 21, impact on 1 file(s) + 2 : "lcorolib.c" line 18, impact on 1 file(s) + 3 : "ldblib.c" line 20, impact on 1 file(s) + 4 : "linit.c" line 34, impact on 1 file(s) + 5 : "liolib.c" line 23, impact on 1 file(s) + 6 : "lmathlib.c" line 22, impact on 1 file(s) + 7 : "loadlib.c" line 24, impact on 1 file(s) + 8 : "loslib.c" line 22, impact on 1 file(s) + 9 : "lstrlib.c" line 26, impact on 1 file(s) + 10 : "ltablib.c" line 20, impact on 1 file(s) + 11 : "lua.c" line 21, impact on 1 file(s) + 12 : "lutf8lib.c" line 21, impact on 1 file(s) + 13 : "ltests.c" line 34 +15 : "ltable.h" impact on 13 file(s) +Included by: + 1 : "lapi.c" line 28, impact on 1 file(s) + 2 : "lcode.c" line 29, impact on 1 file(s) + 3 : "ldebug.c" line 28, impact on 1 file(s) + 4 : "ldo.c" line 30, impact on 1 file(s) + 5 : "lgc.c" line 26, impact on 1 file(s) + 6 : "llex.c" line 27, impact on 1 file(s) + 7 : "lparser.c" line 29, impact on 1 file(s) + 8 : "lstate.c" line 27, impact on 1 file(s) + 9 : "ltable.c" line 38, impact on 1 file(s) + 10 : "ltm.c" line 23, impact on 1 file(s) + 11 : "lvm.c" line 29, impact on 1 file(s) + 12 : "ltests.c" line 33 +16 : "lfunc.h" impact on 11 file(s) +Included by: + 1 : "lapi.c" line 22, impact on 1 file(s) + 2 : "ldebug.c" line 23, impact on 1 file(s) + 3 : "ldo.c" line 22, impact on 1 file(s) + 4 : "lfunc.c" line 19, impact on 1 file(s) + 5 : "lgc.c" line 20, impact on 1 file(s) + 6 : "lparser.c" line 21, impact on 1 file(s) + 7 : "lstate.c" line 21, impact on 1 file(s) + 8 : "lundump.c" line 20, impact on 1 file(s) + 9 : "lvm.c" line 23, impact on 1 file(s) + 10 : "ltests.c" line 27 +17 : "lopcodes.h" impact on 9 file(s) +Included by: + 1 : "lcode.h" line 12, impact on 5 file(s) + 2 : "lcode.c" line 26, impact on 1 file(s) + 3 : "ldebug.c" line 25, impact on 1 file(s) + 4 : "ldo.c" line 26, impact on 1 file(s) + 5 : "lopcodes.c" line 13, impact on 1 file(s) + 6 : "lparser.c" line 25, impact on 1 file(s) + 7 : "lvm.c" line 26, impact on 1 file(s) + 8 : "ltests.c" line 29 +18 : "lvm.h" impact on 9 file(s) +Included by: + 1 : "lapi.c" line 31, impact on 1 file(s) + 2 : "lcode.c" line 30, impact on 1 file(s) + 3 : "ldebug.c" line 30, impact on 1 file(s) + 4 : "ldo.c" line 33, impact on 1 file(s) + 5 : "lobject.c" line 29, impact on 1 file(s) + 6 : "ltable.c" line 39, impact on 1 file(s) + 7 : "ltm.c" line 25, impact on 1 file(s) + 8 : "lvm.c" line 31, impact on 1 file(s) +19 : "llex.h" impact on 8 file(s) +Included by: + 1 : "lcode.h" line 10, impact on 5 file(s) + 2 : "lcode.c" line 23, impact on 1 file(s) + 3 : "llex.c" line 22, impact on 1 file(s) + 4 : "lparser.c" line 22, impact on 1 file(s) + 5 : "lstate.c" line 23, impact on 1 file(s) +20 : "lparser.h" impact on 8 file(s) +Included by: + 1 : "lcode.h" line 13, impact on 5 file(s) + 2 : "lcode.c" line 27, impact on 1 file(s) + 3 : "ldo.c" line 27, impact on 1 file(s) + 4 : "llex.c" line 24, impact on 1 file(s) + 5 : "lparser.c" line 26, impact on 1 file(s) +21 : "lapi.h" impact on 6 file(s) +Included by: + 1 : "lapi.c" line 19, impact on 1 file(s) + 2 : "ldebug.c" line 19, impact on 1 file(s) + 3 : "ldo.c" line 19, impact on 1 file(s) + 4 : "lstate.c" line 18, impact on 1 file(s) + 5 : "ltests.c" line 21 +22 : "lcode.h" impact on 5 file(s) +Included by: + 1 : "lcode.c" line 19, impact on 1 file(s) + 2 : "ldebug.c" line 20, impact on 1 file(s) + 3 : "lparser.c" line 18, impact on 1 file(s) + 4 : "ltests.c" line 23 +23 : "lctype.h" impact on 5 file(s) +Included by: + 1 : "lctype.c" line 13, impact on 1 file(s) + 2 : "llex.c" line 18, impact on 1 file(s) + 3 : "lobject.c" line 22, impact on 1 file(s) + 4 : "ltests.c" line 24 +24 : "lundump.h" impact on 5 file(s) +Included by: + 1 : "lapi.c" line 30, impact on 1 file(s) + 2 : "ldo.c" line 32, impact on 1 file(s) + 3 : "ldump.c" line 19, impact on 1 file(s) + 4 : "lundump.c" line 24, impact on 1 file(s) +25 : "ljumptab.h" impact on 2 file(s) +Included by: + 1 : "lvm.c" line 1134, impact on 1 file(s) +26 : "lapi.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 79 +27 : "lauxlib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 82 +28 : "lbaselib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 86 +29 : "lcode.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 69 +30 : "lcorolib.c" impact on 1 file(s) +Included by: + 1 : "onelua.c" line 87 +... 30 of 59 files +Unincluded headers: +1 : "ltests.h" diff --git a/docs/examples/notepad-plus-plus/output_unix.txt b/docs/examples/notepad-plus-plus/output_unix.txt index 93ef042..a47447e 100644 --- a/docs/examples/notepad-plus-plus/output_unix.txt +++ b/docs/examples/notepad-plus-plus/output_unix.txt @@ -126,3 +126,15 @@ Included by: 10 : "scintilla/lexers/LexAsn1.cxx" line 23 ... 10 of 119 details ... 10 of 243 files +Unincluded headers: +1 : "PowerEditor/gcc/include/various.h" +2 : "PowerEditor/src/MISC/PluginsManager/deprecatedSymbols.h" +3 : "PowerEditor/src/MISC/crc16/Crc16.h" +4 : "PowerEditor/src/StaticControl.h" +5 : "PowerEditor/src/WinControls/WindowInterface.h" +6 : "scintilla/cocoa/InfoBar.h" +7 : "scintilla/cocoa/InfoBarCommunicator.h" +8 : "scintilla/cocoa/PlatCocoa.h" +9 : "scintilla/cocoa/ScintillaCocoa.h" +10 : "scintilla/cocoa/ScintillaTest/AppController.h" +... 10 of 12 files diff --git a/docs/examples/notepad-plus-plus/output_win.txt b/docs/examples/notepad-plus-plus/output_win.txt index 7bc7664..dbea16b 100644 --- a/docs/examples/notepad-plus-plus/output_win.txt +++ b/docs/examples/notepad-plus-plus/output_win.txt @@ -126,3 +126,15 @@ Included by: 10 : "scintilla\lexers\LexAsn1.cxx" line 23 ... 10 of 119 details ... 10 of 243 files +Unincluded headers: +1 : "PowerEditor\gcc\include\various.h" +2 : "PowerEditor\src\MISC\PluginsManager\deprecatedSymbols.h" +3 : "PowerEditor\src\MISC\crc16\Crc16.h" +4 : "PowerEditor\src\StaticControl.h" +5 : "PowerEditor\src\WinControls\WindowInterface.h" +6 : "scintilla\cocoa\InfoBar.h" +7 : "scintilla\cocoa\InfoBarCommunicator.h" +8 : "scintilla\cocoa\PlatCocoa.h" +9 : "scintilla\cocoa\ScintillaCocoa.h" +10 : "scintilla\cocoa\ScintillaTest\AppController.h" +... 10 of 12 files diff --git a/docs/examples/simple_example_cmake/CMakeLists.txt b/docs/examples/simple_example_cmake/CMakeLists.txt new file mode 100644 index 0000000..3664b9f --- /dev/null +++ b/docs/examples/simple_example_cmake/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8) + +project(simple_example) + +file(GLOB all_sources "*.cpp") +add_executable(${PROJECT_NAME} ${all_sources}) + diff --git a/docs/examples/simple_example_cmake/base_char.hpp b/docs/examples/simple_example_cmake/base_char.hpp new file mode 100644 index 0000000..ba6b66f --- /dev/null +++ b/docs/examples/simple_example_cmake/base_char.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "char_kind.hpp" + +class BaseChar +{ +public: + + virtual ~BaseChar() = default; + + virtual CharKind getKind() const noexcept = 0; +}; diff --git a/docs/examples/simple_example_cmake/base_char_factory.hpp b/docs/examples/simple_example_cmake/base_char_factory.hpp new file mode 100644 index 0000000..a01d9e7 --- /dev/null +++ b/docs/examples/simple_example_cmake/base_char_factory.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "base_char.hpp" + +#include + +class BaseCharFactory +{ +public: + + virtual ~BaseCharFactory() = default; + + virtual std::unique_ptr< BaseChar > createObject() = 0; +}; diff --git a/docs/examples/simple_example_cmake/build/compile_commands.json b/docs/examples/simple_example_cmake/build/compile_commands.json new file mode 100644 index 0000000..3922087 --- /dev/null +++ b/docs/examples/simple_example_cmake/build/compile_commands.json @@ -0,0 +1,27 @@ +[ +{ + "directory": ".", + "command": "/usr/bin/c++ -o CMakeFiles/simple_example.dir/char_a.cpp.o -c ../char_a.cpp", + "file": "../char_a.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -o CMakeFiles/simple_example.dir/char_a_factory.cpp.o -c ../char_a_factory.cpp", + "file": "../char_a_factory.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -o CMakeFiles/simple_example.dir/char_b.cpp.o -c ../char_b.cpp", + "file": "../char_b.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -o CMakeFiles/simple_example.dir/char_b_factory.cpp.o -c ../char_b_factory.cpp", + "file": "../char_b_factory.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -o CMakeFiles/simple_example.dir/main.cpp.o -c ../main.cpp", + "file": "../main.cpp" +} +] diff --git a/docs/examples/simple_example_cmake/char_a.cpp b/docs/examples/simple_example_cmake/char_a.cpp new file mode 100644 index 0000000..8ea8215 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_a.cpp @@ -0,0 +1,6 @@ +#include "char_a.hpp" + +CharKind CharA::getKind() const noexcept +{ + return CharKind::A; +} diff --git a/docs/examples/simple_example_cmake/char_a.hpp b/docs/examples/simple_example_cmake/char_a.hpp new file mode 100644 index 0000000..8cf9a2a --- /dev/null +++ b/docs/examples/simple_example_cmake/char_a.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharA : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_cmake/char_a_factory.cpp b/docs/examples/simple_example_cmake/char_a_factory.cpp new file mode 100644 index 0000000..0051051 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_a_factory.cpp @@ -0,0 +1,8 @@ +#include "char_a_factory.hpp" + +#include "char_a.hpp" + +std::unique_ptr< BaseChar > CharAFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharA }; +} diff --git a/docs/examples/simple_example_cmake/char_a_factory.hpp b/docs/examples/simple_example_cmake/char_a_factory.hpp new file mode 100644 index 0000000..856083b --- /dev/null +++ b/docs/examples/simple_example_cmake/char_a_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharAFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_cmake/char_b.cpp b/docs/examples/simple_example_cmake/char_b.cpp new file mode 100644 index 0000000..60e1b11 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_b.cpp @@ -0,0 +1,6 @@ +#include "char_b.hpp" + +CharKind CharB::getKind() const noexcept +{ + return CharKind::B; +} diff --git a/docs/examples/simple_example_cmake/char_b.hpp b/docs/examples/simple_example_cmake/char_b.hpp new file mode 100644 index 0000000..e6b0f20 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_b.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharB : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_cmake/char_b_factory.cpp b/docs/examples/simple_example_cmake/char_b_factory.cpp new file mode 100644 index 0000000..6276ca2 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_b_factory.cpp @@ -0,0 +1,9 @@ +#include "char_b_factory.hpp" + +#include "char_b.hpp" + +std::unique_ptr< BaseChar > CharBFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharB }; +} + diff --git a/docs/examples/simple_example_cmake/char_b_factory.hpp b/docs/examples/simple_example_cmake/char_b_factory.hpp new file mode 100644 index 0000000..1e06696 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_b_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharBFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_cmake/char_kind.hpp b/docs/examples/simple_example_cmake/char_kind.hpp new file mode 100644 index 0000000..0086d00 --- /dev/null +++ b/docs/examples/simple_example_cmake/char_kind.hpp @@ -0,0 +1,9 @@ +#pragma once + +enum class CharKind +{ + A, + B, + + Count +}; diff --git a/docs/examples/simple_example_cmake/main.cpp b/docs/examples/simple_example_cmake/main.cpp new file mode 100644 index 0000000..2586464 --- /dev/null +++ b/docs/examples/simple_example_cmake/main.cpp @@ -0,0 +1,49 @@ +#include "char_a_factory.hpp" +#include "char_b_factory.hpp" + +#include +#include + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); +std::string enumToString( CharKind _kind ); + +int main() +{ + CharAFactory factoryA; + CharBFactory factoryB; + + char c; + std::cin >> c; + + std::unique_ptr< BaseChar > currentObject; + if( c == 'a' ) + currentObject = createChar( factoryA ); + else + currentObject = createChar( factoryB ); + assert( currentObject ); + + std::cout << "Enum : " << enumToString( currentObject->getKind() ) << '\n'; + + return 0; +} + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) +{ + return _factory.createObject(); +} + + +std::string enumToString( CharKind _kind ) +{ + static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + switch( _kind ) + { + case CharKind::A : return "CharKind::A"; + case CharKind::B : return "CharKind::B"; + + case CharKind::Count : return "CharKind::Count"; + } + + assert( false ); + return ""; +} diff --git a/docs/examples/simple_example_cmake/output_unix.txt b/docs/examples/simple_example_cmake/output_unix.txt new file mode 100644 index 0000000..d6a204f --- /dev/null +++ b/docs/examples/simple_example_cmake/output_unix.txt @@ -0,0 +1,32 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "../char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "../base_char.hpp" line 3, impact on 10 file(s) +2 : "../base_char.hpp" impact on 10 file(s) +Included by: + 1 : "../base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "../char_a.hpp" line 3, impact on 2 file(s) + 3 : "../char_b.hpp" line 3, impact on 2 file(s) +3 : "../base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "../char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "../char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "../char_a.hpp" impact on 2 file(s) +Included by: + 1 : "../char_a.cpp" line 1 + 2 : "../char_a_factory.cpp" line 3 +5 : "../char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "../char_a_factory.cpp" line 1 + 2 : "../main.cpp" line 1 +6 : "../char_b.hpp" impact on 2 file(s) +Included by: + 1 : "../char_b.cpp" line 1 + 2 : "../char_b_factory.cpp" line 3 +7 : "../char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "../char_b_factory.cpp" line 1 + 2 : "../main.cpp" line 2 diff --git a/docs/examples/simple_example_cmake/output_win.txt b/docs/examples/simple_example_cmake/output_win.txt new file mode 100644 index 0000000..6847c6c --- /dev/null +++ b/docs/examples/simple_example_cmake/output_win.txt @@ -0,0 +1,32 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "..\char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "..\base_char.hpp" line 3, impact on 10 file(s) +2 : "..\base_char.hpp" impact on 10 file(s) +Included by: + 1 : "..\base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "..\char_a.hpp" line 3, impact on 2 file(s) + 3 : "..\char_b.hpp" line 3, impact on 2 file(s) +3 : "..\base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "..\char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "..\char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "..\char_a.hpp" impact on 2 file(s) +Included by: + 1 : "..\char_a.cpp" line 1 + 2 : "..\char_a_factory.cpp" line 3 +5 : "..\char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "..\char_a_factory.cpp" line 1 + 2 : "..\main.cpp" line 1 +6 : "..\char_b.hpp" impact on 2 file(s) +Included by: + 1 : "..\char_b.cpp" line 1 + 2 : "..\char_b_factory.cpp" line 3 +7 : "..\char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "..\char_b_factory.cpp" line 1 + 2 : "..\main.cpp" line 2 diff --git a/docs/examples/simple_example_cmake/run.bat b/docs/examples/simple_example_cmake/run.bat new file mode 100644 index 0000000..d540280 --- /dev/null +++ b/docs/examples/simple_example_cmake/run.bat @@ -0,0 +1,5 @@ +cd build +call ..\..\tools\run_analyze.bat + +move output_win.txt .. +cd .. diff --git a/docs/examples/simple_example_cmake/run.sh b/docs/examples/simple_example_cmake/run.sh new file mode 100755 index 0000000..6751f99 --- /dev/null +++ b/docs/examples/simple_example_cmake/run.sh @@ -0,0 +1,9 @@ +source ../tools/examples_tools.sh + +cd build + +run_analyze + +mv output_unix.txt .. +cd .. + diff --git a/docs/examples/simple_example_for_different_type_report/.cppinclude.json b/docs/examples/simple_example_for_different_type_report/.cppinclude.json new file mode 100644 index 0000000..8d7be1c --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/.cppinclude.json @@ -0,0 +1,3 @@ +{ + "report" : [ "different_type" ] +} diff --git a/docs/examples/simple_example_for_different_type_report/CMakeLists.txt b/docs/examples/simple_example_for_different_type_report/CMakeLists.txt new file mode 100644 index 0000000..3664b9f --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8) + +project(simple_example) + +file(GLOB all_sources "*.cpp") +add_executable(${PROJECT_NAME} ${all_sources}) + diff --git a/docs/examples/simple_example_for_different_type_report/base_char.hpp b/docs/examples/simple_example_for_different_type_report/base_char.hpp new file mode 100644 index 0000000..ba6b66f --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/base_char.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "char_kind.hpp" + +class BaseChar +{ +public: + + virtual ~BaseChar() = default; + + virtual CharKind getKind() const noexcept = 0; +}; diff --git a/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp b/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp new file mode 100644 index 0000000..a01d9e7 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "base_char.hpp" + +#include + +class BaseCharFactory +{ +public: + + virtual ~BaseCharFactory() = default; + + virtual std::unique_ptr< BaseChar > createObject() = 0; +}; diff --git a/docs/examples/simple_example_for_different_type_report/char_a.cpp b/docs/examples/simple_example_for_different_type_report/char_a.cpp new file mode 100644 index 0000000..8ea8215 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_a.cpp @@ -0,0 +1,6 @@ +#include "char_a.hpp" + +CharKind CharA::getKind() const noexcept +{ + return CharKind::A; +} diff --git a/docs/examples/simple_example_for_different_type_report/char_a.hpp b/docs/examples/simple_example_for_different_type_report/char_a.hpp new file mode 100644 index 0000000..99b9f62 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_a.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +class CharA : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_for_different_type_report/char_a_factory.cpp b/docs/examples/simple_example_for_different_type_report/char_a_factory.cpp new file mode 100644 index 0000000..0051051 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_a_factory.cpp @@ -0,0 +1,8 @@ +#include "char_a_factory.hpp" + +#include "char_a.hpp" + +std::unique_ptr< BaseChar > CharAFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharA }; +} diff --git a/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp b/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp new file mode 100644 index 0000000..bda76a5 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include + +class CharAFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_for_different_type_report/char_b.cpp b/docs/examples/simple_example_for_different_type_report/char_b.cpp new file mode 100644 index 0000000..60e1b11 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_b.cpp @@ -0,0 +1,6 @@ +#include "char_b.hpp" + +CharKind CharB::getKind() const noexcept +{ + return CharKind::B; +} diff --git a/docs/examples/simple_example_for_different_type_report/char_b.hpp b/docs/examples/simple_example_for_different_type_report/char_b.hpp new file mode 100644 index 0000000..e6b0f20 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_b.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharB : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp b/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp new file mode 100644 index 0000000..6276ca2 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp @@ -0,0 +1,9 @@ +#include "char_b_factory.hpp" + +#include "char_b.hpp" + +std::unique_ptr< BaseChar > CharBFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharB }; +} + diff --git a/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp b/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp new file mode 100644 index 0000000..1e06696 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharBFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_for_different_type_report/char_kind.hpp b/docs/examples/simple_example_for_different_type_report/char_kind.hpp new file mode 100644 index 0000000..0086d00 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/char_kind.hpp @@ -0,0 +1,9 @@ +#pragma once + +enum class CharKind +{ + A, + B, + + Count +}; diff --git a/docs/examples/simple_example_for_different_type_report/main.cpp b/docs/examples/simple_example_for_different_type_report/main.cpp new file mode 100644 index 0000000..2586464 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/main.cpp @@ -0,0 +1,49 @@ +#include "char_a_factory.hpp" +#include "char_b_factory.hpp" + +#include +#include + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); +std::string enumToString( CharKind _kind ); + +int main() +{ + CharAFactory factoryA; + CharBFactory factoryB; + + char c; + std::cin >> c; + + std::unique_ptr< BaseChar > currentObject; + if( c == 'a' ) + currentObject = createChar( factoryA ); + else + currentObject = createChar( factoryB ); + assert( currentObject ); + + std::cout << "Enum : " << enumToString( currentObject->getKind() ) << '\n'; + + return 0; +} + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) +{ + return _factory.createObject(); +} + + +std::string enumToString( CharKind _kind ) +{ + static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + switch( _kind ) + { + case CharKind::A : return "CharKind::A"; + case CharKind::B : return "CharKind::B"; + + case CharKind::Count : return "CharKind::Count"; + } + + assert( false ); + return ""; +} diff --git a/docs/examples/simple_example_for_different_type_report/output_unix.txt b/docs/examples/simple_example_for_different_type_report/output_unix.txt new file mode 100644 index 0000000..ee89d32 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/output_unix.txt @@ -0,0 +1,15 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Files that are included by different ways: +1. base_char.hpp +With double quotation marks ( #include "..." ) in files: + 1. base_char_factory.hpp line 3 + 2. char_b.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a.hpp line 3 +2. base_char_factory.hpp +With double quotation marks ( #include "..." ) in files: + 1. char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a_factory.hpp line 3 diff --git a/docs/examples/simple_example_for_different_type_report/output_win.txt b/docs/examples/simple_example_for_different_type_report/output_win.txt new file mode 100644 index 0000000..a380293 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/output_win.txt @@ -0,0 +1,15 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Files that are included by different ways: +1. base_char.hpp +With double quotation marks ( #include "..." ) in files: + 1. base_char_factory.hpp line 3 + 2. char_b.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a.hpp line 3 +2. base_char_factory.hpp +With double quotation marks ( #include "..." ) in files: + 1. char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a_factory.hpp line 3 diff --git a/docs/examples/simple_example_for_different_type_report/run.bat b/docs/examples/simple_example_for_different_type_report/run.bat new file mode 100644 index 0000000..dcff19d --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/run.bat @@ -0,0 +1 @@ +call ..\tools\run_analyze.bat \ No newline at end of file diff --git a/docs/examples/simple_example_for_different_type_report/run.sh b/docs/examples/simple_example_for_different_type_report/run.sh new file mode 100755 index 0000000..ecc7c88 --- /dev/null +++ b/docs/examples/simple_example_for_different_type_report/run.sh @@ -0,0 +1,4 @@ +source ../tools/examples_tools.sh + +run_analyze + diff --git a/docs/examples/simple_example_with_include_path_cmake/CMakeLists.txt b/docs/examples/simple_example_with_include_path_cmake/CMakeLists.txt new file mode 100644 index 0000000..4062a89 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8) + +project(simple_example) + +include_directories(lib lib/base lib/a lib/b) + +file(GLOB_RECURSE all_sources "*.cpp") +add_executable(${PROJECT_NAME} ${all_sources}) + diff --git a/docs/examples/simple_example_with_include_path_cmake/build/compile_commands.json b/docs/examples/simple_example_with_include_path_cmake/build/compile_commands.json new file mode 100644 index 0000000..28820ae --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/build/compile_commands.json @@ -0,0 +1,27 @@ +[ +{ + "directory": ".", + "command": "/usr/bin/c++ -I../lib -I../lib/base -I../lib/a -I../lib/b -o CMakeFiles/simple_example.dir/lib/a/char_a.cpp.o -c ../lib/a/char_a.cpp", + "file": "../lib/a/char_a.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -I../lib -I../lib/base -I../lib/a -I../lib/b -o CMakeFiles/simple_example.dir/lib/a/char_a_factory.cpp.o -c ../lib/a/char_a_factory.cpp", + "file": "../lib/a/char_a_factory.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -I../lib -I../lib/base -I../lib/a -I../lib/b -o CMakeFiles/simple_example.dir/lib/b/char_b.cpp.o -c ../lib/b/char_b.cpp", + "file": "../lib/b/char_b.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -I../lib -I../lib/base -I../lib/a -I../lib/b -o CMakeFiles/simple_example.dir/lib/b/char_b_factory.cpp.o -c ../lib/b/char_b_factory.cpp", + "file": "../lib/b/char_b_factory.cpp" +}, +{ + "directory": ".", + "command": "/usr/bin/c++ -I../lib -I../lib/base -I../lib/a -I../lib/b -o CMakeFiles/simple_example.dir/main.cpp.o -c ..main.cpp", + "file": "../main.cpp" +} +] diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.cpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.cpp new file mode 100644 index 0000000..8ea8215 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.cpp @@ -0,0 +1,6 @@ +#include "char_a.hpp" + +CharKind CharA::getKind() const noexcept +{ + return CharKind::A; +} diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp new file mode 100644 index 0000000..8cf9a2a --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharA : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.cpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.cpp new file mode 100644 index 0000000..0051051 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.cpp @@ -0,0 +1,8 @@ +#include "char_a_factory.hpp" + +#include "char_a.hpp" + +std::unique_ptr< BaseChar > CharAFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharA }; +} diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp new file mode 100644 index 0000000..856083b --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharAFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.cpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.cpp new file mode 100644 index 0000000..60e1b11 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.cpp @@ -0,0 +1,6 @@ +#include "char_b.hpp" + +CharKind CharB::getKind() const noexcept +{ + return CharKind::B; +} diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp new file mode 100644 index 0000000..e6b0f20 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharB : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp new file mode 100644 index 0000000..6276ca2 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp @@ -0,0 +1,9 @@ +#include "char_b_factory.hpp" + +#include "char_b.hpp" + +std::unique_ptr< BaseChar > CharBFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharB }; +} + diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp new file mode 100644 index 0000000..1e06696 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharBFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp new file mode 100644 index 0000000..ba6b66f --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "char_kind.hpp" + +class BaseChar +{ +public: + + virtual ~BaseChar() = default; + + virtual CharKind getKind() const noexcept = 0; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp new file mode 100644 index 0000000..a01d9e7 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "base_char.hpp" + +#include + +class BaseCharFactory +{ +public: + + virtual ~BaseCharFactory() = default; + + virtual std::unique_ptr< BaseChar > createObject() = 0; +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/char_kind.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/char_kind.hpp new file mode 100644 index 0000000..0086d00 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/lib/char_kind.hpp @@ -0,0 +1,9 @@ +#pragma once + +enum class CharKind +{ + A, + B, + + Count +}; diff --git a/docs/examples/simple_example_with_include_path_cmake/main.cpp b/docs/examples/simple_example_with_include_path_cmake/main.cpp new file mode 100644 index 0000000..2586464 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/main.cpp @@ -0,0 +1,49 @@ +#include "char_a_factory.hpp" +#include "char_b_factory.hpp" + +#include +#include + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); +std::string enumToString( CharKind _kind ); + +int main() +{ + CharAFactory factoryA; + CharBFactory factoryB; + + char c; + std::cin >> c; + + std::unique_ptr< BaseChar > currentObject; + if( c == 'a' ) + currentObject = createChar( factoryA ); + else + currentObject = createChar( factoryB ); + assert( currentObject ); + + std::cout << "Enum : " << enumToString( currentObject->getKind() ) << '\n'; + + return 0; +} + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) +{ + return _factory.createObject(); +} + + +std::string enumToString( CharKind _kind ) +{ + static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + switch( _kind ) + { + case CharKind::A : return "CharKind::A"; + case CharKind::B : return "CharKind::B"; + + case CharKind::Count : return "CharKind::Count"; + } + + assert( false ); + return ""; +} diff --git a/docs/examples/simple_example_with_include_path_cmake/output_unix.txt b/docs/examples/simple_example_with_include_path_cmake/output_unix.txt new file mode 100644 index 0000000..56b73f0 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/output_unix.txt @@ -0,0 +1,32 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "../lib/char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "../lib/base/base_char.hpp" line 3, impact on 10 file(s) +2 : "../lib/base/base_char.hpp" impact on 10 file(s) +Included by: + 1 : "../lib/base/base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "../lib/a/char_a.hpp" line 3, impact on 2 file(s) + 3 : "../lib/b/char_b.hpp" line 3, impact on 2 file(s) +3 : "../lib/base/base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "../lib/a/char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "../lib/b/char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "../lib/a/char_a.hpp" impact on 2 file(s) +Included by: + 1 : "../lib/a/char_a.cpp" line 1 + 2 : "../lib/a/char_a_factory.cpp" line 3 +5 : "../lib/a/char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "../lib/a/char_a_factory.cpp" line 1 + 2 : "../main.cpp" line 1 +6 : "../lib/b/char_b.hpp" impact on 2 file(s) +Included by: + 1 : "../lib/b/char_b.cpp" line 1 + 2 : "../lib/b/char_b_factory.cpp" line 3 +7 : "../lib/b/char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "../lib/b/char_b_factory.cpp" line 1 + 2 : "../main.cpp" line 2 diff --git a/docs/examples/simple_example_with_include_path_cmake/output_win.txt b/docs/examples/simple_example_with_include_path_cmake/output_win.txt new file mode 100644 index 0000000..aa9a265 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/output_win.txt @@ -0,0 +1,32 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "..\lib\char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "..\lib\base\base_char.hpp" line 3, impact on 10 file(s) +2 : "..\lib\base\base_char.hpp" impact on 10 file(s) +Included by: + 1 : "..\lib\base\base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "..\lib\a\char_a.hpp" line 3, impact on 2 file(s) + 3 : "..\lib\b\char_b.hpp" line 3, impact on 2 file(s) +3 : "..\lib\base\base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "..\lib\a\char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "..\lib\b\char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "..\lib\a\char_a.hpp" impact on 2 file(s) +Included by: + 1 : "..\lib\a\char_a.cpp" line 1 + 2 : "..\lib\a\char_a_factory.cpp" line 3 +5 : "..\lib\a\char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "..\lib\a\char_a_factory.cpp" line 1 + 2 : "..\main.cpp" line 1 +6 : "..\lib\b\char_b.hpp" impact on 2 file(s) +Included by: + 1 : "..\lib\b\char_b.cpp" line 1 + 2 : "..\lib\b\char_b_factory.cpp" line 3 +7 : "..\lib\b\char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "..\lib\b\char_b_factory.cpp" line 1 + 2 : "..\main.cpp" line 2 diff --git a/docs/examples/simple_example_with_include_path_cmake/run.bat b/docs/examples/simple_example_with_include_path_cmake/run.bat new file mode 100644 index 0000000..d540280 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/run.bat @@ -0,0 +1,5 @@ +cd build +call ..\..\tools\run_analyze.bat + +move output_win.txt .. +cd .. diff --git a/docs/examples/simple_example_with_include_path_cmake/run.sh b/docs/examples/simple_example_with_include_path_cmake/run.sh new file mode 100755 index 0000000..6751f99 --- /dev/null +++ b/docs/examples/simple_example_with_include_path_cmake/run.sh @@ -0,0 +1,9 @@ +source ../tools/examples_tools.sh + +cd build + +run_analyze + +mv output_unix.txt .. +cd .. + diff --git a/docs/examples/simple_example_with_unincluded_headers/.cppinclude.json b/docs/examples/simple_example_with_unincluded_headers/.cppinclude.json new file mode 100644 index 0000000..b300bcf --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/.cppinclude.json @@ -0,0 +1,8 @@ +{ + + "report" : [ + "most_impact", + "unresolved", + "unincluded" + ] +} diff --git a/docs/examples/simple_example_with_unincluded_headers/CMakeLists.txt b/docs/examples/simple_example_with_unincluded_headers/CMakeLists.txt new file mode 100644 index 0000000..3664b9f --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 2.8) + +project(simple_example) + +file(GLOB all_sources "*.cpp") +add_executable(${PROJECT_NAME} ${all_sources}) + diff --git a/docs/examples/simple_example_with_unincluded_headers/base_char.hpp b/docs/examples/simple_example_with_unincluded_headers/base_char.hpp new file mode 100644 index 0000000..ba6b66f --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/base_char.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "char_kind.hpp" + +class BaseChar +{ +public: + + virtual ~BaseChar() = default; + + virtual CharKind getKind() const noexcept = 0; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp new file mode 100644 index 0000000..a01d9e7 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "base_char.hpp" + +#include + +class BaseCharFactory +{ +public: + + virtual ~BaseCharFactory() = default; + + virtual std::unique_ptr< BaseChar > createObject() = 0; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a.cpp b/docs/examples/simple_example_with_unincluded_headers/char_a.cpp new file mode 100644 index 0000000..8ea8215 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_a.cpp @@ -0,0 +1,6 @@ +#include "char_a.hpp" + +CharKind CharA::getKind() const noexcept +{ + return CharKind::A; +} diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a.hpp b/docs/examples/simple_example_with_unincluded_headers/char_a.hpp new file mode 100644 index 0000000..8cf9a2a --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_a.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharA : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a_factory.cpp b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.cpp new file mode 100644 index 0000000..0051051 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.cpp @@ -0,0 +1,8 @@ +#include "char_a_factory.hpp" + +#include "char_a.hpp" + +std::unique_ptr< BaseChar > CharAFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharA }; +} diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp new file mode 100644 index 0000000..856083b --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharAFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b.cpp b/docs/examples/simple_example_with_unincluded_headers/char_b.cpp new file mode 100644 index 0000000..60e1b11 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_b.cpp @@ -0,0 +1,6 @@ +#include "char_b.hpp" + +CharKind CharB::getKind() const noexcept +{ + return CharKind::B; +} diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b.hpp b/docs/examples/simple_example_with_unincluded_headers/char_b.hpp new file mode 100644 index 0000000..e6b0f20 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_b.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char.hpp" + +class CharB : public BaseChar +{ +public: + + CharKind getKind() const noexcept override; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp new file mode 100644 index 0000000..6276ca2 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp @@ -0,0 +1,9 @@ +#include "char_b_factory.hpp" + +#include "char_b.hpp" + +std::unique_ptr< BaseChar > CharBFactory::createObject() +{ + return std::unique_ptr< BaseChar >{ new CharB }; +} + diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp new file mode 100644 index 0000000..1e06696 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp @@ -0,0 +1,10 @@ +#pragma once + +#include "base_char_factory.hpp" + +class CharBFactory : public BaseCharFactory +{ +public: + + std::unique_ptr< BaseChar > createObject() override; +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_kind.hpp b/docs/examples/simple_example_with_unincluded_headers/char_kind.hpp new file mode 100644 index 0000000..0086d00 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/char_kind.hpp @@ -0,0 +1,9 @@ +#pragma once + +enum class CharKind +{ + A, + B, + + Count +}; diff --git a/docs/examples/simple_example_with_unincluded_headers/config.hpp b/docs/examples/simple_example_with_unincluded_headers/config.hpp new file mode 100644 index 0000000..e69de29 diff --git a/docs/examples/simple_example_with_unincluded_headers/main.cpp b/docs/examples/simple_example_with_unincluded_headers/main.cpp new file mode 100644 index 0000000..2586464 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/main.cpp @@ -0,0 +1,49 @@ +#include "char_a_factory.hpp" +#include "char_b_factory.hpp" + +#include +#include + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); +std::string enumToString( CharKind _kind ); + +int main() +{ + CharAFactory factoryA; + CharBFactory factoryB; + + char c; + std::cin >> c; + + std::unique_ptr< BaseChar > currentObject; + if( c == 'a' ) + currentObject = createChar( factoryA ); + else + currentObject = createChar( factoryB ); + assert( currentObject ); + + std::cout << "Enum : " << enumToString( currentObject->getKind() ) << '\n'; + + return 0; +} + +std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) +{ + return _factory.createObject(); +} + + +std::string enumToString( CharKind _kind ) +{ + static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + switch( _kind ) + { + case CharKind::A : return "CharKind::A"; + case CharKind::B : return "CharKind::B"; + + case CharKind::Count : return "CharKind::Count"; + } + + assert( false ); + return ""; +} diff --git a/docs/examples/simple_example_with_unincluded_headers/output_unix.txt b/docs/examples/simple_example_with_unincluded_headers/output_unix.txt new file mode 100644 index 0000000..9ab3f31 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/output_unix.txt @@ -0,0 +1,35 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "base_char.hpp" line 3, impact on 10 file(s) +2 : "base_char.hpp" impact on 10 file(s) +Included by: + 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "char_a.hpp" line 3, impact on 2 file(s) + 3 : "char_b.hpp" line 3, impact on 2 file(s) +3 : "base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "char_a.hpp" impact on 2 file(s) +Included by: + 1 : "char_a.cpp" line 1 + 2 : "char_a_factory.cpp" line 3 +5 : "char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "char_a_factory.cpp" line 1 + 2 : "main.cpp" line 1 +6 : "char_b.hpp" impact on 2 file(s) +Included by: + 1 : "char_b.cpp" line 1 + 2 : "char_b_factory.cpp" line 3 +7 : "char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "char_b_factory.cpp" line 1 + 2 : "main.cpp" line 2 +Unincluded headers: +1 : "config.hpp" +2 : "settings.hpp" diff --git a/docs/examples/simple_example_with_unincluded_headers/output_win.txt b/docs/examples/simple_example_with_unincluded_headers/output_win.txt new file mode 100644 index 0000000..0a9025c --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/output_win.txt @@ -0,0 +1,35 @@ +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "char_kind.hpp" impact on 11 file(s) +Included by: + 1 : "base_char.hpp" line 3, impact on 10 file(s) +2 : "base_char.hpp" impact on 10 file(s) +Included by: + 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) + 2 : "char_a.hpp" line 3, impact on 2 file(s) + 3 : "char_b.hpp" line 3, impact on 2 file(s) +3 : "base_char_factory.hpp" impact on 5 file(s) +Included by: + 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) + 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) +4 : "char_a.hpp" impact on 2 file(s) +Included by: + 1 : "char_a.cpp" line 1 + 2 : "char_a_factory.cpp" line 3 +5 : "char_a_factory.hpp" impact on 2 file(s) +Included by: + 1 : "char_a_factory.cpp" line 1 + 2 : "main.cpp" line 1 +6 : "char_b.hpp" impact on 2 file(s) +Included by: + 1 : "char_b.cpp" line 1 + 2 : "char_b_factory.cpp" line 3 +7 : "char_b_factory.hpp" impact on 2 file(s) +Included by: + 1 : "char_b_factory.cpp" line 1 + 2 : "main.cpp" line 2 +Unincluded headers: +1 : "config.hpp" +2 : "settings.hpp" diff --git a/docs/examples/simple_example_with_unincluded_headers/run.bat b/docs/examples/simple_example_with_unincluded_headers/run.bat new file mode 100644 index 0000000..dcff19d --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/run.bat @@ -0,0 +1 @@ +call ..\tools\run_analyze.bat \ No newline at end of file diff --git a/docs/examples/simple_example_with_unincluded_headers/run.sh b/docs/examples/simple_example_with_unincluded_headers/run.sh new file mode 100755 index 0000000..ecc7c88 --- /dev/null +++ b/docs/examples/simple_example_with_unincluded_headers/run.sh @@ -0,0 +1,4 @@ +source ../tools/examples_tools.sh + +run_analyze + diff --git a/docs/examples/simple_example_with_unincluded_headers/settings.hpp b/docs/examples/simple_example_with_unincluded_headers/settings.hpp new file mode 100644 index 0000000..e69de29 diff --git a/docs/examples/tools/examples_tools.sh b/docs/examples/tools/examples_tools.sh index 04d8c41..8544061 100755 --- a/docs/examples/tools/examples_tools.sh +++ b/docs/examples/tools/examples_tools.sh @@ -9,6 +9,8 @@ git_clone() git clone -b $tagName --depth 1 $gitUrl } +#------------------------------------------------------------------------------- + run_analyze() { local outPutFile="output_unix.txt" @@ -16,6 +18,8 @@ run_analyze() cat $outPutFile } +#------------------------------------------------------------------------------- + run_analyze_git_repo() { local gitUrl=$1 @@ -25,6 +29,32 @@ run_analyze_git_repo() run_analyze } +#------------------------------------------------------------------------------- + +run_cmake() +{ + local projectFolder=$1 + + mkdir build + cd build + cmake ../$projectFolder -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + cd - +} + +#------------------------------------------------------------------------------- + +run_analyze_git_repo_cmake() +{ + local gitUrl=$1 + local tagName=$2 + local projectFolder=$3 + + run_cmake $projectFolder + run_analyze_git_repo $gitUrl $tagName +} + +#------------------------------------------------------------------------------- + clean_example_dir() { local exampleDir=$1 @@ -38,6 +68,8 @@ clean_example_dir() cd - } +#------------------------------------------------------------------------------- + run_example() { local exampleDir=$1 @@ -52,4 +84,3 @@ run_example() fi } - diff --git a/docs/examples/tools/run_analyze_git_repo_cmake.bat b/docs/examples/tools/run_analyze_git_repo_cmake.bat new file mode 100644 index 0000000..a6db1dd --- /dev/null +++ b/docs/examples/tools/run_analyze_git_repo_cmake.bat @@ -0,0 +1,10 @@ +set gitUrl=%1% +set tagName=%2% +set projectFolder=%3% + +echo %gitUrl% +echo %tagName% + +call ..\tools\run_cmake.bat %projectFolder% +call ..\tools\git_clone.bat %gitUrl% %tagName% +call ..\tools\run_analyze.bat diff --git a/docs/examples/tools/run_cmake.bat b/docs/examples/tools/run_cmake.bat new file mode 100644 index 0000000..2c5d9d0 --- /dev/null +++ b/docs/examples/tools/run_cmake.bat @@ -0,0 +1,16 @@ +SETLOCAL + +set projectFolder=%1% +set back=%cd% + +mkdir build +cd build + +echo cmake ..\\%projectFolder% -DCMAKE_EXPORT_COMPILE_COMMANDS=ON +cmake ..\\%projectFolder% -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + +cd .. + +cd %back% + +ENDLOCAL \ No newline at end of file diff --git a/docs/examples/vlc/.cppinclude.json b/docs/examples/vlc/.cppinclude.json index d96e6bc..9777780 100644 --- a/docs/examples/vlc/.cppinclude.json +++ b/docs/examples/vlc/.cppinclude.json @@ -1,6 +1,6 @@ { "project_dir" : "vlc", - "ignore_system_includes" : true, + "ignore_system_includes" : false, "include_dirs" : [ "modules/", "modules/gui/qt/", @@ -29,13 +29,344 @@ "include/a52.h", "a52dec/.*", "libmtp.h", + "^ui.*.h", "matroska/.*", - "ui/.*", "sound_manager.h", "screenshooter-client-protocol.h", "server-decoration-client-protocol.h", "viewporter-client-protocol.h", - "xdg-shell-client-protocol.h" + "xdg-shell-client-protocol.h", + + "sys/.*.h", + "dvbpsi/*.h", + "libavcodec/avcodec.h", + "xcb/.*.h", + "dvbpsi/.*.h", + "EGL/.*.h", + "GL/.*.h", + "GLES2/.*.h", + "IOKit/.*.h", + "OpenGL/.*.h", + "Qt.*", + "^Q.*", + "X11/.*.h", + "jack/.*.h", + "linux/.*.h", + "opencv2/.*.h", + "netinet/.*.h", + "ogg/ogg.h", + "CoreFoundation/CoreFoundation.h", + "dbus/dbus.h", + "interface/mmal/mmal.h", + "_mingw.h", + "gst/.*.h", + "gtk/.*.h", + "libavformat/.*.h", + "libavutil/.*.h", + "alsa/.*.h", + "android/.*.h", + "OpenGLES/.*.h", + "SLES/.*.h", + "Security/.*.h", + "aom/.*.h", + "aribb24/.*.h", + "aribb25/.*.h", + "avahi-client/.*.h", + "avahi-common/.*.h", + "dvdread/.*.h", + "mach/.*.h", + "media/.*.h", + "theora/.*.h", + "vpx/.*.h", + "wx/.*.h", + "interface/mmal/util/.*.h", + + "unistd.h", + "fcntl.h", + "poll.h", + "windows.h", + "initguid.h", + "dlfcn.h", + "pthread.h", + "io.h", + "search.h", + "winsock2.h", + "dirent.h", + "jni.h", + "inet.h", + "d3d11.h", + "d3d9.h", + "xlocale.h", + "gcrypt.h", + "emmintrin.h", + "netdb.h", + "wayland-client.h", + "ws2tcpip.h", + "zlib.h", + "bcm_host.h", + "direct.h", + "dshow.h", + "dxva.h", + "dxva2api.h", + "execinfo.h", + "ft2build.h", + "libzvbi.h", + "mmdeviceapi.h", + "mmintrin.h", + "mmsystem.h", + "objbase.h", + "shellapi.h", + "shlobj.h", + "spawn.h", + "va/va.h", + "valgrind/valgrind.h", + "DeckLinkAPI.h", + "DeckLinkAPIDispatch.cpp", + "altivec.h", + "audioclient.h", + "audiopolicy.h", + "bdsm/bdsm.h", + "cairo/cairo.h", + "dxgidebug.h", + "gdk/gdkx.h", + "glib-object.h", + "glib.h", + "iconv.h", + "libintl.h", + "libplacebo/shaders.h", + "librsvg/rsvg.h", + "malloc.h", + "net/if.h", + "os2.h", + "os2safe.h", + "pwd.h", + "roapi.h", + "sched.h", + "soundcard.h", + "srt/srt.h", + "syslog.h", + "unknwn.h", + "va/va_drm.h", + "vorbis/codec.h", + "winapifamily.h", + "wincrypt.h", + "winstring.h", + "wrl/client.h", + "AS_DCP.h", + "AvailabilityMacros.h", + "Base64.hh", + "BasicUsageEnvironment.hh", + "CFNetwork/CFProxySupport.h", + "CoreFoundation/CFBase.h", + "CoreServices/CoreServices.h", + "CoreText/CoreText.h", + "CoreVideo/CVOpenGLESTextureCache.h", + "Ecore.h", + "Evas.h", + "FLAC/stream_decoder.h", + "FLAC/stream_encoder.h", + "GroupsockHelper.hh", + "IOSurface/IOSurface.h", + "QuartzCore/QuartzCore.h", + "SDL_image.h", + "UsageEnvironment.hh", + "VideoToolbox/VideoToolbox.h", + "aalib.h", + "aifffile.h", + "apefile.h", + "apetag.h", + "archive.h", + "archive_entry.h", + "asffile.h", + "ass/ass.h", + "attachedpictureframe.h", + "binder/MemoryDealer.h", + "byteswap.h", + "caca.h", + "cddb/cddb.h", + "chromaprint.h", + "comcat.h", + "commctrl.h", + "cpu-features.h", + "d3dcompiler.h", + "d3dx9effect.h", + "daala/codec.h", + "daala/daaladec.h", + "daala/daalaenc.h", + "dc1394/dc1394.h", + "dca.h", + "ddraw.h", + "dsound.h", + "dvd.h", + "dvdnav/dvdnav.h", + "dwrite_2.h", + "dxgi.h", + "dxgi1_5.h", + "dxgi1_6.h", + "dxgiformat.h", + "endpointvolume.h", + "fdk-aac/aacenc_lib.h", + "features.h", + "fileref.h", + "flacfile.h", + "fluidlite.h", + "fluidsynth.h", + "fourcc.h", + "freerdp/channels/channels.h", + "freerdp/freerdp.h", + "freerdp/gdi/gdi.h", + "freerdp/settings.h", + "freerdp/version.h", + "fribidi.h", + "gdk-pixbuf/gdk-pixbuf.h", + "getopt.h", + "gio/gdbusnamewatching.h", + "glob.h", + "gme/gme.h", + "gnutls/gnutls.h", + "gnutls/x509.h", + "goom/goom.h", + "hardware/gralloc.h", + "hb-ft.h", + "hb.h", + "idna.h", + "interface/vmcs_host/vc_dispmanx.h", + "interface/vmcs_host/vc_tvservice.h", + "jpeglib.h", + "kai.h", + "kate/kate.h", + "kva.h", + "lauxlib.h", + "libavc1394/.*.h", + "libavcodec/.*.h", + "libbluray/.*.h", + "libbpg.h", + "libcrystalhd/.*.h", + "libgen.h", + "libkern/OSAtomic.h", + "libmodplug/modplug.h", + "libnotify/notify.h", + "libplacebo/shaders/colorspace.h", + "libpostproc/postprocess.h", + "libprojectM/projectM.hpp", + "libraw1394/.*.h", + "libsecret/secret.h", + "libsmbclient.h", + "libssh2.h", + "libssh2_sftp.h", + "libswscale/.*.h", + "libudev.h", + "libxml/.*.h", + "lirc/lirc_client.h", + "liveMedia.hh", + "liveMedia_version.hh", + "lm.h", + "logo_intro.h", + "lua.h", + "lualib.h", + "mach-o/dyld.h", + "machine/cpu.h", + "mad.h", + "mfapi.h", + "mferror.h", + "mfobjects.h", + "mftransform.h", + "mfx/mfxvideo.h", + "microdns/microdns.h", + "mntent.h", + "mp4file.h", + "mpc/mpcdec.h", + "mpcdec/mpcdec.h", + "mpcfile.h", + "mpeg2.h", + "mpegfile.h", + "mpg123.h", + "neaacdec.h", + "nfsc/.*.h", + "oggfile.h", + "oggflacfile.h", + "ole2.h", + "omxIP.h", + "omxtypes.h", + "opus_multistream.h", + "opusfile.h", + "png.h", + "postproc/postprocess.h", + "process.h", + "propsys.h", + "psapi.h", + "rfb/rfbclient.h", + "samplerate.h", + "sapi.h", + "schroedinger/schro.h", + "semaphore.h", + "sensors.h", + "sensorsapi.h", + "shine/layer3.h", + "shlwapi.h", + "shobjidl.h", + "shout/shout.h", + "sidplay/builders/resid.h", + "sidplay/sidplay2.h", + "soxr.h", + "spatialaudio/.*.h", + "speex/.*.h", + "speexfile.h", + "sphelper.h", + "srtp.h", + "system/window.h", + "systemd/sd-journal.h", + "tag.h", + "taglib.h", + "tbm_surface.h", + "tbytevector.h", + "tchar.h", + "termios.h", + "textidentificationframe.h", + "tiger/tiger.h", + "tiostream.h", + "tlhelp32.h", + "tremor/ivorbiscodec.h", + "trueaudiofile.h", + "twolame.h", + "uconv.h", + "uniquefileidentifierframe.h", + "upnp/upnp.h", + "upnp/upnptools.h", + "usp10.h", + "va/.*.h", + "vdpau/.*.h", + "vorbis/vorbisenc.h", + "vorbisfile.h", + "vsx_manager.h", + "w32api.h", + "wavfile.h", + "wavpackfile.h", + "wayland-egl.h", + "windows.security.cryptography.h", + "windows.storage.h", + "windowsx.h", + "wine/windef.h", + "wine/winerror.h", + "winerror.h", + "winioctl.h", + "winsock.h", + "winuser.h", + "wtypes.h", + "x262.h", + "x264.h", + "x265.h", + "wingdi.h", + + "^qpa/qplatformnativeinterface.h", + "vlc_about.h", + "^ncurses.h", + "^scsi/.*.h", + + "modules/gui/macosx/.*.h", + "modules/gui/minimal_macosx/.*.h" + + ] } diff --git a/docs/examples/vlc/output_unix.txt b/docs/examples/vlc/output_unix.txt index f85be72..811cecb 100644 --- a/docs/examples/vlc/output_unix.txt +++ b/docs/examples/vlc/output_unix.txt @@ -2,81 +2,93 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "modules/demux/adaptive/ID.hpp" impact on 78 file(s) +1 : "include/vlc_arrays.h" impact on 1581 file(s) Included by: - 1 : "modules/demux/adaptive/http/Chunk.h" line 30, impact on 73 file(s) - 2 : "modules/demux/adaptive/playlist/Inheritables.hpp" line 26, impact on 63 file(s) - 3 : "modules/demux/adaptive/ID.cpp" line 24 - 4 : "modules/demux/adaptive/playlist/BaseRepresentation.cpp" line 34 -2 : "modules/demux/adaptive/http/ConnectionParams.hpp" impact on 78 file(s) + 1 : "include/vlc_common.h" line 779, impact on 1569 file(s) + 2 : "include/vlc_events.h" line 28, impact on 424 file(s) + 3 : "include/vlc_extensions.h" line 28, impact on 15 file(s) + 4 : "include/vlc_http.h" line 37, impact on 12 file(s) + 5 : "modules/text_renderer/freetype/freetype.h" line 43, impact on 10 file(s) + 6 : "include/vlc_addons.h" line 24, impact on 9 file(s) + 7 : "include/vlc_fingerprinter.h" line 27, impact on 6 file(s) + 8 : "modules/lua/extension.h" line 28, impact on 3 file(s) + 9 : "src/input/mrl_helpers.h" line 29, impact on 3 file(s) + 10 : "modules/demux/adaptive/playlist/BaseAdaptationSet.cpp" line 33 + ... 10 of 29 details +2 : "include/vlc_threads.h" impact on 1573 file(s) Included by: - 1 : "modules/demux/adaptive/http/Chunk.h" line 29, impact on 73 file(s) - 2 : "modules/demux/adaptive/http/HTTPConnection.hpp" line 28, impact on 5 file(s) - 3 : "modules/demux/adaptive/http/AuthStorage.cpp" line 25 - 4 : "modules/demux/adaptive/http/ConnectionParams.cpp" line 24 - 5 : "modules/demux/adaptive/http/HTTPConnection.cpp" line 25 - 6 : "modules/demux/adaptive/http/HTTPConnectionManager.cpp" line 30 -3 : "modules/demux/adaptive/http/BytesRange.hpp" impact on 77 file(s) + 1 : "include/vlc_common.h" line 409, impact on 1569 file(s) + 2 : "modules/gui/qt/util/singleton.hpp" line 27, impact on 60 file(s) + 3 : "include/vlc_interrupt.h" line 28, impact on 57 file(s) + 4 : "modules/demux/hls/playlist/M3U8.hpp" line 25, impact on 6 file(s) + 5 : "modules/demux/mkv/Ebml_dispatcher.hpp" line 31, impact on 3 file(s) + 6 : "modules/codec/omxil/mediacodec.c" line 40 + 7 : "modules/codec/x265.c" line 33 + 8 : "modules/demux/adaptive/PlaylistManager.cpp" line 42 + 9 : "modules/demux/adaptive/http/Downloader.cpp" line 26 + 10 : "modules/gui/skins2/src/skin_main.cpp" line 34 + ... 10 of 18 details +3 : "include/vlc_configuration.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/http/Chunk.h" line 28, impact on 73 file(s) - 2 : "modules/demux/adaptive/http/HTTPConnection.hpp" line 29, impact on 5 file(s) - 3 : "modules/demux/adaptive/http/BytesRange.cpp" line 25 - 4 : "modules/demux/adaptive/playlist/Segment.cpp" line 34 -4 : "modules/demux/adaptive/http/Chunk.h" impact on 73 file(s) + 1 : "include/vlc_common.h" line 1025, impact on 1569 file(s) + 2 : "modules/codec/avcodec/avcommon.h" line 32, impact on 17 file(s) + 3 : "modules/access/vdr.c" line 64 + 4 : "modules/gui/qt/components/simple_preferences.cpp" line 34 + 5 : "modules/hw/d3d11/d3d11_filters.c" line 31 + 6 : "src/config/core.c" line 33 + 7 : "src/win32/dirs.c" line 44 + 8 : "test/src/config/chain.c" line 30 +4 : "include/vlc_main.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/Segment.h" line 32, impact on 63 file(s) - 2 : "modules/demux/adaptive/playlist/SegmentChunk.hpp" line 25, impact on 7 file(s) - 3 : "modules/demux/adaptive/http/Downloader.hpp" line 23, impact on 4 file(s) - 4 : "modules/demux/smooth/playlist/MemoryChunk.hpp" line 23, impact on 2 file(s) - 5 : "modules/demux/adaptive/http/Chunk.cpp" line 28 - 6 : "modules/demux/adaptive/logic/NearOptimalAdaptationLogic.cpp" line 30 - 7 : "modules/demux/adaptive/logic/PredictiveAdaptationLogic.cpp" line 31 - 8 : "modules/demux/adaptive/logic/RateBasedAdaptationLogic.cpp" line 33 - 9 : "modules/demux/adaptive/plumbing/SourceStream.cpp" line 28 - 10 : "modules/demux/adaptive/tools/Retrieve.cpp" line 29 -5 : "modules/demux/adaptive/playlist/Url.hpp" impact on 73 file(s) + 1 : "include/vlc_common.h" line 1024, impact on 1569 file(s) +5 : "include/vlc_messages.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/ICanonicalUrl.hpp" line 23, impact on 72 file(s) - 2 : "modules/demux/adaptive/playlist/Url.cpp" line 24 -6 : "modules/demux/adaptive/playlist/ICanonicalUrl.hpp" impact on 72 file(s) + 1 : "include/vlc_common.h" line 1021, impact on 1569 file(s) + 2 : "modules/access/rtsp/real.c" line 33 + 3 : "modules/access/rtsp/real_rmff.c" line 29 + 4 : "modules/access/rtsp/rtsp.c" line 33 + 5 : "src/misc/httpcookies.c" line 34 +6 : "include/vlc_mtime.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/Segment.h" line 31, impact on 63 file(s) - 2 : "modules/demux/adaptive/playlist/SegmentInfoCommon.h" line 33, impact on 58 file(s) - 3 : "modules/demux/adaptive/playlist/SegmentInformation.hpp" line 23, impact on 42 file(s) - 4 : "modules/demux/adaptive/playlist/AbstractPlaylist.hpp" line 27, impact on 32 file(s) - 5 : "modules/demux/adaptive/playlist/SegmentChunk.hpp" line 24, impact on 7 file(s) -7 : "modules/demux/adaptive/tools/Properties.hpp" impact on 72 file(s) + 1 : "include/vlc_common.h" line 408, impact on 1569 file(s) + 2 : "modules/control/dbus/dbus.c" line 63 + 3 : "modules/video_filter/oldmovie.c" line 39 + 4 : "modules/video_filter/vhs.c" line 37 + 5 : "test/libvlc/media_list_player.c" line 28 +7 : "include/vlc_objects.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/Inheritables.hpp" line 23, impact on 63 file(s) - 2 : "modules/demux/adaptive/playlist/Segment.h" line 33, impact on 63 file(s) - 3 : "modules/demux/adaptive/playlist/SegmentInfoCommon.h" line 34, impact on 58 file(s) - 4 : "modules/demux/adaptive/playlist/SegmentInformation.hpp" line 24, impact on 42 file(s) - 5 : "modules/demux/adaptive/playlist/AbstractPlaylist.hpp" line 28, impact on 32 file(s) - 6 : "modules/demux/adaptive/playlist/BasePeriod.h" line 31, impact on 19 file(s) - 7 : "modules/demux/adaptive/playlist/SegmentTemplate.h" line 28, impact on 12 file(s) - 8 : "modules/demux/adaptive/playlist/SegmentBase.h" line 30, impact on 3 file(s) - 9 : "modules/demux/hls/playlist/Representation.hpp" line 25, impact on 3 file(s) -8 : "modules/demux/adaptive/StreamFormat.hpp" impact on 69 file(s) + 1 : "include/vlc_common.h" line 1022, impact on 1569 file(s) +8 : "include/vlc_variables.h" impact on 1570 file(s) Included by: - 1 : "modules/demux/adaptive/SegmentTracker.hpp" line 23, impact on 31 file(s) - 2 : "modules/demux/adaptive/playlist/BaseRepresentation.h" line 33, impact on 29 file(s) - 3 : "modules/demux/adaptive/playlist/BaseAdaptationSet.h" line 33, impact on 27 file(s) - 4 : "modules/demux/adaptive/Streams.hpp" line 24, impact on 17 file(s) - 5 : "modules/demux/dash/mpd/MPD.h" line 29, impact on 9 file(s) - 6 : "modules/demux/adaptive/playlist/SegmentChunk.hpp" line 26, impact on 7 file(s) - 7 : "modules/demux/hls/playlist/Representation.hpp" line 26, impact on 3 file(s) - 8 : "modules/demux/adaptive/StreamFormat.cpp" line 25 - 9 : "modules/demux/dash/mpd/DASHCommonAttributesElements.cpp" line 31 -9 : "modules/demux/adaptive/Time.hpp" impact on 67 file(s) + 1 : "include/vlc_common.h" line 1023, impact on 1569 file(s) + 2 : "modules/codec/avcodec/avcommon.h" line 33, impact on 17 file(s) + 3 : "modules/access/dsm/access.c" line 35 +9 : "include/vlc_common.h" impact on 1569 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/Inheritables.hpp" line 27, impact on 63 file(s) - 2 : "modules/demux/adaptive/playlist/Segment.h" line 34, impact on 63 file(s) - 3 : "modules/demux/smooth/playlist/Manifest.hpp" line 25, impact on 6 file(s) -10 : "modules/demux/adaptive/playlist/Inheritables.hpp" impact on 63 file(s) + 1 : "include/vlc_viewpoint.h" line 24, impact on 974 file(s) + 2 : "include/vlc_es.h" line 27, impact on 971 file(s) + 3 : "modules/gui/skins2/src/skin_common.hpp" line 32, impact on 230 file(s) + 4 : "modules/gui/qt/qt.hpp" line 32, impact on 134 file(s) + 5 : "include/vlc_vout_window.h" line 29, impact on 91 file(s) + 6 : "modules/demux/adaptive/http/ConnectionParams.hpp" line 23, impact on 78 file(s) + 7 : "modules/demux/adaptive/http/BytesRange.hpp" line 23, impact on 77 file(s) + 8 : "modules/demux/adaptive/playlist/Url.hpp" line 25, impact on 73 file(s) + 9 : "modules/demux/adaptive/Time.hpp" line 23, impact on 67 file(s) + 10 : "include/vlc_bits.h" line 28, impact on 45 file(s) + ... 10 of 982 details +10 : "include/vlc_text_style.h" impact on 977 file(s) Included by: - 1 : "modules/demux/adaptive/playlist/SegmentInfoCommon.h" line 30, impact on 58 file(s) - 2 : "modules/demux/smooth/playlist/Manifest.hpp" line 24, impact on 6 file(s) - 3 : "modules/demux/smooth/playlist/ForgedInitSegment.hpp" line 24, impact on 2 file(s) - 4 : "modules/demux/adaptive/playlist/BaseAdaptationSet.cpp" line 37 - 5 : "modules/demux/adaptive/playlist/Inheritables.cpp" line 25 -... 10 of 446 files + 1 : "include/vlc_es.h" line 29, impact on 971 file(s) + 2 : "include/vlc_subpicture.h" line 33, impact on 482 file(s) + 3 : "modules/codec/substext.h" line 25, impact on 10 file(s) + 4 : "modules/text_renderer/freetype/freetype.h" line 42, impact on 10 file(s) + 5 : "modules/spu/dynamicoverlay/dynamicoverlay.h" line 29, impact on 5 file(s) + 6 : "modules/codec/ttml/substtml.c" line 31 + 7 : "modules/codec/webvtt/css_style.c" line 25 + 8 : "modules/text_renderer/freetype/freetype.c" line 43 + 9 : "modules/text_renderer/freetype/platform_fonts.c" line 45 + 10 : "modules/text_renderer/freetype/text_layout.c" line 44 + ... 10 of 11 details +... 10 of 725 files +Unincluded headers: +1 : "modules/audio_output/coreaudio_common.h" diff --git a/docs/examples/vlc/output_win.txt b/docs/examples/vlc/output_win.txt index 2b9e8db..a37f59a 100644 --- a/docs/examples/vlc/output_win.txt +++ b/docs/examples/vlc/output_win.txt @@ -2,81 +2,93 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "modules\demux\adaptive\ID.hpp" impact on 78 file(s) +1 : "include\vlc_arrays.h" impact on 1581 file(s) Included by: - 1 : "modules\demux\adaptive\http\Chunk.h" line 30, impact on 73 file(s) - 2 : "modules\demux\adaptive\playlist\Inheritables.hpp" line 26, impact on 63 file(s) - 3 : "modules\demux\adaptive\ID.cpp" line 24 - 4 : "modules\demux\adaptive\playlist\BaseRepresentation.cpp" line 34 -2 : "modules\demux\adaptive\http\ConnectionParams.hpp" impact on 78 file(s) + 1 : "include\vlc_common.h" line 779, impact on 1569 file(s) + 2 : "include\vlc_events.h" line 28, impact on 424 file(s) + 3 : "include\vlc_extensions.h" line 28, impact on 15 file(s) + 4 : "include\vlc_http.h" line 37, impact on 12 file(s) + 5 : "modules\text_renderer\freetype\freetype.h" line 43, impact on 10 file(s) + 6 : "include\vlc_addons.h" line 24, impact on 9 file(s) + 7 : "include\vlc_fingerprinter.h" line 27, impact on 6 file(s) + 8 : "modules\lua\extension.h" line 28, impact on 3 file(s) + 9 : "src\input\mrl_helpers.h" line 29, impact on 3 file(s) + 10 : "modules\demux\adaptive\playlist\BaseAdaptationSet.cpp" line 33 + ... 10 of 29 details +2 : "include\vlc_threads.h" impact on 1573 file(s) Included by: - 1 : "modules\demux\adaptive\http\Chunk.h" line 29, impact on 73 file(s) - 2 : "modules\demux\adaptive\http\HTTPConnection.hpp" line 28, impact on 5 file(s) - 3 : "modules\demux\adaptive\http\AuthStorage.cpp" line 25 - 4 : "modules\demux\adaptive\http\ConnectionParams.cpp" line 24 - 5 : "modules\demux\adaptive\http\HTTPConnection.cpp" line 25 - 6 : "modules\demux\adaptive\http\HTTPConnectionManager.cpp" line 30 -3 : "modules\demux\adaptive\http\BytesRange.hpp" impact on 77 file(s) + 1 : "include\vlc_common.h" line 409, impact on 1569 file(s) + 2 : "modules\gui\qt\util\singleton.hpp" line 27, impact on 60 file(s) + 3 : "include\vlc_interrupt.h" line 28, impact on 57 file(s) + 4 : "modules\demux\hls\playlist\M3U8.hpp" line 25, impact on 6 file(s) + 5 : "modules\demux\mkv\Ebml_dispatcher.hpp" line 31, impact on 3 file(s) + 6 : "modules\codec\omxil\mediacodec.c" line 40 + 7 : "modules\codec\x265.c" line 33 + 8 : "modules\demux\adaptive\PlaylistManager.cpp" line 42 + 9 : "modules\demux\adaptive\http\Downloader.cpp" line 26 + 10 : "modules\gui\skins2\src\skin_main.cpp" line 34 + ... 10 of 18 details +3 : "include\vlc_configuration.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\http\Chunk.h" line 28, impact on 73 file(s) - 2 : "modules\demux\adaptive\http\HTTPConnection.hpp" line 29, impact on 5 file(s) - 3 : "modules\demux\adaptive\http\BytesRange.cpp" line 25 - 4 : "modules\demux\adaptive\playlist\Segment.cpp" line 34 -4 : "modules\demux\adaptive\http\Chunk.h" impact on 73 file(s) + 1 : "include\vlc_common.h" line 1025, impact on 1569 file(s) + 2 : "modules\codec\avcodec\avcommon.h" line 32, impact on 17 file(s) + 3 : "modules\access\vdr.c" line 64 + 4 : "modules\gui\qt\components\simple_preferences.cpp" line 34 + 5 : "modules\hw\d3d11\d3d11_filters.c" line 31 + 6 : "src\config\core.c" line 33 + 7 : "src\win32\dirs.c" line 44 + 8 : "test\src\config\chain.c" line 30 +4 : "include\vlc_main.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\Segment.h" line 32, impact on 63 file(s) - 2 : "modules\demux\adaptive\playlist\SegmentChunk.hpp" line 25, impact on 7 file(s) - 3 : "modules\demux\adaptive\http\Downloader.hpp" line 23, impact on 4 file(s) - 4 : "modules\demux\smooth\playlist\MemoryChunk.hpp" line 23, impact on 2 file(s) - 5 : "modules\demux\adaptive\http\Chunk.cpp" line 28 - 6 : "modules\demux\adaptive\logic\NearOptimalAdaptationLogic.cpp" line 30 - 7 : "modules\demux\adaptive\logic\PredictiveAdaptationLogic.cpp" line 31 - 8 : "modules\demux\adaptive\logic\RateBasedAdaptationLogic.cpp" line 33 - 9 : "modules\demux\adaptive\plumbing\SourceStream.cpp" line 28 - 10 : "modules\demux\adaptive\tools\Retrieve.cpp" line 29 -5 : "modules\demux\adaptive\playlist\Url.hpp" impact on 73 file(s) + 1 : "include\vlc_common.h" line 1024, impact on 1569 file(s) +5 : "include\vlc_messages.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\ICanonicalUrl.hpp" line 23, impact on 72 file(s) - 2 : "modules\demux\adaptive\playlist\Url.cpp" line 24 -6 : "modules\demux\adaptive\playlist\ICanonicalUrl.hpp" impact on 72 file(s) + 1 : "include\vlc_common.h" line 1021, impact on 1569 file(s) + 2 : "modules\access\rtsp\real.c" line 33 + 3 : "modules\access\rtsp\real_rmff.c" line 29 + 4 : "modules\access\rtsp\rtsp.c" line 33 + 5 : "src\misc\httpcookies.c" line 34 +6 : "include\vlc_mtime.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\Segment.h" line 31, impact on 63 file(s) - 2 : "modules\demux\adaptive\playlist\SegmentInfoCommon.h" line 33, impact on 58 file(s) - 3 : "modules\demux\adaptive\playlist\SegmentInformation.hpp" line 23, impact on 42 file(s) - 4 : "modules\demux\adaptive\playlist\AbstractPlaylist.hpp" line 27, impact on 32 file(s) - 5 : "modules\demux\adaptive\playlist\SegmentChunk.hpp" line 24, impact on 7 file(s) -7 : "modules\demux\adaptive\tools\Properties.hpp" impact on 72 file(s) + 1 : "include\vlc_common.h" line 408, impact on 1569 file(s) + 2 : "modules\control\dbus\dbus.c" line 63 + 3 : "modules\video_filter\oldmovie.c" line 39 + 4 : "modules\video_filter\vhs.c" line 37 + 5 : "test\libvlc\media_list_player.c" line 28 +7 : "include\vlc_objects.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\Inheritables.hpp" line 23, impact on 63 file(s) - 2 : "modules\demux\adaptive\playlist\Segment.h" line 33, impact on 63 file(s) - 3 : "modules\demux\adaptive\playlist\SegmentInfoCommon.h" line 34, impact on 58 file(s) - 4 : "modules\demux\adaptive\playlist\SegmentInformation.hpp" line 24, impact on 42 file(s) - 5 : "modules\demux\adaptive\playlist\AbstractPlaylist.hpp" line 28, impact on 32 file(s) - 6 : "modules\demux\adaptive\playlist\BasePeriod.h" line 31, impact on 19 file(s) - 7 : "modules\demux\adaptive\playlist\SegmentTemplate.h" line 28, impact on 12 file(s) - 8 : "modules\demux\adaptive\playlist\SegmentBase.h" line 30, impact on 3 file(s) - 9 : "modules\demux\hls\playlist\Representation.hpp" line 25, impact on 3 file(s) -8 : "modules\demux\adaptive\StreamFormat.hpp" impact on 69 file(s) + 1 : "include\vlc_common.h" line 1022, impact on 1569 file(s) +8 : "include\vlc_variables.h" impact on 1570 file(s) Included by: - 1 : "modules\demux\adaptive\SegmentTracker.hpp" line 23, impact on 31 file(s) - 2 : "modules\demux\adaptive\playlist\BaseRepresentation.h" line 33, impact on 29 file(s) - 3 : "modules\demux\adaptive\playlist\BaseAdaptationSet.h" line 33, impact on 27 file(s) - 4 : "modules\demux\adaptive\Streams.hpp" line 24, impact on 17 file(s) - 5 : "modules\demux\dash\mpd\MPD.h" line 29, impact on 9 file(s) - 6 : "modules\demux\adaptive\playlist\SegmentChunk.hpp" line 26, impact on 7 file(s) - 7 : "modules\demux\hls\playlist\Representation.hpp" line 26, impact on 3 file(s) - 8 : "modules\demux\adaptive\StreamFormat.cpp" line 25 - 9 : "modules\demux\dash\mpd\DASHCommonAttributesElements.cpp" line 31 -9 : "modules\demux\adaptive\Time.hpp" impact on 67 file(s) + 1 : "include\vlc_common.h" line 1023, impact on 1569 file(s) + 2 : "modules\codec\avcodec\avcommon.h" line 33, impact on 17 file(s) + 3 : "modules\access\dsm\access.c" line 35 +9 : "include\vlc_common.h" impact on 1569 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\Inheritables.hpp" line 27, impact on 63 file(s) - 2 : "modules\demux\adaptive\playlist\Segment.h" line 34, impact on 63 file(s) - 3 : "modules\demux\smooth\playlist\Manifest.hpp" line 25, impact on 6 file(s) -10 : "modules\demux\adaptive\playlist\Inheritables.hpp" impact on 63 file(s) + 1 : "include\vlc_viewpoint.h" line 24, impact on 974 file(s) + 2 : "include\vlc_es.h" line 27, impact on 971 file(s) + 3 : "modules\gui\skins2\src\skin_common.hpp" line 32, impact on 230 file(s) + 4 : "modules\gui\qt\qt.hpp" line 32, impact on 134 file(s) + 5 : "include\vlc_vout_window.h" line 29, impact on 91 file(s) + 6 : "modules\demux\adaptive\http\ConnectionParams.hpp" line 23, impact on 78 file(s) + 7 : "modules\demux\adaptive\http\BytesRange.hpp" line 23, impact on 77 file(s) + 8 : "modules\demux\adaptive\playlist\Url.hpp" line 25, impact on 73 file(s) + 9 : "modules\demux\adaptive\Time.hpp" line 23, impact on 67 file(s) + 10 : "include\vlc_bits.h" line 28, impact on 45 file(s) + ... 10 of 982 details +10 : "include\vlc_text_style.h" impact on 977 file(s) Included by: - 1 : "modules\demux\adaptive\playlist\SegmentInfoCommon.h" line 30, impact on 58 file(s) - 2 : "modules\demux\smooth\playlist\Manifest.hpp" line 24, impact on 6 file(s) - 3 : "modules\demux\smooth\playlist\ForgedInitSegment.hpp" line 24, impact on 2 file(s) - 4 : "modules\demux\adaptive\playlist\BaseAdaptationSet.cpp" line 37 - 5 : "modules\demux\adaptive\playlist\Inheritables.cpp" line 25 -... 10 of 446 files + 1 : "include\vlc_es.h" line 29, impact on 971 file(s) + 2 : "include\vlc_subpicture.h" line 33, impact on 482 file(s) + 3 : "modules\codec\substext.h" line 25, impact on 10 file(s) + 4 : "modules\text_renderer\freetype\freetype.h" line 42, impact on 10 file(s) + 5 : "modules\spu\dynamicoverlay\dynamicoverlay.h" line 29, impact on 5 file(s) + 6 : "modules\codec\ttml\substtml.c" line 31 + 7 : "modules\codec\webvtt\css_style.c" line 25 + 8 : "modules\text_renderer\freetype\freetype.c" line 43 + 9 : "modules\text_renderer\freetype\platform_fonts.c" line 45 + 10 : "modules\text_renderer\freetype\text_layout.c" line 44 + ... 10 of 11 details +... 10 of 725 files +Unincluded headers: +1 : "modules\audio_output\coreaudio_common.h" diff --git a/docs/slides/2020_cppcon2020_small_talk.pdf b/docs/slides/2020_cppcon2020_small_talk.pdf new file mode 100644 index 0000000000000000000000000000000000000000..fc4da46d2cefbc48b4acc3b766d537cd54c9d648 GIT binary patch literal 796116 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⪙3Y1=fMOmSQKfknYp3ra23%~bKJ^rCJ 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

eJO7gk3e#PebpQHuC9fQlp#12q| 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�g%=&0ILVH9#a}{Lt9<$?FSt6f0*(u%A>{nnI9_}(Y<98 z_%eifL<(Jm<~;_fq%IU$n}lWSZOv`m0w98=I=vm=r+ygZD!2f=Ar`RU!0_(24fwwg z(!NaJq7NJZoCO;rffOiUUNu-xQO%729@vPMi7}|h0jq4l`n0sSEG>=5;h8}30?@K< z6o6QFAf6CIF& z+4d>U$nVBtrkg%hJ+2LkqA@L4nhM>W$VSJk)y)^>tLQ3JZ`wlu;XcwcA(%MkZt7SSMwT^bTsNEY+|Vq zGEH-Fm4GjS;FWym3uPrsOS)mq_18qNf&_+#y5ZsA@?bMy?GoeTb8EFk+@qtTLmDYu zj{-oBmnrH?)J?f568*e}(;vwH%fT{%h`?8+DE>#X`Ttp;wlWxvvAKA%h} zrEomQMh%kAy8PXX&V8Myi_>F_HJc%mp7IH+^5!q;r~~K~_MLqTc-bhEoRkD7(j@JM z@PQ(rEfU|jY2xbS>HfD#W7u)8YC_;VmuGkr`pCH&6nBLnR8fDA->Tu0q$Rqj=qCoG%+)R#hcy6I=QF z^<+sAr4Wgik8%S%+^WyH(hQgmoF)4PMnoo)H%>7+;KR#4??kB>Z15a+WrT*pi=OXK z&^1ggD!+L%eEhRr*Hi!y#_&?!2f0L{W*-3$4UZc#k&kYPM2f=udDGfTYXuG(ZYVAI ztsFK~f&I&%RyOkjbv7XX_XTP&C0dVpnpdny%ib;J9hBzL<_Wt&*Egg>br3?gTK%88 z=w#eVKGp1lX=ES-v%hmI-TdLyl%?L=XrZYzub1}atmyr3sjI6He8cq^bWwBx9E4a} z*+?{U#3+)jd1Zr55N@9Yp zV9w{TvH*-w!kIX?nShQv;CQBlhcUux%{c6V8^=2M=iJ=i597C!sLfU?a`zVgT-lc+ zOzJK6%cPR5HxyGy)+-6vBfxYrlY#TNY;7Y|RS z`hibGD%Z{kJH&i~mfwEK?f1F_%sW8zGR^kC4|WBTQ*p8SY9g_{dp;lr9d5vW*vs^M z8{>v$$n{ofuYe3R)BbS*Ac_hLTZi)i(YQMr0fmBp)Y?NOTuJtIkZLzTJifnKQgd5w za_G1@K=n1syE~dwN|_{>+V~bj%pYUG=mfVY1@D_Dr4#uH4;~{?CF@mq&}XT#&Mi3c zqS*7mL)^a;6$|v)K0SW3w*3*fHQ2&hpJlYQwL|e1JXxHP7G|SSpS_fV)sPJqGarhh zBUK4pgVtwAKLM@QA3reqOW_?41zCpm&P0TKOyi@BbBl`LIR84{oQ8|IY$Lb@bbOu# z%0a!f#ALlZeZ^@%2@^_=KiMzV!A^(z9$spKm|2VX0%f!gEG^ZmH%dx7pM&kL8|Mx0 z_RFi^l2@8&QJL+`^-R1aZ!?Z1rjd=T(p)$@y(MR#e{j2u$eQ1=*W(Wk328EoC4KI@ zX6~?WW)!&2;S^i-ddKIX@UftPrUWM;*pzc76O) z-jegz!Zh~3N}A2pT!W`MFdibU_sxwSWPj`IAd{i^fF2HXwO6I`!05_#927h(^1nO` z#m)?pGB@AmVJRr~U)T+z0)>>)MfmuL!p4C&ZhKXJaGvws$l!2?Xj&pn9o?az<;S3_RTR zu@PyiYG<92r?wtfXvD<+TDmk`k+DW<`aWfKXA}GT{-p4T0tqhl^NmvwcKl$2XU%akTgzX?!O=-Sg#T839v!V`CQjyzpQl$Cs& zTmI0r)zl)c!(rp`VTK^}S5{QmH#G%RtgNgEaynb+F2Y7})0q22qH#)K97T79u?c;Q zskFy1oSLfFMU;kTl%S3SWje3h#@>8(WgztI9DT5_G&Lnb5yRz1UV?9j+af`G=x>QFgOAKG{n z-WuVOZ?6&gs!IO+9DXx8EbN(7=Yk%ax3c20IhE2d5x2!CS z3JgIziEezIntEhS1_vAd7xk2tpHml+P0T;uejY%hk-#9u_r)ajhI?L4VQ)@LlouJ6 zf<+Gb%6fofpfM9wWng4Ef>16nwYV(jc5sCYlakt+swK9ujiZ#tB#5Z(!nAy~X6+eVh>MZ`vSSv>HmC(ng(o)hNR@(DC#Ke$) zf5yzb`Wh#z<^y##8zsdG9h2VPu-YMh%->EbR4^Z<;RUyMkELEErQem-yHb(#5C8mm z&cyVHej9ijM^IGMg_=zuZxDZ#l>9`KI42{kjEtNmcjjJoZR+)<1 zLg~=ZFIrkF4zi)Kakk*Z^mO6DL3W8^3k!TsN%KWna#etmkPJLo!eEmE1H!A6WY2F) zOX;lOdAK+}$2+u+CV%|^;H=A_E#7WpFHbJ$}U8Noh7njJD>i(TdSmzO0K2bYI^)p8T~cWdnW-yR*8pH*U&(f$1T{ zNUTaMPnD1JP5u7!6`C#iLGLREltPLGKK7IKTVo)59eY)By$WoZ{=cGaz%VOO`O44p zztN-a-493Q@vJ5sgBWi#%Qi@~f4m$f-YZrSSemvXYOILK@n?|d72R2)B6=1dV4RDm z=!MwXL#j_6UKr%r;-)dTU5;TJG??+w6=jx^QVFr>gt5S&POlBj6cM5}33|85ssHH;rGvE`b1?0mX3LWPNu$ccc*2{oA2UuVqbRr7v*d&Asc*L`9s^ zla2G`HSL;FqCqCM$Y24bqKsOTpzFE&&1Iwo{ve~Ap^6y9Z!j{(=!@ZP+wTMTd-C<+ z9mBKgHeXHp%H=Puv_pJDzl}$wEwOv)vRFicow=>vT$A{+xC2K#T0HzYdft8I*XERH zOled^0+)hygn`&9WFcIqqxH(>#_PZZ*kT1`v*LTZ`-{txYUjS@A@RMzaj`hhb?H;Y zV4I4rE|=d*8~o17&N>2`K1{=u!@skD!L5XmG(M@w;2a-9H59r?RBmT?&m*m^dfG0{ zMKYqLWr)(DrEgXS;BD#;+u=u0x+-UzjA-uqzoG?=sY= zHhL>`AA~K<2qU?$(PV!^l_%2g}+yb(>KogamLj`m|NIs#nyq{Yzk& zsnuJTx9TnZEm7#CpXPnqQBt%;cqI&w^CDt^&o=k%!FtME6m}LzaeIS73X(kqWkXvV zo0rWn@UgQxg{*D&_q{929UTv3WFapKnX*+B^$V+wsAcwk>E;=Z|IC;20cIt1+GNDS z=#&=u!sP)2ndLx+CHKW8(xhaq-05S-gA}dQDIPE8pJ+s~m)a%TcN`DBCSOce^nyLQ zJ-Tm&+<9E@%lE6Fr9aCIa^~~2bhL6$g@riVnka|iIB%ieM89o+tA${sgp_W6pJl_3 zmPfM0S;3S{ET(=o*%rv!!l{w zD17OapMr&p0leQ><~?cndP=viZ`kYcB?l)b2h;1;-tb7z_qN0L;5MNYQjBpYznnSYFi7~ns?z3r{-F$=nfua!(eP2IBiWpO3hlfIi)RIP3uK|A#sUL9MNo8OX6 zFN=il#_7@I0(m*-;Y0BUEwrh^_9A{WmDT~?;3fu#se}y`A_n@fcAS4synt`t$5<82 z665nCqcXDMYV?gDi;Kd-<;U;2Gcq<66egSY7B5puBRB199 zgg0wxmMSdQtogJVLsuiRoc%RB=hRN?o(S&a*Y=Qhad*hE;&(zVv0mPnoQ7Xqv6AA+l6bFp zyqs4|OQcMhIk8hIdC5pPbaK{YM0`Jz4GDh&65I$!k0tl{s#C2g?cWObM#gOqOO>Z6 zA6ZWHV?;vAtB0x<(ie&U`6~W7m}6s&=-%$uG%gvT@Ts|d>!&4jRBf#|G?gF9-$$oD zJd|vAzeCy_9$FZB6BsBvVy>Ml;Qu61TYKJGTy=cx6%sNSSK@JWtERugyrQn{eTOhh z{WJT`o37Y!uc?`ts?xidU;b4WBs3nmhdqlw>Q@pFI7H1~b!gL9rsE0Pt1Zyb2`PF= z`yOH*dCIIsBN6q_Cc7t5f_%gqgpo@Z-v{N`3^WzVVm+?r;Dr!`i}oRX^Da6s)P^9k zyW1;+?5-}=scz*p9KUnFrMrC*qA)1Ms?o52_aE#GY#mtN9T?|iNyrNi_LsSo`aHmQ z;8;!G%@d)|03naZaHX;dEpVW-MRo*nlPyHrlO2>D$C&@ePwf9JN!XG}PTcW$Xd|ii zf2wS1+!6g~TDIL@ z12u9%Zhi>of)l^ATy6e(e|UhPzNJ5(&yvNQ1$l^y2|%=Va3!DD!A=?ZRzbP`Mys9 zk1y!jg1}2CP0_bSAXWEZ`>SFsA2t4Mu@ArVyjG&~rKkBj35>}5v7 zMO}-w_ca%FNvHzoByl_HPl-vRO`ogK7Ra?ogE#pu?V}Y`J~PYp=?I2>(^6I zQQ-FGmI#9O(1q-fk87`}(LhpJxUh3qL{~&NW?>d%xo|8`Mm@q@jE{mv$s%si3`nq& z=o$PpjVnvvFtUATV~EYlx2qg+H2}>3&>;rawl?ze^7*{iClkcHObB-|y>%v1ZRzQ- zNYm2>r%C1Y?zUQ*i8_-MZTmK-*K5qN1ZbJzX|4@2{H~Vx+w~uS#I9z(9DHf@56|O< z4QXx2#*^kc0b-(8f-#!kQ?V8`b+4}Mnm@ZDiF{Td@z&+gG3sMAEbAK9-3_ZeS+3j=Att)^U75ZhpOO;gcL2d~_1 zL-p`Egtkgq(J&$ECNMZTghA1bb}gC0PvN5oVnTc)wjl2pM2zX;-|3QOF$;k04zwp- zU0sPQ5vM8*(nkXuk`4FUOl1OdIHxv-)+L|aWDBUSKp^DWW8%`Gma{Te>nrbj!^iu6 zNONiQz`kp-ksb@{(R?X~4v&YA7QdhIQS$@kfwV=y+x3j?!zCx>-fV=4rL>S5)XUs_ zo!Og9mUC%=;-8Gt+K&o?Y|NHumMxPM<&9U3e3PZ(v~4S$tzEu}o=h#0fgEI+dA%7# zCBs||pcz2r7a3NQJksf~5*PZJ$+5qns7=3(rm_NOx!jZ^1`%8G`e;Pvla=M%ANr(l zgtQ+FR(Z&oIV|X2JTN00Dj~=k^%Ukl2z1mep^_bTFTQF&eVoc*HFFF zP>C!dpHYJM_s*I5&6)+dg?x)*e z8qSeU)rMmFJv`KqT-xCzZ5f95a@EZ%{}i$~85-bvfev=0Bze11idJSNM>nP*#ft!9 zRm$JFb3Q($Y(nVhBap{3NhjL^=*NrSkJ||>RcWVr+)iM>PzenoePsNT_w7#9u?dNg zHqWB(M*#JU!sJ3_)V&#zK@kgsH#aIf@&*Q)dpMT8xl*LZuyT~!2P{WX81LHEqeC$T zlroGj-I1nR`F#8k@(7_gKZ~<>SN$Q!@M)7XVow^&ix2c|J(B1;Xy;!$Mcm6$ut{Gs z+D~MOf{@I@;()xtQMxxC-L1&a@oLaoZiiY`e?=4hFo&*y@5MtN^FuC9YK1tjYy4pj z$@lmi2{(!6wUIObZ`m@wE6iK@C@+IdbaZurCjk#{UeLKp>6rjYhU?yAJ8P4bN{sT9 zQYKNW`RiBOsOei22Zu6JZgAt7d_>pKo@|uZ%<54gOj8K~I@CQJ!jkEuJ)F?_;$n2P z#v#c*Dxo7|f>f4Gn>`q-Xcyl+?n%b*7;8!Z$+H`@y#0KL6%!HRk|HXi<_j3Th4QK< zuRJ}GwQjxzyc&HgC&wM^0mS^jOY>VQI%SJ?+3nKN2t3`E_pIm#$610+&*n%f%=c$2 zmK!ye!`XsLp&BSPS|(;O_v=s6x2^cTX)Wx`2KBPTr~#aG@~uNzon%B^;G{;FZn&Xh z1u>@%XwXGNZ?r42d|ja=Kr_gdLQ zf*>Q0h@f|EZFc~*wYiyh&SnK^5+ifNwYb|KGqZG(a{yD+1ig-u)BI~uQ;}tiWmuh) zPKqmr@m5ND**GIg(I3t3qwO3Msgv_hHbZS?<$adg{ZJ+7tANX zfGL7%_2*!zIB&Dst`7FDXSIJ~d?ppv(ox$i?JCRbDX&t#J)hW7d6nD23g=s?o8a@% zcHe#yaeH-X01?d$XQTLLxij2H?*BFStUKsNzH4DuSJxq(-^#F^PRzf{ZfgMLX}}>8 zQKl!(nG#|4>stO@-ZR8_aewL1#n9K!$?2+;qcZT`i@T-da-^TZ8T8KY{opUiSGLln zUV9z12}bEnw$s@l8W_mt#0^3u!nLXXF4HH-(Z0xsHL(SEWx3_M)B~4*kAkw2|NM#>wt!fy)X%Q!W?)4P=b$( zi<=zSq6BZj9RS2DD;?lQVqlQ>21J~`pCQUqpfkn_TA^U%M$*Ll(S+sir9p{oWn*&- z?q)EB-1ra&F8>byLkT<14JFG9186mwvA7#(o{o>&Z9fUpBLqVK z5MX46h7JrmTvbNNPp5J_=M!?a)u^bA z?H_7cIHy`^4S===L2o8Dso7G4d}iLk%A(EIK-4$!&H3>XuXN~*RX_;eNkp@;EF z6+^H7$vv#^t`4^bBl+y)JzeX?O+L0Uue!K5IgFK+VIgbeEjP1Yf2Z&De{8)UP5t8c za6gm&1MlZ*XDf(fzi;=l_frVus#Zo7d7Mobz9;nSG}`MWeXQ9#I_k7rtOI?Fxg}sw zd(3zd?r^kZPE4%M0=ZC|$7TNd^icGC3SF4K~U^}&NejkX2?fPIt~UQaPypW zCi9s}Q(VuM~(r*BKM zdXe;K*3T9w3#(F&Iykd3c`>Je3&G;zBCqovxE;QNw`XsUWGcwcUJiQXz*h+;WPE(r zA0*g1P!n6*ck0;AH+5gJe>U2>giZBG@;K!@B{Fjf3#(U^K0Z8L9gj8Eas8V4u9lA< z?d=wcKX|l~${NpbGKGupjY3B9t@4e$e9qt9!b1$2P{Upq*3ISG7GZG8W;Dp$q#tPJ0r;og+H`@x`Xc!_aeNips(IwKnjr1_IW3_(#2lkPDaL;`xR zGp!ygEpdekTgxBhD;3(q#`A}$pN#!LUDHn=DXbuj{7%JAgRlmY%1E#vk; zW#hhGVl8Jc-(=Hk`&G)RzdQ##JiL8cFe3zLK~^IGDgg6fZosUexhW?nr=g*twDW6n z^7Z~~r1!zm5g^~#0TuNs&{g9$>4aSAU3F#@HfGPB7gsy_PJxO;!i^}z zpv}!|Gn~HW*>h1aVgoo6tS8pnL-8PDt}KH_C6|!UyL>d!XWW*f)?P-HJxQ#oo*{Tq zq43^39(EkzRi&WD`3aN}G87 zUYZ|ZV^CObo8+(Zqgunll^L)seZFE|D&lAhdOEVD^_Smf+YEx>q2BN-Z8xo6xcEZ9 z^kear$(3Nc%l7;>VnS+Hli6N7=i(zJhIn`sMdI}vbg_tdR$YJyqNMn>5R~5d>`8@%t;egGL1)dYZ)&Xt zIv#FsNW~0;@wy({eh0wc>jH5RgUOz!NA1fI_MN{n+-i2lG5~#_Mq~sM`*tpv;taOG z`Wm5mkBtWJ0(&+tY@8Khiou2ARhot~F2E-Cxjk)FRtAUUGPhzoXVN2ZA=A8-iTNR`MG3N_a5k5ZG$j3Rco;At`1sLOH}@?H*{hUg z^KYM?PsYm%0}9FT=x8t#Gcz-<7Gj8`dE-8)CDQmESAq76b@7YLwzjrB5?1jn9lUU9 zwNf`gOp`QuAORD&YUDvefRDyc$3DQ*4HJ-7QK8t;QNghzLuIj*l4v_mx4fL5`x~UK z7|#$irk{Wt5pbdy3~X(MehcX6D(j6b1x}KOH4R1BD*d1Ym*c_mJNoF0+c`#8wccokv7&}J8OznxA& zefuL|+^05zyRHq1-d$ZccRv%D`gNd@bE`2wH@CaHOH^NPulPS`dkdhvf^|(d2_#5x zcXyZI7Tn$4-930haCdhJ7Ti5(kYK?*xNC5oX79V_oVs_<)H%0iDC#d#6<{s?Ufo}R z{l3qO8;(FAyh&lx#OqiUG726vqXkp77#x9T8+{uKSwnFq2N{VEsWL#x{r1c$=FR8hQ@#ZrG6-%Y+jE zrS0ND9ug#!bx=KH+v%I`ZUESKVkUsfW7(B%heW~Uu*0Kd){)HRxd_()XJWo}f`Wq3 z(@nBO+O~l#fb9i{TGj@H*kb~O@I{trMpnWWc6OI2VhMrP?Ky^bi)?r+=Gl>Hx!i3H z4c|gEa^7xJ!KaaN+ue~0fl?`%{s+2FW?C9FyD)NG`>h#^I={W%VGQwW8|<#%JK31u z^)f?JCQq}3>^STO)+Dcz2ICi%7lU|y^#n`Ll;2mDP#huez~iYNJH4`XGX5&6tfW(g zM0gUglIr^!?Xe&C(%pr)gS@HZ|LtJz9OT zfj$8~MGtZVVwzP&Q3w;3t~i_|Oh@e>?Bc~lp=zrwq;gnLT5p4R9f7LG8Ta!A0kCt~ zp+=s{7f45ZMe)3yv2P zbay#9WRB{7{5{d>=Lc~=@Iy6A)Oz1wUB8oIXN3e_1O@W7wTvI9xgF?WaW^;^s&9tI z{03cu{c<+R_ok*GUr(f%?H!NJMr=f;xJ~d9?D(k;%!Lfd{3XK)Zq*$u4ZNmsaPaA>$tSi-F1REUtORmV;9b4q092#%cc3= zY1+P?`GO0I{2bRwF5*mj0~cL)edzAJ;|!%HakQ12NyKiisu5(s5(OwL{r$h~(-sxg zeuB#rb||dv7*!4F$N~wL4ZKd91AroMSzi?+R{B2EDOOuX=2wAa{M;KO(TdS3!yaG+ zZEE!J@Q`3|L4bKPwW~-8$~Ff5tQ^Gw5^l1B!*Vf^B4ro65F{r3DRaUaVmbXF(1}?$ ziq02rb#$E~ZAqkMBmMAB%y(O6Fo7C*vC*6Za-iipLDWTJ>%$P+6`E|xY72*Nbj)R$ zxJ&1w8sP*?0_NnWfE?u_F}Vzl=hUCMJYH(o%Rx!u2tOf_GrxYt_9`O)k9xwFoY5Z( zZUsl8J85gBH>zs_lvFm zPtwgEJ?*AJ%y~T&=Lb%!_dbfRGmYwkM1u=Zkdr^6D|8uv1gkfy2t0mI-XiC3RO{4K zR7^}&pL1QEoV40K*}9n^ZQr)uqBNO;$`eRAm^JII(343A zw$4}Dz22+9oDU_^o}rcjgzd!phe5XWqoc?vjU5J={$A+G^eG1kvWApBkS1ejMOvB4 zRr|ix@M*zXa*2=oW=C=QQZyTADVDN5X_l6Csl_O;lfs$xe4A;V#8_F8*>`>$W&*iL zgTLAI$;4XGNAw8LG?@YDe-zazL6h#~=F)Om?4mmb5HZy?;^N~Kwo&J5ofN%46yEfK zZ8~sKIUoeOJuWUIHl_Cb+wlYh;*wjm9G`}iw6mzi-Q{fHQn~1teUIbA`3X>ZFfq|o z1;6(Pj^B^2#z=}B-i!5RsNE8B%Xi%9#T5nh_4PV=6S)@2Clk%4&FFa4#SgVLyR9TA z1VdgE@04a^&WN`J62X2wc9NurA`qLAJLb;LDp^x^iWZBM`^&zf{aUqb$?BKq?J_N$3$0flYpYU{^-Vc6?f)Ww~c_8tWQBOxv@k=8=KmYy^&I_tI1M>^E(jJ%dHpn5f@KZ%32gWs= z4R;V6!(pG*q7MJc{%|ffvTb|4j|Dn%x#G(@6SH9=C~1h8k4wtrCURLw;!ir&`L%oD zaM)-h+I>tqQlw&jH9HqR-dQ53;%DZeQW+a-Qyna@anNh&3Ete)S$Yud%9IQKb@9j+o}v|xNR|D2!zBOTdODzwOH59V221Ae0?CF3+55^xu(9PPdPmX%1hQp*fr(%T$k6wB zH!LhH;`UJ-v=tDdUQb9CDmBUFk1sBIfk1+h8-aFUP+E8ok*7?Bw(uOR_dmDsClBK< zZ4)Snyy3w?51^uE>wpYtJUctP;5Y}eq;Mu8ZfWUZ;CBEL(JJGobHM!xh{f{7as(1@ z>u0Ut`g&LKCtXA!6@-Tikz+{S+1j#13+r2Fvz{q_zQzPX9eg~9JX&h%*g+EzMy|G-24!(;PbH9q~<4L_{^NAb|iFK(yqoJ)CI82KFV<^SQ2 z&qc3g|NeW6)XRPRAY8{- z&S%<0{TPumy5s2^FgCkVJ`e>NFPUhAn@a(HUe(`#|cAD@ZQA2wgXS{@Xd zAM(!5k%Neo zmN?>&O19$j$shNQ;t*;G8&OcOr0^mbELI`cd{dhPU%KDG(4KqTofc&v7oxWgQYUj! z8})wWwy5xK;Od6M^Jn}K!B1hE@MKqtP8G%&H$y!J4^R+No7BmoC9)-Sr(2tLtJzLL zt=SHHI(hOl1I182s2JJRIymCG#b~YdX^LF5tc)F7hxe6{8Ss^&P=V~;mml>-1?-QE z&T~x+CR9AIW6bKs)_i3k2>NxW?2kI2Vdo{GR}Jwu-rz*D5?+woaAZ*JOGMtfP3@&> z_VH{`kc^sm<5Sog$l=)h$qI1YeJ_9%_eT&@IAHf|fTo5A6Se4(Irn z+YpSE{{j!1ppKMq>+0M-a@{I_1qI{ zL3=IuJbRsA`Mi28Nzr37Xofn-z`r`?Yq0$b&`r~Cvv#;@(=-13ffCfwSpo>V2K&{g zkE3FMnkI~aDx&Tv$`~{Yz5;U}_(Y@y_~sNY2pE4R=N4|ve;Q6f#BpDIzL<^IPC5SK z>UQVK@{^mcuB2E3i)yPsDFvlUOkul0O65!`xx=zSgAvQS}#E|`L!Y3gWU zK~B1G|eSCZf*#L2gwLr`4EZW`9nbGWQh3~|t&VDCLmxr6= z{0jsWNWZnXSo72XUIlQ+rKP1$Aww`inC7Dy6ZMj1c3>+Ait8J7>*g6xB>y!=ZGdy? zw@NSnjT7F<>j{ZbCc0AZHQS1ejBGoTk6x4VDTQ;=f2LfEKB$xug!{0VNPy@&^$^p9 z935-Em(`}W6y1#Z*Yu?j=kYR6>4;~Y5C$qDy!o-XGgLXo{rx?FFF&sWJ_WEtqz>F* zdgZ;O5NpYs)b%}R(1i>KY4dvDoPuM67bGq4#$~bFYE>;5HC^5AWalG214L}nq6eTZ z&%tj2&s;jQ@jKjZ&`f;EYz_v<=OVGOlr+sY;2Hx>Popt-T=w4HUW?`0rly<6>s5Oz zD{escu&!(miUZ30!_`hgd(u(gi(N$%IuMs`W6qZzBEV{1M?5F4E_SrD^D`6=3F(zb zYIjFRN0*gkefP9MQy*xHv{h_BKR(1eR^RLuWe2GNAhABMUx5^=9ASs>J_jf}Ar89h zqeb4Kpj^-d_1h~(DJQEG&-S z1+Hy?IG7j4bG`NKy30~EFfL(?c8_)d=ALi876-DQnfJ>D&Kgs747|sn`-5iob&H*z z9Z~}>uu`XE%H{Y1z=uy+NHE03#PY2Di$Hbp;N&Y7X&rz@tM>iR$!7`Rp$l{h*#2|% zz+Fp}58|@itF&}=>F3}P&RY>ij3-_}x_k$P)&8mo(%r;gChTshLZt#X320)Lq~;yn zjF)s8(2^9>_TK1+7kp^Vb6>+*sW7_hguEp z$PX};scw&3Pnw+a>9amqqNoAn3S=uW>;~OkbS5yhsZq*jefL8>GwmEhSOIbg;%LHU@P42+$>1W3U9wdo`Z`ON}Kf*!*KdC<_*(Lpc_MzZJ-w{bsQ zK7GF;7)%16PKnf64de^KF<+=@Lmar91UxsCLXX8z!Ony*<@%jZz#a-V ztTy!(AXSJ&mDB5r?hgL2Uu7BCa6l_+G?NFa%h=d>e$M(SZHT8#wbkA3`DuR(ceZlxlkRe>xwwePC-clvwDG@@$agF-h95lp`;KTh{Le0* z>&<7QdFI5=*tu_{kxZD+#6S9d5vQ$^JXoDP265!#rR3rN z=F(I+^txqT;#j%)r57A9V(tWU`@QHEWj zU}RmcOC!7y*W9tr`oofAgPRy#zkhjQc~)ksMbu1`SVpnzf;JZ&zmh}2#tuF%_f@U` zSQQhq&H9%%h<{wq2l}Xxlu`v9YI;6Z9dDhIw$x&|A2v2Es;bL9Wi5A<1-(n7D3X#+ z=ihR2*51C&PD<8~2ubO;b#jdy{q+E4_0iVQ5MH9VS@umhA1{lPl$=A^{JfX9kM(>_ zxU`7fv3O!)qmpu?iTTMEomj(X)hQj73-X1WXPkDM_G7i>KL5)06WJ}UQg zlZ8bms>_S%?Hs+-B2y$hNh?I-hFe zv|fCFpxZ}ufE%AiQS->OU*@`PK0u$v6lJXWoj(0zJ=#g2G)|2zku7)IlHQ(Ch$hO1 z=jbRuP+WlVfwznPOCsTr0Hopd)}e5`o5|syeuU^7z8XGb9*lPb?`&ijOP`NOej$`s zb8>se#w$|+yV3i%>3H}MkQnOf&vI4dHx~U_WngRg zXgZOs!zFUVdA*@fq_C^Aq5ZX2y8z>;aba~u#z%RZs7C>Z8!iDJtt2sf(o2ppS?{!B zrt#`N?4&QrNDc8y@UwBNW1yBHMvuD-UCg7(9(9DqR; z0L$g#`|xN?!fW?a%o2FflP*sPjR&zIT)G*?aP0QgZ zB#h{I*c`6Lz}0yazR|JO@hg918(@}D7!`5GY^|NX_1PBIv!f+(Dv&lQtUH(6%5>Oq zP=gLH5|d%uEbw=9^s(S;dCzy>vtAk2v95-=L&%`k*`A@`Mi&+qoeA-7*-x7}9&99MWFQv)mWpj596x-`30KESX5!*` z_w2Bh(Kn7EsGr+3qz8SswidtOJVEn^NV@hdv`9JumyhHxl!k}^jQrs($6@i{h>p^x zp{?pF&K}a9n0Q#4lbzX0+7k)$ zez%D1JIuup$|^E%Fo^$xAuc*1C!G!*y3VBK-SPm{}skd8N^kPT>-E%`jV+mP%O?|BSW)*T8BetSB>NixpHhfJe!gOL! z56+ikSm)u#jaY-MIF=G+(9YuNeHeRti>LZBzl{e-_eSLlfwHlhsj)(?sP& z5SLD1a0IY%YH%53cnN!u)_c)3q6Zlr^cO_xgc5|uTK;V6&*5td%hcqVN2vNFy^kSc z7_lob_-x{IV?w%u(S0~xH#ajwOPs4%AXVOI;oI8tFoBe%Mm(Rr-6z3n_aJet%mDqI_burtg{>}VaO#P^l2 zFoOUl>fgBf`dZ{!gd#KXktemMqxMp-)>^kN5;==Gu1+1a5qD;C9rezJte` zi9`>peZ0STG?IyD7dK@anl5YAyu*x(F3D?{(Az7dB9QKh^ka(HN6fY+X4jv{yvyr< zqQgT45KXGNKw0fQVC2u_{(t?Y8yXKEzx;cexmR6Pm4h4m_Q@C2%)l=g+Vh&zk9y`u zCXd1FV(bbO0~u`^b0Bcxrr9m8oKPhvt>cwn$}*`%x28t)P2_=FbIP7 z1-~b_2AZ)ZEZEuvEG7f`Pv@9+%AY>nfYTa~4I+B$;aJhJp_(^lS=n~(_ zoFzspWeY6>E#6l=9u4B+mc^hxzg_gM_1?=+jjBB})ceM{3)?;X@8b?RWEX46fH%~3 zw_ip#i_c{61GG0?@D>orPzKlg!kec-?`?8bQi%6NNw|CFC~{3aLqX@E{n z{@S9l?>6|aSJVMDmC3btW3gR`MTk#{eWBJuX^YEy>F}I2!9aa9p~5&+^3y;b$T9?9 zglcKySTb6B8hi+qZkBM{cAMd}Atb{2tfps0O1)_TRrQsM&Fs1drDpLK@nZq!;n8GA z%D4Pd*>Qf!D&G3YY_w9hUzIxhj#@}!xyc6>5(AU|9L6N@kok(X)oJ0Jt3dPA+kB?k zbi{zTHo12ms?s2%i|Cnfyc$d%BuWVHYzkU zl}T_%r_r02&lVRKl|h%L)2G#GBn{GhXFCdv?w{bmGS6YPBV%A-JLy;EqSvpK7;AqS;gRY*K#u`dHQQb!FiD{L8w6 z0ug`XU_`{bi%I`*%;6&0aD%N+i~W%Y9#`KV?k>aB^<|x$t+O;&hKAnU=R9-=I_bQz zZfSLYYHpOc?5W}Qs3D^-Z+)UI|DND`sXDPW9JbtADQam9ZRfLgPsQ$^F5Z#%$Qm|BHjxhs%CJj+>pQ2vb)@bSIaehw^e99a zD%x2Z&wI()C+jgteD$&RakSSCOV|Cu?*Vn5=59?L(D$Y1jWhqR!MR*hPnHyhDlAG_ zjm*z)r(R)e+A_p4?0z6CM2X0mpd?D4Hg@!?gucLAon&1^HScv*)hTm`bT!?oYWh>_ zpVG(7nWWnqVqQI`o6*G1eAhR#*grpi3uro@Kl>{K7CUh6Z*YKb_0nYb>-%>TW?EOAoPCr3{lbijnNm|^Tlk@8GM=JoRt64V%STE6VV}FW7 zy}i3LGT+V4EKl3T$i?fz%!Gr@{R`5)5~Rr8(H3%Cp(FI5b>q#N`|U6Q=e^V0Bcrty z%N_8-Q$+I8ZYX${ZntGk^|F#9Be#IE-(jdvluZ@y*mmg%T8!j!1o5i|pWnUq;qSug z{j#d><$dUNPu{t0U#hV%o*$gqSR7)lT?Gk0a;UK|dqlCzjQbC_oUk)XnEjDtj z0x8_0^;p*7@p9idwz)a{tJGA2UHK~3(eR+X&fnkZ1Grc<{*qov;=3K%opxSvHCmWpla#~%1&k{825;A#sJmB=ba*G8gg z*F<}#pauD=G=Q|wk2%c6YA=xU1HBq~J3Sv3i=mrR2A{8~_4zkH9h)WeYKRHNO~N5W zg82uGuJ!NBn*N>!%$^VtO^VuQvwcX<9p#3GO+ApoKcWHxAQ?_Wr!;9zg1c?%0oSHM zjm;XwiTCS2->KU*g599ArnQMl!L|Y#^#^~>UccL|WHx%SoE-s~{%C^N3thP$M9&wK z^2RyzN`1XTzAAm1dHLF{6efphY^-V(I-$P=4=AF}olfjKZQBL791xwAJ_B4kc8;8@ z!f2neNXx2UWv#M%Zaif$DNPqNF76srr!EEvDu3PRxvSvoSRFv0V{Q*ciw^2st8*5V!>1uG)pLHJJdmaSOKv6Uphs9 zhB4uYQbcf4&6O@2MaHlH7{8kl|8_^uz8*G?Pdp;Gk^mu}T4N79NzfFR-iq_va&NL*3wkKzHlh0jtz z%C{|qn>~`Qyze0}sam#~I*eQ)#WW@7LdG&30}2iSspMz(5U$iUnfsF(1bx2- zPa4OHV|)EP1?3uaO;`v!Yi>r+v>B&kAw;XiMLXawktnugR-gbf%O z8DkfW?C9uTrE9$TRf&Pka!*7pAmBHYK>bj@i_srVIL6q;q{Cn@r(kPq+e{Q*@#;%f zB5A%Dyc*@7Up*y~aGArr(x#``@3JqV zNW<_l@l<)#K<6YIuL#CZa@1b$pK%?#zrOzIfWF0E!QRvptI=TVI7}&Ph^iVJ)j9n! zy#2gAfg_OM)CkkI2!P@NXflOMyH6g~8llH;?rO`c zP~?aecdo?kKNDG7S`NNd+uR3XY(~Q%p0saO6b+# zs;ZqVFS&#JF>$&E5hnjCJG;_}_1y_#Iuv4MQI(MqTLMf{&7+xe51sFp%qzH4KME&N zDK3_pYh4Sz3X;D|!D{a&(r@PoVh9h0Z?)HH%iqEtt+PblWzbkcgmGNYGBPxQ=cs0~ zRJvJx&ieK&g*?-FUqQ#EiQb8{8vCjC(Xnujkn7bQc}9YtC_n$zu4G=mZuMd1QNB!h zHl~-E7lyB*#$RdK!9kQxUtf}CA2xwR!#N>rP^CKy-XA2~Jx1A5sN(3n)`h^^woFJMb zQyCK86Mriz0(GP_&kvEO;J#g@7_$wucnVn~a*gdgn*MH5u?P#_N?tzXs8|Vb%v_O^ z^9Q8RZE^5(abZigZu3O+#O7HiS(79#bY5w()XZo%(x_L;88n1V$@!cG?qjpr2>B1e zy7sLf+KlP8)+qD@zTW~0@Il1bnHh|#SDLhPXXnG!B+I)sSnZIWLC!lWW5s}%FBJU4 z?IWk}cIqjsxs>A5nBO)=sX%P(ARZ`zuKzk4@EFuReFA*w11VY>Zzclq_tE&YI6UkL ztx6g1F$3KV78@=I_>R50Kj(g^K)b}_jG@GMPxyA6gGm;itcPwOjbc|LhTt^YHGIl_ z0z}z0pO~PCy$atMJ276WHmRn5$$$QBW^ZpFU=M;rD(qtU0Zy;Wo~(aVW2=Kn3@e!E zzycHeKLuUg$O|k>RuV0n?;T|0BBy6(Yc-A$U9l_fwq68pz*gsm6&%n6H2=p-{;&~H zZ3FcH_-o1?FjfK4Klg6UCt!MbV4OsOG_2XJxdAmsSeR$A?{pdwftrgZ&>Ts0T{}bj zGs%K~0Hj^Hz9%Jg_tdymwFX@lAg4c%5xjh-g;qvJ#?sszU^RuwX8?al1+GyuXLy}5>k|pB^vyK^I79+b zpmebk{Uy2f1}Fic!kzG-2l?;Yk2XZ59=|R}YbK}%-VJSe1!-Smvw!Ppg=OFcJH zAb*SA(_SK1?zzTWMP;9UD5ALD(Ai;{4v@+;t+u*LN!pu>V<+pYY&m)Fq<5=lsXa;e zfns4&Se)*v93&PLemi$7Jclyf*DhgSwprj0V&aooU5652^WKb*__UU|Lw?L~0Q7|kMLMI{vdzeTrw8fPrvdhJl{-Ql)o}fV`O2F+eh1T^I`yjJ!lt&psEig zbXi>={p~yM>6aj(YLTTf%ti;u}5)-*Vd%j-)4 z^o+5az6rGDaY<~6)b=#ZFzGfrHlAa9^a7NXchxjIJ$QDdY&@a56Y8QGBXhCD&uV&0 zPKCdW#^}b*rMH$Yl%V~oewKm9{z*oa)AIb=CfG7bKnyV^IaAhG)$LyDFoMPUAuz~0 z+}6ehgF$C*e4NOlGdo)!Oc0uy*quy&+huf+wGpz>R?Gzt;7FUBn-6Bn-@iv4Ws^)H zLR?utn5BKXtZcjalt{7Ers#ELGM2siv%mlMh^+UYj|3bi1rm!cb$9grYYB6sk)cVNq!Z7 zmz+f-S{mKo%MiK6p)o5GDJd!GABywEs$uJ+_yvrG$wac~D4#Z^F+T4nrmL~x;mN;x z$Q0dQ8*i>x4_J<~rJ0Glj?PWra!gvg)?WZubaVMpJr;J;pMoll+*8A0a`L#ZP?yW8 zul-;Krr9@G1B7h0)czvwNQY_fpx4(lI>|eoa8(qoTm6*@scJgD<{r@`HDrF{K7>nM zSR_qv8?aaRt?zBy;PGEXwrn(Wa9YS)61Lrh^*TYIm87S;n}nFS3+(Y|73)u*_s0#A z-d#}bJL*g0;S=-A=9ppdehMef%t2asI+up$XuYeqMqi4k&b!ji$R$Rg+cpaoweq>J z$j!n4tp$VBq@>knm-mCUDtyuud4|7($U;`l^|FDAdi=}LD{(8f3YCHePRGoBdE%`n zRt^)F5Q8#|@cK+N#g%%~8n66pJ4q>W3kYpDc^Ae`1v~d=oAiKY16T}F3=XzL%Vqrn zTdSL(penG_Ga7DaNa}o?NyP|n4UcVFufS-~30A;D``M226P9_Dt=EX%?P}oSBi<&3 zf*B}>#OC?w=L2Un=n|#g?ugPwMMsNwj3kQ4g#JMKtUdBfw#vHrx1*nP-|O?o6ohXE z%yaEL)@$7s=H}M4wBZ*n(Vsuh+>1L~eWLQ%Q}S@ALbVb;_CX{a8Lh=K$epcc~AyCyR}VQ`z))&XuKHg(1hJjFKGgJ8V&6mfo=U66|F|d%kxYC9+5QoE*&n+&FrE?%6x0T@v)xm4ZSeOD2959RMF2i;c4Hya0Ud#@R zK-Z)Y{lfo`7uoPcDN|wL9+2*pnUPUPAcPbknM;cSPJkP$s*db|{c2)sx2CB8h^lU1 za|97Vla8BK3*~+uKx|?L?zJxr;bo6lJpOOJ zJowcUBFOwZ1Hadxi%&~E*=^4U4q{-wuZVP^T?h068MYuggY`&*xiIXDc7?mOCn&W=}eG zSKH1eM{sAmS+6g5XOf;Sjuzebr%G(O{E2C3XkJWInVHKB)6jWGOQLbu9Ck~96|CLJ z*ur7d8^VAC4&N{CsA+dTulmGOkPkBpOIrtd~2W4RSCW@K8~|PMf(; z;0}8Ky|j}M+eocHnDNCUAXsU6iZKa^>RqF_u$!iZO4$S`)5rU3L}=(gu+14PN7 zT_(H^>}6Qbtv`Sn1;~_yzBjKSvOV7Y3s~KNt%ON$7V4W&PO1lMhU#(^1gAXI0wCW z1^6xCIq?G5Hh-ZAViCcP!To5#RpsjsZ-m;PprzqptLS{T-UmVigGzk>+8RiWetd<% zBm)U%Td}dRCmr_;EiN)WK-UgbAae|F(nGwGdhW(cjj43c!Ipt{18m0{nR*6HYSfCP zo211fu+A#|9^Vf`>pH{(9BHjAF)=aN2itIQaJU2eMpGp7(8{NcNYLz3t02b~p5DX> z-VM~xonK)Y^v=ztkNx#Rl4cDQosh)3Tni>l;*i`vYFrKCHh`dWKbYa{f%pRSWjlq* zdJE0YltY@2H#eW?dfrvGUo8O4GoW-E6?2(I1EbW&z#&Pce&>opJy7ia%H&CAyI67_ zbA<15Dz5Urb!tLDR##O`Jf&FADy-$N+sBH7SY;g(cy6mQgpBI>jKpO1q9bZ`0f`S( zU8qU)&US`C-t-YCW)0x8!?>FwL73tQ`x!Z@f~;MDNyHbzLGKRR1E5Pf{d>UZ-bfYq zMSVijBH-lX?Z_Sq13tsscRZbM7^L0Y*oTnk2GZYg`Ujh}mM22_0M)g|wCd|lEgc=a zh}X&c?7eqaV4DhKPXhfKa`RR8CoiuTp|#Uz^D3JGrl6>=3Z1}w*n~Ki!S%K3g)z>? z7TIYSmzLIII*hSYxa#-(2o!H14M~$LtB9&Mo?8sUt&0Yayi=3q&GaVkpb7XeGiwlK z`7~sFk;&x)t9EO&Gs<{6iI#IMMa*;;>p^y3w^wc$0A zUnqeF^UuN=HMrvY<5qhR`apL|z-k5uYgkarO_US2N{9W$>O7qsVgYT?q8kgN-3EYs z)3ceCSb#Zx7i(0pEQ2w1bJJu>aDaH$TPAwz?(Pmq#7PzV&Rap`mHk%}kYDy$6;G`R zMI-qGA>6`R$} zAvOquN_>@RHxEGW|A;*Tljqc_f&aR+SWa37Whw#A0!b>Lm)ps5ZEzq1XL2TwdmUAr z;9E#CCR03~13% zRz#MDPxN*O@NF2b24av$}t(9eb^abb$K#KMnUmn@qHorgVeOD7C`z2 zPaGp~$b#{BxcyU}*8~*>1u38wk)KHhq!f-)gmrnHv)))GzUlk`3g~nMvsIv3FTZut*RCyuJq(Od=w95Tzl-2enC3bA^M2f-Ina z{&cM3;i&HbjQEt-T;JQc1`Wh7kjO&_px|+O_n~b_poN2Cai927BO>5L7$0&1eO3a_ z8y>RY){!Xg0dj8&laoeQZ3C;w8V2(7!+!dIgPQM2T&oQO4+u{JSES(NerGcKi zCX;comRI%hWa7?P=I!nJTZl?$+?h&PL`3UVF?*gj?5uh&kX_;ia^FO^+;0da8vMn@ z9=skGRB;9FMNZy3j-p0Kck22`%gbk%MmIcnkxB+xxF6>U#E@~uZ14Iuy=wtZfqv3> z6W~^O`OM3A((a57BnpW_RE`9;cOg6p7D&MmSV>SqDiRNZMVy8V8?5JnWT5gajsf3> zgdPWK(mW#xmZ&HYFd1JRlX`nbe}V?qb|~Svvn#dx+hxX=@0?)2kfPxA_7`$&sJk$5 zJbM}%l9rUT&l#VZk}7FK!sF!?c>Y^cLt0(UTBxL~CO~Xh(de$KFkTfGN0>15*VngQ z!NTqs3IEYXb6&CjZgy!&wxQwm_nOd952N*m-@kjNr~PJTp1vkW%U_?Kg5Aq|SXei7 zjN^XCp<%zU2=BD%>r<+MQN1!H-I8KXd>rnUX4JT#fC!Q6grV@kL1{X=3{6YHE;;w> zrHhMeX=%h<812Q66|8G(8;Zqh`eTFh2IiQ(L-ceyaq*byDj7lo!ool6_E1oJ+aq%& zC@9Q=GIg2sn3*RvVaOne4WNyQ($f|Uitp~PP1A`|ySv+g79lT6gw^Q`^*$&tvbN#a z#>nVPzNv}#51QZr-ngtM2FO5ItiG!&;&0z(Vq^^02+-C!V`E)oUQP8*yStBd3F6_A z7;sS*aekSEf!;-AHgacWT?`2DNKK{HZkEal@p z*YJ=Vy<^b*mW!0u9mS$4Yt6_cxO9LOCu6nm6rs$~_&p{@@q2(||F2&amOq1k|5mFq zm7w79%3RqHCSqV1REQUHj7lVw8pwKyqe*~zic4})6Yk2I8!m1tbX~t!D3jap3=9->*00(b)qobj) zeb^;a0p%nT(vlw9Ie<_LIZlf`CtTPP@gB=|{ON^Rssd&Ne~sYB zIugn4{x+pyLD(eyjyI3=8>3_@LX_q3^E)zQ3QMdFnkFjpE&5F z4@&52dE}`B14SsP`sTx)vOq|{NxyqfGp&k? ztFH!64=epG=TCS#Y3gc|gqS)DC#eX_QWqD}U_vq>rbQqT^ae8#wxw9VcwEq4IA(LR z0!3<7RkcLEj*b!-h!qukHt~9cWMsd-a>Te0O$y?5_raZ=Ro>iRPnOz9umD79ReZVa z=g`nX8MQKn4D=*8|BCb-6C6^c_Bg}LUn9#l=9C=F%;MY_Se!A5r1#;Wsdi>&(Fr3X z^gS~(oz3qhkpg@#r22pV{wf>!t#CR$O{=#1Tj;9dfa7V-j+qbnJF>4|QnNcD93_08 zcEH-9c0Xo_3AX`}fJcy|)&1dFvlMLw=3!(n=xq%3?j^cFM2} z2rkSS33f5y;u1F47_I@aU}0lpY2;5b==G?=!nn0<6D_D3%EEL1ufmYp0N?y^s*5Wa zOjAGUli)rsC}}h`7Hoc;tyncN@gCssrT`O}kRK7a)&D$43B?gZ3#t4UC$#^+|5=Kb zY-4A(_4^_8b)h}I5DlAZNyQ&k<-eHMw$}aeskhbH`ju*RxF>j>6xNZA_3ky&EEr4l z%Ze7JR+sWe0&ccXPl0ZNQ=@gWT_Xi%O`e5Wg`7kfu)MGfg*)AMQQv~|{;D=GcPr2??fDeo_rm!+kv zF((d*e05t)3$lO7cNoI4>mQMCMDqgQFC^h z88%_FneQUzWwZ~Ma^<2g=chD>pv3Og(&&qAb$fj0gTyb3C>?FRZ>E~4mOtAaoQq4n-rhGi!iB*VWtH{=^GGI`y{;5P%vSDeb_t#FR|u@c z{=tG@zIFha*`xTRXl7W`hQajDesi~_LsC<52c@Tmry#8lE)Kn}1D<+OULNXQ6<-UX zkn^hUf`+=T`&KDADGk;f_SP(ZTCA~>Lx-;Y=QX3AeSYE2TJl@zzI*cn@e6*qY3 ziK}dkHz3*}A$bj~tRkHT#A(>pu2_^ERmd8aHK9p<2j=lMGlTbSr zH>b&Y+1;$pwGQ3z(PoI!sd5gUchX;MX?BhsyZ*Px770XHL1gi1ElaPh!LHV_bitSQB$3tg{EpO-P zD>|vaxB=EVt${?6XVNj<9G3<^R#|cAXLFMQi3nxi`e;@G0usXRa*_g=YDDI#;`ruC zeKxdYRA~8V zJ&xz(zS)ADfCZHez3toIsJnS}7f5=q+uA9YU~0;o||R%k-Slw17QnUq)r1%+8z z`2P%X4gR2kPDKlIJ`9YZrn9k;9&LS1Kj?D37xnXlcE5v|*_qmq_CO;0mfboFpyoNR z?>wkHO+KwZLcDobC8Y6oeu%4&>q;mtaV^QPSdq$~+^##bB>a0iHcvdgJY05DqXXkY zpTy5I)J)Wu!eB3HK8$q>p@KZV8OAv~mK%Q0>?8xk77hVgKNXtQ~ ztmrs2+gPMx6$IW2RSJr2dOmmd3nC<3<#d(Vscc$5IcHhn=H$d#*UQUSi?5_nhqW}1 zH2X9uQr|@TQ<7#~R9(baY@0_V;u~MqF4Z6{7Bm$YU{gzqI%lViNT&oF(l*AYr>BtO z<6?0t7|lWOd3znw%mq4aYC>B+6+h)`4mN2ubsJOC%2{QW=nWDbmmcbbvIbHzQZaI- z@IWVkdj~a-v~+ZD@7uVbwi3PTzA2h~@sm)la zq2Tcfm9#;FX#p-I+$;6oWw0kdr|FYGT>j0CItq&32EVS8L&%i3%cZmC{KVW`GGH!g zdmdwXQVz*~Br2kj!)Fv29l7&o&Ncp%!5YRIpHCqVo&5u>`#~1LK4_Q5gV8--gPkuE zGZRBNVm=%lv_$LM6)#gOD*vG>wgK~{!o5PMAtIPO=%jUnh@&yQ?l1LHn`<-&f55F` z`aK)=2R~rECBc?BNgmQ4e0Z7BRvzLcPf`#PECy1`EGvVo4 z&BEhpUX~4DT)vjv)(avNUV8I?d7b`WY-z9ycH{NkoQy3DmgYO>qtl^xcmO%@ zC={v7WT{@z!f_>~=PRv^rweSChyn=-37?#{TH*wI`7IRwfOFwoU`Heu70qlq$7VH( z!l!Nhq}c3eZ0FX%11ia?hu!=L5Gl;4qtJ1w7S`EW{_*-y_|W>fLRD9F{w;@hbZugC zV)NH#aMf$5-S4k4N-N8hpX05JR*(WXML5aYV+(jIMGTL(bpTw{Eu*U1u=r%IkJ-{N z?oOSpA#Fa5d9a`@)gRU_)o!VV33wju+s?!+EG%l-+>hz7_<6B*qK0d%RKK;hlEbpH zE>{grYj*M%eG{XwjFYh~Kir)Nq79NZAHqFpiA&|KfA2)q_H@6RhD_>zn-16R-r^8v zxpeki>JV5>#1{Jw0aj$GxZ@iGm%{IoJw8#7UlA!a#->BzLram($Fe8XQ)v9mc*xRy zgJHdIL(Q(>8-oMGMW;_xN6$vJB86Byw9nh7S1el2mB`&T5h@xLKda&r;s&HyylI_- zU19Cb4AL8FVfUOcgc6#6hFO1agH( zmvb;hD|HBJxcL=Cf0QpfPJjP&Pheo3Cdr=eR-_D6Vr)-KK~oc3dl7Q9_~!R9!6yH^ zrZ~s6>)EpI_l6O6`7ttEjETBgCq~B>$7%avGDH1iVmXSTVl20de;++LOnx>p7m{lQ z>ka<#J+2J3ab-?mAhrvQa8W2}tJG5kQIQ2JdwUh;V>G2@rU+?sUyYZVs_=Qvk>^s< zIs6($WW%fmjQXw2nPph$T48)XpbaC-i%EQNH`q;4fP=&e8flz+$Ig3+L+Q1{kxRkq!_=%f))y1P3?x;q3!kZw@IpalT|rMpDwE|mra zq&o~!rKCerN&yM?n7;A7`&(q#Rg`CIQfjWibGALClpHi`0I`CcaHDt!O-QpJqL`;`f%rBGIuLBQFK zpqvkC{T|=8_b2Sd&8{r6GVjc+btnrFV1(Wu{;VwX%PD#}zI)DzAry~_sz9vR<(`j@ z^q$m+LBWl4vj~rVt^KSHuKMVb&gMC+V2Mo9OhSoukr!8Xqv|4((sNZ9DeH<(!s<7M zxKjsZ2U~ynpV3dt5eED+zwI2LDAe7ZC4kq1Z7S_o|0D?y%~3y&t_4CgFRwF>xj@dX z57FHm#9y=YqKWU#g@&cA1YOwp@Cmz^HI!BFTu;23J>u3FLz{{?s+)R}-DBsh#<{_M z#L|h;l~+z|N>#64!|*&OM;5eMx=%}&>c!Z#r&BN|Ui0cy*s*Cvrpd}CybS$vNJWqX zqp)GM*RI$xWrc_PHZYFLJ3MOtV2)!a{Xw*~xW1`H+Ryd57LS$@i!F7Iw9ezr3%doH ziBSd(jQ!Zc8i@@rhq)=m=Et7n*a`0_dekmH;nY1X>y3NH%=`GRloXHgvUwwpfJ8>d zJHnCEUDYc|@A?uLn|+R}bd#Pe?QK*zfiy*GzMRm3S)gU7wnRj1*Y8gI7zrvlGNUynI88J8!A9T}J#sn(b6}#?2-@iMC zTQ@bAwI1bJWw154LnHM5pi>H^VNp3B(IYHNp?uY_$?=q;qBl&Znwsv*mq-b$qNK)p zdofL4jp*?9W4C&lOo!XOE6}derg*!FCW(!19G#k(+K?okhim31GDB#zke2Q^qc^U2 z_A>2#d=3y*G}KzxoXG9MN+W6Mk9o$n624ilS+DtKI}ey%lo4g2RE*J36Y>%dl`&r* z?fo_7+{kn~-r8DU`Yx*V`HO**ca+_Qn#pmpGXfV;J$b;ebvbgqmtNE7@P}!GP?9>E zz|j5Og{A$~Vt@eyU3~No1$($JN@BG4&Z-^uLRJV1 zGaazF@xSR?%HQi-#A{m11_ z@}(vc=`>r8p7ygF8-i!yPdiuqRrI}@Mz3#t31r8@Kh=eZuNH4lByzi&7-ou4;~hv(VQ-XYI^RI-U!P&Q%PmzroD9xMX+!+42hbX!_iSR<5otB`mBk zvMd^Tg1YQmtcz=oA@lsnRNScz?!3Amj2JD8|z^FUD0eskcC0nfD%`* z{@b@3Y=aK!nCGpa5*pdH>ROKJlm;bvjo(|e+y^+ykok5T;sU%cnQ1t58 zSlUGD70Xu_0s0wcl)I?kcWmK`dlz>ZvY?1Dc;e8Y)fGW(`o{3iolThZddv#KNRR_8 z8_2vPG2S@AaOB|H;;_U%*4cw zyS$*{;OBo<8$U2G0QKEC)9<^xsWK1W#JrFBMgtouU?tUFK~d4v4|U<1WwwFQ_}cx$ zJn0704`1Jl>Tz*PZhZ0htX`z2%l`33a)4}rrl@A!)w-{%d8`?Bcc!$2$Ucw>q|{9| zZqa@)n>bH&y?;N{t`?`!V{H%o(QQ%o9zd_gWhleU3_)Mt$mnRpN2C;(jZNj{rF((U zz4UtP?kn7lPd8^t6-T@!+9+eFNZq{Di>wUg`}zpV6xb+xIaHOz);HE`y+*F`P`3t7 z<+m~W-hBHb^(Wbhk) zW5PC+lqrep=Kcjnu%8X(j(lmvMMJx5++cPOyxxr=J`ntRsV|x(q^lcCEwYp|?A)?u za($s6hnbo7L$=}l?K?5c;n-ndnCW%@HG!C3#$;E-ylU)|Oey0kD|sgEjLfwV+=2Pd zAlYA1^yvU8ZyM$l+6S|##NxFRLgeH#PJHJ>L}C|4mzJt-Oe-p?SsOxDwYgwZeLRd3jh2~;+PVo&=hchn zV%)y1=j?nNPjqRIqc_~BMe1XFJ57kCpKc%)P}~RShplPH`@~gN*4EXx4dtERFLw(Z zpB-|guF&o5*Q|YdA2!?d*^->{c)Is}>qB1|lP;m2E1^vV?fqh<=nN81c@x9)8>ZaTD(;3KjNuj2G8y7u+wck%LavLS30Zi~&UzmAK^ zVip)gM2Z9~W?Rn7#PZ?bVNe+#`Sb~I(Pw#}=i2?ZPo+ZgcGXcl+ZgXqN~emHMKv^B z@Ceq_)f;sX&>sg9rJLL~HR@eDCMrvi)24ab_hF}p!+9(%b~~Z|JMx&ZGythDxgZgp zlDi=^oUE>{-ljb!)5N?a-^FxyLn9Op2@t(Gs0iQ6>!92@n{dqjWmdkcGxuueru;T~|-|KlfVN}l@O@?@6S0HLTG5QPn z#&GM?Qz~C-8k%T=kSUD3(U0W$m6esCEg7zrkcTU^$fBh< z*s``Kb7*!@llJzuy?rSAl~9)bATr)WJkbM!RPe_fBookXknr?OxZ}YoGP>C7mxGDxroWVitcM&j>MN{v8-C?$u;p%nNI1x zv8<1G)AeCc`^bn{ReZ|V=ufFX5eG*5k>DBqY)zVzO*P+?wE-P<7dMqPlK?T3mm?l#@Vh zyU2{s_OV?DyOX8hog0>Vl1dUDT${mo;TYn62Wl$C!#TO~K&7}e3UgB$g(wpe#atY> z!*xpn#qZ!9)Q$(6RlW7*wH-w2ok`uO-xCDeNu$VkJ9N$sy4dlh4+vV9K#!(k*YPw# z0@P-=FG}O%JO*ht_S2(WTs*YFuhJOkZ@{C7R7@2!>mHBBe2~1?a%7~b^7^AT>b+4a zABu06(`WPw5bi5o%%YD7fB~4JFH=@bJn6Zga#7O8x{u%(tLbpN<-||+q;#IEoeRL5 z@rTFcc~7crJL{dW@rORz&Gg3l43ZegU)g5xZWn)JKiS-fzgKOLLAX#pUX)JE!18v$ zslI|>{PfhF)dU~6=GSg-PcJ>@QFefVyR`hJS57x`J@L|<6S#NN*G%UX)n`qo*Bq?N_vkEXz`nPfUZ>qule$Hxuwi zu*%%ZE_df1jTZD|6AEehv+Pef$0S4-%*#IwAG$qKP_ny7{q2F-o5kMm_Vst4;gw%t zqEuCNe?1Uqhj(Q_P9WdZdxLfH>2lHe4cZ~uwiijHPu)e9tWv0{z8P2;tZz6?Axw!i ziH*yyx*80Z+SSKZnqN2L3V2@Ykk)HU!A!ZC_a<+zaTcF+h{K1Qhmu7oT$m+I4)sS# zNlCoJUePm4f6C!}CE`LLZjDSuX9PZc_@McWPxO+c(nJR# zA+lhriqNd|G(O|%;3&--TsJ_+%9>Vi2NYvR5n6?Xg$@|o3zrra7lS;me&f8_rA2v9 zAbutO?Uum6&+q%al?pu4o=)T<;>RoLoYNV2J?HsUb<~Mh8N;n3#&z3bRqk7 z+2Y|9x(7Jd{Wm`pTKND6vWd~XyK1+imv=!yJM+cYiBa-?!u7d`cklJbJ{QM)n$`yp z;hO($D0M-i%rblN<%4xbI!zs~ksWd6;Ow|%fqhRDS$T*Fe`Kyx-A(icIy z73~}A3mrxu0}P&>8ZC@AThHh)nB&kAn;g3rE<`gqx#=GTyDYMzjm+wN6Dq@PeJq%m z;2<-?HDek5j{7|MDEKo`Fe@=3AxbvV2m*w<6jz+|JvCo zyWJ-^{I&HL?Ymzd>dyHL($chpSH4hoOD>7}OJef)3{wlvFoGiXYMQY6ZKr#{AP9_X ztzX9qRL8_WoBEP4rDI`XQDMV5&NP2}zCj8iJ6?3ARPdbJ z4Umoo#T_ZOT2VnkS4yirjA>(&ki8v9Qvtma5olLhT3V!?DPjMC=8LQf zsQUzn<|AfLzO`B&8iqix+t&(n2+MR#yuZ zUVnb$>+=Hc?Z&tvXKh{@1SesvkLpJb{;3=y|EtScz_5#L=w% zK)gmF$LF&T3~;HVLT%Lm27Ci}PP<$M`SwraVIS zqjcsR>(S4n-atAL|3CJhADT$|f8M%+yn;V`hXwxbT@m}sVD?|W!(zyGmj6@V;p~9;5 z{%xL=K!6GV+6$#Z)ED9!jNZODmKAee3_IU{Fk5MI(sYRH&)+P(pZn~_NIvn3y?2Yy z1}&|d&=FP@8aB6Jz-Ug2|=${Do5jqb9rd59utoGc0XL0x3y!7Xq(@=pW@(` zQX)|VMc2=(DUwO@te;-=oQmxEPY#DCdrt1ENertkG3JMOPbqT8mKGF0sl3_3Z+UK@ zrx_{s0y*2js{-pObdAcKcC zeTvdM#j{~mo+D`7?zM@CRpT-{#SJ zY`Sy)v)%Gnmy)pHKlaLh$4Xd4?DAi&OTq%;|3|G$|JSU9#s4!aVK04>&nG>~Pm1zN z#@jB9pp#IS=yr`05&M2FvDzf1emZXJJUnhgZYpdTtH;d!psT zjOJc(>NMQV+RWACAos&<`|Tz#ua%ZTNy$xUT;~wK?4y(=^k=#w{>g8%qM_6n*0(r;RPNA&&i?t26K zFRzl>LI4st`z9sX%0HRMOl`1SzaejVY_>ar55X{1qW6ndlCiBPJ3+bTc5Dp_a=zm`f zb!sunP`Cr)34S2*GGgA1A{>;25d(jGFO?NXgfJ5oV)>7|z`QSvpwb2J4Wyu5_8mz4 zWucYF@@ZU7)FLm29NduSg()c%tQY0LA3xTxx~9h6%gY%ofk3ujcI905*XiZEleKem zbMR3lJVravcqHMz67B5-6^HRPIF3tS@o(T@f);tZ_}BXR*@+W9!ycC&KjH7&UdL3i zLyA}uvzv$h7e31tKj`o419fk!Pa1RCrL*} zerkAlcyx3hdWDEG!Sd`9HnxkKn}YHz5Ef%cU%}Sc8rodI6APDwW2oG`5gI~rY5-wV z&|FTuUk8p@Dlt^FVlH#gE#v9x`rNo?1xgs^P;vS4MfA>ie7kngb=pT_wX@RA|&27|FJ;0?;s+{`LjB&s?`Gz_$2EL z-Z(yB*kPmqSX=4HGhi4|6_;DwS3iJ@GAcg((jWQEY=;e2S zkreFj%?~#|Bq_Hn}eL!c+y6N+!Z-&g7m<|H($UAlB>VHCxcnQ710M=~ZhR^;{^66p%~6 ziohauwuY^O)*nn_xagdhJiBzR4I%uXk&9`b>30_lbT`7Zk*~&e_cH61@Y&;2QpT%n zRcpaDJNAH_f`WpG$Zcn?9hONuqQ0@Q7246DE3rdu6BzyXqO&}vuQw}N&m(uKMecZSa@6jx5q{*#4qe%YiTK%?#T@Nr`A5} zf3gJz#2pJ^bCO4z-cPwPy5k_E=!0T`yP$6Q%G3AaC(QTs$ifa%yd6)hQdjhCBXjXE=i1@nr zzvATo^3C*tEPuvt8H>^7C;ec{CNF9+waF9t=6xxcfr+Ltt+AR4L6SZq`$Ixp`~mda zWlDUET%?!vN1B@#Y9zaPc<`9iI)q)K{g5Rc<-fZ@2e#jXla+LIbet_(9*`2I(!xZi zV`Tr638ESY(+VPw%E?_rt08tKx%`y{hyuLeCDs%+<5Sr!PmIpqT8ee{gx<(fSZtk-U?)Koey^!80B+2%g zbS3v{s?g$l4+tw)W1vzO*akCj?i~AHrgnPT&5gWORWfae=;ARlyg(FWObsOTHon*f z-#h^w%;Pz~TUqv%L6Jd@n)4OpGSCG@-r5yoLYG;ro#}J3RR=!`kEHAMyK|>>92s&6 zTYs9vqJxEyvkI+qg__So8^@a-)Cl{3E;pZjuu2<^^m^IE4mdkK6(H$pbz9c(k?fue z#KNN>fF(~tQfu9bDYXe>k|Niv;-F7SIg+G3kd#Y5{s%;y^|?8#uFzs=z#9&_Td0ZU z9Ri*B;@}tKnwp0k^?HTikye&egTrv1+JFNDa1AL|e{4^vju`lBUd=;caAuT!M33U2 z*mH_4_XXC=TPH-IaiF%1o>Huic!1HuR>n(mo`anus;?c8@h;X4#W@^?-$^~2&xFjAiUzP~T&wuC)L^E`O? z&HXK|kKZ{xwx`9VzOSS^M}`5AAv|Yn&g^))G?;DqlLWxV9vq|Q_t+>RHa=H?RsU12 z8#pbfg>R0c83Y9h?_+%QiA3Drnq>92K;L?VhP5Ja_NK&J!|ZMfSmigNQ(dGIj(_bm z^_tfQx&0?+r>0;%O&R#hT0~$5HibY0Q&B?8@k6N0-MoTG=DMMvLY!TLo6Dgx2!EG6b>d~V|yKIbg3*TTBDy2>rYLYwd zIF1$_pPU51K7__>Z;iBP6%`dPUvl4nvZBpz{svC7!yam9>?4T!FyV^i*~0rP4nqt( zMtBJa@PJs)`RDeQ-#VaUU|fLF=okw{7`iJ_0W@E~G>T5bU;={ZdOcT|cMct?3TXav zlig584!JAPO2ZiDfao*r`wMAWpA|0kqNb)M(CQF(C(7^agXA}G44@cfvIYMkijW6TJtIJKb9m+S@tWD; z<^*xdQTx5I4_{GEAs7H)!hKFJk^}S}Ks16zf@cR`rl+l_p+i25iFS?d4EF2Oa;eSf z2I4K~ca?3>D0uc({!eV}WYmpqgn|M>XQa5!!$c6^Rw zvewakZG^QACP^%?q3`13Qs|xHB2?s3@qYzrM+ecuTrZ7DpaP$5U45*aut=Mr^lxXU zTL3=dW<&g8!dXJ*@(kgBI7S`hRpaO~FWbi!7uyf#DGz2!vL9~$e(F*DsMnVow@aeC z;4d-=<{e@Ogm8{}5}UY$guzRLyU>S>vl$C3z5sR+IJbNQBQQz|#H*I`*u+2Azas*V z1NL@e{7(Sfn{#tRa7v68>lAz6N0mh#3OyqH9kGg01ajaLi$6j1Q&dm@X~5?)Q+Cgh zKl2+a^eoJ_K#1wtbOBHz=QDq^^gi7Ss8%p(%>6SZ`s1j_K-+;K7ncAg!RtnRgl@f~ zaBWODuCks9T4Yz&aq4MOm6+j~=3-;(=}4fAo8Fyka{xmZ$WAn$aLA+OU{H=CuDRj9 z)PNzt1OsX~moC95GHA9em?aCN4;Sn|9k+@T^mU034hwt6V_Xe^Oc-H8fF}nNZFGKp z1X~9BiCUrWLu564`ki}FzS#Y z=GxKTE?=7q84?(FAzdRJI-lR0sP0Z2{*WyT$ZQX0N<@YMT8DqUX=k?tPC6EiTisFQ zpm|t;^bz<+nC1+{lGVX%_H>K*3~~4KA5+e$nI@Q*se~P_&9*$O5n#5pK)EK0e2Q?_ zce{L%_Zz7?aDjt~lA4;^^OhB&<=6QMa&oj2c_I-pv1T$C>m*WEaNz>s79h|0I*vE%uSqNfoOlr{>fFe92JO|f2|nEwMW3Q+}HO6a%iC0 z`MPT;DFPwcXa1OW$S{%2V@#y%0aXt;j`&`Dg9Rw+IMVg@?c3g7IB&$iLJ+(PfewH% zek&A3aP6k(q{8#KT?RlmN@?! zxQXJD^C`X7aDG@hgkX>+g+YdP7A!t?Q?!!zVLlH*=0aizG8-`Qh7ITd#wqG=2nnAP zED8(uH<@IMx!OSL&>cGmEr&xEHMe41FkqgIXO&Gi9Q#osLj3pHe-IH83W9lnV?3PC zRy4vc-tgeQ!x|IG?x=MfjW-(gy&3-#4GoQ$n0UB{6CNzRFuYQ~-o?6V7EUmLHewS8 z4G~F6#5QleRbZ-6FL(R|Atn+=JFU}N;90~7TG6FnQSw+if3UD_yZ zJNG3I;cN1mpZBXQ4GllTnuqWuEG#@GrN-i*Kf0zxX?%ksam;6D4(0I^Z5%vqoKv`4 zw(m^fqye*S$X9{a=x6g~n25%^H3oQ~%C`5Glgdi&2qZcZe`h>(LkOvdKS@YIB1hic z35KMfUmD`aR8|Vuy(6J!y4=AV{sWv{{2o43K7mqV$+g_aB^C5Ce&HwpC`6TR0(yY$ zfQuQs0Q|}0khU5a-9ny;hII)KA72%Gdv#$0ip&}w?=3GbER3YP#nDMmzP@{V2I#pj z@93GNq!q96MSJwuY`3^XS6P^|FUk$|?2OvlVmM;rzzwmAW0Ks5Px%ys> z=nt&=N93>WWX{i(8q=1l-g|0^!eLN44lrhTyw2GYLP+HcmUJRxJ3AI4j>riZwG5(5 zhKVOk2{_#bZCzMrL$JjGwnP?0|HzW|?P|SXC5(@c@5sNsy`6WJ?^;e^y%!%NBg(6q z`aA%OUTY&h)oY=0?CizB^w4g>mMZZ7j2x0<1@U=@T5S~EbiN-PkbIseybE~``h7Ti zt+4U!W3sceIo?5H6D1W(*tHdMeOudE1?a|pxHG_@72RTq_-9_al6d}cQeg(fhp?UZ zy7M___P(Kvzq)OhDs&SS6%`JFh|;jrlsjBYu=s<{A+dwh1&M2v*|{88BzI-+mAJn* z?}EUjd)pZdg}`(MV78{n7dL(x(J-K9!ZNstege4${7&pu39B}Q{sNqOa`u2zcCJy~ z1u_9Pi{c^xsFI3+)7{=NYvyC7x|RMUtip!?8DRJt-%rz82S$w0CNprRwHv*A$}tXG z9s+4A`X|9NPvZMrESe7$JL^xWnF%aNj!^)0kRMej2b9Birw|O^!oRu6 z53}!`fO~#IP$U^IfR<59|6>ek4gsW_c%IS)o~DuykjruFm&`#?I+%5jqz5aoOfEDy zI6Pqa9?$^SFGzGJZ^4u_re*7wu=*n;E=7r}5U0yN{HdRMJkV=;4^e;@Zrcwh<@EdV z%BMWWdq{Bq0~S1hEg%oe{3zW1!414V(+Vt+7HkJ*3v5X63OQC@InT(LxFI`kegn=zrUhY z3#DtI z<)JtC?xzZqR~pFzO9X!`{Z&;2=97y7=z&*3!WW`c2_wcVEiH97f%B>WE1}1#iA08G zy00sYsub?rfQFT|w?=Rh-gI`3Q~DL~>o8!1FP2_*dvi16)Dmq7PRiZg^7!K7;v@D$ zfMH=_VX_bQ>>vq?p}L~+t#Q+1*T=*GA)qS8ZIlCO2NGtSFoUA|ca^`djoL%jOh`!h z`pH?6BVr8u4=8oB6BA)f(R~DP01|(WmO)}5b1l9wd#0Akl4WeV!{gu2v|F@UP`H$Zt`oz zkh`hz2P1?;c-7WufmBV9+}AnJ_BgFAFSDLcG&#?YwqR^7OE zE&iy($Q?4}3aF+oxIY4Vvp@s^0V`Nhjdl=XF$|H7&Z8)F*k5^n**D3$XoXw!FEag) zBWfV@B7%kQ97cK}zI)5bAu56RCg;-s3QHcMnB2fUz`}b07u#SQHWL$5*Xnmz&&vd( zt(CBhTELCRLCXJ>;x51wi1}9N!rB>PkIo^Vj^uCG6ghjN1)xZv1KhTNHruiJkRq55 z?CwISobf6*H}ZS@#+jO@Kk6naBd+TUAmGFo9&?TYBD5Ju93Vm*hjQAHNx#^0O_TBN0TvKS{DI>BN3 znrE{MjQGdWv&}kw6424fJi2Zw*0!*)fam!^=K9nlibvTwGo*+o$b)kLAqE9y0E%yu zxmN*CuB}bLNdtf-q8Mouf0+p*0CtU}WFw#fQ@Tz#qmXI6w9-vrFT-!pCTG@G90aEc z!Vw$G28d-klAoDv27p5WX>_!jfUADR0_T%jz>;rQj$S{+2yF5^-gN|SSQjWy+GI-O z5PrKvzeUriL52^dG5Eg6y#Y6axe@D_R_HQlXq6C{KRJA^%1%HZL`*g1z!qu;tZJ^kS`z6r`6m{q|M}Fj*3T zJY+vBPUdId+qW;_aBOdH2X5wTL}VoJ!g@wV6hvfn<)(F)NQIq#K#}3zc%}RuPneM+ zI^&I|e$gHs$MnGO`$t0nn=YQ7-wzK}eKg!(#>dA)sG0Tq24{8HbBkIB!bw0|8zY6d zuN8D4{dMihg^VE!&L@>c$V9_m=s&+sQ3JPYT%g|$A38w{AuM;zLdGe8Tr?3eQhZJ5 zcq%YXV4Qp}-y_5tX!y44W~G6n&~$=zCt@tf@D|KvcKks86J*x9O(#EpKIJnv@o68; zKn~@DJDqN`0HLC77I`G@0|0o&Yf4trHpPgz6Gb@pOyK6Gnum>73FqnQsg)Zt!F)Do z(lNk>uOnmI6AdwI5iil!@AfWbuVc42{MbIJZW__m)5DaX%cD&FpbQYU1H<RDvwg zApoGbS}$GxKTjXy&%11cP#Cxtycg|A)FAi`kk zaB+9<475>Axdr(J;pIuySQ_~vZNh%AJcS^`jVQR4@lAjzPee!B5>YY@-nnu1f}CP8 z08fg=cL8UJNlIEm414dTbQ*mG$Ift;m}_2LohVhHb>XK{wD3v-$~TDFxK{UL-a9NF z3KrS~?u3qb4JCG>?7j~Q-s@5PEpm%b)$@okj)12cmfKT+?1Gyj4nDEygIV8q2v(4x zaqJ=MdIcV#lk_p*oX7MCM8xw=#5ZJxZw`=nBczldJKCsFX0H~w(*}9#*5+og<{C^A z1(;Mo%eWRrzp8PWP!T-VE1~#v<$?i9;UT0%%vl=JmUb{g@NoO#Le~YyU}1K+6z`Oz zgZq=PV<9UG{{d+zl-HC_0QKd$?##(AJrpJaw=fHzI>Enh0_{0a&XA}_jZ1DyU$WYW zb>=;POz2|xwh%epSYjsWhCQJu zQgOWyhltFZ#f-&Zw^e`bZb*FmE4?nL>QUZ#1$z4oo0T7kRFBQ^DvFCi%%n_LqS7%# z1jG_0%}`Xd1?OPbynVvSJlSSrYgadC0=$|&nob^NCYs>+Msn)WaKfWpspAO+gm+E|jLOJIlk zEdJ|?k;kc6MAyvx;CxbD8yQ(Rm{^ibA{UAAm% zeRTGUfqGFuziO6(_$HtLBrxT7lW^mBtsFu}KoD3KPt)yr!7jiXQMDC_g0@3KqX}n@ zauq%!qmPdd(>d%9TxKM-Ku-P)vMuJf%rQ8s33hKfXD23%Pt(yNH%M+s)q*YMPHe@} z{QM&l{+_GuEs(ebvhRwl0hJo!HDI-%c81&=Fg*C7pPxz`UCd^jf0JIgnU8DNDy_re z*I~5FFxZM#*5413!jEfbxacLk~^Ym*?$8G^T?xH>qT{EaR zfV=MIN3AX&c*f7a9XyzJO)@`+YzvGEJ+~%5YPdS;!h!AC)v1OLJ(E`uQ+Taqeo|}w z9b%+Ws^6N{p{`PQ5iRfqrHCold`%8yjIgvN`#nxj*6+F6=a(TFk63SKXCxCl!f=3MEeq{!_^8 zkRFN$DKLTzAP)znj!(6e_RWPV6wsnXw@n42X;#XA7b-fx2-1f;if*jg2MUZ-#+saJtd{M(^!c+*=-=3A$aM@ zobz<0&gh^ytbhNEioDe;%bIc;=N7N8`h6U{{5nykR#AiT>&nM z1}S(leOC8q_U(rcB((&PLcRf6QFJF#PQ|?^vg123k@0waH;KK%>+erx`u(ZzIZNo^ z@0Vvkj-BD(TYA<1_qSR2{cU71XqzpU`fn!z19a(Ecs1!n+qaujZ6q8T z-y#Low>T{Lo4cO78h_S}Hw;03pVtE<2Ydbr>=njYhJSvcmpjN$Fi3rDf&7Fke_!v! zD)JM`u3(rqAwL0BQv#Qenyi|^DfkT2+cE-&7l zL(fHF(6O-o>!v-6t9wKoj0rlfkpC@jCYyK15P7pi1TZ2;o*lT2tg&jxXqsawATNPN zr~(nsULi2Zjp&)bfgjl9*K{$10it0)H%QF>SVMceA})^snZV2bx^2I2ivpTlR#OKQ zJY8WAGVs$oqp@Sd>fOTu`Pu*f-|U?5W@9yS@jc?a_N1lYS&}xttCQKf1i>EMkGc2< z7{4E&#h>fz{{zn%xljLhuRv7Xqu_VpO{B*=J3EjIaT5;$WwInjM<9DEA;i1y=St`ub8ZJF=KY+^q}h zPxgMGO2oSkVDkAYpjYwh7kce)sY0f6(DLx4nmC+1uGgc{|eFr)IM>Z&>Bi0~eO)dC7iO2N>8 z4a|jdvC$6b8Kq~gGF*NYRnhVjC#clq)quh|K$TP~OBu&$M4yKgHrfubroczp0!0f+ zX;)`pU?2+}zA)m=GBR>c6`+X0ko$ouCgn)KUuPhrgJc`@Z;;ig`MjFrH>t(OeH9g@ znXeLq#5m`GQO3&6C4mSpS&Zk0n&I%o>$|3HkWda}1L8Q|?{)yoc;Jvbak4MlYnQs^ z>G2$mYp#0(skFASvGMh*QMH|V!G+-mKq3Mnf794#yW|BP_fS7XR><|anA8LSAC>@` zR!~@3pM13eEaH&3^Nf_PCiqCx&69Fm%Yl@uBLm8)OaM;13vQw@%&=d?v-D42*K_Gs}t5LQd@T{EQ~5Pj1JMoYP48M#{Yeyp(nXO;`r&>l5ZZrR#WQ?n1L+miQ<%TJ$P4D{;_I+jK#Aa4Xz zUtmX3A-??HtanEc;K5IR+X@J$2de-El@#G?ejJu@nL|thcOyrg`;GGwOj=XvO@Y4P^(2XVyB5ZXEC|$WBdZqq>||y z6g*NUy6xFkOP(V&rx62CU;QG{+Nt;BGQUrl3JT5IscukNH@2k)rV&m7ok`!_vXK-U%!slvec&{eUtci3YX=7^SKg zQ5cqHMPv%p(t1T#+bs(iCoDck|FM|kf6^g#T@^h%gpv0z^RN3S2L;vcb;D94!Lf%W zL()=GJ1#5lQq|XZjz9qY!TOE46I6nMBUkk_fD#X+%Mc=vj9{k+eo8I#RRZZg@-^Ng z_>qF_!bGKY5aTQKWhVxJl5nVC(5ZlW3cFH=_3T=WVc$C(AxIc%jcJ zB61(36M3?0AMIOKaL-|#L)L3vphgIdZa^};Jsm0H<)sc}nTW;O|AiU|D^m}C>!8%U z@o6vG#X#-f5jt*(WQLZs^$4S1f`bG5wj(Gft1`-=BsnV;ehNEw8IckCWeOz16q$)s9hr{JZY*g`~V}H zc2H|Keg9-?^A4$i<~F<}4MIcjdjGSZPy~i22mCmbs~PZeoMjmFPEapde>tszgL@8~ zXMhIllnmYVX|zDEf!SHhBSkv=3TZlyyIegiukyW{4~U9;ShLaQMO!)9TpR0;7)(hW zPjLc=3!)YoYc?)Cxao}q20-?EStrngkHd>TsKCCUzyxtvLH<7v6=8%A)O(tNrhH*g z<^voVX=e_oT0A_Y`kK$<2dVx(mmClr?!$<$&yc`U2Tjgc8P2x`2gJc|`UKOB$C{z0Iu3A=_#Fyo+!hls-p>ieG#H{@xlpRaO}3Zaq6+8Z>zfqz`O zi#%743E`9k9m{|jXes|Y2kC$B3(F?zt)HJu78dXvpLx;Y_aw0Pq7`a&rxe^Lsd#3w zFjl|h&QN+3&1?Y&IOth_Ep!KMmVL=q-`U?E9{;#`p$|eWjm`&~vaPa@m zMbzCu69D!axSX2^kdC)NZ3sdPcqQx|96+#N1jTxn9=BmRbPlSwLr@<6@L?MyB2Rl= zfGz_ys0O}Hh8Q6Q#nEmrJvpz5{-mK#WO#UAGWWB5b*OCCExZknK-Tl1C`Lh9UTe(fV5iQc?@&8yO!P& z5BukuV6F)W3%QM09v$U`|Dl(vtKsINGo z-vY?Q@x1b0)byiZB1%fmAFn{B|2%K{jVE^{NjImEW-N_(d}sk(lMsv?)o^bic%epe z8|+m8uspTc5oSlq8^;Axz7i)C|gW z?tx}yHm@0Kf$(4>JSkX?Kp$n3;Nj}p{vzZ98LvtBSy2Ni72IBsKRk?#2X;dcMB2iY z)4A6h{f>nq8A=_Edb?twNi`DlI>O-m&yq;xBw9V7EGVK0en3h!BPd~fxN`9P%1S6o zcdWpB5Wz6rs*R%&f1E6?%mT_Ocx45ml4LMN5G_J+%;xzjE+TmnYC^j_Y$5O50PG2~ zx7hYxvbSG_7Z)DK!pwNk9iPI1sN}oQ6#<- zK?R4jiWuFJML?f@%-`D$sIp6PgAQ2>DLwWM4>>@dgqcR3Rh!w;zMnpP(6%cCjZ}`>ll#HSbQqb! zYECf}f*o)jA6W`8pO^rv7vs(K-LGmrZx|j4F}t=JbAh;P#+aJQ+Ey*-Q~_}kYypbF z!oY|?%0HDCVFZiO>ad)2?9O$+JDFF|+7=o6+x{7sU%6l)G|4_0IkuBX_@9b>dINzb zCk7Sk3e^j`K|_VRkH2FnUxV6irBA*<7b*rFE)Ust9#x~WktrNT>tt=hK?p#VA3-%E zbG$^n?-7{n{zu)zcCGU|&pjgIjya=u2^a!yktk4Nv@E(xIgA;aXyAkMQn*^h2bcfg zlc}@%=P+H**nd<#)UKPq@sQU5kux1v`=3>hBQ+{y)#Foua6B78d)iGw7M227pCA=b zF9I*n>xCrgrn@+ZxG<9HkN-RwO#~1|YPu-aABpgFzvPt2_p_BtL@M*Ymn{FQ${_*3 z@jq5MN*{rOK;)Z}G8r9RtP1Fwt7am#qob=y{#E4I?XUP<M`=Oemmg)i$F~{U zHM|=ldzl_5UjM3asFL#V$w27F@>N}gSzxOE>Voyq>+&D2F>Xm8v-MZj!sS`Ov&crM z7*Gr6xxr@e^YEzkcP_3=zK+U6(KYxDa^&;iKve zTk5?o=w`X9rqo2XC!9<$r(X1ND>qTM3Q8XC`rOrB!hr}L z`qiLYtSvsL!xLU}>mR4ZzMTs!4$*(0C>Sz;KtU}V{P>-xtK^}0-J?P%8l&GL^jRePF(C?`tC?nXb#ZxokHp|L{{%GqX|P2u;w)k!n-eR4C)f$fY*0IxXIJnrgnJP@cWjxSEc-i>@xAPBEM&YKxrUuS zFwZ^=$=SYTdvk%!mMJ;B{WhleC*Ny-e=&^#yH3p@3?xY|x$UucBcu*87Zf=QQT&0) zmlOgnamZgm6z-ri>1>4mHqHWBn*1+HHCiLNRWM`$kMT9^{+a}=psits%VjIfTL2g7 zst{tF#lz}FzTgP}6^eyBxg;Li)Oap^kO!1riHvi_j>PIGxwDZg_zP^ld?$(3w-@xS zF%2a@3L1f%NQNkdUI=pCd*ITAhl1-rqv8#OX`g8SMtr=_xRQCJ65FA<8Fe{;yZ@F> z>!_xF!f>^3FG_u0&hfXLyCz>K5^G~N`Y*qZ=BnXJh4`{nz?&6&`)}Fqwc zm&1|rJgB;BZ+jH1=ihE4e>Tv0@NpC7#Y3w@Ep?#t!aLqnY+P6RH8%}v7ZKw$RI8(7 z(~ZBOtku4O_Q_ct&P9x#PfLI5w#%CS0JEX|W-6ro1)IR%f&^B`br~dvzwzpg8l8tW z1?!J&{%?B6Nam1C=7re5L{1b){kQABN))2VV=Hm%b zm;6%A|2J3Gzg(sNC%&U-W*E~+gwwa?fpBi0ExVM(KRO|@=?8qRi96YNDfQEIRhxH9y=`FNAez91+? z5Bt@0kJs-*A^H+%ilEuZc6ubG7P5N|K;blQPhBeTY?v3b(M{q;16?{`(RwyE@4>bK zYALu4`$Hya!EZb~JiuzR0SMpHz)Xd91S)^ISfr^U!((e}D_V;LUN(;rnxUI6C8PlHpTqSrrn0!Gp=WP@J=vJ5+TJSrh61LdY8s4!C9PLB8mpp=SGE(T@sb5KS4NSqk~%>jB`PNIj_%)0}g+8~-UTgD*!^}al4sAB%>46hNIaZhUawimGf%tS&Zd`(bFsM09< zUa1SvF+s4k)gSMW3!uijb_1frRDYibl;P2QfZ10-&j-k#UZ~HL2d#u-&=Z9`=%h0n zLTlTtOPIi*`3lyzP~vOnCf4e}DrSewp&0O?oKA}lG?)g9dHpefx3ez+Cc1Kofegm- z_UY7l@XH)YlCOiZ4cWlpASEez4c-z}2_J=$a7x&kzuVh$X?eY)`TJeq5gWAP)Q}{c z0IG74m`xpS5RmOz`KrT!%L0#B3w4Fj(b4i*)z#IZ9Rzn@0ci^*S3Ft$Y^<2MkK!_H$ZsVRNfL&0e(!!|5BpFVt~VTY!7D6LwPM(v=92&(RwdY z$xK&Z_pYr0Sq&M{*wh4a)c2{Z!c7iq39LhemRHw8t%c^9V@%ErKNP8e2-E1q{% z4S>d6*-tSZKlt_iH)kN?VWdNnigJfBRr<^GZTqZS@A(wo2`Wk1E3bcvBTKKNC<^V1 z@zM*RjC~JoD}bsk6xP4`>rY3}>R}xLr?|IQep7G)gq{E{*P{GpsA3B$iAt(5WoU6|c42#_&?>6)Gx@F^qJ7m(rbs zHo_iw8sxyvu5y^aeC>WOnyDBM+OYCB95kalEeSDGwC>z1(0lmsHP_z-2MLyt`09la zaDc@0fK=_i_Ws^p!s*Hp1Tg`JpQzPWHqBiHar!Q>ZM|YLxM#T9Ufg06eRg^-oy`lF zyU_Za>x_Q_oL?y5UOuj}<4sl6lHs}j4(%h_18|dHt_XWaxQZ=`j#^Aq`$nB{=diE_ zz+r)pPjw;XqdQtDt>@Wv*>$Sl_s?tN$32LT%gf7P7vc&9G2xBhO7Gt%flmDqgcy(u z?*XCl^@ZP>>0y*_1<(a*ups*XGWYp?jKl+XM;=NKl%db>2Q>35DExM_K;8J7)_quJ z!Y*rf1lOMr5d7s~6V2X?{hR@@d#u7%yw0U<1UMOgu7r{vQHat2B(=Z(!Ljm5r^cly zK3)yP3=lgGpf*l_11wWGVAvEgn}HUd2HiwTO6`oh=K#w^`A`GJSDzV8W|szpxDk|s z0ja75nlqr*dkO0MR&h&md|&|r@zD`_gIh-@hpVKrezcxfRDBEaT+8+@6xKB+DXN)y z65!Wgkat`U^#&TZE_8V1<$Hmb3xsf0=p|7IL8lZI^g&e#pO1iu$e$1oXTHvMx)nAJ zUMot&2&8yizAZe`8z}L&DXOvF-@gqb&?U&xS|u>*&@t~kIs1G4Yk_LPFw6_i%^fg7Up*rqoA&Vu`qzLxS#Q)M*(vFD`S=ia67>H_izAZ{zGVU3LS*bTN7Q-FI<5Cqx>QGAc~0y3Ypvd zn1UYNH1o#B#=*qtNnkg01R&sFK$Avk45MW+zXN9+e;UBZr$Ds79uN`{@lNSY#NMOt z&=||T^bug3NqogmH=LFR0UrYU980L%;X(8)$p$333AdxF>OYtE&=0^5R~HvUOGDj+ zzy}~1`sw5|`|xt;h&+oKgY)CZDVaB%k&+S;NBeVWE_={X#=XjYHXNuGTcEZNhl2$m zJwQ`W;J%Wc2?zW%{S;y)AY%SQcLce(ioi99R1a>Jo}S)qeUq*Pg+d)+%gnNYz?u-K zp?~FTMxW8-m0OcUp1Oew5A>zTbTMD(lxBV!8F7bR$J7ukm#eMmfJ{CHR>uy|Q8TXW zj{y>|ZfeRrOeA~P3(z<4gaU7;fE`$iI3)@nEHws$!2u=bmgs%zkliUG(IBSpyt&TG>i2xPnbVN{jD2Qs-Ac26x3q)#hF$oFk(3qftL;K!+}v-b`M6z4`NFZ zqZMD?36;dYX8aOOL89se`^zyz_7U7s~0q^;X-rv>QKx%xp8Bc z&P!-9(+6f!Y{8tt2)w4?b}`uAexb-n=oQdx zr-|B@!u*OY;o~#!|MBtnzG8ld%wJNr1I_}-_9P&TL!x~AK^=MS1-&$`vbwqgaCMli zMnKpBy@kxl)m6^Aujn%gB_%hdm=&{vTz$NOqQP13u-9<@F5#|@Z?K}Nt3g7o)kmx=5RTd%z0d31JI2N+ z{fRn+-QC^SV@XgwF`!~ZLU3OifD?;J%4f=}z3qfw3iaaZzr$M4Up z6$Po^!Ui#!_ZzviOztX|^-LE)W!FFtl0iUB%;@Rg@ksqyRIG$M+#l#LW*&o%33i&; zS6e)4k!EjH-H-`JQil*r&-r$3_eoRJs!R?6H9fQ&>}&!817C5$j(}a8yqX8$4r;^s z&+otnWXhR`0hX0B)CM`kQRn4xL%T^hbt)<=FAk4hU^e;qsjSx&++2COlN3``e4 z!s4UTeSFrIJUNCQncN3(s~!95GnU;qLHpCk| zi)tAPNXb~BK2}{igMpboH39}U#q(;Vf7fq=lJqh0!tHhO#Ou&hv~Yo_$KXDU9mu-PbRl2bUSQ&iNQ?7>q0u>t)Be9`u&>yzMI1=faAJ!eu#eZsxr;7a{15B955~w^9kAx>1Bj0G9~fm-+rKgpk^|y(qsZ`fL}?G+NF1*)`5ATZ|hn zYu_Q~3BP*N7;d3vkTke|!oJA^D0=uuzxLyHY$y-mbD4nm1-O&9fyR+|N+Aq5|8nCj zkkjzFI+CbwpvZxc8Y}|Y1Zpc_7eZ(I5VDIr^2lhEkYMA7Rl@IgG{TTC&@5Z6JA6p$ z?dRu5#%rGQpI)PZVe|dtGpGxaH(^r)9HYugg`%kc!jhjn5aH&AvLkl(hzTlWNdEJP zB44A3-*P&f(ENaZ=^nv00)>>)CZwT&&{S@$n}+{#OWg*%3+UsVo)BQc(jwE!^8}aT z_8Rz2D2h-Otb-sSwMGX>wxC>S0l&sY;FFw^b5aa4(SMSIeC2@)m8xg%rElx@rIBWFDdFKL0XCWv+4ilpZ)74 z>88#VV*b7dBmlZ^cWxf_KSn(`I6i7d;X$E(h=RQSqcJT?ZSi6Ny9W^jFD}3Kw=aR& zm0IKJnp#hW1FNBS?a>{05ogb)n(yCw6&rRaZ&%b0e|_viq0=A~Ov@~O9|--Zo2YY_ z0p6MYAMWWNA8OHm4jo?f=if*DiTGql*8lj#|I|s>ZIbChf_$};)e-M1!Tmz4>H0XX z)u^c=n>_H4ZEbQPl{20$lIQzvyDKnNbSIozRLAZ1Ni1@)VXx4r%RS45Z8T*4236|| ze;2lx&wn;$+F$%>ri;2;8>r^auZGM9^sN5qi9xsK-}CGJ<@6hS4OaOAWG3d)VhS4Z ze>45%Z3Lx1jgki}OEBi6)fIxk(($(y)%oe~CG!cSZ<$39)xd8K(h8`Ew*dbULz%Dw za05;j!O#U4aou1L5U7HZ3uHx5b?t+*Zi_tH^A#~@nNmRGTNpk<2dJh60N@M@9OQ$d zM+>mQMIclCgc&#!TuJArfz{Q~6))u4iE7-T)<@zV6cS*NA`J3a0Fa>gKL(BoT!p!W7{?GJOu>_m41~$Hj*iE`DC@)Y z=IZk<^ge^Hh6bDM`|Ru=E*3)I*S2n8VBqWP%QXwcgFL8rAZ0dR-llzG^J^hO^AQ)W zj%sEf7|{RGoC19h07r$aSI>%{0uN082#D4|{nbGOvPp4yxpbx%IK!4MLd7pAD9Cg= zfVKrpCrB@l?;xI5f?}EHwOkr_WuCy|gWQwX{Hsh=D$OU4_7^>DsCFf4Gh#(@Q}Eul za|ZSeiqhFP1SJ_17H??u&_qs;?72LD`%h>d#BR*>01#RWl?Z*ys}PipF328Vy)ppz zhC85P7rU5K1WZy8URTG>tzmmkQo*9enw~GMN<~|LO6n z*H3U@eF9obG%&A?1g6rpWSoyE)@du=#ft|^B|VBbM1Y;b^^ z>ZPU%371NNV+;U#I04YU2#JYzz+DE0QlN||1|=*2uJQe27vA5Xe!8UqJL7p_GLISE z%HqviXfj`NzSY*&HuwbugdBN-m*PC`DIDCGiGC-L&VX5Eck(UHp)FlBP}jj}15R36 z)lLOYvxw9h<9`+IesAu7>Zbj#1HeB7x!d)#@c$Yd@lWPPh=^RYcd#?kv%2V#5)0!L$i;AK zdkTB`zXyxV8l3CATVtDEdzILYS@@bPB3LU0apIY!;l9|yo~`rVIBPeRC;GBl8WsoE<}p1n(NA^i&sk=i4Yau+yH+f3k`XV7lr!ntUGp%we4=fU zUHq+Buv=h&Oj?~~_@Nk&>gDfb8iEO_-**~(uG3w7&?AhzaeTh|`ck3G5X@6(eiSBu zC%-Gqh>@Ei_-%Von)^5|`GP{=rQH-}0(_4CBT+xQ`96ZOG4= zgxn)9L5t$`nOw)W7Ny{6I_6C9KP{7!jplqcTD zODiSBbTKz?rG2!PsXssNO`AB1TUl6myO6r@X8hfXHadn@FpRea5Z!95s;rEK;k=IvLq&7w`pole7#RZt zVt)P4l(z=;?=xQ#;cNUGcmi=ScKFYq;`7LDFK*6~7g|mnB+Z(Pd>dF;FsE|(a(+rL zv+^~a+5H#2`U4RKYK4#LJeS|jnw-{+xjR|A=fB$#E03U|B5OnXah=7&nr2M}ren-? zrT5FaHxR31o8L~HomPg*#$*%#UpoZ9%_kcKJQ(Z;TFYQ@ zM|xKD;O8sIAWwiJ4KlDxR$AKHlm~K%(r{EtNl~YmYgx%cW%Mvr$jtP`cqcmz4UMQM zwP^T*TgneN?Z8|M+Sa$MCscnnRq^sog*=p%ZP5WKpLr+G+jSbhfV3eyXm+YDj!8aY zJDz8fer#5jggP>DJOyC2V1}+{{e4z6~>HnG!0f2`F7s^2BsG6q*dGz!) zC+8}R8$3GN>_K&;Zx};9i?1-vGPRei;RX#yp*%OexPZhbO4oV8m z3oqx{+FtcKC7(EfR1M`uu`;3o3Lizly8@rAC7Ps88h1iHvj(u(OAs)Eugq0ZPa#C} zOF|)Eks~0`Pq|;eetoj=7FcUJW*Ejq)}hF>J1?gM?$XM5fFvpJ?OSzYoJC-EcB4!` zw@`lkkZG||(tZX;Z11aHQiu8i-F{@n6mFXGJiSpT|9XnF zELG$Nf?iaRcO*3fP9uc7F+G|;@7+L;=XIJ>~CS(tO_vx|$nyL~21i4b4a z582t+Fy9Kpn(_m06XBgf19hpjuqQRIUk6w>Az1Cl=2s=En*$Xe#tOQse=+lp(By+9d1^ zj-NM5Sjn#cOdRyX*WNTfqw@W&*yj5S0|f6FN(pSX$yx14_s`nzkg--yRI6WAszle=J@%kPsK#E53coyx>MEejijYwpxL&MnE8NQ7oHn4u*4t ztDNQgxpSMs>1%$ODVmc>4{xu1@7+fmP+hpA47rI+ykkFlgl1eUXpHFHfJa?-xFYCu ziI{}MAaCU+&4&S4?yxXgAMV-r2)`L}NwMO&kol2uW$0oLBf85^an?xMYV!~>kx4Zk zIer{cqL-KAG3#CdzDIjbIFQ}m&N#iN$?~V>Pti7C>(+gxFG!)Gu%)IXt0qQ@$7W`^ z#%@4Xel7y4*{4BzWMQhwBB zWzIS={t@`gH^$i2-=jUdi1_p~OoB98TXyhV9=_T4<2b&U&wC>I?Z7SSof)*^<>2D8 zNmpmMTmNj~VFdTk)0}VFAtO5Zj7&^ezDRTa5%5rJQA(E=^a@&m6ID zs8MCRq%a+=x7%on#&HejNhOCWUUO4y}xl!0({*3w-SWT*(o`{B_8+;&toCGD1HW-L#)XgInQX%PV;lQE zc{)#X;RiggQ$j*6deHx5|4Clu9AD9auLb^fXSC5L=&?Nqg9^`)Pw}!_F(Y_syEv+!t3M*8Xew2Oj6dl6X3BXhUX*V=;=a)ado5 z@L7>j_%{QBLVJ#*grR!E3r*M3O zgSbV0hpqW_Gr6JJ*&R~q376?hk4nxXQ^5l0MBJ44HoLR(7eWLub$$%?y<&5bGTHm? zD=r(H-S?_a$yaL@iuCD6Dr#z2Z_{uVBCIQl^oy9erLOiwuedn3`U+1pYm+Cx zG`Lmb#{QY=Cw*f>53torBvNcr1f0H@WMvQK6O!c$PG^(_KQ;}~RO@>dkVa+q#KFbY zwV^8s?+W?BmVAah&3B299`~N=o&wH-^>*$`1x|$xM9o&V4v+KMi*df#XZ+vib; z&#HHD)<65n=O-n)^u@cm06DFTE}Kgw+3Fm8e+J#o`py>Qds%vYv(diqmP^RzDo9kEj-;8_yM;aq1Wp_RN;b}&C}+q$B;1diBuQRs!f3TGaj(n&|Z{UKrCQ=ftF1xzh30p!R~5gGm5na zwhCN0Qp}@jnP<;pn)ZOFzH@&x7mk*y!$1UD?)sO`4lC0T>ETb<{$&1 z@JrNHQLg-w`1PdQoZ+G9jDBghlQzy5D;_|y*y=;P^&G|Rdh3qsL#+H1m`h=7^Yio1 z7Nn_2Tb^H9CyKa6N9Pm!_~&PnA9|a2A9a8-N`Y~4{3xzfCL}cK_yFS_*~;jKB^?h} z*3Uals|XWALmJO-ILSj=)G|*x4v~94gGv{+thT60FX-~TyIz62tI8%PCe{FFK8>D( z<|Cz1`qak8yQ4+=6($qK8J4ZPdQxU)^Vpm<-ktdS3d7Ju|6E&5ltcCCyOnZ7Djp`8 zmDx@s749Y8Os~5nGcz-fiYjz$B;OBM+fwlql1PjJmg+B#zFI%+@^i4(ei1L8^TcI4 zcU)nG?k9aY&Ln!iSw}q0&-hYk_4AvOfJJ- z(cPutlkSnzZ--)8!k(i)vBp|ILNoHgz_YnawTy~NO0TpiO=sM%vE%2^BsA1A5PqIL zAiJnhCFvS;GOWl7Gvavssw*O;*gn@X%N%`v{G{8o2w+m;w-KMy7B?OW78k~OkXTeDIyO?Zx#7+lQYjhGsrAL0BO=h`_+es7}t<*r!U0 zb~SGoG!>DXGBGl2EUblRvGBTjyb5cMlr5Kpiqso7m>AeLxAJi>lF4fxs2I)Q)z!(- z^mTP{2)Jpw?mOR~>8Y$d%r7|BFuro7q`5iP$cV|p+_Nz65S#kRD(>W@!Idj&B!m9aPx+1@9Z0txnf*A>^hklZiP8{{22;7TBC7~a0 z=sltSWPkhQMEFMWV`n9$ML)lp#6&F(0k)TEr*+xcOmSRwk0rk2-sD`R(e&YSckQpJ znl0K&NfBNi{(Of{D3Y?a#+=;U2VjIGKU&0_*VX|)Q(l(by&F(WXl$mWlw2(+5*xR} ztrd`6QsTVGPL1j0@E~AhW}}ns8ow*XqmH-?H>^OHC>A$ra+31%*cuvw!ynis*mFWd z`=7BUS*UqE32kW>AD!cL}$hTvbXTAEru~G>mf|&Ic1U*h}+p&dH$j#p1ld# zo3Bc1Y-|<%Vt`iBYQWmf^rubs1|I_NBH8oQ6V9T+m=KuoQl>`-nu|+Y1I_dp;hI7r<0er-auWC z`s`X_;>e<4)LAincApIOBw-%E%i53Z)I;L3>FJrSF}~C9bYrKa6lNFkyr3m@r&D9N zo1?g5@8+POpgW0DPTTwJqICHqL!+6d;tVNI1PP&six=B5HVI-;lT6xAJ&831qsT$B z04DOYqop}#A>YJaK`5o`}ASQyJZEGg+a^Kp8 z9O2HDD>rYI7khi_un7ygJHtX%Qqn3?pIS=MvszZ02nLwRlweD9cyu&YSQmj9p^H*4 zZmyQY3+ynQBQUp%#FfNkyHqkWM}3zeCG9lzl>ztJPNcRr_S?KuycPd)SR?cEg?9sl zZc=4rH08bZjOpZ*l9auGN3AqrL8V{%zUD}9Tab!8OOYwgybXC9Mz812%)IHNN*Maa z7lYbY!NIHwxeuJqu$LBH;5!I|naey(t*0xrC8ZMj{mo?97jd;TTuY2{zh>n8q?ePE zywV9Dd9NBNkFeiFhKsZD!M)NqA!$&hq_~W~YlmcnJ6mdMgurli*3g?QLL#rUw4@mu z)-;Sa)5DLp?s{1T|2Kl%zZnbv-@J^c5m{IFva?g}9z$Gs&O^31X2M(Rxdq2fW7^+( z$8O#%-#-xP3v!#LoN_i?UMt;t;Pjx?C$tj#GCKpYSO2lmmmjA@wHl^KXzPIf-ZRAU>P?{aJIph7UAy3^7LtS(3VD(hG~9wIbS!DYlrK7 zNI@>Uz8PCWazf}zRp;>6DuQ!-g6zWy#%xCcQvsvm5&pV)UhLLdqg&_~e7;K;W;Zo` zYMY6N5PSVPzmAF{`}KKOhNQ$Y1(qk%O4`SvcWqyEF3qYYMHh3?fPKrPLgJE#%bvRR zi`u6TRKMZIcq8wM2L?;%Tfd0Qe);ky0wHIU$ItIxQ)50<{8HORXWY|&N=kD$E+wTl zC7WQ`fan?tiB|~U8ujbE%0>1Wb~YCcH|@Nt*2{_23pERMtfwpHGyVKr_6*KX@NGEj zS=|R@TRvkKV>c+y-dYUDnAM7xw#l|9^PczP_$lwDv!%TJsotcq4gd zy~W4mmFC)G!x93KdZ@K-r@uuYJY+dM;M%4N7+2_}>#>ZP0Kq`JWz}yO1=Abvp zWnGs39phH{<*1I$5;!}^-wwzis;lEIUPI^z>QYkDokC7e5z{0T?mjN-O)8)y6gp4! zr3>v%Y-Q|I`8BbLk9F#j5B)}c#WBSll7>DQSuc_dMrujQQ|goJ=P0`0JQOuQJ^voJ zcZ5_rmtN~-pEc%>E-U{Xu8TDKr}x&C60ArOewLs7BDqdv9I*q#BZ;YIimmRAAVqUT z++cyzx&8mR88%U&>*zrwn zojD{wLcH_*Fa+Ht-*jO%OGEJpE&sS|K^Nyc>1}b7P4xcKe6KAjhy^TlS46Cl^lgl$ zW=F_X);dugyP7v%a&hO`b@Qs6G&~cZTC-Ri-!>tAOBi8f&v_J{NXl=kvn2FEh|goG zsL>#YEFn@`8`)Q=As$QU>i^Rg!p$0$C|d z0Ty#}MI@Q{HXxdd8J_1`z!5k<=XPg7<75|dFZXJWMJp0As4zhZU(-qpyRScDgIOgP z60XwbMaJSGbYm;-+nXnyQMsG&AUY_U*Tj0UfUt;1ts_!q^9qbb&775Oy5IYexHSzz5PIQb3a}G*H6S_6FOW-CCSx)S;1^aVuUr-CQ4H?M|B?!IlDckZ=iiW0}kJjh*q3Icw&bZ~J#?6f#R>E6I@_!ceH%8kT7F|R5BC8BBdxJGJNu2IYiCCXNvEpn_*zN*>5I$3 z*N}QoiU$2gI%Nu{^ zba$=vREZLV@2;(`8@DFQd_uo>lVyFhr4 zjkA-};7Vr+qnRwEGfA@HWs%1Ih?B`h9vTZssY^P#gJkN z1&ZT0zw-UZBNJ=={jBQKIFXKm+1ZuNE#;uEsRO)1fl+a|7Z=i^)&=6bHOMrjdO6~C zjj7Kr>*>+E;wrIS#=CHJ!>B#}Uc|jenK}sZ`reII-g^2eqcql7wGSrNB=aRaQ}+2M z^7|O*kKYYG>8NYB>%N@Jek{FAT@^0&^=a`ELy{kokKsx0s9%PjNAsRssAza;=nsAh z9~vske|0oY($1j@6;_sRyF8oQFt*tob0Mk7!EQrf8h4%Qd~`j_vAO!s8%1sbqtCOW zmLbTFja||>X!611HJI0Z>ouuwRvU*o!d*^OL0prvW2Z1e$IaZGHh&Yqa$U>9Q`itwAan79&}MC z8)l?t#NMa;Z=Z#UT%RmVjLWY(D#@Lu(ly0NbwFS*F)$uU8ou8gjWdTMY9Sh>hY+1V z&6=&@!LE_4iQ}+mbr+uAE=1Jx^(Ev5W{$X*-hW98+Sq{AkW+h{stQ;Y%h5$>O)xJMJ=~05+^*2i6ypDYi3hNgvEgxuA>EYo! zC%TX6ItJ%m2F?bQ%VZRYwSx0+aXBiX+94=i8du@}y`^ zgixOFsbEn{(aPLL@yh46Zng>`T?gPndB%lp#;%&U*=R7~=>Byv^nP;Euh zWYM$XQB&%8R@E%HsVvMY^Q02_@X^R6J6YKzbfm@J)={$f@?*PQ#-ZEB*mVPMX1e0R z>9;ScXV=Tc3bR>Rg*kL$=4PutwqLk_TkCetCfR}A%Gj9OO4C8Y@1+FYyMpb5$-w)$ zZi?usqHd+Vjd$sYLlqS%N{UyQ^&5ODBtxeLBidGHjM~2l8Jqb(zu=V3NO$(WpAAw#&M+l&Ezx`=Mgg8ARx{snYl_ z$kW&e1vGXE%n6P<%PYvDkmw>6&wJfS@c_T~txe;7J(APYF|&RSVI*u^bITNL-*voY z-`qgF;)+#cQQ~{e@J@A%;Qg5hO8?4G*X2`lCEfcotE6Ye&O_fPK-+z5Z6JA~Hw=qz zu1!YJzj5mHrzMpiH>NdyOrt_8A5pO4H77N%6*K#)SZR13=amg+CFdMvP@M1~n zkE-@<6E8qA?8g3dznFrybo|JTUD(NTugJh35#PGIO6~Xb%9YinOD49V36}QJ|NcSN%KB(TMR#SNqm)ja)4XoyedCjgMWb zBcGMSWgAX$h{wu!ED{)l+M`yIR+BzlD}YULQ`GO;`OKDHi}~I0&Q-fzzDL-%cX~t@ zEv;5Hsig42@&+D5azZ^Vn1RA-%-Or>ef9$I4hO7>kwT)6eblH53t zj1qTd;*hvPeOSzkjZ%nNJ&&s*IA_0>(OQAR`fSq4;~1JCRq?`X+WyTsqoE-Vd`kz1 z5 za9`5-9z`#RQMs?hS6x>jdO_V5s)Zk4$$Qg5otZT)n52sJAV9m(iIzIXi~@@G#l`A+*-n%NZ_moM4Cux?tt?eLS}>M4-0|M7a%>kpk`L~ZjsP0|xa%%G($}?#pAfkf1dsV$*_JiG zhsYLV7q`~p%iuR-JcBB?@7d>`>4@*B3;Vj zA$qamN5$78>Fwm(NhQo@#e@j|*I@LT`fz8b1<0GhmAJbDc`{}KnM$VP_af9(?=N4z zXjKYBa^lA*6i0RA@g2}$jLX8;5{n-V=0V}s+S>ZT+8(lkphNf#n8oxWI$HB@zYzdv z;(Zu2MoN)C7r6tSK>UILNY%5l@_`Trwjlak$Ll<(hG1}p`taAU4&V>c*SEF%1^yZp zgU}`t+#FiteR9{{Hd1 z^LV?kZKlKF&I1w>dj?};0fX4i5)-+HRt51gR`cTEgb73FoC+4U<~Lw1^MoSHU=;Zr z49{(zgQ%o$uw3bI^X7}bS52Vm#!22;`P_$70x}S=Ox9LV=zAm$iQ@YE$8E^uTW>VA zlJ#BJr}kj+pOTbHQg}s2E6UGf*JwC*;%>(>w ze0(WV)Eomne|wfNv<0XQPEJmjgl@xA3`})nU!FBS;}z1}NYoSD`}BPDyO+ zz8F`0H6jph<*H+$gH-ZlEv~; zfB&-v&mtpZ$5Vo`VbGhUl@+;*4eHqo2e8!|A;>aK<>Wf?MA=ArS#W|QB9Ieah1aj! zmK1Tlyv?<-VZ?7T4;%Y^Rb}P9NU9UHcgn-VNp_Nsi?h2Yhx>7H(I2eXOU?U|;&tkT zCdZuZF)&m%fqG>9EB^trBvYLvsE4nJ$E9*#TiEOgEz~KHV8F2|-V*cmi9&~V{d~QR z9)-#LfDS^pjAi{``>nyJi!Y*A4kd~9Tn~4;w8~?c9>!EvPcWIYBj{671$a@C>m+a6=#8nY`VLy7A~Z8dWu;$InXPHu>~sjk}^ysi`w}e`8czx7J~S z{n!2X|MfQiANWad;CTxRi(rYyxEB4Qf`VmVD?G7M^t&YvbKP}s9>!{E-q*}{mqHN_ zTWRlTTkU0dxEbr$!5UzHXFx+jtUPnuI}wSDs^ug)#@JfSVczQQ5KVl!S(xO?a{R^jeNieD!wO$i}U(S2ZBj4xqMd<}o{D`~Kg?&7Lg}~#u#h_JJ2E-=EZ&jnEsWkI* zf$}{iHUx!0L0&#XnHEXC+9IyC^)Uz$I}L!hihvA7r&GOPd`aZe+k1H-Fl_treBi;)Y%nt zh6PFyFVz7)<&UDK<^ZmZvGF;W2F%pYf8i+rq)Q*VMnjaD&}3_Seo4z`k*amk8nqad3g+CWs4EN@c35nHL1x#Mp zHWSq8IOg5sAvZ#YqI}M$<(2G?PTw=12g1QRHsad?X~qQ5=>k;IGoYw++TPoXa02+5 zt`UkUN(Lzi1fUEEYYaH~_=tW79R92TTp@r(D|4{0u-Mz%E7LPE2{Cqcb&W^cC1(q2 zmm3BYA$B&lFJZ;UGycL7*w zn(lQX05p8IB>fr$Dc4fT9mn}oV>U*CH>Ihe;j%j(Oi#_jqwbik7fHlb0swOPXnZ2| z;G|$6_CEom@nAlb6b~@ol)y&$N=Q>Wd z{VgJDjVZ(c!c%pRg*pT%YtYar=lIF0i|`{D5Fi{9861?({q#9HtW0$4j|OuW^{-11 zXregjHJ5Y9+ydR#arL|FFvQjIoA|@&p`$p}@mZh?4>mWyT&(=5cm-Q7 z0T=-e?kfVr@^uwI8Fp|^-mcljhvB;cBFfoeKrvGA9>0=`iUamo694(6A`g$N%+neL zGY0Ltv>{lGN35e7Vl^7!eFeLYI5vicZxl4Ydv=Q;qflzZpaHmn6i1q7+`wkttsc-M z4}E$KV#4=)_C6+q39Fl%-8pZJ!QSri7q?)0yMC8SG&?t!sRckLNYm~>^wQJwr_y+M ze5Yz51@88J)50ha6dCr0kn*Y2IhlJsJ_z^4WQq-0n6JsN`11>BHS?Cc9{Kfu%aVwh zz7P#$xCem(P?ewHL+7(Xg)~Fj>K}Y}zc`1!j~=^1}2l;r^iabZC0{a zO*NZDMNf#yZ#x0(gO|^6YT-u7G<^W=tFxm6ng+8Vw&L=h9rk6=mKQBy$W9WYY$6-w z+qYu1U%=8waaUJYZ}`Rnz!MWi1}PFjn;yxNIHQhr?mWe6f0lJ0!+u)se#PRVN%BMp z5J|{EJy+<-mWs8~(EPTxRwEgMw^uy#`*)!_$pcovroS5Ro6hTlTE~{F%&z(QkCuvo z49!MTcQ@z#CMHyM7+P9NBP$p|`wNNIwzhcKhONH7Br}hgRh{EI1GKc!I|o1$ZaS<) zrs7|stvy6!&ke{U1{0N5g)YFgQ_aQMS==fz9V;9r7Vrdz+4n=+k_A|ymzThT7>~Yd zXb6>@-X~(R++M0bH9l()pw&dRXy7%$h>zIbE)LG{y$^h*&AWThV~_QireI={aS{R; zGT`bxBR~P_I)~y>W%RFtvNppW$KHOA`N_q@lQ<8%S?0=!F~V-Hw*kmqHO0lniHQU~ zVTjmNWht|OysFXch;z&zlDwVfiDvrVaso_a8Sd|f_hVY(7+2!`MBqm%DZFgjL+o5L@sRC7Q$_&1lUZ+xeL24-~#oYmTm zH{nXHyL#74p4Y7p8d1<=JHC>~H-$XTh2SSq_$gTd^UagM<6jb94(R)oloX)6?^xo{ z0a3@{T>U7Hg!mdDcTS9t16%@aTw(6?2{x6aQ^blRa8GG(zf3a}>9!-b>4_a~rle5t zl|--sY`B&}Fax#bDwM#kmoufnK&D^Pw^x3I)Imu{a6JyM2mE zo73)E1%S0G8xP=Bc6yrROZV)nRy7?a@zww{q_B{mWBCN1l>!B*vsFmAzw|cOkdK?1 z7fiz3quvt;i-2HLv(|(SLbR8oH8o#rS}`NCuy_>SpxfH!xNXE`L$hLcNWkk^7b!Tg zZ|aAEhJJoK-nERf@Kw)i)vE-N;@C9JUBYsYNc&Y5uB+^cS%7?u0228_2?&t=^(-uS zEhcG()NvU9)L0{jIv()=a)M!8a*8iU`^pqB<+kyOywU_gISIGi5Qu010Zp;g8USYM z%<+O2?vBj)k!a#R+6YEmHG+Q>7W&Ggab4c;|8iabPP@FOCjP@)D|H6E`9FUIXD>L= zGSnL!O_vq(els#s7R#y1L=OxlBY8dC6b<+EREhsZBF0OqqbnCL8tr;F2+I3g3H!4a zoPrcMUUDl;j=rPCZV4c&7j<^7&M21K0sevz2t+f}g2n@^E?`q=H8nBuM2EY$xL}l5 z{roR6yTRmRWRo#OLtlTMYTC?#&IS*ns#AcIOlajoulZ-ZlMR$BlgW}*ipDVfWnm>g zgUGE$%b5Cn3PA!bD66|7c8m;9) zPyL3MkFQp4H7X0lk$_0tvk_!Vz5!Ngsakm^2vxOU_zb$j07h5Tle`6xCT#8O?6Ne? zOij6ftxR(=94eubme#LCkO#7XlSX2uTh_JpaNB6xhQ{WXl!l>=!BQk8^1lcDt7;8f zLY(~ZXat1gN%44S$C{#y);2a^OzsiP{+yWx=G-@2>$m@&r#pJD)A!|z1ed}qWUkM@ zN$KW4*@kvl2UxG+btP7_VzWY2tG?#|0tG0?egFP_Qe=}W0AvOPJP;PWHa`$TfW2N_ zLjz1>)MRD`=fNW}tAWg7&adY7G@uBwO=A4dUMNx4*7%JfD@Fo2qA#vC1&J9r$ z4XsAKRghrri|=BC(PUrTG8yF7`J7%rK4PVK<1^MH^}RX;jz4|FVJYvmG0&}9ohBLa zjPq|~TIHD{J9BCV+0m-1+FDTBDXLE!{6-@9j$ePSStfXNY(bq?QkTkJcz68Bvm2!<{4~7u z`nCBDYc!-63@oF>qin=5g7GagXMfk1>A!af+UjjUDaYD{lKXY|UbE_n6y@BJYP zu{o&mvn}zJHUW1X1AosY#kYRELVuFEnV=Kcp_M;i2N!TZHH!5Zem=Fiy$u|P z;5W0XwQ^|efD<~19y}kew>e{IsHi}mt&U$j>ekiIFPZf1TVP1BZY#-VnMC~e?{?Ri znUyccUev;YiP_@IE?!<T6bco*yer&pKc2;Dy6A+5N$;%>4DxoXnA6tZz4L={yct8)e4Vp3BR zv$Akd@i}&uh~rP znEFpK3onRNLwP6nOijZ_{xBt@K{$l#w``mxuCje@KxI{zh=NZ8zn4>8m%>`gCd#*C zO^rPo@l~BYe{>H?pP=vjrf`QH?MWI%!}@n?SJ~BHpsWEWFM$?3-&@07i__%~oh&>~G* zD!r!FIQ)KSWMLU0Dx;MOH0~p@r_TsP;xGytJq3jMtPlwR&ILR)biYm&^kcztr2ya_ zbY$c}iiE!yqkv$>&%}f_z}*R^pNtdb2LS7b;?0}#$UA^~Y=g(|Q<0#bB<~Ah*Nt{xk zWa$vzqxomDrwZ)ZeJdCcSxE7xhIk1Ru}X$~yxl=aRwX4Bl|=|r$hbShP;f5GGm9T; z3zvP$6XS=QhX`-#KOGab=8XNB{Bf8{v2X+rMO)!vPpYh@`=njG@s6Ov>Eh68(P8x4 zd5@5X{1D`^wg&9a+!s*a9LUiTxg6^u^JrOHOW~pQP9wWhHvZ(Fy<};{?(wNKD*{u_ z$5HQ-IF%fJ$=@+bbg3-*BFf6RvLsGeVtF3oL0_<*7shYgLU*5v4aF2))m2KV5nztn z9{p(aUXR7*vnUai8f?j{0}V$TK1SM`Za?9 zeF#MIz$|bpIw>A)k2EMhZC(jwfDY^U=or~$LjPPaOfPvCg6MqLW*AXy6l4Y^z zUY(dR6<>|*_#Q>ey*7;NO<4!u4K9lH#sUA8rZy$O|r-*X%J-?BH;;# zc8>#YMZ<`((?q%9>5WlI{GUh8o^j9y9Yw1RudK@GP~QFfHA;vm>Cj=wk&#cm$2!92 zqQ!;HZ2{KV>2QG{HX&J4;M;1_*|-5V>zYNuHymC6HR|BFk<@E~6vrWTgODv()141l zdE%xPPFT&7ztxlS#zQm+>3~(;BJA&j<_*0{93}8;u&PL>=6$=Njy*Lmh)I?7czD?w)TKnC_ge&4-HXc-T&b19eEka@g5Y zmVNlPKQn)9ayH>3GTH@>7c-@@@7USP%f8g*r>hMm;Z{1D)-*S(OGn;6+`9vf|5Gwb z29i;b+S)WezTkJv70Eab0{Q6mQo22(T~q>we#!95~WyeVXjWR-|j!jVa*1`#08#Eg&U{eU_9hWoqP zho-$I3;~de&}r?_#HIeY=06NGgo9Tt{yWAw(*NRxwJ+BL>t}Xy&&U}Lp_uad9AYU>$8yp@U4%1G2cH#)^ z;~HF{WdsAA6wkT8<%mWW6cqBL16%-uCERM5$=qKI3|jivqTApcnSB<4km9Kk+UE-Z zm|I(0W_O@Y2iW?w3g~s9?8QJw*U?f^Qo`bHvgJKPJpPm^HrFXfBKP+f3S(=~Gcp=0 z(uYJVW&52%C9ck`lvQvN`>MqIC|i&k#^6{A{Y|NL{Mog?I0sY%(^XZarANThn1i$q|Klr2 z7mxw{#E5(mO&i^v{)($(oT55cX{a$LQWK{aRA-T16_{F8xELwls|Bw|rIK3y_AGtw zD*h?FWcZ!B1n9WJ!=oPnkq&emaIqar6@?3dC1qDG z<{JsS>&l7>ve)|oED4^Ng#Hv4;t-5>6;;*BtoJxkgpE$S6&6!;N`<#w?VX)3#m#f| z_T4}!O8yGa@aX91>IfW~CFvAet9bM~V6sPmZ#dVBB=MZ=Z2o)bM8kFlpb~>wYY;Km zJDnUj07W=;w`>uXs??`L0m}Bd_v@J6yGsN3{i63R9An&UwIWfl*-o%*U zgEF(nwrmn?-3egBj3udt{sqZbdw(lu`{=}uWW3R?BnDHw4Nc)p*<<0vUD>P1-OF6W zbs$i)UuOZ?=FZMed{I7V_k@+#hufQ)n*MS)BB-Ilj{&WS@twu~@ffnGnksU@Gdh9p zO(FYl00J^rsGlDaWP(?Zi9z>$h$jO>$j$moJ6Qh+@falo(>Qm6|BDnJs?ktb zXaO!gpgI&>rYb+R&Ba&4b3i&-di?_qH1&Wmy>~n(C+E&L?lb7>nVGvWF#Z^DeiUL8 z^=(Oe`Wr+yhGHc;=SR;M|ME9ajgLH8(qh#L)cb3Xr~j66r5yA_y8-(aw2yAy`<$hM zCu2-qLdyUfs-blW9F9}aWp^+IM;7VdJB}1Aaw!yha(W7~aYeu+(P%LTjZ>KPoPh!G z>X#eOH+?4l9&s4cx;AGo|T=%VM~n zyFY9{w6g#6Db06uH5KUMfQgJn{l9hRIVQ)UF7QAXVA;WNkl)V984X@B=ouLV8|bJA zDmcJ{FF>*PpAW8mQ3Ld={woC76PN1=0mjP1_Kx*GAz)A3t^Y0!@V^fMoh<=*O%};|22Q_=~Mr6i8&_^DG$6e^m$F$^TrBzryeANe;fiV}Z(f{BhCz zo!jlXyL|K^IyIr{dk=;b`%yE&P~<4~odY)6Ps!mg5pFp!g<}v3x7#(rg?4mFxz^fJ zv}DNYMo9)zDZMkEhc@M3n|3cpW>+ftR!znzO-8=;Uyenr?MY)kP6}QW&t=jeAt&q$ zLWzn3nQd3&1i?F zkl@!V@vRzQmmu&%(|ay`k+QYCgqI|~{{4W%0>!gvd$~!aW0wzSO`t~O$gc&BVR?>x zjfKP#8{^_D)sAiQvrllY!O5FV_Cz?J(;v%oh+y_N?%U^v94Z0Z-x_^gE8ZVpVKY6i zfE%^4|0P4qrTuk(ZgA%2ohkY7jSGFep3%9{LH-6qQIpojBWJPV`420cUxBf+(-aqc zs&V~H2Cpz=Yf>5|>!+|Uy{jxP8ucEh-(unvQj>d?g@kmg+o!md<+!jqy{0X@z;zeY z_*SIW-Ww4$eJqA+>zx;soMrv)kOu*IJwR0i>$O#gSQs4Ar^?I^7HE#6aLhxX!a01i z_wyq*gDRD~#o7goiB;Ba3eto1TkOo{_=%9murM}sVpeoEaC&+yWvy>&%&cl|1Q?GT9NhoG>tp3&{onBV zSXus|LH_s1o&N&tV`X{52P*u}cWNrUms0niN7o5YvbW^q#^0csq4W4 z`CU_$qoke(4z4ET=Uslux(4Dm;4pa)y!-r&d@2Ay8(* zCk7=cwoPG{`@56SqwCP!?FVmWQm=zJZ%>!S$e@<e8qVcsfI4l-#G&KJ7rgJimsM`KFu&xQ_n?&N1glKJ3L*@rtbXv>-N?d5g})+ z2GgUoAHYXUQ`vD?S5oK+`!w7&0{AR4iEKH_mm>W3%o~?@Q&Dw_S5QKUQo<>LC)_vn zEfBim|Kfkh8DxJDp$Boo`h?K0=O*8*-&U8-3u_dzBR-g*HNlF9Yccj8cN zxD5dRz27S;O>*VirOvBmy3Hm#vS%xvYrYve{z5D~AV_?=t> z#GdV3#U`*86aZvlFIn(jVtqQ?0v*=&fH%WC+odL8HUO@){zalH#&&6Gy2!2K2p*@l z5Ij1`-Nn4EXu%2Lq})|4L3m{N(djS^Os~EQ~tM?Zv?K zHt*XD8A}TbG*ZDxjwjS{>%%$ohZM1HV9z~*>;||rU35Put!oC;1c+kmg7l|B@i{j= zB^;ZYg23ujlEfW`#|tn8@u{b#ruJPrsmKHlJ$5oe)xazvmKSIX7ts>e8TDgvoB;}2 znAh157d$Fq7dAwT;!lcfRK^d9L0>>IUdJNDz<4%ivha z>#gWEOe)R-8b1SEIUOPrH--E&p~q`koGvK#17>5Y02u=`Ea($*BNQNaM2Tl7Sgk}n zJZ=EMMaOLwHeQH`A5bG%%3sNmyp&P*4UO4YlsdZ>mv3?8k2@9w~rg0 ze$)D+B6Y`IKbUo+@gv{kZB_L9t)mS24}YrHTq(GQ-ndvK}K8jo88A4tAIXk1(+-KwMPTNmd-S zlja>PkQKZR(p88U5zFxD>F&;GzCyC^nKUe1%JfNk0mWW(e^{7f78G(mS%dW&EE6h^ z{`r{kr6UgFp7j_l?|+k(6@+-)<>=smfo>@`=OHS<&5h5qvbt8Xzi(A;gf+LP{61@} z3|1+>C*;A?+grdu$LmB~>3sov$aRHf6$8H(|2@chgVNo%5ENb(|O>1K!6) zy#!F0)-+i0J9C>juguJRVS`M9H1eF)ARM(4x9HilVh|A#QE)BM9yNr@D3LI z(Q%;a@UOAneuw)OOfYVRVu<@5pOH-(PA|aVl#bFgbM}FHX{#;E|LJm>JkD!m0=U&1zIRJ83LEnppO|=py=@Uc!DR;{IbcrmiQwQ;h-NB#0^3uu{T2Q^2PKEW*AfWOYCPoEGFxEimF{O5|k%+i00yxt9U1mstQnd#{YPtBrqwUxT(=%8^psd0}}^lbi_BxP``M_UB;VFY{W z^ZtaHw%1793|ODuKkOhy!rzI7FjR znbbgj=%}a~*&mC?vprd%Gy&ww$G@P>LCEK8t1i@@!s9sncermF;Mjog))nnX`};0~ z&|}~k13DN`aC+6M2t7v<8Ft$#!v~1XiGMD^Y_lg<3kkr{5q|D=1zswn3cqHK1&?t9 zLwO{RC5QhmO{mq{5XX!BGTYaZ`h}RlHpt!)#Q-;Q8HtvFheaILr>f&_43rM|X9&Rl z@5>^SeR!QX3nC|7+QtB*#&x1lxrR zenk4{x2`TRm&pJa{I>v1YrOqQ4>0SjXhaU*ekCCO23*G^-+mNhn=JvF(Ix|MHU@4S z{;5Vz3PcVnjuN&EIK?~}W7gtv*?dxzKfsT!OaRH`j;7m`LIvI>rAn{;g<9Iq z0pQt^6ybA4{SgzoJo3EGBlX4b1bnt4Az{5wV7Zs}^hnf{WEAeFe2^9zgHb!*Cno10 z73m&0rTUb{(ek|mDA&d8SM9ltQ25|K_;uk>vPBLxs5ae z1*UBKjA$2{h?tm|AK>U;#Ez~eB@vcaa9eq%w0iglEKRo$$93^yG(^Q$sAjRgxNeW{ zqFkFMr%L;Haw){l&aUr>^y!leMa)&Q`y+Nta@6aqGJOA0q`_bizz7G=MxX#{EV!rP z+`Bls%uE}jKQ6{k0+1oA_iO?t#KcK@4R4l_g{t*x4LN}T{A&7Wcm1Rj8zjt@v`L7w zo4;1>6U4z4FTA&gMaTJ-5qmbYmgskd^&PproF(|7EN;}#-aQbBJdmC@pE~hj) zodoo4C*R+?1c!c8b*t2y)aTZ>+iNzWi0Wb{yA$`}@?ZI|?^{FnU~_*On4wS*V%evn@-IL3@Y_p4z9fLq1H({q9S$bN0g zRVi5_+Ag*It7BlDtB0i5Rq>Mf-_wXIA_vXKGb2#N;ln2YC7%DqS68Z^$XH|M8bIWD zvLD6`FmfgxofMQlF3xLC{h6<<&{3fANR+n`=?z+(YxLgtR#;HLI4(Q?^1;f~{L-{D zT}DO51jp&`mE??XihOGQua-ND!=lx2RSXn$iJV+6N(cgWiZ==R<4uB#`T2Pj_F9#u(3bwn`=|#gN$$3kq@~iIXO>-dkZ0 zPK~5)?V4JJs!0o&(wokvBg|^detc_kHaYftEHc0b)49d@*5Pu|i0WG>b#1FpjTD#8 zm{!4_LU0>%b?bL0ruu6X#IucoG& zEK<5t;oam^QqisBB|IPOK*^^&nwk78aY@WatD8z`TYUsnG(xXmSNIjY>Mj*^j;tf_ zy7#Z|;(M7Nf32}^kgnj9$rHH!1WW|4((8v`dsbOBn%VDFmX*8%yIQC2L!JqaDp=R5 zH4a9l-MV*g3r*i$c`W^9DZXZ`7OXzPZ4UkTP`lr1+>j>kD!<;7Zs{xGs78fs_^P7I ztoye6=*{EIsm^Do@Qp^?F^R;8N z-xR`dd8yx3fCi=@?ITPGC4?CdU6AgcrreO?MS8q1;Q=Azq9Kg^e0Y@iWPbs@VEGIc zVec60ds!h%OJ8}qP;x8VBSpotZ-Id?^x@%!XiW81-h)NlC91mVfb8=l{KnkeTvgtl zm){GE&E9oHrC^xtzN*~5sE~Ji;CmP4>k}H8Odf~CyUwrZ#tlPN=pO}FPGWilJ!l@~ zRP#zO6n3x{yb^8J9_1fx`kL z0dihn=;%)3Zbr*tDmO~zGq6_I?Qvn6;D|rj(pLHGQ=m?&e5yY~C1g}K>==Ncc2K8X z?p~9=Be8^m_zn9f^}||bk{B!^qy}weg&@$UelKG@QKTSgO1h<+ci{Qr+O~gy9ANgu z)X-4p5vdRn>Dkd{n*`o&msc|#9i2KlIc&u*m_JC(y^U`Tzu7&|CXd{{O)oQ<7*AUT z=DQI6XSFp^#J~9NbRPNUm2f&xsJV!^E}VS^z51wHk=RjOl6oZ10=M9I&_4%pxAEC1 z@5;qFl%945hlbLGRwc~J2@zbxU(njnW{F6&XB)8|;Wf_-m9>sZqntbHK>15TpSf6- zT5btI9c_nonqTwIIq~W`FSU<9*U!I<>?6Q(#``O=^Ommvn>A$l9lu+h7{Bm>dUl>| zXe$aO1G7*ty48nOWy2eH@7e9m=EL=@*j=1iIZqy{JyW~m<3Y>#IO(717}EF+%F4@S z=qQV2Wr)SrRFg40=N>!6UeYlsXq)=0w5y7GamCVV;RUGuANLZv)-uwu(teSQ>eN+f zD%7^QhZanPNZk=}n%opvIuHQmQ>_EeDl+HE@;9``FoayM*lR zKc_fJ(uqh<%2HG3NSukje=h`q0O8|NLIM?0ax}lX!)eIutfc&x)YKo+wdv}rmqf39 z>FM+O`gU1p6Mfe3zURn6g{fLvP&qk;PVZ&o_99z-W$PD^et3CVFgg)A6&owB(G4oj z%1`4>ALq{5WXyIQtuC*BSjFt>JPED2)3_`mxY@PdMlD8mLaC}Qvp%-=N3%^9%XXq$0L9A0}Qq~5cA-u>fj zud39>O9F~3WN4E zgS!zEqgBm3o}#Iu#%tKiJsofj{yY!%bG^;D&8{W~93#G=jown;hz78>9u8MVXHfPw z)|G>RTK(T0Xwvo&f3!2mCG3K0(+0N&O!cqhl9dw`2m1U&CZ)<|)Y>S$b2 z(JVbLq?j5?D7JO)AAfN%e8jQad}!7yHr*B0@e68;7rP+>>HG16mIfT48MRjOoa&H0 zptEuMMQRX%tp`7VhH&X6b=-{K9ycqB>ILsnh9obf;l6{dmqzO)-SW`LgPxg z=Ev+RXpn|CkNWnZx@P0_q*gb;Lz!}~@R$EkRkzrS|M|0BT>Pj|$+V+0?-)YN+ht;U zB!Sk)$WeuP$k&>kmwtGt4v@IlGk_k~(sItQzlN2T?kks7|23_Jk;_$RMpmuwDk25) zQSd!+w&sTU-)qGoS%j-Uw>m1iTPNUl{nkO9N+;x8y|wqSaNjP|USWAdut^BJDsor3 zJHpmn{Y4Yy{}_)Xii~s!@OZY&c=@V0*T~N^D!dm$-y;2WQgEGlioC(Usd3p6>BVs| zMohr>pnZ3A`FUCPX_H2OMG~Ua5`RfpSVeF7YPn!%YsT7iS_a00)u!w&J#lGFICXBT;tYW#2WY zZ>N1V?~9{?Q3v47^(M=W_!T0@$g>;;9AZ(_wewprmdSM}SfOWp=dLkb{A(5mNz=3k zGYz`94Tr%#X*2?>M=Q(|=5L(l!Km_!`-P;MID(NFO8y#h_m>0I^8%h=Urn^3f62?N zEgC>(6H--GtfCVA<=2-ltR6p5&MQA`TPg*%qkKY1Bs|{s3kG;0w|6>Yp7hu% zXy_ylpQgALEJJ)u>P-{Xn5r(pEyh@&xzf~{cG*ycTaw4pq<)S2h~#X1 z6P_-zu43k!n{CBWYW{lX?M85Yo5zX7Id%wX7q+VUUEXGT(!ZS689p6##d`{yHh+f= zrN?C5{gV$dz%=(%;89^3SBbt_YP4N)^S#u+sPXW^)(}$ObmNSX;#fuwt zjX!g9?!8?cbF)qx{a?Rvb@d2F1nloO88zGwHZ&}+TxqKFh)c+XO7%mrYkx8XXQH#6 zoLlD?T*n^yg1zDH-t+gSO5Mh~qNTpRwFI9kWeM*W*Y~^GRW)THTmm#^U!=8!Jg+YO zZX?~eA6UeEi*Kh;?x8hjEgFuTqpYLT9X0K>t6o#?89pLJ^3bjCL;MmVLaQ^q&S9e7 zqYC@8NnNLwS*TRlDS;^Wi&YSX?P zs~N0W_&gl0VHNN#v?|G;xN9w7(bJoTbxSv7JlWcgM<+IoV|y0tK#Mqzr7_i$VbFvj_2WX zBC|`)-$AVRLa_&-l%zVpTIyI_GOE=Fkc2V1v{9grATaK9+c6Dx6~CPU!`hj}e&$GT zRE|0?Wo${B&)!7aJ$`#?{slpw{`mj-D~t~Z%o>uo*x8j;R9I{yO==aFUsl`Ju3?eN zN-w7^*>vB3I;K0L^Qhf%naPAjLVx8^)MV?*820W-7!G=T22YJE;Aa8SCU^P>Gz0|T zQ5oCpUFo&CwFNX}HP-6C^?&E9%VQz_Q5O>J2@)F)v#MQto8KbGSo^j1q6D<;faLt+ z+nt2T^3{=$o8`Zjz9o$O3Ok8M?%2*80dbYe9T6}}B-eRXGUYDi@rwrcT@@rGBuj;w zDWWNrE++bB%DTVM(qA)8I6D&U%V0w%g6dHjczz;@EIAx<)hk7qiSk-Dr36F{b0~|*~N>78Tz(76Z1bhq( z*$??F6~2!ToSd9oiYX-c&5S$SvIm9fzQlVEy4sfKKm_H`|CJK|1D5&E^f+B53O#+p zRo~Lqtq2L5Ig2RyWx}M!wEXKP8$oR_uGEg>?41nyj}ELh*1?yevSHb=zZI^$kq4btIZPz zt96ra6|CaU62ady*2S9P;FMq$uv-~OT=cG~H=p0XP~+bVsWEIQw`uPk*3`uN$iSns zhQE_gO<%O;B)%K2kcOMK0wjXKOyOW>hen%bMpokBak64ip9Y+wC09+ETfKy4WFPer zBL(@&<2_W}vTEWlZb*kEO$%V%g!eT}EvwGh+adC0&ekU{W zk={a13^^Hz9ar9$bh+Js{|@Ew8;vi=J?w?vXQcQw))nXg0#S*fTzdk@Ifn2kJ@@D z+2BjXgYVzi1XPq|-h=#}3S2h2?6pdygo(bP+$_`)(#mH8Fg?^IncF8Ve?@wGjydigBXapu=kY(E6#PEZ5 zTs$Z#|m z$y~@p$li^hXH4GuA?3#p>c#Q7N>fpkr+TZ3D2K{UG8jUt0`+OOmmU}U>N+|$_{`7a z-EvvnEJj%~NO~BfCn|-sDYW$*J>op|3E`lqehP>aSzqUCtj|tQv6fz(&o(&IYYZ8_ zg9+*dw7Fh`Z&-JFWXw~`KJd`Iev5=_ zS-_FtjXwekCFA`OON?t8)G#;dP#yWaNEwx36?4sruhZ|i-WoZDNtVFxtzfMNh-Zs> z!Q-Ldi`~?T+e<_1DD)FQXyquQK#LvwoCmt{eMHJvVfBdHJ%T86|MrzIkTl2o(vaR~ z9bEA0uD*kuw0=I{A8C8=S2G~HQi)cf;k7iyYYkHO%j<;WIqKQ>H9m_i*va~!lRh{h zYRA$l5s9CnDm&{R#!N%A!dj;PGpM_}8v~WQZf2QbNGh=&>K&D^U}RHO8Ob4M#Ld7bNoK|3=jrpb3#s@ zbpz++;T=j=7D=QfrsKYo6~jow{Pcu4t1DLMg-}LHY^=lu^_X}^N&KiRilH6c+Rb+o<$eCDK#XAgtI?hdn=Y%BZhZ zp@piu=eVO~a^>+gA7V%ZSgdm<+J18GJz5-${MlOaBac!+E)_X0&wYc6M~wIKK8W5r z0iEIfLiGDCQB3{yPB;F)E*Jh2xec50`-}a$8u7mcdzR=iOxsIOM>DL=SWOPviJXF-XRU#3j4_j!0tEQUIz}=9V!*#RYr9s%pf=4lG09h?$U&NzV`jvyF7Z5|h4tJK*O^kvc z#nOPX9=t6n#|}k7&MGW>JLbZDl+WY3deU?y0Rta{VpFjNk9y}_Cm(!-a|)3-ke#i< zPuUURzv-F^S7$bF9OD@zxQv)umJ=#!EyhbzZZ~uovC;8hK}PvO&OdRgxEbvq?UH)1 zGBYsv=P~42M5<*cbS;hZB^Ero{R!vK958$(*`!gt6++{8j~HjN+Sc}-yU&BCv(=Bb z@64YONlKLl$1Xm&pTy^Cb;Ia@J1BHG)eK<FP4z>DOs%(8DaSN^~GO&77KNxT}ODj3-px@n9hbc#^QlirCbDbkKJw( zz8?RPmWmWfl-|`>5*o7zBiB6vTcXro)9tn4IcC$d(z5aE9nQk^GKaYv*kh=AcU7Zw z>kRTxB$17K(fcET=lM|7i|rAv*>s5^w<-z?6P&x${5dW)<}x9DCjyeNw!uIO#Dful ziwO!2?nm*Ps|PJofksRUI9hh;1;EBiuxm0y(UZ2jz+HC-qH2%b*tX72QD&@a?N%Rw z%T}_cQ8lG!KDBZz`U@S3*h~1Nq|8v2pXnU}BY2v0Dx`_SpYX7yBB$`Qvx&Y~QpWQ6 zksFGvupNKK=O3lHVphYR6TM`Bb|FO*ATjefNW5K;?!1>>>PG>;6LAsYe@Ga{f5ebF zkZDxE31XbmPW~07%o%}KSzBd?3+#*6=AY$%(v>MR zKa|*Kq%&r!{G9xP3l!Khvg^S$3PLB)S4>(6Z@RjmWe2Pz z23x&9<}Z5JLFoI4-# zPV`XKT_;Sbt<8 z72@VrtMi9Dm#_zevLOQK00&tz%%bxmMhpD_aSJzU&k|R~)Mt=xV#t8s9)W5fuZ0$e zjZO?ir}&!~#{Hp`BKKnOnZ8gj4ol0wz}s{8;I{#O=WUO)|8026(1a|+6O!=SPP^K| z#TR2nc95A{FhRXsVP#?DHd{&q;qH4hMO^E%R>jT&CrHccK7MA9 zl>C|Dr#asN-Y%CfiMez@Y#|X2b9XQMi`i~Xr1xFXa~O;o46EV*E@W^nk>Lz6;<~&1 zKfJvKP!(*y?yVvr-JJ{RZV&|NMG4ZK(%lWx9ZN|mK@gB`1OY)xy1TneI=`FuJ@483 zo3rQxyZN6#0=LvNUqNxgN)#NbFP%!vPG~Wdh&?k57efo$?4M1&oTPES>i%scIc8k z_WxYE?^NfHE^Ry9wZ925)pXPr>?~J(p@uFeU_4}bRQ~J$#c+v!55j9OXD&h2sU7FnL3sSkgrg=lo=&n{Oy&Mk*TSApoP&)q0c}`XlxX` zH66obVwmJB;7&ju36nR}DCheeEClpAL*n;%&!&nr*xtv=ipgJkMrz8LHn6Bjv^kN8 z`2Eb(J_iE7oE)(-iE09#u}{Y>VA5N5b7=caHSZ|={t0dP`BRiSr-I6L7k9QHnXe1( zX-hjh$e(l$leG+AVvzD5;U``aNY_71Ga6R>I>+=g-041uU$lC8AhyOi=%c7Pb}O0C zf`N{XzDHv;^@rWd-ck#o!GOQDs><5!70^Bc<`L6zuaY~T*={~zZkEK2iIK@W(EI&4 z{`i(iYT=-H_Z?&6(HA4nw`sfzhlK0ulyd}~pI!f#ki+=-gUY){6U8A|n;}D!JQ}WfV7GmH+Ya zsi`TT6V13|!3AHSO#-CE0h6Pk-5fv8gA|BCc-~r3S@{`QSY2FPdSxE%C?wm9Eg}zD zmybWrsOM4uV)s3;jIaj*3+wtC;nf2&_#`CDpFe*}ZGTx@d~}oi2fuP&TmF4GRU!Tn z^7B-}@+f@Cjp^84?DXf>6nsTpo`sIiEO;-+07wDo=j!sFVQbE4@!n1wu8%D|#GHUU zZaT%x+q%25Df^E`zZ0s=?$qwFEw5`&2PAVI;;aOB>7c%xHK3{WPO`vFMoPXFzcQOk z0ku*FWi>}NsOxt8%O-V)-|zQ19l5g?1?Ff9=+G2H!F)pR#@V)K1J|0sdYWZIF+^|2qw za6jG?f2}RUb(1c<^nv?$l3qiQtuee1iwx&gkIOaDU#Pqe{!2=FdW)-*bz^_h%JTAZ z07MiO#dp3ba$4O0eBWod`D%$d9N4c7Iy_%fkaJ zPtR#G5q)gJt$J&XiS1E5fEcXw;Nwe+AyFAff9HE`c~$S2&8%E>r+KtGDt+PJuD^m;ONs&#Gd$Z7^fj4j`zGfDapw5=lMGzkx8y~N^v0*(+gsfT<#%q7Ss zKBw~PI&K@wvA%-tZP@2SoHQb|R$mO0KM`dUQu(mdx)snwu2+S>W=zKUV~ z`gwW#7dhf~I380^mI{cpK9$RHoR4HF)D7W9GJK%Y_9?F4$S02GwqR?4Hz2zuT}kfJ z@KMihE_Oq;$n+xjBqyAT)JN8}s;Gztd?Uk^Ey<0|%`$@)VQ%iRcKHLBFIfa^>Md7h zqQ*IH=hIW%BB#DLPMd>q01dM>HM~($hrCm!;85=2n4WpZP?A;O)#EAA>7U&_I}&Li`5jdthdtCk^5^ zvSw{vZ&Df>AXH=KaO`uwlduIuT<1Ds8Ze#2a3?voU^smKb?|L*UU!TuNFJ!rX1Jzj zCSz{A|H`Dzs8^sVM^j#1y$4_|Dk`7q>gw3ZO}>K2U6uv(yW7>cYr0IR*pt=UZkQPF zhEZ6$poUt$wWUWr3OD|Sgm}U{=oTjpy1J|V>ne~o65g8d-zGr0s@%m~r3r$OlZ|~tHjcdDjUAe_U*Nk>n zex~fY1}No^F3ylc{M6NW?6Hj{{ciU0y-0AVJbf$Wa-)_(d)F=-1N+q$dXuH}!oa{_ zI_B4wtgNh)6;(2E{FGezDR*%cS z7)lcEV}>r2Qhs}J2;sOZZdO9$n2hQQG`?no|N1ed3XBX}PZ;hL8E6ZSzAMm?XmSpz zF_SWPZh^NHgR&ISEU}mzEHs2FoBng!XDO7&0SlPe0y36L(YO!-99(BUyA*0S?FOvM zxytpmy?#~5^c3NB^cUdd=)@o=%~gFR3Ozm>%D$a%toq%Sp8qz6J)M@coBA^|Hwj_i zefvynb7x;%M5gzhB5EtLWSz;&U&rp~&So$|kL6C}Htv9?fHwz4KOBg(ZOY``Bi~;V z2mm@t#fl*ZCrw!6lP$Wnw`|yfSF`r6ed1l4Z6Q`37q?c{XDW*6VA-cy_*uh~A0Tkt zD_m%f-!I>aF&b4%3`XEzyN6zD`BpTD>muUw-rPcEMHZV%vpmZ-jeL;pad+sX*lrd4 z3MKD?C4PM|eOos{*Hnz2hDrNQ=JlOKCb_F$f^hEk25R#@*)|fWb5)-9ZJu7m1bTip8`2<`>2b8X}~3aMR?)H-^Gzn>>-AFPN@KlZ`}$f%(} zISOpblf6YD3L4Azbm02vojVGwL%D6>ISgg+VyI7W41PQs*f)$Mf43!A6aq1kaY(JY z2nq^H_9vim4NV5@OnCtj>`_Jen3zuO27mv9sfuhxkqmW})xT3FF95veVBM4sCZZkr zb~FliRMCaH{Zraj%CnJcA|64;(-|T}=J69nc}@XfuQEBcMN9eeZO+f#P*tRLp-BLR zptFslqB_CctO4=4?%^i@QF)tAzd!Z|0lm4*u1ySeIqnyesNK;i01#V>-&LPgE9fR} zk?t^mvUa!ObbBAH@Y6046hP4F1Y;xHfMMg^Y!+@SGu36m5I23dbG|@S8HL|O#E?@+MQJ`$ce)0af z1u0yO30%pjY^tueVKA$)GVS@^OYKPYrB&j6SdGc#|!nY z_3n@33AlsXe>F=LZHj`SCogj6eMvyhAR*-S0!4kk%yr~i>-rso`}7BJk=!jBe*(p4 zah(S9Xo*CM?2jKMT=$2%z+E$V7eV)NAfqUdUHC#*YO?h0Ew)tKceRKkiRQanuW8Qx zQe5uyKXfX~`97!bEUmuJhEXI{XZ!WAtP%2dbVYKgF|`!P`v|?Ozktu~o=*FEB?=eC zy43u{)^v}BN@eG8j1Vtn$!qg43ZI3T&n{gb3pwOb?5(Dz)&}i1JnOIu*ID}T>(cai zW1G%rc22|Dx^!Y~?@t6MwJ@Zk%~(f&+)g)EjVF)cWofjtL{vE?ITd6xGNh@*bIq0Z z5dhvmutuVI;`cJOE$)=9z1&~8YK~4$AK(63d!@o_dhMVyO z9@LxgWY{^mxWdrMyc(^Kli`>KfWr}W(ct5@dOBdo*Z3!fH z9oG>*2!oCYm6X4{qT-nC@+PegB_$b5@yg2hR_bPEXZd(|TC=Smw6Xrx!L=L2fJ;9= zKY#H+`!T25v-zy_SCLja1at&3YCC z9vidMg74o0gBSkS7aAKIyY;QIFMlW!UF#}QF{FMzkXFa zEH+*IJd4wqEb-L4)Nb53`}Qr=dY(J59=26r%BS7jh&5ep)c>Pu@y_8s{ix<{zF&v8 zv?;IfSi3Hk(vA?C>rc|w*5-gmtMHlIaYe#r$+n2X)BA6O9D)D+-ss)!*)CghZBv!w ztYF&Gh>o{g@@S^8@3nj?r{vogd>AgJb}n|5uvjoo0bUA?hNM^s1Y!&<85plmmC}Uq zNJs=-cgDcLqUNiVZXjTjyN?1oEv9oR63+IZ$X&OAe6CJi@#6hJCrjGIAIEL5i+2a6 zX*d6$a5A#8UI4`+e6v?YEgk#w{(9H;+6MH5Kv`jGx{hZ>vU)9`5&RsSVc4^#PW2(d z!MJ#M%lWC>#_KN36n>Xf2x2$FQQ6?Ac&^}T^C{O_$oKjbY!7Bm3!|e^eRgUl^{u62 zkR-B|YRM=l;_6EL+TTlDAGe%~<$5LC&HS{qRaI3LB>vivxmNCVW|gjXn+}}d1@FGj zoN8&}W`%^6Da{g24*r0&^N$7oX`+Qk(gAj;a?nh)wzdjk%|bCPD;iRzU(-ApB^sB2Y+6w?8Yrb5G0tV=9aApFRRTZ%Ch8Ota zIhHm?z1{>~-5*ZtJsJkSXTWQe5+m!sh8%(Wjubbt z2`sd|0H}};7@qwf{GyxB)!KgqNHmz-oP%)_%BnJX#%H#X#>3{DyNkuJO7Izc1tFlVq&_-cZJ=GLU=-3d?PTZTa>_L*6ht!3=k;;|b$4gS?QkJRXc4qc zkH*{jw>d_j_RNRxOXE{4e#&?k*axQH@!@(~_Va+-3t5jQ6((Ek zKyR|Q+8OrY_Hqm$l(a%CD>;9HQF5Xvb;m%WcFCjV+8P6)7u4inTBkEF>B1Z)ZxkSdXdLW;~B9UA)OCaSyj+oti$mnFb8 z3g8-+$@D#+UR!&gWJjr7VZ*2r^f@Bo_-xVuMJJ>+u>EXz@-HrLs_9?R7^&abSR$(| zek=5puTI@mW03G|317Kv2_F6o;s{AHB&@uZ&xKCcSQEGzIlK_JtAJThj({05q+`WPVZ`}nzb=aB z&G?9-!=IrIz6B3BJPw%gPP_0xDX!feR3ae?dIm;^7I2O7oni5*sh&Gyh5omz6vaLh zQ3&Xy7DLbq=MdqbeKJ9}zAO<6y@WIRF-TL?mS#gr8)aO|lMvR9_~hCG2?10nMg~5@ z@AXVUcUI*gxM|)CIyh&mQ$!?+c{tA@$sa4hki>2?C#9;VoaO_h(eOdi0v050%TJgX z8H2Y8;h_{FenQ?+^v~>p9eK*|>h|v-SkQz&ZCe8=D)^{RUmD*`=-8{(L^E`g2BDh( zqkr>Cqv{IvJNl8};OC@l3vDBWUI^BSC6QyK!C2d+8G;MG7kan1lhWR^xUiLhK$L)G zwx7v`tXZWw-b-&BI)jNEwt-Y4KK4>+{G1TXa&T#u7*|!mUc`9%Wh9Tq2lXP;I@Ro? znEdmYm>8(%Zb{wHlSE;m4L;*fuFH&HN!mL)jBeJG4TJ&xQ&u)oRIYshuZqUltkxR9 zM1LyE?m_+N)XPAEao(-;Zz zIbqdn{bK<6t4KrN*bticff=hu5uuf$vpr=nPK}Aevwm_=K1I%JlXA4$2{D}xUhFdD zLa7i3007k8qAd+V*<$Hb&r(zy0NVA`ei)PYA{efy_O=>a+RZ7)_ahea=FCt3{+&@* z_mtzb3CM7QnzjbRhu8&whreMX7WU!C&Q2bcqGVUsV+C(V;~;JAT*}w4$zp;P2qBUq_VDo88(uH3vnOH}a=Ds{ak93HSd zHF|AM^A&&!rOwFer5c>O0LG&3IQ$e~P;6BskTX42B1W&n$bi*f4=~-ou`@afES-n# zgJ>J!^C^>~H#(BYN?5X;Llm4wXQnmQ0A&^9RM2$Y3UUBo;%y1X`ULRy)99Xv{ zX|oVq*kgG&DFhNRLer=Z9QUXarl<_}%4KkbyOkZX6}LposT@mFSf<6VK)T9Pyk)n( z%mMJ4D1F|SN6Yg4<1IOZ+i||!<)8cS4vj6+p8*&fK=J`KEamm2R2;Ys+0v`PlJ9&C zSA;4FTuA4-2t@eIn&ki{ckY1vSR55IwRvMt%cJky9JWwI6kttb_II|oABE0?`_17H z42&riQR!!(iOqXNM>idFaGe9sab{^632wTnJ~ z73Kz_{THjmB^q3NucJgBUY^s87_jOETlQlyu+Ehm{hrD|w>86%Z3kt5=&!-%x*(G- z$yORJ;R+S+kfyQ#E_?vSt>~kjgevg9$@6#MwVq&3h|mKe^Nzk}q zX&`Y#eQyU(S4Kt*y(*zk<>n=wnKvT@I z&aSIUlu7ifu>!kCLSbflyk2l2tx_WyI@}0*ozkzw6c;luymS$n8yY5oQREq^8cPjc zv^^*>eK(Bzq-qwG;46n57D^mPDiHWVK!`X9K{_(}!-&KDjI zX5e}H*17gJ6cltb&4i{sbrCsbI#mujEU1oby`AsVYaf?3j;U7I_Ma5d4rCx4>z}*4 zSj}$5u$!(v$f$d;JPGk|?c3@qRhxCFN;5{TSaJq7`_5F3sFt37-X#D4=^*=5LWtx~ z(<%?m8293J6ZJst`+ zp)av;ELF$4cXmdBOD{2*qM+n;*5_+xY+xd>vKj~tL1Sc`$y29z3r#6h)vmn#^9SYb zc1K(sQC-#Nor*Ip`;psAZJoyUj@O0i{wf+5&Z4c2v9YbpRUsj+vOQdhiDAUV_oHK{ zbozRY=i!mWi61Mg>pc`@{^%#DsGWfb=2hmFI(J9?1=^Bx>6nf867A&^u`)#D!q5AQ z3I&prYTG(HGxG2W4$n^*yL-I8R-Ra^E^iUGk>KE+5n}J|u&!^~yE-A8Zu9bzTUriU za?=eBgoiIz4sZfvm-S1?$mQks+qXs@9bJkh444eLhzg?WNlEBK@064%YEd984AaT+ z>~NmAUV_VX!X!ijZ41p&At7k8y#s!qOwlp?>6vzUpoBz*jOLpTz>ynXox3LfGABJH z#SxS2wD+&K=lWMnf@F)7xqg;+E8&4bH=_5K^@)ilPA56(={(G25Ee$S!G#5k*?Ral zGq>z0DDF8l7F8|&L3Qp_a)X15BPFvc(BQ~pQU8a|^GuUK%KHsyI5)Kkp6=RqDhau8 zLLNH|7+!09&YS!CG^ThZJ}1{rzsHNu4U;B5)zP~nlarD2CT}pAEw5zV1NHk%PX06oO!-0Kc`^J zH-y#9&D!QRLpq<-{UTv!M@2Rd-aE=r@b#T!gzSsJ`cy0&2GqiF{SQ9un;lI2mv2L0 zP!5VN-4t8#T=r~Hs)>ox6f)|C-3eP{v#u1uDwn=Fjt+Ik5>1I7WL&JmM6pc{7N4}t zX6(P$fr0LM<`+CX=5uq{m$N-RWe#jgTar7wMMe=RtI0|CC?o>|FjrTC7?c1365@Nf zzf}ZnOX=yZB^h$S{iFO6qI@3xVxq13a~@$hH?5hEY!7y=t#YoTqarO$zxgZ@$`7cX zu5nL~aDd_86JCy9hIYwFw32f=#IPqxXgsn})%BM_z0@NH9uii}%A{BjWqp1`EK9ZV zcM;lPs>HtnQ8P1d$s1y!8(11NNP$vQQ*FXO$N;+q* zST`C~>g&QPKc-Va#)63n13w&fCNtyA`Z5dw1a8|Ou3TUHi^nN3(GF;7m9=VMtK5M1 zK~2q~hDKIoOa>tyPh}0_g>1D_$-UIW*u5u7+FNEd`CR^jsVNz&GpuUF6BoBw!^gJ~ z1H<4K<(Q3^+FNV5X6G_ANGlsT3N6#^5|LMxeX>ze7ySG#rn9`f2YGoES67y%NitxJ zS7H$cy&|@}`6b`-ZKF6!j@x_pATxRk=A8&sAEB!|QMiVYddih$IV*-*(_Pck4~7Q* zAkwm4G+RVl?7uw2{?o(lf9`=#=MmiO<;mK4oxm0z}{!xzqh#_l{tTinxWFo=*0CRAg32`5cOV; ziew8U4Jx(JBkNeJ|D&>+-@|6^b$coep=j;gYo8Wx3+rZ!rzFINxVnO#CZk}evDYve zoP_EV)=D|)-@!qluK*LH98xVeaR^a_=k?k5!Q;z=Dq6j@x~raYsB^5dIm8pvah{O1 z9EbIP%>63SP+~aiY&mFT;(mM}`6p_P0E&tFzt8#WY>98 z1nVOB_SuU-D%z2P0@(O?J`+<5Bb$hlj<+z+nbzZ7Ffp#zR@8h?(AV#2Mv)bHdYVW@ z<({12Q!tzkE`SdAA3r)aH|*ZLpl5*?r--o!qk-t7RF!v*@h$y>iz|nV-L-nUImjq= z)-?p2TpF93_UjPIzUVsoAH{nn)uPwXCfg>q3BC5vmZpcRnZL}iA4Pv!wn@(THmwGX zcDjP9jSp88Jk$Kf?!z(dQcBnR=dfJ5S|fwZT##v zdTTTiQ&C&)$GlTf#?;cR>TYR$KcSSbw2-1XIn_kt4ZFA6DC#@MmyK!^KUgqmpxBol z&&!bW6!4fG&)%JD{}DDG=BPBHauz2mBK9(ZvAO6To$VWLL|c1X24H?nWnKKVPf6+PIur_z`=%><4(d$ZURm-Qits?RaARQaJ1U zHpmF$B$7PN(;co7vf$@o_yD2c-7eAaMS~puI0?zup<+U>oq0Zg zlFtQ)1$Y76-jU#XjY7!AWk?y?$`yNsI}pSQ<9db7BKq_&vA9uCfI37i>x;0>r1&z% zy7&65=9EOEgoz<-1I-RGu;Ne%Bnb1dR!( zaK}Fgwl^9>cnB3c6q`tS;JH6c?9))H%xa=o8)7O?7PFtHTg{ZjqQktDlF_eub&8n z%yQ`HB&cyOxPDoN`?DJ&79cFKI6)jbC_`9-rzbXwn>1Y6{83zk1;e7$kg@I-F1^D| z!vA!>(cRluna>PdxztY~%8{D8`E;HS-Gn9~!D6F{E$@$sqg0C>V#+qcufzXHs+z#s zH0t5YKVaf|;E{e8YOkeIo(r9`okK$oSgd?yYD8V7vQZmoJJKHt#hN&2P!b$?e6|$i z2-=#SBug2&C>*NHn>#4H$oUNlOS2886j|{IP+6|xF{k`yl#eidrzG z*+$AGNlfhJ?{=Ohlo5ryA+hyX(s)yy#zgy6vxJrYHXJez^L>1@i?0n>Dt z*C9p|#d>~yez{9HcNbUJ?J5t0@~4p1&I(%dm_K6ClEmxSXJ5aFxKtdTEOtIrCTgaS zuw3axqlhMSKZD96URvV*UNXY5k|x1Tj=~KKoyB3~Y5u13w@x-$5t9=Z4xQ$reeS2P ze}&N4hihrGmpe9QYOF?pYqL9&_qoN@U9s@{tIkESD*4Vq~yprT)0Rk1T&$Hn177p28v5Dsj32Iu`1)BoXH zLqpaTaiNqmgmQ^DZv?sV_I8Jbxp>y=(q>5Xqmrmpe)OSrOP4&(cC%Y^@(wG!Ac8ot z!o31GoVj55-UM+mAs?FaFf-^H7-J8-Y_=TWSu5k!BU?}^f>ch2uR3&l+su@M!d0uV0ht0(t zVbDFzM+eCJmS2<5<+?Cxax;Mr3FL1sX(z_lQEa9^-^a&(?exS9EyRZCW&9vU?7%mZ zmWW--KOXLuCMzLzlw@Btw?=yIxQ>ZaSW@CH+oK#}7uzy(8FgV6iR-eH5Kz}$Je(dK z?xA^E{%2aCvUm?CoP*E(wcHC75?vK%bYwL2gRB((Fp-*zb5>S1kq;3*$|FD5);ewr zo1)~R@0p%17L6~yeA!nyBBE}GL+H}=Jy!H19XDO9I@!7+&99^I<)fX#9TglCI`H28 zBZ2&m(#kaMvZeUaNok5Qv*nu{nwX&ckqFC;Y6`3RVeXX75xYy1fW33DbFi3ht^=`6 z&<`%FJ-jItt^;)3LW$*a90~Vt8-4Km@XvQjCrWQs;&%d0;6x_xZY4Vij_r>3`j!qp z^mXxcIhJ7w*AU=X#+zWSXx<}b!i5kQ$3VkzH4y1YlTEa5xvlRq5;8iom&Ies7({ic zwlpLntR*$VN|9D)@8q5$H$lgnt%4+ImGS9t+Q$PVyw=}XgkjkptrWrh^JQm|Z;VG~ z(rb`z))T08sn>NiT1uqmUdBTsiZFC|QqBKHLyyMrQW>FLF#F0;82S;UK{<|<430h6^vd?cUfx)d^q z?c*&h3*VEiUM!OE5F4y2f}8@6%kr58{fP%6uf&KnQUZII+~-Cg-6V3=)q9Fql=C1y z79Q&wiD(a&^z#NgdRrx1O0aJwQ1N#&6g9F;G>XNqv_mBB8RxX7n%k&DC6`w1Uf7+? zdcHPP&P~q{L{W&WuAjQ8nXFuzJy-iK80OE-bH7l~^rc_x(<T;@F}Yt@wQb&JS>mNwe&ZQTa0VX--;-5oc+wT(xIs8v`g4$4CKR^ zuSK^`LRGJ2awl1^AthxOvvp-_D;*7N%>@MoN6XutkeYI(1z-2>`@6hupCdy_a8Q9| zsMjrwddGRwYQZy~lC4ZjWnrP#zA4f7)M9+Piib(#8zQ`bZ1s@99MN$2IbDfL3eLjJ z)l9{QfCz4@_o{!IKQ_p@60wAxYGIi4!)C8s7yFV>aE<} zPr?eEwv)E~5>$F%-~gjfG!kCK%9j9{1J0Q-PTVPsG^K$@HPp<@qR%YN=*wt>30)U?&v?<{e9S_u? z@@2=g)=qPuB(l)RYsThc!`UtD6a`g(4ZRz2+ZkueB)23X#bd;d&#Rxmo2WS|c2=O2 zSSuDYy|p>p-l>f1_0evqE}J2s(IjROe3M&&V{Fpdu|%tLW}B#(7w3{!KNs(_`Ej7b zJMx|V$;w8RxpMB-Z;O;`lKDhQgs!EQ&<{F4Ng71=ue7Ui5YY!`y{2e#kGp-mN-RI_s72w&zj9<$L!{?NbrISJ7rTV8tV!QIAe3$jL0qpLaK!po7yNw;VDq6Uw(Ii3VsqcR&keHw4IVg zXE)n)w(oPflq)M=WeDrd4=o+$#8C-QOGz|8_+dR$wYH8@*Xfo3T<%;hSPq}D;EK`w ztM{jx8Q+EqA)(RD*1;vB-|VA@wc&f4i4L#fbUJRKI$NHptyGqn}o0!mh-jJ zC0gnEr>*@V+L53$a|Uxg^jh%)yXN^LddY0}udQR`uf`=?6t{B>+AF45=M5P9q6>?Z z4e3znHTnLI%iH{>i+QlEKKr?cDUXeX6`-S9G)<|jYklu_w$pcWh@l3JOelk`L}rN? zL`4l$r7|e5wF-6I(x`;vnv>KqrjyR)vTtJ^)NH?BRa=5@T|wwlHstD))iu^dMQ*JQ zX^}kbE+ud>PBPMEkcbqrAz_sqZ|k+vWw43xu8wJp5f#8>u#2@2(hm;~X*85`d6I&8 zp^_A+ALB5&Cc}=;5NP#0=awbV+)w%gbXX2e_Dver`if?GOaKm-aOZnT2|-MpZTCer zlD-*!TFFR95M=+t7!_6AhnFVr3XFgk%6@*ly1S@Jnc1xFqh^0{bAhqY!1EABVZ~8{ z5%1&n!R}iWbTcg$I{lNsKoPTc_-{oFLn7-lAKn^gE%Q?&8$*jF$XrzU}4N2H?TWj2(HIsldpq?D?N{pY>Z^LZ`;o#2!HaCWcEpdA>~Mdxv~q( zVTrYXSw;iH14h4!AFc9)A(ay7IM2e%hE$5Xt)QX$P&I%4E1 z$ybIStolFmlETM9v4WN>+Yn-}*C`2k{N;q-LQhjHblr7nlNM*jiQUIX{1YM1W4s}; z3bRI%b2`&wntU802E7LZ$D=FD;;XV~m?Nd_C!?inoTfycK1qol3)U za~uPnTv*aHcRQg8%-Fb1Tq~s6d81{1?nyZAaIqs5e+(h>6#Y$gpNz;E<*Vl$u!9-3 zvBtV>#Fe2X3V-ew1T{UqzJ~7_lWxwk#S?XNQ306O8$q{0)!f=!3kjKIFg>-rL-k^{ zzN2xQyzn8{lriX9^9_VnxvyTUPC`lJR38h2HWhj$5gj0q(8@{sv&$_tedg=mU5Wgx zH%3TDN<>ugtgo7?1VRZAnh1%f)>ZB&Ae*Ym;d(uDC+=EUBqukK6{V{8=?qyNSvqfD;ifW%;1yLXKw`W( zW4jP6UJ_XD!|>C6 zB^aT~o}Zm{z;z_IcSBe@PTdGOE?{ZjwwLp8S_PG<;fEIWN01DTKs!Pu-p0YGwfFh+ z&hg(tS6*Ix**xQeISJu1idWn|t5UxO!k@|;q!1Yq$Fgd;79)RR=78m7?V5Exba!&g z@-y)hy39%}d`LLbi5qJ=i;jNdS@qNG~ znC7PAM*3K#->Y2CGxGPEXM{%psr2$X9~ABN3}2o<&pT@w`zuX{U2PeI8(CDc|4iq6 zpTy|?#US&Qua^*OMeFDM z0O&B9@KrAA{I7YvI;lu4dAHgz6%1Bo-3!(ly=sDL8~AT4y~r7(2@Uyj@u<$9OX_S- za^BC|Y82{h{_%PpRq`<9F||ax!W)bd@{TyCIv%@^6$~7jVc5fMd!&>i@BQ6Ds#i~wP{K0-SQ!y%okcmp!Ma0E${+VU(r1Z41 zc`~uym9gSJhbCoppe=l{ahWv9DEJ3rcgq$gI#<-Lx?}M;@KV2`+ zKNod>etgm)@!dj;sS`6^SOXPQa=;agN+JAnJe?V$S51HQcoLRCZ9TOENVZVeat(fJ zUR-UiZ*P-l`Du4bUbo{orbsL~wVbKDZ4M;A;Nl!1@l(3)uK4cOoE_(Vk^1 zNEkODt}IUOlnxiSlwxh%M>u1@LuWO(j@q_)p)H?F%cNHQE;m**c8g`pI~cyOpUJMt3)kw^ z|8yY=!!K-Uc>vaHKpOv;mS)Wf2iB-mEF%D{ZfOBTt*D^AXGaH* zx5DtZKRkuQ#>OtSivmj_JN8`3nL7K$G1XE3s8Aq^HiU+cb#|J~)jJv)8Fe;3s*z(; zprfOY(PgiEE*JA7lXADki2PX$oI%uwUP)iv;Ts1Tn9eYM@a3^XCt(`=g8$ z)e!I)NSbE>Sg-0HAqCfdKN3Pan6tq8wrGE!&-%qr@4I%F8G7_jv$1ProV4nTZ8a+C)PbYry(44T{!lhnJhXd zBqVouUNBHn4X1DnZw^k93*xB3oHsydW7rmrhVW~@&4IRZb~?hE>{bfNV?7{E1tF2-{0?7k#c7cO zw=`c$d>_87+~2ZD2K^!KM+jaitoh39{O%&`qz;T*`}?m!gDx&cs<5HTn8?7uz{<*M zDUbBungVFkNExh-HnZGHb%A{YGCg9yuieV1UU zM%jP_^UkLELn~qjC{Q88zkhFtfFS_eg`-m?F(2zjaZsAVek~UpD8$04P?%+t0Y(YvI=;c@6z(e<6_jND(+VIKV7Z*VCKNmR1BZg{RPP z)spijT7}0YUj@5)3>eY`#((&yUg3II@&Ax2{LgLk{&P9RzkQEtAVfh~{3l?pAvER( z`j2Ia&sDs1N9Vta)b$L@-kcfL*~zy0X85Ejl?ZvXXgzwa{?lI0tP9emD6Fl5f*q(T~zfZ)1Yb> zg~oK9vhVAAAZM)S170k0mW4m9cp_mxUR62EY}WeqjF0m$Gs{DQyd%9wvlL=l_$D5d z4SwcNH4f=WktpEYEAiV&p|$Yf9x%JaI;iV(h-3@fesU6Uj+59fD0Sm}@NkS4$G+4MKnoVh4IA=vn}@C|2F*cUvc9Y2wK~ zylvM4k1=^%p^)mf-kR;`AB1(p3lw#B*g;bugpA)|3EaT+LBufuyz}C*~&*)q$flW|V}O*skeJebp_;y7fwnl^%F{`I&erbc9} zl52HwX;4_%vAiw22rd@>%6f3JlB016lZzOl9SY@@rqrZun*0KWjH0fxMSLet&(?AM%}Odx~@ z*(?CfR^<}x4-jaQh$H~nFlb|I8^dpVywU;0TR{SjCwSLdAoqJzy;w7#-O{V4H|+*t zj^FEa3xsnhrgDa0`~oj8poq)jD+WLSkOTEgN?V(_O_dw_%25|&r!d1^KM1{kl;x|9 z8%$#5G=c~;2Z?T7C8b}ZO+SA+d>GscAZKBAX(H>F`mGPLx`1`GN-8w;o`(!r)7|pl zW<)Czw@vo+^r#P(C>IiPzPvp$I{V?w!=#@3qj8r0^wWWTOG#v$`|9-hA)A8Yh0<0- zsnb{i{hA0U2wf~AoqOYf;D2{-I)a8K<6@6N*sa*=cxA)7!okSNw~1oo(7@-Nd5{`-m9PYH;bLEK@Xo{KN_^DrS6u)X675C2v}q{K#PLwvOj}Y1-JZz=MN8- z<;tGK1_z2Y%7c{u1_WWx2oom8Mp*kUPEu<|$7{o@&07q%BGuw`wv&?s31S@j3p-d{ z{jJh2F>~3{2|C#F08og}{?bnlX(TKcgEh3*8%E!#UVq^b^$k?|Rt^0sEp0*&$l-y& zQz_f=hJ?KrodUa5i4j=8v8u9>o9j*u@;b2?PL)BcXU#P;h&{XytcXJ`{{E=85j%vs zxdnPWZ#v*4bwAhBt?K6J4LRvj&+%(s`JMTtBvNw`Z^I4(m>`b1&BO-5UppUPNenLD z4J3A&8Jw?-CJr&TDBl%M!DNG`>C+7dP+fr0Exe1}u@eo+X^BH9umUi0ekCm|EQH&0 z{E;*^Hiqo2?e0d|;`&YMxmWbnyZ?5r^(yDEnPS%$_WBCyG}HX~dEen2NqXej^4A*! z%w(CUFJ3H9gH&E6W?s7=>-ZjN^8{av>nE2mfzcF)WLC%_L6+v#8x<8C-X%|;_*6_s z_*ywRImZ-!O$(xaLyFd67Ol$m%RUb;FNheg=ZF&7fDV(ny7~4J9Ab~Sm{JhlT#cCm zx*YIIq*$`Rlx>Q4L6u|UeY&*;iW@=K%7D2IaI(&FzNZ{f6lR#M=NOb0iL}+eej?Fe zZ}2CY=!KhG1CNgNZtr#H$$Fs}tW-Pkcq45(-qWFc^?W}BD8>^RPwUuIo;#Cn|Ncn} zi6O<(I`zW}Bto(Njb+5FY*1q_*(;+?SOQx)0o(4$rfj7khLRNMGAlVfq`UnMzF*Iq z-1*F%q@VPuEt1`gRLWCtZa(2JbIVD4sQZ4`zAdii?kxPl@%=_Mwe0;#lQATQn8-9f zoZj?g?GN^@rPvfPgX+YoG>);K$i68SvzWx3V0<{7W9%4L8!sZ@ z1w1h$;lsyZdJmf+RSAWGf&NWKIy&>csR|zgF}U=(!y|7bhwuqwN@%_{;TAky6^U7Ic`DT$4A zcQBz*2i?8wXzEk*HW6Q$azDfdd)K2iES;U$w)`zzs<*tlE|JogoWu@8FTg|CZr zcBLAWT@<{(aFvcN8Ys0jAZRZdCZq}|KC{Qvrw{N;PJO%4xDv(Rk*x}Egt&oTs#R?{ zK7dO;{t!&KRb5>zz=04V<=}1h8`z-YsO8vb-3HTnkoYS&PA{#s0}q+5@bZjw=PhIbPiXSZ_3G!EwV$xz-wbJ02rZPeT{xgvaI*V>z$ zFA|~i27#23p$=CHtci6}ujn~5t**W3FB=#i)gV%KdJ(_= z$wS$x!WAM#@wz)^J&?1u-ixv`|FW+{lw7eY?6t%%6`c_c{8&E3wCkQ9<&YI4MfmWg zqCrZO^d1Rxk!<+U7E!HoFki%U!jgpW{4D&(1u){lh97o4E{*pFDRP?KJ5Ai zRuu1ZlD8&xich4@Sf%i=!0ljzN!P&!7(-%Sh;2D<$V76L3sp1Nqgqk*B(+my%4Wr+d%X*IR?cVh%W3e!$U=#&VHQy5#?v7)t}ZUFOY;n zT0J^KFm9N{=(X|I$Pc3;A~>LCWW7V&pXmm6JFK74pfKR9_`hHdm-4>K<)u{Fq+D&q z)01UkKA*2Df^4B5QlVUm28Bv#wf}n>u z-_=6t81SY%#U(78_D1#P zj`A)sK|+f)^R?K01;TnCDWg(}P{ zKiJvXEmgXj6OZ%q@)Bfn2OLq`2_w$BZJ1c)fHU)a>s7gJcYZxQa*jN zgs0z#+{l`ZA@X^ubgtpMd=7HcTOc@^>-M~+FsH#PY|8ZdRhs=rZ|8(-qfV?2DRV|r z5c8Sck1$XL2S$I6wD>T^p{ypjO6@t4QS^|2iq?N133CPDM>X8J84s;kKa4c#X=g zM~-c%EwV#wn2P0kY^qyNSA0T(NHp++ki2&1aM3X^pfJ>2834Rq{!`|GR0x%6B}mxQ zyGv&^fXfqYuM^nid%vr`+Yaw5=>^X1z#8J;is2~Q*x2^z)2C$VFEa9JT#?~u^+6Sj z!q|RWyw{@f=(Efe5_h<;W>DiQ@DTC>wdO9pe`bczStKI)@&!JtFb^Lb9GvOT)N0ow zL*i85=YP)kid2b8hZbFbi9X3pgTIIa$B>pQ37~deZH)3c*IP$Ds-`5Y!nT1J~KDH6(&Eb{J}g~1lrZ?-4vjZeu?u>`BRH3~&rV*Ex;V1$&b?$@MS zkqEQQH+{acK!;>^QTFYSgA1xV5*3m3eT3seaOaunTYd!+CL2XLb?wNdxj&`h3sWXM z(WA1#!uUZ+F1u9Z>hi6fR)8Am88I=jfPho@P)IrkqTa81MMXtw`A^nnlQ+d&5D11L zRtASSa;A~`dcGAQH-mLOJ}}-<`!)ub z?z-VQqTXB16P64hNzJ~L3LhIBv;|?4D7cJBsEq{oExbT!b2L9QP&$}ziu8Wlm;T>h zO|e8(OIzDI#{55Du28cCzzHBy9RK-xrw`}hyFYR5jsN_@BZllZ!DyW~b723}PfGCy zlx-lzeJ1g)>iFl6I*b-Oa^eoYGlg~zDbO>-8o-3g-!NtTLxs2_OBM4m`?suu2S@y0 ztO71pPWFE>;Quqv{%^4g{=Na9_wO6<{|>9*IiM4?XI;qKym*TJ{{~d>?_Q+_(Yo<} z0WWxXKYv|5$iG}X2;@IL3ND_kiLDvPWQRZ=hz5!*5*F4@CNLHWYXc_}F%u&@W0QY{ z3M44WSJITucJgz>{w?tG2y$@zRs1C>HW@=bayMgQe0`OC2dn~CLw>& z>&}Mgr#FX+gdc;lN-sj^Z;AZznQpTaneC#a#ERbzvMK+cSGKZ4}werSmpFLUe?@d{T?#W|!bXe%&?k z{;YfXVr*o(kOTqiw2h*P4{sz zu;(~#MK6=2u_0*GoXfs2sxqEGzTW|I3(m#vMl#vAb9)j=7W<=D%PL$vk1=D>3cJ)& zYw^!VeWiN7B`To=_>RM=i$`N~&HS;P_jfeby_{MS4*Oj)rXQ_zj+%FBFNPN0P!5 zXH*k!lu|;+5m^h4S5RELOV0~b=SRh7mi?FUVD4Y zgd($Y$yWSP-_Q1S-yh64TwU9F*Se?N^Io2RYO-sd|I)nwJ}HWPpHK>VZyFF3l+6Ni zJlH+Xt+f{?78$P3cN-mUH|{;%Bd%}$^hZ9iYjRsGnR_>O?S5e`JWPG{jW z97u*hGyz=PO16cS_Z9@p*1d=uz4ch&xtvJza5=CJ&u#{qA&4B{zH)vBPQAULK2cFq zBf6Is6>SIf@w=1Edmy*20}HyX%6rfe0;%UFCMG3})JHBW{VXlm9yu=c2v47GY;3IL z$1WLeB`3WQxfZ@~9(uSaPaEhWw;!eqfMLvX!41gr1U!(Y^O^6aWdOX14=- z>0T=DK6%2)H`9@@IT)*yoCKV!KbyU-W&5L6<1Z^-)nlCYWwo?;gDv|0df{GlIXQco z#*i`x1wGpU{Y`km90&Z;CZRQVDjo5Y&NdN95aLJ$7+cG5^6f4tfz)xY;cFK!TIG>0w zj^xTb#6fS5(ZK^EbOR_QOk%01s36M2U(KrY%M%h42}k7uo_Q9&5Fv(`0d#1z(ilLm z7toF>0$^cWhS%v`GQRoU+|&eK);Kzit;2>XJdW6`LG=YpA=siR9aH9vc^kr zyg1=`!`y`_>1?cwSGnyW;)_IfjctLf-Ky3%C*7>Y8u138Pifb5hD(ht?N`^j%+4#0 z)Fnh}V0!e^?wbW|%qRd@tEj3A|7kXOi#;pTpD#vwh5)u^__8AT4Lyeytugf9Uv1)yJ45)tVAQN0fol~^_+ zC^#=A(2~j!kZ?=NEHry{_GQ)b>JPg}-DKY1n1K>MPU%u<*LlLE93CAh9MA9$n4u$xt!f~e%6-+;#baCJ>=T!HdDUZnQL0P-BecdxWkn>B10TMGRNDMA4# z?530go;m#rCXY%+J;uSo($kcAHDVzAht=@2(dI2U!jr@Qh}LnW@AFA|{>*Q;OuG)# zfmML#^GbiA7)MiFYUBvet&Av<(A?i~35X&fFf>eEni*Y!BfZCVVZN@{nF{r<eMMi@E$--Z4l!WQFxJ0LP&0$BKFq9IY1=rr1& zpBDBfwRCsG?_d|9)<5y<)tkg-%J4$PRDQbG747pFWKTxgSH1CPS^cxUb zaGoII+5u8BLS6Z~xZBIL$l5@u9`g9n?rt-Hwulj-r7!KQQf4HngZJzghbJ`LhUPvu&TDNvmH`T6}4Gh4~GO9jnWmV%%~r zNY`+uz1tzS28wh6w_f1j9lKVzjI^|qqwffEI!n8D^6oBs?X99Y-Uno8Uc}q{>}$aNI577nKfUgt4Z?d)4-=&!!;y zbnDkW9UFg3@QO1uolR)f2DUKb>T#QVV=LctijTXOL07kDsh%}5(?!gNu=w+m+uL_o z0%+x9ycK}U0qCiAdE5|}Uk(7!fY+}!9F$CDZp=|#S~-MV?zjQM1x;v>6&7)D!F%7I70$hi9@TF?;I9e^@Zlr|VkB^iVC zTNN{$nyYZKSi>>Y<+$_dN{U``FsXY8yXa|@_vq@w+(?q`zSUdVH(X}ZpB`<)dEiTX zy!G%o?xBj_)Vy4u;co)f3ku#Mm8av;GJ+S)b4N!g5%UZSD! zHR8+~@<7ax@A_Zuxrk1b=|xv#%8>GBV-_J0)#wBM4Wlt2fz@_S;r6RJobVj{`vHL3BPE6kygk{Dg0X)omOMfJM0f4+Ql2ls+6_5lEBI}quW$OIf*Op@i zGBZm0V*VyX1O&Y}#Q>K6PQQ37=G_4G_h2p{yqqh$+|)=zDS}vCz^+Ws-dJ>$$DrFj^Y6Fj(U9&b3@b?mW;ha!2)SwS(sgsq#0QgMtvhZ+~9h?RhH; zRiLVUv`Zvn{@Cd`AGF5pm2f5)0(nG0;g#b*iO`)2ce7Kr581C${UG)r`8_v9grn%69rRacVntzXeW(9@8Vz(7$^B;VsG6Jh05T5IdJM%t^T6G)h zvi`KVw!^~z@rm2T^J1@)A*luL%Co`y0FV(%_uhSMd3`9z>NAZ5A^oNo$hz0?v!mpV z;X#$k5@2BX8iKZC17Lm&o$t?IO*DIN-L}5Zxa*1kt-{6V8TlvXvY!UvTqYu4v^0Zp z!2U+JlX9Q-M_todzDIcf#|fequeRi#f%AcP@zl4z@8MJtN6rgmAXb!@`9NYZ z^<4!zOgm#tIuKft5k4w`PpA}z0p-X5cZM?m@#EXR{+5cWDsBqBx>?1NJB-ZwdZEUq zgc7gU>?dbFKF!ptX~Pf$wFzc2k4)?uY;D&mcPX*&l~vb8cPumvG+1nGA-$pZRHtMc z2^(c!OZWSyT^Nu}-w%vOfb3x>jTAKk%nos1GhdA`N%Zyhtn~W&hdA9t3mnx77iX8i2@{J59F?lGoC+if1}fzG%=L7DZ7QmrE1Qhv%@hI5E^_Cw>!F z*4HBX$2ZE?@RdR6`f2eqwFN4{F%S|z#t zI*I8S8W(EGxaLB&+fN|OOpQhs5~aA;`m>;D(_c_uaJbCE*^8EA4U*t5 zMp?p8E6Wcmv=YlR^Yi)jf9n0;JSqjDzT`O~B5yz*GzMA<2=%S4iHKK{k!d(SX2-x# ziV11(NK|z5?JbOq)G}EU*P~`+#z2yMk9n5RznY2bO+RYe;iY)<3=fTyKi-9Qj1IdV zIi>GpAkM;haj0HMPs*F3m7=wK{;A?LOID_AQPaC}Tjn`(ACUWtPC$f0l!&(6m~>AX z-i5Fo7>XKzhy0>2z!nvWm>eVX7ie+i1d;i%$?x;kg?r%{2WvKdJVHh(+g5b`c5GNG z$!v-IjF3hT5lK=}O5MCG+Fu+D=;5BK{B1T|SIg zW*Eaf=-j+^p<^Y5^QHmThR=kbIh5EdwjOuLhuW93n34U?!`Q9bH-{vVKmwyGPQ=kGdwMsd@m3aa=k& z>enYFDz5fHn;^L>xc0Y^IyMN~FkR`g#p_`734_TSx9=0z8rQv&v8eQ z?@@7qq_}B3x}~`G>Z#0A?KcBv5`*!ymFn!GTnbXmGv}v!UqmI|24HoNL{+8d<+nWA zAZ%AxeUD70o_v%4XSK==cXhpaZ{wZli@hz z+!w-ldrNR%jJk8e!W?IrIud*7J{-&GH9Mz%tmv(+5A(Z1+ZkJE)8p1ILyLD!5SB?f zVHn+Csn&s-iT~70tD0EUs)r%V*qO9Tzu&Vu=qW{6w+M#_hh}J{5R_F7++I z`KuaKVa?@u-q$NC0zSIlWt(&fvu%!$F8^>rBhPRN-XYjX3c5x>P_~p=TiXep86^;u z=qrqi6D_%;W3|u91u3N&F0!&;BIP8RHDSkHQ&TiCu^AajvJH5eTGtIpYQV;>WW0)s zpDqhMLOw=D+Kd+S^x7#Z@?JlOCiI=$-FdCT7zB=w3cn58?pG&{hZaF>3`{h%)RWv2 zzGX;2NH+HtuBF;A0$j@X9~EAeoO8#mRZ%oPW_HxfuVVPhu$3|Lyg8R4pO!a%Skx9{ z5xtz#nZeBTOAOeHDqmMHttI{{{pFawZeMnKxZ{w$3QzpL5dlF0Y3$(X_zSmBZq^5< zhHK*ZO^g-E>3%;Df-_}2_I($hUiwPmT8(n|*}-#;Gvo_>^;ULPnAV)496cy%HY57} z*Oj4S%K!fT)7!T@#)M_w4f~U4k?~5yg-V3B7#f9*=%j+5ys_7IXRB*3c~&6|JI`@3 z3HkEAZnFh&(3;zO-oW;a7r^G1vkI?$9S}f+g*9nUbIr^gJ5%;tn~p_@1g{2cHq!y` zTjPTl)9Hks?AXemf3n}OPpL(lQlAo*U|kbpxoy-FZXro|*x(#-HpuhQn<{b4B6)*9 zZpDoPrrpKK!u{J@tl|#rns}Lnq*}>~r}N&8mpqp6M~oND8|@{ls_08aUyBx0ylMnK z@S+5SkTCECNw;yVk)_J?&}~QM!doE=p%Y$e^qQ5KHujYj1~`X(6z(gy{E=@v1V`kr zO?^>)5eUhgp!>Nh2JexB_yar#!K?ACzLRXa{AB_|_sm7lK&j%*E(Hae=>S~s1E)*l z?-n%wf4-x6(3+pOj_10gZOl?OGB#EMGTD()gp}!rB*kP`NS!y) z(-Nvt=*X)N4-qf_%u@NL*Eg7fxb9V3N7(tFKNH`q@RC9r8~rWMs!vb%czLgRc>`}F zv~skyZ=Us$>*&dA4eg9iIxJZoc&IohpwxUX|AYxyQ=Tp)8s|RW*nQ!E96P7nNIOXj zsAhVy-m$%9fwP9{hvi1%-7#amBXQyx;k8coI~$8Nlpi|P*7PWDg}a5neJtIDHsLq z4evsq7mD~yN?qLViOr=+Bgu6%?bGL**NPWOIceeKNGlNYjIJ)hrB&=OdFx%uHY&+( zVc+zLv74{&B08#@n&h3&oSz0i(&p#66p`}x3sTpdp(18uNYb*m0}Fp*;`_BVGfK)l zatxOX#@u7LI3*&Yn!dj9=H_a)l6gwv>9=EQ%yHhDH+0O!tE!pU-tB>JV$s$}ke!hO zODFzJth=rER)t-d&1C{m1NtKRqS3(B7g;%8W5k9H9iH zLnD(dW%K-+MnP0X)^E%siu~^IXvZ2!6>w5}3G#kl6V@+O_d24lAAyj=M zX>s&`UQpA!|3R@Y1ql%*`G>xNz20Btp=m?XFvo@SBZdAdzhZ_?Vu?Nrsh)y}2(?;! z=zm>27=eoI{d2wRFYVE)uZjtA*dEGhUOXaL>eeR<@B?;uT%FA%RmxK~FVb%B&DM<1 ztmE|1A;;{+GFj2(>%P}jXIX80jSCjND3P7`4Bw&{`MpIiR8F%hZNbzfFc~p2zylzI;yI4IvgM%`8b0{Sx zw{!hP9esUtY%oMrD0RLof*S%nz;`t_pN)?TIeO$vueo{O3&QGfNUtu()Ya9~hS9){ zL)P;;%U)6auTB5?b5eS&q|y1irX?$?Mt|q0$%QTBccvBTTmjrX>U=rQ(hb@5ALr>Z zJdg`JMw#feYSEwZzSi{=D1AfR=danAa!Vclhc%8C%q1W&# zI1a{V)`9ccKlkkP8TBcFr1RP6ZL}zw`N3CA1 zYgK!Ddq5a{Md>8Ft$wfOHAm*m*)oPrOm{eNV*Q5TOn=Qfp`7h;pyVGqEk%F@F{x39 ze%q836RXE+?R(LQLyxS{h{ zwgI&0hzO>~$DKh}b!VbPtJ#xR>?1-V-3rHuc`CbS)GaF!i5ZvgSm^Ypx+iKbI!uHfbM zdOZqqq)`6#;Hx2_5%CRix@g97Qm0mfC5IkWK8|UO(zo@%bjlsBycZQ0#tT%i)Yw>v z{i3ju;mq_j7$%38M)>{USz+bz_wz%KvKk1{(v(`=+1)KB($&)PSn#^oO2o2U5O^b3 z0kwH;!>-%k%Ig2?V?F0MWEjI&M_GryrKE!rjp{MpWe0PZ$0n@CR@j&oU=VWw)$ObcJH;CX zvB>CXmGGUd`R6q=5o&C;cnWIfqHDQ*6)gSOKX5L4+YNN=m8c9g#csk}-`lL1##PXX zyXl4|FJX!4pdyMP_F=UMkebR)`+ldr&J555_2{yNkb?T*qE{ zBkR^1ipfmpvMFc?Xo1Cin?R-|S&Y^QNLN%PY)gz&-^j*>_A{bZi zZ0`z6@K!-HA}XAAs#+T9W^DcHdlZ^)?&d`HvE5bT52If~TtZ$yaq96I$no_JcGh?Y zo$>&kS9I5(q@<+yFso`|K1RmW5m_j7|91_Gc2GB&wNR>F_9WjI6ESVcQou>y~*S87|uv)+1h~ zn}Tws3#jU#s>Sb-j}x3KFL#$%qlsU{x8mVjr#Gc0-;U!@ZhlWW(SM z^!X9eS>d<#i~+it{0=v2qK7{|`1}`#M+uAfXx8R}INT10`8#w~;?0(XFDlF19bj3U zr5b=cMI&0(W;eZM2q#K;eEZ}h_e;m4&qB$159ITBELF;OU=6H8Pv$`H0wy1Gq(%!V z+?sy)AJ)JwGb}4FFJF9M?|~8Wp^f(Jd}8XJl?pVq`Y4S^0+y#O+YlCL+l?>IY#{zI zo!jF@8hCGhFUeKf7npzr-LXVQCYF);VNgJ{LgkSkDgy43c@Q+{*_v412jsBK_)?LDf91H|E%%*7I!3`JobCK zMAjN??qt4lb@h<>W~?GQ>b&_9qA~0VYL{@;GkObMbZ2&)qCye(i~UFqMv|xNrMhMs zMi~@G{`8?2<-43v z6Jm0gL3(2g0=#6!d9!k7ak-5X>4?@Di^=f|7>OmQ$0BsJG&F2xYhx>230O%$bG}xq zfcErx_EV}jvge2|8Gc_Lttcs_t!Kr>Vab|^C>Vq}mb#mou7f6H-)q0R{$0z^RMAqc z-N1QxQ`P{@0|xbX>qD6fPDUTomm@)D?4gE!cB_HYq22p&=QZqk+!~2~+1Fug4xs_)8->}!h7kC$K{^( z^VNTtsj?Vp$kS#@zIs^`{{y3S_H<_{zxUTT;UG05rE9$X{I6Zc=7(Q|#csB`xnEmq zdzl#@RbrvK+^bekGHzSqyy&()wB&f!UZ)>dk_zbDRj3UT3I@j6`-i6ru)zgMZ-)k4 zV#A*dSl^%qM~3#dwnhRNhwt>Xs@yPA;AXJ=#ObhZ@OP``&L2Ic`%j$s)=3caj{YeR|6U{ zvL82-6v6ycRB>h!^{?+PeS99dPTZJ-*?e_ag(-1+#)g3H=G3UX(9h`g_4Od^S}pvl z!?n7OO!sZNyn9T}z>LBRVq_MuKB^orWbnHLjn6raevk9o#9u{O2}S|YbkASJl06;i zu*vRoTEz~;sDyfXrZPSLSs*ys_{#5@Rcd;B@V4S~piEqxQhXRYX*sd|1fBQ70J&%^ zZ%jY$XWZ|&H!!vwacX{kB7Y_>E>%W2HIxq&knogTc!t*oCU7WX{*HZJZ3q0{Qrp)% z#@4x(#jMVZF|a8GODMkp6?#%IYw!zirx6RfR`zPKs_J);)Yc9 z;YG79C$@kI_Mt7G#uhOGWVgq!+k(a6bf`fy} z(R1fOxX(t0NH9em?W1(3<`36Cr{fn#E%jj3?FN2tOIpAR)`GLP*8~0 z`4cq>8;=QnZ78T07I^X$vAxSkkHIkBQx#Ky5x>N2$F?87FRMrYwo|(Adwz#GS7z}l zs|D-a&9(V^c1$&zY}`!**Xr_))MBcmhn0x(AcV!FwH-1 zg%Z#;wi;z_4vhR0a{|UPDDuzwLbVjN!{PNv5k_HfDQG&D4GiDjjwr6nb6GoA1|V^rO59J$=(N^T@l&LnVMd>BTf_)tOWY%!rN z$qOQ)Jb^N?5X0K+%TdGT^z7HawBdpWXJ*{Nk>)2+qo!zgK)XtJhi_R}yj+};jE4;V z%R@)b<#SY(;X)6BhfGw2w zdI_stMNPSYZZ-yl)*`Mc+nw}@tzt7YuMgZlRRR3GLw_FLPT{~g^$!y4UFEPN@fQsI zqQmBgEpP`f#^8H78Fa2J_ImFUvGHlNjUl`UZ+AZG(<8xAQ0+{X1yj%<1;^Ne{pH{! zdz!)r{W(w1kKh*@dB(cB^G{v~WTlbhyf7uDX1Un}F?Ob#%QV*&n;=AT(fPQ^<8%w` zGGUU*Gw6J{o6E~1!^7pUHR-9$o{Uij7Z(?vNm>eARp>tX3_3F{1*UIGTQgth2AG%h z6M)qW{{WMlln&UKhV2=hA>+z;zcw@>9Yb!D}){5(87k!T*B+q@CLx2Jlb#UOy_ViHF|4xaPQgj_OfTTcr<;AA)q84mMRS5%~OSSUIuQDF%1$are%x=NQvaS$1y0?6yu5Vm#?~BT=zd*g@GU}*C+ZNh#;KB_5 z(jGonjK2=ocFJN0ddyRrN(5EMn3V+6>qUR#{Ib3np)XcxF;kSu9x;Awx!)d_tUpy zg%w{UQT+W$a#6Mtw^a{Ce2KY#9b3ibt{->4}lv<2#SBz|ICvvoXQznrkZ3=WK`=j3!% zw_gel>^tcTvA|%2Lss(oLP!=*<0N~spwMv{&=iK5eKSY8mw4**QEd4U+s8_wr-3YY zIrwgGxx>3mJt)6l_s@mj=_sE%V8}Ya&$v%z)9IT6orlRP@#f+r?dx>^i#UWL`Le%GeJi00gRA zn>Em5@4b=H=(s_z>j{~gnDBcY76zMZ5!x8Z?E?S+=J5%q`9^b3``E+@i`^+!ZGGKz zK^^8;L3+%*$ll;yI!#PfhAv&e(ZZdPg&?qsg-7A2=#_Oz`C~hlEl#uzQG5{hyi!{O zm5=0}C-#n#1<3pi2&F3S8k*W`ZZyh)c)tHr zqnx~JW+vN6GVNl%zpR0Gq3z=<2e=(&P3Vz(%ZJA|9TfRUr$^t+3QM%iTH79U8?7?B zM*?kG6e6&qb-EX?Fx2zImclAn`qF=7aLVk3xi+Ws@$=h(;XN>E=y$55sQBG(0pu^4 zGmD8rtv-|}M2wxrHbuVz{{ybDFjuM?fR!R{)gJ?+G!FnZx3t~ zoG@g2r5Cw!x|su4i#@-9n0L93Bq>)XG5p)bkW<{UIMm51tdk+j+b7rGWK&2~L1|02 z(~{mdH`fF#%S1#(O-)T#OZY@j5K&n#`BqPdgmxxM<=PRtu41VWtOtHD*13MGP}Ld@ zLBf+_E)M_WzQ8>{d}F(^-02XbQLN9Ztn2>v)Z6dPXd6MzMKxaH^kBvQP(6@jAxIEH zNC8|`il(}j{u*p+-S5cfv&xwc&Lmt&+`aAxrK&VvLofQDVEC5L1(z@A$y2lr<-VaI zZt6g-j=hA@mbVM;^W6Kj9S~XEo>*oE(NZw=`X6P!8osF0J%~R$WR?cq?*{d zSl}MMOvdXa`Us>LC$gsBAk$Arne#fcEAU6NU*zW+5qv)q@d3ip(2mur?Q44T z26Ez^@S~Qx2vI}i$vah)hJsb0SILz(`CJ*+0_QcK96UeY$D{FNl!(gMCq2`3z2~2VT6*uS&5^u6sg0WS zF9$zIQKe1KDyn_$L<`2yi%WGf^5qZm_~m%A5)0TC!t_~punBu?jc_}}hOF)w-j*x; z+QomiojEqBlc7P5s2c#481bU-0zt1%_hBJlzEI(k7t3|!*oW6P!I00e;6;VJ@0$|q zPA)y~y~e?!Iy*YiS14R$0{UX~Y1WUxCUfT!>qKE-)~*x;YtMNI8FxW+UaQ)MsRY-e z?ar)%lRoclxdzm6VX)JFtpzAqsHQymvsC^t)*?GA~kH+_Sh8A~PX!5EI{p=SF7yIf5~={p0HX^0X3 zJV+O0x1}0RXt|Up_9z$UVYb?N0TT&ej2IaFGOl!Ub!F6R_5}PLP(dT=nZdT5PL$2N zBBW%oQdEV?^vc%rM#hW2zMVAbrbN1nV!ef?|7^aIH&EyIjArW&q%0lQy5Q^Qz@PZ&Q+Q29pbO%CO~2fzTAA}# z58`K3FCma$)6*#^ZQ(c@salUljQ!GQ>VF&J3d^TfG=nMmP%6>BJnS!oq9}UC#l$6+ zA4-;PL}Zaa@DgBBK5@(j06ahsIyq)5H|Sq5d%}C|m^}0e$WVIGc^Oqc&5zS791gFc z#d)k}21Y;b;tL8RXz~qHzNEc~IT3Q8QQ`_(Tt^b}C-vUbLzr6SpKULZM_UFGJzv3{!Us2V8}8yX#LXKfuH zLcSvRI=(#oYxtkk8Hf}+*E{~mie64L0&~hdYeO#@1*I`KvPpBb9=p|n9?&jgbKnIJ zIfQe~e?F7L0@E9^7MGeD7TBdvX$ae1H+8>dJ-3W?&QNq4V`220N){mY zlzz%A(E^WJHa9(eq7HF=4J}>?)xX**j#;-j0NQ-2crpBrW*-BwYkNG@UaR@K)ba}U zGYa?R1z=q+jd`AHytVxLJ3kXQO#!-w3ya9kHWJ@l3#-Hlm49`7@iU8P+M{AzsLkk&dUKuO#jMM< zqr6_a^t^O0-f`})l`dwIL*eU#8mH9Eqx&z6_xcod6cRF-qqPXl))?2k-WY>=mE7bk zdOKp0jrG^1JPs9hpIy8;2mayia2tNC0}S>ts?|#p1E%9zHQbP0NcN4-94*}YUGD27 z!~-9?G_i;C=3FqM2;cZ*ky55y^*Gu~$iuH9mUGRA^VN}8P-A1`clCU7whOTQf$z{DEDvbEBGfjGPQZOZkwCit(cI}pGc6^e300w2dGqGSSfSGM4>VxdXqmJdf2RtxNW{gv z?%1fo7_VMID;^l@@=m1;Kz6^^N!R=@R_E^(#MEi2pLYbF#B@{EK7x!6N+d@&Ct; z=wfmH z)85U-%KKm1yC0YhfAeA~N{S-0D9IT(S^+e{KcEc%lf7H~y8B?ngX$UZb;r$n$TKIc zj=(F&P=+8p{%@?kbyOTdn>QMgAi)XlPH+jqEoiU^!weccxF@(KxJ!a-&@h9$LvVry zcL?ql+`r=8-MjC1?(W{*J@*{`nI3woyQ{jYp6B^VF!Mw7hpgy%$DBUQTyYcXJxci5 z^g#_kI1LSgEc5R7#M#~D)}6D!uaen0o9U-7)ApZH&nBm)CeEc^?D3YzlMswPH)SxF zMS9J^z(8|{faPm>qk;6pzx`2mC4*5L6*+&O`0$wBkWU03|Mf3OI}CNNdB4%Sq0(eb zq&0mkf8N|IuYTw?eUSE(+PF2d;C(gIwmR7Qpy%DP|50nYHMP}jh1Urs)`>u!<74~Y zmyjDJptb8G^4xql8zh+wA5m+IuH1xM7QMf{I2y!0NZ0eOEd%bih1&c-^PNw(hN1y* zdd3+joKdn!VpeL28MOMPq@--CoMQnFmlaT1iWL3Z9d3g*^u~r39zn(jWOO2 z7JdgsM5H}8?g3nIVGR+RE zcLH3svbjJdZp-lkUef`P#i_WB^7Hdk*Yi9%8kCR#^*5l+GLpL`B`qBq8VblbGn0M% zFPrf^lC1qR>-1Qq)l4x@m<#H=*Wq%biVkr5pi z7m#)D(~CVG@qkd+cm`~^&nK5?<><%W-d5s3##|lSIFA~>(vlSsZ0berwCB#C z;0IDy=Bkd|tP%d-{?Rm~@j_@eY^YJr80{04utOeTStB7KiQ>)3OA4P>l~FwL@%5#4 z-zf!hFF(KOc^r0Jo@}FHlF)d{zskPsB)9#Z1qvo)bIIxHcbD76-hloMup>YxavxN* zX){k@?X{&4PasajAWr75KuAY;C0Rm-KQi!RxSt;8m-OsSip$;2*^D}+Lad+%M*wM9 z&+mzeYGD1V=XJp-)722-9gWWdqVAS?wK#ety2r;U#Z8wMK(Yw1l*d8JjYla~d_`D+ z5RcL!q!EH_MyJ4`ZY zvO|t8fw)<8koSEdm6r>EHm0H?>JN@b-j=T}ba!_nV-Wp8IxEBuKG9%;&GLbu%5QIJ zX^CN)2rxgdMRWw;7hp-&@uetyW1_{Y|9t~GxFx%Xl+S{ojP|qlqCfGwR=^z_x+j1; z)hvRrT(eNE95aaR0PhZ6yW0(0jxB(E3+z!X9Ub{*av*S!M(LXNJ<@4#0sDcEq4j8_ zLROfKqJ|^h)YQ~_FmG?~ni$ftnVI^zkvm{>1K8~M#`KeNW+7>+>gruil7<^Utwg{= z1=xFj5<}9uuB)+tdKXvp3|49-*@?pUjdeNMwh6BaogO*Za-wLJ#p)~D_?nX;jK&39g)U_*LWi&0!W0rwy&qEcW7 zZH;L_a~AUZW|H5Toxf?sR~TU`tuq zbAvjKJ5$fwP_8Br_w7mC9^x=rV15V_VKBS`icFXmRAjg!aujl?ooEY$4C0vn5ZQMB zqmEZ3?qC=6bUTqlv62ssek@g_%KM-N_54hadf!qtJLDO*4SEHOM<=q5$jvMD7KO#F zC%oUuS5{VNC?$>FX)k#+Zc5bC1I&`)1*77)rLSC;!CURciVnL=AP^841LP>U1O-W` zho0Vs@fTp+5b5}sQ(xF;*coSQ3tCUV@Mzd?y7Ect57yAC33XHn){%KePb&=|cfFQN z?ZHvB4I$P%Ss}5$=A&X~v%a@Zm&fLQA6#}aQOk5nx~i;a5>j*Drbm!`&XG8q{Uq=A z+tBe3u7}^5Pf;vFgTGXgqcJx`fuc^B>|)US_GmGX+9Zv5`_9dis+`wDSwW%2353Uq zby(#FD1niH-i!T}BET)0wc-Ayq=y(PF{5Dq?XbjW}L2c{MyM)?WpH1Av2Q|`;X`h6F-`katn|43lv zV|an3L}dAhswqI0R58{V->cvE^~?5whj?6WWHv9DBqu`=Iod&a52(|D;XKWwPjT__ z=|he7-{xhz^kai6}8Cxx~eFZMlSb>8g!;<63k`?C-hO zbkI+o4<7ePPAJ0IlPAB&#j(o2el1JCi2uPCNy9Sy)Voo9P-<^@7-F?N^w~Nk+JOJF zJ|Vq;{6~_ILU`*hX7u{+o^72NIq1R!@U2!TQR-DtD{tV77u=}8ZS=)__7>hIr^4;V@c!{XN$KVbl zH6_HC4!>B(L|Ts;Ct!J8?N(a}RlkPFPKI@n0w26lmUb0DSPe5Mua$M*+z5h7T$(N1 z0$z0n%idg?Sp5tEobC~s>&9=|#%ftZNUDJCeB#=aaK!F+sC^-r>3t#-YC~5A*fk5V ztV$_&32wI@Q#F|u>3lIg!v0`%gw4-rFesj73Mk-T6i`hb1JRV9&FpwxOP$6aK9Eo` z(!$20C(l+HobdkA9V0SSeB1S)ht4-Zg%%fn&xrM_Of8CEg)i?j@Lkp?{mv;)d!TUU6~Cl?yBD+K;$Tr zmHZb~0b82iWQrAO0J)UM!(Hyo&=`oA1`LTyck+!<&H&|#s@PWuYL5fSWIEV`T`=qz zH7m@9?vY{rPoBoJQiVHkrqbmvr z&hWZuL^#fUdIxx^A+L+MvxKs)PP;)cdpO&^9NGBusR+indkesq{eqxiQv^kBEC##+ zZ$sm(_ip9HJG`{f9ggO9PAR7Zbx^~R|LcyJ>{w7<)H_v=p1Bbl%g)XQOPcrJU(a@K z1nagzkoPA&M=8Ecz380ys{#-j*>{LSYWo1Ni8~!cF6*hzQ4!dfsEQwWh4aA8weZ$C zw|56H3$U_=2<$|N?0pUdg!xC&hA&ECm0&?HZw$C;ehu+|ig#&9)EOsujzLgr5cCSg z-ImX|hoD`jW*W>_oK)7s&8DoOPyt&l_lx!P_NMI1-q_v}8_VpFWFYa=o%Y#G!kw0p z36?_4guD~_vIe_GlAXY|5o&Kr>kak$tAdR^;eG-S9O8pzS)&a%I=h3~3J#TMkWRYS zCCe2P$sV7@hXoFU4E+xu7|Kd*UrG*ma7gX2a})jU|E*s|K%K4q&>v?it3ejNH(QGz z-ZE-3lKc947tzkSw`K`zT>r-RPFgg}A=^kwk$|7R{pBPZ z?k;6nY;+Qe?qJizv%T()b>+>L)6?YYuPPl5IP(BN1%bPi8nyv-(h)i$!-387eVU52 z@NM|B z)g4C{eH+z$g+YJZ*`4_@s{PJ4qx2dT>o#e-G9HH8h#pX&#XK^~T}bTbUzsvZ?`R`v z;Z7U9Cg&;)%yv_ey^s7rT`qorR3xh;1{0L(ZXJJZES1=Pj>fc&28@9n+q^TMt95r=4`8Qt3!MV9=Fxa}3Q~(jd4ip~I-qDy1O)9$% z4*t~GVBzZ<7!&KM33D7D+_zy!N)~Bv7tM!wYO5Z7(w#@GszPEf4-R&P4Ey~3+veza zXKr?mFCi{2Mo-ttz{tVMKC2C_z*&VtJ%|ZUUi9wo=_Y(Dm&~foR!c|6u(aAtiOI-l z8)`rxj#yZfIM`D(EesZ^1gaat!kXjby?t4&tRJ}=(b1*7G<@A3J3HI& zPNSt|Q$uUhWOBe@!sLOs#*y{Q2B94pUO#?3 zo6jA^y0(+R1=RZq)kfLcXJ_$v&Dy`r)xYh;Bs;Q)f6w%A_oxu)4qSma9AgT38@zV5B|s03Tn;c0Zt}hj$nv`_6MW$wJl79EvE2c6HU> z-SJUY?h_O3dGrXi>^LPQytGuczi%g2QB{3HSzG%qu80x5;(1UGj=8D)6yOJ+n>)^4 zdLcW8);ERMeOL`e$Ae4BAS2h~nSyuI!Cv7Dj%HoGyMgs?bB3ZB(YNieuh4(+1`2H8C42#1rFHY3p5eZ3J)md^m!_cf+zx2z? z1u?NPYcWwa%gXeHx!pX079j(jQ(-R4VuE-As~XKZ+M%A&t-%0^UE%Ayz*zqQbLA%Y z+m>NpVm{(#_N(EA@w>WlM&iK^Q2|CL#jf5&B9YzFgRT-DF|W&m-;0!7Q8bufM$R&F za5$FnA24#OpPj?teLf#RB?58ux{Vl!Vg2yX7BMGIalT%kqW8u21t2owoJn>&yQI9gS+0#({ zge*~6*{pv%!0YZ3latGdgGm8}9!G0=KBqIpTv%NpNKS3UX8c}JQX=QCFSxA$j9l^y zc5v?!lIwrX)TddC2+FLi+m4uV=Kd(|>!0h(3DF>zSGFablfzonBFG7?!Q& zKE@ca2HlZ{uX9^9!gf$Swd*(v)z*K{pZp{L`{DOeW)peVuJ~u?3!n0KekbZ49 z?axM0%Eg5rjOl4bqK!PJMnO734n}>i`_hA4mXiP47LC52N~sr`dQ~yvwFkDwHh>3UAjXIB!Ytm=Nbpf8DRS z8|4Z1Og5{S&GFt)6B`%|ONmBC)rfgtO(Dt~aIZ@esNL6@20FTy3A?)FB39!|f4qI$ zR~cGIw97FYs&jN0zelV`Q~2RP z2Ca1UinV0##D~H~C1JtW+57C1!M%SWvq}v-<@hF%Xp~>DQU;>_&<>vk(M$)*WRsDL z^bc@8mME=Puxz$81B!WrYC~0YTv7A*EjowM%wT76;9HzH zp)QVfze|}IX@aWgpuevln_8glG}3#c&SKP$yH2duua|dT7vFl@<~9d^Z7gV{37Pk5 zBouxmL4L%Zgd{ZTKG9}wM#zTh>O{C>IOUT0m`aVRdF+Ns8IO%ZeY339u)y)ftZ1% z$IvGu7fGy3^A#1%hsWpVn`p7xqIzP-aXf+kn7$)^q<;k3Wl0)*eNmR_Khk~g`0Ow2 zH>GA;*d(#xb&E&#q!I`Csz5FqZ_i%Nyvz#!(mvU>UN3<&ci33+B0JpW{8|6o#nVN0 zJP0KvPu(08ZVr|v)PmVj`Lk@EE#1Ta}3aUgx;sxj1b%?(#-cxlouR$-| zr-6YI^Kq&ZnF0?CKA(MBFrDGXM7jMtx{5X|-hK7C_<=qm;vDPSyLPQd4^c{FGziLV z#pyfQ`9}Cu3m_Vy95V6(DCIiJI#c{6U00!}S@WpA)G`+e0}AYvkp7ST7B?4Uv52A8 zLtM?+${sV?07$r9Pz}Qd&RjwLP4#WF)hbcEgX$hrn-s2C+0UmVkG)7ce!HvqPYvIETRa}G=WG*EF{Wg!xU!rq>1dQ&$G%{&JRwkR)>(ywo>5|gwvHC>(d#iyjWv6SEFJ|!2yBGfD$l|I2q2&bDH={ZvDk9{!n04=+veo=Xqlxa-rtn~+7`p0Sq^^I|L+Q)Gc zGkoMB@{S4}{A>GLaZO{~T=rCJ4U$fhYfNjaRI6YU#oC@T-CI2|-`Xf2sDKM=4SB8z zE3m`B$M9P~qv!clEl~anmo2QZnfb=>-5(l1{~EL!2YFYH6TYTg^a(MtQ|4Y4CKz|^ z)yjmbo;Uq2R-;1-Uy(1jM{Lwq&vC3EOI4Hzs|P`ISY)7tjipJb$j7EFQEgM2paDr` zL|ojSfL|IH!lmQ5; zGDbdsMmjv?J)iM*K5HEw_D$G%#?YszoHDp@3s$|&CanWs#S`oIv%MyD6C>6SA04=K z*rOd~U#^sf7+r^>kdX2}jS$mubu&C}AHvH@1TnQt`A+^ry;x7a7ay1h^~MU(X&3yr zFw$c^n3Re0ogv2zf}~sX3FSO};>xs~uyd@nmTNM;)6?y6&DtEm#@B z?!^=|03zg@m)(Iwg=cN*Tz87GRfMO;KgKlkf%c2MP%9s7;Pr|2$98KF({6Z74)+xJ zX;MB>C1ijt<^F#~zW<92;Q!*3VJ7(6TAfZ^cFSP8H~-{RqRxJm0=@`i)#4yZbN!8t z6|apznmeaSPmD&RjH)W*Hc9iHZn2s>8P!;Q^+Gf~tK~NKO|z;<7&p%^k?I4KGYrS&Mfb)QTLO| zw@TLD&WT*l)gS{C+c<8KjIH;uU9L)&UPvEhAK_mGzI|WOW6l?8H!`AlLrotk=qRV> zo&*o9#6?+LAG^4~PZugXsEM;?OpE)~UMP*7aV|u}^kt*#JOc(j&6C*Fgab}I@HMNx zU%K((=}wWwHSx>0h7iw1|2;$Zj_heknz0qeUz6O)aius1UDV|lg4r0y%!_6b9_miBg~xA)L$FQ1;5rkdJX%LrDE zg<&Se3+98LUkpD0Z^?q18n(CT{2ZqnDq|N%Fzu?9)s>o32WRJA00b3vDgd7Kh}B-z zn;UCJEi-D1NM_liZ=Ia&*wlrhg&H(1*K2JM({)wq#Sg$MK6@r8~t5cNlLdYndlo2Q{X$PgnqE=|F}96VggUnx!Ngls0>RZ zDHP5`Too1_heC?AxSDzyI~Yx+v8CW!)QDx>5a~q{#a0bsiOG)VS+L)HNnfP=TKEI_ zw<>YU2j@~kS-GiVnH0xV2tOumtqlahaf{Y%Ee-4vlat@33RjkvstA++Oa+#c?ww)h zjqVuDw{;DA65es*Cd%!zwZWp~YbQlTabR^e?N@ZUIT>YBw-CRr5#$-t)JRH$Qd0Iu zV@Wh$L)vFMy_%0!vD%V$wg7ZkFq%S z+sLz5Nm5D**=H5)5zA)l*bO)s%0fRQ%A9Y%c&$E|2OSC=;vTD>774|yLQ)U>tXhCy zCwby;QGx#qdtJLuGgH{1uT`qU)Mtz=Z`Q>6gYz-yUxOsc2v zPmM`CA6}Ad%WvF?;<({mHnbZ*n+{BX<|FEWseNMnI*PyHA5038Zf8=(vDsOWvNNKi zr{r$VFFq4@uj-K!2o8voxXkPB>4Czb*|~KeOa6)vnD`hZ-c)n-( z2|aP!R7NCd@W2gc>gUNfH?HkinC#7Mv&Y^SNnXQ8`-KysL*YEVN;+vt70e1l6mXNK zWOHhp$XbaiPq!B*-dT{!(=s`AW$oyIA-^vu%~Qyhu>F(`Ow>%C16B*5@I>HCKuPil zpD&Xlfnp}wh(3A>kx#f2lBhqv#g2(<-MihOc|r1;M6d+u14d(D1e&a2djgu5Q+M$0 z_bcrL&B>XWVvSNmpvgTv1?Jt`F#FUWp7Y4aQ#uWKEzRf(@HD}UP6w*$lc85_5fmy< zo}Cy*v!*3W!80*D&kYt+gr0D668$zeGD-*xjFq9Ug>t-Sw`060Kq5PA93l3R65dnl zF2Rk{{c9fV?0fogk(9vB_VcjvuZTiXonM@l(tf^|G1Hx|>cc({e~{ zFPmBzk^QwpOUoXPZB5A&F!hXx-Fts7{8a_s+LwT@>0B;XHECYD@r9l8wa=R&lVfTJ z{#m!~sEK@Hc#=laclSVS99deO;kuV;oWD4&h_gfN@y-k>K8c44v{GY4PK1kC%X;yz z2KEx}zK^8M#{I_nVY1o#^N@6V?p=^l7MLZ-iqpM@{Q_s`8R@fn6M17D9p|y@CcpAp zK+pH)kkQ`v_rKP%qRm9!Ex10kYjj|O@oVF_L+fowFJja*H}nnY+d{-yeN;3(%*gYw z9wlYFLH*aox%`UZW$6WcnhE-4I&PMTjS6k6P)IT{kPH)#1IF37f2$K$(30_li$&QB=Gdv3c+?aj#m?X5d)+fBC$}xyl*3lM`^V2G!P*6r_gV1La^A6-?=D1ecciKuI@`SFF{0$)p|LU<4NCN(# zC59}@YaJ1lrNLSvUdKty^#$P<7Tk8fYWvo(o$3%yDN_qh_cC(nt)e;aYpM z_B2)sAuqt*b$+}sMDdMMzU*pcF9?Zy%y9GFi{vyCLuQz=hD%WXZ^wbzvt+UdaJn8o z_Q&yfzR2W^>9LcWxeR_gK?;uR13u!OVa*zWPw&pNBx}&rw6>74wD=^taHu)gA;vUJ zn`6CaJ+Wj;y_Qm{2^Tr>OZ=qUArwC}o*kR^za`7%>r2r1PR9i6>(L~ZEm1GY|BRZb zjPNMy#4Un9R6cZhY3Ohn`Q>|Tn$1`L#h=nJ68sZeQqB>Fn!v9n@^_NEW{#j8g7 zu{>z%x0Ivmb^3r;`uY__nae>6gxEk&JDgP5g9LwB(0rKh2q-SHa`$(Aw{x!kka)Jo z;YXXA(ucQreX33QZR=n$gCv7J_w^g6i;HzK3=I4n2+t=I(e$fG61+OE##>QYoZRPq zX(1Ava%cI1x=8!M3WT1zBEGk;m~ypR6YKq;y-lo239+9uLagU)L2PD(6zuPgk$6)B zo%=X9IbnhupE*KDXSnT1b56UPRC1Y3*7B)yh7`Rj*G;lIw~iGvme!hrbXmY`CP0eO!|_kcX5+zpx$ z_V!w;bDU}&j$>Cye=d_=|hT_pt;wkBGf(D4L1{Q0ou7*MlA;|vj=p*y;7!6#%H*_$rOO!kMOH{?_QvOB+}1BaIx7QeuNg9uY$smufklR|^!sj5`{A9fJGilCS>d_x2uNR9_c zkFf+B27%_ypKZsL6A&)FqKl=_;ZbP(pg7wi#B(i?M48jBe!-oq+;YNlg_O!BQr!2) z`gG+)x7u68gF}w@;Z0v`O7tbaW-asO@3|f9!wJ!A0_PPzs{OkbZaO zZcyoB`;C7#^v3OqR@`7+>OIcJ1k{!g%$1|sa#6_ggyop7y$m)c9_|cr3>gnsf{hu3!@TcC!G1Dj7VE?PfNK=H$FqWL&T^e0^SJXe3VtG7+OzD^H zb`^D@n|qlpY)4a=tE=}frO*E$nv>B&08GO&z{LUdqLWkA5GJVh_~Dwvu}QdT=;^b* zCCdOj^EMsF7_D@G%q#MXN8~ip@rlw}V8V{hAIl?NSS0~%?DOT6EYxjlP z0D1Yb)>cE{8A3}-8&H1_^UMN8RX#pPKnw&R7%1!JUCm3NZl%RQ2jk@}2a-3UOiZ~) z+OnXzP`bw4>1OXcfKJQ$$EniUIhVhsaa8V0yF+fEZM#1|Q&Na-^`3#I9>3B;03Dq+ z$KS>G)!qt}OJ7!S`1yZuxBnU;m&wC+?z#c&$V9I$`(n4cjz!fF>ntE}CS5q^je`BA z{1`Z2fN%na2n)u~3RkSu7TB(|Ecf-@6^7gki@)}N51Fej?!T|WoNv=IjfuIV2V!GQ zl`-!B&M4!vESsHWk4}hP4T%&T%za&ZaxxEM4d;DMm%qQdF^Cb7RIs^Eku=WYI&Jc7cT$qlvZt+E$uz;I#ps81NeUm?{XGK6xpH0FKmC z(@6&I;{|?c|# z-QBh{dhv{I4D`Lb`_;d;LPt9m%Qk|S<>spC4YuKVDvROw(U16!t)~Izn4qfk8nyusGVwSJZ z)zaPLvD2qnh)qdRwgm8i*=u=u!jV%jy$E?Xq1!XDcMSs;nk2e|u>Q-RVWfxe5&I3_ zfTQ^m0k zx7OFIf#*z5kD}&a8bBkMFk~YjuJch$px!rIS7GuR;0}Du82<&fkkJeQ@403cPqtg{577dgK z%ty?Zc^h)oOGHMkeougTm7zOOD*`f7Miy>5!U$l>4WN%^*4F*v020j4&#(KV?gQvy z*8}~{DB2deGk*R6j`s-;Vq1+<*<{Br-yOG`1!JbN!_K76!m4>=a(mw7tAriLZt8^A zRh=-udes#bg&T}HpfG^t%|Cjlt9PYjy*Mv*=5dByF(jA~>9^DZJ=4~?jqteQcJDZe zw}1>glCtlj7|a9BG3`XsYJg5N0Ol1*JVq$cUr%EdSHChU)r?~XhllS1)v8xyi9mrA zxQmnKYHMix%sW7EmjduJn7t_BMW0-DD@V7sY~-Bh#3A7%ltVsHbw>o$mg*z_S_KRN z&~GFODk>^ZU1`Qbj0h*WOSwU4sQyWXejlF!>;wO{t?nW35$UkM^Llyr0QuWi(>C+{ z+!{v0(>gwWdI=k1dd|xW=F*9z6g4$9uEyi19{z$Q0FR3%{^((aI_3;l^Yvdx>y_`4 zz7SPatPvm>wAXO-rp+nSvgK}~Qeh$%k6!9d5mM<;-RHrDZ&V9%SX+Og+TPad`)YHA zf3FnVmH5;xO1`8|!b{nkrTwIDt31M-Wh`rxKlwvCvaVy*b$L>V=77QnfT>rMmM*fO zbry&gOggnE1f3@yPI6a1howX6P3qQc2a5%Dqi@yff^(h>_fz%{VP1b1OHv{;_+@4~ z6>khP%{NR7Wx2?1pVlT9U9sso+1zY3EFeIUUeXOQ^4b=!6)BRt@!rn&E-+E=tRG0GggE8(b#|ew`&^F^Bc@_UiHt3# z0W@?y-Fv>bSLssM4*uNYPRDW;-l(XEZ~W)`&!tBleDRj=lqQy#(&@#Vv z{-uS8OZOT$vK*YW0g!F|ev=3t-I71Cu11rGE3lErs|h@K-QG)nfXvTuwMIKq{$ucX^H5e+2Sfs* zUJZt~*SYRI&NhbDg~V&;AnoXMYBe?|ETo(^djn#t>+7@TlePezRJf3E61~&SVb>N| zC&A>q0s&>X^Ye54ahirIj*rsWWD;U&LjCQt?e+7?uE9v(He?a+umbGb@$quUbBm^m z?7oBW`hi-}d(C(6zN;h4Aq@i%s!K=$bo)*{y@KWmIocTa-O0A+Ym%@QwitwT%%jfw zSGA~Q%L^0K#)?XOAFUXiXytuBy`#^EVpbsW9{yg;K+kC%?Ib9rK>TqJy@Oeiz@_+* z>(MomhrHr~Xt@Cu1nCiqeu5IT>kmYBSJKzlh1bPu48b0Edpx3|nw*upVb&!b*fV(w*7{`rRi{luq@n&4 zQi*cc?w1GoIUw5)!r}v8CZ|2+`gou9{Z;*M!yR zrq(qk*r{8uLBEIxX`sEjsd$(_ zJWEoa+xb`wH|Ewvc!7;+ENBSNEjUOw&3#WO_(Xu#>NTO3<#`s;CnTP*u;<7#6bWzjhq&qQ$?k*5TgL`ihu+O?Wn0XI6UUtby7 znO11R3W|%@sTU!$TzPMcE76#M+g*70D{9Y}!T#Ny9bEoxKEk1xM$eH-(9LeZL++f@ zuZg{Ludr=H_NP9nm|KN`u$1A(^aia^gg+2#sAS`1Dlb&EYHG zAEw_PpC=(?a?t1SS%Ct}`D!3hEiI%Y?+FR+=U~xRLghPakK#AOSUF_Z`gUveiPuK; zdQb(0$|)n2<;>p?7FFCJ{;N`tam3BxtsKlLuP3K)*fVhTN=7X)(c2l9Ku3mb9X}ny z8nxi_Ngtn8qk>C?y(6_atj*e#v5O5kC1&hX_{s5dIr>{p{d)bfF!b(S_@+d@&W>_D z%t_TV|9Js)Ululx>iT}oFqTYA^@$xG=!l?%CWZBe^)&bPOwGsUZWFlk+NFjaO8qZO zB7yJvaDINiYd1PBd`WY#>e0i8KtUs0{V!13!F}=fBW@)f_rcLo+k5SVUEovs=FOW< z6sB_zZ0zJs*;w%EFn{ruu?w9N`ahsh`R68E)%|Yj5;Wl|f z=l5I?{|DBOl8Ki7?4BwRzB-K6^?!*lBXmd3Dy+-P=Y~{bneA>rz3B{#RD8;wZS*&E zs$!n@DWXNpUmfo`X?TkuNY6&UmFpb*txM_`QL~e)_L`We++|MyWniE>o~!6{a8B@K zqLxExUhVtkuREFXoJ_D_#Tf>eya|Z$f>2I;l(SwkC9IL>E>8l)_m*q|H~F!fj5W66hSq&zE6l@8q=YIAju7|zAnyr|%u8{L zQRZ7b2w_pyN8Bi&8AqO5F8%RSI5P&XIM1in!B)kN^Mf`^x-mU3^AITEbobQ$$%HBf z#+-na89JZlZxVg0Zin{>P~!;#)tqD#e79&2u_q^6(~AWi*C0V)7Gv$}w;A+OpT_mV z=kb_YetrEGN8Z~m8~?lM}+?;bA+34&uHf;nDw(N zJt2-<4#iFH!lP|WY*981diuzMQIQ5(XMfGI0P#L;aXnR#I(>zL(Xs2Z%k3Oj!(G6$ z7#Wy6l?32u(A46mYi|=$qsm?&6Jt%W&#`M}R#+UglLC(2Vh7$wK7b4r?hwj&xlr$M zh}YU)K%tKE%)dPEsxab$!@-5QNTS}bgwY07dyzn71k98Ode*at&PvWo3nHF8JSss- zu!3QtK`0Ih9|+)M6SK0ic&d*C)w1~YfT|3OND#TwIJ+@ zTtmXO)5zrn=-3FhN7{aPLSP#Onc{G{qlfz#G9ro4!o~s&C!*0?t>ki^F4|Vf^HYiI zQaeG4fWCz^E{{}e`H@fr-t=Eu;YDp$Yr?q#6~TwCAzWv@ccL;TtkQN(behdRht zX$aMZZ&L3OhOt$Dm9<@a0%BrfUdDnbhD^kX{Y=-(OWaVWtq+$*O8l6!uYkwWq@3Zp zx9PpGLF;4XXul)Rgj4vBv{p`K3YQlffBpcwW3)tiB7Z+uUmYDCo;kVrG+{^9c&bq> z&z3;u$Eq%;jBK16=b&N<8O#mANI=xfTv+FGG49|mG}4Q`hM{l$%glM_$C zkO0QUk*Xu*lFeQ>P}UnhiWDxbymhCnKU2>QWj3l8EEaCLwBv?zdig$~nh~jFR{n{% z#1#-f1*qe;)$V3bcQ5--ufED6Zf~pho73HaP(x?95RL=|oyV1J1?b>X5HSXee|*VD?&EZhdk z!8Yty#ouklYGJf1p0o7@P8%$Sv54Q|@DND|qZUplJJX*am3s})#d_au89O^}Jw`dl z>uqgsR|^XZOz#Y3vVUN6Nvz%W2WkET76Q}Q*47qiAGq6ApRjp@G)y(`aI{4vl~_n< zs7S5C{Q=Hl2nQS6a&zS?kW#A%s(=C!f<;(kyVLd9z3{-yV{`cU=qSmpP{cnSDQjlQ zI6Im6ry~HZ^g2z{6%;+aysDS)EP?BGW?{v7CgN?nctCUB*m(0a$g9~W({RATd3L=ODCqtDinp*9J@s8~o`* zpkDa@e4vH7?E?}AElNBB17z)n4F1!kKk5k&kmx_6<|sm0 zzb9o8_^jJ5E@NGzJ-!w7#+jt?S8`E;xoG8-4~p#D=n~s}DHa_V=JH`>i<_2>1uu)6DsXT)P=ZkjYN%dayJF2bUC%?s zj_SlA+US;Q@bH(DEMKJ~hEhS|mlC?_5#d2Q?W3FY{5(+9vx`iMEuAAqW`6@}U#E!Ozw zd8>aph@;7Kxs^h3x9?Sbuv?wq zbezL(YU-YyF3fk;cxG|C?wurlU4o5qZfS)nP+8BY6nA`fR;=4tS6y8VG;JCiZva_U zS63Gs8=H}l5x5z&*QyL->11-2Vl@RKAZhI1+SouVOxEND&#pVFRK7Ufb9`rWlUX-SG;wk~j=9i0T6bh* z1T5NhAU~XvLeXGlX7*EiXlO{g+Gcla%f~4i&9+AXL`Yc~x=Kn)rSDZ#zO1gTnV7FO zHHo*ewfXGr*$@-QOZFN3rSG)0LmeRyNJ)W9&xA+gL%*MLl;}tEHTFiorJhQm(YCc~xixyY zzR}YQ`1Vaq4Fiq);)GPy?X{v}>qDtt@I2{GDROnIZ5Ptg(rjwZKm`zp7GmnM+&`g% zk~m#yX`OU;&iz5}BJZnR1R+~)(sU|IBVCclMn>S}1kMI&Irg3cMS z+Xr43(g~twskr~r{(?KD>dSFZ2Ud9VChl2hdwYtwr`GKaCHVG(UqX}{GSE&X=6oL% z6okulb8~a}oRwA4lMQ^^&Z-P;v_L6R4^+ev6cQ16B_|hQ;|iXvG8I#a?h{(Ss39LW zMsTGC*e8nMumgMR+FblH2hK5UdF(KfhNGI}U-E|t> zDql3Sf?t#BdnH?pBXP~0rG9?~THc0Ze-fXot7{e4)BAT~US-G8yc>ZrtlYlBIYVid2cNsJOhLPCIkAW)5_7PQl^ z=)G?WS5CILWwnKoEB?i8W$6+zVFq6YndLTLp+Mp3jh0B@l|%x?JKWFL$+zYi=CiUji4gOo~Ywl68#yV}u;u4FC?bRrKeUwm3^ zC;IyOfSeW%@3(+}fanoRD0CFa5>Edg=H5Cg%C_AbR-~l6L=cch=@da4X(R@TK|qmG z8eu5uZV)A;qy!l-sR5)^N`^EDL8K)IkbV#D``P<>p1t?`eQUkz{nq;Y(>23fGuL^Y z=W+b%`2HP+aB4U(!jF~1v&A)6)zq9HhJV7Ev(X(%l zJj`3Hm@H5HPR)BS^;-tZ2$j^m!Pgsk8C<3b<}BO;HUm9JI*mFDnklAI#R#J(->-cA zpvaQ+g9YZJaZK7}5z*Yu%d*-;>JA=D30qnb@Cr z^Omt^hB?P!3=$*{oj-pbMvFs)vB9k$hc)=7GTw{E*4C2|q>QO)X(_2spC*#KE>S;$ z6iCZTdH-#f%J>6ttus+mbKH4p-^(&%1Y3_zwZgZU++3@>cX=fQUUmECF?Uf3>*@Z zK9%Y|b|)_2Mj)Y9*?GQ#u!=K{@$cH@7Dfk4s~*caV1CWaEPsEe{}hnd!oh`rfB@F> z=Mj}=999{++S*GiD^Dez9|4=GCz#HA52oX2so_`{74!!B~ZkXsE)`f-5oJ6H&2H@ ztAwIK4^`X^j_QtLS?%+lB=noHN*3CCuE?BQG|3-!D%H)7{6clQL{rvpgbq*f;GBGAzYPvb>gJOl`4!@t;2J^Z^yu>cdGf zor(YMpu&Rr|L5IB&Ek3MguCJt5=moG_9`6`c9`3ttBisYI}J%?wU(z5)>KW&QX z2Xfb1h@_k%rIhY?Ee^Y6y`q6u-y-qI`$P_V$6je={*6~pQ^kgsAV7m1HP2DAJU7R? zK;PQ?SvpAk0q8cmA6-f-EjxJ=3oWfD;3v`1#LJpm?P8%0HJ0Y)B)Z+w?=`R0N9quB zq~U*GqEE?PY4(EkZxw1;opY?LAaPdy{LzM++SfnJ6=vOd3i0Gxps%elKP+}Yky08ZX+kYiR@WXPv7Y?nb(Wh_ogwU zcULFXKU(_!7?rdWR1^&j4F$?IFZnT{KR+a$jG|(p7lu4#e}8}O zkjU_G%LX4^6f+xJqVL-`Z-#T)E`}$cZ7T~{mAs&skDJs!cRWJetST?F_WF5OhmC5H zcW`Be-#eZuGv$LOUwRCx({H57x*}zlge}L(CT-Kzn}Z-bANR#am_>S3Ld7ly%T>Ow3EjQySB@X^*EA+Z(I3Hi}a=uv#@Zu zIX?h#tmVpq0{&HK`sPRDpj-xuh;+1d^TgobE7X=#%Hy1z07ylHN|e(pBC$Bb1ecYW zIXXGHx)QWHAtB%3y=1yek|}HraZn{@k@spE`ug<5lhUb_c?j)h5ZOHEd?Mgg{ZxgvVzN(e4VJ5*7o-Pken@oi|GJ^ohwxC9 zD>WL8pYdAkulSQ2tf<(0BJx5YlG>3_L$HdzFEPr*kpzebc2Cxp8tauR6b_baqlV|_ z!XX*&#cPU_>(SBU`Qo*hihR@b4Y#y#{cc)&SB{>Qc;mnSdGEJXO<-Ot}u zg2%@_Pp*I1^Y2$*wqjLZiz8cS2(FBw68m)W&AL}Hp$Ci`9ls6rN~@SZEe!qIL2{Ue z*KB;qmOc4kn!o-YE|yGXNqI@}`G>bG@VdLS}i7$X`zliBr7&^<5mKGzC zTd%&2L4+qm0TpfxHujSrxBcYBO*=T8xupm<@DFZ zhwI>#A>=KT&ok_G+ zy@Xa^DFlC&>gB@JjRv1@>0*uQF*JBL4^0TR1egF!kwt4s#IE6Kmmg2i5z z9KPF|6=J1=KK`RIsCZ~(YMgFi_IPOtohfYLqo4Wxt?uW~l>JV>@Al#L4k2UhMx&Y> zjzmKx;|qguZqBlaPu8PHBje*&LDNA*M8xXi?p}j4RafsEZ+IXLiD}9ov|+W=*!p9d zHncu14r60gsWE$dP95EYrFY-G;qF2_^br&Y4PFa_YRgWQ1h+Tl>1V%!gM|%^ulnT6 zSFgeXFpZ5uGKBCOs?vX7+Jfeq>a_q3eUj99IfMjamQ#61#5Oz^^n|LkD*^HxgAea^#gZ(bKH zY(W~>?(S~Mgtw=s3YqgKrIX&v=?fAa$Dnq!{chOL?=%I4PfUzaBD;S7;}K`g=x*M; z`NE>{+}z*U*=@l)4Os;XlDxd76%~RC3Lqg>5EBERl-hvB)YKGI_OOG!nHGhfR;-u!w}_A7sE z4?zttc*QXav;DpS-|LBi0Xo3`@&C3P>iaX`ydqv_7}gsvjt^@RT8KC1FNQsNPWC!j zzX@Nd(%giU?nF=zI75F1=)~{e!?R%TsF6`n7Se@ zE$vr0<+W%wwLJ%YgOT~*r%&Y#4d=eH$$HFmWe5_xq!b1jKyv4YBz9LvN5je|$;tf_ z6PNRlrUbBvbM+o93~;B<{dgbt{{8zfHh#FonwZ~PSswh{#dbefMMiT~e6YmC`{DP&PlLCv40~Wsf{s_l8`RX)Vy!ONtJYiU3k;S!<2;P# zw}3&1lI=VL)Z}p2HZ}a&0iA}Ql34VQtFRFt-!ojD3yR&Uxc9~HPf&-zp&o4 z5qUU3fqDjaw3FxU=u$jJJQgWH@{#l*lHQehQSzDCvx6;3w7Ljq0ys zV~sFtQ|ZA;j9i)D`%r>djb{UcgMe>vXl(ViwYCD}K{!qdKdJkBK80^H^Haomvx>pN zk2c$BW8j3FSqhhq$ULZ3MV0pp;^}8F(=8WzW;du6{2;m$z?S${n6X^Uj3e9S+?+QH-r9I-AK<#qq<<#im+_?fVE6YCYR ztZ7erc(Y0B^VPi| z1N%9L%x}5oJ4#l+_uugU-m#ab6ru?C^k!e0_3FEh$r2b9Y$v(IqM+XZ>7?*btJU6h zf^)cfEA~8dE@Mkuo5~$Qm1^sGCTL& zNJjHo7{Fd8fOGIwKJo(rl&f$S#Ky9CDwZq3`NKD~RC^0%lE7q^A}bQO>RDw>BB{*W z6@X!c|9^6B{sWY`8?Yd`^JJ{7*ih=b)zHhbE^AY{TDdPSNogTJHh!ccv|ywA$p(8Z zgwxj7);>130q6(5+N(P$#2g;5?bu1RUu4xbxcR;lb<&p{&AD75x|01HO9#fmP_0m* zai^|yeux1U5d8COS0Z?147XDf*(^bKTqaX3;>L7Gq7Qd(P*m0Nz}aqUhve!{c}Xtx z=duKSjzVclYibAOw^3-WAXV)YX0MyPvN_@q83oEeOITE4>K&KD27* z^(ex1?EkqHeltefMFCtRGz?p(Ep!twS2%M!ubx@y|_Z8vewfB64A`14`f zNbW}Uj~~+phk9><6N9H7kXB4ob?x1Fgn4y!Ah$%Ofa#BlAN0P$pP7FN9pChWryz!x zcJBCglXI;g&1T-`BwrEb${%@4*4yS!%p#vx3%B1NZZ6kb()Gl78J9EA5z^B%$iAK5 zSNn1iY;!jCUrX(aq_U1m%U9au48^AsrfkzTM!Uy3$J~U>npeW)4Aaisl$8-Oe?5;| z7zEk%;+*n8MgG*WRBbrfP--q_{ERa@-{H;;=)9M?%WzM>rabjhDBl>(coST9>5nzR zX}{9~8qc?er4Am1eP(6v&?`XX^ov+A`6SrdsqlLiT``fpVPtG-s;m-8-o^*GfP)C! z3CP-1O`czrbJK%|G%qcU%k;6RT_+sb?Jq%}2z&XNGiP>I#=n34%3o~v%cR28Mssjv z#OGI61`IBX!9frFcpV^!yL~x;@G`_`KN8{>7PhYQ;Fi)*(Y=11dI7Lsr2rDg?SRCj zB+6K#DME-=a{@q1GH*!|`cPTi_I8z7P3uHZ{#Hpz$;8OuJW zD^1PlbT)eWH?EUSfMyouxJehNe{P_TtvJR}55=$*= zpH~lFQo52bM$)wK$IjCaDBWc{c4!Q%2s@S!{$fyt@N$^90f3aQ;Tj?m_v6Pc{*H8H z_7OIHBrTF4+_ghdAklm~qMvEJ))I|;)!4sDgupKnF+%96JzYfQ)&=uSDE}bbzm;TL zT5^p!OVRmhlXrcm-p?Pi5C2d!Bu`uld^041itvg>3entA-&HHj%VXzEeDsLHt689d zRuk1RVK?$YQ;Azo*VdwNR7W_Sb&k00Y)Y`1irFVYZZqZxTraMJ*-&;Md66o-D)LGM zQq=fypuJS2XprY2%kj5)hF>Kwjf^y&_rc%;4&hwA(k7NjPEh)oy|Pb;iXv(!sk@fX zVuEQEDzjNnarbJJzTMg-!g!HeigDp1?d9&C9@et@Y7wEI%MLhH$IEKP^ie1xGKiF< zv#R7#2}wyG43tp(m9YgyW-T!gj!rTY=S@OFG7}Y<>4D*7_hq(k_wezNQsA2A6pzKP zVPIr*eq#;*CJ0+oE_c~Wpn5-kY^kC)su;b*k;eLc$-8rcSxuOpV@>J7bKh5>pzv}SFTo~hDNV;RzDlM zI?9S;<=1g;G+ZPXr?1K1B^#64>fWx{9l!QxdB%Hkyd=?UF}6HnQcz-yA18NQx>=mb zG>o4)&Q8p{GBlJzL4tP`-+giE!iWl$z_fy_04m~Ua-kW!pf#W&?rJPACtw@J(G^N;4Cfu(M}{lBSR7PdT#dgUZY z36fol`vn6S8-5+7DKDZT?j+aM<_I4BAWc{}mmS-BLB%))SH+L9eGsea6*xRRd_ua! z#2CIvJ^gH+J~n))Iy0JJhXVhN@y5?oS;XuQy8JaWqh~}6goSL2M`nn%W|H;^-SdtP zx(>h40_1QTUzh)|AV?k2{XI0F^8BHegOii;L!MAcdM#~jz*6r$t|}ZYeTwRG3#^RS zrHfhPH|DciP)jzmwnk%@=x?N%hH-NXpIf9?s*-P{H|Hku56*Xrd1#q!?gjXNh;8^JBo<$=I zly`_$wr+|1>Bq&scy^_g9;rg`Yj9?GrAk+ z3%{tU$+-!V39b~CFB`kBde4SD;s1R`GR%!;Siz0jOur+WK6L?Krv9T^O4(`uyZ-R} zZ4E9ejO>=|3k>KknA|C4SQs81-GNMCV8I5R-h@>Fc)tuo&6r1MY%#5^{sj-9=YUJv zn*TmzDCcajvk=?1lhob&dwD!a++FN za()}nu0Z_XvBd)@Kf+g|XS{FpYOI*%_+KGyo`9qsJEo&!fM6p8cR zZP{(!$Hi$&-mqf}>>!KT&gLuTdEb5%maSr@!nF4rI=^a}YB+vyyNOQ|`>i)idkd49 zXnyeJH0Cy@HIgjeH+Q{P}8$-=91C<;L-RJ@Hq?S;x-@iU&F$8wgql_x+Lu zW~5A_a+cL?)yB|!;ns4E-==+ASBj@1%KP=E-nM#ViZ@65l6UQO+8uD9?rNf#k=?^0JFK z!pF-?)ogTN0PlT4Cupcub%+kZ>O&a=R-GtHcD5{}O=nfr<$!h(yl`?LfIAEf)X=AX z7N(}seC!?^G?HhEpPtHxfd}idY8NdmEh~2|(IPSjPFJcaTs!3pJHR zgcg@fH1vifeFD1l7V`G|&!1s0uSdM^25V6fVfFHAaPv`HTifbbot;)!I915+qS1#3 z4;x))hl7o+53?8jth0HOQ2n2P{ZO`fvpO0pqE(d15*{Jrpf{H@R8j7MX+1w6d0F-( zEq8f2{lU%C1gGccsPA!nkB*>L8LUuW&0L%`E%K$T^gs2B4&_bmd1)`muq{}6=4$2~ z{VI2`hi~T!bG5AH%|GMHyG7NJWB#ul_pcopJUyr@39$;V=k&ynF>yucTDh-Y@_ZJS zX#C4+!5^Iv>|FUrO>L~tU-GPDA4Z(<1M*1S59-x1^eo9>o#KzD?t*8ctT*rLe(L5P z*mBC?g2vfsE6-%wA3ec8!7_-Fd}Ab@G}NOag^#`5$uX^T6aV3Ki04JNt0+1fu4l{) z3{nypCmiKhkF%O%e2mGXqLbk|HYwlIPbZRySnyAe@|J?pJOjxSy}n^4FYuJf{y~02_!w2zlbi# zRsl6>%;+Ph*-Il<$7}?kf_2NEjSo+wV)_NAot^J!^2in!7jx~nxx&m13ybf>cl18C zKSZ4u8^9pqqQ6rUC3GFf28+18(5Kd-6_Wtqoa#4BLFCH1EG*0(aHdYuUfvnio3aaSG(v@)|;1UgD`BRCkL4T zz>C=}9V^!D&B3GQ<534(O*=>fE^>1-``PtW2kvdNGaUCHY$=WeT2i~*Zjvf$Z*O0- zIDjiS;c2Y{YUb1Qz5eXu24`n(yYe3fAFmEf9ye{j`kXcCk0uPByRGI!sUfLP}Hky^VjE=vn>*L`MM_-^pcr!-5{-!rjMMZ482Z5GV$ELkmQR*xE|=dMpM zkTE5)E3z>&J09%;q@bQ+7>}GpRcKWqdRydQTn;{TE}F^$NDRiai1O-Z)D>uCwYIeO z$y)!RAK9x$$&7Y?>P9T>=eDl8#Ef$W?|dhiq;R7UQ9K3)7E+X{Quh1(E zEL~GvR=)aTheZAA^aWp8Qt!mh<%YBW(V9rGpC9qE8UD z=x}Dam-dqd$<5t^xxC)M?UtT12qUyY+I|m}7*q&Cmf+iU^SA)muXtw!(&io1)=$z( zyT^7}M&ULNmg;B!P{g zL$4c-g^J1zfTN>yIarX4okKfFlau2Hg)0kdyO?_~02B`Y?7hX1IFd(~t>k=GD!!$v z#WB3FZVq~_ebT4nb*3OC_eh(Itila1@bG{F2%zo&(I(u9KqH>?zjf-&ENPxu{(yPG z2658<|2(zm9sgry#%pKAijk4gNDvxKduWc|3Js`o%F6Bnv})Sp2HOIhkZv$Z$djxC7P_pXfT12 zG6*s0*}x&f28O+<8IjnN9{J!h2A*sT=DcKl7bQ9Qu$cwg`~|~($;}6P%F48SL*D3ED!<^_>^rst3?}$W2)p&+<`rHuzM_uuH?Sn^B(?^B$~xC%SH~L7h=L5e6S9uQQ<((P4=*BLu={$M(Snq;W}hIPmu|FrANT=DBZOs zz$IL|bjenhm-p`QbCZ~un0bG+W!+1V9c)3@79B=J$vJnzf`9mzrtKH>eR6VgfYwUv zo%19nf|13ig>myIJ(l|9*RJ3RSS7{TQuhV|szzb*%1r$aQW*iwY?NB4TD?8dY|XOUg&_k(NeDZHCa4V*gbdT?}`cLHkr~< z`pX9VaZ^`U2N}e-NQvfx@?5+|+~%f=(fiBQ*RQo4e)4lCTz`a$aKI_vi5UQ;-ia22 zj+>ED(7^Z$GcQY6g-R3!0U@DQHq%?A5&89^X0na>qNM3d67o5={ArTTBeyibu`k1D z#-8Us6Lv;pc0jHy;V-ELEY7PNAGyqQ_bkaszR7POF4|rUYrS>xmOW3njtkFYq^@ph zRUv|jXGigzR1${l#=4&0+D$U>ZPgIU8MtUr*4H8 zB8;xQDPyU*^o*8`jl#7r_X;C2SuY9{ivk+dm}z-i%MdF1rFZk#c@3_Oz08M5?542A z+n(OuOHxt{cJu|>8M(@6P!Ynks=<#egljuHA1r1O6auFuFX+EF(<~jdNq*=enwY9r zQ9e>3I+EOft6vl3fXQbQiMf+vVyIn}&`gUL?pAUoQXhld;+cJtoyMi>Pwa@pl?zh~ zZixrC;JdE?IZYSyk*Ku1tnA}*J;!ZM@%K085W>cSb(%q*(Fi_%5oSctu9=sj4tC`;4X9|a~XO-5+x-e!DKHPxaSr3 z)Ie;g;uJ-$)IAnGi5|WiI&Y8(HId<5%KZWum;3i011+=-2{^vy?>zHOv#;osL}}KmIV%4=4W5RZz6k5nrN$9~c-oz^#SPvbD9vfz z3H<9$OYRwkRg?Pg2@0k~*+rrv^nYc>o$evl=0yFTpBE8|nZ}mD+P;o3()~?`%D9}@ z1(QIfpKBWdaen!GtveSBp*clp7ZkE_UPdnvc9k49ZrrYvb#-+&!rs?tBAS2QDxFRx zZWLmBGcX_Qu?Y)Gdh0@&MoNz?pG(ke53}dU#oGg7f8RgctsB939b~%b`MrK6=Bmm< zM7U;cW#$(Zyvwh_pa#-=&4Qj`J1Le7Le%M~iFGdeG*fz%VUbt+{r;aVig zO2Z2dH%?t3W3OPqRvc6npAuymyL6AwMhh))MY4Dlkeaw2+pN@L2Uu;fTtJ!_f#YQd^$za4d>=MqFAdCjf zi=0ENb8>S#RIaED3UZb}%P_>$$~Ti#sVZMwh)6%3Tk89)eR9&esF@-LNgZ-=LOGew zDuIqL1ZD6MrjGzowlG-Qy>s7pb!+2S_w)@mlE^Y$0a=om2OJl|b2dn^aAtmy#19vH zym>ou_wl!Kwc+RtC?$Uw46!Xg)YQ8FiInj&6cPC|e9g73{41DP^N5XSyiQ(nxxOC0 z0P{vKfP#ZM!4dO(c_Bgc$j1|@*8lxPwsXyI_@f8B zt&C6vKoCtf`guA!mN(k|niOd*D7P-B%1FXiIorSb8$UFd>|ovqv!Y-9z( z%0zEaTZ_xf%LNN2MZq)lR@`HwSZocbAlF|%kA-tR&KFd^b?!eqYwSL>(~3pcJzK?S zW%6MyY$fOE7nOV~e5S^NXmkD?^ykXSLPj`@&!rTIopwbqjP$HAh5v_=UUA zaukD+dw6fuP0%vx#&JUmDk>^irWt>~KT}cE#1-t+EHr%tkrJ_90WbSc#UryWfE-{Q zCugYC&e7DWqJF-;qrd)7Q2!sis!TfRA@#C3b)tSXo?54W>jn;1du$*>n5=QfC;(MlK$#%tHpW zf4e|@(R)G;sfYh20sRkMfSoFOclUJgp3&7Kh5gE}ZEfyrHNRdq$dEo%onH`4}^nn?q*LK?`)U&p(ZlR4MEhqceEDOVFs}}72m$mjE}EkvXe!A zMKErhaK?EDw}brZHg>+A{OuDWbi6rucJuSx{;uQH*Th7+gX^x$!%OPa3Sr8;$Wk6#!(C_ZwiNB?EA~?3WweOE!`w3rBL!DwwAXloF z>&iaqCaQVM)Fd#FN&Xy@jL03SqX!R4J3IV1TZf%~AOEs`xwCRU`UW+@F%a?Ek5oB- zc)PnhI1ryG@xOAM5cP{EoO;89&%T?zv5E%;+YOVKgf5Y%Hj^4Q?XR?SOdRgtb;7ML zg8djFj&pf1blN1ztJ_g%_@!I3is z#8ewI*9GlCwmJk`SZ#fM)+-NSixG%Xpp_u%;8urNJPGt)V4ZMtb7T4)N+mW@fYe9_ z-W*({0yJTvq1&rKw@(Ix7`CTJCqFngh06xT=*7S^wtABokwSBUotMmDtwQGff zr^Mg?iW5@?kciJ~-XhLSgxKlO#~DiN|;1Guwuj_sae!MHv?Mh>grm%1!8d^)v`XH?11tf5snTH zOwA~a=Un0wlvS-8hm#Bkn3B4oRuU2#n&0|1GGhOtRpP%_=WiY&K}=VMwcfIN<3vw( zWuAu#zc8{?=ZP52FOJ)-BI`JozlaQlc2XFAsWxg;nwLZr<~grZ`LL-5L|H;}Gc) z&BPRzm~Z3{oE#+!^|Z9K^zsxEbl9LN0k$X(2U@ZGma?3upTUy?Au_j0uIh1jMdnyo zSaf)sQ&OIIh&kot%njw2f2~cmf$|o%NQZM@3<66}2_GID^cz=`y3kNjUBE<$N52~q z#J@$GzCGKUt*@~AjIXZNETpitPX^0mc^<_0A|eLg+N-y+oHSVu?<7OQ0-bBY)D)fe z6IiQ+SDu%ZwbZrj{fXydXO$7l98tOlqa4>Z$5WA~)lrPXNLE~}#GX{r0euY9r+g8n zvyaoxaL_)5(!dKfp9RKE(2bzc!YHiL7KuuM3hk=aXBQ@2jZyN<7&b8>A+qkmBsE0X z9c)E@ri!aj29Yqml7^8{+HL0K^z`s1tIay3p$I;~{3C2PJssUg>2~cpd?&CP*p9y|%K-(uHVbx_DS`zra2*wS&|wAp zxH{>H4Qqnp*b;&yIMKmp=jpE=1A9PKq{PWoL2UJWnGSW;XW0yie5yVo^02vCaYC%w z!{BV$X+M%qWw~66F#Owb?&)6Ux__6ngkkD8OiUtl+*JAebadi$mqfY5A6X5?c4yt2niLbs`IGUJ9(U!`` zb`LBA$zGDfL%{92?;0xs%wuSk)oOr_&ZibBw8{TO_Ts4e=}I`$^$y&e+m@857+uIp#sbm{3XNXp23 z;e5rkc;bqnyoyUU+uqzv!#O?Qa?+8wm@z+GhIDs0VUTk!OTU@+f_=~cm1RW`|7&|? z-1+f+UykVH>)rT+f~>Jf#tEgUg`YpqtjB!5QqM!&{q^fj`PbqS7*1O-XDcUg#48_t z)M_^pK&dhJ`^9Q#wIkRrnBroIFRn9$sxCM^6CvJ{qZ5;odJB#okP2^L&Q17Z0(M{e zE;13Q4Dn>JMzl9jQ7P-~M$7~BvCM*}%-rKA_8~y$Hx04hmrJ?H|u=J&TZ z4k0oO?J<08oo6`5jhBX*oHeJZy>>AOER#gZ775^ojDskC zhD&YS^tA138>6Bt$~@<2b)Z5XOq!Pm6?cq6_1m|m?J=+HdzG!jDV(+zPvRO*$c5vN zg7sRpAa1h*h-li;gdQM!#&xLjLy=2gYV4-ZGJ9DM0BNM1K0j8?vL{zYH1%S-jwc}m z+5w_iDnF~{pz{L|c9lMWZHDkG2BJ8xb*5LR7*sx7zRX|5)>EcUDpG&4p=E?UW#^?B zPR-1G2cF0}q>cUz*?!BbR(s_PhN7&=`FcVrDsLMPH;+56T+C-Bp>&WR|f_Ls30%olQjc$DEtF9 zIo^j~J+?*)u^&l(PUmos9Yl;|JV{7Qqdfyd(C2vz5VZj|=jrMB$~`4AY3kxnaFznO z(hS0PeSLlSZ{Kh2gr09KBqpW1PAryvmg>Y$T6EYjd;4>b2bMz45Y23s#&ePJGEYL2 z0s}mugexp65=J)ig{q$G8NR;|FbQ#ara6;2An{{)J6aK?;i9f?t=sGG?agj~d(6YF zmhr~!o;?HOadrKkw26r;FV9<9x%!Gy{U@o(dB@7Sy{ogIkFUF}9Zp*C2?vk&UgG2~ zE_%6<3Gc6M(D(MCXjxfYQgm`T2sUf6HpFTV>;(k{+3RtoppPxt<4UkmynkMq#qQRoT30Qr)aRj9(UrmnMe&< z?wh~(laDQ2u-7*=H8u1=QYEWmd_Er1k>~bJi7J@&+S~Z+&T`P6`MxA6RH-25QInRI zX}V-#_9yqtmrI<1M+bS4QPR$YL4+gXa(f(LVa)JyfeDiLeg8akZfu;csF)17(XrR> zY>16BG(4k-=i-XaSOu;nD=)7ZTwb19i8AYuacIWO7H-DDDEcWk7Icv9UWKUPIVZ+l zA**^ifAgweTPhif_G+#!ZzVRyYPr)Pwcl-r3iq*~%2rgzU{rN^|=MJkfIdZn&E ze#~U1^OAn(Es(%)DxN$LrYh~cRv)B>1mnqsyI(~lLNk6Tw_HnLxRWM2c^M#Hu&YXSU}|c{#$s^PThZ(BNT0ZY$-jdCcTOokLWiYpZA=( zUp5Nf*X?beh2m-fynFxhLuuLAOhKi6=^J!YouqF^;a+J|Q}3|dNQgBTSTJcFmTb)b zVX?lRRQ`+$L@%{>B!Z1lZs5EU8 zEef6p9o^sCxOf$yDx|LLTif@1sYtCF-ZMoUONn`aH?SxyOxw&X41*b*+dVg0QQ_>M z(q`R=A*!mZuNx08qx|##jCMr+IQSfcpz){GogN{s#2f5Pi&~ymm1PUl- zI8p@BfMxzH$ppbPw>AP+O(Gy8_m8`nqMqG;-M0t7zuj@#5c_ML zo-#n=;pR$K1oUpHJ6CQ0&4f+NTm1b@UtP|klqLR{lr8B?`kd-0C zN`9n|g`b=*|7KnOuRA>~y8ma>?|&dZ{}P-ox0efw66pXo73GUULQ&@=Woxo5LKmGcU-IXV}Jxmc$9^v?~f z_NR$Y48I0x#y!LjXZyQEN^mT%IKX!n+C^fggoZ9eS4ZcyR|UUONqc7}OG(jeU_ijo zyF;J%?_BSUwYE~m2KVQFyF^2ZN21_-w7jYtoO#rrBXnt4)6;ik>bP=GUnoaMeph|> z9K*frN000uM^ie2L&c;^3SU4#;OW5TYqpx4tn#m0wITHL&e6ecTTlD;KX8uNb|AihmM=ghvC7hb#g}Fn^cGGM&9p5} z<}Z9?_EWF*_yVP=W~;4DnpJGp*VT2>1whur>m#lt`RUbF*M&p_#WJ&nJC2V0-^eZs z76WK#)#yw8Q$k$a63kwDrLSHyWleeG>22%Hb7ZPt%HUOy|2-xC>a&?~>WR8t z0O2W^zP-G?JAROGJRI5zx$m7*nefe^Z>X?SL)yJr+Gfy0EZd#vm!810?P$ooL>a1z zt-ed#OVgAnMyS^MlByr6bqFIb`|Y0I2@%g;$`iES1sOtiYj!(c`{ApNyf>wl}f+ZL1Z*%O-uZVx}(${ik=OkCuLGO^4wOWtXGJRjcu)SaB(r_JH_Q0 zpq!9sPw(sN`y(voGTxFl;IaI^A8D8A z36~h@=^b%-M$7j%XM4@qe`U%^7Y!3H|Nf07Gmtmt5=$qGppAM=%Ke_l;SA@G^UAzn zX?oZ*byH2QP}$4qqYX5%CjlSiWW8*&PNQLG=<@K$IQpyHIB(T^qWXn8y1?xm+6eTz zf%lEOp|*CtZ~~o|al6)}LCo@#Du;!M{fr{ns+ycR1zrzWT9Hiw%)i>Nr%1i;auAOs ziZEC9E?68&vclWqQTrMucA$4{Z8J8H*N>N#)oBFN(K z`-f@vwB`mG57BxfHJ&ojbT=S)7YX1nHo9E=%lYOkZZz{=!w)$utdQnS3&HCdYv%JvQ4fA$;$T?x z9MK+QQ*}lvSbo>N%%JG`DCsB0#+*ildq;G-_q}n8=$U{!{Tm0jkMv<%cFFqi;{keh z_cJZxRf?a6)`$Eh$YW-gEMgKa*ar0W!F)dl6ah+}{qvtk0s3?=#D34$pr51gIVrAG zOTz>Djbef((vdX}kyj-p>D8}wwNWa@>*<^879fns&*ru%U5%7}ZXhLLsIpl&RnP-@ z9A;7h7w`j1EYbb=PK2apv>wzJ9Qt(E0t(kJt3TK%JAGIOi8!*u4mhr&Dnu=r9S!zd zv5GiKwT#NEZ`$Mji9*__kSl_#`lSq35K)!>omQA0D<}Zq69N^()iEKt_muU?PnFoz zp^=e76;rco$OM+ab1fl1gzVlhT;)7pH?>K+_0#N!!R|2c=9SZ@#ZFwjP?+T_r-T-% zAID$Dd%`86Ax^tsaEWk&m^?XA_k!xK9=)MRSL9+uQ-RuUkp|vtGvf$(0+Vpha8X`8 z{BKe$VVW9Oi(L9pBD0wv;(fJ|gtDNSOiWCadPQjP5e&RfUX_^0oqqq0v?;;OB&GJE z$JuE*KX5lrk{@F@?9V*HdUDPtc%%`yheYIh%F#c`e~VSie^SoavW?2Ed7zHfRs$nK zf5r4A6-=aYWO_65GR7FldiIQz6q_#^N|mvKHPJVz76l$;=EO5xK4H`ueo8nm(EGOs zkqeLJqd^DoTST}&28hhbu5v-}Y?{-Wb3MYkAO%p@Va?R6jdnK6eUmkfG7f&X))2PB zVrxQnTuG2sVdE0#(4b7hbgvFPpQq1#QC?&;PcN(ag7iE;%059M@sYw7AY@9` zmp-5VNg{skDK;s-9=Sds!d|3-@BVT1m@}UKv``;uePBwod55+mc<>ARe!U|GMx(v% zku_`Q`&P?=dpAQGA%hhE;fM25<#eiqhR#+%Cb3Rku`gcag z&Sm`=Vro(YDVBITynLIu$cxv^?k)23%n0XJD!t!Tixa!sJM{o>vGz(mmuiM$d1%m$ zu{N4~(o3Y5&q=V8og&1{y82_jef_TXPIaz1*?Pyu%09TnV&+i0HWHQl*4@0Xd4l~4 z`7V~nQC^sceGN9ziO=%V2utmnN5~HEr*NJ{o2e_0nfgNAFI3N5aE%)k!CmZ)ycB3+ z7lUj@{K0TAI{wLzlX0KMucuS{5lPbQwQwUS=qO+IAN?4Xe!Oo2<1e|_WPY^JDPm^X zDrt@0XtFwaKCk0lI?XOort1_gfTDjl5N}(C;AaUP zrh5XO1nP=ni>QoM?ZfCFMrQhQy7RJXuQ^8r)j$5Jyq*pE2mj2Swp0`P9i-u@hzm2r z#Cculfiqti=p&x8&UG9AGGoCM*1Ru`CTQ25N5-;B?p3r;k8yN%rTTgIarsm{nmbB_ z1nl>AzZzS6KF)2)$KBnQ4j*UVP(q{A8#yrtrtjY^wk<|AGxnDK(_GkGPosa4C-<IO~s9>LYd07t7+eff+N1_qcj)Od9b01T< z28zvNKtLhR{zqaj#c=`25FtVTqxOV{iZ!p~kKuv~vKpWp3kYh_UQ`h#+j$joZ zi#i%=!`RgPiGD(zt3J*_ybl8)r^Ucl5pIw2_hG@w4+#_(Q=X)pMP#p#-F=g~SyAFBA{=KYC^uf`?B$8{B-h zjaRf^GRnpWFYE^M4gO%d+YTtTdx8pycJv6k>hd& zC%^QtI2B*dT8Q=Vz!WMP*6j#1n}-&#$T5)Ft~TTnIB_HRAsE9 z1Chej9Gt3jG_%T4m0udL{%Gak`On1-LD7fqd;L<$msp-1e7y*Vm4upcE+_uA5JQiE zHFqICMZ#0l%A(srTZ<-BbY-gY0vB2q9uB4?L2v1mV0>i2N};4+n^Gkn=ikM0c*b>_ z=Jl!J(6Clz$U{?&WQfiYrD@T)roba4EX?@eHGMSi(u{sN5Orm0~zYzj)ThH_aa7BitYY}uKLr=zQA z5@=sAHkd)9Wr=q9?C^p94r`k7-jZeW8!Pcy+4;uAMsz+p3LXt-nk#-tFTdHU;g{@OxI5C;$c|KjegqpIxM zePJb}LmFvNkzAB?NFyL1N(jiJyGt7B29cJM?h-*7>6Gs7mhSxK!sk8vJ@&Xcjlmy_weEY~^PX|lysqC5De9FwnK~Jm-8U2%!AE%mLcG4chZo0N9U9eCIcX|y zpSsdA)9E%)Tc2!Cz=HfF+Wib6epqyvFniqZhZdf*I7v=^ezS3tH5J7&-Qery4kU*3 z2cHu7v)CJOSw=LhJGikEow@O7Fz7Hv{6pkO_`wZWctU^P<6*8QxgaEQ-m9tt-ko} zy*b$u8c3J4FNLTI)qGTW@KnxX+_V~lrRewpE*@-^?U53gT#H1zPz~w^8aNY z18k&nfSm}A7C|_4aKp}z-qWb(R=g(A6BI_8ECGd)6Hj%OlWYHwufCk$;puD80zG#PL=>gy-ff3Ue{&)p6@_-kAC0 z*tfK{zAFSt_CB)Q01d_CO!W6@12pQ(rgyAbVV#u6&G{8T3gP3KxI8lg6%jePbQ+V( z0Q3WYAir9(^!%It>w}(DmB)U*RYB9vE<AN1(001 zx(|c-@Bz(hi;7dbUi@fy9@O1%b_wuPQrtLIoW~UF=%)(@w#ut{#Tdb0)n1t7N}~+9 z4M7>5UprTU!jQ;7+Ft_vAg@WUXC40z+cSQ0xh1fr3;-n10q~dOWBmYqL&HmttL87x z#{(Bvr90sPnyua0Yl3w;o2cig$XZIAw6JLp&}_8rTS?-JUEbJOpVx|wT!N6l#9>s$ z-k&tpcXw9;kLD`A&FvEJ^wor=Q?8IypewD>_GP-eM{3-pipyp`N^8y(Vq#oSA7$urR0O^VPOt4Gr1J53a4Nd z{{BrT<>{5;NPV~zZhyN^p&uV#f4g?u^P@-;KpUoXx~<~Q&{{?{yvA0b^k4u1Z4j*j zA)oKtB_Lr;_Gw$|sb>2l00#qV0Lkv~ONeU}ienZxH=RKg2yitHFvF7PO3{u@=zyT; z?&^B<=c*xam5!ky*Q7Y84}s-Qf#&`W{22DS4uD|%2IsVM^=^PPFN+g~6B`@lZ-B;lSo{uPv%qaC0Cl}4SFD?a=+t}EE*zWaSGuG)Atrw+VRI@*p2MC=*YWJGJ z2A8a60vrN={#sgJK8AfpzYq71ul~nxfBVp~m-aSn$Y?gUdxmUWphajqDD@(n$8*b&8tqCg_RfLqU}*FbhO`T z1;;#Y^j0EiW(aDC3Wjn%(OGp4r<&jegid~%6gDOo#-{NtwsdyBP;As2{N;{{lFLNr zge}eb=^#Hpg+$IR7cPxR_YJqEociE9e76$>SC6_9O9?Y%k*jWyfZZ zM!)>X{Lr4BFeiF`vK*rTqi{2iw1dF=1cOO~0#_Go&$9Om77Ca({6lvq>rIJ9SoYvh zyol%&6|3#5hfI$707297MIR_0qZ*i)_)&gLDrjy#_Xr&dRCMYqU*F56#it`9bp<2I zQZM7%Jq`}vM8^sR;V7sn4$2CD+E3{@dh#r%Aa{f5ru^GMU`GdL#qXs^#rM~Q-V0{d z`>9=B*_HJ_o10Xkru+9EO=?{Rh-iq`8(%*liP(v-LU61ui#(i;s@lz)6Bu*e$?eL< zsm1ZpY>wMWxKW&uk-B}gZy86fO)WrYF_?c`oR;(B%WNKnQeSuD*t77Q&cvD)wh zU4C6Njx5fMlhUB}dJb17MHic_{qN&&;%)_(MDZR*xA#fTUYLetw@w&}w*~2b(S`nS zzm^?gxB7L)Z2r)^c(~3>qJHAYAabK;z4>^2f2zXLn!DiB^StMb>|u)@TepNOLhq05 zzQ{j<=*jF5MA_Ol{d%?>86#ixRx_|!sE8+dBcb!~D)R!OFRZV~6w4cGG?=~;ZqYHj zr}H~_H)qaMx9LD8)0^wjT*q-=Yn#jFDVr<1SqiHcC9~DrymC#=z_T1@jEC(*>}|5p z$;tZQ@ZF}08W%CsEiQ6$X)_l`G2wSQy2X**GZC0G5uJ%=nhu-68ar77r1CH0gGIc& zy2>XbWq~4sv#Wj+(KC3FK?#UyxJlzFFI}4F5QlzUjXly_+AvizP04p>9$6&G(bSr7 zOv4+JlrKgv663@>Htx=zaG$6+^zKe)_WzBa{q>ja=QW=i|8!E))?I0j_CfU~b-4{W zB}A14DeXwwwpYtF)A9D%@wcD1lhB_RpyW2DHYTU^Cx0|6P5BDJ&b5EHWyLvOx->V@ zS(cj02rq|OP$$b_$RfJQAtL!T(1@yHscvy0VIE4dG2humJHhnJFhAM;?1WMnn-E!C z{FDwanPnqgvXAAmQxUqksks0(H4XRi<3yG4ReP^cqLSyzcl?A=mPT%E3$o`I6tuIp zF)^{V@Z$KC=sNM*efune$s|Ae#Pj}M!_;MqQ0G| z9rqE;{CrF$id+F3x2t0}gNk87znbYf%CGY=13!K~(WZlp)w!B)mn)-{4#!ThTdXu|+NdB`2=31TT0a z+}2hsB6P!4Jd@*^v!6&0Z%tl7-8s>el={TPh!7%0-kIRG%elRjsx1Bf!GJm72+<2p z@@4jAoZI}fC$zWK4gM(hT3o++Sk&V*<0`OY;?4VH;{D%U&+vR`K5EQZJ6|icTMrK9 z6E}E~pqb}l?6GhY|B_vM@Um9?sp=3R)NoD!(PiGXut$T3!FaT4)RvK~Q0K>IM(|FT z!8<82+@T&bF*WAyo30fYZt=9$Bb^gT4KA)dj%Gh8mT!EOGUU?Z!@j0XDO#3A$YHmL zKTsd_PrxSCFg}S)y7-)2&nR?Do_mm=myE$xIL>x;efT9oXc?L+C=1;y9_PWigdie< z99#}ebjqt(qi~~cyL`V=*6$A&n|26MvdZrv9U-{bWAP8)&C?MPb`Z!m#mhw zadWC)JbjM+s`x;h&Gy>@6y8AQX)dlW~@@SM0FaU8dCc zO*(TB#jCRNQ*?}=&+WHwqfYTLwXNg15KYbf2hA$1tYaN306^HxZ=cl;4iYpy(Z29{uMn%~gpV2+vTbI5{iV3UsGK$}y}e5h z^$PFdz^a}aasj4N*$66KGxt;Hp5Sr_^-SLcR>kS%$u3!cEXxlT zBjEzWg8WERL%lWQ8RPaNL?(X@?#{$0a_LHu>4%~;@<#G+5mY+#576gA^f$WCm>YsF zMh4o_J()en(LVd&buQYga1O1||-q6`O5tUFA zDkQYJ6lvhh{hK{>RaJTPJ*w{ycu79+DHWB=Jmy8xEfTFGl!w6 zrKlxxW|#5OOWm^125wom=xwgX7lS)d7VSq*+Spf%pL_T+APB)UIB%;*HSg-?7>Q>4 zL*Z8(+K-ZpKGA)ZPT3N=%~*-Vm>^N5F1P?%Wbx~KZ2-luZ>bP&2O|bC<@AaVd_aazwa}JpJNw2(SVnvs#(6xNu$W zm6OQKx5nuUD!S-#lbB(#2@`CPqkJfSR?@K`(lh$*LY5YghBG^p)4Q$vocNqsnvi}x z@&z2p|L#x6@#~omeB(kBT|H4NAx%Iqd=SJzcmu7KF#Svi!Fu4ueyiWJ`Z!(RH?FKf z5D9ETBs{3u`eJZt6CVvm;sEik~x9_aAtp9NVCb*!# zl~8nng3|-p%@ftN|H@M!_!8DX*tp!kdu9u=$bM_a*E0whY#(A+@BV}F`S&CC|MHur z`%zuikA7X+RMo&=cInx8FUYv^^17p=4V`>A{q{}hS+okTLa})pU3*=z)7(rd4K?W1 z#eZVy(Yc{mW6+^L!^{lXJ5=`Q}8 z$dr`4+N;-59|u2wHbC_Xxz)>p2n*}KdS$s^933q$CgD(GPLUF|x!C~pO>i)llCogy zF(NrZecH00-&nt&AQozy$GeMfDqGN3`!6@>8YfOQws>6Y%`Z=61|E7k7M}@4-)CG!byjAP}+9xYSK)$sXHdv*8(Z4XnAqrtQY)Y4I4 zl>H>)n`D@2So*UVp`TB*j|FWW zH=req!R%CxuIifToS199_5DJ~>l|%&vAz-A7~K)G8F}%?)?z%YF0dEu6}xlvJB|L(w#$6!SR`!ajrz~a6kxh(SOF^P&$yG6#qMpRWBgZ!UXp<{C zB54w?LE%xSHAwjM#oP~%@Pl$~wMv=As~wxuZ2AL^d=xULhcgi?gX%D0LwdwWss{aPQ zA@YIH3Rr*R@_xw8GWL+)kZB=y<5hO0z7lo4m20vNZ7q0~1AqETBS|9_VrA9hRIrKWaP{>ZzPmzu4w#+$l1&P_DHm+47K=5T z9~hXJvBCTzh7=6jMG7&PCdI0FO;`e7AXcTeaZgFM=ebQ43`N6WRhp2{BbiCaa_@mGv8|Zicr(=0S&#n1yTDQxV~P>77r&R zF7};=hiA%G3#>MzV9cQRSdAjk>17MBGjWR>=An(>Z|W)Sg#%0jwA6xmig+|hReMgo zY&qyGaH7zJoH_&$P~7f^tMJ!Ll((rbU}UFrHuAFte(|o03oRE% zEoR*_$Sn=17fc)-w0Y2lL&8VJ=K}BH&iFW^qIBN~I8Hn~2{yJr_Sf27T?b{cvfY5Q z)ZJArle$-NdkwYU(SpnKhpMlO_=*OQcAGVw1sqd}FZ^Wk=AqPJR`!5EEBG1sx z7+fso?(t7L+6iyM(GE;uf&1K3HK_MnLy%UM`MLCWz$)o0Pj<;W$n}|xEqsS@{6wmS z(0c`%ujZm*dnMZ)pPiq)y5pzuG$ob|%jP8FBt6NAug+yo%hqXlWvgsVbVIYiZNGUH z>&J=(uIw)ErRwSa5A(USC)*=krp`3GFLX*S!3I%nLj+p-tkpUYw9ZT^0P`t_$R~QQ zALXakXDkMni+``vIAxQLLHXA7vFYHeO^l$B{S6S{2-OH8Mw|wgE&iFJP)$q6>ppxB zO#R)H?NGi4J3ZAyJst~M#izr&K!k8&Mp7a#HmxZJKvvhbPj%bFt&^=4UE+N&z&I)6 zsKSLmIC#uV@#P?TfnkRMu@WJ1FiB@h0o5p`VcmR?l;i>~#*pz=cX#Uru-M!KVWaf9 zF0#S+y3NEL^b%p?OvlQV{F(ba`?aCGioh?grWXnz_!HRvuo=mwdDao#%@e9yu1V+S zNhF|pFmEa2ZmJXw8*pI_)csbl8}^`%QjoB>Igqlnmi<Kg@b#r>WJk3_vHQ$Z z>Pv1$bl=SaF(IUKA)|dCqzV?^+D-QR! zSlfT+zZ!9l&dyyc2N4#C!m5q!?S>h776N0NvyF(;);rcTKL?m9W%>GLiY5vcr-Jgf_=Vz{W@h)V-E10 zKFqm&0LeH~TV)^&c1q%TjIa zYJxgyP+!f-cD8n|EB4`PeBi`f{daIV)d&^5Q93@}Y*6Aa9wYuPNac^86YcMablmp$ z_K4DYH&{USYTfau`tKfqzflKrqCvq9C{(K|EqzS{=N8Xtt_IRKQYKhN`&lPFj8q!( ztC>%Avf1@h9CCJPLYpB`%Zs-=!4M(&Y}nCjoBH zv*@n-1kd%mq5!qA+S5qDAqJpuj5uNNP(4LEIj_@qs<)VXydKmoN9{xj9<3y3kHn(+ zpLmp?szARaBv{A0y1AJzd)9M!^oL;35@xS6q+u9husJm-$>PK-9Lp-5r?1p+)LW!l z|FQ&~PhsS;l= z3us&wCgJx1m_)7sEz-pz@e-Zw=kv7-UB8bWNSXITULU8ULy2{Y0_d8G77nyIG5$FL=s4a-=Nj0LM+_QIS#QpUYiI~UW}lg!ZC?3;{K>oL#6QsMF#*SJd1p;e*H z@HcMmM|WkZqQ8DmH}_B%LqhR`TDH49nTH$yjs8X)<$iA>8{~idX9({eB5n9(Ie)>dQ4 z@p}XzVmgP*$u@vrIpsl`zi2YLyfrVd;(kQTz{b(eQ3(AZLZg7zt#v&4lFT^nDSBaa zO~MB`QsZN29*r7}LfDP1KrfL@Y~FBNgc>4_cUY;_Les~O_ojG=QBY7o=I<29+XrYj z074~vCc=n?NNa@EU+gt_VAbiY%R6TUg?_*-|H%m)_Bq!j6PqONbwe6loBc5M_`o5) zimGadbp2s3A6An5n>X@81%-v;a?6r@06_keR~qHBjyH;m)N$3;R#qkbTMZ!pJym8G zVDNyNS|jgJX+yZbi}lPq-H;XI`)yDMT1`GE>nVVKdQRYU+8e{Mg^^6){(Co&Y_d+on-sQo zy1y?hBuVWqf~DQt3!uPDAs2%un&ZE)uXwE&#azWdm|I$Yu-W9{6%rEa2?juHAlIY} zWd$CZf=a;GdL;B>x%)rxnQhTk{Il|sBCjNFYa@AW7 zKM&J4K8TnCUWU2Xqn+%-{2mZDtu^zT^DSvk{H=cVc30UnmM-L+ES{1nDq(zmwBn&U zZmcFPSPJC=*t+Kc zY_~vO=aIwED=sRMlSigHM@H$dTQ#M8F0>ML#L|;cec{TKA2-#;m4DhmV?ZFdM^Zx0 zNw0t56+?sQ{g53a1X=UZpf=JrkEg&*u!tW@+zAa+QLt9^P8|GM#>LORR;9Kc|My`5 z6#><;TOkDMPZ97QAVi-|hkNyFK|^%RB;ON^?5V-Gh%6MYUs-0agd%g22U9$g@URNE zYLC-jdYz}(m;qV06qpbrYtE~Gu`!>a`^b9(+kiW82wae)8fW!$NIez3A01kll0w)@FuMdMD*R~x>XuiJM7k_V7g$!SA+ z`a#{27pre^4&tp2hj5^yCy``ybo2=axm&{Xa9!i^LO2q|!?8zp{LEXVGH#wDP2$VY zU!zc#uY;geIvikVE+8Bfa~`#>hr67fEm;i?gto54ZJ;3p{8~ha)UPOnbbRC?k-(K{ zzsJb0@XTHgAy_GJQMC0c>j&^PANm_8V;0?Hyo}u5PBgnlBp_cR3-Y`F><0e}Ibd#_ zc=Yr=W9w#lB(Ea+ll%{S)){dd`^DV(si8uB*o+L(yn})Ox(+={vEq;tUIIH-_Zjk( z)`gdG+?g=}I>zIsOf zgyE9i(uk4u8FuRLEOhI>xP9YFxzD>SLy9`1Ynr~tiffOVo$hhSSD0Uyi zB}+|xFz=y$c|2IMS`ySwKkm?)!e9omZZc|4X+_k319yb2YD02vuA2)%KWjCMFRriG zWU*&CvSl~))Xs(MEe=eaef@aex*cFHD)wpOAPjK6E&+NLMDQep&R@TZE@R$g%ZWGl z;QT_bQR1ixYJFT`<&i3R)c4^B<1u0+vEVOk()V+_qEP2C+#!Oj)ccEMzm5xU@+A`^G==ov2WlWwC22CJspp)Uq5!XrXGT0-J|=Y2~f4nd!|v*(2DCXO!mW+ zk9|8miK0GEe8IT&E!=Hp(@L1x`IHwm0xC8&y1jkBO}p&Yxh2(-JMV;dA~-T5o)RpZ z^=fadFW46kuS_R-pJOp|Rb$Keue2DAcw`kjR|h4$Lkz}CGO?Sy=FIjl^3hi zku#^{(&k(pY6G;@Lo*XT3FZqTemGedt&xSjyb%+1zVQ}CC@2sFOp*6@Nt9l6#BJS= z_KY+w2g@QbAmC&BuLhkM`@MN#PF>G>EoI$z$PWlPkez^CW>J4`z(*49bZ{@lNmNqg zwh@1gj<}osZNAbXf60g|l|)HD;dhNLk4C3?XsGg0bBYSFRwL;U;aTgpFyVr$8*5n0 z>^as^#3f`gGgOfEM|GbvUGa9+yS3#_y>pFF^L%x{)@hojn47`2myXSavlRB~gvE0C z1c5d&!5L%|z9gfo#X*8-_NgT)d#(<)osVrV`h5p zz$1Gy?rjBYJ6B132^ib0y|lJ1;Pg+G#6CUlbgStgt!T3nq45URL0d4S$18IYtuOh)YK~AW?|rF58w2i-*o>F zx`Zg!;Yog}e@xaDSKl+*EaSDY>Er9$h_|$Ob1~K+!DW!|9;TfIu_6U2r_BVr2t(4O zL$RO=5THh>ADaxI48*pOBOOA|$W+*GTl4Dgk)rXQg9_!>u}Pur=Op^LKwztu#Uv+c*epvP=z5*GxQ`k@qZTIYZ%jf_ zsO&k?y3MRX5#||4g#vlunxDEK+E)3}n%kvFxTr_x)YyLDH9*Dd91Y7noA7wu!NSmN z6iRMddq1w`IiaLy{(S1u$CN?##>jdHMadxavonLU#k_?BZ9-u+Xo1S4yj$bQ?pRq8 zP(nnIb(Xk2fT!RHfC@oQyq8bCmX$UK75n4WNmIa)W=D6)@R^~g5-y&VUC-pnD50-N zBf%>cn%3pe!WrGR06g?f6x^qj`!VXUGdlNF0d60FiLPr903R_(m@93*g{Ee)_Wjc( zq@?Z%R?M}^^>POMoQZCrGvqyHU&&>@{e#7*|9LzI%7((n$=5}<ng_sw28XQQG1l|| z2HIjvi*X<@v%fNy;_AHqrh7sCA$IL|$B;)Vm)d2gwFcBH-)rGqhd*sOr#r2sFI@ZW zrrgGN+H#`Qs|DhGmV8tGE67n?q4uXB58nZa;5OvFlR|7=|hKMAk%H(uXZ+doQS3UVj<|lY5y7aU=is zWLuLXN*`ca0PaphtUlEd!bZIX)=I4_P_&L{`ZI=&^$6fAH2@YBU@j^tDFq%QKBlD= zT?eJU;SUQ3j8t`Ay~23#yp69-27u{OuoHS+F>rR@o`sY3dnY$l$6;wmo|Wa6Y^wp)7y=2N zqL1FvuzUX%f{`u@BgmBC)Kt&TR9%5nbZ?Lj+@J z{m9}2Pfkt*QRRF1~W^!L@3;MR*ZQUuM1XFl-vH%Q$T9<#9Yw{>gku}yq=ZhCR)@Gwbk% z+Z513xK*YogL;bZx7CdFgIE+*HgqLDWKm^3?*3NB*w#eNoFy3co1G7hdR`?E*}CiU z*e^sarN(MEASIx2vNQPHp#pF8*C&LJL)ZJ`S+zkSm^`|UY4>5b@&;Bo8y?E%8ZqgX-) zJggegXl7%wAlf8jFd7|I>`N?(? z6~7hAG?J^ivGGKO`4sS_n=M|6iHkROlt~EyOj>{0MzNB*o)+^TGZp&XF>P&apr|vj z58h>{Bb00QSrOn?o)6>O83!PvprZV&JItUjIW&=xIT}hm+1^E7$?V31kNMzPX>9H6zQ0Qw*_Xm@?%Zo91W|dE z@NJIzq!$Z?0d>sES4A#&j>2%AVr)5ca9#Nb-El11%M0pyF;`wq3}BQm+sjz#T_BG2Q+U0#IOe$mlqe4{e)&fCllR@ z=x805HbSk9b0LhY$a-jAUQMUKhSBV1G3X&$-S}Q!zHjf8sfa>?2=A4m^|Ayb#p@cu zO}M#VO6oxfKCUpHU?W0M`7j~T&jgF=Kyfp@(>aAl48%d+7^K`#L1a`^9i(wuQLHJ&AyyNgc=GC zPzE8Pl!g-m>RvcvA0HpBFzxJm4TlN+7>HpRFFA@1H!)a|UK`@|=QRiKNb3X{@MSL) z_Z@xp4g50e_fAimGv?RFIj5hjcK>|ebflWc@nCzCYAAS7yDxrXcb%o4IeY_6ogto8 z_d&&*H*bI`A>&!)_g33`j{e6mp(C%9cGk<{G2I05YX@s<&m>PhN_~)#&d87LT~|1^ zeM2PUBlXU$oGy}w-A%hRbUd^Yumv_ANmzh0=o--%rJikvI4tavZ_HC(v?(Ax7sc`^ zdt(QE=&IC>X_gC#%e>Oqh)9;sgc~_V%YyX#0*w8#NMl&X<5supw$2C%S8gtM*F4nC z*REL=R8;)8jAEWW2X8$N+lO9s4oaI|!xs%BTXGw0F@^!VDN-9~4GG$TpaH^gBo)MT zf{OPCS|~0w0#}6AaU}UAjx{<@<&znYHqmOHw}`mw>FZC75)$BdXtA)kEj(OdJk|$X z^HSPWR3K@$gsDEoPg*-_evFh2QB^Mx;CMs>bBmAJ&}8h~A1xo&XEPaJbWt&A`# z-yhMkkhVP*3vlcJv?pJ`nHLecA5(oC(RP?N^C)Jww6E}BY-OkQbI9;dZ2TGM^23q# zSH@Xnd+!{3=p3NkdG+%@OG|B5q#u8)^bgwzj=J?KYp0Gzt_xEV7Z2xxk=!?dzkR9zwf=O z+!-l-^;zDz93e*HCfe5P=rq*-%zTcvLl>tRxivntguu!jBIe3EhCK#iGHoT8Y)hd> zpKnz@^V3d9WHwQ5$SesxY8@~)!zCkg0}N0=S~Vuif8j6&ff%zKwGqNNyowx8XsI>u z-9WMvJNuj3n{S{R22`uW%eKjFgNh5_^La)F(w|KN0fMVO4R-GruvTSA@!T3;!(yww zi9A1Mowoq7-F)jF7iOcC`AqdlcenCAvffV*p5qFoXxy|PeD_^@Ww|{Zdk8mjU2iwP zb-71sE#A``E^y%$3Jj*y6aaIplV&sa{=-Br1O$nfn3>jA6D%bl-^d2TK*sh$IK-fq z=7YHzuy1m{pL-h^A%&OID{XvTN9#d$;l@x#J3b*M!-sbOh371*C7BAuplCu^1d8zH zV;&iwgV|I?A&BFDTa2qm&ieRf`@9rjoF9^CSUt&-Pr)n|)dk?Vls7|CiL=1Wf8ne( ztz4+qDtGgBT?U{`tqz(E_)}?~R;_+9b+lrhLN``mFRce$P1=$@nr9%xFPK~5eWjqQ zLb80@yCgRKAa3uZ3ol~CX;r(A=Z9YE(mW_}s4?HH0l+F3#CoMF2A`0ot$a&EfaiLRUk)nUC0Q5yAw@h;_{hpm9PvMn4 zymHR4|Avb8F$M!5W;c^@AHRCv~JE$!{D;un&0QQlUjg5=@-@d;q8TeNVP5$)?26one zy@KIiC^Yee)q6C5J%0mTxTkdg|7h{YPfPyd|G4Di?j7!ijD_`|28{jRN}+AW3)Gu0{z=O)UIo*fYz zcJyUz8=FO+`Bx>7^J_bqE8FBM{C)RoSnVyoT(Rz5F5XRGwqit6#p$;#$Q&X#JVib z9*Ok?K3HY+6>D^=gN1QZ=I^u{d)J3}-y*T=-{ddGeCO@0U8gpCn8a#hq3N=lZwzJr}BJ({aCTA;c)75(Y?K}Y$7SXtSseFQnQR}m*+6P=0mS* zR#EFB<<4x~R?dX+M$Gw7MJ*ZK)kyZP7WV z1(3B$xstD7Z(K`t_gV>YV~vRlVv>?Idw;t_aJ6Oe9}h-)>OtuFf`||RB^9a^CreI! zo3b*JV;tS$b2?aNbq;-qjL_u9ZOcfGFA92-9WwU2Colk@PhKAWtg9-6{+_e5UaACqr@VqC)tWd$3s%byU{*>CMGj?8{RHI`0r$>VACz;GTfvJhAl} z7rZ%=CGy==JzXtlp*2C!`}O5`x8auH#>e*dZer!Z+$F?u^(Rg@ctFo^d#~?in74o z<#Ob~u!Vy?i1ag9bDDC^iFe)iUk2|OJH$c@d)3_%GB6AH|27M!)?+4e7USX~AQXM= z`GOMrRw!|VS>BWkH2db~(tok}J}Mq?-wMb7$8M`_c0hpBep~Rqrb4sMncTd4w*7rR zPn9+yNE47aMS}Buadm5@T*F^z55`FTemMKxSpE0COe7DTQr@tt8x1EXpew>#MF5j_ z(|WgQs{q0eftwZ~K;I|5;rBx)W}A*wXttcG#{Z|QT<;yceEITZRaieG&Y$N#SSg0d z(L{Um@Spzt=hzFDJk|^HyIbaYg70Gq-gAn>z1#nc5BSgSEo;mD1ZyO@?B8y3r9Axb z5V@sc2}IO{M~#3LO9dB%M<*iF7Yj*Y{|XA9MHT=ON!`1CfbTAr3=RhQ5YTr~5#S!i zHFnW?BK3L3x-82j@e-$HtCs3~KLRKCd`m9Jn@{kP`9AcL2mstbY^RHp-&@#~fDFP- z#p<#ibb*5MPKIpt9CFcuR|*_;JlT%ta@K-%Z&&iK-%R!7KtfFGE3(-H+?4gwpRjd3 zTYR^#$Gm`t>H=b=W%}I&I5>*cb{ntLC0@#YiL{uh2B_9`fH47tK2lRtEo=ANK&&Y0 zC8ybV|5sseey0P4&!3;jV3KgkRuzDJk2jy^=jTB_Q@PQAR~)d-a|SGR<#2FtK%iQZ zDM}kWhoGjLx8e2%q+Jh4QX~m^B#$xxggi_{SZpdYR#O_p@;u=X1p(&;h=$~H&=%ED z10>0ow?!J~pb>xw-VLbGz?1?G%?g0NUscahEG3=~+@<$93RIi%giu#&z-wkw4Aq5<>{$SR45@VGvX71x#nT0=O7M(QCxgR(53?0!iA(PVto zi4vf$D*hR;zN36}SWheUxV_P#)?XDlQSjzXC?v}FUIl%uLvaTDCA1pcqs4ItSeS|KZsiOXB zc&m>A4i`8qf~mB&P!iy6Gd%+NT*5to57Bm|>j@*m@5WqxuwLO{a4f2yzGDNpP4yD3 zMnD1BDV{S>%s~rK!SP-`ef8z>eG*%0CIqL?_u(H*SKDs^iV2V^R{D@p*)wjp{xZz9 z70?_lOIJOo?JB}%U}l$T!~>KQ*kSqr$TTezIH@{rnX8JK(lb@I{%V+{+?0t_#Pln_ z*n8TsK<7di?6gUFmw7oqm6A)4e4&|Xrd3wlYJSfIN zF6gT2b~}y$dJ6wXf6pC&XdVt<3s6bC%b7g6(1v<54X_W4u0Tz){t}48a_Y9BvvG?0 zp>K?rrr*=i(P{Bm*%>zwrvLR4mWZR@{j}Hq>U=Fl`e!_k@pNTrPXox!$(#ov$iQ$K ziI7iDAR?YQnE0$l2jI_hzNbQn#CqMUo~!u86Ko01+;NG*<8~z23tN?w{8K zz)TM!TLiHWvIESN(TRGu8Y8^ZP<}v92{f~CSkr7`B9Cnw&GmtpPY58OeRkh)RScQn z+#CV0rmDMMZI|_Jj}511+h@q*#%In0fGGMkz@J$3EhTdmpae-9fS6{QH5j7J%l4=L zCR{FKcKcJk$Ej`(x*?cO&sW8Ewm>XF-eqcec^Mou@Uhc!7E8Y|mK)4^b=gV?Rk)$t znkfN-Ao>MrPbVM*Yn5Dy$KAY7@g)*ui_yb~tP6fJYgB$6uJyQe??fkJdBNd+_>1fB z4~_j0{>+lq94y?oZ{LE=&$QVS=!)adAJ`!Tj^XFN;984r1A)}?y9R9Fs1Ko8KNCB+ zMi?OdArwNhZHcg@an&298Y8*tvk25u+7kfF&dtr;;mlsrPxBnGqrc0_13ZvMZ8n z3uyd;-nr_?MRil(F0qt7vONIepOnX@za5};f_A>twu6QF&9KixS8f@D2Pmb|KE@_r zp4@i;*g1iVg5R;f%us$ngt@mZak)1s;j<86-UC@mX_+7u?;uz2`L!<0#KOY9(@$=_ z-L&tXwK$;!5o$VmIusDtuj+xRT~s31lah{MBqk-Du5j5B1AhW?K#Z$xp zg;|XJtp92K5nO>TlW-Ve6A(zabb`b*Nl8f=*-)NRRSLC0kf4WxLZ@0X4^l*u0qY2u ze<0Bmo51|5yBf*`#L^P`1WU#9q{e|C6{LdCmLuhXazGf$lp(zDs4GVeFt`^N0iZ87 zIe9XxZkr0!O^H8FS62?e0SMSEOL@I~U_TE8|FA2R`QP>gzvF6cXo5{g&CL`2xlN$R zYa3u%7@?^K+j1ACc+s+e;%!PK1^b*!8+6W#hr77rFjn6?($#&u6N4|1e&>&@1B2|*bw}J@`@H9?Y}P4;Q10z z{@|6Egv1We%v$e|5#Sbvv{s^EmdBUfi82^YFXL#6%FVntmXQv?daiRh<&^&O9(PU{ zza#5DPy!&YA=ubh?ioycEO+8wAK#5b@}HL>#7zPCL16q^zYit?QK1F2&c)W<8wuRm z_DGPYK$h&C?d!4@a?pm83sgJqr`e$WQW&{5xL*TuhlPRd zq9tH4g5+5S#SAH6NGX23^F1dH{`gFqG`1qR%kr~MYh?0w1I({}H#o0)Obz9p1radi zwf)T}1a53FuSZjr2W%*lvx)ZR!L{acjLIH^H6JXaorhscvytSFsS@Z!))Uy8B(yLs z1RLhQH^6g$x_Zn?OAz}vH*oA%qH4iS2Eg&n?i+n163hkc$=%0E|uUuz}G{;4uE2m}pk~ch9>iu`)DMCe~qd zcmwpi>2G83;7cUnN=EzJD3F-S`3M1OvLhph-fI-Fzisz`%<-|_Kbf*5(UAkP^}~`A zh`B}zu~yT9$y&T^ir3xG8TCZM64b9<0OQ?}(s3z2jIeft03=r6KYY}dMA)}Iy;VY> zE0#Kc&Cek#E#95)xz_VnRN^m3cW#^2<^v0te%AfcT(svUfUpI=v5rpK|L~1@2*OS7eB-wNfBD8ofHwkAg6bZJ z5-_RNp06fwZBw(d4y@mRkU+pKML{BtvNL;oFd@XOgxKNT?Y8s-z#yRNcT(Q zGpX4DUHm!Kxbf;}Nd7S&ph5$a2zbKD+4Q6|G!oTUfu<_Gt$+IfHphRQ3D{6@n2v@x zbOCY>OlNX%k_F^FPTaJ=pRX@IouZiRQ1TJ*ZQ$0YeiR!$?o;^s!V|Cx1p(ZWaMXF= zQ|rm(M4TK$>W&m09l2lm`}vUrko3A6nAMq?@&8cw<>6GW|GR0PB}EY{6f%=}SSn+} zqEwQhq)dfSAwz>QrA6k5B1Hp{Qjt|6GZ87tJVj-W#j>3H)!zHNzvrAke}9~_uWMh| z-pg9=`@GNlJfGqI-1q0viwYhIw0GUvL90u^q3ug-_FP&w+;V>Ki%?mTx*ra&DjNIh zOcTGj>&kND6^Cw%?0*nA`$|eE$#=^B1ML_h>Pv?pxv@*P$dlhFuP6NJW-=bzDGq{< zuYOh{|4KwNJ?stb&dvVH8)S|{NyVhwB68A9QDhy$J4VJ4{F?CXY5(M##ZzIKE&`G5 znCN=fsWJPe;)n)FRH&v#c+bURILi4RHS#`&H5MM7x_5S>)lX6;|96uk&LSl8MC9ds zW}h;xoQ-26D&w}ZZj|Z5SCZ7uKYwy~ql}HmIkrej0b?8NIa zk!kU!!Feet{K*13QkBXQ)$%_3>^s?7U?D4y*GLxJx|L{6g{Ilz_jeM9b6-HD`k{n4 zo0^J5isM&zh8)yP{2n*g+?PR{I3YQ)!_W0A&$JgVlAGFntqliT@K54|9j8yXO*o3L z7o4cN>6(EVwUA}v$b+%)M~xhgr6C9K_Bq~w(xMq6CA2Q*W;Gr`2HdEug8K6~7bGMP0ixJc$S<--%(dkpD;rR=KtM=i56Md=ci^6SQ`#jlj=z z_30l^cV1o$)F2a}&ivcd4qAuoQZ1ZIiWoSMPu*?$_o?C51xr?!j;>sl6p(M1jR;h3 z?`U_0jtinL%q7o!%sBh9GUw9w%$ezs_qa?@G)}8{1W*u~mNCgXI#R?HZCG{dFT8Nl zTESlz7b{`$D)1!;xnkTnbwct)PVFcjbXb#(PjEITXt_7Gz9Hn&3 z(1suujbmxs)h5qR+nc)l*(@HegE&uX-y?O{IO|5r{Jkd)o1UY=GM3#q)@1!idjLsU zRtV*WbA0aw+(y3GCY5dMzO~(F`uF~_v>&A7h(O6Z=EC)f^^#S)QN8FE=f|333q|UD zm+H=tAm0#TdxNvCPF3!Pni2Ou&IIvnHIMSbL(a0PIUvQY!av!G!Qr$68c!M6wEg21 zc{&6-Gl};VDSA*sM8u&qj1LK zeOcsS7F$!Y{UZN`s~yaj6kkU8-Wr1bdWhM3oxB zPa$(t^BU77Z`R232vK(13+?8xv1vM1T`DEXGN*Kf=H?ScOM36)2RRWc^~|}_mV*o&-c(#Y+;GsUDstOC0G|F;w+U=cXgOZ7 z0GIs|GkgXp6A)eF!-JF`J1Qc#X&9ye;I;fBks4CA{zsR%7#*5+){kwx3$w%c;B z4jMHP1cJua3=5U;i_v>zipJud3$`U%9XMu4rgyOqhadP2aO7?fkeX%B>g!T;SVIRyJxeTCJMU<#ck7hn!wCX#ge32_s{jtNv z%wI@V0XxY6UdCjM*6@B8VwV9Fi|pY<&SHZPI_>&m{gq`ALX@;CvSH}j)1f9FxdpmE z;J}5flg$aZK-j&q;-Ex67L)*-HhM-G_z=Y&@`pcZCYtz<9#)swkVK?v`Sia(oI}_1 z|D?Doog}h%Y*?5JP+1UlkuciAy0rRE{{*Ovl&1FKLCKl%v>-g!!3QSk4=Tb~mw&%q zaxh=J=PrO#cHrSM$ID>>(0&>X^y^T~>&J}aIP9PB1n8^zOLPY2ytig9YStiwIgX72 z2Xr3169EAM94pcS7#r*nb@0+GA`{3fTYM%gny%EA$e(J$0l@EfsI@(7gH5o2 zIh1~lsY1V10KLq~POA2I;{E)oLw+3v43eT9suv+>;O_2@pxurnb%Z#IeP!(eOGhRa zAsodGQtqj*#2MJu#lckxN*^W1kRG<2M~Jv@1Q;UkfGV;r3q~U!&7na=ZJfKbq@;v4 z{VNX(m0eKZV`?n@Cg!mFsBB* z`dOSe&(2J=hFBfR>80Tl;%8~bop6c`22>8!P+R)bTJkbux4tzeFpt|l;Pta(`bLMj z;v!JBT1g_ChpHcKQ7``tPl)%CoSa-VSonFAl|;@*<-y5oa)|!utqv>6mspc#&qPqL zg&|Yy+s%?0u5@Ra9Mj)#_5!Qv+%<_hwNWP}c7hrROJ0x7?egJWFmc-Vzp*6^Ch99# zTE0d`Yi6Fk{C0`vi}JD774`O3^|l4kwp-tO=ilooN-j*28cf1=`PeV(P_N6#$!Pc5 zFajTdnBu~oDj#ke-Ftlo;^gxukg7ahlIK5 zBhxIr2a(3&9cm}(A3l6w6VS%dWGAW<;x6+t8M&>#hcN?~L0I-ioKxNN3}^r#h5tOD zax8nu9>2mTeg%^qA?7b#fvFE*DQy~a>4_0POdLFhRKXX~F#vr_Bt2PPjKEf!pI^Xg z9=p2+35vrAzpoCQem`);Pz>38(%=drm8vWmIA$o^SK4$(z5Sy)_RcM-qq}ryD8v73Th5ag0?OlV)FcccYv`J=V?2#!g8FLIV(|?XsBH`Qq3^QZf^t`W|4wyoIb6 zCAJ%u+UXAh8pIX4D4%_C#iwg=Mata&U;CK^llU6j47OzkMnI`=Sh4^WdK@{CEnHcK z34sAS70Js!q|Tf?hO;C9okUAml<%Z!S-DwfjS5xLB!?~nV8A79=RVLLuYvzmKKE-A z8=Lg`-zUXK;uHNQhmPVz;Nl#3e*2I2d`7y0m|m4d2-0%EpFo)qcAN$in&ss#FBI)J z%}$#vc(X*XM(-NkL%eb~Skzz`n3Z_01C#j3+e@p*U#uFW!{R?i$u?ClDw}rx;~F*J zawHhNFe)4$_1vsSLjq2YkM^Q_`F5lQ2*k#JeT&b}G4}FyGK6Q;ERmGxU!a9DQEz2j zrxA5v9;>Co+`u+nfEK^XUeg< zSrfDg9Q6^36B)<1j|@_Vn5C^+eY{u$bKDTCq(7_#Ro1!d6DZU+s;T3K$Mf&(Mv~jQ z#%(Ra={=fAh-<%HSlZ|ETwv7Bk zTBViDnPn}q2yS{hflQsRd54P=5kVpi#t#tJ>)xY=`jrIhqQ(j<26$D=DDiUw#_E-P z@2v{#VQ}t-1RgfZd5nw#eg1@MWl+!@SV9kxCb7EBZ#fTGqKNqN5TiJjiaQLd5py#v0ZP)+_%g4m-~Y^T{%`aDxfmhCwO_27di)!UTMI*}P?UgJ{d3IH z6qN;Rx7$zZ^wg#;9%LhG53hSq6CCkih|LS3J2y~I7R7SD zN($L7)YA>z?SvHxb|b~!=l0YwE0POvRMEt!*f;GFH*Rd=Sd!bmiq);-zG~&}+ru#H zA8F)ftfZPC+pU5w#M12djE&eqtYcJm{--{<%IAk9b+e;;e|^wp-dqNpSLCHtjSGks z?Jw@^;Uf%Xjkp>hFW&ALx6=a@f?Ia9l-trHd{-j4a zb{Y1-(F$%$5>UGMDBG=9`7(`%cN-e|GA2(iAA6Iqa5Jl0VYEU%8N?6;QCMqZ#-Hx} zNUEQM=>-ss$|a{~ojvIeNDgJEQ%yO`SXo(Dt@1$!1>j7{`q{9Ri&t?Wb_%!=DR#*9 z^OK|H$DcWUyLkg=;w4g87b! zg`c+qT>&T*-W;-14ZP$?+D>gz(Y;%@Yym@#6PUnQ#08{KFMm-uS;&j9_p?-cr#7F| zMy`oiEAw27rx0TK9KM5(&BkM_d{3)zo~lKtoNSIa9`@b}u3B~g)^wM-tFhOc(fya5<5 z@115VB$7u=~ z?NZBkyEr0<14 zyAzERGjJ+F!P&B3ba0xK&jo`loapKEM71@nOy1<-fuA?!fK#f4KR_;@(Tjj_A8tpu zeT{(C`!g*qDzz>flzANDkM*OqDS`FZS3~^Ky7MM-qLZ6Yf#xYinB1H!OwQpG5)@p1 zq@yS(**M`f&Zud!UL~@Pe-_y3B0`ZQ9nu_(=Xh*MlX+@K2RL&|=BvM~(5@$?&H|s4 z(^LU_vx`$n>i3S3{%}K1JcyR@Lk6VT2~^@+e=h6Lwzi{&*E-@FmxNer2wH8K1cOOM zR@UStUtX*uK-6SH<5L&>S*m<38(zI}&=Ka$CELPQtLEeuF zbzDsHf4GjSnL|JW{Kj@J?qWBom4(iwS=xn!x<3v>p0+tDnueq(n&a0<@Pc#%;z zF{#@&dNz3?RZh%U%72{AaaGFxh1NrvtkxPh=rtugo>u4NR zA-pkissC!!3Z>iQf#y6Hux+&EX$hs_z^hu}j1}sCGe`JwUS%aet26{6DVDUGmGbRF z_B`Bgqk99i0C<>Gi%J~c7r3u{?hCZWE^d!Sw@&j)vgbdz1VZErOay+aofy6#E$oMq13*eG@6f*k|G zlji?=Nfo230QXnw6(AQVU-jjSxkF`;L6FDy)R_MoLU%(ulD)F`I7AW$dpBfQd`-@n zELHiL-V?|Gn`(Ubu<;2FanO~Xl`)3eHHPyxbgbS_t=#=#bWg*&pr9aBB0!iJIVnr< zNc84-BNF#aj|XU*#_U-B)pm;cU$zjOb}MMiktd@972x8BQLu>l8tk0H`60>erEiF_${p+EB@_6Ek%I zk;#2w)?XZyT_Ri@lEKtU{qX=9?A5P=PZfH$fNvrpkpX*yv<2-!?!L-_KKi9yI?-kU zS@@P%4n1omE2)+=g9{WE#E)V%FUf%lX(kU$wvow+*UfdeoGR_|E{b6CgG3`g7lxEq zI_>edLKVT2sJb_X=F)es4#QO%@5(Ibe9H9YE<40h%X7JU3UJ>OY|_+8uEuL^|(3G{Ec z&bf6d5eiT4m_wm>^L+&7%6touqeCdwYh!^3+)1yP1^kB#*k zF6K-p=cA_>xy%YFBC=i@n&NHyw4eo3gD?vcT|;gUEHUpJN#(28C!r#D*AzdWB7Po~ ziA2xcT~;X=sM+)uzdO6GjP%w}mS_Us)CZxTiNfW=bp%9+&CUUOyT@<`xvUkARD_IP zWf3&RAK{?=uOc#=t(2=a;7}k;CjnCBcFu42VFIdx@~i;KRYkOT1@K1jw$$o6<<&i$ z5FNG+;jqAa8dOj{gB9N4_V9)%PEoc7iY#te1#v(b05*=fq$edMMIFgGgsE`Q=sxfo z6@ivsbtuhjY`Rd2IFGv5y@mnf2$CvR#TJ)I;7Y^^>aapqzVz-DlKCz;+jnr3Hc~E% zqQ#1+%_5pf-XpuAf$&mu7y-Lw5mrFiBvSKL8>B7>V$>~2$8mxRhS)OAKn>OaTVB%q zg%MCQ}>scSW_1d@Lb zG&&=0b{I>mWNi^nEclcqars)BuOBW8AT-VV+0%irf*q0f;{j-VcyM&!kx# zG7Mha76VRUqc%hu90T@W;S%Ww)IG?U#?3=O`+t6V%x!>RMY}m)*`@6bg-kD+W@rVk zd+9OEPdsdLca=gb10q+80plc6zOi?KH{CAGyDiTS2{xds&>cR+{g2RzLO^$n6^FP9 zN1Eb?BD^rTgzrASr*oGXocmsP92PfOZOfLTJDuHM)Z5fLkayOE95yH#!_5J3Xs~ZT zQRy-LGxv2(5<*~jr^AVP>uOE0AAwd>Sxqg;*RV8SI3|2~AXdrk1Z)cU#i?~k*rc4Z zz}$hGmveX~Yc!Yk`!G?R{`EDNdau~REqMl*A)1j)1o_S-{2xaNQZ*J^u{%Nql;I87 zv2(Kh3IrF?v5W{d)Xm$wG`n@5?~6k$7(GFM%UujIx81H(^@~cwjs?I&2tIYJpxZ8v z;tB>#84-Tj2Q&sX_p=P1!@TYo9%0MJk+dILN-7wL080@q#NNX-OZTa@eHj5f2$Iiy zw+&GXJ0yyneiN#w&eR?H9eyZxHt>YA-U zcW!>cCm|Yg+f`F*H@<-3l{z{Yiit3mRR+zDAS(k(UoS!P=rYP5von+6f%WcnMrO%I)bBVKY49ix&+-=?*}%X=+BYM3JE1~5%b#b>&J~?sX9Im2woc{h|e2C2~EyY z2y$*_NRC!dSoy;GgmTH%?W}?8HqTEFIyHOYAW)HoOIwj#ko*|NOVmtmrtKg`PtJ#K z$GVqt#E=nwu%KZ7J~cnaa0!yAGz;IMtAI&Z3T?|HzoRUx+;^u=bCDh~v+X`khRo5V zSy1#oo!*G#N8Pn6P(#gWL684}B(NOt*!?Lw4E@-%cymZR7S8vB?ikgJ?{w>4o{gi zX9-5gYkbCxE+)%#>&z@@N&F)mN+Q;j-!MuPs3dsxhtsk$jD3gR17EuM#)c>4eF_j1G8#BIPBV%c`KowFn#?T@8$XXXI zy)|wW=hYo`5Pz_Agf5A#@tjHZ3ODP`eyAlP(;CRM#eaZCpFvD9n4Ou`g6~c6tWk*!+r!C#EOC}MOtm}N7Vwe0nfqL z6ZiDvlJVMaj(As=A#nk@&T`efb`zMa=PLGkE}(SsphE zN9-%DSA+FQByhyof-yD)D^yTm*tk;zyxG=E5bNeTB9crQy-4BHZEsjo#u8LLv*Ce> zHL?!DloMH4xO9h_M9U4EKwe-eA7dl(mWm%k%!-1#+yMeSU`+Ywj zWg32iSQUJ8fF|&2LJknxpm8OnJO&T#SQOt=88ji~!5I!Iiux?$qp2D^Kwo2K68=iS zh2mByL%`5*KMYvT86`xR-||X!QV@Kgj;2D~8quD#D2bbUx=bj^<%33dNHDR39f^^iPet>D31acDBr!*Id-2M9pH$YWdzHC{0 zNgTX8zM-5lefBCB~q~u_zxNittP3py@nP_zl^9nqLR^*QqnPU#^q`s%iv97 ze)vzWMs-7D7-^a>ielh6Pu#%Zw@S9)jA&|itI$QzlmGszL_Jpq8k(x1 zYO;E85;(B!(OK7df>WrB0{5olhJg00$;<$fuU$*N5=l*_OEf+fA73JdEcV0dVX3Bi zgW3aMVz^f^T#`DX5y^tdOH|&CBgY%{$1a?ko9hj${lYEAX@OwdOGo@ z&ZD<7*(;LISMVA>t|ngn>UZrFPnlXj)G1xN%ZF%Jdu?H}^oa@q1K}+&{8{ zoq%lw4as{Qs=*77Yk{_Yi^ZI|+*~=^Ki)o;gc=st<3ghB*$rb1M44f=4goDRN~B2% zE;)xtgml1OHoQKuw8k1i4#JD8wIT_NqvS-K@a-2=aIU^P8zQxMhWZQl?DZEf6rB$g zwO>kjrm|v)AKCxDWX)w{uOF8mw1UQpse;mB7-qs#Ht%1dj#i5FBCj{x#UFFETX{%o zzjqc_wcqaelEhN+*FM?^(%nV{r%m{qG{i&%dkfRRHK&<%?XTYk3bI15q{XW-Pz>mO zS*#*XCLNP_0fhX{nN)pN)_aVk?4E|v;uSPjCzzT{LpI93*&F`=Z=CEq{n>Cq)KyU| z5+1zwwo}$X1i)v&@;hWxoj}Lfy~h?RW~M7;r4jm9p&gU>>vQMUL@KZCZ1P&2E7vie z-^AL8_rSV@uP)S~KDBGg`3@^T*|*Ha(h*g#sfbp;S&LL&IhK}Q2I{wJ&Mm5BuY{RB z=A1n#OY%`wnBOAk+FQ-T$ytJ*$Etd|f{s1+^ChUu^->fkC>Mr^qYJUw>3yevONyK} z>BECMV?$mz_#Pk?@DltqMA2jDw#V0H>}o94C_IWu%q;6=E?dZih6MOeZ%T8ABuR~ZAP;i9lWS$x$m&Zr~_>CYUvJlBj@l2G+GpuNd)WjV<n-}dVa0LB(z-3e!Nmb-X6KMt>p%@{>#{Zv}QTq z#uW(~_e1rpm#;6n%`Tj8m1cAYY=M#5&gd9*zH)5T+)6~vKdLU5>!K`Ut=NjHFf#hl z+D>`=SI>`hTaB@WGJ|ezBT2IiAsLzM>lM0)l~KXcP;;1{&q@cm3~^%^l~+zRN=3vA z>*ibq0d3DBpO>|-8>&sYan6TF&rgk|V!AoO=m+$dc@-Y;#o)^PBDBtf8U&>Vs6|(b z&Q^*RRgZ+}wpdcRd)|miSDyQKED*f{Xd}_#qb)_~h^KgE&{sP!$$qkf$6`ki%P06K z4adON@*Yd;+WmYicN50IgUGD(;g^c-^|RmaCu!^GjMlP0$-mg+{~&-+dzXxP1IZ~* zs;|Y>6N7o9$b_9;P2{|&Bg0@#_8HgAf>(}6pq;quv8tfC-!Pn(*MqI0q>xxLSCqOsFBEwqLb58m z_1jj8_?XNKJ#f*51PacI?Dv?n&`%vZi6FP()rD@y`ZQoEPQ>kq%nEjXq?SFFV6qp5 zUxy6az~vWZwgaf%5W+*eGB!#obva?dZxMO~f2BiDj=-gNt?q>84cgYRKDNKFGvm`+ z0KOA+D#I8HN{-1)&Q*#N_esNuY9)Y7k<_-erO(^Dk(iwCfE_=NAhb|B`(p#~2l&R! z9*?-kzU;8rEEOp5OrsrlcZ$#=)%80>;A|#U)Isn%J=0CFGhezM2ZvI|rgY85jda9k zb$)(R-|wfT35zr#J3aLLWSq<_CiN;S$r4N@uow{eA#?R35bE70^$?B%)LtIa?LCT`2Xj(Varo>1sL8#x@d*QWw7jRkk?ghiy@K6`BY2rGgQ)JT zeWJSmJD|3q+6bA%@;0n}%&ueNbG@ui!Yw0vjgmg5JuD556s(C4*q&wQ139KLRb>T* zb}ZJ;*{2p>iHQ)OciwGR^ab(_ZhI7XpnEN~UwR>0x8Y436Yxi!Yw8y1ogvJDOxi-D z7cNH~2o^H<*!FBTsS7FeZi?3#K!ufH@BADZ8baA4OmeNbgYVJcnwa8f5-L9M$E7-y z@=2;XGnOGwQe#29yikl%66OA;0-t+`T;`oIiuvTlxEUkCzwe$ts8XI_7bE`DT%p9C zHOQ;rlwe21$3^DgIH%ju!EF29iS*k3?35`Y>3B$pkkeix-w;nXPI(VUo22Sl2OQ|_ zH6E2ucYO8Y`7{>K2QXM_uL{Nkfn0DX&C@gs2GIZwBKK8*3Z=QCVbj~O{)Rm{VfmnD znLe^T=HE~juOOK^zTbASnAKffwsBfRu@Noy_AqK$XUJaj;nbGtGZApQmzL>Jf;~kp zyI+G*wi>O|a{twQD2D-x(R%TY-&=wKc-PiFIjT`hv~?2y^y1uLqFp*-Ud23qUu&pI z?d-pCK)OxXGt()w8+Fj0d zcZ2L8hkTN$jDkJaViD)94LVc>)k6ok)UiIeus&i{d5l*BGotc3PofHU-u-w$yf5fR zY#p1H79$fqI=HcDe=IV?GKS5b0>(%M^xZ47uD;0MHC&@UYnl*GNIT0DG?({0YqWGr zvr07k^3v`8_8I=iV|@I&_hW~l9OSs76i)UZVdYUakqusPOX3pVdxT%_t#iPssxcmK zAWj6g98(rbOc~LgbC!-yppYvN;pOziV2uuSc0^v{QU^+s$yd%QudTQ#C;AL!Ib(04 z5&#IDqf6L4J_0DSXpBTGG=2?tm=Mh_Z^QIgkA>vOJAY1t;59bG7Njhl~dttvxyew+!J zb)dG4Sw>zUoJQ?eO`6qep@z6 zmV{aGHMYN2@|+yHlg8Tdya58$Qyaoz zZ%FiVo4$|O(}_~y(G}>4?f`w1^7&=1s%I~#TG(Osu zQbM7xi;Y0WyzI8oon1CUpg;o=yd`MB)twp<8OQD!5#+I_jHqX9mm}&KHH##{e4p2) zP$X8D02u~MQ9R(MzAsPj+kHpb;mBPjbp4n>`2u25WoTY&_rhchU!zi#x6kt&x!CcZ zSCF{5tVrwUV=odf0HT{8=8X6ZI2aa0q90trdTp{7Ba-q(O~~ZUB18|oBiump!9Koz zG7ge(O69Uesmr~1JF=_^x$MqgYqXjI1D6h8Wmo>OULU>dtCQ3vH`o($S8cyy&-H9h zgICAXwl4@J{O#dq4#hfD$|TnLH7>be>R%&3&3pgv=j~qJh5L@)9VykJs*h~jE@ZL; zaaIBWH^<2|WLnKa)L2$lhEkP4%nigzsN+qSCm5Z?xh~+}A3b{1MkMX5mX3~Sqv5^K zkdOhKPXl#_{cZp9CH|>ONC`Dz6<%`hj_o>%sUIcVJEoid{kP^ZxaeJ%l#y^nw zlyS~r-B!KG&FASC2Ro1#>w~O{cp03>Dgls;ZQflwz!tbO{^?)g!Vl0YmImIo7y?v$ z?LhnG+l7QFC4D*^j6BPxBD$(iPUEf=8eQ;L2K`5D`}vH#?e*dmvl4&FgBc0lt+yy0 z=sf!a@hl4KC!NZUWEYUT5c}rha1ZSF03c>NIuTjDK)Dazt8(A|9KRp+6}P!s{vlj? zyz^{LR2ts9QWRQ7>#PFp{og6Ek1|>52n`_nyh%-b(~dsu7!&%3cL@^RyW>ktWPjq$Mi3onu?}Gi9|iMt(@6KOF|mLQtUU`9)K5) z?ZR!j&&}F+l3j3MMdAXW@?Jzj;rWXgu`?ZO*a=;nsfqK55eJ`}G~`pS%Ut=mDyaJ< zaZ5m@kBZWI35@fhIta~=bv$FosE)orK4+1SFPFeS0EB*FB@FX|a?{izZ;8fXu6_GO#K7B0oZD&{{`$zy2I4En%x1j*)9 zV(V!heE{1;siNQW8=y`NKU}GKWarMEkH!|x|MQ!O2xfAtp!;?q4pz(|lVz^r;6<`ToGr4xyNYP~|^gNnr&mhcmyXstooHj0)&KLGU@* z{G#>@FL43n4TrJu=zYr;!f@~K;LLNSeQ+j$4G1?taJ{u&r~XVu@|zKX;rbvkr?mkk z6$arY_uFx3wNAn!&iyUd8*MES&cO%FU1}1x$`|jKFqe);4bdK@`&A3_B{E72zbUHQ zF7KZ0d-pD3auFIOo#uANsZJKw_{nDA50W7v`4HLBqLP<6EWKf{4 zs*6UMmFuAd19Ms%0C;o-_<_5geY--;mct|{s-P$!cl`+H_|pegSsWp70L`Rbih*Q;lfWQDI5 zbm&~$FpPFM$YSj9nY~BW_U@FD06-H<@GD7t)oK`sBthW$>q@c=KY;pBnGV%Cf<2LS;rRfKb_n61AblH3I&OeowOV@SB7*J4&)v4tl; zKY1HKCj!25;#4-uxJOO=yM!%Uw)}~(T47K(&23N2H~{=r0LRbR*%&68X{>66V1us> zF<}2_UV}iLm$M;`@%f(4>lPbxsXM0UE((osl?aNLH6##~ zW@vT67&E>B_hW~~M&MCs?AnEH8cHZ(Y#lZ-J=gBayaN{o zqHA+d*r67}9+GozA+#R6-zkQMiRym7V2E!&UaqN(z#!kQmcMq~wKkq~6%j8-2&~1QE`%-{I<0%~WrDIkyC?o~ERoovNyNgVAQ?tmY@w6{ zA@RKWg6mA@`&Gwh_qcT=@A-b1qY|4QFZvMR{mM_E^sf(x2pFh_nydZm@hHn^o$be}i^?LDyIeJ~F4k z#_u0TQ~&*9Tk-snI{FbS*3L$qw`?-ACp~DskJ9M$@7-uX5(B-P^bDf9Jw)(Yzsu0_Z94hz4L5@G>-v#EM6El7aOm_y<+BLF>d3iO*0mVXU6mtX~kF~aL6$_ z7v3t2&NqEK=7LeC|3dnH2b{+uY?dR;g8F(+LH#bviJ~C(YUNMbRIbWIAxVQ@#(4~) z!u8KSs3<8aA{r&7FzOOMBqpN*m$Q8ajS$LK2farD=g=b@ac7ut_Il2_r@~GdX#FJT zb2o!yT1Q!Py?VyZ-F8bf^YTIU30yS(ps-rz#7>c?lAR{nOzNgqZQ(z@EwUbu^mY0%6Oc%7h2yOt8L3=LU+!RZFl(y zZ*ZND821kOzFOqac^kf>Ztm}*c3OZW&q8!Cyi1*~W&Xltr%gmP+FM1*&qzkR=-aF0 zFO2fYv8+UG6u6?YwSJ3eLDqrPB>jr^GdtAmZVg;NqsVJAGWP7oLDZq!|7BHMM{@kU zAu5q8mz)sGS#pg^8Ro^jaDxt&uxS7c6-k=U9_DREeI15-=;p@Oubha&<2*EgaViuSyRpo>&Fjx34+G42Vrmg#iZz%K z$oN~?TO{VHp!e{*v0qa>dsBQ!ahVg5=MU}bC=7K?)%1;z%2t#S5;x0PhzOz+i92KF1IRplke9PM`Y+N>GhV^*)7Kv9TtM4GgX;&5|l%8Cz9-XV= zE!B{k*u4aMK*|J$<@C2Kk?B^xSwtTZJavCf$)7Ob()FG(1)&@(z}O>m?%jJ$4u|{D zLt|IZcRS$dZBm-QMG715lCMjgdRjvUjBEt78(5LRyeVO(sNrQJaD5M^@4XUBLY#zv zs)OcwFbc84)fx>;*+T{1FS*j;16O2Q7V7HjyDx<<+gC%rJcJ84?pkpW7Y@Dl8V6$B zXLWa!AaA^Z`bTu$X?hTc=G}6qb&y|hhWBILWrr)f0h>Xb{lhjCeFBzW)epQGm0TJv z9zS$O-XdK2jKi0A>tO5HQE2=1=tn3tMW45bS-g^c_VM7^M&(!j&Oe%-J)B8ya8KW~ z3t(n6(Me6~7|>s>kiPvReC32fbdGs>>+HjGJLM5N*>i2}UGtZ`qI&#yMnl5q#=|lR z+7kiN{}teXzu&9+v&3)ur-Jy%9uog=gKUe0SCS@aVZ~Dtil<#pkwA)&VWqE%pN$sT z-%s#hicjaf3$tZf3~+L4+EIRrH z&((j{B*1s>G+i;h=Ki)w(QYx?OdPv3PFsv!`<3QLD@7AG$B>T7GWd^EV+6IT!wUQ# z!7J8H%*SHqZmB*#_A%9U>6e7tMyvV0JnX89q+_lg{*Z1A&mKm(=d@>rb_nC@s3Ky3 zzoRUKGYQn|*O@?JAm_r`j!-oSd=L5MhZ0maLZ}FyQOnddGz7AkYZu<5d4eEo!e!Y} zH_yx7U(YNd`2|u(e5=>>)u7H9Hl9fF{P{+(J~jg2elQg%R%*(52RfwnJU0pOChyZR zl6(*PVX5re?iqwgmh8)jR={SX=9cVTYKOpx-wj6vp_d&0d5s=| z+6oHKcPm72=Yeh7C+mju|9;({u4Mn=_C*`JZ&4b$za6lZqUZ?wM5UBF&VI{{UU$ms zZs?Sr+MvBJf|h?mucT2Bwjva5e~mI+Yi_8VbCTgrK8>FxX8}td%YuFANMQuoC~wG> zCb}<{FX6YN=#}Cr2L=D|T~+eh_izTC@CtI|7^7|-54D(754zZbj5vu2qO zXL-Z9qlUsoxf**oS=q~`ez(0{@Uq>*!4LqL;Dmv!b(BVF@{3-gZ)q~Dr6@sGm8iMu zSwH)m0e6UEMsnhWtU3bBe}cyv&!*!a`0n59@wWyAB&XzBNJzxF%SiG4H#F@DrgltK zAlg~6PIxn~7u>$+Gqm$i=*ap&0M2)PV4=a7PTPv^X31LQEi$J&G)IIMesJ3JBlhk# z*T;Scg!nbU-s}6ERNkgCm@i;vMRW={J@?aL$=V1bOT8VdD>P^IojYvaR8*)m8a~ zX!K*PL<0l-`9+5^#XxDl`a2(b*|l!rUxZDc96`UABAuzdMFcmadqC1oLBy%>ZVtwG zFp~zs1OEc?gPYv<5shQ4V;;Xx@E$1>>JWJR=*4eMx4-4$gO$sMN64Fod)Un!WjwOA zRMUTYrHTa$d7*Qb=zc<|Z#MsXrtmB>g?{QA%kGUgeI=*XNtnthOZvT;}P!QHmz z=H`S*^ctJ?R650c;=vR%Hwb-6iMB0jH4f(qrj`rRK?Ya@wU>w!Ul`#$tHE_ukxaZJ z*w`gTEk~4=1F`g?6VCJ;ODmD3L`ND4b@qR4I}X*yD|nhlK?b1Eu?`8|K3YVsxxTCA zYNj0E-bT7hP>VnB!mTD> zi#C92;~wust#tN*CBwO!@hzdNB4*HUb{dqHxPPr~*^cS)0R_(y8x$U=1zOQvln_i+ zL_bEjli|!U?&#(U7{)C5ES>&ezrw5A=KJIQLAw2sC46gE@*^Q`q1qm=L@BEMyO>pX zFR+k*4OpWdsTQ7-SM@MBD8J{*$vP_knu)XC=wkrnyhsPUUR64{QR$4`JU(M~P&NH? zo$G#o7whq*m2_af5V78*@*4ar*=!nypC*J!sI#*s@=;Q6qr~PtW(OgZOPj$-!(TUr z!Ahz{l`v~c8ap);1b}2v?xU!@WCoJM0c86k`$g!}h41@oFWujtvi@$v zmJl=z)LUj~ zy3$~0xv1S7$+?ts6Zzr2@%?@`byd`wCqaTC{Db${2JpoC$`BWTLeL>fMpPpv2CB<3 z&!ch_i~dl89_CGk@U%0)sy8I-DEK1$=+Z~y5Jj|+ntB0J8xG9V z3e`HAY~@Hs(F+A?PLi57>L^~g922z0$*{lr7))2YFzv^#!t@8MV9UDg~z>%wc?eG5Kplm=T@}H;G0IQSc2meRMP7o3FJoW=*yK3pW1vb!)zZ8640jBRRY#8zA7On(uY zJ90B&&XD_KW=pMJxZHta%$jI3F^Q}-v>}C+h7;4Xk6yapaNkhs04u2gb{3%tJ4wyK zovjbr4S*3rh;hmJ+T1I6z9M8(1WV}aDCYSTYP7`U=c2Vh zLK!##SQOidN9y*`8F|m0GUn2zjvgu9s|#KJeI-^p0!tLKHzS$^>l3mPUT~ZeES$uE z!Q}bQcwu?rxHrIi$T+>b%hw;j0WWBD1H_lTf48PizXPIaG%+k}4Z2J}IkI!@ zEb8s$w*2M+iQFr;RVJ#bkkph%(G~c4RSY_)h^f~NviqVQS5EB+-@0IYL-oGm&-tF) zN$4M8?tDdQ8*o&DLIJ)j(e2gY7!1%UUc+3gRzw05eYFDo{FgY)0Menu*WM6@WP>SH z?-yVW)cWrhbY)NZ0t_n#Gg1n8hqVcyEJJ;edxIwyl!jhe%zJA7&fqlDEdGtI;WjuP zA(_~d+V}MNoj?CVt75w!U<1Y)z07)1b&^()(HNKvFspvoS7V|^&rWo}Q9V^ibQ#x& z_b$Fh?E9%5qVZ%Oui9+DSGlhrjJ_YK+atNVdlMECB|%YIP!K>HS@q0{Gav#gkLI+C z)~w%OI74$ zjwPPP*vggeP2-4VCk@+F+t)8TRMT0z*%K}w=|Hi^8cKUv=oM`<*pNRmM(ym6$;SE8 z(;zjYoyXeUrD^*r5biE|f<={eo9H>kp=^n;i)eTaqFL7gLew@O+88LmFu>8qvw&r< zd*6qhCkK%wu#0!~<0QR?V!nKYX z!mJ3H^=%eaRZTFni(f15y629;;hs54z+C}!C2I(XVW2(JM>EAQYxK~{wNOZm`n8HSF;AiRz#=RccRCI@FHh>Z_MNbCU*r6wpM@{LqyVf z%i@8Q9;;sqb8W2O_ldy!{U-Mfc|dA?o8MxV*!UjtoapRfbOD|lD3(Cb?2T}jXsg69 zWBFIYFJ)-uH!8ZO*R!~Fuv=PInY2`VgX2KwAq3fn>rW9DoSkIPJ=ey}Cp#;RkXgP1 zE3=Q^~G`v?LSBG!R@=d-6?@<|0>NT9T=E+rd^%rPfP0oh1}8{ucqs954F@la3|d z5MwUbnz@uHEFsz>2oll?(rI=}58b@a9tD)cT~aE5=$Umjo~ntG4})`r*|-Y-O3>4?=V6NVVm+8a?%1FVU9Ud(k&w za&i(4!h)N09ipDq9xYP?gAj@aP+#`=US+Nw1qfC;yWB0gpbL49N&d+L$IFh7&p?Pt zkeg`1`U(ZE(?oU$0igSi5*;dSG>0=Hv$X9th5=dNFtN?CdjYjtaQUme)Z;ynBO@NC_nRsPMGU#_1dJHW|;ZW&|qeuI#_?XAi+#EEb- zc)t|SY0@R>17I>Z`DFyY^bLlk$U>O~++tRgw{Yl80MSM8%#Y9ER9@;Na)~ETqzE?4 zeW&}?2)*|aU4fEhjxPrjc0sg4meR|R9Ug2*Ji*t@tQFb2Atxl?o1R@OGG99FYx-#D zf$)*QYuB0)f!2zw3Czp-B-QOIcZS@y;39m&5;F*Mktnj_l+Ugm=S&tYx@!Z+M zDq&nb?hjIXSz+TW&Lt5yeS)W#%OChELmyCB;_N4yo#kaR(u%fl058GnCzS%^^cbop zNI51R`F({UI9N zqkCXbvF~&R&Kl?e$G;boxS0@Vyv+-Q=94(!1$6uT@|d)z4bBHFnJ)9#)g&f?|DtFU zfw#j#=uegm@}tT5O9Yr?uT3Lp$7DnwbyFRWkLOf>34YafUzDGb<8|ZO7yi07EGtBu zSE#%J-Vl9?s^sU0o3O~2C=$JW@!gP*&D}l{ zD&aq0MUrot?;#E42>M+A{G$vR$~cC47y_VP9I>Lp$XdLB=(A3YV!#w&I8q6E9~+-# z3OcuW$VnrqX_QQ^Jw)yLhs^)xGSm;OEoaPuJD^Mn!OJ?y&Bv3M-@gwZsv_3UaqgQg;0v|qKgA0Ds5V*`1wA{yB%6AE^rKaenKN> zzTYqk`oDip-X(+*XFekQt_(VfSRYm|sR@91a6t8+ZaZ*`}&D>7m_*oUCbxZx|SM|14y@X!%q55}pAJT*NKy`B6+`2sM zj&Aqs|GofDbc+<(UycrX=!kFdo>=J4wH0$Dz%L-^%w30Qk3T?$n|Gv>T z+~`YoaZA#l?*3@%PP~5_&RTfQ8^uC)@koki560$u!J7o_ zPdX~o5D35i@87Y@p=z^JB@n>G*FNKoZ3_a>XY)lUD2_y@pp(z%j=#$r7_5XM`Ls zo$|Xhq2xS?DjRw3|K0p9*;dCR2xpePotDJea&z7MzcLpNx+MlFg+s>>cWdrDbFcmA z2}3~Kq^PG)e^Q3Xz4Tc2V2mvN-(NwW^%`^}VCec<2Wp%^?<`Y*;w|Z~hrR zzgcUu2~h!DB~7$5R!2%5>Zb!u4!ZpxAx^CLGtC`WEfDRNpcQ_ss`cZe<=x87pArbc z8A~D2IHHGWc*ZK+QeE zs8C5EG;1EEND(0s85%^TiG&PA^F*b2p7wctD$nryzQ5!BWAFFa?|%1lJkN7bpW(i* zdtK{VYn|sh7ol0r%wGBD-LJg>`N0MdlOfVXBZ5Abu{7o9(7faN6~6z791<%K2jWDX+2 zgB0FI+KNqz_e5TfM=4mVkS`-o)fR^zzVVrpu!x8VB3`6};JOAkxW6Qi99}6w5x2zy zdX_&>Vz38}0ENZ@_9YzmU4f?C`4#a19%9kby&2?xKtRg-UY09EvWUFK+@7#M+N=R)W5O)bZ!oFoPz@1)m~6}oko(x4c>?r;+#L;O6^hKbKv+c z+HAERu;(%rn0~FaA=eiPdgjBarhZlYxt~OClcamIB9>wmS>zRjtM}5Gq8>Obg}bXI zWI8Aik;ilfW#O~K;I~n$*iw8dp^N?dBmAC?!VYM5-2gtld>}axdd%BVfI`v~hekK# za@_adoX$lRqVcpMbTVl-%vV;0TBo)?!pFSmQTl74u>coPN`xZX2g|WK8p2x}+!S%$ zvu6rVKjsSb*~Tw`Cx6#0039(%3P!}I0f^i65Eb!+U%hY%Ec-`B1|k)S*pXQ%+%YnO zalO1pf(*Ey0X*AhZm$FKh9{tHUm(6c-C`2;FxB#DkeIhsqtuQw?~EtceCHLfdU}6K zIGbGGNYk(d-9y=x2iV?ST7^X-jMCQDb>dSXtYgz`J(s}Vu&2+ac1CD@@PGh~_Q}phUj0 zYxbYlo4hak!lDjBe>9WI2sKu?X4#WYUodh%`B_MbSu?Lpm_>lvmM>leK)?vnc3(&)`?+jyJ7rg_1Yq%@VAAxylXICgq^WS6sX~;~}hLo0md* zz|=5(g_{S%He+uE-8$1gTdtG{aFzG zK0hX?1K>78?a!>T}g}&}a+t2yyRdvstZ2_gr?74w+bD-ms4rp~iIVt}}LmzR3wzCr#f4pzGl_*S2; zq>GGFj+~mb_qI3OZUJOqHNBO#sd1S}wJgJ>%a`Fhw@5*%9V`y6ARzfpy}Y+Oy^gxJ zHht{-9{+xIE_%X+F7<`;bKb@|bHnqD5r?!=& zA}Mt-Qtc!qk+bMp^4C6o?yTN-&cjA5Y%fuvrBT<}lcdEt4Uari+K9vk1VReSSCm~G@=PA85l^%m5X36E@LpyqCyh+6PDaOl38-JpZycGV!79@iNaoiPc8e&Z=-cA&PsOR~MdmbEng*r?m;a9j930XsW0) zf+$6C0qGGe!cO@Q8CN8gABOt3K|@7b`7+u?OJ4A{-xx`koO;LEykf8INggK-C1|G0 zNOe6ed;{pSaM$j*oofKFu}YD8wiGs;-a|}tPP)p-*R9m;59H2o2$%T&4Z4Q}I&7%c zMjI3hAq$TRYJ8~(*j~OIag*@Mir2tNB2+*8-t*g1Xk}g<1aiu>-uz;ocysG%eHba5 zAK1P9aHJ%is7i)C1GUDEz59ZOKqnMCD5pJJy$9fxLV3~= zszkk9b%`L;o`Mr@N`b7yY}K??>T3h;ZpUsgPPa5TnALIEtM$T%QZ_oqj~|R5jC_4) zqi;Lf#iWlDRB|^Cj+@Q5Q%g&a8ZVC$e{tSbX^O+P4|-V|Qg9vDe}Z(QxL3@_u*3JX zz{h0Wm8zvQM9TRWGzjAD_5zgEI^GVA0p?!RJH8IY)XFy z#Hr*nviVKZyS|#8q>0u)3KG++Mp44@8zMp^NvRVUyE^e;|LgO2v!uhskNc3BM7;MS zbXu)JJT?i=Hg3SwgN#)}j4lyU{T|5ClPagg1Z`Pj$j;u5mhWAob!hs-P15f*eCwB; zkmBTfM^4nqx7tDVh)-&Hx|1)sQANT0(#x(ih~`;=ZXSB7BnsmrPrRva-?^;b01@fP zI_dOx5{U-a4rGwF=arl%3N34E3Ns!(I(TdfTTYZt zgPp9i>i}42oLVi>!Fg}y8$^!m~b6!l|{63VYpwi!KZ~Wcasj+~* z(y6<4LvN66S(L%#Sal5B=s-y6%;PIPz4g;#%f+}`S>e@bzP~~p=-~|pvueg*X!j?AHmng32A_})zb@G`Q}FS)VG*$xDhuwO(@qR z)cRS;d==f1*t?&)kNL8S9R!X0S)sFYqt%F5;^$?MUWrYFW_lTaGV@MRe5&|@YvwgSeuHfSaB=OE(0yFyzIsL3`iHE;HESjSmh-+aLNz) ziVrF;Ps01*0~LA5;~m#IEO-#;4zJ8sK=oe{E7= z9j^5;a-UDerR9)3gOo+EYj;ZaU4AYu&=;<)(DFAr4dNm|1#Q~AK7})qzsu=)-2?h~ zSXczT-qq?mlPOtBCvRR5^84(LFwu$g*{N$c9O7=~Sb&Cs?wzGPJQAmN99ppt&R8Q8 z(%6V^Ayu)MiHQt_yv<>FD9zGx{L7cLWuv8ndXqOieRI)>k*SFT>2_TM^WcYgKw_H| zC+ree_#{sFBVH!6cT3ebY?&mEY`;+zbsElXeo8LH-{(>+sh8oQtm)q`G0gbR_1P(b z=_Y$ml+)9eC5iW!HMBMU7V()1M*)rS(on3))82~LC5 zFt`aL+OrA!ek7vT5`fE&He<{?9=j3|(Y&G!TiMZdJcLPkWN+S4x6uWMuRrhkc_2N6N6n2_zN<3lS5nz}?1%>kgm5Z_kkSX|qY@ zi_nrm8MrY|<;*D!x(j8;&U7p)5`ER<+Ho&y@v_AFSW4LrSpvqdP;zC|4e&QgCX64E zzfrPe$_skxclA=TU~0^(5@5bFcg8KKr6ww_yM7)oYJ0Shlw2{o(UdRx#7mws@I1Z% zJR54?`Ae>aszdqIcai0_tj{)Si=wl&~eB&Dsp2U0_vH6nd8bF%9;p zdoHT9B#ai^iLD9BqBo_ekgk>osp9HFe&v&aCx_vgSa|uKPsOU-8+_U_GfHD;Mg|lM z+|cGxgmKPv9%v!M7U5d9O!spRgg7o?*bfQ)sI%XxEDOW-t1Ljk4ERf8O6H5N%|?DnHsCiPk-LoF%`O)Y#t%x~ zLi&FOgoe0l4LaT-_h!XHEw)G~L?KmD#YyG`c*aL`cq?Cm2qJ3~54bBK6$aJQrFrim z4XQvM-sC7LreeohJ;&!k%EmU09GsXA{UFBlh~$EWi(}*+vh5`jTjPRcRfE*;>$2h+x^HDldqTqv9H1-%`{E`AHmIztU+@R4Lta z1z`aPKmXCYz%>R*DXgQsCf=D4h<2ExY4%eQmFk*NbX)xd)NiFEB61Ka+j#J^&p2TM zXShF?GO5P1??=_bTL$8 zEEGI}N}&3Os0QbaK77wb_QG0R1|0@YMuvbPSuX?n=$$~yvfjVN+y z57cr{CORsa2ebNOaXJWCRQ+S3<=^pg_*d0oEZE#j*7LKl0QXu)xhA6cmcH(ffLAz~ zD3RSTfknmoRuJAQH@VNpt%b__M%#5sHNW;4!EhmD0sKnEHHZ|T;`%^)22*1LY1GHd z6?@Wg_#T~u>sU7Y`I`sp_4ymgJ>9ppK+=n;7b+_h{2X(d7` z0Z0v{F@nl{IgjZj+t5*qZqSY(8Wq>mxj@u`&efAop%lv=*JFql1{y*a$r6;q{F;6| zC!)tjR(w1PYt`*c^z_l&&_Dobn272G7zof;A27y*ScS+H-dVkixeSRUn?cB-uII6KUd2W2GG zlc37sOjc0A6YV89m7B=DTarh7rZ5j`*my=T-ZpX{m;S;NU3)yuk4`2zzf5a`s)qc& zm-9fTq11(&=LC=N6z5*k3^i>CwI5P-mqYXLOW9@wY3Oh(Bv1O!Yl!Q^69xZ>1uK#u zI_sKxi1QyNUoZU^6}pSqn9As%KG+`0Se2KjOTOIOa|&(`>?1M&#kLH?L*Lpkfp+5?nR?KH8p;Y&c=yW!Kpe2u^Zu82Z4WFL+LK*~(D z`dBLu|IuL8F}ng^7JLt>Gq;sPlp7Pv;)!YHKt-xsnub_>rI`S5kBx+OYD%%Y)dS}YEW+#ibGuwFZv$T?rEM;_8pD4U` z-*$?20!$MF!5~|Qb{FFu3S>ALji&5v1i{p3c~_LUG&h&@s6a}%tDN2-L`@fMDLU?C z{_GKK6txyIc}v;LYGllbQVDOu-`R1!BC*6NDN%M_Epbd3js0O zipUHtO#bZr$Lp>TrHT^7NgGNJx=z~>Aw|6MAVu`9W@>(S9;(`jeKWA;R!CcqIb0gX z*fd!Ak?e#&z~}6jK2pqZZ8u!p%}-I+{O)@7Eqx*QZJm?!e|;3@fFsM+!87^wbg{S| z!lWJHZ+oUHDR@B;AV^f`g~Y{6wRo>hf7m!9=7t%Z-Ed*O+iKfdFEpa*u*O^)R)dD5 zP;jZ`BO4}f&=6DNf!KpvPyM+LCG}8rci?cX?f|k$(X+?m5_l8rfX1BRT75k|r;fi} zDag`sAR=LmWI6n%<3Q@-9?-U-9Z(9a^LJfd_vgf=wQ3Y+|E#wNbD?PdzKTchDq{T0 zU-$i*$ig{5FnPLf#+1n@-%By!;Ih=Y@)3mQl=uC=oAO`4=tFi;$d>+KqkDwI^mD`4 zlb?S}zO1MLbJqhL?L@=O;5DTbm)1V63PNptORBT;SN(^rARe{4aYK z#b)a>Jc`otns?P#X3dm;7NAdwtY`ozAqc5VI_t!N@qa3oQnGbKgfg-FgKIOf@IeK{VlaHn=mt8IjL8aTn}w)!=iYmNEu zW91Ros~#JHM&DZu2tUca4vt*nfd0p%jGaolJ&4T>d$fZM)=SV#^-Z21UI_miv~rkzGP+Sa%K;)*3yPv;yAqLhy{*8$bedx{rYDH(6A0ABb|8O6-Jr3P zQ`MAb5kh!5PrHC)X0#EEmb++EkF3ADK>kYP#8KP<@8|hhV;65j@@L+Xam>^5(H09r z^qV$?%vt=)DU|NyYb1YiWgmXaDXll(@!31QbA`q`mZMKWCq=#8MX;i;+honLdi7vE z4IG)D>fUxdpUxlmXIk$35TdpF$Hh=E6cw>M_Tg+6gc5-F+x19f4CwaR2Na~f#y<~4{-BNtCb>um^4Nofy-p6uc<`u zLDz5PdeolLi&9XaS)CapP7;QzQ~o|2>?$L# z;0G?pjHtu;?*(g6F28;8@;ww2R&%3#(egm8iwD8!)#wvvpV0Z7P(Pw6-f{NrLE$V@ z?pnrKjuHc=d)nD5(Ujq`pI?SqT|gLQyvAZy>M*()#ETzOIPB}q zHSVwZO;aC;eeyhUE)?ciZnw|dX1~?pc@jK;#^=`x$BR#*U*Oys&=ce(S~l|W#xl4$ ziESTf4utDq2}+tO_D{|ZB^r-O$I%4DIQ}u0rL~~WZ5J&WEB-C@?gFQkCc9{<_gT^= zD`qU4I5N2Czr`#a4VrgaG5`-3<8s`_AbI&tQgM1N`}^ZQHF_zMG!MP9rD+(wOI+m@ z(l_PglnD?Z^HLqM;pJ2ia-=|%YcJZd?@ZBpuRV#;^~M?i3lg(Sb@>auY>b_r2yith zJ*o*wQ&&C`X>ae%!Efo-!eMJ~Z;_8SLcPo_7(<;I^4d5IlYp4Jh(eEfn|TIQR4Q{( z85={Lo5y;?8L3v2OWarm)Ttwa`kH&-F@CP>+GbrD9ysAt=iVV@TjB^#k@$Y<*Y%dP z1vJsHNpT)Dj%q%^hIEU#1?w)=j-axPq`JU(eN#@=r_t1A*ogS0#J=bEWT3F|h~TlS z?sJ9ba1B5E=ChtVW^vJb;pdeEPDRLj*WL3xJ_AZ(tFnD-ek=%B)VZ}84*mYR8i&J- z{V!J00AJW1R%){E_;wC0PoI>trk_14QAjM5^~Q)YBv>%mzpGNH(8ra{QjKkU1D`%;~pzl~bEQhwyim)dyZ04^#LspA42rL8Ve z-*Q(-k*Psn_Yy_CFgsG51Owov#3~pDr*+P~%iH~whd1AuOfoNiq#z1^9X%ZxeGAfB zJON27Dz7J66XCGR_8t~Na`;&GK4hGLmI&kgb)XR(v^l!9lQ!@0+;^!CZk z5Anq&`?lSTpt#A>iJ_EzpcV}UMAepPrIglb@kwoC(b zmB;~`Dl6KT;9PxQYYIttwZj!ic9xbW*+7GeG0UB+<1oJeqh3B{zMmPBgRZc~XNA(z zD?_9gZ`I+ud!KzsO5NOda|~rPKhBm7WMVHWZ1nC^{tLgfYMQ=kZ*LdqxN&)Uyly&m z5)E68x0DKOY`FTsp}nZ`j9tk$e3S@Cz@^CS3T=P6OD0L&1l!=pey?hUSMejt(j8~} zzAdxi#WULLV45o<%1)Xvr2rPQ?J>oq5ID9V#ZW^g#g7h;?)gpp(m&Uiz;*=&V869f zf4<`sdYO$h#h498YBAf)@xLy|eRMG$sd*PIo%r=vOUqX751c1j!I=_lY{ImoRnxP& z9^X9yG8RfwmS!MSMn_ZgtM$njxkIf5s`uC>EsxaQGUU&H&pC!JEpP|?!_z*Qqa65P z731ZCoZ-fsr+Sl$1v*ydSPP}PWFD&0gF0TN4(BN(&yhPV=pU*IEVIrrw;ZTIjjlkl zFV`lkuh|63`Dftz?qta5qE1*i>H2U*<#Pg>WHKO0=cv%SiRRJfjBdkmZGu1A@D`(Q z;2w_m7{nYTrM=cnV5uqr;gy_RaqyBk`+iR&+Zkzc{6^8-E1$|(dJ^z zL7M)%;uMaqb`93cN2`{{4u-v6mMHlyD1ek_dR-_FRUwE#0<|O8i{cS3=%^GLE_eY( z8iZ2_M=9Fdejj=qio#5slgjs^iLZ2vj*@)rkNfF4iW!E7rDGVKAt@kuP)I%Zrh2tE z^0^Yv8%=Q__w1gUbXpLnPX&MBi57mXi;6@CDgH2G!*}I=vTl9$i=L6rsc*jMD+$_X zt@Y40{%Wz!;|w5Y-Om|Q*NPsJPh*EhRM5hILY|6VQ`uvKkJpNVB=E=>+u~jP*9fXg zyQ5pbmwrrTe>#=>^6(ql%Zk_0eN4vX6^nk1k(_CoD)Z*IsU!i^;OxRe!EOGmdCFT7aiZWx&`4035FdmRElFR ziQd5w4nM|8yEwh$M7xJ4IaIpi))~tFi1EJFyJ_48Q9uxeIefiq;;^+~NfMl`e{k@v zl@Z_*!uN;m?iIR=AH~d$yX^Q*(ouJiy;0aV0X0MQUtWFN~tm}ihFEP20?Xdvq;rHy+1@AU~q8(S-$M%r@ zX{uNhKq@ut-X9&eT;-v0?H06uW3_7!g1wBf;X@H2vs8JGX{vOciNV$me31IE2 zxJHuH7H{f+9tfZxOn;eA09T^C+Ec%S)R_^RrbE^BfBwtKM_7=OH9={|2w;+*MqzT( zGR-2`{||iW|2cPDZH9wU_Oo$8QIV3vDNgcym}+SZ3r!&f!*yN3cbbTnNxlzv3B+kt`IdQ#zcYE{};bl_1ee_Ospi(ef;^z zZB(;YfwA%nDVO6-%WpI>yl`?X6wx1QcY~NpH5Xx3zN- zP*@`;z0uyq*~rFe(^1D`M~~PXaS>QAy~XB;Enc`*c0E4Ugh5){-oeGjNm|=szl)8g z&4HuVHqx7pIvjP{c5MFv8);3OllBK}be#6PG2qYSw*q?v*5aM!463ROv$xx84S)Rq|M@>{1zhD?ZqJ+lA1#}h8nNtkGID>}wcMJ&?0U{9<%nsS z{0E!-yRlt0F*w|`hB>EWXZbVc6RJXGRDzr1sh?+^-_K-YIQcb2&b+#8YVw`g6J7aE zn*+z1V~4em)-HBGul9QZ^ZS*oaNHPPB(-*pWWwpUbcHI=-#^%K}=>GUD~4GL|N;b6^GZT=64x~=dWZ4 zl%~0TIsNyV=i?F<+ZRsK8msJIXdKJ(Lfe|I(V0=tV^wwWAi-W8F72>rZ&!JUf%g9RG)p>TKQf7?)0t!h2i4nO^Iif`Ny*}pSt%O9rM}rW1z71 zjzq{OgPqh}`o%I`L3^t7Z5DQ~?=|9hGi3kvL^Zt+_ra0nCSKf*YP7|jx~;wq?X0&% z7l>~*Tw-(TeUf2WsT{-JpC?!DXWOvp!8z`;3nQz3+XbzQdlK#cJ8 zX33%{=c4D)9aD9$xkPpAGX9gbP;7wW2j$oP&01vsvX=h|FDN_b1?A<}|94(cPL>$l z|C|>z(b>o#z0F|1^I?Ita&naS{oO3Pa!z@$SB+2cDhX0=?A{Sl`$B+OPQbuDoROb8 zna!Qe2;&Prgs%9i&aP#DUQR1yg@Bg-S$1J{Dms&mWvauE+S*1h?>T6Te}4bSxv$n& zy}_;f+u?WR-<{ufvR^R>pPCv!>L@UGuX_$5f~_et$v>1G4CtFAV|l=GW(6V%`FDjjL3D(y4&?02*>zd2G{;wqHu%|H)RUph4(5REFDoDDgo4 zTgu%U)*5D9urQMO34T?UCkY!=pSp?2zw~Y^8JCU$|x!;#0iSJ5Z-Qo_jtv+uaVtnV;n{Q-SeT~~XSAsofj z>L^>Q1uCuy*@_tjtu`_Zva00XFf5xayo%dLE5El1ThM}jJB3ZPiE_n7ePs13!WCqr zLfS2NS)K&@(wA81C5A? zd*&C+u1JsB#xazePo|<7&KN1;R$#w68;3$co{45DV#V zo@CKi`GtAPonJGWfIxf~#+9!e<&ZFiX4O5ALs6h^si%BX>FhVXGV235_Nl&zM^PIH zNoZXJ_T2s<3=qER91->~*JqELZaw_dCaX@()FKDo_% zjV$^ul$}@+t|M8QPlj)!i3!|MTk>f7-3nNL%q}vEK9)S)8?Tx*V7?5J*C@IEzx*Y= z7kvbZuM$}keJdg#*%%LDOsTXt3(gA|aN9&zt)?>J?npk#sxq>#@p$IUEiIS&-|Qy; z@44KWr6MY`;ClMC-hqe_6ykiHKcEBtE*}%!c{%$CbJG`en|pP2>hoor!41`Up|ah= zVme(rOb>eX9$-@jQIb(WTYm5P<$kp#ab zJ@pF$bR^-ivKfNSlCBWPH1ZNANi6NvoDHi!fQey8ruFy=Kd1OLCdnDw6aOE7jOz#N zhu58lYMw~Zs^yaTRiQCaOsXR<>pbDx#Bw{J&oQh+-1>0ToJnUd$aYBi^14X0=PjsbTV&okw zm#u(goDwiCs3wgAGR^5rjEKm@XMkXwVwjlVVS3xd2F2fqWe(Fp!r+LZ55W+eSU?0I zDL=tkCMqIQx)qc&6?A0+RSYA7rtbqtZ_U;V4-dZ8y9%L}_h;XGZA;$ViwgJi0AbLB zXwR5K5yUPD=a33UX8cUFSacBmsMaqq(g|$9xA0M5lHt^%7Kw$={LXvh402y4o4*!G zOA8Ug42*X=WTT2T%N1L;6I<^D8rFoxjsaCn!UJ#~(P8s%e zkSJH21#V$1a9z8)G#W=NiqHc}D^@hZb5&15>qN^#AB4G7{@%F0;I6!k3wmrcVQVge ztI+se7uBwZwiT-_Fnv6Ym4LR7jYe)mv2i3_Ptpz3)m}}df$B`J22u9wcA%p(YOVWa zv}GOsv^9yp#K_m_jU7Kc#MCr6$j=-cSs_zFcdfhLb5dYrvd)GTr=z z=|B$@6d_v$UwRF7uOu6kY)j2pmn~by!-Ia#UI+;UT#LlehvP4sL9IP+5A%W`KcbL= zf)CAa3Jd+DS$oAGXGirFZDEXjDytG!-j!QHY(2r$LS_Hl;k36YxBIk(#-qb zzd<)P^%_i-aX&pdcB1zQ7IH-v-2#M2oasL=uJIHBB#{vWK_exKf2bkXE5yTZtW1 z!1(~I#)rlSBcT{jqFt>GbuLGE5vVX6{dhBIUi-a~^z{Q8dO#v^9{Y_VR5=PA?Wxlk z&+X=LJwGo@EfiRXNkA2}8rb4xZ1j$IzS@NjY*t>A4!^>Lv2S z+6&JMNX;HZ9v@g-dt}ZLDaLQBJ;#al=6FI)91MV0d+k9=e8{iI%{VP(oK%4A-JT~C z_4E@Egv=3)ojDUTnR@xf&l7IKj9nZ2ilEIDT1#fk0M9sOe*h?5#EJE5sWIXHN9(A2~foCq$U>h_9QCWjgFvix{O1=>j3`?sdjgjv9sK6b3e!n|L5w0yD=aEH6e!#%eg(*U$&}b( zw?JVzdV+cZQ|L$APG#c`NvPZTS!1y2YHl(Z6qoY;)3XC|mxG_f`MLky`3VLsUE7Gj z8kQevdq&bSH-2e#dq7s>mnbw6h3;B8+repL5kWzXfNAu&`|lKeOD!YXtpm-<T2 zXd}ukytV2e)MeDrL)+MeT~o+a*}A8;M@UA-WN*x-AAo?(UQ9!@z>lx}bjc;xA4yt^ zs^bm^3KO+hSADi|NSl2KKyLtj)~659>%PKo<@fZ`W^Tr96G|&%k#aphkQodb`1SHR zSCudTSwFv^dJN^kfDg?4G-n_k)xQwOg8?G^1Z}Y3FkJBQ;aX)x2m_c{^bP9+aLrzJ zH?$wFOsWducv@|lt5V2%JbI_zBDnJHW7ipJf!jtbB7hTYH@3bhBbr-tf#O-H{l!ocZ9}}vdEG41RQIS7(FEW7xCr$A- zEVVSNZ-oHc#L~ily`;ypg#=FuB$l6v((e`SXFiI)lk&`#`6?r4Tj#=kO2Jp-kJG1Q z-`l$!@jzZ~4(-iT#fw2VI4B=q$jF;YAnDbsWNf zT~W3Ynz1f{E8bd>n1@CNI2Opj>;$b1Z`vQ3c&!25&%NKBD{#IX!UKjx8UiM;_igM` z$wVtOEyi`zs*Kdv&#gdr7@0uLjj8OMoSzZz;+#eP6v_<PWzdu$1tIW@zv&vfGJRq1bz_KBj)BDfi+!)0D z9-gs(l3G{|dcW`r+ltE2Iem2Gp$y`G(0{cIhAJ)`Nek&eC#qrR-@=%(XG z(EvY$9XXH$+#To5!|(XgbMNN9)Z!}Xlsok0zLbS>diTVnY+IIN4Wt(~^tvOXgp`|K zK)|E-|9s2E?$7sXAVyHofz{F0)HLf5T{Q}3VEV2{+Sz2>DNJ_fz1=qCNi2x_b9MR< zPKV&A6JpKi>0dQj-8c^J^|2LT7QF{NSEL6H6T8fNeXw-(KbC%q!gB7US^cLbw*G19j3`WX}rK&8kkF!b#~ zK>Y0V@cl5-$ACbmxm#HTiL$EtpLkpX){zcoSYPh~(%Xk)zpV)&LhGN;O-VTY`x!i3 zfA0bdJKU*FX~Z+Pei1h0&(43gi6KTxZg+JZA?-*7Os=%N=;uK&ik?jl^1?^hZZqlg zG^jra>pBr{Z<#oI>ekG7*O*`|-LgJk;oKf(>t{fNKVfcKnz{P!LCBaRJRd@oZpw2` z;O1ZF|42y70V}Iow>Dl?&zFZAFdaAo)dS2rx#Wk>+SR*$HziNRIzaD_ z8JXWLg$AXMU%#5+UEa2HxfB0+l`gxsw^tNYRTJ>`u@TIJ-JWXHfTI^zNn3Gl_MxhN zBK=~Om*x4@>d!P_US%j0qfvm7=|x9P%iNL)7Lr)!dviQK>QWD!3TCkh;T`#Vif7G` zf5ik+Md<#vdo(Rdn>ecwg_)d(2ziH%Efy}JR(#gKjTjMO96kl)c7XBP3$3;RWf&3`ERohe>u|r{yJWw za1Q#Cdf54xWc>;ctmhyWpOQ4vN}%)h28ux>qs0vz?1Ry74P8-)kQVF5R4X@kY1f)D z6fPPJNAw}c;?h`iF$t29%Yr7#3vljS5=zUT2MY!b6b4qikytU##0FwwUUNoIyR5Ee zHJ-W z#D4geig*lBAal8HZHc8URZ-uZZK?NT!9o6NZld+L)7-k0NY=Upj->hL~Wt z^6Vkw@v;|gfT$heixynP{Bt6PM9z^~uDK`kveCYOt^EfftSK#R9+GMt1Vq`CeBp^d ztIojB&z}fOtxz2g#BVf;>L3e%Llb?l`$$pi%-rJ6&p(RpE;wZDq=SvL9uN95GBQX9 zCRyC0b5CisA8oE%w`^IA>+-%rnrcC0!nP#-pvPjaP$1ieUxL%^9o|DA35#H}oslGv+oTv=ALqb9X7p5b*Hr_|zHZqE}h;ZQDA6C;* zKdYK)cg48ZEwH+fJwXr44sp#FLlHc?WdbraW>BO|P8K2`u(JW?TXWxBncU`1hS|DM zRy;pOrV$-b@{m{Np`ZZ*7RF!4k$X&Gp7E?%Q88uNuNTg7ZM@Gg=uItNNB7%kB<9f_n ztTS`l>^LJ-hi5{CJr68QDjEiOFIDPU>xv&m%dNpcGGW?SCu1J3P1itCVd3aw zubz6THt1LFyPQa5Pri<+D|t>lJ)%}0+r!49KY)t-gBHRTWfj)TK9VYffJM>ypz{O@ zGPUU*2+hHOwA**49Z@(cFF1^BFMIWP&K7$gw1`DzqhHhF%;y`WC>WuXfQA1>fhSBS z^rdrfl8B_M-d}C(j3$U{8)A>~C5FtNbPrl4+4ULuRWStCuB+ri*9gw)#_U8Z`keO( zTh<2~7SG=M*S@I$;em~(W%errU+`Jqoo8nCG5(*g@C*``fBWY%ED!h@?2&0uQ5Br6 zUhgX#SC0CcDa`hS1kJwvQ9!s26K6~Rq0Jjg1*1Yx1CIpN zIPDh4d4Y7)>6>P75gd7D8}5a0&DDCpuy0OonU!t{Q0HEalzh1zf0jDp5j5)2t0%2MSr1JFDxM>iOJG;IXHp4h2f0XF zRmj-=ysiwPce>~=G!53F^E-G3HB<|Q?TSv#WEx}DwuQ@XL+3!>sssb=uj*f@@}57L zsQu06alqM#qQ~mW%dAx{M_rKY4&H^y2tR=#wU&hI`0xXjTP`)fJM2v*1&ncUD+miA z+Yq%ddCcVXv3|ARJ-?#~ncvE&rDd`i`KV~q@2d5p;EN?!m9utwMo^Ii|L?bD?Uq-> z`T?L2Aiy;_^@BLbU{!%QwD)2E;UZ>s58{0Lfg9|kv_=m*Ah_aJY;nOdAd8y;n_c@K ze0e+tlZ0DwuVV7)oew`vR?7@E|0f9Tiu-OBvR-NYvOK79jcWZx=6_vzx!Fc;MW^H; ze748SMS@YtjMf6R^p*-XV||!i0^HI77yTdJ$p0u8St5!2J1n4wL+TT6Jl6*@xeB7H z?<-7z%m;8}8>5Eb+{Jk~#<=4iA{!Nz3FHC4CXX%U@7egTWjNY!7c=ngyZ`6!tKO9k zulFB5Kg;8Dnh+af(*g@Rpk!8l4Jye=$U<;s6={Nl=3X^f2FJI8v6)4=N9%-86h^Uqc&2H#Vd?wn+4#+V@1o3bjiNodWq~(@O?$T-%qcq{vb=~k zoB49o*;6HRK1(Isk3BLMxrbFGP{d2JCUF(b88dp zfahA?7F+IKz=~AquSdS+iGiGP2>?@#s$Th zJu&l?|6E6~*{k@!*He7S}tWS-_fui;5pbaWwaLat1PG z(^c~FCo>iLijUSjS&~t(8<(EVIR#y%cZ2&8N_*a8+U^zKvA~L6V#cRyzwE`Zr&GH) z<@EUB1Wywz7&qk>%8Tgq*b5)8{R znEQLgf0O_fJItd&kQW|rcl=MvWTW|gM!AT+zlv!Sqygfh^aQwTQE=nEp6s#UJ~qz%)XGeAZ*|4VNZShTQ7Xc zegvi$sE)dwQJ17Qom-~Js|fB|qNp;2MqCTRjOwM*nS6!wQL`fXK~HF1#sMAFXvi2! zK0XUn!w{|Osz+UgQ?q#Hl!7Q5g*ty>xZbK-9UQhGXP+p9=+Zvky3dK>Ax?^(xrIl0N351*j9VuQED2@i7_s-{vza8^qah+1DBrztFO*fjOK)go+Fl;}X41n}O3| zESkOzRpBkWpqn(_rjAaL7*=*?A?d#f)bk7Rl#8Nk?T;3n$z5J^d7=>#|FTK!L_0`9 z02u^(=*YH+tI+4!CPcR_6=`SYwv|e|o;bwX1^WAA!gNTdrp3g@9r|*NOV_Apzc)L% zcW5tai>IQi?Bw=huGXOvJbcu#ZpTDO?A*GTs_He2nO+SM4;%kofL0teh!{+|Sf#*i zSa)c`I}$FRF~RK&^L+2Iz{{6!a-mkp#ea+LI0l6e8iwwFcyAyc5yaD{>+@41d{N1z z(>~x=uj2J>HePe-&-C8Zk#06_=RAQb6F`H2DyR?bm)H8{7Z@1m=ckC0An+x-XiYi) zs{w#HQG?%5?r9Wp@?>fX@^UIn*M2;bG&9kqZLHp#3F?%6cm%Ek-QW9xj`6ym4AFm` z#Ag3>=&1P$z)%|O6^PjbIICq@J(JrI$bQdu3*Sv9HH*u3SyY;hs!nO3)Jr|TB3t$A zlzFJw8lqHMZZw^qGZfc;2PX6@Q7=(-gH13%MKZw{0bt{{%yrvkR_kk`p@7#REt>90 zf3)n(Q`)4UhEyeEH!@!RsZ$6PGW*Gds4GdG@5Md92$;X+s?rWQ{{xZO|8|Fm6yTPT9ZvRpcc{|G0iAyW$?4DyJA9ql+Y8Fv{p^ z#3Y%GF2|?jQhdYf6ax*S2s+o+!Tg(Mp<*n4Q8U#xUyg50x9r3?CIK!~$Xr;zX0`qW zZ^uE_{F75ovpGh4E5i6ypRWO`%oi3bW9(umDZ(BJD8hiMZSud7aU#`2+dyDYP^8+k z4|^~tYU=sKiWAeN38c%+C*kqZn^$FMUnjM$XTJ}lUet+-rd~xU^+sjCq+awaeQB?& z`MHFVa(z>S8h48UByW?Cg2fG>PQNbFFhw_9d-=laQ)1=5!P)5J)hjahdkSSs182W| z%3g}Id96!7Y0Wzv@}h3Pd4hf3fj5kmt30R47+eZ)Rr0JeUg?D13ooe+hu2DWBv0h; z{uGa*p@f=*XF}8sL2w$qEMzbakTnQ3#o_k4s~b_6qNjp6KX|q)6fN3P?%SqVnqzr$e>N@LCoBhrF zTd0oa;}JYRv=J>VV)eOt7t@y*I*}jgRgm_qazM*kO~`vy#!lTbf}cKr*4BdGVfubC z!s=2o+S#`jk@gPN6yd0+5-dr!LBi*|CR%2pi1%;HEYAV)T|Hfck43Ga>h`ubH}7>8 zKWZ0~rQ3(9=%onWwgfZ?wZC_^vP$|o;LBE??JvCFKQS4t^^vGDt{K-o^(uHk@k!O+A78^FHH1G8yo6UT6yiWJEB<3j z3b9q4y_JS3H&Hdt+@z7_h^qIi&McNym_BN7^xN^@&rnlh+%V3nzpB}{h9!ARtjRnu ztRTvMcax+&w8dg3EexHmMYO#bTR%lkCTiM>XYeFBFE(QY3Vg77-HPtJD@?8PM_Bdu zM$vr>E@I7hn|g@D&!fRx9cGszt}z&InuZD;6SrJ@V_`s}C22)FybDf1SURf@&x1n> zCVQ)om5(n0$`ugntwS{jmACC{Q(warSl>gEuQwE|HMf?x2P&+$3`qXYO|5+J^cGuH z3My=wM}8=Yi;F`O3f05W1|RdtaP%Z1L|jS}`?sYLGnqhZ6ZlEJiY`SWN#`2h3?S zSJiucZfBjh>}NxxKAa(EeykRkPM?;j-X1iRj52a?pt2|Ka{X?q+EW%Onwu>S_|f_P zY$=)zGka=rZkSR+rOQhg{R0B}i(LsAMaVQ6_>U6$_)dr>dYE)s?m#6dPNGtz+|ZL* z|1P2T^rtg{M3XjK1gX!#l2d+8OO2QdQ9dbgZ{n9uWMA+z+@pxLVzdm17Ck%PVE!pb z?B>i-4(r+c56A?`*T5jsnX6^>oI|`qvdfhyI>1s{f`^y&4CPY)-s;@v<8_0bIbiBzqkvfrD}&SNMZ+W)g;r@r&kyjr86I|R@-!j+ zY`t2oqn2OVjh=d>Fu={w_au#`C$J@&-?Th=3d03i0wf&+NNfW0=3aNm1uP^RQK&p5 zZ-sNxy2>tX0cG_DJtiE6iyo=PbVBhMD1oT9>H^~*d7C8NCPp$`t$7A}a7NU`dlo37 z_T;JzgakTlm>gY(nu^ftfsOVtW00*U>?2g}!=){Afs9S!zpADB%P+mUZrfWN3BnO@ zv)iCU0_et(?TCU6Q6DOKZ>zNvU86`L3Ckg<9Am98q-=$OY~Z)P*B5TBg~t3%!AS+M zPY@@g-n*px3o1w_p&<^0-leZ?nA3m3twhE?phoDITQnIze+s(6eT&4b>Yzuj_76mY#R9fhe4 z(Y0X>P$}A&xxRq)4qv0x+ry!uCdr!xcdruP{2J(eG~33-laBANohvd+Qe|(P|JeE| zpnwR4g4foCSwzrx&7UyM<_ZbZlqg|ZmCTnBNwqDm+$Ov85%VA3JiYy7>Il1p>6R>h zP(VqsOGTKifR)k1#YL`53k~`GMA$xg8b{^FsPiY!lcA8jp64TP<#_hCyKyhCwgame zkG9Zid_C#_xK*RK!G9t(SiT@PdUJK5zG_GqQA)5+#>a~>YHc3!4NglT{`fecwIIdS zqa5)o?OB=G#*T;W)*uOlx%diySd$WZZUOYe2HN5NF-FhHJ|+g`s4&*T^t>r?(b5Bw z#>*J&V?JHqL>sz;bW`s}_}y0jOw*4Q)%VPAOlE#tHXG}e>B?-0;uj$$VQ@9dpf`bu z;RPX62yHeO+QJH@vwO}ns?~c3DhNh>-5ySF<=3L36$)0XulO{~%EEKhrf%F2%Cb3? zh+ywRjuC)-=GDH^U{0D}2jEznCX{thoK_-1os|R#F=NpmZgc?KVPz-^PP zmA8AZJ|yc{EfJCw?Ri5aztp5RlVmN5B&Z&4iLuzMg_hJLIj5-!x9WQq zd7ftglY4acgRzk`X;UpvUrNbzoKg1`YTob1HHWsbl1y1IR~@?bvOv(-}Kl zlTy}-0|Hs*EK2B2fx^FYi?0?KZbS%URh9tNU08zn{BN?3ZzC^3r9e6skJH57HUB(K zqa(rsYjC}UxG{gLrOb%#b%c6E;ynz7pUPk|B7) zZZN+HdNRhLZX8>-6*P@hYGXlnbS)EgmD7nv_5M!jpqd{v6rp8YzQ&DeUG?X!3)$2_ zjfZu82mlW=@s6CMU24L3?KI*q{0m9-XIQ?EHEtzn0C*Fg@}45~_q(o3N`3YfuU#AlON% z+r_veXpxJ(i@*ReWTy^8Z+k&}O8c#Idiq@1DKc-DL2K=)sGWO8|3RiQm#lRCDC=Vu zhNu&29>HTwj}p7}$}S0=CJd{elbsmmIK5#8d3!u9g1 zo{cTHSxP&sc0X~@Jsp5(Cd0m_^y5v9>=d~bXMq)R^XM0drE^JJu#2{vg07Unb!R1! zqS46?^79KV$L8R*(nV*mKIxFLXOHaKZprX$=!{HM>Bs5mc0T#*<1k(pD(qzoLF$m?ZG)kfwuE(sPUQpi*iJx#Xk<#&8 zHR{XBo6!u>CID#Hvyhux=D4p*Vcb2T836CYlyuSG`?8rynyFN2)m)&>@?uD@0+r)y z?|^0ZVa9p@r}){v-3O$aZW!nPU(CIET+HhmK7K5RV{KJr8KPB5Nurdc6qU57v{Ipv zltaasv7{AKX(gqSBxER|4V5-pWvR3$(l!&-)HL(Eo}6<&=kxjg@q2y$`~Gvz3pMjz zp67n<`?{~|x{LF13geU)N=K5m@&Ttl$LF#7O8}n9=p4!%M=Gt|&cE^d{z=P6c(Pcvi zPZSE*K!@I89=vq{Oy5M@J0rC63dtbyAdSd?H2+sUGB0b|WafW+hCHR_Y!${>_0?g$ z9vft{H~8?PmB!7&!t-C6EEAsf&=RNrf_~DN02;*mn#3slA^;?hheQK~|GgtA<40M? zbNYC$?Ym*3U0OSI{)tlkxQqFwL69yNCkMcwzg|mB&eRz$oa}aqtfGu`Yh*@H%A*;F z85e;k`K}IU)db%qsJni;0|^SSi*U|n2ZaP4;rO+N>k@ zq!$fzT{!$|mXfT}SVSCvwe4f=8HQnVBwm1}=el6g!pEJ()=kUSS7~CJC_9-C?1i=b zkzmAf`5pD+-aQm_yv1G%*9#>fTXa;!+^Q0gj7HPx^|z_$O7gx_(DRavgx$T(MGsoH zGKD{>xO{Ls_nmgca-X1Z?a}F#@mXq-A+~+j)BXUoZf~#9p2Bl=uqjvk`UxE?!gML6 z0tdlTG2s6+?ks8bbaxsfzoi*jSXA^(Gv?(DL4(;HXlN)>o^;A+V+YAuXWZeBPEQZz zcU(2T`^*xozHjMe$)Ol^1&0ciQop;ldHABZ1roCDQv%Zl~1!V9_FiLp21gu8YV z3H6tegc_aS%jn}5x(FcfU9E}(4jc$r?^U(IH01-%{QEZu3mG}jZBA&`(_u3{Ol3Dy z40wLFslZ3$sq8>k2aKD(2i)-b&BgFa zJGE$+I-Q)HKBPMk3J5Diy?lJ274^bc%gZTi#!HH?OfN*p2oe}gl9DK*sx2r-d7|6#k{P^zq{@2uhw{rxQ0%@J)IUrLk6^Xov?ih!r4h9LGiVBt6EOP7Jp(=NhU5 zTkz{HP@H_O$zC&4&6m{$yHp;ee;gLy;28~s4Q#U$;9p;M5S6V>y8+&YJIV#4p;|~9 z>rHy0TLx+9en?1yLMdUZfi%mLu!w{g9!D0lo@N8AAc4*nVA??M5n%3 zNJw1Y)sAt%eClb=Zx+@jq!ILH`J-JgFs&?ZsGro6O%`buy$IJ&su;|i=tV+g=9O8} zwmFB#M;ONX`Xymf!QQ!O!l7u%&Q^QBNc%lon>$c|Lef2uB5z^-C>k7ICsh7tK2MY7 z13VQ+H6Two!$b%({vkh;3*s3_oz(zRd=3!Ym1t@rCOw+@*Vh5-nN1$w!>w)8-o_|#If%OGE0 zS8s9&q@<0Y?~9RF1@hYFkKlvWi;#32O<269n^dM_5eWACBjO<>CDZQc<2J8g6v_}n;VNldIaK?1T6Rn2<>W$Z+i zhBYvQ3pnPk#r^JMJ9U5K4BxPPEj*WYud`FPuxyLOCf-IiVq#8woJP8_@c{4!^q1g-mtt_Z#i-0X6IwwFXJ$BJM6u zqU0C6#6kQBUg9w-xX2O1+F4b`V7x<)#r=>UKY~Ur#F^k-g4i_+tJo_{TxboeU4xI~ zsV?0i{sKkb!Mu<}dm=``BfFAf)QwA0A94Nks1uH7-|~5Lx&W0JMmz&YxolEK6@w5g zg9>#EkxTyY7GkcaQ9E3>!G*nH5%+2KzDK)hFUA-GqgL#7KZctjXeHvAdnZ}^9~Bz? zm{MD}DkG@O6RM~859|(S3T>Nc6j~id-WzUc@6$=j8LQqR8Gvvc?6$1>BEHBxW%>OU z*=M;AkN`zf3^3~K=gaAo!g0$sA45L_a*`}%gUd7mOR|`e^{A(jG~@0~xL(a?qEOo- z^STiT4$zfImyS9mNwsE17GaAN6clhq5+t`JUjprw)^>sC61Yt{-bjmG;kEVAdt*co zXe~;M85dCB)h6l&16DxvkGViOiU(kslN}szpPh6=rV=*$ZSBRkTVEdqr?+3=SI95S zZY+BEUfb?}5#g>zbj<0rv)4J2K)Ia5-l?~U`_XpsNalM1 zZ#r7r*zim95DK6?`dx?+P^l8h>Ba+xG;#N(Q1iA;K>>)G$OLUb- zN;I?sqZ9bRSe~Q)rE*I?%+1uZi)3IL<^Cj7EeM?sCd&b9i1U^>3$6fijRj7v-n_Z%oja24lh*n4xAB_yxm$&!51i)ZmCLl{l2=|cK4lK zlbD55iMFI~Nw(`VK7uj`l}*Chq}&2|x2|7$A7|tkdRnu)00DeuNjk0>uga6ZzZ~I1 zuc=*XOCuC$>E87la{6weL}KtTSB06B8!AR}zVR-HWsxI{lo8a+%d}{V2pbxWuj}8s zP{`n?zNf81(%0A4k(Wg}L>?Rc#ECx_~gk&Ts@?MZ5T4ep@G2*xpJ6i>TcgYNwN zauAd6S}`4|T=nnRmiAdkZ@AL1Lc{Q8(PA4*>y!9@Eed2WC22XYAj#tW_WMgYCd;UFE& z*}yDprZuwqRIZcoLb}I)(%^vyf#NEPcHav3OYTSbZI@8>kNSL{o+D3_toPj zG*nTdFKjr7O;Z-BI0j58QzGG8mwc9AM+J zF(_{aMY}t3{02I-zCLykM)g;;={?$;6A&6^Z*XxUgdFQ(_1Q^(yuW+sM=C%<9$?RuME*23=mpAQ&ctt z4N$`B#oM)>ZjMRf78DM!PB=AQV^A2vQJYRR@IgPWMqz<659N2A6}exr{ys^^#p4c7 zkDWVok3lp1lG1K%spPrUTlf)KR}*J% zs@Baw`l+J=EmG=lu}(7-@BE02MO0BA`CWAda@EUXe(8CmWyYW)3#i*`27dfJMRx6waf7J*Grtk#t0{?k$qYvP zt}pv(`te%hpjNo#O?XM}k`}V*#eo(`ru7(6yKi_k2`OTe-O9>Xf0I$$fZ9O)&y`N4 zpgM1LcYXii-X8MUAXY=VnzR>wzF%v!PoNOBp3H_p_W~ls#Q`Kn39ZbS_c?6CpI<}5 z!*vwV>k(5V;Ef@e9=fwWWusU8mNs>pZ!AcGCRz5E?+4*UIgDWS0I`i>P%eWo(hB@G zBLp>-6H;L4BrD30d>MLMueH?*v~uE`Z@l9-|7-Cg`}zZIGT}Zk6ukHq))Qu^ra9go z)nOqaORXhTU6xu8p$4v7<>6&igAJ>6vCPrD!Q=kC4}*VmZzH28EZ}FjL3p)tb=rKCB{fyU{3rGa9C`c=2?z zRL=boYRq~G03MzJI?{sObnt9`(J|C5mJ}U)()|UT09cI_6*EqHgT>I+C)Gz3|G-FB zDs9-?30&i7PQlfH%pd90vP+%3+|JY=CX+haWt@HdxqBbSPnWemHQcAj1OR6mtS|;V zp%g^S=#{C(VL%dP^X*oXmWu%&TVCjFnHyav3y7te+BQACV1b}JN=~H+bo=@2D7nkx z#jZl}pYC3dM=yk%dgTHoeFTvssHk!?j;1u^jR@q1LkL=e1IVToH80YiB`UMhZ=}@d z{T{*qX&i_(AOS>$HE(De%CMy|ep!c%07-0R-U5U+`6C!x8vKgs`}A?5&7)ibB~s2Y zFlX|WQG%_wyz}02UJP&SIS1>iuPOIBgOcuT{Ri5D9aZXJBq6T!H)K^(Ni>+Qv`X@U z6*CdRIMtY~Hc`pE=vsfb6a;{hr zQ<+JGn08(Vnts%}05B4`2|5l6p)ywkvaeLNEqf3}D7;VWy`a#T95OsJl1X#|I66{( zCIbggyl6prSz<-<79?JTlYt>d;)IhS`k{Zmq}Jozl>Uc%kTGX*k#C~$w^NBUJiva% z+bA=8q)5)30hYYD5D*;g>u^;UIlG5@&mAFc zv1LqO9lML;D?OO2Q!xgs&DNqJpSc2ALE9B6;^1HiCkAwlR?c5wa81o^2fc_Xx@=0N zSEk3c`=cXxW#u-t#|DxvpbCDArnQUDNMClpIz%8^vOZDbLS$Mz6s3_P%0VfUt?*j3 zXj`s+5I3MT>9IaU^F70#D% zGns5qM-Jh~(NNJ@a%XGjekkX6MPsm^g4^ReY4}^>#XS~sh%ELCpuRuN>76}Yd&3Bn zR;CJ}QO|AqWSlt&FFW7e1P9gir7zk9uTP%Zdetj0;3vc(&}@II$PH*P)~Y8J|| zoB$~l!WR3S6+(yAs#|5gu0?~^!->D?9Zn|Lf|y|AAV{Eke|JbD;Q^YWbLOvxS192b zV4Gv@zksRKBHi^X&}ai>aO(pQ_w}$;sJlX)7qOXjR`HLT6f|)HtrA~h1mT{-Fl?r8 zV`9DEiW)Ks{8K`Ibc-*dk5yMx;>1=_@dS)k2oX>UD01&dCplo6z_VF<1HM$;XaKSU zeof$53(52HIe_CY`ujsN2o;yZ2%6ny%0vbBg7pPjURkYzHpP74#YnveSxKP;>_P(y z8m4<4m_8x3${O{)H|y0eXDbd+^PHa;2uVrg-Z2_BS=dAKB24bsWUGVF=satD%|7yh zL^4Vwbl*kRHAwi>mjzFsqReW)0wX4GoRs0>jO=#wZU_QIN6~wQ^ukqFK>8v=(5PLhEAl|0BATLf?X-$X+)z&qW81k8Z()!PM8@()l(D4ROU5!TCQBQ3h7$ej ziIQUr@$72OSQ>iec+XB;&pXqBQY`*grFFW2&(P*sA^k5HKl`EN`T_%eph;dtLt-4l zYU^I8n1k!Y=|Uf2T_oHM=1+@G`?f{5qZE~1Uqyk=@j+$E8DW-f13?Pso?FXj73{Fh zr=$94EiI3&jyC7z?n>B#lJfajicv&)t>aJ5r2cvCo(jxQ2Zw< zoVw&e6J~bS8e9zB@!;Ig$Z*tg2rk#!wWGoPPI7*F8Ej#^HLLt(GKl}h7%qX4r4i-O zDliQV4OjR>Itk!wIGK-_VxD-J`ZcNdxZiQN%chsai*{eV#CCu@#`DlDlV zXN{xm|H%H9d{>rIbs+qX-!Kd(fY@!|`l^5v6+T%i@?%fdmJ>UrBb6dE%wj=DR{3_C zPt0{-oC1Q(_jWWm)y7UVYncCpp$rLz$&|~J(-~1+Z@zzZ;H+>gPx*k2d1wT={f(=E zowbBJsk~#7DA6PZW(MzvmVVLPcVjhtbe16`?+vC5+;a@nLkv8M`~bs*Drl-RbLR5E zN;uW`tc&{1;a5%7j7Oa8fw^8vFt}|IHci~DdtGYqfMBP z&UTz3j=+O;s-wn9J&)>jWxHbz#zAX=`O-`K9N>^{vvKya1ccw_9G}`3bJJ~~VVk8B z>G=z-wLxWjafn>9Q@G)!m@3;@5?a7bou#0Buc=YN)pl~`Rf!1&S)h}&-&j^88N>_j z&dA7&#ZBxasV(7#Io;=ay&rYfRkpB`=~3&{lpoTgR9amE1>HV-etA<$=UJD4T4yq| z(aLdbI6BZWmuY>;jt$WF9@qB|c)g)vCs%p)r|gsV(#RAy{~ZZm`kOaHMAML8jL$A( zvy{<|z}s953EBe*3!${4k5UfUb$}k(ED=e~c&j$5-k2Pna=|`bdQZe_xLF z$)1m3K_dV(`_K!+AbtLMDjR4;Nr^r~VBnGR{9o55D#$EM!l)ZQ;G1C_xJ$NM1T!`4 zJG=VN4p0In6b~RdG!l7#F{7Vo;`Bn(a3Iv257G;kzle=@UM_Oi?%`-dE5+A+$j^$= z=Z!&4Mi|0zbTFLJ2Iq_@`(~|d{EEI5Pk3`B z@}y^Q6`^wHzk)zcQ(C0FxY%%F(>N%Y7)#$1bMoS1UxRV>67>c^t<9Bi#PY-!P5jCd zgLl}y?M{%U;ObN&@2n8PJW1zbz9gti#6Ta-gg>Qod)FT$%L2;WRcQosL+32)udBKa`T18IXLw?0C%3|W zWWH3P@QFPoC{d4t_yFVxdK%$IDq<0|i+Cp{5Ft?jTF!D01Y&fUrtt04<1W0Qwpi!7 zrSlU%e*B1cV$&;W{sT^FR>B5i3RZ&7<%(OuxC~WGvdA6?#+L8uJ2077+dO2|mecr} zZ1W`+hlr8g2;=FVn!K|<*_-Z8QMYy!CG&5g&(orvzg}D&w)6|J5QFMukma-#PDoVP znJDiFkm`OE;^kvj_8XgGg@+(Gi1ZAz>tLNQ4X>9<4heGWhdF2}g5ToLh+j%TzGx-0 z+i$=R#;t?W{hwPeN3A+~KMUk?8Gx>k-iQbbBU-*HW-x!khKO_PLRUBg0k<|bwz?DXNbAKc%ei%u@d=NGj zBIj9Q#R0P!$$uCFnSY@$>06j=Q80<>%qeg(27Gi6ce#s=GOi+KjSK}Ms3oW8+LHB3 zuFI2#zOhp74`B)@srXJQl1<{(4X`d)wK2P1fZ2OV*fH?ALKl?plqE|lij5zVT~LY$ zbON0tDtBq5ch7%T%v>s@u<&0%sl99B=fIi&nD(jct+wO#-=MGBHiM~Sw`c@%o}9r7 z4XhU_tQRU5Sv3LmiW%B?{(s+r_;ea91SYx(GO~EKE$yVSmUrf~7L5xubpSDG;@Z>) zu=G%qEyi;z#XV4(@7t{F^-@rN`QINWl83ec!~$LIGDP##(vF7hO_quJmk}1a1LQSS zzp_aL$MG7)049U$0qm*E>{fb>&M3-}m^DV-H@-*Wkg-e+60Hwi$`-Z3T1)Y*0OQw#yJP)^DAdI!;_v*{pVLs0jr~fD<%$SLC06ylbbkGpt4u zpb4BR3rJ*)m^&~ie5{CncHD%A!NkF4Oayn6$}pjJ9LzQ2&s`64M5R}VnE<A@20&I+QH0vv(-0hK2zHNs4%H%RfI8>t1hNO;ho zDI=~Kfv5_CFR`WAF97a1mjCH5F$WHO>bvlnas^EhL$X1{%2syGE%l5y$7O??Y zZ^EPmJ~T3IcpByuW66TpKfzFe6sSG*Qtc|m-o0N+LX!ZIXZWXiBqAwktx8derJ^K3 z9iTc7`z4W61EK(O-aR~YWS+GxConvoz#peuFN!yv?%!Db^;noGn(0OE#u;1W8uo)$ zZF;Tze1h(Iu`vARwt7UwmDbOlEq};4x^#mA{SKTLi4J5(H8$&?Sa*2%+?Kiv257yH z`SNrw{I?-X&fFChsEQ)yx6@Estew^mB#>pVX`37Bofl6Ci z0t_rTmaMSHT%Rv!%uc?UvrNLZ;2NG8c+No|^sX!t`pxZzTu6W$Df!m`NJ)1!Flsp3 z%gcs#C{GGC_dABS5l4@UX1%qD>-W^gYXS>Y3ZGp?VIANmwY~AnmOGoyO@6m!eFA8i zZTU-_NrFi8@$j2PSq+#pwq6 zO=MnQ5JwOz3n{hVwRt!tMQ6|MaR6s;8&L_UC4u2)31mgL9es%-Lk`M>W&fldZ<#5# zGx4SyB{#WR%w}76EAaJqTW(a{_E$Rz}5$QRY!0*mAsJaNU6EMMp2|rRw4L3UYFRufn3Ou2Fq% zZYq?iw>AB(0Sg0}E+FLO{hBxEg~anzryNPww_fZfvM1cp+G+JnM0cfowaG15vH6Y< ztIxQcuvfMPMN80YE&v(v?Tl9!N`gF9UA6$lr=j;6w7tWjA^_GYflba|M2AOr?RYI5 zu`D83@EbaxnV$r1V8`vqKrOXt{oPy00IEvN%8~!*8eq$sZ>#&vZZTE0$%hGeZ%)?u zbol)`YW)iET;*I^r|UYiCFcin>CcQ3+$e7Qrz+7kTNmIg}bg9roXOTAKCLc+md=?Q6%_H_P3U@)?6;oG2zb@*?)YV z0mfzZ3EJtq=l+aziCuH>il^$=g%P~cFqf2)6%wvyOAcsfNHLD+ms%yN-0~EHtxEhG zcXYc2FN0(MsNfD9@%s}yk^hA=Q+3Az8?n^7yV3IdwP|s{Qc03qsh6>E{=tj);*RFu zftLq>owaw@`8aMuq}!j=SVgoVYBg%7z*EC1jG@?cG;yYGaxbD6B?y?JKtK(!V|H&w z(^HSFT+5@kkczx-aVU+~w|HQiT674}r=UmMs_IFl)Y7bka8>6d?hK+;OYB6F3uKtq zetF$jhmOH#U2!5Wuo9R3##%Y=j8LeAzsViE_rx?Hpk>=6-k^_-hS!sPJLHz)vx@{2 zMRdzz*RN5=Y3emU2t{JKkTfyKOY8z%E2ro5CR%y!VsL1}>RltN4_h1QIQC#1=Ah-_ z1*XsbfXlwV3Slx|#>a{)I-1L=$&RJ}r91e3(rPWB5gCB5RO6yyRUy_s`8$ak)op{k?ynN~w8!0KJx$j{6_~JnR`K>*>G=d!id;G)v z3g}q-9^Y!Dt~)k=O78HWo#3~13Dj@PzF=n`xK(3TqDd@;h?cATYLYJ_H3?({jE@o* z3yru6Jp<@Cmv6cFxG-Ucf1u~5{K0BrRw^JJISx*e;5gur_ZMA8VA(JdC6kBvvkxua zwx0sp+!k)#s`NsS`KFzcw|*qq`gYtgl{Xtwy0TbK&(N;B9ek}H2wbjRxxL8mQDnr! z=_9G5@qWR)B(3`2+|`Y<2QoIQ+@*KQrH7^DCo+LE|2TT}!48+;(OwCYR~zUpa&Zc=$MImezYSlJ2WKoXh(h zIQz)QhnqF}-S|A%2xQ3{WJ}Q|N0Fjtwx!6x5)P7+MH^4O3*mM4RD>=s21Dfc{C})p z8!``DvLb5&MnrqhY7`3BYiRheZ}mhz@%Ux^s$*~us|p9V`{7{ zx*R$_y@p6!3RA+nBH__tx}GD?^j+~~?wRbTyY%0$3OZD_{IY$KFk3GDO``WrTi+u= z#|?-lvo)sPPRM-gmhYWwO5qO-9P{ao7HewYjlZ<9cSj{cfG**Jx~Xt~M7aRuHgDPZ zN~NUv%8rG*vpe=s+O{mL*9!W#fo$0hn|0U6Q)YTFyO8GUW+7QYIdD4?aAlB~&!iG? za^+$KH!W0PZr`D=U)4s(dPwv~N>Rh(p;rXzw4$|($dOtx1N5|3GzAI%1QRBxecCOQ z!GVnV^9&F$mN%J-C4NgzB`9Og)M&qIpG23(eXC8L&>5F80ay#B?zUf7^o>az(7qU* z7YsYi#`y~t$UQozo@=o&@UFdAjUXHpbUQ0;pMX6yOB_ZSe#A z#R=Fz8E@~~K6^AGT676a)fA)a7CC^*9*iU+ij*#ltD0sWdtm#2Th^HN$e-*BT z-wq+MRheDltUHdwdG~MKOyBocfLE^^CrzW)X2lX z6dSBu!w?P{c0T^weNN2i&0)+}K0kDy_@nv8+AOmwrZ(hmINWN|41AR)(Ctanl_Zz8)1OGPMo%P$Zd1LH% zGcL<0cC-n(PkS9k7%Dg}Rhi*Fpd}&w&}o=u{kTL^(HH#3AL=HFS8=At&DPV^m5Z-? z3UdQAdUq|CI)}{7G^?z+`km7ZSNNSz-X*=&!EuJsHyq8S!bZOhOBdNdWf&792|_l4O%%`R}p!Y-ViYHqs! z4s7llXW$j2zGkjVdzb__)nhAn+?|7zL{MW+lpvDd)qY2qt(xlL3fqJdU(G;>7q zS(pCU9~o&UAjwwz@Eekp0;kHk1#PQ!Gp>JIt*chlU!P&z+Bf%V%`tRxT&#`^m0K4{ z=$)1=%e9;r^W<6;Eth-77u3UZuWBC=nepWXYqlx$vJ0(0j~@?^0!Pb&C%WI8|J(=n z^IEuUHmF82Yu@n>r{_vPKLpSB>~G1@%O;nCgu6Y{10Vv-0&YeUTZ~QRMrUpq^q~`x zBmXS2(t&sn9tLRv=$w3IFl2X-D(EAm4DjqI=8P0m{8rf!9x9N9`ymYp-M5FOm>gd;Q5ZMComfapy^! z6_vTg@#S|t+b-t(Q8HD#BGD}i^v!Bod<>1+8j%&1@Y(9;5_EuaSg#i%r>I4Fl7BSL zCpUt*!qDU5JJbqACyrNmHP7P_AtoynwQwmN1ByeWgDj?ch?aC3o!J;^+wBl5pU&*C z)}lvjQK(jwU+j20I9q1D*Gfx~puR^YO~RX>^_gvn1Kt6tTdGSwnjez|y_RRmiLH;y za`lvH)yq9Ny=h;N?T&lP+vZ+BQ<7lzhlkVco^t@j`-IMdbK;bX zDY=&Q^prD)f-+H3Be|c;T(Mz;wU)*U%J}y$oDVip!&gJsx#dA)F!;kXNRWR6qZ_j0 z_LuHfJEidK9Ur}L?2q!UbW?b^*1;xNxwfd^Pd+V>{pJ`aBpej+dUN-&Z#mZ{+(kB8 z+io1XC(7}PmW&GXiZN+w%*o#<3PZ-2XY3@$JDa~dji4LAx>9pP1 z`PQRcPz1{Azpl<@k17NS_MJNEBly~>G?|AI<4*2B@06292FdQvf-X)0sUE7iBlQ*{ z*ngu>ua#W5D!&o4K!WsEW3F>JSHmzg#53qf5M@KBR9b~sbhw|Z!=|C-0tX~cSni&} zAwxYlv8uDi;aoXG8}@--4SMC{YtpmmD=QR3#Y;dbl+o0*-Lr6i={%X+JZLxCmLvO! zw9EbZ-lnrhcv=R6#j}nu!k2MT`g>P>2m7PVybHfv>#6^_tgF0si(~DRYj+xl%rseV zZ+or%)|{VT4EvExa3-bsbIo+l7KnZl{jQHAuJQ9eQwb!1(|>ZorQ?Vk0vz;tqkqxn z0}rGTYRls`YLEuI%`1YA_wBs%uu*&PRN5se05JfIpp1(057_S(E@jzx!Z&CiLd>h4 zVM{LB8DACW8G39uOeBu;RIQJ8f4B7{!oT#tU$28I00Wql^uOL7d{uqU_VPn*tS9km zxoM?9P7sX+4K#O#8nLz>1WkV8BE{C#g%3B(uBGOsz5P+=8&m)|kx-Baqz5w;ldJ*K zJy!oZcrla$`a=YaZs>BRkjnlm=QD+cXo;04u4%}A&D z>A8b&MV|p{(8nVs30wW&y;U!9s$?&Fm~q7=Ml$T_BoiFZkc!k|2|_yQ;lI7UH0+XU z4xP_Kks@Sh7kU->p-*SCVfEY+3>7|{IqQ!{hA@6O0sYneldYR$zu$klc;$ZKGAQOV zgff{pY_W15bu0m)3qBCQ@@}ozN+*U=H@WT)BW>qRILGpZ))`>@#dLf7*gLPX8$a)D zYhDaXSa~0J$+@&Q9Yn-v0SSoR6~Bu#!}emdfcBS(!cTTqVAypHucPx`KkHz#(l3z8 zsqoN~QHH>KE5dp~;|yJr$@HO~J=Pz{w438WC+8~;7o1D+_~Wtmy_lh-I?Czd+I%G{ zRv4sA1$a#`3oIZ1C}^NMKooh|*L`*r!IHJW_~C0|Q-Jp7edaHk^H1^skl%$9*V`TS zBQQ@7mo<51t$l9P`m*n_d`Ag!jwO8pZR5*tc2#}Gm6dGLgB``T5&s2W(PiXXb_w7O!wwE24xBd zSWFsVL#R$-!Rhig?Z!->ATdSxxKI1?C|{^>Jx5vVO4SkFZfF>bM~vm<`djBt<%9eU zBT#b^{whc!2~DH2oY_l{e~BU*Arr^7HgMoX>pTo~l@@JwhikEek9H6t*aB@+8?M|x zm__-Lqsh6N7?88G_5l6iHO*Gv$MnTi5Ge%~slO=xWwConIPKF+dkT?G5=USLg+2hp z)(5RQ}F;0IL;Rmb?xMxxc{y55p994# zILfhn0K}bxyAc^b0gFC7{;(6YWm)5s$wFgjJKX!(ZplLt4C^2{1d^>VEmYod@4!m$ zGXy^+Q~=U%Gd4r7a?K}Gh^{#E|1{tp`+}?9^~`fW=LzORsGbrVWv$eP5g3um{P$Jx zAnEY*dVPA+h-Ec^v53IK$b8wX;K-5I$`5yU8#FCzJU|~xX6sAP`Sp0%8kNh;Y085eL^ne77>58B_9PkxPfvuSTRsYDWq{n0!gK8 zZZ1k9at;jJ}D8)$}&9fK5%R1YO_3{uZKn0s zcnc=hdW2ClV_ucpotCDZ_e(KBb3=)O>0G}w=<5HzMkOxD%kA9gC%>_kZfOdgzYxE) zophTe_G!_6u*x(tj=`>&4D4Dca4{VFMb)d%HqCD27P_KuAZ zxm3S8Brf=a^6yXsgWag%1+$j&E7pB__}*A>aBkLlCU}xmJPEXsu@b!p)PTn9Bx}H7 z1U&lU-I3q>m*+#KgD$`Tt36Z+a_!Oaf|xOZ$vh-&s^TLftdilLPsd?K zNcds@`UcX}fYA>03{;f$m9gs!2rX7seDc?r9jMH-y!sZA=MT5lUz?_%isKcMMFB0y zL`+OffOX>)FRQ4{LHh>G={_3?5JvaEv zEQ^Wr>wL74zd~2re7hB9xT|#1b&`flE;K9)LMptkj=Wq{u zJ*)XV#j1UV)~%61w86+zNWYj5MyI*?yYGH?5m%tiUR|sWS0}Xg!0mNvVQ*gy7RnR6 zGtCqX%S3O=gG8pot#Xl=qEwJ(>_Z&&QK`jXK7n8DEUlIi9BxMOTA$Md?tVuQA*MNq z^)8$1T5++&0{Pd~z8aH@qz-*Lh|=0qEBggefh_jchMDa+??HvJ)xg*P`DyT?f{_-T ziZGlHO@6r#zev~=ZSPDOk+}9L;Jg0kbJs?OsJS=Y+ZeNY5oI89keFk;hs~&DO`?SV z9as;yj)ULRv_ixW>Uqzm<_T97BzZMo^|FbZ`SM7Y)`Xkyz-i+yHqdX=6oD7^O#L~F z)T@5|DClUJr>vKK{beaT!G3s}cUb1-npPuqYsnwL@qIK8ygEk3#DeR`GIRpMwgX() zI9k1m*z1EJF|k;!y=xr{+U4k8e8~Np|08*Vik34f zIgs!ILq^exLjxe`5j6~s`Q*HX&-E-#@6Z2wXhH@M6J!-!1+Riw>>Sj#KO=+*6d=sq z!oE#aiiaK09kktH!}XZbJ6V93y8eB$=;bPwU0YKsN))+WfT4 z|NI=R)+&jaF9wVJwdD_kMe$+{vFr6;3W?-J|MRAxErL}CAh`>rcHmgLY^2r3C4w4Y zIKK$9LLYKaT?S*SYP(ryw`?Iqydrwx+pyOs_GrwAn*nkHWL2=8gGD}}+mP6+NQ{Vy z8}W$Xf1WaIcjJiP@Pw8AUwad_ZwHB^u)yZO52;MtB0dlQ*$URp|Fa(#Ie;|{`Y#yX zi$t^&UjMT}h|@CcmJ6MEFt^%x>W4lGPxQ*6qHul|U-f@H4Mz!bIH0`>wUaB_w2LO# zqyKj=Wwkw-WPr&GkllfHOtd*^y_@*?|MXife}9B&sUpOEcuki_MqxTRP|!XG?uJQy zYgqY-ZdE$&Q=2yB0rN)G2$<}+c4|7Vbz+%t%ghu?;W|G{DQBtLh8^p(?##+zYG!p# zhcWZ|zg~1;J_mXv_{XZKs64_Bg;x|40@yh6&&LspC&q5pj{F~kZ}$KYZF&3mf;9XB zK3XG?NMtxe-)g&%vtpQTr7xDR``o{lkK+tJa2rs6;oe9lQ ze!!JpTz^eRYplYHy#V!?iwtJYZCH0#A5cj(Jr*YEO)(%9CX`<{;+){D0Hu8r763Ub z2i~(u*khh6dvrW0C~w89O21L*5tAdlK*&L#leDK!Og5Ecl7c) z_+V$VV9Yp)_?ckbhI5>a0%ze&WxIUZ#)>~p6qu);C%mYF85B2F*4^jR@C`7Cu0;ESkq0tD;R{~;>Av;dz^?OumNABSyM3)BojGh* zbA?ni&q`JREyx@3a4~Vv`RmaN-^__Gqx~AX`R7RW%ku4CVK;nk94`ID2`R5wxN{e1 zY~?n2REc>8I@&OPt13DCt+`$DE|b1q0x#e~AQ(t*h-D-6BRHRL-^fH$;tEDw({?>G z%J=Nt@e8XL6%t~x%at&Q%;Xbslmi1G9)(o*Ey%ynva#f4!A1VvcC>miQm7V`4#y_% z_Boe%b*C-jn^0(99JeGOjNkXVw3M1&o0fcUc46tO71yJ~PlVDbkq1(~T{O zQlcm-q5!^~kTmI@#r=9P&sBH!W1{7vNGY}wFY~}#iJwx<`-IMbD&ummFn_Y6&f`N;I-hi$}6YNL!Qu^_egxC=PeTy}x+OzK`O z?!ea4D!S|G9k*P*y-O9Dcy0;_T9Ac*($fi8_!1Okap8s*b4Sx(NAqF3<$M&sWA+BRb=D?aZCo zTd-oF^px&>9I%`A%K$v(^HnIG!8m|HPT?S^|`**2I;MwA8oq~_DMEf{`!*BL+ZH|OdSa_s@3kK!3ia>Mt`UQ z7G^KHfQ}?l`n(JLXr=Lis`72uiBbVKCCubm`W$R{(*;2&+FmohYTOY~p>pr1eErr0ytY1~Xkmm+2f85AQl)i0QeVX}d)am8V>iTCqbXk%jCS zQty33%^DfT>01?q;s{O0E6#3JqG-YM`eYBGd9)0rL?Rkx2Hz=Yli`*W^%K&M+yM`m z@c3@5IX7jxPCFDo_f#%qFtjJqG;g-~oWlBX)Phet_8Z-_Gx?-nSDDZfa!1&70Tzez zks}IjdA}3x%Kpp34jmEnpJbI}o7tx}fT8xRX9&iS;_irJT@UD8*NkoG{+DmGpgF5p z59Z-56;V7Pp{6}HrJqW{Stx*15(c1!vfH83yaqJb#zmOJw zrnBh>8cI6t;Ff(;?A<`{m^TrziCG1{%M8ktbkLOq~-?S z=~%le5ff|LQlyf^O#F+CM?!<+t@d>)^ns-Fh|UTQ+ZtjP)%jCQ6C*NwWtw64$}9_> zHT_4#IQT!oSvX|i`=q~PM?DOAvLE%={eGW4KW|6nl9UhYBlQc=o%j6I3kF=fdG{e01abjMQg7?UYJTV6rnFO56lS%KL;Oa$f6(6R2|G z(|`>Mv{wvUZeiU~hx2 zFI98f?+}+|9AWkw4ms6ZJ>^qA$ZtFyYu{xhIR{|Yr~O&P_78Yb^!S5^>{tHiyCB*0 z+x7*#fX8x&@^bFA;0EU@mK`^^L-X_Z_m?~BmY^c)Dees~!hJ)tbm7lNIYijk-T{G{ z!7tLRwv3h37{jO-L6)~PYZi1eq2mEY#?j*vGl$m{U)w0wEe+o84V5)8;5#4 zPTg<{R8^o=pZw&8Coy%au8OiU3l!3}khOC@Km~gwXtA-!`1z*~bsNpEqLrcwv9` z;ob>ngvM<=9)uT2%2%FneSa@z2fiuLiYvQRPF!1gUfD_y0)*x$tmRk;) zNyy+Mn|)>5qjw>|#&_(lz~cZrTCZ{Z>>&f7Y^Y8?LoL7>+)yXx5x(2u6NuTtf9>pQ z$7p$HfJlYYXM|*Vg}iJ*IUL%)ZR`@rbeZGBw*`O5&4A79S14H8E_5@Ufq=8kfSAqe z)p{KU_-ez5P*--nXv6OZZv!H;(%Lwha#s8RLnI^NmV2m|1!y4!pw(oOklp$$U?v~y zo&u>(k@0G*@qwh&kmZXGiZ*IVBNj5lH@Dp;vQc~c(K`Lue6+jGIh_=&WoLl1*4 zS41OOsQM0~Jh=IOC*QbUOg=+bEI52#T`9gzVSm|*43=B%?K!>Q(1m$`7zp#Z3zp*n z3vY*R{3L7@EE_t}rnLBm_)zy~q;yXsa!!OWGXd3CZ86tHxj7Qff0+JK2Whjm>$SXG z$-%A;ki3`kbhiV)B0H@jr_n9~qV6Vb3}!^Ouw=~3ifhZ3XKZX+uZ5;}*U1duz&Qgg z7nf*J^|SrW2a4>E>*y4MjBuuhg39omreY#Ga?OtqGKO?T|Ekz>rtnK;;>`zd!6Y=I z38rS>UXU(Dg06kZ-ludY4sv8axfR9&1IfUn4o4YZua)f1q25(Wy!TqKSTYD$2&SCC zay|%E5+cxTP`?P19*MW#4^kR#iW93wGcR3?)J3r<4*hbTdZ|uL)i0M@Wu>)jR`R&e zjB~r=(IT*NoC4cSpbgXA!OxuxPfYR$GEo+m`V)VOA(#sOo%{(ygHR7n{0Z0%zG%W4 z*NRhJjNXO@fFOcG3&0y&h zBF;LzDqGkMqf!LAjNIc^9RU%Ecq9`>wbRKoMPvaH zpwR;ad;pOnyuWZo6Ps^R8U$-ln4R)K1qWJbP`<@=_I3c9gdVK-DHC^3aK+v~W=_j= zt^I=O8nO;~Ts%qA83euU)tkgq0HiQ!$IkG*+Y2Yh2N1sm@-jkc!5rK zpWUv30g^9K_g><8C%6}ijBEx`@bdphm z%Oxds%HiIP80{7TbbJDnInxEGqT@SC-k@4r*Jp`yo=c&8$53F*4Ongu-+3@F&^cnf z9iE~U?OoOz-t4nK~UYn9!td4&$djA1xLI$2#)IH+UH zT<4`Dn|uaOqr>B0zhGzv(OwgqMC@R1;Kk_G2uR!egqh-F@w^Y9C->{NF1Ibdvceo@ z*6$n64)pIVvwDTaxTy>40^@DvSf|ixz|tT#bOZMYY~?qAk)5YQC3PW~1ROc3UptN+ zIA~Nixdi=TKe9#Uw2~s-XYc@NodSIri-=0OhWW@#ax%&FHgmuvc!K2xB`BGJHoP() z{u^+=j37e$`vesls{re{1ux*AA0cy(L3o^KPfdIZg@Y(eCX6sB#8VC?WN3qqp#GTX zF=d&}s0Bx$^ot@{>~#h>5qIktgi*JG#-LqgEcM`P_d5>JAR;An6tHNpC^Q2a+fCVTljEJjSi%~m_t)Bqe zBI9b;#giAMNHk}V4MCdbPVU5&`%5JMmfQ(ZiL~Ul!5700GcL4fh7*sY6dkt_H0359 z#{@pN62%f5yp}KR#Z$?L#DK?gRqxXLm*hjF$%kYPA`OPZ6*9{&H8vlta zA;?|&4fNf65qz*l6OT3}X?S62xq-foB!CazV2yt-MXumFh28~2FZvKu0riD|c( zl}&ic&<;S()zV(7dP2TQCHb9__$G>27^2F^awg%5zc@kS=;&#a8 zr&jsTMzMVzc1IxqoHcr1I73Ih3o#8=^SfRicQVQPM= z8z#_Z6`bUeCWYf21AwPoE3duCo$Z6M+odfqLt2@>Zr-*2CzLGu=UB~?tNraI1F$?g z-GdIs$Nq$`ARtSC##cmkh&T~}8m4S^&`%3dUc>lfQCnx)yB8Be>RKtWrTB|}9VUg? z&w2^7Dp$DrOnw1sZZK_W7SR4;D%a5IIG$WQj@%Ttio(yzwt_@e06jCDlu1iec+n7k zc5^W~&wXi_immwTW5LUC|G#@nMnd}Sy1QnZ;z@6(VTJHZxvl~`_17|vYkkpqkUyxa zu>1&Zo|dk6a$6x&9pn4q$Wnr*_tUK-PGg9N3<+$$plpdp`Yl&|=^sx6%u>9RTp~-BaLG^B2ytS3Es68vNm3UY^v?Sa|90L@X62 z37LxsY=hmPsWm^<^#osc+=?j@^NQ?>?^?kCrwL(#V~zstgok*_#@~J6y}6t$>1?aC zz-0zb{kq><6?zbh%zjI!M}I#TeDdx8em$|^HUIc$#c+EvBd33ELoNtc@byy@2DxN` z&5}Pa4zBf!>D(^G3V;X~nAl{&zx}wo)jVNd-mJUZI6%fSpsM3pFaCrgLLaq`ptgUG;=2$mc@JdYI9clVuqgI=~L!gE6rapi4j zN0s=_VBf*t2jcs35DKDxYe+FRg#If!81k0fEttj3>%8_kXVuCso7cVarrAMI#$j#{ zX4S^^u$FG*r%j@pMMG4{#KwHUAF;y8)Tgfr{Kqh9`AzQZ%kNo*TT}yqMDC2-GgcRF zk&d&&i<;c?|5g`zo)?;_W)3Hm$E(8!Ix5$eXyX`t>Mk!FT%csHI1c6I+_1B z#+Uxmz3~>YD)IK+Ne^}M(#dfAuU}{ws53gZ98GvmjH6+Y6tuh1h(6zh!;yVO?Pb~m z4r?=p4-UxLK>+OYJGXIysyGFB8yg#0K*B=cSihkctmVX>y07!F(;_<2CYl5K!8ty=(l(3^e(+Y=>GZZ&ES9x@e{~G6=ZDi`}zxX}%SG7%6fn$A_ zGK)i=72wOWk{0cakd*V&B%)O0S>H~HI&(08^&riay$CbZ5S^!EesZP3P|73IYQ@SKODFlZHAC;W z>=zEQ3L~AO11Ltr-6uM`v5W4me^?Ug*_#4TKbiV;!+l4>jqFH_158(PS@ZcDGvQUP zJDA~>U%!_*QZ%++Mr5uPU=3aM4}t(Bb!c&Up&!++C9F7()^y8Gwbbl_k%MbuAuuj= zYhz;=`k%KEgm{6CVTV+i{Jz%=y{gut&eg|I+GbPQ;nww}%3f({tPUJYx(>l{s>7#{ zqW4OXf6X5@QYrp78;RyIzfjD5YY3#|b@PBBHesVTXA@IjprbinVWh-n8Zo|>7C(zE zV#C&m7fOA^`lL+N_VUwJf9E0Fn!)3+iQx?-Od5p<8l|~(e9*QvhOJHT&%}k$9_hL? zTCX(d6}OrJEFBB_-iPS>wzywk{vwHf|ERv{r#mZv>B`R;|Q2(FmZu&wWBqCzQkY)@0+Yan1w6JMTsI4<~=-H}}v*Wx?TEnl{gdBlTxKeR*%r z`_BGahQWNF6BVQ^O)O1i2kaNihQTU6=Q2XoRMW~11~Ccq%Cp$YKBwKk-*J3XUgm{0 zY0j|e*%%c+;Sj9mQkkU3)m72i!+#N|cBd&&t*>D-M>O6VtvYOJvqktw3}0~A+vjXp zN;!9p>Z8vqmWU(sILobzhY+q>IZ_9_u3}mAvZI)EiTbhTKUnqX-Hvn4q>X<)zWffNPDxx8fkisV8!!RGAjnY8KNve9!UjBTk(r;D?hl^?EMvZ>^s zQ*r^j+drA1_G@5c?vjQPq%$X4t6N@Zt}iwdUUWuHc#%h1#5sbLnF$|>ToIhOX#^YQ zC7zRsn_Pcf5}jRAcXwS;MC+o~SxVvWRfU$(rdlg6?&2%dG+nFFMEbRHIV_E4VR93Nw!?3C zPqb(3(xa|(CJ0S=W7sT`@AOo=<`vMC>f{A`rTrQFm%O!zAgaSI*QH) zVfjPntk>V4)K$}8&yZQ@&hySMiJ}%UYSEN|-Q|R>tbeW;{}lz^#ecPhR)v@c$HCVy ze*d2$9xIx^^n(Lm={6+P3fHPV&mU=NX}#?HxPd4-)YIfwh@p7lk^LlQ+Xr7OU|N<# ztgUattc8X9|X!nYYTeX#CfZVH=H`~{is<#TBz!rZI%h2*@%_Sk->C+7bhe=`jt-Tu8XfiHLJ2pC4@jzHE)c?&gu^G|l;>0kwG; z|H;ekU;43cO+V*nbWb2P+{GTdcDt%h06~6RJ%|F4YPKi#0N1lg4+;@e6uN^fl~Pnx z-0EC3J1qW^#{S>rB?loduZ<5#^&VN!+usYp^oK5C>v>(z3MU}0;p5EPmU>SE)?lGF z>PoALW&aN!w$#;csJ9zZ?TNw_8gaxTfS&?YS&|?&jVkoRkSTdWB7W zRL4d|*9Ba<)wo@C5l@Jn0DV?K?XW`GJ@ReDSjJ1jWCkjj1lZTW1!((KZ}2+)cUR)o ztrMt#I`CZJ$>dqNr*<%@iB78n99?UGslsyo<##B)u#S#4Q(Ot|3 zhbjyXO^T7FU>-KJq0UzLlHg@{!W3Uu^3`eC%WMOI0(0}o>zY<}>im&Sa0kr`a%mRX zBx0H-Bvy;}VFT=~@s7LcO@NNj!FTL3chwmCt{dQjIOCw3wcoK)%z|TW)iY2s3-y!hv7^Gdp=at(-=4*X5OvS-f+aO)e5#w& zp~h<4(|mmg#4bSdO>p)t(oLhvX0pwlT&H{Xm?-Zl>1)Q{5oAR#7n!{xT)(F#Pb_@w zzAh93i82W41Jk6@@QVs>_r{W-o1kefoPUhtEHuK-e*1%#O3XNU(GwWu5uZ48(s=MJ;=-j-18AvHqXrOHL_WbVKNQ}(dqO*gn$yu_EA~WV zvRt-(XapRXq7b9bBQeLo3v|%M4jrGNVS2~G*SP4@fij_&fgKC_V&$vO0(&gGC3N}y ziRUP=PUDY7B?v$$B7!p?Jj&Y0k$8FmiB0Ibf9qsZoD;A104Co_NT0sEki`^YR{E6QREm^%irXC8s}G%;&Nt0ij7qv!xVj%N^jJ4e# z@|_YxGz8NuJKhNSFh27?`{Bt+hFPJ7Qp~o8ZH~DdwY5A%{>#bg05kJ?X{l8btH^&! zOUbO4`P<*6r~a;}C~oX}#8!N_zSRL+YZvkD$E{q*|F3<>(#}>K#i%a!tK_7l#JAWw z*x9?Rl9iPgS9NeXW?*|%&FRn)r^B{~T~^79Z?!#ahYzlomceC>n8h_64!YPL71umy z>0+yHYwcuXE3W2r(CO&*BbL^-;_9|19IS1%j#|1hT!VTMHqawHbfI@b=ZxbR54a0!Q6eEn z_qzN?N#K5)0Y;S{bLX~&uo|1tjAq{{)73cQb}U$G_$Z_8_1cv&TFgvx=S9A29S~3B zSySZj+Wpzr;?-|od@LWfC_3={_yd`X5*tmAZ+n!o<;>dB4V!;52Pkme(PC>mA!Af= z`h{NW(_OTEEHAEa;Zt7Z6bIJz=YUo&qh?*r#*gLfCM?Js${=d9y{-M{7x zE;!(vlNz;M?`#;GRN3swFG?(P7*D0QY?fa$w|T=R9pxk55ng+~@NAK~m)Q`QRKKR} z!cNOrH)`k%?jvXPD{P0>&-ea5+u@C7dvrkY$$RVN;`5(IeLh*4YxVL`S9!HW#PxGe zc2gaMi{fu8{`_pjr#0VUX$|A#8;xrB`?m^jeUrY+e(F5em%%E@Yr4mzzEoel>=&OU zV&$k3<I}I$K;T>7L2I9YiuTWDuofWd9mO8Hv9J@&9}Wl9vCo1IbJMS38gl*+>4H zJCKowfin6x@IOa(l@S<<`7_svqx8 zl`8)%DSlpBye)NibUw1l>ywLr9}G;C7~#^*v*?EeP6FC3MWzMQr$bLn-wNqzaaPu; zx5wTyOdTgo-T(NK+Jy4Vvzt~en(NIohl%I+`GgZDh4+8?%KuZh^S|(={#N)^OL~kE zALziJtM~SUsFm3Yo*D$YuqV&iO~cEOx`2_cRjAQ`)*8K4wH@C5SdPbkxNxB|vm!O~ z8|r@*tn*odLtkD*_)6SvP`}>=BRh7t-={5k!~Lzt`y>X=9V9KVlq!Mz<0m%QGf-kw zQeu7MQNI%VaJ~EJeDe1(*M*!Y7%T1UuoRuF;ZPo*O-}3y`at!!4h~5yyBpMwItDH6 z;Xnuu>a(~?=_BP?%RsSCt%*cUU$TC-ojW}cqQ-d5>8T&-&!=((_{#c}4wLbv^-f)E zK|lRswHYt3u6EA{8PHQ7)cX6joNoHY$En;-UH`9tf9RW<{PNzFixvbfD&-rkIM z%ZCGl7Z9-zVE7OwF5D2Bhi$FG`x-veJoUbOeVw_Gl^?2mH4dfM^=b~~CVpZnfKo+b z4FOSFV;p&u8O2ktMV-=*A5tJU-3k#AY%S(fDBT}!SAdYSdclo1$TW*SbH`kdDFsS# z<=D6bKwq|eIS^sQ5Phx5Ww<-n(kuQW=q*`gk!D}_|>5+Ir-zZ9BeSMLM(AX6f10PJys0K?+yYAWlFJGp6 z>@?%dhCMXk#YxmikVyqKc|b^txhWVA5zXB>2bcbBFc>f9U{%!4=Ps~xY56_LC={|p z#i>*dv#HgXGxZs6&0SLi(j$S5^XIw0y?R9!%$AJ$hX4I8lYf$I={;hw>e-2Ht~Xy3 zNGn=yaXPXCizb$p(}5CC>zhUBgzmiHSqoH+ zK23Npzr=%^re;ZZCM_e&K=a_idycOa=u^nEVfqc#db(0MFw0*4d1wEZ{Y3yI<}#}w zxR^M#4X6CX8xa7CpzXiyk@g=(KQIz^fs<@qddPon=CYVs)LYUj zW|8S2_m2-AqCK2L#=96#@OzG=&ug~?o_Y){1d;zkT*=3mfD$CEaKlg#Oz`;G2K+Q9 zI~&r(FPWa6ExTyY27*i`%48tKs%mNwCs#nbh))U+0`5US!eJ=mwPB>YYEp@vI&HVEN#DM5T6Y}-J5;8Cps+&(hR9B_MAj8t-!AUCj|uuM`)ukSsC@u z*x5pTupw6j;CK92^8pvzqz!b?VN+X*cIfJn_FJ*hu94VZ%c_>b)q7(YAZ7GM)E*x& zl>p4Ux*DaLsDje~$!cw7H38)ItTwnDnG%k{CNzMP=%3yloLI|qKHS|E{Ot$&$NP?P z0fzVNYxaA+Ox#?Qlb@d-wC-B-3U8RRZ=V5DR!chc$s6cTuwUhM;uM}oq^Hg1$swYf z!LmY=t($^|py+dU)7%s4o!s=*I#(|AU8u4N7o8lGFfMqL;VonZlx|2H=GigOul15< z7@?a`J$d_lv=L05^DNA$kucGfXwFPU^=iBw1fdCuAk3RPh2q;}G*F|i&Ruw^>1cj3 z4@7!iQGZtUwM*PSdpCnLLc_!!)Zw6}$3)uy2D7+1ZP76$y-_f%H^UJC(V4 z%^zX=0ndBO-hl&&9PO5p`-`6)X;2+~0AZwmIH&~EiO$b7a1f`+u?`%@e)_06-yGzzgnt;YsDC)7j?2?IiAHWdn3;w8889GB z=tbe@vb)choZbM(F$OdMSbGLqME_+CmO{zbN(Q!2;7rC*rg|d+J*o~AUX{7qlF6Nf z>D=c9p~T`K;;E(4V0opLzgl9USK%m@DEflXcd~|E(8UX{H$(q+Em6c(mX=_mu*5XT5Khx!y{Q_@3V($%hC648PDPZOQ_}=RfBUnLl1mNUTme* zP@q|g0ALM5E$%X*ZA~G8ipxL6IDfRT^PCB?+jYfsaBSx==e8w7UwaLA1NJ_G5}go#Qw*k);ba*G|^?>}s-v z;Ac&(M^6?L%+r&?(MY{C-nTGD>E(PSZr4b#{97dZ?!m5WbT=FKe)PjE;RtJL+DIa> zzxH5Nw@7Sog%!IPUW;aMQO?$8g^V?P1E7fxf&FoTR@3l|ShUEJnb zQ*CFf*65*C)IpXRHkVZIWiEh)-0d=AXcrQXeHT3fTt^3P)7UOVpV6UghorK12w};< z3Gff`@$m^76OGp0mO}CSFi--fihU9v`XIh1=MIYQQ1kd9RNmRjS>Q2ezNLhTC(;gV zvcKa!n%>@5?k2_Y(vwM;R=Dx(AOq-Rbyl1pY76_Du1`@h09hNDFI@;E@)Y;n+r3_L zHLR`JWBK&q+V%h9i#UheglNf4YRKtt;-8au5ObE6}9CBB{?JG0f z(i%zFEf@Od!0PeoC1DI#;q+x_lJ=J=n|m%oFo;JeTlgdWcOx0H1=nj*<7XGrhcm0l*7FtIY)Vzwt(a{s;tI<}XhK z1tX)G+~?@ zbrW{tt1$n-Ka^4ZdBRAhOHm#s?OYog8cO^hdLSXAu>9GlzLItVq(Jr{(pp}S{y&{)?(wBs*2q! z@V^Li64{{?L?xAPJAU-%$v;0@*$J|gP&wv-69}TKB`G+m(bIhbB6C)x zgWcVKror9jmoDv+L?SkdtP#KTtz+JnS9nU?{?ZggIMJxK20#a3Mq%LQXH}Y3(e_aC;1d6{BEy^&8KS|paGA*P2gsa^W=BEcMQBcuS zHp@I0*MrZP^Uoh<0=Q0V@t>d9L$RHJsOWc0*!>AiG(ALQim-mDbMIfkiW&8|W%|XK zFDF)q5a1!Y$OiIZSB8uL_6B`rh*Q+2;}pU5`(B^HUU%*O%y?Pl;d(EeIhY)k2YKf* zR{TBRdf5V}4wRs(DZ9PC+kiHHp?G>w!x#PV6ehj$3#YPr;$Mq$UhJ+>Z8N%s>yiy` zkVbTP2s=ne={vjf8`qlirRaZvxkEm*auO9=q+1WlhY1K!dUk5=A()4sS)3UaU;mZe zjrPc3O_9i0C146vOy@mJVyN(8b=E(HH|3aJb$6E&;2U=WCh$$IuHjY9-CtiufVlp} z6&RVwM0-l=m58?j4^Jrph4y2&qC*N4Sr3$Z;#fk+f?uI=kD;(oO-;=cp%WPhU*CC( zB>Uc+hk=$65%I?uzUTwovRvi>8xP(;*Yrp!Q-|>mu$e{TBXfF?&E7#DLu~w!ZP3ha znO-SbuT@SB!FACJ*@!iMFocvIU0$vI$hu%5`9ZnB>38wE9}dY|!bPibjeMgNaZMdLZF|%(nRk6U}eTdmbx7tSl`&qucaMqwITiOJ*2X*qDh-^wOn8 zqp@TRk5A7Wo@94Kqj(KP_?j|tlZD;OYjTN=e_oT~1YRI?pbAIo88GdZ_kp9o3y~jr z1)V@_hD++SRe-x) zSM>~sCkD>0Boh|@2-ES>=tF&IIs$Zm-2;CcB&RKSy38JIjKsH={HSBz^yFd~hCEA4 zQxmV@GM>w$fG7&^&Y(R}AuA*&r-vYn-Q8oP>n0*LyoB{-vugE6pm)F?h~k4nG7GyE zruXK|Zv{bIRhVOB8Y-wD!$GXwi)BO;pWeO3BW^w4pY1&lcTZswDX}G4Ai>k%(XYjI2)>{=#XT!?3`5`? zF1&p|;uG?iDKS$MjAqe;Bum&h`O>?25*{~sXqluRG1rYem7FGCH*fyu5I~r<*YV`hCs7ov~W}0zl+KQa~GE)5lt;n6G^W zKL%uUWH63Q50P9zY3Q0FOb+@-_IO}S5utv=M;1+eWOzQ-Vq@Y*~x%wbDFz$U4wLcKmUWyj75Qnq85gOxjF0W*`TP@qcGc!H|m8%CQC z((H-*^q1oou3m=i>7cAn|1hK2?-}J~(X-Jt5;;FY8l#LLO9c|?Zb-T88_(Wxh^4i6 zp6S%yn^`~DFEOC{*GFPOEIeHwT_9*b^`6JhRaNHfHvY`PCLejkQMkIRc+P`?0S+LB8>5f};-P>fMjEKs)6D zd;O+UMuwY$@waTRsU!E%P@m(rRS$S>qS_wfX~mh~r?uJ&v$;X1NH(>vhC@1OXc z7vm;!6a(`Tr*Fb3(l=E;eflN{G&punt~_UV^q=R@#B;Fz%X4@s1?Ktvxdb>C`A7e} zL{(0XG>{=Q7LvKHg}HpJJP3wyg%iR~eib{tT!al|!a327oX) z1#PaJ6QGtTN6jgeCRs>$rQjcqsrRYVkhOln6pq_7zxFrjqC5R*{QqieR6lW)G_j^l z?b;q$*E%h4{(0sHzKj259wnXPu(SrY(&+#SD~s#(wI7y3U|QPC3N{4Wy`EaN!?R1X zatu&nqUP$Ka+M{P*1`Nt=ts2u? zaVSFzs$ZQcVw@92VRxy<#;vGZ=8EH?tycuWaq>-*Je{TSz!A(Sh6NcV+oj%=uXgYt zi|@p_pBD+2L$OvY-Ha97BeA)tv(>U~c6B5cerks}wfkS5GL80t+h;fo`{wF`p)nw@%RCq-=p#9%nS*|$e zeP)uLFC>nYU;f>lbG2KxS@eI)sr<~buxXY#BVc+eM-zP^B7iil-A8E(32Kl~uE*(s z1+qS-H4Y1eidQ(;BY{qLYj;09nrbC;eH@W=>)n){a*3Js88{7J=j3pJYQ-#4-1@%H zjT)I3;G`G%uqZDxgkKJ%Ct7Qi5C6Lx>TIz5GO_2?n1{MLSwhdBu3wSQM4S81d6P!- zeX_>Ha$4%)g8Vmdf70KhAZqkbm3UP6z+mNnv$lN1tZdQ;O$=?8~48EuvB` zi&RdEjRJiAl5wi)d&s6|{_xJ)u2>8Uk1k#BYOk}ynSZuCM*5cLyh6aySG`B}qh5F8$TS9vC^FiVw z2Wqe^MyQRSh0`pWi0?b%ha3r1&M^-x&lr4TA{%b#Z7W}Lkb*dk+}zy2fz@C7;B0Zm zcRh&K87V%QD7-y=8ZdbDgTb>M!KY83@wJ=^fa|MB%k>o>7lk!oNmv6onN{mJ0Z=Tz z$~UvYQhqAJ97g=b3ZRgMnnIrJcL4I=`{S$rpNn7QL1k>cAed|$U%OZN1F@JM?;V`K zGOemWJTdZ^DAeu)&P68CkM>J%SO3Mb z32Vb;5opq#v2djO2BFB8kU2aADVIz8_2Z?;;94ozYD7wYc7Gyi%v=H|`t?gijG;z8 zfWTi0Z5Q}7{Bg-ibdWWooZflUKOg`efxD5_XsaAQ1iJr0LB%1)S$Jd##n#bPU$!82 z13N?@D@eF2e1M&f0JnM87B|dxs4UIueUjcC@O!s8zt?8$kzA+a{o%$VbqR}Cic@bY zt&!Z0kRe~{8Ufw#tu!IS1jb6nfCSCsT{U52Y8Uu$Gg>co`3iBkXppAIxCPrKuELAL z>ourYlJaUN-q5N7GQGsvRBD~|y6%Iy`7{P7Pi`;;%@hR^{ zDcYT4bFqv^Fw=Q#*tsf}FKhLl+ZzyD zAo@J#Y{-YCQjjBT&AI+Q+bM7+Zl3G%v1jF#I4?QwxMc@C@?Y08QsN z1Ngt6?`;m#VyHX)^Ev}*rDxiluZ)_cK|Be}dvoYdvh|vm(L)WxIKoAjsaCA$(l*pZ zx^zg9W$BKnOkj}-y@<*V4=M!g!(KS^jGZ};sQ-ef@0aae;nYf{KKpd(tB3zbqmW7B z2X`^g$9Xs3L7SKB79Wfdx0_l-dczo~fOlO;ab32&<cPX5RfKMyhn%(UI!f?l-Z4wXxy!>p zpH!`W=yvd&MSvNG7|+v-xQ+sZ4GThT>XK>_sx@v03DL+fzeTW>U%3xmQ`RoGThj<+ zW?AK$b6tHcQ*ce(Jk+Kg|bYLi?r|2kZqwD z4aGiszE0cyCZ24aWYH2{$-AQed{>~7{NKH+b{IQw-~-6XywBKQK*N_kc!#+XT`AzEK zSiCs?pr~Pj_nQ+)u-Rjcnk=Kk=7yNq`t5t^zF`U(vd=EEcyMcL6yIbG0yhNumC1%V z2@f<29hu+kn@dWyu6_{uRZKkp3W1!7e-n0|b6tyDK)qLL6zm%+Wx1`C?i#d(TqUN; zQFm0&Gbb26w|jeH{gqnjX~g&SRxCJyeHD(?`vx zolCM#j2xYUci(%XImR9N0A*~o33EmFJcapDnycxD%4A@Qy(h5c4GdvFLW%#D(AD#v zkXl~%+?SlTu^WJK%SN^64}wae~1P_2=B+wGAKYQ zZaft9sPs#sF8j6OS5%Ip>Wxn+I3Jd7!Wt|E*xzIcn{PI&j2RItgj(ihC|~r9!%22F z>(~QIxMz1`D6lIu#YD#~g-;h2m`LCfzH3y!8Jh6Pi(5R!J#~+b$N9lf+E5!;U2wdgsnf z5?`|(xaW}7B`+~Bv9Ss#Lq6Uw;2J>z^-#caBf7KDfg? zpS>Aw$6I_3Zs+?k`EtarC|oZ}N5Yu#3X6`n$@*;0{dar1>+5g4?#xwiFZN&1?N(>7 zM`=bOJ#un15OZs-i*r46^Cgi570EZjGzzFr{pnV-D{~96=se0SV0rNynyF<+-XJ=G zEpv!FM*#gfzDjZ*rumA2 z)l+kz{xqV=VnT=gLM~>#ZYqWCrn&ns%6@sN)U)BayDLUb)d<+lq49kwjf zFWG$bek(LDd=S>1UeQIN`S1y8PY%)e#`FP-fvoZx>$d3L!%BeyZlZW&Szafzk=&8Q4IlHW>&1?6 z7<{(C$Xdh+xHQioqev!bA219zAp{Z?y$31=N}>>+2-cGTra`mTLPiA85l*!5JDi-3 zy%JV~uSWKx5_5}0h5>WZ7@%ZmY^e73_SkFc(10GDoAeTWQ@e_@yLI5~`aPbJJ<>klu_{-4Vyz?(4<|DL z)&{gBLsFU}@9QlT!(2r8i9Mdc2&5d901YR{yFJZ2=NS{~sd0H0Ti^0mP(fjRoz-Zt zd~u>nr$pVAKj3J~TiCx{SdGQDEC?J%W8q0Y())V$dw3-N4$`s}C>1YHI=Shd%N*@k zTV~Z{iK@HRwdIeN`G^39OE~X-o=p*YpX$X{ZIjUA-5HR0;H#>*EQ%3!xxvMLRPWT` zaMU2qO~SY|dZFd{Dt=?gK_3|<*rMy;fpE^)LEm}$YC2q0gfB9M`nJCQ`rx2wA7?3F zB3RiTl3mK%_wXx&JQ>orfJG9#1nfg&cdB09Y5%hW$oPP&eq0|$RUghX&^M$BH`s>^Y)7NYFCh)Pgv0JivgnPWfrS> zs;=P?A-r3ma3ZkShjUzqA_af75PVoTG_6;{NWvrn91mES?}!ROd>j*sC$|9eSac$RN1RU`vP(%TAYWve6xI$`2Hw+F;4m`=jhE= z(MGx`qo9HZjh;C@H=- z)|VEnnyg57vT%LHl(Ez^j61)YeZ&0TBEZL7q&|mQX4l2O^D8-r3q+wUF}LrbPaveFBHDHZmV4)h3+7yE4-HHc;x>!0 zxopCmlyGZIzMA{2pT+x|`>*oZdOZ4(;0&U!qd?1+QKSyB#`?XOpc&8~0+=p5H5`+P zDFoE@#uD}O7ivSrV%J;ya4L!Pd;Juzeb^*Xp8x5CHhnig789+BV?OsYHe2}d#hx&A z(Ckr~Jk^~cSn?w-ss*Xjvd%B#5W>9tctbgJvX3m8{-orwp@xt(_IS{}d-tlUW`k(C z?#dB%GU0Kr1j3SW$#c4?=|qf3?&oq}_N+0m{0CA7U-7 zl|hPY@J;aNI!*^Q0~KWv{#7Fo&A_}Q%G@A}y|r#3hs2qWtabgwDfj!D`}>VAsO#dV ztM2c)b>E|BBAe^G<@evK@2u1$EDva-9d{dLc2Mr{4v?e(P2C5Sh`N)AOH)g3N_+a{ zKYS>`u79syR(WG@pUc9Q9je&aZj8T2Xtw)<$;_)-xqBY1n;D6Y>rc5gqbp9eyj|)% z=P2Yk&3-B7R1T5FjfY%Z(rg5_McX%7qQh6- zh?`QsJE2}&y$MWsWpMD@xr*k|bNJ0GK8lruUWKdxe9GxkeccZD=!Sc~3$zDu+z3iP zt(;ODOns-sveaCJ&DLzr(jd?uSIaGOj?Q73gka1$g|ZkXB(-pc5u1z&=sYz6K^4ju zzFK8mj7*}GQ9;7gq?{aDytC;Bk0&I3t{VcM^__&0&PrhEti=6|NvD~6cXDXl86gIJ zyQGWyd1ZPf*l>I;aeX7;w@h5I7+D!k8ht064K$pHkA%`j{gx&A#I8Bx2qK5XU+ zu6;MDdfb}kW{t-u5HFOQb7dUqZMq^pGJZ9p>bt>(8!PCc`Yxy2iuZUApH+R8h)^T# z*Ly4!XTgn<^U|cnYFr~BRNb?;WNWzEci~eIhbkkzsdjX}bQ4EG<9*tXLUzh!eyxSh zb{x)PJ1z{0T9}SA^2?B}2h597(fK7fAB#^`TwL}_D{Uk+_Ta5C;Y-XRyU!|>&r*I3 zVkGc0b$qaD*S+1mNhNob)w`2p+DPzs@j0efMsH6hX_GQiY)V9IX7tn+9*`1@ZJp$u4QS3Q9t%F2mRQO z+M%0gJ%jR3#>?9B=|p7F=T9uANuU{?Z~=I}?|bZ%cUqZsy?rY)<5PIu)dkBxB zXYF2!TEh`7^UMj(aH&C%njDbAEFEL2v&ilUpq3?3+#%~30OzO}XyT5}*X~P#Jlx=L@Du!bXGEO^&Xxk- zRl9xM`>up^da3k5PF#p8q=AoW8h$#Labc;}5o%;XFb~&zvXVJ6f%-srusqHV(3?}n zU^qU4dVLlmv4OIpgh9#pYVxM`2p)9K;?}$sJtKduQ^MW5F+c>-1k@mN41u?t4_Y!T zU3y~HfPq6O``1pq<>?O#YKJxh#mH}4tbd_GoK&Ch0Z9EelIC%tP%KupXWq3JBXRJ%G8TF9MMwyhLJIdltxHt>SN;a;pPM8y0-b@y6C#j@xAU z_!zn)k)5L$xyzuqh3)qBfVz1Tz2R}M+y2rRgqlv{eb-9R0@tMaD88GVoD6vH@-cXd zMfJM5G=g7oSO?>8wA^E4QgZ9TH2nyhBnXwS0w#d=;pzk5S^7&ou)pMYE-r8y38qjN z{GL;D#DAnY&|;u*&Omv`Xp3E5g=j3$S}5|B-G|>d>@D4!`FQu!gC;nh^P!u8A_1Ah zdjY2h+~ZW!T@FEOEKKV-v0UVK1-H{W_pEQbi{z7ip7VinHKIx>${AdpM0L{!Q65kw9NSeIYGKw(`nh&zS|yM5=;x_iij)wNFq zdUDLX>j#}PI^XJLauNv$#{Q9zVlfh`Qv+?5;oP&Ry=p$qx8shtmusvjl-39~ArlRT z`L^NQA|?RvKVUC7jIDOthFNFCjg#M_M5eg>7$7QC{B%Uru}u((zhM^~n)OcE+b0LK zKJ70{3BC2oAUM~t-BKu2KyMUcfu=!@d|>jm-$D=cc4{JjG5a8=JSx+mrmDL2gW8(A zo6gQ8lP-w7zgwC8*aL{Q^m8}jnghggypO98xkl*FTl7ZLl=z>vw58Mef zCCgI6xP6L0qmC!2%9?{1Z38^`)Q>E6X_W=ny#gxH^+7xKtpk1TZfdCrI&L+7r;7F}p@^jIb9#!$$bx$PXn8|q%h&ohjcv*7 zrj_R$d2hW=JSFp$OZyTgrK|mjcd*1#p1YxJK(9p?Teb-xrj0EFjviRH$hIZSD9agq zPi~Ys?QYx$dDiN2An5xN3fKT)DI>9n1P1Fm{-hm>Y$%AKR+3!kmh5i0m~80E^g$fI zil#5O`cC{5=pgNW(6q#3x~ zz?X#QbN~H(GWz}9z;HLTq5I78`>~@fRnZ_NIm3E!DhM;ZS64~`sJu>fucsMSY&wSE zMuAq$vH{YndvoyPJ?7V-!t`+Op+^3idps3sAT&LwiJTNCZQ^QTCHI`KiQ@#>H-rc) zO3d4kt`yu|fE84jpXONg1BRXZ9eahbC1=9o{PB*l%s4*H#NvZX=YGYM{m1#i8&jER z(bfbMgyJnc?hoSu&&nnum-F@GRt6-P+-!y(t)add@R6 z-G)|eb>Y~z4i!*C@X8u)i${*2g}@mzHA|g>*dU+1wxK^|d533D{bnq+k+zVOL+etd z%_!7&zgG``_xB{`q|V^LK-$S}ZYCw^Ypb_KquIpB#ukbqzOPj~F;c}cNEk2d|KDzC zy?Xk*G7Nfg#}ddGuT=23+R3F$o2i6piG+TmpX@j#?PXm@`VzTEW`$ux@ZP07iKWKn zfocfI%7uB9`kuTKE6}T&Wqyplu|wlISY=VdEot>)0zs0Wlzwr!luO%t5D+B4#EtC3 z=hV#idUg%P`}?$qxFfX24aq6HU2zHv_GpTOB-kCR1zAev*H1!wpGhdP$a!GLE#V$I z@L~elRQNix8a5@+yn3K7_trhh8R%^QcVu6J6u+)(uu8MzIo9wY{?V47Atz5|v8A`n zujP-~?|bsQ6?S_5$sqI{42kjPoVcv7Jo2j!e0?@iJOfa7ANZt>7mLJp-^~~ZB@ija zAu&c>O&P!EB}^8#p2I1bvPPxQ+M#~xfrST;tB9lV7oy;0n8en4DmY$}2Et@(Gil(5 zN;74*?@c&4Fzqrd-5{E}f^Z4QOxqO|Di-fJl^x6R_AM|YptL@SXLc(tl@oD>#K`0ze=_{ z-&j%rF=GbklYLFd2PZ-K^^{rjkQRIh%Z^vFqN)g`Z!owTv=i*OBPfBpnMH+QXhFp> zz|2r`bwpUO#`trE$wO(|3E3>;Qt@@4n{O1Dy!pJNJ;W2i8Q46a&L4z5-vdPV>3vJS z+z+pCHy6pkTDR!l5|$Vfd>0fy<5Cs8NxW_EU~W6!Sg*K49?owqu;nRM&NA1#L}!Gk z`sWlW)RYmtq}9L}Hg2rpPy#`F3TD3pMJY=yAPGf;)?dc@TG4lu^%D0t7$a+I>Eu?C);JJQ2(DejG*@fZ~q{wq%<+QqD?)~iXvOt-H-#6y z@I<7guj~YU6)xOQB&gu6H2m2h54m;69M~cv2i?~b={H%HOTI@dzc#Fd!LHA8m;hJ8 zpUzG%m9Is90(7hbAi%O^JJamTKv4@#5&%XAj7>FwWniUOU!5O7^^eJjO$NAG=JkKz z{*w@pql8Qz{oxiATrQQAiFB&GQwex%q|KSDvBOZmAKi9u6H1O#8Woj3Pl?c1ytaC< z%Dfpdj^t7so|Jp@1-L!V`NdC!`ngUmWp zw73_Ggf(iwve1)s;QrIaBkF`LO1l~;7;AfAHEFa1(7dngh9t%+{Y00kOf!0L8e@JT zXM0o*{ReA|>;m7?%$-rOcbF;{Eg0m;(XHM(z$hjDPLtGb7a=Cq&;>=Kp^LDJ?j~$s zjVw>r@xq=MBN{S=#@#_jZj~sq)sv~IY!pB*4&!p+Zm3qq+eI(Hg3~aukrQ}}!dWLfZhuwN;;K56-70=q2i1Y3+ z?OlILW%DlOvu|9+WBQColNtKTSkq`h)em=VU#!fYfOOo365&*={yCj9D9Q{}1kRi>Lu}1H`RbW&F*-a;H{nHv|IE&T zR#_6ukoV(udoZx58kaiY4!}<4rv$;cUn5S9ZckUCsTrb+YHt>B>OE|L94T8yV0?byq^AvGhB54caF}u5*V8!KiG1-z#>7<-8jZy} z*dt6aOj+cN`v9X@_j%utGh+)b>|GGWTBo$t-JM4L9wOg=0-MduNJ(4&u`Ph50PF66 zu&Q@w4CNR&&oV;NVvTRtMbM%iFd#t?<`uEbOGTb3y=f{V%Q?RXVQ$)nG1~`-co7x@ zq}%(7zyu&u`ij?jp+=8q3+da2eO&KXc3*<=;nB(-V+P0}-fHO|=>vj?LyCD7!jyMulu^r>paiPNjjptIo~>(Gpp8xu6)p?06F|)tkHoc;6spI*?xHtDZl+Y3*ycq zN;hsFK804lAOUiGk-G}xCg_Ow5k>jHT;G4?6Vv&Mr56%icMm|U3L$70RwE{R% zG*t`YkW^l_4j2}*{W#YRD%LWpRfFHk8>_n4V@j}kPADn_ua8R^BgBkl*zsukC>u?? zUWGi#1)(Ebg=az%9jHp+=}4HNA3Y9s!I8oxLwR_DFmI_V-GB&sP1dOidamg2n=Uwn z+UA3G0>O93DM*J2aQ1@N?0ms3ml4jnjV3L{F@`Q2?8Kztq92*89%6Pkx80>Pa3buk z`S1@v{vy(Gj z^PmsA_(_^!RuP;Me%~h=KG0hLA^P`?R!t?DtukP^&krqST?Vq)=22vIo`BO4iW`Be zkRpGSV^2QJw=r$*3#7hi`?BfSGt~A%(~8xFLL&HIpTlfGh8ZfaSi2S|$&jaf^m_ey zBS0}e=H&F2HeWYGWWnRY;np2Gi`4~H%&YVLOP|6V>VZhfza}{&R@N!u5-#~Zhn{8& z$+NnVXE8J&mE~N$x>zG*=@jxO=#jf%7@egNv9zx3NX+ZbIo+Wk%rG`-A;22r2& zJPqZUv}4_k5DM262#`p&Y|3uu15K=GCqlW8L8}t|D4=u`?aWcjEA6MYRwQoBbT7ti zVC3J_G_PXySs?0 zL48ljwJ`aH8qN8RhLz9oWmw8R&9csUJtRL=k|Fap11C}mz-!;ZtGqCZ2Aete2O~c! zV&=M&%aBy=$LXN>>m1v5a8U8+IzQ(|)tLp1j1cCghMJlQ)ur^>1X8b>R7<~Zw@ml< zcE8Qvjka;supNEPVDu2fOFD=UsC%`J08(zT*tT@&1Qvf&Aw$>3=`3c+vrh~KilQmYM$AxMh| z31m6?UXV!kCD4iYiQ?(FdBf7qAPX6xy(9S?(#ar~H0B!RdD%Yb)ub38#NzG+?^-aT zRtFqR&(e9ZkuYxq5zrJH3TNnBO5~inrBmn%5TM^PA6T5C*Tl>nZy`%srVlG7(0 zNI;0qCg+nWN8)Yn|-zT)szE(^4z8rn}sl}qYhu{ORfj<=Oe>=$7y1U`Ic0e0K#|- zg@5)G7fqAFagKMT;BIIwO_nj60vQ0c9S`e^#NC4ZfTzHhm3ovu{!^Yo4e&a4{b7&p z2~m!Hj=tflFYg5;Pamaogb;(N$tI{{^2^nFOlO5I80K)4x`Ad1-n?9wD`$VXJZ&|J zJJqJ;<+nMsR3alwqCqxjv6GbVbf0t>%ons>%B4Bl%!el3rEH!-Fl}lQQN}xLwaBqc>VXaY*`3wD)(I56Qi1sL8|otM2Jq zBF98>w4~%?*4KKvdNuL^v`MKytFtshLa1T5H-j1ie#60%kN*CQpXNiZSa>`<>GFfu zUMxV8cLBi1LL!ntQrMRG@eC9?&q_)cRH+YLBOV!KxfUxFAspL!33qJ-jefI3&EcKi z((OolRdUh*Nm0QBcr2!eYayPD{=m+u%6j=+@=i!d7?v%${9VJ~ zKm~O)C;EE#HmQa4Yhoc0wsONLFiP-naVXD7x;0^eSv438~H@jdYdL=&DlV26i0~{U*L7|3DCZOrF#pU-v9_%ko zWG%_gl705iuQviBt@By(o_Yjcm}7nV^B(x`3I1m>X%*4 zoJkb%m}3l`yHtx4w=W}fIoEsc*!kdvXIzZYU+p#{VupUCPQcM1_UFV3BVU$mO)RB6 zOnbzU~&U3EBVpDws#~fhN?RC`hQ*+gfLuYb6>XAT2Y%L5mi|dn7pf zhICwd#V5V80p^KhAZG{8g7O^P*eo29M?(SRlU z5?|5T3o!vICEVsUxXqc(r2U5BODM6>Ll{B4ntir6yrHiF){R;TwiN4nM!=W6m$4~m z&VRn}dxG@8<3Wj#0O9BXN+4Ugp@_mzoPb$kWQIhw z$Xq#0pCgC}>>Ys!qZDJ#?0S5u7oLJ)ev-x)e-m9QYS>i=9WVN&nmNKo&|%0WY85di z3z(j-qR9)Z2x}0z-Fnd32f7Pug0mmXuMA%{2}1a3@#b5%?#OMy#_NL34$sP(WP|oi zph<}eGgl*IH+nlgjZWONi_5L2;u<0;iTwa2UcLSJMEv`P4^aB4GrvRCg20V%A_!3# zv85yNAN|!46rQUUJ)&kp+{88Lb;e=Z11N0wzZUM6UQiEEYD@Acyw8LehOjr9^K%!_ z_mn2`{A=y*o&eT@V~lSm*!Jps0S!jWoQ+3eY&Hzc?5rQz(2j+6VzteDAn|iRqdGhU zt#20&(%2(mwZVL#8Tr>6xTwv9#$J6z)GUBw5wMj0buE)4!1c)_o0>MVe*C3@$#vhS z9Gk!zR5b&1eCTQ{Ooi4Uw*%r1z!464^B?y1oIg8X?L5y7sYN zgr94SyURqB4*qC0MGdH!M)o1kKoOV6RT1oh%{#Lh2J=&e(!CD~?0`H8}dclgZX|SVAgi{&_!5_z|Fr82M2e zW0qzUru{YvI?Xh%!K)THIeR2zph{c<4YPuy_p#g0KKIq(xxb8a&Mx3W; zUmT8LZ5$I2rQt#V?kDggp)f$^1vakl#fz-4tpI0u`0?7QF?4;9mt+7uB-U-qmKB4P zf)D~ia8eOiTU97~G3|zoOqD8?0<#oDS^9T)gJ_BVHKEf33@)gV7gwA)dR!4||b?7pAV`DWdt7 zKj^Y@l?6Kh3|?ZeWY7;H^hydP7MUinfYNu*3U*@@Y2muNW%(o}1sqoqh~HUy!nQOa z2TPWBdJDKayReZznz(VWtL)S|Ad$B7 z^G-bgTZ`?aP|8(qhz?LxV;KAmcmX;5o$b5Bco)2lw0yYkTXIR7IuS!DblZA)H=+Qt zIR18$i?WcSz7&dZckF9XqTq1ExG?e*h?R=AC|2Utax1hd@2{k{2b(2967%@5sh3(##8Ob9#DNGzAMuNzPypo^lj5fL2bT~~mG3`pXtX?fai=C^K>m@~GrJ{6!u|D7zqGHta?C;+(5U{KC4p5xLBVG9A2AEr^h0+rvdk! ziKE)+Xg;ou_6KW#-0leGewEYCHcn^Pb#`I*-g1Tpu|2@d`Wob#3Q9!X3Xgz z8LT(!MjG!La3mN0QkTTxXBRV)hlA`;YTfTUfCmSzzSBzba?K@!z2Qcx5n+kKU#-x0 z8P|GxMrQchFf%&??8Gt+td4Hm=k%=s9k6q@=vFE#&y^D`J<$11e*Ri2Tk+#RKBSFk z&);9AGhQG5cVEFBeI0b>N^2pnmHkA?q0^MJ@scbIuihhD{~U#*$K z3C<7u3rcTYW>~#t0Ik}V`#UlYt^nD6MfL6NtiuMnz5@~)d<~M7S%?*Aj@zDO7#<~H z_Lp3NZW4exv0(Y z88>`v5^f7?_Vft`!5#L%qru}b(k;Wkzox3t5etU>XIgShn8LHbIw9ep+p${j!wGKzjp z$lch35j^%>Ug(*qr=+>^S4)a2U-9_b%JWD1qAoFXm>*=gfAAvCdg0k1^{-U{Gq2N$eY97` zb)yQl*x|$*kwCBcxonlEe%|8`PcnmTn%nK?;i+wPZ#wGJmv&`^tnR-m=$?0Eqj>d?7Oe2Z8!;ov7g*K4`T zlPOHZPnVdJs6Bu&dZ9XJ5gZqZp<9YHQQdI#i5$f;0%BzWyBdd0EF`kM8BHMZ!l!up56?n}Z~(K8%9O4M4B#@C%?DfP6%e-Oas+74aN=sC`sWbS~eWj7-6i!fB!4u=j?xInPn~ zT|{tF3+9M|*F;ob2HaqmE9^o}ZPJy>$i>*-*Q&KqdEn}LQW>MyqaI9JVP#ogPwq_e zBXKk@cEW&|qLHuTnIxt4{+DY9~M?)1KnxPtKiLk(%&>dOx_DC*pPObm~c3ij@} zd=wdXF?{>Q~l=CsFY-v4p zv_;^`!%#IR#Uh*uYK2IJNMom|@9TB#mz3!zPb6FgZgT#)W*3gfq?{a~`+6tyO)CtJ zhcU&`Hr&irHy`5)kL_29z0bR0YeK#Ol~rjByZ}k42%1C=U8fhTG~1PZ>M431%(f6w zfr7eC4EAX&#QIJ|Atpowuk|^ySElb z&<6K1J(e#*)Xg#8xVyrva}Zjp)-UB!K|?or84r~U7iMUfkRz6hOLW8d$}_*0rN;7U z*Q*6%%?J4VuTWRMq4cvR>nD)CDOFGQrN5DtC7A4g1XibiI-G`AbX~M=B%D- zkz;cX26WUB7T0iGd(w_DW$H~i=Q|?_pc)l$6@IoC{lu4)22{f^B?Ezlcb;d;*Nb;; zYSQjUReyn-x#Gw+YSJeZ456l`d)A7?$| z8#bJ#i5lSKo?}@#Bjw@GmT%P5fe`*u7mdW9A@_z2}Enc3LXpOwK^pk-03jM`R> zG^H=-s-jz^XY1BqyqVmt@N_?LYahir|t@PcdOLw<)_Z)Cf9_%WPP_Fr2$v=%Q(FQjK5J^!z zUgAnETZ#D|5fdgp76?LVg*uj6SsTqiT!2dP=l3_8QJhGrHf>&RQ~<#Hwp<|F*_S%v z#UB7&?DJw5xIKAtjM-BJr5o-zFtmpnW41J_ zRP(|?tBb>YetFbO4!szxQ3J{B$9@KVv2DW_+YdS>rF(!Zh+TzDYL}f67B6CH^XrTj z`TYL!xk=(l-bA2q%eE zp=&Z8<9v+VxpA& zi1rkJ#eFq}fgoV%3<*OR4sRNi|0(&1PUAi_U))~mWOF12rv0J;Lfo; zK9DQDZ26lJ-d8$1-FecOAx@W+zNS<6%K4+ik(jBP0sqs79NZ4;PO#~?i+=jeB(i`V zgAjakEZ*|&w~tNhPW&c5WHs@;38smB-gg>7Ud-r8J4PswM3H6pM&9{r*95nG5!eQi z8UD7h^>(qYZ&8pisQ-ug$d)c~*OiT?5PRD_AXXfxvZbFBCJ5cpV}IKsm8ZVCJOO_-ibp_iD&Id$<{G5L;b){j~GzhUX$pThB>G!3Gv`rC;XSygMy# z&>7Un&T$Sdt}dBp+UVEtD_8RcTAUAGlx%xV`&*1j9iIXHK8nn>VR>EG?Aj-%4k2u+pS-H-X=H|JIhIV!}jXK8tBjb8!Z`v*PvhRi-M zN2zM5UR$VVuG&o|Z>sH)Q8>Y2aen3S;>h4WDTCgJZ&@CFJKb`&n%I+6rC{lynh+Bo zoqbYfH+a?PYm5aMK{&Fi?|1HzK$YC5%jDKFe7)Vwadlm~M&0Rgtd^lkfx@*@TL8ve zM_c9Zm3b}p>WX(>=-N)LnaRRq907LBwcKw5R8vcn=qFIG^T=hh~-0UPoRY8>@( zIO^7G7^Qzd@}eU}JA~Vps&VgW28JGmdY5EgIhUiB!fRuuDOI4QYT_5xwG9GpzzVHe zUNt|smrKtzKhCdxy`p^3Y}J+bfrIsQv_+KLHkIG>AZx{&alxgNgibQ@FmS7Up8mzi z;A2`FT4`J^1N{@)X736B8(%n6=tFuqZS9?d-(G(4iV6R?^2-JJflgl9ifEB& zdFT5y1HJ?-JS@0>=YaJHMUw(C7mS|=rH(CIdN36sFwhy6w~Tcxu@Cg2P8j{6yRhF) zRDl?}KYe?$qpYCDrrgZ+Ip^py>*&>#Iw#{3!VuR?ez|tA{8|c(I;9%FZ|u8P3A*AA zGD`#z>49#duiAH+)~4LYipTW(IPM1)Vft`WFE{)h_$Or)R>uDfQ|oPhM6IcsqQvV- z{IbfE?~8h{Z#d^ms2S#=Pimf7*Gaw+q04?+huKD0d&8{lS$TyQDT*E(Y;1QP1wU;G z*yKplR)=9AOP&GF2rpr~#dBtMm!=M+o)!Q6ieTZh3VOlnB6y!s6XD8Kt};qo-}yqA zee*HakmYGEZ?r*Fta3Oq$_#v4Lo-7=Wbu=ZFtya}d++PzR4XVaHK0AM--c5rFU}LA zT$+EbQjjrk*>W6cHIi$ZXRYuAD!aCy{3~c*c_$+?D=RC8f3)N?yY?KYR6lSc=ex;0 z4lwWdv)#%IQ{IgQ)akuvY42ha+OzGT&h54rMMDC^&}{bKYq|c;Ba*;fDZa##J}+Z! z_uZXcv9cvQi)C7eav!rfrr!rl^Sao++5Fp3Uc!je3uLggfEHMrP_Xrm?>)tM!`2bI zJbi&tluE?jweC>tI>iU9pa3jtchefn2|ftC#022R7@O-eb}I)c_Sw3YX^A3TxP z>~FD+St$luSG!GU?H+iGH@{^~(9^ zoeb|m1O^|IWSlO4k-ZhVL%_PJO|z8mRgNk38JAW>+Aw zbU+sa%wgsmU5{VJZ&<~#Q3=Ewmgk_gbQaY7c+x^_D{v$O>RVf@GR;g#T%%Rn#9nQn z`7QRw9TL)jp?UPepN$LJMiDhgdYPfWOm zRoaAcQEcwo>@ol2H7aK&Csbp{JR30&9n*clAS4cfk|rSwDC%|uSUYoi>%LWR=5qV7 z#DGyn7c6x4GZz|C%oIRI4j?3kgxk?uIMa#?Jsg1|c%12PP?sNv5 zl4$wBuxUv2V|BE6`#dvC;4TV8qiB2ppPLaAUUHV*+SB!c;+`Z zD-rbz#l5h4qdv zpf-lYfY@p;k|S*vG8XRqC{aySk4}5V*Q*im%(mn-oTKBKZ38G%r1RUdtWm7e@196V zX>V0ZEHT_D-fP&_IftiZ7O2DoLDVbVJ#xZR3H9b4V;y(#rw$6dyrQ zdjO=a;3}33bT`H86<{Gf%T@)m>CgQrneO(UHhyvlU8Z;afa^ICM8drhO;8RNmo;ll zKzC*zI|>ikaFN2CTyIRZk^0~<;PO$l`$E=su&dZyICNmwdBFsl7;}gy;GHB4VFG+I zPNJ3U@_BK&Y|P^iclU!6gMLKuzO&mV1Zgwsrk8;KaUA2;UiB__oNCh;`{j7VA~}|> z&EeQ9%hzCx;-oH)-sDGYv&9fon8*{<9|4Sp-x3i*332h;94W1fW_W=ykMrkdCNr?9 zu}RQSrBD$%_=uPOkzPEDw=m=5Q4n#pW*nB(0-K^hV~^A4#PBndq59zBEfSxL1a#)b z*wA1kp|^I_CB|=kOtRoTmr)a}OHpD(M55PB}6%nvSs$1`c0t2uiW`T&A-P$&% zDm~CTS&420QruEK2wcR#V;KhGMn)nKH&og-h{-{9CWorWW8h^QGz5T0<ndy+-J!u@_fBa2pb?T4h2ciUmfMOksgp`eO|e0{iX9=c zpuWC!YX34B49egegd$^C)daj@e_ac#Dm1Jebe_m~cHTQ!aO74K3@vRygrhSxB=k3Y zt!^7mBtARC`7cS1yQ-+&)Z zu3|cd$LN^V)dEu2)`1$OJz0n z4T!l8mY`2nBuI~Y5RTR0+%2ovpxu6IkjAYn>77Fx3`3d~m}WqXwZXW|>cyag z6!>!Qci4rll|iR2&x|Giz4mUtbFyGI-%a<6U(uc$_1*A-nL4t@8AooyEUxxcTQg-w z(;iMSGYDKdo|^h*N_2#-VHs?>oBVjZj=M|wHjemgzPXuDot{bpl|A!N!xL`t(lqV_ z?d!rWc)!6{4&UZ^btmg2$b?i5_K?&zImL!~H0B5i;K`sWj?-2ax{6v;VyE z&0lflwJ(aJXRmx2uCZOlw|&Hi5v}`~9rBtO1LGeYBVSHZ1`Nl_(BN}dpm;Kk9BKe% z9e_C;A}$0DM)0m*Z;y%)v^qvijf8^i&y(=;bDbFJ-EfBVMNl=@boKrS%v>}NGgjke zo!f%C2Az@gA{4_s^+{EtBJrvJ6OfXr_#WB>OK4+?(cs!ddy+KT5mX6)zeBkUYdB(? z=P81dFtgvf3SccfH8t)C19RHr)EbqQJuI=4E9+t3;c^w`S0fg3p6tJrQtkep1LLV8uOiQY(4Xdg)stx2Oy8qLmAsCxj%ci zJqZLIBD%>O#NL&5?3kY*jWL+pnf_)&9JJ3%o~DO#0Uo*~H-MP;Y$qn$vljyox=m;+ zWiDF#=WI2>J*Ul!#OnxzNQ(}{sTeZKg*40m*{g%eaLEn)i|4}M_vU}OkCVI@5)wkl z(1^!TKbFY+mm9pWAJT;1NQYqG20Q`K{gKz;;QzJGVT~M%yu*?s1JMLPDSDg7Py=&A z(Sth{n-Q|ON%qX|8^V-z5WW!=<4^DNaQbULdx#y0+oqf>{BHir4M2PBhFolT0L}AA z9NGqrB@lP)vSTl}v!{9fCr`^{lteLgb#)C5jB_|T;eCGHqu$v0F3UzSD-rCK?wLR~ zd*e^G=4T<9zXRh*3tv57&%iFa6tNPA$+LJ?SV*)7RvMFmb`n18I2x8foNn#de8TxQqh!hU3tvy*$>2RjF6Cijx*J%4{l z)CVPu{>6bnY}YWhrUN7p7hm!(xUyg+Jr_GCG6)*YHgPe+(cD?TsTor{3^F1sH#phv(>L6pyNY8jna9wrcOc>;u7u_VM<+c4>mRgyl;VUYEU%jCjc^6er$l$Fo* zb_vQej2uGL%N%DSD*?|OXYG6P0z$XSbS6JKzc~uGwp)YzEo?q`VEY*%7*geCZ*(vv0e6j*7E2b^4aj{sGljNI!crI$ zyY@C+^d*jjdv}iG`?}xO@brSRiSNU}puQ-hK6L)(hnkw2JW4Igo7`A0B6<|jc&uBB znP3rw>ZD&egq`|R8Q(*?2rg4!00xZyHou|*b(FB<*x3C@KPFdH`;Ws7BkF&NJlL4Q zy$q}9ETR7~5IabK`**djT|PYzN(rL48Qq>V=Ov8Hz*j-q%0;0}wZ%A^zB-{6?T!D3 zItU{>MFoTpzU+Y^bEG$!DUDghokK&FEF6|E6WWC$S*lp;iri#WqqTI*P zaqnk0h${A#0%hV;X&`k~*}W?kF#;c%Q?yqwW51fiK2nPd8!ElOvE|fGi3%Eg2RwqQ z(x#3oH<|xyMIQpEC$r{1 z2kA!0V^{^9RE~cx&a6x9BJGRQqfLf~QE}a=*`OE+-D-^)n}+4LJ4wG0G7hE*f=@Ga zUC}0$&2{XS4V)+xlD@z5-1@wHgEbVks_q~Kw`7*>Cxh~G_Q339H(wl`e2ws$c;7PGh+U)8dq!e+V8-ijlGqUed87-TL&v8{$V zL3?cs2p)9oVA|&ft%r&0WFM6@j3T7X$t+J6ja=|xVOqo~B>8|M%IZSzG15H8+ZNaK zUb=i4-ZcdIx7E;;3TR#l9a0`94*C!JZ~67|z$2YD))~w3{B!E=2K7;>us+>83r~II-bAo)kvf*-GyP3 z3b)qU)BUOm3_NN(mzCj{9gp0J3r5(=eJG>tEl#X{|H5l0qss1EI9vFA`yw3J?h{%2 zy9}8Of%~QQ836&#RbNsPfc_lr-*ph{Oo@}HwR0HpT9jQf2W#@)#eLs#4@8X(d^-l& zRc>M5L$y}9Pa*{=44519^NM9yTwS~t6XvjFx=c*o|{W~ zm)4;D`lahGCmIU1Q#I}!!Xt2>IT3X=;4qS;A7m_4iz^cz!?CL5)dEbL-b~Kl&g-yK zsv|yM0P%o#F9LsH{5{y<_@BCK{L_XZ~PA#D<%2GuNmj(#G7HeLa~^vR`c|BkPrGy@P#eqKaaBt zlvGx8iWus~YfREMpo5`q%om*>VGrvC<2)>M*Eivw(7Upr99bDmd_Myh-1eGyPx3To zI{C=uy7XQ|BS>ApCM`mg>%Kvafgrs|jKL;kGZbcK73a5fKOT=fTyN79C|}mS1vg^L z*1Olryaq}&mX}ZAxM*^KeZY;@^td&7B43Mw&VfYp+J+cu2gbwD?XgY$ODDd!tChSw z{0GyQ^a{s>Y65n$uHKIXc12eSy-d&(QDw$oc7eoReLqWtf0VdtUh8f|I+2OK%*_+jG`vWzVN0-s`&b*^a{-+7`EZjX_(e+6*RUhuE(x z(lhq!B}}B3kur^B?%1X`zf#`%If+IM-Os5-{E{nlRNC%=b27n-%q4w?0F*F^y|BUe z+|V5WEF2aJ&(GKG1D8JglWP8Pmr_63;7zazl_>&9n-mK(CI4K6cygt(mz1-SCZbm! zvpnPbf%&y#!V0@Ut-tastwL2MhUa#LJ4g3EU6{fiVU45~>>U6F5_1zC@0)$TabFL$ z@?x59#Kw#f^TOQ0SIf)0#9a0f(tHn*3J-2SsNVRUTM`bty)WPx19%QcBhL9#G8!%? z#hy$EzgIhwKKXoDLXSZ9tM4GJKXTz>Wo=!bF*!dK!?a5+oVnG1y6a7#+XrXf8;zlg zo^E;qyZdmi+|LT@&CBA3LuO}~pf2Y5RwhKLDvtf&i?&7=Ie{ph|Gug}trK1@?J<#Y zJ0SE&PrnR!Jt!gb@LtQ_yA+uXcr(p7_@W7~`t3}SB;FRviy|h+2$^()L z@jHTBdTaDNw5!A9e^nz`20RE>`_8>K#p2dRQ6IG2j&9V*Yi{4Lk@noe&S7G8lf*C7 zm4r88@irxe%0T=KAVj+rHVQ{(v4ADYriTeB{1RL1sDyz%jN+A9(pNZ1vYcpl0|K(P z(#{@-t>aO`+;+(fmhXQLs)>8O9%-nkCdxitD;S2hSb@AnEPbk}Zj(o&EZMf*qM!W8 zpl=&Q~^fJASfprgokwo}fk$WvWJ zlbK$ENdj76j^cIsiLUS5rEssMh4;Fw9q*eAUHoj3XbW&WxCaawLd}&LpKM=lfJ#>P zXIa2Qxoj)NrWf~E06+6)I00sIos)w^@!RqR9qiWY`~#g@7Od%$TIh82;WPeE^1F~K zfS9)P8AY3(W@_IwutV+gqspcStlYQvSGt-kYr92 z_x^|tkfEpt9~s}9hEtyMI01FcJLmSxV|xeQHBD^5O^J;w2e8YodBc?>bu27KFWD=B zy`U=`#=f_xJ0x1_<5a(hiw{bS_@MNhd;VH_boi-DL|<*NQmnJhAKc?hZ+7ijD`J#p zgX#ejUwL;gxuwj%e8_FH24-Mdqh8i$2n#7#J#G2(2jz+YBXp4St+?88G(4oIBa;Tv%Y#LEb^-%g6l(kI5Z9cK6W{ z5|~RWv%YD#aA1`t_C)~*cH+~nsb(6MO$yzdZx5iTrS;-GDGh(N8m@%boKPL(7{*~; z_USu%N%yGwAHb(txozC8iLYtHiq0%twnjf`=UxbGiJ?tjq0TExz}K()b(5en-yLzq=E_GM3~!ys zu8CgIx^;`W+K|7d3GQB^xpL4A#O6LeL=)yBIPCm5g?W4su-RUVd+{4khjf`M40C~D zMr{1NIM6RWTx-B4lxeXQ4K3qFlWGBldWQ5O)N=Njvi~&k8eeVhZu)z1p?luF5;D|% z@Zr7M37Lm+Ds?%0sV?yI^lq%C_?aiqk#`v0YBHR4_f9eQ5!3 zV|Rk5OQ)eO{({H?d*1bc)a)v7h6y|a-df1j97fP*s7=c&+#*$#A_lq1)C#pceNK;j z)cU{2Y*UTZepTsIJrshT!GhE&B`9{tgv2Ri?H~bS*tsjxU+`;EH2?fo6zOhh0Uxq_ z$Rys8t>VX6FK>IfSo&`3p-I&!j?Os$Mzg_Hs1J3P;l^X0wY-Zn`D!!&LnT7IKY#BH z{2_DZC4apA@#>z2$uLsGlX({+q6&4rco2m&A4~E+GDC*JW%&fm%fg_l$KPx!ZC*_} z5qWueSj#YZyogDVb22xBgAMmrGOw~E0H5c$Wg3k#v^M2{U_j}h06&0!NRbdtbRO{e4`2~S5tB_OTM`Sqo^^e&fD?&IAh3*#y<9Y6|(pTra2&` zzQc}W05w$LNWHzTq8e@kqLktXPNa2@0c}(VtT?*@ZPkNM4sAz}2X2P0j2Y_fT6?v{ z^AlGHRN1pG2VHh<3bPs9`$1~HM4C2<1@JGc!~Q{w=*$#u4WQ9y`*|2uxme!b(riaQ za-?GpkAw#n2<)Ucqn!p;U0E%p6whJON#=t;YnoZW)G7}&9e|4SnPPuz5)mor>t>XM z8|Q`Y%Ez_Hen4p7gtH6XCk!Ko`9EsmTF}!V_yowJRtQ-Y9+&M^;N!&puVGmm^U9Si zU3giufcVfm&xOs!#+g z4wO4KRE(z07S(x#ph7G+Nk@ZJ01K(Y)MCj1loa_*KiS7_UL{Z$UZ8i1OJSMY^64j^)iL4P8t|N#kj-(wOWQM~v#2S9b`l~1SCyJQ&1rg+-tB6M8_eVVEv@e zbcyWctP!xy;e!F64F$5>7WP2>NoM^L|AH9W?(u~SfeqF#gngIDR;E*e_Y6*MTC)lQ za0VAkm)4sua({m8jhF>S5sl+p59Ffn^w@`FNmS99dX6-2X~WbwT%RI8|Ak1b z&fxY*C$C1dFADqv1L4lI8W&7}?Pbk4*q>q$5@}U#hDLWziYSq+p)!X$YcuULyikLF zd1%;9dScBaR*n&$W)v9wZig3& zZiF*hzx6!%kS)EK`ioZDRvv}inGZ=Zd2DLH9s67zTw{zhv4t za)%;v<9*52f8M&3Md&!K1Ia+}$e0hP<$r+WL;Da0@*yf-sCt0nwI_abp=~QN+Z?4L z2F<(l&~C!>CUi8TWt}V(-FA^#hcO@Osji!lug`o4Ex8#nKG|L83GvsFhZ1tM-mm|m zAkas_!n*!=?pX<`uU8K)SEQ%9P2s%3bHrC(Px*+?%1Jr!><+m0w9ld|8IomiUe@5i zD6h0UBHh2q!B^`v7JW&A7HIsB|U926CIWy@Tz(OFG-Jq z;{>*j`GoX;1my`vDa*SM0cJ*z8Z`#{L*t(6>;WC)?p=2%!>tHUqc_mocpI2x!_B{3Sg z#}qrutN08$_^{`sSUIn5swn~}@#=}Bmy}{I*>=GI`Z3e0I#K6UFi>9x9z}V`0vX2P z7>E{fMjPBR2F}@o$!G}+MA~}$yF=@Y?MnWZYL1SN8R@;!KL}Xv5X2K40s$BUw&*1M zI=-gaMrg>8mM3x4%uR7Mp-m0$P3)BaDBru}4idqMIlIN1x zxBKpYG@s8(cCL%5Bco++HmxByr|8+B#4wXc0(OF%J4fIb_?u*-8$0dKR4HM+fcIq+ z4n+Kb-sxBnts~29uaz7aTsUZUK7iJDeGu9gzk_xY0JPV+)cL@Xf_O2dYglqz#>|yA z+Od3g2^oyM-ytaK=A?}W5ng3-m2kDu+-cAxCOH-^oU~q%_4p^ArnEAM%-p2ETeC!B zJ|gXi>B##XijbKp6m)1bcVJLF`L%}_RZ`(NXZ_Fn1J?-P^$3k7DU7E43Ef3MQU;Q6qz}2tkMUxrH}>ho^{Q`Kd$@tqTq}fuup=@UM*ZqD3oTBA0#Yspr9(xV!|vQDAp_YdDlRb?RrLTN_d8&a_`=AL=WLdQvbR{OnhO>Ar3a z>2WJU(~q@=ZtYR~fBe4Xq$T_JkL6%QA(I=DTYiRii{SynM{Cv3K80QK@P26i>(&yl z1)MPG*P`7@nlX4#9`XzeedHPH4aND#CP(yO>0 zm>8z}BEQ|C!wb!oK2cKlNGwO2lPWxcl)=%A9#DN^{?PBAI*_J4O_@g)E^^+vAsOz& z$)4s;OaR-jW1)fB)pG+*O)ir!&RCN+D9ynEtB)D0iRRVaGY2bdJ_V&OIYnb}5YMCa z2s5$zh|_mwKS>D|$TrK7n#iW@T{ryzGC7JOJF4(jaocfx(=v+CTjR(^H!^a|u2{YLCJ|5H*F$(OKB=&s zhWK{BUe0l=J<`xL-Vu4=n~>2C9fLVIg2IuTf%D`37$++kVYqQ_Ru&8TMFYIxAOS)B zA~Frej_qF5v+L8Ro}y1X*N2gVlr7$+VNaes!GY)U_~RY5t8;ZgH%cL_!XP?02=FMf znB3D#Dgf#zRW#iRU;i4w{;_+#Um+&U$y^lVCv5!Uk%R;Q*>^uuZNri>^^vL&hiV}e zLB@#C&>omRiVwKFFWdm5z5`hkK>M_>2!(Y62^OMOW|5{Dov9#W;*r*Ln@)4pSYnOQ z0&h$5MTAr?FPt8nBX6y^SfL2ub|+-pkc!qQ2xH7MPGkOCQgjf1I-=%>vmXEtuq=y_ z1`0*kLuZ91BB8AFlM!ZM2lp8RI@_)Z4IRmcaA#Na|9;c`pdzK{;LGFY1@`@4HjsmK z?Q}3G=dxO&R{rdOBRCY?q$Y*YbVNh%zH$17Wmo8qR@^g>*mpGrLa*f%`6zXt|7If- z(hBo>Y4*MyN@Bvj2WslMW$Zav9mdr4V74Y7ZC?54z&U*1VsMFJvA+F2sKwmO%pmqo zzvS5K66MqKHhEsb#0DABz&BeOlrwrLa1OZrODcOG_IFkq!%^HX&X%$#>oZ=H&gF%C>P zO$HdhU~0W%1Q^8idok)uwLkNV!=aI+_t_aYqoj{7%aScR2y8pL`VQC+@1_zUu# zgA6$^_|5Ku3yW6oO0=&0v@;GC@=d~ljY-VF()RUzc%@)wg3SRKN$hxfvO}*_@3E2e zm}v20)qtz;U#8u%%x2H~^JooMk4N)13@l|-k;CNhAH-ZP=cDZdXjWfdpGw}JdQQf> zMkMEjW{NGvFtIvOZ=3BYu?0}|Jn3N1=gaEYMY*Vv0DSCa5_=>(N=BL z*=vu`8kkd84bTWEmBkJRrF)OVUHV(xI@T&qP{-(A1xg_lSx#Yo&VnAMmj~{ish1WY zOd_%3kvsV#G%Ci%JAy4O$LPxfm90LY&c?IV=oi8l(q;lAg`3NS<#+k?;`H9f5z?7S z%mg}L?5jGJdC{xUJa35s3?Q@jc-1H{{kx<27>w_-1Hz$Zx7ROd+NXQ{%G`0vtH%aI zNr#YxQ6lHMH@BR2J&UqNgpp{XUd7K$W4_~F!@EA91}zYgSLxE|vz7{7RxdmJwwN<* z8GQrj2F!H7^!?dhtqxwjb>Cae@x|3W$^R+yQz57}EiLJ;W`u9uk-X6DQ>Hq;kDp0r zvpIB|3&q&nM};+U`hf^Krfm1K%|)$MbkQV05BS#CIr44;_cH6?VG`3D|FqdCwk&Ip z!xbKT;IuX@Ry)}s{5R4(0_Y{77sm5WGPe=!a%(H*ynmQ74?WiVYTqk6UoU_8S)96P zLA78hOidDddV0_W+|WsSLKoVgS*VOY;#bS*Dr23rjZP+M+YencdSbo%h~?|aj}F3n zyaLxRxc%{f@SfOieyy{U!{~`rwXbPEkM+eVT3JTah--!I*nfHCtJhpmYbNvJxNP0y z9Wbb|5!r7a`+hgkDUozOKeHC2jE&Bid}qJ$%`)ruf!8~A5($&w?r-q5KsZS71eU?pRl#GSaAbGf(^YX8Je>7hKFNngnTWiH6T2RNIkozDyqQY~>V1*g95rAC!b;yw9Y03~vaj!wrsUF=uI_p|1?mQ+CfQ(NnJ3^Q7L`NO-@(AcWK^^(T^KqoWi z>gmJTv`(g$UAMU+hKrSM1T|aW0F3!cy}TDPK2cwA82PPkGAn?VV@s0pTZ0(v!B0ialisrQqqu zs#)q@ncH{jQ}|YfKhGG4^1eq&%XPZb@AXRnD`Rs6lF7`@el0Zg3C0IoKMy?3UD1_Z z0&LYZrs!B!UDiu&QBf5GgDcO{hA2mXStaDO$?gJ%t2Pcupw&$Xvw|Sa-xO+aDS{Do z(@`ZwoDH-~#W5vR+p5zJ9?Eke`YMpB1)d%IzNPd>5B=ik`s%o!^C-Sbj{1wJ{Srt2 zY;px&UfwIe5R%xcZORO*XZw8)#gF|`g%^Yy9-#L>gD3i7b{#{&HC}z?91P8OcN_MeP}V%b75DvgtC?6p+`B`LUfVP|6b;bBE~47ut2;-! zEoqK`8?>U!)3dd83D9XVt6*5*lqCoq1g^n8MkY{{Cdl)&A-H0!)!G1KW6a$=Kzf&K z7H^08k)gcUUy{PiXv(DIiaFIE$jXj4QI5`_P1gQ-tnkBNE|=pDbrzif(wwXg{g5@E z12TF^6JPp5tK^AG9MU!V*o`MBUfJ$O}U zLDTO=$F$D&86OtDHSuZZcC6$ih6D7(L1k~DX3hu*-iUh67!v4o&W%uYoI;gy%C0-= zwwqg6SY+4YIR9LWGz+6GRDN!qnaI7B(QC6TuFq2Qz!?wOtz6cG1?C*>=lNd@(x}7k) z74&*=XD|b&KAWRLkY^jD_+Jm7<{F~pIvACyY}H2pdL#-6_F-x{1{zdTR!@ zu3s=j@og!!II*@QQSVU69^r;3Ugr#X2=DQ`1rYYMYB<68?)wh3c^QYqwr}ncO#lTg zw2#p`p`)D!Z&cB{(z0=fIBIs9xb0m_1W$w0Lgv6pm)x3M+>8F`WtZE>)glJ>dh!M1{M}#p zA6H;OEtEil#LWj0HdiQZ=NT14Z`--{86#foc;j~^SfaBJNuR(b`^A&zoLA>z>aJ%11A}%GT1Y`bL4eq-(4QgpB`{cd^EFJq zy2&hQo9V`Cu!A(mw1l^D0FT;$ey6FU7aGI~Q9>z(gS;8nSDU`-Z*8hzw;uhH1zd_k zWv6E8HK=)wsFI%PdI~wlp!14K(CfWu zm(MeQj77Zp`3{ThBf-7`K8HcOPj5E-^`QiQCQWN#pQxfxguz_9es}_v=lgL!ouoA= zWDf}U@G8mgdeZy8**sh95z}JpwaHI-Sp$m*U%;-%QYdMlwAPWMYU_2w-!*ijb{Ihc}CWJPp#b z{oFbU+N;PgyZ?pWTJ44bTNik82^)Ft*==ji@y_7*@-8|s*O|SH7az@|?C2Ql5GgQw z{{Op21ep2%-oj`h?kO^L5w{#xkmvQ@{k{I%)(-REd@H6_@vT@qf3CSflu6&}MTDF{ zdjYzlYl&oyJTY?RcM0R3_DB3Uwhu}VS}&h`Q~|^if8NwB{J+4PmXD6(ittQVcyVxh zu>5rmzW>c@2%Vm$V~IXfOmB7Uu=B|iR^|@mPmUHx>FFhh(%wuevJtl2CjE55_Z*4pOe8X4J5 z;>xxso%dLsP;qoP?s&}V*vU1r;=8PlS>uJ0(wp$Hdi3Jzw)Q8jPKc}9o1e5&wX$?P zY$dMZXzzGJ|G2rOmAIS-;h(Hq zqxxozbbIHJ|M~y_`QPOZOe`!~MmOhwxTeV>BWqe(Qugl^EhYDVX+_KZS<#y%Wd5fs zTI#>QqV+VC>BaT6&7JMA6QpVH``3EDx#%Rzm*I~pOE1jdVH3~q!(!`e8Y!Z^eSVlv z#r!90*6<1}(PJ?P;$3rV;MlzNN~wEPw*_qPP+QQUc6Qs26>EL3PS!u`9+_(XePmPh z_vlw!```LyReO&9{NC+8UU##*=u=UReRVb(y-!vC5R;(GOj%0;=Gko{))G$of5k+_ z_UJr1a`=&mSt4Aby6{ij@!0LUZsT9?cP`izHs?>cjMI<3#4sCTJvvPbCMt(nlwpV;H9+MTfU_RZ61J`?8(PE`GnMg?!Vx0jjzTV5TgS*FpO_4$ETP zEPm#mIr{;>>=_i+2s zkM?%O!{H~(WqhX;db6XDF|Yb=iCf~>Jdb6l%wsAngfhJ6y|nkU_p`sh}l)AL(v|LaL_(ZK4WKh`+(X@Ym#kC2J+8^}LnTwKV# zXTrqTsy!8Fj!}~*UmVX%+j+|q&7LY-xXaraF&Wdecv1&z|>Bv&hpW&i(y#OJB&WKtAu=U1agul&omowcjhc%91d#JMCqSM^}=S zyZC$M6xn$NEBspJ{`r>U^<18)hMwpB=e9hTVXVdZ-%pW~&sgdThEd8>Sa}%_KV!a4 z!-|#&HCnQ}{j*%Rud&MoQ|ilm#{(|B>}>iS5eAPRKjxzF!TNo!%-DWG6&J$<6n?+T zF)HJYyA|2F!PW_LqcH-hheIRW0zBA9Lzx_3gvUdiCAWD zd&Ulg++aLu3H|qz$}l$bUgz)4q%sUgvgEhn6fpMo(7oS#>pk<$>wnwP!9lFqt`CEd zs$EbIpr6lm;Y&!I_k1q#7xUw&Of*#vKL?U(Q-+?tzHi}B>Bfqe^O*S;<8Ys2VXS6Y z#-~f8nC`QT0Kva|)eh$H6v7rEWDRC+DhF6BuJj)G~w30I{N_T?!h(LUH?_HUcsA z@5k7J%bILlTz2SzMKOzQsPRllFAoi%I*2Wv@EH**6#n**0!!ATpppk1-MGq3&r#;-=iPY%0 zABv#2Tca*3IE_8;v9`2Kusep8FIoc7(EXFY#lZ}_q+b;!kO{z*qXQRmCL3cJ!$Fci zo}$IufL)b5@O-#!fOG*bEMa9`NmHH}m@5Oasw5gfrFm1I#@s{V zzW68<6x(Qz8$?l6MEZ`}>vm@qnsXG*9#cei`J#HD`8GR$cgl|M=78Qo3VsFpCy1}B z=iT10Y-qguq2F8u2)KSVOqWwrSP{`Ko3cW?D&9z{)d~ZS#Ej8wDE3ogGYX%S&6@*^ zi71QWx`R@k8cLP}kTSfGS?$;mQi(h%m} zHHG`el+p3UrnBur&zd1pqywwPR@4MdspcoJ(S;H*XPYx&#%hvaqF#C~)6ru#g$k-i z{*_-p;`sU97{N;z?)bXv{WUS(^%u@UPC-b@N*i?tvv$nC5ac1uw1zPNELic7^_3u) zLFiiYDvIobMz2~g*$D>7MeBy|1PP9#Kxb-VNJr>y0Ijz^DY6vsoI_L#kh$A2z3=`qj`?s;RfG-Tr7r~qYssAw7K1=3t%cw5 zt4va_BFbA@O`QQ`=;(4<+r&LU$QaWu^mgBtk3sM{UAwasU#_KMDzfGp30}c@w_siwC3SShr(gugI`O4^#V*aDbS(kBI*#_R`W02xb z#eICV@Z|&HG_eEEAJNl5abv3o?@UsEFJyOvhIW7G!JE9iHDJ$!DGI*jc_=1E+?oix zK_hc$J8*hIsSme^(+$6#ap_Rm-`7MfBg4~e=c>L(U@R=Qx^DHwQXALE%gu`q27+ll zf5C$M{Cv-lS|6QQ6b8#K%XMMa#xf%{zrL5~@jHKFvs`|7U7M~3%s0=#UdUfw&ebdQ zCDrTYAL4JFtNUSkt1Pwgeo?cQ7Y{kU_wrWxk0UAoX*C>21=Z$yL>0kt0*EQO6SuGOL^gucTkr-6{OnVaWb9 zzrW@6VfuHMfR8UgCuXufJHOW1RL;06`nI+x?#Mfr6thR zSz+zkaCoIvpt9qeB^c36_O>AyUw?DfbUY-laMuoh`#1`CTzWqv4LaXGvkV*25ZaDv zutt3lLSMLJo_IzEbFqsgfzw`SwGM|59bS{oH@pVKUWgVfDA~DY*}~N~JVNHM@;U7# zUA!nn)}NS;`;KW8xA-u>t|j;R2uSgn-<`hP9pm-iv?+x_H%!Kb?!*Hy~XdI5;>HR#qG)8Sy{9a8E@{Oib4OBN*~&Rw7D8 z1>z5MEZ~7B$ImRBcU>L9$s@EK-Edl2RaHe~Cnh5*YQ8*4>I5_Tq$YW`kYpaZ#41;i1{Oh~qEAt6aY-F!~C+)n>n_RDldMWCt_5JgKPadas*vo#({|7dp z$j_@Xn~}7f|Gi)TXC{w!5ZPOrBm?_h`9MHYvaDwiu(bQv8TX)g=YJ;`|6k>T|67Ut z|95}s>a6mtJ(=Z-@wE!kAlM(n0A?M;`!po(LF~! z&vtqYh1Yfqf<%-t;Ia(!@hpzDR<6YZK@6Xip};_+Ui_JL^34DY2Y=fLrHcVDCI9wH zj-`xS%zP%>y)hcZa1H;J?q+tPs>grS8x23_D%+P%XEX7;XA;uf84CLO*!nMG6qqEP zTwWR0jFfj&l9jhT7%>-)z^|1IcbeIGjH*~OmtnTkjGMISg`%Z)`gnh1&g`pWQgPYb2*WsqIY|i|=!y{D&)z#=1@#s#v_yi&s|y{F$-!e~RWAfKNp#tzAKfmFM8F8d?*wJNS#M8Imb1kRe*PVS63$V_55Wwns_ zv$0(KzCFUBj_2Z^*OJy$OhFFm!+K|wobrOk9L?>7(Nn)1T=zNCs&IsfL z(fp*&m4b0E&16I~zlJNn(b*R=-y z2Ry+@+Aw8x=v8+ZyChiKY+ki0arnEFDg537=S6u4BPYO1{vpHTr}zSFAsdJ0RAIT{ z6^twlRudi5+uI9hqZ8KF86E%`heb!hFc}_3*Kyk^5H)XAygK2H30e!o_}p^@p*!Nk zgQ4CVOfG`TwfU!pSIa0y?2Mr)B(MI4e#44;k8s)1_jxPQ-5H$4Ua{a*+K;=Y!Dxit zF$+$EQ}SKDuC9Cvo1j%GI%ZW}P7UKI?UW>}Ca>B^#eNGcScDDQz{I(E+s6q^Cp@uv z-aB7{PkBn7K)hxiIV^`x)c{)R9=ziVbqoN<7(vKC&aN~VG_tX{B_J*R9Oj#Qcjy(8 zh_ODz_nk?%S*Belicf%XcKY!>F$32Y9Fgd#s8{p4DjrI)`EK-~No5RNw>S)C9t$A8 zN09MBTUyOU-~p@B*rQowiu-JL>#`o2d#R>2lH=TXIm`MrynrzzOnM%j1P8@8`~@cs zNnxty0s=KIWq@N3?0XOV9PLk>mwQ=;m}~)(L%gBE)p%%m1=<$|Z<$B~4-hF#WR@mx zyKGnagLpNU-MbfNV|&Y!)Y`sNEVDSvlbn+38jzdZV{|AZhMJn1 zCr)%hUT2l1S7|zkFfeN<3F*zk*^2mq(!~+QZ$JbJeqxs;wdX7vsLw~Luc8Q8Bp*$% zah>Q$zI=*Wj5cUB?K_sG=q8gi6|ETH2E$uZt#eG2#FQ=e#i(Gs$VioGZEd9+-h)uH zXFeLFt7?LRxCZ?{-JXTs&hDes>Y5si)D#$siHZW0Ao14u%las|(X;2yox3_YaAzVw zz@Z4BMwCgGVu?BI^SaKSJs5;T2DPcvc+3q>Qgiq124dzn%Ra@@iuvM>iQH;nZmL>% zFse62*nq~pQEgNC{moiJk+x2NAn|O9h>wYX=Yn41OB~j2WOnp~0GK43itr9a9Fq+c z3aGK@V|&?j(1~LNag*Kka<}q zsgNvFO9u%XBS5WT9LQm7eQ^vSDD=cEW88^kXJG-z0Irmf24hP#!c+t(C1t8~Y_}-T z2T2yCbwWZOYK^rYFq2VQT3Sx-N2?n@XGkM9-&cf)AJ}m;_#y-5fEK#q6~Jn_ygo@j z@}aob?!G+dQN01U-J2;iRCzKFXRcFGbZ+wy$=%m<+Om}Bi-hT)#Kqz4APwof@O#FP z%s5)}HsAeB!sDZ!C&TQ852-mvc9eB9;`ao`{W*o!Eq2~AD3SFyy?KoTY$pBg-8-BO z^!}R{LHl?U#5-_%!T`}<{|Asmm?S34?GAyt_ceYUy%wx!Z;NL1!hHAFW4^D)@H+n1 znv1Xtd6=VB8LxS7eFJVBVAmVee-=F>8fGA?OIffwY}dgEPM{&cH^Moqw|}@*>-nom z*B6)Hd?uzP-7V*NQ!J_k9JHNvyqFj5*3c-r=hHk0gpFjiGbz#3yZCXMh`d(?Ix$$A zif6L3(UmjNixVTXxmU(f^JSJ)U zXV;9~noN|;w#~^hxcPLnwaFiXQTzgTKYCEFKmrMQY%jJ8$N2^Lr=}#+$_SqMvYc*Y z!|3FNKZ{4IY-nhRgc_x!=?-wCCkApL0#q6xQHRs}G=}f?ka2ww{*kHPMIiz_J1C7` z=?Xpxs2phEXB;n*dHAUFovM5GAaNL`)uhdM!`H2yNA{Ri?oWn?LNMUr<+Va2QhXef z#5T{$-iE;{-=z8V4GfUz?_40fWsBXrn~R2PjfO~CAj}BpOoWsnZ-9gg?7=ChH^5yq zr(1<2IlTRK7k$WzS6-5_;@H*$2M$18X5#%`6_WG+MztE~m>;^|!lDQGr4H{l2cFfd z0l1u=J94$|y0UG@Zn)^&b}ZFOzSbupcTeP<&S6zfwQSIDu*E$JbL_%C zDJf0CrEKl1x-$(O5~oA_JuZVoeLs6pqdYUk^RANAtFVzwNs#(L zycr;>*H$Lqd||8xI$PK+D|hjmVM&0_&{45v69fWp$<<)5(I!r&Y%E>g_0bNJ*>NFC z39MlLTHwVniSzV@ie(F%=dsJ1A0*0?7#ykLs}l*?Ot>}{R@S;5SyK~0J03^;1Qw9VD1&bCTte>3-ER^YVDD(6n1}d1E1qIZV=U2{Ue3m;Dz^pbpR?cN{ zI4}r1!$eU@{l|rw^(!sz zqf&j7FUdOPcOxiDeDlLtSGN+o8x$I9`I0ZI1u~5jz`F__65ox?ND6uiH@;GK$u` zpM5gyEdZAKi8b1^L25*xO&AN*ZUBZCIiK8yrDge7x=BhUJ!~>Hd zUXX>jti=C*8O6C+2N*HLqzTx!WkOi^(B#B;ZEYxNnW7i4_b9Qt|GKfHP+Y| z@QW^9A-d*=)I`tF99E!xDRek-6wfldxgpZF*?%r(*<~e({;!yZplw@`Xi@qoa9%QB??L^Qpyew_wA~2m~v) zprC}!2R1w`y=K|L1;o!a4MfTqM&`cI68A2W=GQqx-@-#ZPJS4n8>=Xss_FgK{j86krd<1hja8U^7( zMuysUdSji4q?T7bS&NRj_d_c5w=DZ!8Wg%}S85Tj{`JP|>IM|~Nu z0wPF19)le}2gU~!`v1wtbNttST=2w=NXR8R0{^`m+X5FxGR?hqZn^d+e{=g)@a6ws*qhHob<12yW`>Y=%kE~Nz@|8~Qd{$oK6vr5-W2gU${M+E%_a{f z@SqUDZ4GosSe#!_@b|S27zg<%t8E3&4DT85-)xc&ut{!4%0#!?Y|76iV{snz<>1(F ze#&a-652Nxh~_9EwZ#tt3fNGxJH2%&V6qt4^!qV{NWG@~Q(&z0KZJSiZ-=$T!xR(p zi76(A!R$^GBOf8Z&8Q)~$N4@$gYhQ9vXgiimhHg!bQtA(SSI5$W*q!xa(EnYP#B*v z@CApWo=&vMuTl_F-IIQWmBvk0We&TVO*Q)0Lmhhhjd4g5#nT*8*pHhbQ=S==BvI2b}LKen@4 zddK0uNSK`wAUJzqp;B+DE(`TY8F%(`pWu3<0x8`C6YaN*w9oD{%#ji}yzAOK{k zoN&7{h;kS-&bMm=L&Oc*)cNg;GQ%J=tD5Hk~lbu?N(Ao}RTtlYk{$UuA#VHKo6-LTn zxReNr6un%(eE0%_G2f!}U1NFOOPZRo{>&XKG1eCtToM-)i$wT#sjBK7d@fd83rsk6 zY@TQYLekWlbu*+B%+>0^W#OlRl-96w*9_?-cD;e@dGrC7l(MX~@^Z}P5I1~u4;cV} zC;h>=Bd^oB<~?}`Ngqz_Ke;4vTjaqdIsJgaB}vTZcS?sfT~i$TxrTXBCv+4yQwkq! zdts+=@D9xWl?%tB?;tzqr;KSF%pQBZYhc`rJcb6x>~_vg-*ztI@>8 zix!C)J^KXU^aU#EC|PBJ@^m+ryxth%5brhSG#<`jJVNY>LG=qykpSZo8Q(v-5dj|C;*fSUpJC zu9Uf>mvuoXysI6?ocz9j6{w%bs9tTsbxa}0*ZSRHn*eZwBqd-; zLs>l9;{}b8qKcd{Ud3hZv2f|qGChx@Q{&f1m*BFnA|O%1OGGSx%rgr<4aSD$<13<| z%LuL95!Fk?wAth>>!rs7WGEai-#}*iC2!0AeWRoBfmIFBwvU~_@whnuQd{n#s4k?e z8ftvQCXi*{yY2eGdbY2}QWr}snEttj(-uxLfQB!*$C6tX4j|-xN$TH}Qs9ucQ zf8ov6?A$#`oeUaETk=o7hR%S6GbEH>eSeWq5JB7yEc|>AOq3^eiNYx=FEjLuc0B*q zeB>!05;0SWOp};pOsW6HIBEEDnPq?vY(naaiVUUtP|oBQBIVt=v;50G79(+wK*%EH zo1a*Y0JmahW#pM~d+RwNP|x)&`I76r+59x5RNHzDbSSDN3L7_`hk(<;05SWU`)SVR zUEnPiXMl&p-^kVIVUU@QH=6U>w$oF82pR7>)RfOvjRA`~5#OvZ;|P8mnJo}zf1=yx zzeFM4C@x8cMX2o>6JO!qpCMy{lVH=yNmv6y$!bWB+H)k>*N9v9BHK7Z@@_xbsM7Vu zCrX1_?WsA6$O?7y!7ZT9Qlg#L#9Y z#5s%wS+V5cVal!vpfESCU-w_q5WcJ4_Bb_T{qj;}(}6B9W2HTnF_dCUVkSD%B3Ra& zW*$!1VH_@Z(Hw#fdTqUMg<{Iz&S9)X7i7SUffY%av>goAKM@_{uOJ}sZf#12nJv-0qSNsu+U3gO4oUHZT4<3(_}SHCXY_EB_Yvbg%bE_ zkYZ8E<2kt+kqJ-lHQJycZusjNNh8?{5MsL!B&-iX@z`>N873|yn#dyF@?Fh`wX<4P z3!B}mx`&ccailKv{@HTH2^r)cS4>(YOBg(r|9#TKpDc@}WK<&Nw06%#V#^lZoDI)% z4QLsaPo2S{MwTWqfP~ihYf?c*1(d*ZP};FeBr|QF%W!t!!0p4vQgdD!8C7YCJ1TgUi$EBWrUtBVg8pFAIwPbbqL*;4AM=$dUvz)7_LO$FH?~MERGs=~$$`f}l9k6(j z_iF-UuIn)YFkp@NF38QFfC#<=kRy1i=8bk&T3avm%6qH3<`-GF43#T~JbU15ic)cq_w;a$4)HpC z@~5iJfZdDi4Mo)I8#vBy-{C{%JtC^b;TtA`>sTg(NOf~Ej3)oUHB(%0+S<&NEfB)k zvU)TR8o8M9{iebN6h(M*Pt9c<0#)=}b{#<8E5DD#R5+H!-{lT&<+p;}Ki>Q9idX*HiBdc1DoOc+`@j`gsb9??43i&0|S z$TXw7^TcG@21#X?l~0=$Z~Nfei~Q4cgoWsHk56}*^s=x7-T)fQS1C*Z6EX$M4gaB7 zbXf*Y8#4i9!NwJT!0b18Odv;l0$2p;lWE|R-N@HXNQ+?M=Cy;d+xe6VDqXm~ z_ph0qUqPf6fzsC80LHUFRyVt30!Im~uSa&;x7>^M_KsXVS#sti_0JDKI1YsT!;^hl zN;EI83-yyldQ-4Z-S65yQKw*Q`1MhBV!s(TYSs_}d+(kpQpc4_Q`J?7hX7TEZH(h4LXld1Km_}@kD%H~?&I8(Zt8n_1Q5*|2anLyPx9>iy zPJQfWvqd<^%qgf)nm-Gu9)W1jP|A(Y{gP9*V}V~&9RpD30yK1MPk8mN`I@gMT1Hwg zrpuJ?buAi`_Bp1MX`1B>o_?jV_gIzuH~NikBuocxvMyRgbOA3`sziA#_9sh}^XpUo zI$`1cKySl7E@Wo@1bxG`lkXKI$H1HbC&1_o1;Jt1){9T@+vgD!C%h$fETjuR|MtyS z&Qe7Yf{ccJw18qN$|{z-T`ulDW8;j%Elz3W4)0(5hIFNwXXhA$2XbU^=pc&GqK@Mf zT=y>Dj29R2B+hMa5wmu_n+J{(iZ5iEz{Se;b1N4<>}IOC29GsIs=}yBos~mW+yH`+ zEf4JHT9qPL+4K9&h0!xY5f$AnPeCE`p0aq1s`G#=Nx)msiZFm9+Y{$jTnoG)tpsI= zrUSex*&Q($H>5pPNHiWQAMN;~*T$v84FZ`JVz3SeXZSMEWvdRd2E-xfJp=prkkKmV zYWe(^mid*BrVnb2gI!RS1KjX9Bnn=!Cc;<@k~q13@*!E7cp6?e^FU z%c;HbLp-p=8FhD-(bihyikZ9w@6vP*hi}+v|LDm|;|gS1(K-*G!OZT{oh(Zch+phU zEI%b#QWtMz4QkWYzBs+ed^qJN_?3M4zb>M0`~luVWf-%IUIC?V>|{#B`$wKKK0`;o zLg_`Z37JJW(;YTn%61M48}%RI5q-&=I#Pub`kW@gz7o zNXAMQKBR*(oj%?iT}S{G-aj-{dj z7%VMgnm3OtmZ*3C{)Q$2xh|faiS_ALhfrVkau`MJ^vEmQyx7a?7Cei7NE^@J={E+) ziwf7-gazV<4KuyoUmaKj8JXc1G60SbBFW90&WC-Z_C>3GUzl;;-SpHZO&yeS(yg1x zsx4sPrp_qr!8gk7XXV%+Zb}wpxwTKEj9OIM8dHd9DNj$-h*Cf`cR(h9S8v*m9mt(f zVWp%}3s|Tlx~&oPD0~JV+vN(J?{LR9hZ{Rc{rad*r zG%3)tka*DEv-9zNcQUmR#_8h4b0uJ4+B;ORi*~RENQoaOFEgL9yIO+?4@STdIPo$J z2iFPRB=|?`6)^q%nFyxP2*l1#G0ctiCl6ME=f&4}_P>v>BggzDU!byY$uXz5jz!p9 zUmYDC*2Rn4BHcW>0%W1rOu~EYt$qgm`@RKV8ZfkGk2EnJ5O!sRrjZOo58KC^FXSWd zAU8(P0X-(R)4KZ7G3MHK`bVoA%z`8^vzWb2jF^&x6)A7OcNwmF4cCWPUB zCKCC0YJxx;Ie}m>iaSKz`&(AbxD5o!0YJlyZx56+ZTEW5J`?ZY;eh2`E}8~(gc}!P z;jS4yz8-u7XJ;1j=H<+W>q!o%nhs42RS-F1gxOkCATNEbj#|P`k?oLt9yAl&S8aN# zYS(?plqdcqTqEckMBW%-ec%L2Ok+^?qgM&4G~EsT&xc>TJg&0NweR<(4k2R(My`~J zL>J*lN2EG;TX!pdOsLFwa*2TrE}S3EO|oQdI{A`sfIbLF#-wZm8yj1)x&MxRs`8U9 zSMs2P5C0P3G`!_zh*qrKofvcb+x0{eKWavNlsWJjda>_ zww|)8UJTi5^KBgR;x>5J%dlG5=cfq(3p@-}c@%W>;YTEFOa`P1!B{lGiRqzYrU^@Wh+00We|078ozQF+5!Yp(`7U+i44J9q)}!H zoJgrq+6L_MfBFQ>Vwgag92=JlEDX+h8{YbMWp@5L^KQ_!y;a9hFI=_ll9zW_!qhII zJBuOFj$4nM!}~!P&rpNPJ0`!M7j=0?CP)YjCo#&X-GfPUrol-HkURt(>`_IIt>TyQ z+-|h0jZZzsaepJDaQEg5T$>n3ra$gc=k+tYEDMBEE z>BtoZ;gPmvRy&h3aErt(c{dla=TGq(3gmaKs~tdx-t@2LtF%FNrH{=~<`HC+BFNzj z@ugOOd<2Di)!v*IMWy{Mg!}QOmh3}k+$X&%oHM8NQiR2!zX`X4f|)2mqnD>GQY0Ro zL^^N<<2|#jLDBgu#wo;*#0-zS<&*RKm!WtL2oe@_+D`nk;V?OIk|4!4Ep@?&q(;$! zs&*v|GrZE@M8SI@P|__$7*2Ung&YxmLMV3*uq1)G2;6n3D$+M5LOlw0J@9=lTm^5K z92361J+k1+CaXq&x${_iMv$|5>xD;8PpYZ8PLU@tq!eDl?08?1hU!J<;i|5@g;UB= z{@D|W1PrTx1uVbgkXXcDlY-)d<-{U`!o1zxb;k`ffA;7V8B|49la(C>30+A7xTqv# zk-Wn!RXz=c;$avRcv#UZ`#}j+r{NCwm}>R;7+ElI_MH=M(Rb>D2yGRiFs&9}xMLMK zohX5##5mznSwPNwbLJ$xgVYo+vKtu(uJt?seZ4$9WQ=dQ?TGST{HRKNSwjI5ySZOw zFt;Q!ZEXD}TXoJ3x#4i(4sRtCGD^qKcb5YQ!y3s#=Bi_ge(u4@flx5_?XMwxKQ_|6rf7FrKig6q`(b@hah6`^FznKn9yzx zAI6?@c8}Kwq4M8TX*wW#XO#kx?NoA5Y>Att&)q>};m^tj4FT!eYB#V3W6i19O~ekZ zkp*qIeay$fBP1+Z%xHgWF#EAA22x}Vp|&43_M@B7ir_Myz@39sjGilW?s!i9#C3;q z3EaSh;ilY*;=&26DfhNZmbfu)fd7({0}!1XQh?4LyT4ID!C z6ya6jtiP!qz5R7baoj1vavV(9C;*90!?A8P)zu)TV){lNJWL7Qu%b5-QwcVP z6}KSa81ET86ShC9J~wN)S_{5boFt3)rA#w%&k0yJWpwE8S~9us`!2teYvKhPQ6^m< zjEwfcta3Tm(zz6&=ABV%bix!nH0EvZ-~E1##3Y7*MvMmd=FWBKgGbkz#VDE}O9y-0 zr|G(OV2fDRgxCuVNg8~IkkR$lEz*6v%HKk7yyWrEgrdS9wK}JeQ*7V9Yu7w` zU(^gq%WuZ6y|aAoMc`LaW~-Gw-=$qu4M&vC%(H2C>fMamTEmdZh2GMt2tK1zGkJ8B z_$3a7r7L}LDWio<#e_L%+Dkd)j2s9?q9g1AW^^MBUVs`_yyn~Gp(+UR5A(t;b4ViL zd1J9WMo$mB>dtAL7h#TF=lx~_?sio*!g!lpwTYv<_RF~*hrewT!s^CfShHcoPo3>8 zCP;NWRP*9m&d$E^($@onhS5ZR*5VZ!UBOFF16X??bvLhIuKNVA7d9Fa+>%TFN2yNl zYHlLhU&K#Q=md-88&ZV9Dylg`%lnGoq6qlp&1XFZIJ~RJQRwW?@qub<_jd6WFtpbx zua`B?-fU61y-Q^75D<^dAB|@szpl;v6h7Ad(8coL#~|?fi$ixUjz$K!VWcEyGsdl! zXlCt}Sbck8wU~(=n38A=-d(VB9PV9`C$BC6J~m%u;(P^#j7w5-uq}r51&g!tQ}*Lt zPAEdR>WItqFMfVX(*VeHAJ7;6R^5A=&fBlz2ZKm?BS$ z_@|FSFhB9;Bhuw7uP&VQru+z+1;&|wfV0nsR;6`tD4bG{GwWB#sX0H`G2SU}ZWx%n zTBx4u;lQSo=$#+y8N6BnP0q3Jh$Knd#)pnmTI*z395Px@IRcT!9F&Q`(YN`ZUSCcG zel`0?%_$6dKsD0pG)BTdt+3LDh0S{oyfR^U8-GVqgH$hv)QXeWHF#6b)NMePInWy6 zv;JUu(9oHvN!}{{!X^Fb`s1xdcvC{Oa_LvMN zIkh?Tk~Ok&9Xc5=WVpGxBb40PZP?k_=Szd*JMN1TAt4mPwY0@4$`kd`2q9c1($aU0 zEt*YX5kt5r3I|W2_afcR!FFqylhS@yCrit(An4(}y+lU0!Pw#E5%M3n`w;Jiem6Lb zu$bOmw-DnicT%3qpd!3-J6uqao!N;KdxNCc!W|S#omEVcp__5p)CI!Xd-QoAxfOgC zW|HajYF1&ed*JT>ZoviBOHH~uA2T;dUnI^m5;rzUI1k;S)w3OQ^E%M zuMF!Uv>oqBB5?SQsiXqFUvL=Yv9d1qadN0(L;Od-e&UklyDkQa1O-1>A{?DjI-$`j zCCRMt7jJ1^w$ju9+ogJTnQEiE`$C(7Adu)6M`LI+;?-qdsWJ#bqNnqcc$S|o@873P zR_5#kx;1{_62RKa==ga?G7>gqcgJJZ>ld|8%AqoM-KfsT0| z(Qvx#=~Gl(XR?^ONmukoW#lx9C7G+?Y0lgk1D2C{+8fL(qw{QM?FQ2xDgC_Ib(=#X zn!d|C>}Odv_KpThU0}||>r+vt++g7iTD`gWO0vDibl|&6eGul0y*&1q<}-S4P`hHY z--6&A*bEE(2&kU~03{bm6{Tif;R_eElc~i&cOdmA7haWL2H4s+JuB2$U4^d8eGpXh zk~Y4@dK}3n0;%C+Z=x2mutXoRi*$4ykhX}?uIG{`%?3AV4KJ)8%J)ZAf9t4S&0Vgp zstWwP)b0Hgk)59eUNHnnQ;%tK>yY8zI9&Y){Lmd7Ke%ZO;;gu~sK05S9@ZyMK%@iR zJFEEkp51T;?Q2Alr(ME}mqD{++3Tv|@}>hL!A1)Oy$7nOdvJ_SI~_gRf&&lR4yr56 z*InxE;h_hdb#negtGD@f6+lLPr~1r-hU>JHHgDd%e!Z7BA0bQKYa?_~uvHLbS=$kH zB3<%V@9)D79cKxwX+iUg61R>p|CzlECg!^$>E6UqC+ty_P}ie^>j*BQ#sJx0K@|uW zSPlSFU$i`GxG;LR)bg^BCWU7!Qnl1h3Y1t1Y#CKNtD0 zKj^FS*H>P_&uX}{)JEzYr{J;A*2ZEC5N8KGZ4Mfq(!l=2lNNy@DT-QU|G96z&?`du zg`HcW^J0pOhQb9|?fe2E{$L=gZ(2Gs+oBAwcDys8MZ=d4C@btHBEAPs}u| zBBI66sSkIje%_oO$YI4g15O}MetRIbDp2{4f*tq>PPu4&IOvZT46MQ16%-I)?v>I3 zgwdU9JfsAvB$QK}Dy%kHH#wo$?K)g1LP(_+tjN0J0SR%o{uREoQ@}ukD)8vYCDf+D zuPHZj?5#8n!`_siO6!6sRD&8oKnojE$N4#0XXJF?Ku`%kT~5qX zmheY{I-ogV*ZKD}0-XQ(jz}RY_rGQQ=-?osL896^){{iAp7~Rt+k>;?G(2__zvkY1 zKj0sK`62(M4R%pPBJ6}<8Hwi6fsM*dmNSK>zz=6eOOrVp3dpv~?L`9Z)ro4NYp_%rxwS7X+PGo2bhO}42#k&5UAZovXw|H50hI^50F1A>Rrp~;2CkxV(MGRJclivLoJ zAFx5QUo_CCt#yZvQ9Hceph9)}^ph&VV`c!}xAse@2wpbZVm($BlyIj=n)_kG7+6B+ zYrsy6O`&_?cZT_An`Q&uEF)ker#dyY>vQu1k1XfFV}JfB{}sCuKAMd9(+{9TwtqDX z^77`*M4}7N-hxnnVkW!%IpBrF**)gkQWlo3$O5Ckepl)D7LB74EIG$-&?X1;)L$s# zw$0=T!DFQIg=+_ipb=>mwm~iOY0VAoIsXKbK$NoL!by71~jb|XjV_?{xdLhsuC^^_+ofN zf+R21@dkew0X-|ejFb+DMIEDNv?85&iKs%!Apy1IAlK>U>8U!9sg)d@P?S3dr2oR+ z_{}I$F9l?y`^EjN14@-MZKq>-V=q0BKHMg4rE55LVH)2%?*aqB9m9Y3X&tz<<{ z;tS3{DR69Bg=4|1^(CPIjjqg0zfb9N8525sj82_8^|R+1=)K);8z)~*^m7?-ucE}N{?RCl zNbf(5vP+@bff*xcCqcDF#7`G+g>V#&Ub-rq{pyv<2!tlAtn1{~3E>WFpOz6n$aoLpIOhZoy zOBIg0KMx;B0E0*BQF;kzm$LE-SsSHuP#PsXw8mgUz|+MI?SKj&HwdLv#k+?$;ov<3 zptz}U{^Avnz9n)U+T1!gLD=xU>~$NmlKyKG*@d-{*e5GFJf;!)Ow#c@IC{w!K`4`w zCf$0#fxD<^seze_@YN+8G}!+XAgZTY<1%%yY|2866qU}kT%BccW`oJ@kHt)Uc30QW zqeM&oLU8%M4^d{8T_EBuJ-)%93E#2!Pii%PL_d9M+c#aUC8Z#OnveE>b?DML7#+H0 zAM&By9)U&>`ktbasv2M-Wa@Y7st!ASmprV|)PX%Q7RL?v2E*?fg%{wTS0sAgzU}vh zJyJ6N2a^32v$$ES#@;QFa%VE5J~PeQu&MUxA*02Z`k8EZ8&$#DV-pbG+V~hq)^f>B zhdZ>vmJnKSHv)hGooPp5gT5A~fZ&)diaqjLZY0pSkOQqiTjH->tc+Z6zN_e>Uq$V| z7ZbB<_J9mGTqS75Y-Io@%C3;lD0cWgiLh|OVYB*Sy)U;bOfE8Yb*k9jIR{ChIx3v= zkbdJg4&^61H7pENc?aq5(@+)Q!CvYR>-+7 z{tAgEwBxR9WLn8<(U{>G$%M8GHs(D+si~#oql2&dwyl~N?@E92DQHPqn@rgz9Ur8Uf;}*Z-mU);BpDhExTJRwhOIuheIYSKjDXQmOhc1 zRjAyQmTI5Y(AHid3A*Y9<>wo^Z)k=o?Y9kR>?D=Dzxg+9Pt6 z2R9Y>%aR^)otl~&`9>8!;|5IQns7;X(g2A_T3Q%Tof)oHM}6Y&th|U zi`aP^Usy}=cDlyFkduAVdojG^hx>9t;0lB;Gs{7IN}T1X?z{yH(M(~pLe zbC#JpSMe^7v*l79?yJ*zjJxKp<>PEjAkK!gj%!0C&j0nbuOp%jRv-@LV5vMNN?eS3 zP#Ze5IfIeC#jm2F=c!@sF&zEa2THOI+GlocDaAO@ZCPpe*9I8GqSEX83NsQc681m6 zZ?Qa5^Nwn87V_>n+aR5GFXzjVyK9k5N2?Vn5IIX8`LhY<-*Cv~ziRT`yxBp~%VVD7 zf$l5j79Dq(yTNI9oQjJHv)%G8(TA`1K<<9+^xIM_g?p-~jX7-FzLqcN=a(9~yU}Ls z4B$mb@1HdI8uFTX{LKx=$+kYO#^{spR|Xo1S3UEzSke6gEtvP^5;mAa25N7{u2u5q zri2AP4qi~=NxAgR_}I=+l~q4=FNw!bl&e#7;~{YrP>-x{7nynSafLb+?z8(5K_fU^ zww~`|7F*%{px^eq^!NiDSA zf)0sQf5l+P-X{Q10iFuK!H2eO-x#KdB-qRF1;Q5<3yw#eS6W&MN9oRaifWb)ZVxOc zD1G%Di`rP9GUtt}1`Wf)zg#1YhfMVq#{-%VZ@J0Ci@D6KgZ^q`s9)6*O3v$48Nv%o zEKq=s76Qvk?PpXpei2G=KHL)o>5>h;SZTv|UY)e?qR)v(h@)oajOJ0x#k_**DqWcI zeHtZ_ULD}!PQ6iqJ=wTfx)q-&q{$$44`d!WqHwDtmUI09-QX-jUyXcYH%dJ-WHIF@ z$0IS~w0DS5DgGA3gvIb}wrVtFqS*4T;N#oNsfr;LFZDKE>ia+o!z@krn6_1ViyN~q zKbHX~u=w^4i;&&Fx@Q0I+m230l|zSYt}%ZLDJc_r(}8ePKhZSIcdgXf2rF|Sc%Yk5 zPS=WtK$2}kL{XsB!&03lZ9!f^9TDL^fvZ3*^^BuvdY3diF8BCkRKdmQBve2D!d9P&9=(}7J*Y#4! zww-glDXHGxU;6r$NV*RFUoZMi>05Z;BX#@WB9upWfBb-$r6^@Tx`j2Ft#tAX2ESFn zcMAv#=0#fW`)%8E#@AqLDdkUioLX^WAzm-F%v4diM$nNvIJeJ@8~y~ykx zskrE47kXB_DSl;;?&AFh5DD6{^bRi+{@%xXRQZ^zi7E{xnW!?&tCNOSHd~V%c~k6% zPW)saIpTDVz(C*LnS1cxD37E07!c`3`s0-{w_q&4)#Ln3zkGa=XyFrB`kIxs%LP3E zD;}vjBOL!*D5}(Y>W0MVp|l!7>z`H8dw3gl(L}3bS;y#W&twX3<)Ec5dZrh-;Mdh6MMzhWQmZto>F}|h~6u{%jpCOh9NT#Lb=>47gT(8#4 z;0XB6=Dh6XGx`Ui*>BSOo^xYd$KcM1mkvrX;|hr3|C8Q~-9*XHy}tC+lWv$5`yoGc z%wwEh6k_F6G3F&p`VfTCn??{QMtEQeGH6}^<^v|dXopB9%d~CC zOkKO*x${^`v*4W{AM!|_yhezfxT`|7&Y?>@?6P+AzwKb{iTm^kGKqh6$UCh2?x>=H zrVX`_76gcmPN%7b86%Lm*{a2dE{;oZ^McdM*x6Ou5OZfD(SS8R^RSObK5?E{-G(FZr_6)0F7>VH(Q z7LAc3we3q2Gv4UnHvhbC@G>u=;$ZL@RbEeMBZ>V_>gkk+?&-buKipd#-iBNSlf(!e zKc1YDjZmc>jmi3%MpL--mFrF9rSb89T8JmVvhxJgNurN98_$`&aNdo=5c$N>p@ZBI zVY+PZUTXBOKOkcwbGEdqFyiqUIrXS_w+MN@;H z()f?`d+cr^bRH+(D-vD0?g}zc7S*VhNOiPdxz7D7o#&?`EJUavgyMDfPPxXN zNFQCzvnG9vu3V%}H9PRb!b|Ve(pJC^?TX#2ua`QdYu~YBujk^Cx0e)Wq9~373qZk( zvS!U1^}Vj%&Ld>_JP2X1H3`{`tA?dJa7Q1&5I7|VuQo)!7oWXw0bKD6vd402ucv&=@hpvQTD@^hf$1JMgc6;STXhtk#p`K47kG#8u@ z$Y7|Fk3B{m1}t!4@0o>wEM$m$JWwTiRn9dL(>h%1*mmGBeIU4cxw}8&p(AhOj#AfA z+Pd|=gXXjgyr9_$;}>V&T;=`j3K`0`<}6be%FiL(Lc*+mK|x!9X*v9XyMkxg<`b?S&QI;f zwam1Kxd5Q`fPT^w`e7MCZHP`tyvZ97Nfyx2Or@hZc+=ML2taVy6ND{T0ep8PHXAvC z>O85_bqT>oglbSQ_@q1$Zmd}t&6fPqX_yPp&EGzhHxn8esJQ?N7oEZa7ssTwa^8!c zX`i3%GMU*1!uAweY1oj1e*~4V_y>F(H$G4q_yrs=2Dh*Ia{(GH?Z^Gnz*lX3#6*zh z%;_mdC5J5o&|Bz%ux0P;edTZ8ZqFI%DM~a>dxApUb#MmTAVNWVpX1g)!#hV!il=G7 zp>LwSJ+sVuJ_Chmpu0**46qD>=t;<026h^pF}aJEA4RNqy8zb% zSojf1cyKV=3}ETwAW`s|SOXFRtaf2 zeed1jC474RqI%c==Wa?=cZ+m&R0|-#2DJhtrs{13Gqb0-|Ee4w5|9D$=fj39(*evc zM_XO-J>)8rz}}%QaPJ|=zjU#(YE-m7Y^S&m8OlHc3guMUEd-oJq(*#UcbMayA3?El zau}}G%I4fX6}H9ZIMlxg<3F05Q`Dj3RHp(?Ti((9j==8#6dgu{0^fHpAwZ}nd=T8C zR_Q}fIX#%bsBUv!VtcS^MN}T!BX_jl`xUL!xVQeG0FR1_$|;tTb#${4Z0YU%l_qvO z6m?%EB$s{tWI9TTh}8|BlUC^&4^dmmdsx9GVVtj1nb1hmb_)mSvF6SPWn``>Ta`lZq)D6Q>Joav$5*%W=T*U#()}hpafC7HzI>8(E$iiH0)6ags&(~4@ z;7~^B;R3`4$zS?WXa!lKtuhXznbpuhpOxAj5b3KmiH-oDpS~sCLuuLhJz@8lmCGt- z{nFcYe=oq{L(h+13sPt^R(+LVu@?l7-=g4xw>R+QO;!N&JcLdYpPQx1XfReac zp%WD~fm6;Y;s4|6s%Jk&>?SDf&A4=6&8Gq%Di8v?rFC`5!K||x^p2A(4j0-3lp~6F zcr$m6eE4B)way!CCw4ZKahyW|{i+MaPqNIkZeAM)DKgFg0mONXe~gO)oovos6D{*1 z3KGDySgBXqN~X(+**}o8x*w!~>?!*1O5&d895YJdvl>g-X>I3B9UOkDIaVHD{`OBH z@hXA9fL{+Rm?lrlZW}iGVFCN!;AjTG15}sWoQ*b1mMn?nG`@Gd|>!L@wL(ov$JkDcHBwz0K^(Lio(&a6(;BN$Q(kf zn1zc&lDBB+w%Xv+XA6xr0a^TC?7ekZS6kOEOo}35AV{k;NS7d?A`Q~5Al)G)Af>3F zlpx(9B_Ie0A}tLfDJ@-sNK3;R>j&;<@8^52_x-NxoWI_4_8}~oDnerI5(P4ZQ_fhvj0i4x4@v*TGsqegaYsNG$Y|>9Agm74 zMI<5tKykx4ae|DoIy32>#)Dv@r#sMJn&zRCsy0UkG;ZWo3sfJ!vel=fL=L-TrWFy6 z&eKy5Je#5DTc-#3tMR7!e#z7fBQ%S~Z-ys_TyNo{0x5D%X-}}fi}Y^go`oLoD`fSX zxrl1MX_$bdyL-9Ii?|e6vDNbQwy0Ya9^qvtpe7i) z%^)8`OBPPD{RtWC7C>aD=S+QydQ&kEVZ&s8xQW*{$?k4p!MykzI9r(1V~%SS^gGdg zIy%H3Rv>3l@0IX9s01#-MBbEXK?}Q8z)mR3TJ}{`#6$=K4|EVV)EClMY#;tOV-fKU z3L8s~qXU6JRG%m-i>sniAULm5?yx+Xn(14qQ%(~mFg64vsqS>%-BJUU9Hs{< z4?|FNi52MHP)pVGm|@_rho2 zKZNoIVE3@l6lLkCgW}}`Q!YJv2XQY$tBm{%2(7>gW*2I{XJ);dshHSrs{L-7ncp3S z5+_JuqV1ACK*D*j@0A-+Q5ng;Q_L&PYfuB*#_Q0-o@;R0v>pL~B!FM)HC1n`50pbn zQ79bEE;60p|FV!PuS7nLeH(UrU|=ivN-&qI+Gfqa4BdqRcoB)1c+$sl8OvBdI*GnI zd@-C(V_r$iKH9zV%6-`M9{m~?aAp1&RRZBh(*2x1T>g6j8Lvf{3luBwy14OdJ8oK00sF-Quv9ht>v_ z88{04)r_jUJ*Qi>)5N5p^Bam>7LkdB3ezmi%rAqf4yVn@nfVr}BI$yibciiReoxuI&rFw|g1 zp?Afj*?4vPrFUSbKyF*59`&-VpFev2dTO(YN=Z&=XlR{0ni*MNrjn14GbH3&g1nFh z8dxq26ezzQ(3dwJqKTa#R+#vWji`9a!8$k18aov;5AcHbzJxNDsXEDfH@*X^HNa~L zM2D<%s90TGEj{Sn_Ts&uo>>2lO>TWFF2kDo8?K03oR34rhy6zixu9bJz+L2s_z0GS z7J0nvFX%|Qo2hu&_s#_<7A0WNS_L@MMYhjc`UG|g=lVgv30z|7oZvXM)wQYOe z))td0O2I`g0FpZQ5`iy$;WZo@I!^eVd%0Wts2te~%hPWMLm_pkK(g2iDPz?gQAEVA z6BJEAyIg8{y286G0G9&D`QHIJ5%w|+_}g5PJ8I8ygglJkaEDZE|H_IuagL9NKxWYq z$)+~ApOy%f$%k)1P7gh|64{6cr7Xffbi(@Ywr&QXB%%TE)%Sp528z;=UKjWzJenzm z-HJY5&Tk2AonL!~%m}Y5Zx#8KzOYQpob}V5fHFb82<*y|@{c;$)WRkc=8qU`1wP*d z+;U}i30R#ZmyxxiRbJF8Kml4{ztqImHta2V9WH>x1hsJGH0Hshww!S{xdxnT_duv`tYysqy0k$6Q>-iJ-IVF7k7w^Fz(tOG98<>0upg)vW8ztegKYVjT zb&>3DserCY;i{v)ElB>Bx!@h^Fq9`3t01`HLWZ>SY_HkRz^_&vT2DJn*!wChGlDF*cM6Vdz$)FEYi2^=GI@}efFX&PX0^}6bjl9kddr_aJc zn$~MI)F**rWtG7*YVQ3tq`n15MOYUT6l7&-2pfPE&9a8tQ?!>4z5?*I1!@40u?sI9 z=%DRycxPx8(zb5AeTU#m2jcby=D3_*k4`NX5>ZOdTv7xFF40QfqA)Nl4tPn z2uacL&gl`X@|f#UE1e3D+KQIGz@Ld6w>won?l!y}30kvCDOgZLVEu}uh{WZmwt!;` zRl5Y3K>4en8p+28wEktATidl~DAtYYk8>{M{;&PHe<<&?17T~q^R*hI0`)YcZN+C% z92{B1gAE8-(-0sC&lduO9|yW{2cTTz1DzRmTO0bd8{Qf|@qnp9k;{Gk;}qJ(rFi4JJ{+=b5og8#|cQBMPrgfU~Q;g9cu#R=UE%K*qR!i^$@kfUc1*eV%u zV_{K3KkX?z<-6it(XP&7z7iQh}&1l_uvc!5A9Qe9Oa42&9?yK28!@A zxpnYYzYfSZ^c~p}QInCyL_{>)ZU_1(=u1L37*#nm0ioWbvxlH$SiWQ1!R5-!Fdpg! zJco@Q!jTvuSMBzhj93?d4;;IpLShv_2DTXEd_e71hYq!yB7wj?hNx?V#vC~+vFCUo zcosr9y9lBg7cO2z+8cl_cjKeqU$9Vh?DHxh$^c*RwL2M10_=i$t+rlxOYAP)%h0C= z$BHQUeb{zoAW?+&nwSbf5MuG|UZ$)9N1Bmq+bF~Yd`fbo57TQd0O^_xMI{60NsB_W}$=OPbvPk?g5?ldePJmJR& zJ3eV;q@e{VTcX~UC3X}|t?JJOpe9&wope)Fx*F{0ViCd(1ew=3A`6JiVCdpi6Z^cc zra=)=i~*|A>s z@#nIE2HH~lf4k;1xma2y)Ppt(f*{@Q{tbz;*da0!OCWX!djtHaG`fTcf)s+N6c}^1 z5B_?b&kfLpxn1$|3J=dZ;*PONQf}^oDA)mWy>7pplH>jj&^`v9&j!rxziyqFPeMM7 zS#2JWZm4b+>_=<4S}Zft4c75aW% zi$FQmOqa{wxkJxjxGr_+>e*Aj^S|!4bTm;u=ErXzHw%b0;a~HG^zJ1B zH*<^?DZ0UGiU?DT?T3Ldhb_~eL5FXaK>iEQMfOj4BHxGtX}4Mj7*;6*3jh$s6ie@K78ZZ0^NlrNbwLBnFHuf2eC2aE)cpNvK=E5y8oNEgz)U( z^$&zf4XJ_Q=URk$_GqOFr3dJ8X^;N-fY_|7EMGdT^Wf;f%li!+9ioK(N((W7EDrJ= zyG($;!no+5io7+u|HboM{0vIJac}7 zNM%Bra639W;9aT!s!`qnc@e1xF9Z6BuRH7%_YJSLq9JXpN7EzkTEGeJ1yC2jw-(gf z<_`=0hUGH4`uqzH%+?oV{*Wm%YXj3fJ`oY5ZVF7rv`X@KNGqo)Dac;@`B-wqaRGX| zia^v8(BG*foN^#);)O%fLVm0)jc=P|^_w>2mf*t`030CLR#VCD-c=o;EmBASvC zY1m6kAZ7c!u+5G@t3mBK^zWW1k90RNNq1iB201;rDf8Gv6Edo^M zMv?at_0UVf$i>TuH^uQwMvYtyTHk-3x?B{wxMml6&)<_B9yvEEB#KZ#pAXUj3}Wce z)FCA$)dVW3_MDJV!ehCh^rsmJhx{zH?1(vWkP3o*!advz7&WI(oq|065kg9=ZTL7V zZ)o_OkeW^K91)Q!Y^i!bGO}dDhh67CH+UnSrG~sCSbQ^ZEKNBLyDCi2JHjCP6mB_me>1Z7+wx=6}9C(mff--Aa_hj7VhurxB{;^u~`*5YF-LYGo; z{}(S-^be5ZTT6KBBXSzwE0S)YbAcELZBj>sZiWY*bp>^ryikqTqisEHN}gna(26ys zN(iHC2qUVp3MW)ByE6n%p?OB$QU6$ER1xPC`v0bdWDh$RBsVd-PEfbMZsbf2=fl%m zworR$7RV*a`LYMJb^sZI4pftFpwDXn!^Rn9=9Rk5S#aW!45E-0{GkT4Mqqfw z!_gHgUiErRRcnfJF+5CHt~?=w3TRwN$YpFeW-8HwsZyp`)l@M;)`WZmI<^GqptwJA zeW{#=bSEE6>^e%&n2GlJQ>gmtan+rkfri+70HUd?5;X&zks3-IYun9yCTr0m1Upy| z9cd5MzUsuxvd!k!^1Sj|>`L=*b&bvS)E9-_+niV!+VOeb@Z`fofYxw!%K;=nefmKm zo;78CR%-_HU2?4!^MiMDCxGWYV>S;olG+{*7z;XyVC+I@(a1?pyDHza4@Wa7>A!s? zoZ!AHy|ez^U4prh8k|uPxkl(iI#*^w1Q_ah!b}@Qx*{fvdPIbfnK@ezR!sAUaNQY!N$O^Vme%!^Q- zsXv{y3mzoiX3%|}_mj7x!z6EZ{Z=Pv6LHGy0+Uwd`r>^sijXJ*{cuTwtAXF(VQ+ig zBd7-julh+~yGyN{+X7^Oa)+)28xbn6_7a25Kkx!;(R50n3mh{MH9Bo#cHOH{&?71J z{6J<%>x#H6R0ZN2U$?tEi`oL;M8LK%<{rEa&IkEDb0q()uJbiQWGHu!0)yCl=0e*Q z&d51VQoM=6Z#kVkA4;|BjUw!MoWl7U+IsF4TSc3hgC3uH_bTL&DQU30^Sp(zy^_kN z4T>fcT~Eul5f7L1u;0^9noEW=qp`XVrU`;A8GN|esASj^$Sa0`f#~c2_1qHJz##HE zZ9>fUpjPQu3KA}W3uFHD?Wp(c0E`to-{KqdibR2PXXP4@JP?1*U4wyn4U=@r8y3m& z*L}YX{O;S9rJF5M=2)b{l}ON*-i=i~XP#s>%Try+0wJJ=0j*W6XwxCCZ!=RKKv^5A z5I{dxbqb%%x;ojCoD_4l*byfB^}ubdcYvcgR2hYyqm$`4u@Bs`$J6GJpx}AJ^6dF z*=lkTS0z<61P;H;-7BygxFfrLRs~wGBel)Q5VX1_!pf)F{X`x>rG{LdP+}@@ZbnHq z5+_v-Z2 zJQzRA`VC6l;Ou}A%Vqo$8AE8W@{b4zz)Oz4`Vv!2hhqCPVks)|-U)L`!;z(cvFYZE2xuI}f>y5nDler` zJsfg}l?n097|Qf_O?jU408z_TeyBwS>y@gVtn9c$oAh@@oKPHlmFE-{u}TvZ5D@0u z2MPBTvgY=W)SBUwgd^@CDgzDK88_8#GG2;1BD$q0^IQ(??%fR!Ww*Wa(OHY$8cNqk3R!&!!C3d0xv`i-#q$!=Zbfu(4 zfT5ET?<|yOEKGz{c^9E5o1Oui8TxN_n!0R?Tl53@`aV`f*S|x#)9F6o!StlAMP48| zyAJNSgA-B`o|TBpOYCD_j;(f`6(2OjUu^7~XH0EDKC$t!fYW@K5r~h{Lf@#V{iDmk)p`#wzwcRGFM`soui?)0x%#BQ4hNP!s)t=-E%-)jZI+%5S2tif$>cB9Js>)2sZcTUguU6b)Oe zyquhBXiJu*!-tpRo{=h%f(!QUJ#zP4c_ds%@@k91s2@NCf;KV#UHiIWoY&iUx(Y|f zCSI0N1g*oRU`u+H+|ba}eLE54B?b*lOiW`-R(OlavNHg}o(cS_A;lTpZa)GIy(MhuU_08zV^_>+@s6Na zU;uF~W;)c)xI-BtubUC4LQYd9-zozSuV!vI)#Ie8jyyW=f|2KJRvCb(k&~}!$hlot zjhe5?!Rqk34?b|I1n4WjaC&c6wV>Hzz(L2TTuA3WzzGE*zbAp2DF3WJ{cA(h0!e1d z%RM+-Ib^;}7`SL`(#d7mfET&ZEAJI=9pIqNq}d+@nI+Icu=eR&Fl{&p$PCon|gj&a(6{`||m`HXh}s`$cqSQ^G=^+k4BF!Dj-k!vhxTcfNxa0kWs)kQ+M0d`bzCS_uV4d%rzY z8RTSPNq|CU%EvgxgP(roQ;O5GX;@~KC zY^d9fmO0~>T84zs48T{4CWGWoO>x#oL1bD}#Da*`tlYwwvgUac(hqPi1^?itJE%5T z9ae0gsF1+`9Hrc0Hc0+ipw@eXXYSvC;^<+3xW4^N@^#k6rm+s-p44V0DBpF> zZfMAiK0!5fk?SS8^R7~f%{?~~SJPNH7$jbMaLdDs(&`J;s!V%&J{X%CQl!5#TkmQR z0%;E|dF1_2dZXKPHa$}%BWO34HJjRNc?L>na?Qu?y+ws$(<#8A0!NN>D$rO7B;pJ3 zA0!zdJP0K^@KibW2|AS(FjW50wepKxcpO*vofNSdtKEgw#*-9Xf~V7^WMxy6lUQkZ zyT&@sblzZk%>XUMzP|pCUbS@N!Km{9Icac5@ew3VQ1&xx)H;YzDTdR~koe6YAWFq6 zCiX`i;Y2~_LTTqWpprE$`zA11*m2Og!x`kb_tr0WaYd4|`>uR({^B(GV={^LV=FQ; z{i<@9!PWuSrau4}0d9R$72xoKOMF$zqTcD({O-b@Ay#F~C(!P&Pxu7I8zk?Fh!1=a z^(m!OmYf^-#Bf;N^8>zR88oT2+@O)01Zg@i*YmAbKHuP=0S$DJO{NPi+W1dg{q=TS z-ji2U7v^Vmgo}C22Pba|_G12R=#3G%F8f?IqXkNe2pbYH4TsKebuj-z{FoJ_?Cdxe z$sR>hL*hz++(YahWSAddCaQN|9?qo(0}FpR>84MEmZY28r`SEnP#&ylpM?T(pH!9Y zHZ*FSV7%q&ibY-7vhV3P1 zJ#*?WBV&FRXsEoH+Vy0%oq>*S`fL0nKndjFiuO2x^JHY&Z=^z?k+|xeKrFHI2x%Yf_JdZmEv9Xq*@W;00c0n`erMC=i2ka|GMjcK^yU4kJB{26$C z#Kpxs4U*{$K~8II1Bipwg%epsNYDCu5=gy6^kp4!*YJB@tLSdAy+`0;FbB2B0q|xF zNb~#PO#Onc5Uz!)%0#Ais{_qbghUUlk%MN}I&0W06b z6Q(mX^rLFu0{$Oj+MKSbj(}CrpAgW6IdWwW8c-24n4?3ge*~Q9kknP;2RflHG$@}C z!tsR7ufP~uLqO7heGEz?z|(pT>J=I>Y|{lTM`EMv;6EUUsO&-=OODWNykqrjAaKKg zA?BG(E#zVgrA!!q;M)W7IE?Bi@U!8eo-Zgh|K<2%uZ0h&8)&G3MU*Y&G3@vTXQIw! zz!T1^MMXS-!X3xKg+s`=e*fr}6gq&-9g;EA9IA~yC|pC~gO!RU@*DKx!{1K>v+3UP z@QnN6SGAy{YC!YPAeq*)u*+)$kriq`VBkaA?xppZ|NLP!CZQi@6wwi_tzjM+fCR4! zV-RU3KvcI34GjVJjhd~>sg4b25KS#Vl>n?{pT3w`JzGSh8I$_#*#`%Et_TLY4Kzji zndvMpRPZvjSB-FmpzB(C0u{4eWcMnfHL?d3#Pe${X?36=2GWbq`-Ut}J{1PE1>uON zs%_E3>sN&PRD2TFQAqK*0o6=axu|Q4XsPY{NAh1XPHB`KS+2lbCjM7*Kdf`kLWgdx zw@N>5*!Zcm#6E5qI*+KQC#AmXdN` zQ5<1nE%mY7>Jqcg2`I7vvIuLP%fUv(3%q6RWx%$B{QXfq(1*s@Be=-W!&`(vr|{Fg z1=jPVV;{yaF)%cLtXx25uH>YGtX%gV;-+7eCAnqT0)rx4tk0YJE*0MZR+()^{I;Mb0K_I5R6LDQ zy3D4*D+T4$`r{EzcrfLv4vD4c-`{u`ECgnA`GV~4cMU<#QTh;~%KQLVvl z@$%)%iBw4()NO0QcCrPBIn=|^9fyoz|SJ(q17kVl2YUJP+$W>ND_$h|6ly8#kkJYq}A#2sLUc&EkUA5aF^O-GhD$?D+AjJkqA;`+6^Xd?G zRUw@vt$IlMngAAL{S1ufyvsZUgGevR^rca3Iy_ulGH#QAPT@&%l!PkA%Habb<-lQf zH=jTen$YQhAS`n={1EvdL4~$ zL}H?1gA7zzqTxIM+J-&X zNsB?j)az(s52rsAauPv1vx6Pi^Uc4mjt8r}`FOmc74)Sl)JymLa21hnWI#}30o2rH zuf%}QDHw@lKH#zfDEIJaf)83Ptqnte-Z6nEmD_23j2f-LzQG3CEQfzy2TIZ)!vavY z{TOPFCJ|VgIqshyionigug_{!kPhh)phDOJl%$_eKyReeq)~qmAt?WE_rXiE7uk1& zKC4%KOVRo39zP8LY<=hX;+FTO9%|leyh8;kpQnMpUJN21esE~b$jC5V`1{?mS_Q-~f;Aqj0j1msnMCczfi!}GgJ;OOfj8oRC}D43 z&{>;g`DZC@gt|T6d&H_2wwUm=OGh|%6f0g{2|_yJ!V@K%Jct4uIu+Y?YXse8nLx-l zm6K@7Xv&o<<~K>X)1RP@?vKieLtS?i(Cv)~XsrpL^{Ghsmy2LQf6aCCG1yzG_@s`%`aK;X?|d?I4A z;{~3vhTrNz141>FU=PwCJD%qNijOf>LeG{)oB^1SiD<#@1xr%+1vG@U5QkbAI7q!f zo7FUUoa^?067?@g2*Jh{au$H3ofm{z5Hy zP6&j$Sn!&8&7xLkIRJl;jxsg=-oOf3I*JX1{v(g-(1X-KJrs^x+pSwZIP5-1)*|*?z)B8y?zh>&L;}#H>FhlaIlm(%wFSr> z$lMsAmJHbu9zGL9E06|ip&*O59PY`CU4#`U`?w0RsPRMH_bYu2atA~%@)`780AZ%j zcN@_{kl6)&l3A%>w|+g;h7eh9ZY2j<)l*+^Raub;7Bf=A-J4#+UXnZ-6udwyIj~WO z!?$q9Bsx2b9rzg&u7L?H8%Pk13|$l;(w*mgh3u=3ngPfjR`8@-Vj-tl4P)2SrOTtQ zidBA4S;9uu)e=z!!+lp1m0e$`@aonqFZ*8x&(GA*EnXsU_RA^!~c^i@q*h zQ_!9LX6+`a%nMS`(c>^>Bwqm2DFY4V%uGg^3sh7h&^eTIM`pd-7+Y7qV=wu_cmV<9 zCU%&U_x$r#!Lj_DDLrUSoG2hL0^}~ZsYxp4H;C&~v?<4A{}YpL3q8W5Q;0fR+TIfN z-&LzeFzHO9lkqlF0|z>|x*)ei5&i^{jx15p0dQ;Eya2DnJUc=PFwl5%1vqIF=<lzxs z=%uiz9@vpekcx}9La!$_crSA`cj%d?-gsm71EE2#AY&>rWT%JoCQwNWr$9RwL7(A^ zZ|qihf4AGSwuWhYlU@Zc1A4BCcDR9cm*HU8`NUk4K$*vFYHGCnp{dF@cD}b3?w1g~ zQq>E`*i0mGS%jTm-ITP*P~6FThItVK(1I;^sf_CDe-)Lu@?w*2U${T&1SkVDI#i;Fy;r3WLu2ttAYwxE1kkWEPck;XUjIn(5~xdl zEyK`Q79IFIHZu*@nXmgT>Iv?VuqtQ#0hec9{1*J-Q#^3G?7kVl9n{f!ZtYsa`b-=M zvMjN!D~>i(@Mf10YT=lPf6T$OKbw_yI>V}}jTq$-actYPF)A`yAj5YS}%+&^eC z@v|c|*^CbN2u-dHEt29N^odArsxt3}ZkvQ>E-&uNK(4Nsrx&eN?d8qq0>I#l}-M)2s&HpO|^ZwP9eZ}&X4NCA@_EHL&rBO0~rX7jn`&@NC{gCA=U zJO&)s`Hk#m1lpT%4^8b!)!Cn5#2p}<)&t>g{SbLi?r>`_${<88ZlJ=%_rnYqvb#k^ zWzvQpPam5sx>N6VE~27l#S&gXB(*;hi4j?2BoZ47d$Lmm(!R0vv`7kh z%x7horGZ#3f(s|RH>cg+m7m{W;Ra+)aRwUKt{Z(VuKLQ?0Q{<}R$ri_mo1^I(o{V< z-m>rCq2Ubh-^RnPKLUqw0UTz#BJJd9$-f$B{RI}LDZS~wxkS&MEP16evxmxD&{+S> z%+b{~ERl@`q+fdKPH{<7r3WJfADQ&l8$`~IQGCQP#eFkO9nEz6^khA4WiZRj$y5JLg0BTmivB}Tp1jiVBI8x=0ZfNM{ zFGHgJt+)}~xC~T!*j#VcK$JFDka7D9620^L;e!(>XaXpr-J4(6inuRr)ZH_*|{Ga!ld-JlEy8l=$Y(Il8u zZX>0I(*sJitt}dm<1dfbrcA?O!@&3gtF|ig9tV`$Gqbc2Sjtan=;4OVHe3tC0L*jp zF0R=&tU(cH({9|w@qiLMDioUb{uv4npd;@=i(538@okS+daYekC0T`>K(0Ec0K8Gz zZH0Kj3#6n>zb_q`L;lyeaPIUUT)6BHF8s0131{M|*8^^7On%mGB#_x8v_17YWjc_5 zBp<*^MsPwpd%r4xr`j{?$;CuC)x3;s;(lKk&M-b2m1jTAV`nMXR^2n>8sm@{PodWuD0?F;RkV0q4lKCM9oAUUi| zt?GsLxpWK+yKq_=9=sT%bwn`%sUhpvxNW$um0%eL;ck$B>8 zO0J_+?dgwt^M>|;29`Dkh)$fw!wUdHnx0PgIYfrEO@%!5%iUB7{1&-K3V-bd3s<9@ z<3Y87Sy#%te9?#J9Fp=+O69p=y9snG4a&IVoO zFpMG(CY}Pnsy}L}a`$Vd@_m5dAuKxQtPBgnGnD@IeE1>9TFYw-G&5=gxJ(Zavufx@tNsH!%6ToKgyuv&|A2S;$|93kf8w-aA&7 zZjrd?cGTQW_d@VKB_lMO|z`V1l6A~2PPK~c`RhcF8*m1AO=AIO1(O+Ey^6weFO(q&}GVz zdE9!RH}N=;_vU|@@m)+w0dj;TdCyG~>8CmOS{}7#e#yf_rD|1^lroPSx1pNDB9g5P zttD4mk1>$wzX8E{;s_Aj;`$nZU?CSTu<2$U}EOOmEJtPyb#aPRai#w6rb*`o`f8*)Kv+m09T1RZoyluNqHGV~1>pgCifP2>{_Oi-;l|=z}IxHC&;u2$>ElXWvv#1WKS` zggE(GvK7SJB3Uf|V?pmGzTvpU)Qvr?r87sBL^s@kITm&;UK`X?b)N6v=I28!(xa4&NE|24+IA1NK%Vj zMDRcRA`~9;nB(42=@1J;|KPYR?!*6z-+c)U1_i3@N0A1O@kjy;;QR;$Dr-LB0v}$KYF%!TP=Vk7Dq-99ILFxts*Hboqs}FsER~>T| z0PRD0)WX<72qmh3?Jw#ph~KTaRlqI(TsIqLdIb|1Vz`V@BmckL#BmAvl82jvgX3@i&U^gtLPG4Su6D-knhFLM#)gjUDozHD$oJCL`liP0 z8s(4xC^56^nsQ*2F@hN$%KkF?%3+=ivSB zM*L2;*afeu!_J$ZjC%Th?Wm_#_H@L}$;y)kw+MSVCyq$J+`8Uw{L`9kn?RslsF7do z>>@iQ&f=>J0`fK4txNM6g?D+#yuVF%6WD!p|8*zw*Z$Raktf~7lDb8(>M;s&Vlkyj zdoN!+wU>|SFH}B8fI%@ndz0W!t!<>9c4ZV#M_d`$gVxc>I-{__l(*pCERgT-mR&!a!X!fGi^lML(qdt+{?nCu3A;d}w2M`4<(g;uq=w8*b1SoFf0KbOO&#N9dv_M^`cDS_Na%n|CdDzmm)R=+rtH6_fCK`5WG2dKOWG*o#+b zX~KQ{a?uKN1_YmtoT9ziYuQLkm1`2DNt0sw^)#oU|Mbd*l$xy0eD>V2!Y{79J7)=_ zB}DM}!W;4RcapW)Hi?~#J8dk!^z#XhHv_@}+Co$2 zdKto&t7{jX=6v?(w5Cn>KT2rQ1mtiO$$Q{jO~rGs>@=`#*pBa!6u)aeSIADX#%1Kv zavd3s)MB&9WhdOf z7j;++TrfbRq*_Qnfkm3wEA#kw>8DZ^af)+~mVPQ-to0wt<;_d7X5D6Oxp=;aNi+NO zgzi^;^n!*0nd)%`A=gIn$qwn3-n1o6Cz;zpH(3F40)q9KG$$_fK~Q zTBVc-M(Bt36e`og2dTM-*kLjUIr-@yob71O57mkt?dco%|i#p}mUvJ3y zXLN{%Q}851-+ver$xquh!Hp};)WxUg6?WE__AD4R6K z@>(u?4Dn{*VQz|KWavW~PMfOSIqDg7Li)W=&c(q-m4nG40l$}dd~N)3pMVLVwHxbW z;%t#Z3w1KfuJ0TbtM9@_zQ0>>T_ZkR{6+Vs7s2as8?ozf1kp2c=h z*XTS|oS^dV$yC&d8U;$Msf6oIc27yj<94XoNAt2ihk3M=_tc-h_hct36wCC{srgX+ zp!}+gh-dDxLy~6{gq?2ppNqWAWps`_(-I4t2i=(R((u)CZ`Nw`-<$VR(L^u>gJKei z)H$MD)x_l3Pa1ps;?5+c`$S9del=DKoGzdYddNyot?Zcd+%TeZEUZI;GTl>>u;4Pi zpDea}F4~(>Z2zY>=HL6QEu&j~4(8%ANXiI(&Emc*LJQ0~QC3!mty}mSuRb(Pti5BbG<=*} zTX-`w|I~@N9C6ZY&1X_ci$;nHr(JYzCWp3FrPjxnaW#8uuIv}ZL=_xmO8 zKNj|#158hO)pF_jDJDloJ4O)P}3^|UeTLGSCfUtF3OFqjWt!$riWjCBG}iE zy_@}$<#4y7?Q+yxdGe&udhtF{JJLeJ*NsZ%Ngj)N_F^)1^m1AqBNu%F&R!(S!A?3K zeJ2d(%(_rlsyRkY^XVyHr9|4^T9H1CJ0BFU$V;;1kp12j5}7K(rd}m;_+f6;DWZIF zT|#I*&63b(T5NG`;jPZ#NoDK&t+*ehEv4@+#IKPi|NefL-8JV~S9+8Ous-N^SmcIL=wshs${!a7Ui%)o8zCBSaAn$t^(Ve7GUM}H$>tX!6 zK!RE&&HY@>lI>xUn{H8cjW>eoT0Ajl_1{{psFE!e>dG^JTU(9kZ=96UVV+Po=_%{C z<}1OXnNuSfWFqtOJ;QKeVdcj)tIPG7k?W@#PRLOF9&K$dQ@kQk)_PDD=9hawAB3-J8y%+2@bEdKY!06B;M_XiT$U~+!E%3X~w0@ZKd+^+DhL9=|c z*`b4mDU4OYYp(PLJ5=`2Q@X;$%5tyYrbN20+D#~waegu*IPAvwa^FlV8YW|h{&FYd zEzvUq#zF*oqBfpx{ClM}H%0WkzTdD&84qqNV8Kru>adz~;AT?z&~6*6u+;z5{i}7z z_2T-f%R>SsE5>G2)`aBe!zH=R@*MGM$0NsmO>Jng??122IBO@kSLrHfHIf)uD1@;@ z?H9DW9PoU~gpx!^sHCt}>fV<*r4UOuVN-R?{MD8lh1^ApixqoAuH{WovL z^xuu5T0hx7O}BgMk!!`hLIqCdMrU@H9a{Pi64`-K+D_lxvKe)ki5{M87S_I(tAzf5 z<135*C&6yCLyq~y^&2!lSLgdLb2e7pvR4_4qZ)2{CGo(Czv|YFxGqA94{f$VgRF#Z zEm9_hW^L+%KF-ZE2E?h;S_c`kEdK8^F`klKeJ(sqQnjMx-V|i{YK9|a{MFWvnqZ-@ zhM(yt#>1~W@C=V-zNcVzf1J9FuOR<|)-t!5bJ5|Fv+F5WrcLy>H-C&>_nhFv32H0e z7JDJUdHd(+l^D&z4>lE{mfut`3u%N>Cq*N!1`ve$t@v!I#bc=U;vAeX_O2*sA#dBc z7MG<&ezQfN(1sb^1SjV8(^I#ZPY++X7@HSmP-s}3&NjI4(S@*J;}tG*fpTH1RWoJv zn-ik?r!cI<6^*)FiVE4PHJv-~Uy;h=ic_982?#&gaLOpj{p4Vi3+1V4@`_aEwl)ds z`jBhXJWiEkr)N))ldPQ1(RXBWU-SF0mD?$^q_V!sr>U_gM|jqg{j;l$2##f<*emNt zr-XmCJRdSH{TNuyH?u8NRS;+9qI)g4A*7@4ti;VdzO6D=d94(wkrUGGU3Dx&sdsvD zOCrnPnO{x|yqbG0R6=2fC)crQ^v#aR>UmdsXDgS}+tKnMlvmst=xwJrTJ2$fSNwrV zj99zqWLi@@jruLUlP=sFdEH&1ToJ7&Ewwb-?dChX+>DT$OE7FE#&-x%b_> zB*K>Z1SzjWafVh4cj->1(`j+H4<1C^%1{fah>f%rXP5glRe#iiQtI=P zMvU|Do}n6>RCh&zmBLIy+G)oH8paYD4Q6zbkGJQ)yXK9qb4_u2_b5;W_U%#PAF7p= z|G*^Syffg5?|`9F_BlR#x167v1jkak+l@co>RPO`!7mXXWzK7?`u1T#JJUJ8WG;le z$-n!WNdJ!EC7;luM^rGae$FOZxX4fS1jCze-5I;jCL3os%oqz!KUbT0?SI!|f~@k^ zbM4ql>Vp&ZBfoC`#|8UOIfRp&@9!%%|9?2XA!+4*w_-0s3OUJ#S23%xRbHJ*yMcf4 z1bsqtatSuZdj4GQcjEfu>R)MIRbh0Wh`v}U`cc)7zr*zVH9r(R^91~-*uI=>PP0!x>vQ!ql z)GxkMv2Hw^#eP6t*Pa&Keow4O^p~S5m6N2d65jWf$X~vgqdd4b9ySIGkJ;@RZn_Ou zROJ_1J>DcwacZgWH*YYnc|qqSk$n+g$8)YGnJOXQ_aytW&~p94^4dxxohgx`7T@&; z=?ZbtQ;dKYgS0wt$z#m-SC?M+a_=34F&p$NE~my;oMuS1y1`{Q8dK zlep=I>&eQO6E?By)wE;Xj3vL{NKS7e<(8vJx#BlV^knt&t2@7m@Y8MAzxFtOcfVRV zn9ALIds3&j@=4?4mqK03SjKECaYX(m?}@vmE&AU?Fl9vMXvr_|-dMkNnK6;;N1AQC zmKT#u6WQ-;_R9?gn3AXFtX~!@&8!I-xyomjKGD_j;O@AKcA(=%Tv=#i814ENQ%LNl ziP_kX_|74%Npx3kcKUhJWWuJhZOtjoo;EN3%%OY<;SMZQmG7_XWxVrV#BRSXuNt{V zw5^%vXeVp_-9vugZ~G%HmC#v*cjcERH-rQr~o4ql+LzTOF>6gtl{0b#}?XQ?kZ=QPTNz!VScz#@ujoX-@ zB_`I0&?{gs<{66Zh_UoUt9y1W@q3KX-OaKYou*;Ao( zKr2;X$oOf1gSESgD;Oa*>ZTYzQzK*lQsz3Ed?VkKIfcbj3rjYhajT}JETXuF4;b!M z2t~GQHHWKniSm9FJiKbOw}VkwJ@z6eGmf6vIsk8hD-wO9~a0!#WYSX&cD^z_&NT+3nV|1^Zs`WWE)arlfbJ$ zjCD1Xnchfr`*ohx{hdaF`B(gj&TCmC?r{-slY?JNmy*ry zl|FK9q@Q|Z+1hBS<4$NX+uK0GeOWN>;k*8)Ulj{f3j_{LJl$q)+M>q^R5^O@Z|8mg zQU1uQkZl=vxROJV+@C*4|AgPCR{;-;m%G6Pk8k;iSkSaPeai}>JUM@o;7zLCl`b_utn%8t*~G}C&_dGAk5N`P$dd1f zc+PQXaA)vhvh~Mxe?aHwN2?rdBoKCM!uVM#oEao|?e}io*5#M{E;$r)>^CzFpJs?W zTz*Qs5VbBmO1VwNf?g`9>q{W@88`5C7+>la(gRp zimd8cb+4b5#N2iBp~UvE=cRH{;(e^!W?+XCjYpK-Hoz7%rR}+}foXd3>I22%>$N9? z@k=;J$?Y&mzfuZ*?Wa{5Ppedk;;q2?#gep*f1_r|Z}jsgk?~w%8g1&_YDV)*C!B8H z8@SClZS}h6m$fSekDZnCplC_dqjbNOwv-pvab_`U$$?UocfIXS(s*gozrUUNxtZjN zC06*BlGO9=XEmHN_g~ZW8abqTcjKBSUv(MRad$mDl`8p-M!YvFPTT;Gm%?%8!)!s= zz1gm^He=~M?SYN24Ag8nV|6cW9ug5aEvcO%t2o{KiGpO<@Kk0@vSQc@tuoWR_L^~r zRpOdgg(TxAUrF*7W#jM3`HOw4H_9`#Lh^a)1q+MRNWP7|XnQ-Gs*?WrVQ`_*_W zEzFmyZkBRjlcx?P-HqZZQI-AR!LT$;NBA)@^sC>2Z^5&Wk87G16`pZc$+N`75iP&< zB3P>#yAO0aC*IZX6sTqqip#d%&!x8^jRW~teuu=3iJffzI90MrMfxj6vkx`e3|P;LI;|Ecco2TmbBP%_^Gx|p zelm6No{~YhW1Mhk-%P{Cf=c!Hw71RL+e=Du1S`qKyw+aU*9T)ei^>~tW=yC1rxvh8 z1jL5KD7%dn^)OCK=LM-TQi$XQmnx za8)PJA5D!DKZ<&;Gp}!{6Q!H{@!qiI|(PIL<1D z%1`&nr$s!hOF$!~Nx7=^#I7qT_r%$oA3X5&HD$3vdv3Fy6`{R#KTq}y$4Sl;jQQRC zSVTV@-#&@<_2 z-URLhw7aV$BM~xVS`BDRPz`Bx>uIQIvrYfN81%$jUVCm+biY|p4|P9;uD`(Ou}r8bl0>NUCwM#WY6^0V|^V zLC`r(<>OJ)8DPycuWrK1bbK>=cZpL~CUoC;zwSWfix7WiD<*F8y&&wmN0%b{;E-H< z9U7C$;96FUI*)1__3Xmh$y$zOkXT1se=XG%+eh2k_}kfxU+`t^4!^;wI*3BUAV;1h z`My{__SFz|?+T7@oSj1cj_hWft&M2)XbuZy1#Yy)6KdiR*Vi?fT{nWUvDE%3Zd?rS ze<)Kxz_Yd%M#?DWKgqt#rwvqMPb`)5-mbojL0?GuN&O~ouk#()t@Tlu@Ho+bjF`V{ zEAH3-kVf2p)!hDJW^q5rrT;Bp5>(}_=2;)AYXiLK?^{e|3{ka?aA$RXjEL>Lve6c; zrEWMsa^tAv*5TrHer~lh=#|aAh9T)Eyh4D^N`cp-o}~gmNiIv{4j~aT_*wR5Bt41r zvEX-m)Gf8Zy!dKbPre-MqR2CL0bQ-IOWn<}l_lNU?)0tK-Rxgp9wd@+nqe-#Y`}fj z@^cUY#Znym9f{=k4<4w&)bo1Vaj&-T1J$z)pRuJO1v8r}h1L`zwMOWcSH9(ldppgs zDxh~3f)LEJrjL*I0we8=BzMAZ*M4KdIe^C`C%{X<@FJwdbj$g}^|=eAnz!0_+IXnK zg|e!-=$GBa0CtUO%-FlM_p%j)zZlnstjl#0Vx0-+y$GK@$Fa=6BU*8FS=}c#Pmg4n zM-))1MCNL-NpNPj<+o%gayPS1<(7s&8;SDS;6l{2ojVU9<|s4dj~SV>K(3~7s*|m% z2&zHd{VDtFS!23kTYM~z!;|cbS*v+y_Exzp@M?+0yy+)PuMZSt)WbEJG|B&*RUmF(kCeg3-_ zuqTVB^N0U&lKiEVIXGWG{Qgf={i`bS-*g$UbFlr@Wx&qG_J8U!;CW!3|7Dkfij*ia zi>kbllNA{o&u?b>?>z=z!wu9XZ|)_;F=XVZpLO2iIK4qY$DZIAf04Mp;SRio234>} z^ELGui4neM^#J&L`fI_(Xj9L=&)Grb`WON`M`>So*IzLVUxBWDf}W=h4lE9*69f?i zLBRS)cr2HTRnwkR8&y+Pm+2mf)Iy`8h~xq2fBy3UY^_DA<-AW0J?s3$#n0_h-NZ-7 zwsH@fFPQvj&8NJGmw&7ACd&4Z5#=34+p^@B?^nZ z{cD^cXm;%vD^r#gJ(!ODK z-+&8tv+77`FPV(0xLtUGC;WWa0L$mfxTm@3CxTmTxMGy1-GJWWM#h#7RD zA!#+Pd!CoxV=++wYdm-s>fQY6EukQdLc`~j(V}y;Uw4(??84Kw%69fm8xmWmo?A8> zOr3WnF(ok_lB5~(^ICTpe(CK!EcLY(y?L{KJ0AgS(-TuEwp7oz*pr=ZdliqcY!d8N zbGsvZTq;j|X=fLWJaZJ_7m%7%#O<=a9K8s_PV#LqD*CabYEpf*+h-u7Bq-3BcTjML zrdi`C+E(iqwUjig?J>Ri!hpoGB%yVLuF-|gjZ0OdbrGlLQ|pj758J5c8idAmJ#W(V z>NG!{=gi%4f6;tSH+A&942zU7#dOd5*$3h%g~Ec!1FTsX^_|hhaZa}vamGtm56KbX zTuzWlan;>O*{F-il6N*r<9RsCIT7D{Ben3Zhy+#%6x2*`uJ5bnSm-iajeq{QrdMC@ z7gpPF>Jr1N&aff>^eSg%G){R5*mj0A*Q?2!vHg~r6hQ|PkOK)Zs>fh5$(f!^hz3~l z?N>torWlloSgys>lc^9klOp(dfBrcGy5bM3#Gu1>t~3+p%+D5PmU=`bU`_`6;czFz zv+wmjXKtdcG1*Rom71r%2QXv=>+#K4o~}Q}FH^$xe(P0MblQClJ!1IDo^ce+cIN*) z_P$wtyiYVcc`DPZo(hDMJ!24iUy2m{mUI-&q%#7;XDhPOg-Zl>MsN3NH$LbcZBEyh zG?LT2(apP&rO|_cZc+$c?Am zl}fRo)$;4uY=o7JP%P4R86GbDnfX$WOwR;l>@Hl*4bWE6rjn05L()`r?DjXIS zzIjXi%x|NHj-lNV1NR8v z+tyubvV1Vd;)j^@*?(@;JCs#)GTpC#r`o@QYC^0WGe;lv3Duob0J<>yiguJLwO@wL*JMYl&QSVcTQ6Y1#Wp!)q(L_ z^)JPa_5x#C28?N)#MV+is0|`)xe4Vbd?f6&F=p%X>IoyXwjLrGX`O)Z5g(334X&BB zC?nqOQ;|Wy3{(Cylx9Xy&Xe(oulG;+XH6;$-5k#v^V3p0CpL!LC*bT1@*QBA7W`XF zDUzclVs?(kvcG2Y_UHPI8SgpQvJ^h(-n6|k(%urj4duHK1BusR8CMhw+{h`^2;SV5 z2=ov@ScY~VD|#7iWD83#`)b8plBdT)D-yw8Y^IA}gz8bkxAzCqrCjUSIf-7`4TbyR zvWBnduUl<7n)F7*Z+FdZjpe!-Ig0O0boyCmCT)}n+%O2@1bJfx&m@x2gt8KJ#ZnHBZ8UKSJqTc(! z*k&Mp*%rk1lg!}?PC@V0hMmSm&7$`G<|4SblmzJ&(3!Be+4~i z{FLpVryC|G{RZ@Asossr{mLskop;{zXbLf0>%Lm8^s1G2Y4s|MY=9ABl~psw9w+=! zKZa)0il=Vd3~LM_l`z`2fxJ%D<6@8Y+`9>l4(*YVznq)k-M|l&?sibi;>2NRMrojJ zzd=4Q|0eN3<=?k|iN(`Qo;I=x?cb6;p?stw#@8pq@iRD$4{F~)pzYM1!4ErN;Y4aX zJs{$zFLOH~Xu<DX^u zah9E+v+jSTUSBD)fLnWLNuzoH#zsbk-OMGdg#W$aL8ETQG}DO{-Th6eSoBi}setQ` ztr}Uv$Dhy-x+!BV2^EM{U>&L)eHOx^-w88yD+z?qj8)@_Hx$8s8Irdc6qAS>m;)9{ zBGz=ERbnW|Y&3d-BwdoBq(8E;7zFERIeOGLK$=su0gj#VIb+CkU_F1~f32rv!Sg>? z48qMosK|tdx*d=Ixl2ES=kyON?h>^|T~dk{V)RibkACy}r3CxF^00X*VPD2IIw<;b z?dX{Qz9abBrJ7VUq_zDc?_Zol`f0~@a7A`{$XrY2n(%O4y&LECd_}OC(9uv;#|=!m z)ja&I^f#mLfxrx4HW;%R_*K8IW+h?^+${tz|7H7>d$*Yk)J^QW!2Fv0Q&7Biy%!r? zhBK!_Uq(z&M7;JjfDl05o)F7M6cClpP!tOJLGc77%xl^Yls^x4R5Dga^y@G>IVwIt zC7*M>zLN@vPVy}Y*7jRThYg{j;oK%Px77&iC&vh(Yi6X4F6B^QiGItyI?eWN7*%WH zFHwdgA^(oH9xawnl4SNa`X_p(B$7^Le)lGr4pBge*LTY4?nv)>S7SQ|3y>P`mxnI# zkga?-KfdiBN=Bd}56Cx+Q#Vt8n+x*HnTppMb)C4^w=PXP z%0!#{dcBS@4#sxgDBH(@owGk>niK{N>5X=7UC4wiu{qb{IGx;8k{u{IxKJMVko%C` z%cXu3lSM`nvsr?F$!0mSSb~Ai=UaxT0{_^gt) zWE{5WjRonQd?MKHpO|@Scm@8?}&O9P9#w?C2p%pLbcxQG;f;ZWu zYdUC9Uokhw#3t;V?NWSaTaky5E{tDZg?$4CN$T492<(JT%Fcy^qo*hs z?(1Mg^5Cy?t=Td=!1?6<`Vob;sC}*bYIq=>%EBDg$A0M}}dHe=~wK_e|Q!gs?}QZI3S`rRLmY}@bW!Mw9^L1I zQivbs-%68)gx&(=Gxxuz2Wq90s!Dncax3&sIrXb%fVX(wPv`%55^2gEd1c^?!4 zY4gYB!kmvSDtX7Px1%A;hN85g=)*t&R|Sp{IPb?Oz@i`jz9>8vy7l*b#KjcdMWTe5 zo3Z#o@wON*8Uh1iJlmvUbFMc0n!2X)B%4ksNaQ3^*FzxdwwTp16auXjA?~=p59Q&T zLgjlO)6t6H<6%66S)Ri<_P^zt%kcKiPNFpOmtVIbbD=+^7Y^a!O>3_#q=7cc3yw7LaFaW)QAw(1BAL&YG|Lni3TIpXZD@r=0Wj2}+&UlGe zbiEs;x^n2ouM6c60Lh;(gp*&D!jsO=FbnbOH>dJB9!nhwhsm|hTZDbiQ;Zy4EMfpr zi(DLUr`P6P3Kv63lVZwCzO7y548ok4-2aqB>Q-iwWn-#FSN(o1Ot$Gq^R*vE{X}Db zW(i+(K-kud6-h16&RldxC8I-CnVCQ(bA!9`(tpS|{pQ?a-)4r&c7ti{_*2?+v1zOz z?SGRy&R#W1+VPmB-XyL&rbWH+2&gg@3V@J_2Bx<<43Llax3b3rTer`N*sgzTk4bTL zE7x54Xr;T6l_`R8lNJUfKpxs^Q;>^f_9R+D+OP2pwv#?v`h0LT!2ftgM>%9d)`p+_ zmnK@<)j#_ze8MYvdJm|Nx7mHGIYMcCgh*3s6Ub8kDV!`xadU&PYiqmjgY)Y4J6 zl2G1$P`pix`Z#*NTocve4<|pF^`5C*_5xSdc@!d2pG2)% zKj=DN#C1zm61A(`2@nm8)QOC{E7ya{2tc+j~+UI9syPK7&!|)QU3@kQEql_Z4gb zv{zlLGk^)al|Q}=Bs3tVuX2KEG9PSOh6ca|Qs{_7iVQhVY#h!a?OaaPy_8`c{`K^r zjZuT0f^tA|Q@sf9UK;eMA-OB*+qoG}Fl-8bO2Bd@$$ZUE)rl;z#Db!NHDEw|x3*!% zZhlV6H*b0M{YCg;6Q0=S;Eun`RnMq@CA$~N%)-zgmy@aMbh!60>a}r)ztv+C-(~_1 zkp5BQv;gTH2I-T>e2r6m)FLq4!SL4G_qBB<50o_EpOm!sS3n0Ex6Ad4BRk^1IH_pF z9Jgyn&b=;5m-)Uvlqq?dD3Oe^nCIIa(#}))erhT@>={7Tpb8N=@+WAvUbkOw#@^&X zk;s{U12#a107QR+wSeb`d|LP9A12J-cFh0wEe3ul@gi2Do1{|h5UIsURq6toPrF)c zw|zZ)#&oFnT*z%dGiCV7iPGWwhdMn?v9DR{liHcC%Z0*^WinUYfg|3K5Kmg&cyTUHaMmj>7 z?c(;HL6!uFZp_{4j(~S-{s7r=rd(T>IPM&}6{CMVoi5SuXs2|sj+vfd7T%*VV3%B(aaoSsM;G$7}D{Dz24NRRrL@DOLH9cKL zxrq>~6c!u&|GD)IhyKdX>B|`HNa1*Wqe03A#yFe{)5Lm(_bbD&Jh!ulR#7{QS|8a;$cY)B(2l-Me4;IN>{kZ7epb zPZFc+Bn>}&nCO$#2%ehCZ*kjHHLmgFiYCG3s2J>A*6x5hr=k+~ys~Ly zNOLgLbL0M}80Ls@jUHZeC%~F@n*S4PzNO7oo<9X>bJ0Nk1f!b--T^|oY?VMhqNh>f z(Ait=_2`Co3x%j%Q1^zE9Br7rwPX}Y0O&I|W??3$#4{B(?c4TdHSvHQcvW?Ptk-B7y>-Zh`7Jz$7)&8P*E}J(E((J>pwOe= zM}TIhKCzJuWlZaoqq~H>s@EVUaVvbmhG(Lp!SeHY`?nI3ws8%g>&Y@V_2D&U#-{4` zZjvzVaHV!^unEW zS(6zb$(=^Ihz*0RokshE2|USd$K;@NpG&s4t~?zSYFaf&9tHRpiac}2?JIogv-iiN zvq$O6lW%Ox1`e{*zVV;ld&v(P!rIJ7CL`BdziGo7ad&%`8u+T?@8^mvdzV5oEc;uJ z*Q9h4gs-ia+O>-Ub|s8f=J3{CgUtP?^*tN!9LG*@wP22_n2INWUZ76s0*=*B~+SZ(E*omw+}-+mb}>&C8n|HVTJ zOa0WDpOA3&0e+~J-2;RBd)f0fM{Htw1SIA7$mm zWONCumoa?670MEtAZeDpJ}kMI#h1`_YmVXN{LJDdeI}jSZ2*B5*1`KI39L%*PA<~0SA4^&MwX6U+TSJ57?&q1f z4-Jrt4X9R4RgnkuVjT7qv}}FTiLT(ESd0KVDrhON;Q49C>Cy>j-RQE}ijM_m3fa@fPm1|C z!5T*KbKyu3SujiV?cRt=!{Ys>clZ*6-?Bfsyp0#Zr(x^9y#UMLsAbld02fezHBRya z)+q-%V}QBijS|rT5qG918?#N%ftvo^Dq4H-W#LHQZn*G!eWj&0DO@>k%q}TQ$TC{b{13{-D3pb&pjnRwOGvWISRk-`TSIWxPMVk`Sw z^!XKZthzwj4Qh0LadAX2egT|>Ge!;4WM)8fG&^|!n&T^9aW?cW@K*qNXAa)$%GW-& zGRw=qbs(;g{eyLcs*iW`@~5bKRZ)^l2@s=v6>*ups!~nb&?DOLC3J3W8_FOI zleiHJ)`^{VqbA=4-X_i3UGZW=Ng~%pn(#5Ok6^h`-?!n`YRu-Vmppx~S@~0TE=#|u zu3B0wI%~HyOfoaXO4xiV{D*fuY;G`ZOv)$*~jmv8WW6IX2ZL|?0w%% zfsISUfMaQRAw%gu>dVM1`EdB3`%~%#8&BOHTaijnIRWXao#dSIJ$mAVi6 z-sZb!NOE<0J7|o{DpmJFeq)%GKaxoD)&ac!kMp6s*TlQ*_+=bE7jN9@N1WajyPz&i zjr(L1e=?I16g2bUoOM=_IQyj4Er%#WkKy9GTaU7f}xOEG(!SLfb{?fYMGL*W__L`+{{f2j18S?2Pqwze+0-`{ho+BJd z9VH49n;%dZ1NcYO7l40EbA{Q<&{Y}+jnI8=MML^xAsk-i`AygyJWsUuwN7Jq-}RvI zjHTlMgW?!}fm&+Wfu%AAof45|1@lxi`+H=aH<xcrj;<#}pa5+HXBXju@g8Q!Hr{MS^gKnG{POp6LvB>kp zHzAj2sx}ZjUucN=Mp@+C8W=j+v`)Ixh@mANg<)EtoB2bIrRN}m;3Y%l`FZMO#wazf zTI|SYRMLqUqyP(H*H(0AXISKEB|iVX|@9AwNu5qXTe-eGDmwW04TxR76 zvTZjp+q~1=Iugq@XoGeOVUo8a zEXV))Uti`NxsPk>+{$X+3Qz!G6E)5RSS0@jLRGHWHv9kqq~jX`jtD_2X-hLl6U)BZ z+K25f#JH!Aks^&v!G@Vi!ORzQt9Wn<)uiMi&-AuPk=ybE>D%Z(07c1=_rN0x~?C3&08J2#vWtugZfn^O7(92G~HA+Y`j;yB4S-z07^Fx6P&gvYv3i(VS{`R~dP z#+dAUYfF%eNx!^3mSpo=fAdB(8?g%oH+72q1INSectwE9Q;h=`tAo{ao1_`yW2bM% z?mK07(ItfU<{~U}N-^3wBH3i*qGV(Z%5ZDXP~-tPdi{iaHu}rA&UdhPLPfznD7<_o zLFjS_s;r5RuD7auY7QOMVJP$)EF59hU_)~MGdOI(m6uW&SxtmKV^@1=vI9OBHSi`W z3IY@WAWBU%aiV}@Q+gzt-2)ukYaYclnn&4p$u!$R(8vMc#6Q-H&lM&1X9Q;^RX*m-^dJ-jW|)+;65yoLgY?+fKk`1h_}EmrhZXUM4Ue%774088}MFc69tB~banWB1r*QomPkvhdkvquowV$(|d) zNV;!1Ny(HWfW!2vTpk>9YpwOkxcm`yDRot??h1*0`dBL>d$k^evPT6H2)t-LRIMeu z$;}GRx|~Qf(mCnxl%vsN=4FuS87PUtjAVu=QHviykICrF4~O+2r{t#pC8tvDbo(Di z1+{!i{EN}nS6>lX|Ttebe1 z%+0_SjE`{I)fr`q6F08RlBnkEc7!aD zT@Y+9%NE$n$#NC>h!#ET4yvXD3nUd@jes&4tGx^lSAOEWZm?YpB_`l!)+p7_R1T1n zH0zPTU1xE7l(`AOUA(Y2c?mR-)Pg-MmieK=beQK6HPniZDE*U-KC1JAjJ$5}3n>37 zbCKSZ#n%M6Cf-yk%`)Zeo+LQ-01Bc&`qu}K90!Sb@1-KYf<#~u#^2EaSaYmwS{noN z`mm;KGEaM)=cOgRtm|HFggR-e3I1J7Re%9_w))gHd>cr=0RlE%dGDkE{ndNZbLg5o z$-n`mBvvuHN@akBydbNqwAFveN#wX1LN_|BW!#CSyZ%a>-^jE0M8D`dMJsu?;Gx_6$kILAbt$;yn^psxQ3f{T8%+XTPQd&wd+Bb^B2wwYn zm!dSOg?2N5AHPpZ2ldZ^OFC=wyiYr00?H?TQei^hF7+RFmk&E`vJl3vAL95}CycMM zpR0Go5q34#U&k7z+`I}Pt~WJkU^aPqS*^Y7ha*YUp6Z89mVSXnI-o12@duq`E)cDx z2EC+1Tf6V|7{Wx^2ypO%ruR@R`ZE6Ab7Jjt8%&?mcZu2ch zR?S7dJ}RLB9{5>nucZ>fS*1xBAj&@8JMxWIyPQ(N!hd%@+DoG?V}wS5G#$v#ZEo@ogNTy>y9 z13xaSsvm4ZtN- zR7Mftp|sv??bY^?0u4pAN_`CEMmi$hM{+hE2eZ0Xcs+SZ=}pGxP~3uAyQ`|(Yr4u(oPFs zt6#>oI9E=t_dXrz%~Oc1m?PHbX33^tc<^2foVlP?u3C8KFQM7{HcV>R6JfB3;&|1P z@!ZaN7OTdai_+PbdM>a)xM%EdM>$RY@O#KeBUk~uCwkNj5@*|&^HA^cd+A~G2mC3+ z^7XyR{%G_mm##zwh=Ygz8;#nz*ZRzru>`qyF(1Q#3fc>|-)KfuNHUZjl`F)UeWBzrx~PrJ2s0`)A(F$8I2c}P2|i0G7CR>_uy08rjyq_zAfGU|~&PA#36 z&(+x}!9vOFboa&2E)|)+)G4J+e=SQDyWsRlm|CZ%wJ;6pEGET_NX%~pLyM&|^(% zq1^P-ZiM5cM%p<0kn+62e9y z&RNc-^=M9k=RT?dU&|tHI*@Q{Db@4{it>3_y+ea}Hy2z=i~)xHhPhaUC2QY{ z)P*Y%xVSdG?X5nUb7Uz5#Ri}Y?BWAYBb@i6mClT@BpP|o0S+M2`%k$W`&R>?E)24C zm0!LA;kTXoDL%i>z?P%4K1{Z2RyTnv(TnG)de){}>lK}@o36SlR<0f;N+4M256|Vb zZ+$PUGegOglKt&%=0ALk=cZ&YopH7dBrt?mfv(4C{u56Bpf|*~E46xaLpXR^@xc%< zS->^&+e&-Pa%aEk$jK|9i=gCa`dz3zzKX6VIVHpRRwDYU*fMXK{!~pC9X9(12P2-P z^nX|nf6I#h^&1uIOr?;@jPgeKQ=185eee$;Lq#2Y*mGh>L^AcxYI>y#553Ze4;`Me z21@|dVIN=_z)CCTcG6F2J8lshbzs_cY35=_Nu13m@B80}H+9oY=&D>QzGP>{6@m^= z+jv<-kznQNs$5M$H-ZkJ=LKx8ybt-MVChf*sK~Y(?M~n$3b1EudOLd0y7zbMPy$5_ z)iV0iZYtP6jrDPr=Bmq__!1gL5>~3tF!7gHWy0X1g_-seAN@C?As9d*9P%woMkP%B zs*vIVqSC%IY~8ai+P8QA0gUwwFUg;$e8%wa9}Zd+S~3Qzoj{KsKG4W_SxDj36mMuH zvJTKs(Mq6xp{$F42qp+X&v>Lr(&8gxYkqwO)K&BHrUmjf*N@!88Sh6;R)MnBdEdN{ z5DOuBhYUQ>-Uzg|bk*?{m;`fi)=k}(zTiD0@22e@P8&z4 zx&+$(CW|CbHGfA<+G~$DtL5%c35q`IV(f=dOSQYN|A;;|A}w2C`-dB5r>>xRpiT+V z;b4K;n*bGN8u>!)*Fbx4=)@|fj{%2h2sZ&A&>W`CDuA4!^FIeZWcpo;>*PZd)9vAb z5O)yzs*ezFIZ#NZV$FmiA-w~%=o6rz8S^m^SY-I`i#nxYPI#vCjjD-h8Cwq}@QZ+0 zD0>y22rS$w@n&9BR9eu8>i%zo4XB%=M^k!l33C}qJM08T6u-?NlKIaB>AxjX{}=!6 zdkf_L$cL5xKeed;?i&B&&L3{}f86@>yDR)*`Tyl6_1};A`M>rkyiX5Lerx{*Q6*h@ zqW) z|M&e||K9$;5Uzv0v5H`y*d(n%PeHc$hI(M5^6<$MO9(p?UBUUs^!TJxbaZ=h)z@V* zbnx&6`2?;5yWhV{ag?kDQo;$tfytIPARc?hfo6ATtw*m}`S*uj^h+cL9-VoUq%Wj= zopDQq9NrEM4BZye?oEjQ^=Y1rD$&o8B5C)(_rADZgsw-m(Au--|94f`C28| zeXEdw#g%!Q?A0{qvNQ4MZNM5r`hH4u-Q2;i=Bg7(VsIUA|1PPJprsEF7zF7T$MzKw z{kFpxc)-^PDwhwwT8=F%hV`lrZ?7~L(K0EXHGw21M|1G?D{(e2OSjArkZh#K3F+VE z%|Sj*qj5&H>N@i%Z9C+;kF;K*;+P%W_Fz4q_!8MtNB{Lu&z`5=t!F)?chyhJN>ZQ6 z$wR5EQDd{x<7=7o*Z#%RcA~*A#Ll}TYpwc~Qn6+OsJLc1G!V@UXRAWhg<|`m8J@Pd zNKv+qHk1ytsy0`ofk4ene5*wgpN(QG)vtFO<4-lp@Ugzz+^^Y82f0aR23*fo+|#tn zm6)a_r7aReoJ!i`Bp$2gTDq>g3tN}R2jL|UM{!VQaUvmo`jyeSfObJ%N|Gaj z9^X0bI#^j6fFB`2zt;2@qUa>}2!`reyF za%BdyfvGC#z|@D5-QZQmfUEVS(-n!0_k{Y{Zg?stmQ(v=a>z@~E9!JXG`itazP3|{ z)ztRiN%5|#YhVVbETN`ur+Z<8W=<;-RSABh*BDb( z+-wV{?9)k52(^poRv9-BF#Uex(`*+K7U0^iQ%d-^3w%-zkwG|tdxN4?PM{`D9G4t)u3GKf<`SvuBq>VA~xG*i+sVt!Z zy7;Y8|L{xIsHUe(r>^^BnQp$(t`@zGfS!TSG}9HDo*+%5COC_ypo;#dkWOc7g{ICo zU(PDMcXe2B$Zr=;A?)CZr{&$YHT$Owf|jT(uf%eyxIsLGiTTd}2Zz>m6o^I3 zA&}Ti<1{>$^jdMna4B1?jUP_qK8coW($u#FDYe=h-C~=1?NQKDf@fdF0|zZMySiXi z7oIazbil? zSV@6`OH~`Mlr3EjuS2}jf$Wm>updG zE2t^ya;#gQkfF%s+i}@(aipE7F_J5TXiP^eq;*9mxt~T?b5n8eie%>i(KamY*YLjC z&Swrwez-fIlq;W)tuJmLi6P6kh;kw%z zXaUX@Z6jO~O%nF?o8vrxMc)t7tEqKT*@@PLRjuBhKX!3UzH4EX(>~8CodXZy{q#Pt zdmKA1>bBuQt~z$S`a!vc){NZ3t?=bpl}~^c@=9bh8uYAC&ob^F$XaX_yTizWW<$ta zo~oDMMJ8OhTihhg0=qMfwAFr&9WOR*lPyZ!uiOd=Pw^l}$!jKn&+>4 z*rgb&vYf0}t|-42;UZygbKQqtn7hOIxl)a>dv9+rs_j1Mp@#OyE=r7qf5YUY@Ovxc6p#oG-?xS!!5$!^u2kFPkFx0o^5O zZzITzT{LgRy6Y#+CUUd`I=xLtmS19!W`OJUAhJ0loq~}fq4)x|xj##kse#V%#ODG+ z2$se(0B?az=vMfp1E1#3=cT0)^m+JLu?}Y=Fw26t*-hSx)VjSbCM;0&HWApJS?_RY zV|=&{k)qDCf^$LlO4+Sy=Q1rPIax>14V0t#ph#vM06*N>5=D=NVfNRp_a7{{f~7v3 z{(+Ar!yHtx!12yd02>j~jil0GkUeF)$v@J0NP9thD z8dpo|VG6&OY&>o;Xfkj^zq1Uxb>lI9f`l3d$zJVyPph6nc0xS_h-Jmt)6z z^1BQ3KoWNIXLU`Y$_}G3Rh|BfjNq0T@C-22;|IKpxXf~X|-ZPPLS;4VLyN=yZQgHuN5JlXWT4#K;0&G= z#-&KJZ*Dd_3%svSA(76S0R#NNRWk}_vDkibimR}aAt1|JF<@br6fw4>M|;k(jh;dq z)V3?q+(!qNx)n-8!u{A<=u^67u<;{Yf?6NC6(W5JM+ z;LMUPFE;>-3H&hE=^z$)8B4HoQbN4V1?aKz7MxX0(<#`u*a7S|YP57|WFCer{yE+9A`ab!P`i*wBifSAMPflyd37<= zs`y_4^mT;jFj}Wl`W|b0OB*Cn@DT{KP|x;sYa{oWc=%W~yI=84s4QM%WO2I|iiALZ z5g!Q)4}$9MDSbYIY@}x*_9Vq+2%47=c+?DRh&1nNr}S^Sw2WParIR#*wt$fC-M^5b?o&`_xAqgjuwl*Xl@2?ASC!ms>Z!S+2a>* zynzE3-^l~;8j^)5;n4IwBtURCd(^i8C;#DJXa_H=NJl)+FAh$#o6+$#?utZQ(Yw}u zv&M@zahh944xl{+%Byo=eQxnQiO2|q3YOh=_qti-`qra7?cjO&pj*5VYumyqJQBQ3 z&xKOQI3Ip;u*E7xX5|$^#h)u1F@s+@t}IlxJY5-_*=`bY!q%R((3IPH!1Whw)A2!$ z?xWU1#lNhh*p{qu72Xl^ADgy=^xCqY-%SA9`0H;pzeh_jrA&FZA*(7yhPkaF(-s#h zHX1$WF$I#l^%|Cj`%7M?bI*pe*87>$=Rbh_$JYm3&At_NZqhA%1}8|fNFZt!HDj|R zr9QnViCnb6S!2=>o?92G~Xgr)aQ75pC|N6r>s7)!K!FOKo z%sL{4oOW3@wbFWZgs`IJY5SEAwmz%fVuvu{fxZW1 zCw-=i1f^_aE{7DxKgSAn(@z|h(m`zpv4c&KiUO_xMycq1A|7pH5*;{wdVoB(yXfik z64~|0?g1+zs56p3N9bydG>u%Pgyws^h-f_x(6ylZ#&v58 zcG*-`@tuJg5exi#PZ?pQ*@%>%$a6WURthqo1GocMa%`)1781#Y^4?COoj}TeD$L)n ztv#(E%AIh=K`r(h4Ds`%t zz8P$t%NAK3HgHC$S{nO5*LK0c*68a3vu=+$k?pf zHc;y~^LZXv=K4A4YEc5AL)AUZ5%zA4PG>?a1Ce+|4S*Bd>5S zymOk9FvWSjlCXcjyJ>Vd>Nzk-_^I#3V1Io**OumBARa;}&lhi}9rqpajnT$P%*OZ4 zGsj_70c~Y!h(~on$5}L;X{&pP(GI%zt=$MM(9`k!;*;~D=wM`o^e5!tO46i#R}8Iw zm$N~$R|Ab&E8r3vH5O>M{3YTGsnnV{ZN+ad^{XS%((Jg>(p;M7f%JS8AzDR1-L30# zMnDCp1Z`;>m&=2Hhp#_#Kv9`kT*E|LOp$d#TTC)h)Nv>LucU<`4N$F1kIYa8z>Trr zV7uBj7tO&MT^1iqPPg_R$bY$rvtv>LtKO_qNgh+nYimM5p&#g*Sq`V1nZ^|ebm_|| zryt2Emz72Yt8P&Fo_&)Pf^1;XafOAkFn^wkJ5HTr9tE5dBN6C9DQIx)^Y<bHiaE+B`FWQ%q(L;)Q3!!rh;sUgiavWeSr;i?O&j4X@@;IVWl8%vNnx(m z7i|(^hHNhrda4>B}7uro(^zWMi^FILhbZ( zHBA;*4Ph$s;@>B^Gd%Mi)Z>R1^dd>YCfi914%v)oWu0aB_Y@~1`l z?b~;ipXZe3YXP#1-{D#Oe+`NGOS=$z*D>9v%T;!UlZR5!JF^|0^M_*=!jnv6hD50m-r+6C%`g4MLhTHG z&zWEN7&8c!|F_o`voD=3i5->+?iKg>_&cS}L9m_zFI>aN%?XW0!w#O8I0*d(07^+p z>iUwJIsO!GfkhDLpZnQtQ#mzytY2jvVMlp@>z|Lt zFmTZb$Z!6=KQio!(5SWKB#nTiWuXEpwmC7(`8bp%J%)KM^Ej*IRx11JyAm;ovKvZ! zkuGYM(7@@jt=19^c#K^_da#$Ji4#l>h?fR@ai8Q7Ai<7X3t6|!%tx*S?tQi40vr}Q zq~B?DFpXaskCy<1QmLcxu0)#D>pqOW1QMVwyUG)w{F1O`u08GlA?_=~;^@{bgOkSH zfJU9vN?(Xgu+}+)s#+k}@?sw0bXY9^AcV_rOBURPaTi$oA z^{&0Ergqy;O}zTqZ`#)_M%m>L`jaI{i8zpPiOZ#Wzmh-rd!Y8d%_o1dTUO!=P8^Br z(X>VyuGu;_1OPy%D20dH0Lu6Dt!A9$!_#l>-J`=qtomNFpy#R&a6W(lmfJj(v-bd7 zuDVIb9p9YgnlgyFXqc2%-tQ_-#pwc>>#!Fi;)?NKsBtgmd^IqHZ+6hU$<@Q&-UIYs z*+Phv(jI?B@1K-;)s{jBuXxf*Q=l+o3TJrd2PQ-U38q+|isIkC+_K$9pX`=h*ju4j z4rDzgPv`ai8h|!U^j)%^0Y@jiPu`*=ocYnQ;dq~J?l)e0b1V!e<1p~c%U_fU?$4;^ z0Z}Y@@`gsSlNg2F3?YU0>b5NIs;wxQwd!-hdz*;XZ!P{7~ZM{V?P5L zKejl%GoT@w+D+lTt-qSdC=(>nc5{h5tvdYu4qR81+)acvRkAMNwKhN< z0^OPQURppuV*mUc93MVK$?y+a-CYI^wybKPZ*l53`g29{_j45(1df-UHGrNF^xEp3 zqrgXgX^-vL>(*;Cy`DT#m&uQz^h(8NhQ2A~qFR;f$1-Kam2(5|*RGBI1Aq$c@<4iT zenLw7d`~8IXdl=XqT(whD7L z>+RQw;quL=KfhALBph`)8^%)%lK(>9oNGFaim6ZLr{UzEXv?@T(V#`CZn4Ic6a`;E83RYU%G z`-6iQ1vV|J)q<0ewEn3aQ+j(fzA2XIQ9i)8c?zdWk$-0o|H~hyb{#)+@6$&|2{akK zgd1*44Tr1Sp!U`0d6fcNjMPFrL6t3zQ9m*CkADrgY6+5Bou9}M;Ol29>~$-UWKXwT z?{GIiufQQZ$}8UB^`RZS35d(b;>BC}CH}$XBLnCU7#JaTwNzX=bH^k0%C~#G?ONaH z_q{)htp_l=p}){HFIh~YtyL2}c4t!6I7B@M3zxs%If%R6dABwse{_;7iHj(4*rib* z@5z+C6NoUxY(zYa4jqr}P1E5#L^_hgk}j-8?^dy@cKQ%j3cd}E-h6fTM?8I^r)zc; zuYOBTUS2S=@*#;sF^o4#gx&rc2f?58FQZOTL5c3fIc zzpj@UJ>`WLKs1TzTJ?@x3G z{~Et&+nyR}7rTPwa7W5`(0R;{5UCo< z4PMWUO~)yqpu0u$d#!yavZ-On0%Me1i(qKw2SNt29uU}@#h1UYTjyiSfvLa!NH503Gze+r-%D$KoFnlB z#gEGGEaN&6B&HUNbvbLv7K!+ToYwrkJwbezi7{FJT5|(Y!+@lOF`nq>CoHb`=33E^ z7Hm1}ZhJa*fhiUPIS=eQ9H~#l{VF0#wgNf!4#i0|%|6%+9#Tjs)M61jbBg(SMI?;K zykY@}l>eY0YuCS%ip%xHYY)e0#KOH-FnN!*{+c#G9c)Tm`csqaYm=@J8C((f^PCSZ zZwPaHepk(ebGV@#$ai1<^iZ^u5i2klBOi$W}z9u1Oz0FE!twBQEgmBBoOqk+jfiE&KHYrH?=5!1o> zB@H}4$FMUkKH$=QEarDFDZ5Pss$g57)fk%2=g6h2^4I4LuTKgrg1OidZXRm8zbvyx<~<;|7svo>Pa#}G?KG8vyq=xVEO=9reydf{dpyw?#XSe zI$U?2{NLtcrr^L*iuGT$1M{1m83j#1^jh2mM6cGlhjo}J{g0edcT8(5pF~#o6kIN?{p1mX5Yzc?OH5slNpZ~Kz_-zBvi{ZIQQNC+UytR34^|F z(=}{y!-vRiMXI+MS)$Ga9ookyOY6=>*FEp(&iFm^bMOt7*_>H|(_+585P|%;W>JDV z`z%WRe$R@(}N8(=V!!iVwT;o-4%^Tx(7 z_HXHItv}DV$HrIwH2kq)28tO_8LKG!9ssBW$g&UJnt;482S_e}7LN{_E!>>(fv0(= zaZvd2{QdR9Ds=h49~^OqJJSq$vWcf}7Ud!Xk=is-|LP$Ty(jYfL-^0>3HgqJx@l$E zFQ+*2qoPVKl-GZYZmMPZRy|tzT>gCL(o9aS^@A}DwsoM!9uv&4 zr7A@wknuy@whVn`?uR2z5vItDa$a-KaH5obO~cRk1xj<;N%=8Kd594)UG$53@IS!L zUq6Oo{$UnlF9DY8F-=gckaKMnQLQ8L?6&bhh>nmv1N&KI1~ElI!AaoM&O9`bCC z{iTGkoCV_B00+G@CXewdb$t9qseD=FncAMq~Frmss%_ z;$V~r8D6LBfBxVCsE|EgselSeM{W1U-2OaS5lEJX7=NlgWR&s10rs4?8}-jMaEkH? zg;4^;euQrZ2_3^{8_wt)U^35uJL$AOHSw{;=zMr$bv`2htI|X397nEChk4Ve@ySy= z-r6C>SwwX0v;?88Lz{8NcNz1v#^!;gny5m-&L8AywDyNlA%Oq}@oP6Gj79{>htnDg%f;`$|7o5eYQ0N6trnK>%V2*4fK zU9u)wz#&9E|8~gES>5n|ji+0dUSQk~T`m5*=CZ%{kLF?HV*Td^sN8?=o%^5cfcopH zQU7V)GAIYv-9IXC?6}Q z=bu~TOWMZlvfH(Fwgou^!iK177P#rmWwZD{ByG&4JL@_zoHT^h@b9vq_ z2IIyQp}~KiQ2j42`HbDY zG#J6+6j9PtGf*|y(w@Pj&>8E#@QA>X_(<8ph_L(VP@=#|z0kDi&?3BFe1P-6R|tdr zgdi1B3P@BkDD`;g6QFmeuwSTVzD!!m>~db9h3sPcT1z z{L&F{x;fw~x4VoL;$p8lnzFiil=$#r;HY5MUlzX^ztb_TA}pzvY(Ig?{_t&sU$;1? z=l1rt2G`LNTnL8kHSg>~KmK|M6m6t7oCew2rH@RD2xyBP4kfY-DyvVi^UTuHNN~vd zsDFIZ4!p>;?2ddUy3D8(?2so%c5Qv z(ptcl3hnxE!}uJ~?BzR0m<~bHPQ0A4rcb1?a$i4S?)*rrDo4(;xJyMsR~6`tbq@+{!)ryN?Yn0k*^ zMYP!8ZJBcTwp9wW(%}4wp54{;PN8a7?4{a#aop;Xb5=gdA4J7RW40cRQ?lqRsT!|x zawo6`MQ+JLq*;CFrv>NA?X-dI?U&H8GG5^C|JnYMv%h!J?0JaT3!R4~MbI5p(fMel z=o+_o+!eJ{!0AX*VZmWL`2~*dRUL8f4n+nukJ}?vDQo8P zQXMeh&}ZZAHP7ZR@z$Nz*4E?qdgbDWBq3J`Ok$FuwM6VtvqJB!qT;iyD{uY8hg=wr zeoP-ePj^pMe&iA~!wiM{)A`@N*&Eid{^E5$^gKHoXVK!GMMDNUwzjqh(_oB+56k}g z2GNp!ak4!|CA$0Kf`L&)wbpGGJe}DJ$DM_odeVr*GvW5~s z5}`6VvGx(`H|jYVVsppU=J>q*?)(aBbeEjt#g!H#TxTw2e&YBh&GAZ8oAGRFeTva( zkW_yDjb3Aw3T4kkB^x6gG>@MSRTyT)JlY{Gr?Vk}zmA+|O5=^_J6y&x#m+bs6|x#o zt}sjPN{f5nls_a)r!WEs5f>XBr_RH}F6=t!9?s!1_N?sQHW6u3;lqd5x^t4CE972N zS67~-@R5`@#5DTZ;=cE)AXz*LKPPbu7!Ki9`1ZGKI2}Rn`Q#e-=@JD#gJ7HO2BmVM z-W+kNF!eF2Bh))3H2JvRw7MphU{A2K*$xiT&tL;%V5lp6*&U_D9~>zxe4TA~$!Q%U zL(PGvLB?hCu(nXG#^)prldyii)N&eV!Jwka50Y4lwc?wDAG{AcNz55jx{3b0c%v64 zKXgo-;2fZ8(W>@#@@HXAk#=gNH}rdi@MJ&E5~RwZ2JH|6E~bUwaB(o8c5& ztMr)GHf#iobks`-ARYcZ`|OJ?UGkkCeL9dfQ!4El|G{k(Y@o7{#mq+|b!~`keAmTq z;MQ>*yb>u9#aIpI=3IpNMe`Xl0^%1M+{!+#``ib&fsl)y%u9P zrboYlH#@WCO~m?KfV2e! zYZQtXhI2FiGmlOgt~0!B4w;~1Qnb`-tT}aOUv%y)?;Tu`;#Vt)+fWfuwmP{g8U8FV z9xL=hM7oaZp*vKJ&d!uA>tfmI`E+tFLpX={>w9cX>*OL0;6Hv1pG5LyuY^)yq4?tC zVb%V9`C-Q@#3_X(orOe=lp)vFw#IsufXNGuBquw!A_H=vhUopf)6FeK!&8aO^3qR4 z94uVDrc8;&egeJSj?>>sJ?I$7AD@(zH_@zOXrqH~xH>-o;#5B3v(@C{d3FkJ+EXKY z48v?+dDL$?DZx}DLy9ZDUEgHJOy+hBC_-KS+0rc7Ll|%-;RE!TXuhz|gBRL7BVP{` z-1q(Oub)w@PwHDvJga~p2}FeYQ~~et6n6+u+MQ5YAe;AiI@CoEOzeGkK~<~s$!p@e z(*@u2_e0jjGE+vlIA2e}&7Kdj$Kc!B6*b`Y>pV}+$|*owu0A&;h#!gNz~vBHVDR{f zk!+nh{~jD9_d_KWFl0A@^>8};TykHob+FSKb4SZaFFV@bKQuIJhEb*p8biX z5axA^_d$LsFbM}r=L_4{Nn;i(T%9KCj+!$7FB5Kcv7E2{wVPA=uFd4Svd(+&+GQ~4PrDCEv@p` z@Ob@3kL&ZFW^}`~g^N2@M;^33+1_KxOkMBaV#T`N=$nqV!W^lEuYB8ABP&^OGLc$} zDk9}bBb1g^>|^Ak8_lJh?z5lum5NAE^rukBi4yRwwT-%D(JZz7Id1jAbanFsF(!7DFbQT(}qA2$}L$iWbE~Rlx4vM#@%`U z@83qoX9&a0Y;&VqcFRM>?9x3u3(UG*j9py6FRY5dBL zB{6B%xTdV4QmJJjyM#)>N=VDe#@Z!r2Wd?MKDZnvY;&scmUS;mqJ7JD#Ul~26M zs?fgEsd<_9Tm365jPLh8x%f~+#5+SPcE2a>FcA$fHV!Q-d3&D!XS3x~aJ!^pDkscO zF`%pYolaJ&Ue?gQW9^{JUg9!=$ED6rT1wE~@OGj_=|ft1TqCvbu@ex0j|2Xy~c+R!N8!= zG|Ujhz`druh;dgT`-CP9Mn{|wf$=+={{B3T)UihfCrT!bfP&tsfuuqPo8^lQz$ju4 zVZ=|2z>%S-z~8<*jJ+ZUkgYNJ@BhI5OH(~0pm#3qX#RZdI8&plJ+jiX{Ex$gAUXWn??Ub|#S zs@N|BJVwJc$lR?840m<3hG^RoX_%L(PY61inziPO7_*Fv4s#Xm%uL}a+}CAqb0r7v zG~o7Os5sw(vlJ!4?iF8wAPg8yOp@!EV;sZKipVdv+JOZEzTd{_sT;$vigXN z-8igQE`T_+&#osKkp|lrB+WxeO~#VnSdo*P1EhkxiS44sh}bgi#leMK?Yjc&1LW&z zCbx6igo1ghw-u@WYsc2&+1c4f@w%6-hD%?B_<#>+vOOKTIua=m#2_E1& zIlJjn|E9hR$5EwdU)xHhS{DoJjfSq~#q-|JrSy8E7*=dVhFM^8Gw4?G^HX5f?K10o zVHM&k1F$jRfDV1Abo4RJ7xF}6y;_sk;7Zg~fmMX;{#g?dk-G4H~IXgZ*i1VJ>Lv=>gJp)O!&-{at+U z-H>99$}T#gr(w%9l3-57fgJeEiHiw6FWB`kUekZv_&M~f;T?M4M_TzfDFT6o$_qMv zIqv9g9O;ry6N#&~~ww%BlTvMS2UPClq+ zex6E7GY8X0YM0dU3a8LUF2Gz-;i6urgxrgl&_#Ad*n8g&1S*;TPSrxUT7Y59aFJP}_O4wiNEy4&;p z;GKpAE`F}2`n{=ui!{+A-!bWl@rgmMZtM7=VRz!$U4M)Dxa-+jWNRa2-$p2iKrDv^ z7Iv$^M=>iVV5KwpX4ImUjqo}ko_yd}&S`=>z+!ZW+s^^u^T_xrS1<-#$8y&Ec`+PS zU4SqlUhDcOL~7dRpbRc8Us%5t1kO55ai^0nvRbKak%g>$Askd#Hc+1{blTcGZ=Obf z{gLdO>(p43F(H@De1QdX3!5(jK;^<4T-;Jl=bc|IV27RXn|Vn}=B{{jlJW8mb6U;M z6xUF{?fNwZdWesXKG@?&2oHi%Kb?rN7M<%NM2dp5vHyZL)o zSecke!hunJ>5!+8RuE%tpakHy%}7PRN+P~5y=lv1T6qXm6xj93Ms&Yfmw?dxwUK z=Pz+H$?`uWkyEDfU(Y6yis>N=yFy6$J14d4P40X|y5`;&kuJL})_)BV_YKEAof#wy zb~?2h)+QAWNgqHZ=9y`==Te2M9OmK@CpqtpmXe^Pd4>Y#n_ykekYKzK0P#56I`py_o&@xUxHOzR z2y{qh9K%-V5@!AZLEJLfWERmFG=da?w(i6yX^vReG&yr6LS}>xc7OMF!zm z=62S|wQ74D0MyWFE>ljPM-?;;N|d(yO^m37`ywXF;^zC~G!3hANKLmCX*rAL@nsSa0MwPwpKXkdaO!&*z}E%8eV{vn+Nsc*0>HKa3k*$XPt{MG zx&6c-s0`L^IYE&!MSzfS`)Q2>u)G>$h%2{a`cQX0H7zY-z&>`cx%kL39)HLMputdw z`J zn@4^$#P6g_okXU$B%b%i6#n!^?F=Qj3eM9+|-W|BWYavvtAHQ&;N4CbrmkjLl+V#nF$Zue8{Vc$t%zbq#zoz_q zr>J3LKbkqd42%`jPp;{X3Ls{yJ2KhhRi93Hu5?ld5#R_~Z%pYw!5?r^q-K&BjM#!3 zCyIovmo7Tq4{^yL_(D@6wd4`0X}j?@FE<}|>7nD8bZyd%k};E$EI5@L#bSho(^Vdf zOFg}#BaDU@!=ydf=~Kc}`JhDBcdZfljDW3P{Na*%n{+&3SkuXX-@eV#K zWkz%J<5eiKwEVBq>T1yZ23RLBcwReaYJCHSuRmBiRX>q%qp-;%;j)Q%5YK!6V zm8#J|%yv`%kb3XZltoXWaRzf8f*Rb@2`B|?Olqga4P%6X&=}VcwDLi7G_@?=P&!s!~edFpRw&*5_DnLy058^(z=bIOJf4u zwi4}OGrJ3V_v0c#~sAW2c_vVhLof z7}MVyRV^}U&>dGHc7fzw#`^UpaLDR01kb$6dT`JoUA5We+&xEr+jO{tmT-QFiZU`g z&$A8I2SDU(BHVtVY3gqkubQ+;YxZ4L)HF#B_#maN72<}rYb=Mo8=^ZaA zC;SUlf#LEN;~ld&ahv0EbpnBsD(V)x(3fHCO@RLNkbb3&JZ`!Zk z*fOb6@Io7KqwDZx?!}5!N1<=Nt#@2U0IPDwa?fG~FqDmoc7ssnHxM zy{3y?%<$J{Gd??k4F+xL8jyHjy)DQdt*t*b^S{&}?}Dg>%CvyC!iy2T9x3P}%v|8N zI;c4s#GA1x&^5@mPp7UMHe`4qXvbiwUEj-|tP&OQEdp#OjCuh-Vv^`QTWq>N;R|kn z-J^-SH5-cxi(>8m*mhs<@ciV=F<+HbBPcsP-DlaT;fGFZ-yonfXquBNM5Hv`ebhAP z7qB}BRevWJstI#oN;1jTh`Pyp{@Bu17$8zn!5N+vYM ziEOj?3&}=Dq1h?`P|xo}f2doyi-BP6n`Rn5;eX*=q`Ux-T0P$+dt;@DS`0K;>#^W# zh}ELA-OJF{YX~oXcp5)Sng`L3mTC|(XouuY$}Y=bP=K%E`Z%7ZB%;PL5VbP2Rmk=* z`xjeb0v$;+zWJ&B=7pE5y`=;Mw;L4vNJH#5cv-#jiQLm7ToSY(@$A$bMbGAC%I$B6 z8ehsM%|>4z%9}I?{R-JdAXck$`1IPmSeWI*h3hM;3cE>MuaK|h>087{lybG|`NxECjH-n4oeIwR9JTHPJu;L?i%(hk&<*ItUaU|O9lmmWsSL{CTR%0qjGoV@-kMaW zN4b$XzbdQV5bGNE;Pm(49XN<#%DQaHAqj-3|A-TX-2nMb(}?%ip|UB|AGMa18j9@- zt72j!Cb?JOez7zf={I$8RdtAQeFgy&_1oGQMlChYTclmO?;Wlqk3jAhFpZ$Eh9I+uTx$0JbU`C$Galw~re2 zh<{+|iGcjQXIDAL%tTt1OiU_#Jz~VgEu+uPP0wJupCP0kdY{X-+&8PL9D7W3lSY0r ztXUMCon7caRw}G{Zusl&%&<&cF`2grXLMxw!B5R?un%u#t_cUe_%PwKc-CV&k8D@) zcO6Zqnc)a&yh3WY&fi6lW>`8i0Jc5i?!-IuL`i9bV26LVd}X-)<^;xf`1mVRSo}ci zeu{=40UCqNW*yUnNRU-QtZNEaSmik|68y;g zdgunC(iVho>QxAsvAT5nAdDdTNas_vwraE_cP13J5B*0JH3ysysN&Qj;Bu~{6)tN- zHoWNJuds|B8$9T!#r~{jAZn<$)W)>vdng>GwrEt8lpo8quI4IqERK82r;TZr{C6c| zOErf>4N$NVe^Bxp`0ymVC-GYaD1n7d@m0vMa_893+uN&u)I$@nYP+Ll13ISWw*yIi zW4P~yzVq5`<9ZgiXK_+*EYbW{1zoN*Ev!&0x*0Za^xOf!TYy6@RNQ|_x#BN3Bvjcy zMklFEW;u$mED6D&Ls0p-y0g1$UqW#q{R6rJ(AB5pmGgy>V>JGn42`QWB2APE4&v{h5hwk0;-WI8_bLARa2xa=2jjUu;1Cf;Y?+I&S=!`46Szz3fK6};N5SQu zL;+f6Ds5>vBehEAV&JvL<$KNbhQx`w1LM*oLUZ&Rg^>8_KT|;c7dlJl(_L{fgBzSN zVy_C>k;Lm_%%+~?r9vyI))D`KRQ9&FAio!ujJ9Kzj22V+j>uV?YSHDEQ;6@HQlKu0 z|2~Gd=V>A1MMzv(y`m=iTO9LrVbf8aIe;IK;4r{J0;D?koq-1!1Yq~GG*xu2GKQzH z_%mxHP=_gwsgqf7)hE=N2PPVxXcBa|vGILofct*f(RJ*1dM-Qodt(F3VY7f6AzH73 zacJc7Y#4Tm#*&~a6pf@Xqzi4AW%Q8)X*9wG&wRBZ>C8{8%nJsE7G2*4lhu|*yLjS_ z@!e>6TOpcze7ybs_6z^3C?U@s=4YUX!0i^+D*mSxUCp!-p`I`I8ikSP5GocDD3>{)mpBrPXN zfZd4}vZc2~=O^O`h*Vi-YY3I(Y$XnRseZYGS@Ct1->%Dy`iK?inB3E1KcOy$>9l~T zveF;9*iAl$Q`2lWw~(k9G?34@xqF1DjUUled)D^6|3pCiMg!TV(;<&U@j2@w_tr;C z)A^{rhPG6u%|H(G58!09kr(G-n-HZ5yz`zh>6dsSEv3vBw`tKBka!LcdU(TOBSgM9 zAoWh@6bLZCD9=C9gysmp0%!|MLSIi$n-|uPoO>Yg8jx1Nc2V(oReGj9*8)1*7r|f< z>=&a2^ONsAHlkeyNu|1%0j>+qYb-~DKl7gT8X>sWzV_{Afad9TwI7i~aYP&X&Bj8f z*nT}+Yhl3@@vT~M>pY*j6K5qns2egOP~Rm?#y%#>GQYIAo<$RBwMBqoM0mQgxDW|F zzqW(Q1HL1@Ax4tRRWk@Rh@Tsfbog33KQbw?O!2K7Cgb~#a7kubRaLsA>YvI-dLiUU zDCmbMo#sUC;hY*|uS?j5Ves6C*H#2QwP=AQWt zK*pkt>ljgcjbrVRDSOfz5df~@H(zR|{+@O1>2V4qc({_XfABH@%?2xYc2ZnALFOtJ zGxcbKJ~)V0zhA;we1M!v^a6q2u+864%BWRg>Hs2qBhY{MHTb@XRERm4_lza5iPY`a zq>I+nAA-Mu$$F>xO+ne8pacvZEX{aa&x-ruaaHv08G+}9Mn$`%;C6i=jLTm>Rzie` ztfZ(6v|tnTIf(@b^W1pxkQc^ZU1oU0Un7%jKrhDX+#!7rj!;*xT)B;bG5}jx|orSg|CKmwcNSQgph%o!0ZsXk(({i)aOX3S z%F;u^&chL)-Uw8L%X`JCDaleLf7455VgNJpQUJZ!Ratq*YC$nYaB^&yxH_CHGXsMt zc0E6#goJOo&h3oUD8CJX%^Tx^1d;H3Y<$!051J*DP3KWw-$ToP{FBcuv<#oVOegh2 zgyB)Duv!DSJ#Tbp^`DgVP4J(<8YA(qe~!Aib-dfe_+GBK`9ml=Q&=@|86NTV6#TCt z-dTCePqN&>!M}j4AdxF*80Ff8B-H-h(7)F76iO|i4`AS#sR;>yiOsnGW{W2#Y zy6vx)x#$B<#;f3D$nfFPmS25EY^Puq$hz3WL*_EoV}frbaapaWzL1|9C8l`c&*6M7 zlhHE*=w#<=EfI#3@!N9W51$wXo#7^i^~N1sr^FiWjg5|)%x1+vg{YEbQ;2_E(m=?4 zsntTUSQG;vo8R`#mVw1lDB`9EMuG&u+!-%OmkpaCs$@V(lDury;b`G!+8`Un+>8HR zqEJxb{UeUFw$~j%?!BFYZ-U%U>b_!KatBh?c|Gw>%+hl=oDApBn~~MK z+{pmJ;zrGCm*=u=%F~CA{G!cH$k`(bL?uXGQ4#FAYuys|EQGu7y~*Zr0@|_{Q5bKU z8)9pb`+dj%e9kK(0ps^a-$wY))VKd*DmqX?K>w!?C8#nxRGR958U-D2rf}eX0RA`e z0me_73NuVXg-krtVd51zX0W(%6gFbiyA%%LAaROuO)5B1DjAyp3#U|o>CqQc&h@x@ zX6!O2!)e~@;r5iiY`v*?R5_rLblES2poPg{ew?sfu9OdCTy&mx@4>W?1QhPQZ3_}4k0=mpxx7m$SER|H?ybJ=O!3_SyLIhyC zd$w76mb~5$gySEpyK!pEN}_O;tIUTL&1+b)0KLf*V1{i)EP(u=o(Y{+BLjAbk4W{Y z^EkD-nVVl~9u6AEDopw!oqx19!2W)uswL}^cJxxk;~QLbbgb*vZ9#pviScxjM3cfr ze51Y$dT=-V$h{iboy2E}o*Mj@7sg2MOz82!=F9_$cdBIflnhEUpKGuzh7RZ=EmrFM z!UH2x{3uCY6Nmhey+pF8fN?ljXlewBGg~B&?!|NeYSae#Ny0|mzAwMQmKKVr2lH)k ztw_I=xkj~BqFL0uO|*IYI8M9tr0%wAWe4b3vLj63!IZH_)Y1wd13w%iYvI++1!CX` z`r8;{6ZB9*XdVZ6HgpgOj4n|JHor>b(IK3MKXeV*cJqJH@K7yuyT1p@4xy`~AiPn! z?~s+u+YynQx_Jy)rrZNhBwyss0u6(aPi9g>+zCUb#(JH^sdnImW`BR`nda~jd&T7Q zDNm$J3M%YyO+v^KU;BcobPEJF6Wc2j`Wy{0APXW-s;ihFXwf)n2`S-AtSvWKArbNv zoU*nA)Yai3?Ff8cA}P0aubM4XUF|GCUzj$KmwDq^Y>1 zhD=D_GuSsE0!WR3z^tcH<~+#w?!x`bZ`UxoC94q?=QV1TZsdpT5Nv_bPo{=7lCXtF zSM>v(OB6JvbT{o0|=9MULyA3U1W9BYwjr=zMHfKMh=yEGy_M29;{7cIPkZXcOxa8QxmHX1gi zMz-k5?zQ{wutCdi`?K{Iqj3N<_}kp^%wwa3o!hgsBcf?#zZqOX)pG|199JbG_X0Ap z>&}wIP|NiSR*=dqATT`U6xo_gK%2IhwSj*Un+kdyMYLkzk_WB__zAbSLUNSJc>C=>1K_-?*-Cz67gvSOAvwEFQX833nTTFbg z!A{>&n*cXZdeI7(PR()9(#Al~;Ou)oA@Y4Ko-wLrcSzuw%h}%7FD_J5zqF&5FVqe~ z5g(rbTSz}$?BdW7|Cg#P8im<^c2y9<-jAzhOs7M! z81emLpfdFB34Za7FO>hVf5nNF70fa+T9xUjub1?PL6c{VVlA76LOmyI!6tu$_DL(g zn|E*^*hHxC@&*1FSEM+{MI<1h%r9&kG#S|-FVWM`uQ=NEwywWv{Zuq9KNU2SA z4e*z3`;x=A@6cyPJL2bD_F&6GH0HB7iHku$=wM&8%0e#j7`u9o`5<>X@rPX2oA(1% zuToL+-`37%yr)pY$&b`?N2}E7$A8B$CENmmqKNv!Fa!AVOm>ZMjk-gB1c$F0C1gzn zAzV(!u)(On;sUX!Q6)<_m!wE8-`BztuP$N*gG-#Of`#VaR&7U+|F$?oX>H_?0)j(X_fr@Q0TZLMBQEIBt4peo&B3NVjSYq4&?Rs`gKyeOC z=!bKDZvv(d1^YpAiOj=Y-{U= zzG43(iY@#3fnYCQe>NlxwHvQg!#(Duy$(aUY(3n zOzOfF$9|Ak!`W*vmoF$#fr#Ew!m#4rp!cB2oE{mjvc2enrZks6%hIVAiPEM{Fn8C~ zA84865h}`CK<*j&B!}{Fc!YR^$ScAX2$bmwUMyXVnH}(HNEA4-h3jE4c@Vx&Q!GMu zFe-a;_2Ittof-oDlIZ|+_0fuRq*XXvo7>OS1jegZgMu#IU%VEb+tUjsQ~XHaQApoA zb*knFgI!i{B$9zRN|+SSE-IQ|C)nAkQL-3Rn)9bsDlMmZOUTp(9spNJr-$|;>Yurk z3WY96jy6ZRK0}(P1ZMcuveGQ?zCMYPR7-)G(~5y{#Rkj7EGnuD0*XPc5Yj1k1Ryd> znuOsX=EBJ-g*M#z12fz!DN^+uI_K`k?@zz7w|s&{@Q%Le9MS#N;+f2#+-^SlAgH+B1{$tNVOEZ!b(Ki?qmq4q?B+MpU<#H z!H5N)=L5qgR$%s5nuMy3biw={N25-!SNbXZ#N+H&8^tVaz{=v_V&}!o8U$!7B|v%L zF{P+1jDd2}|JMGhDPaACk=!cBjf&uOyW4-(%n z8`c&;xG3>uplvdmsK4e#!+q?vxE4WWgkw9bzJG%V3)7@#g6+-DX!&%_0em1`uPA!{ zBd7oxoQf>UUEir)VUHEnHyB{j%jxmkLF|70Ho0>T3X*jm^e>@p!{PaW%Ky2edoQ{r z@8rw0Y(0MWLM(QFT*tykGWyxZ#9H&da0j~g#7B9#jB~VzrNR^JRYXbgq=HV-fiiLm z@-p&$Jt%2>(x{mJ4Q;3~T8pSXpK^s2Qm-e5+rN$?b=s53IjR;2&)6(2m44(}FZ6^o9BonR zlPUMGo#U$ZX^A3$8V9x2$h^~tcnqW-FXKCDzSYp(?n3iCLEnc6pFbWoX#j%Q_O`^|xt`DxLC3$vU6Nmz2#aZ63Nt8LnDF zpR{zve%!>!B=%%kuV@y2L;|)}?0ei@>X&8yMk;|jcdU5(sf$MWGRO0^UkOu0D)-Zc zEE^gMUjQen?3a$%KyFB^7pwhUj&+ zS8&YIG;@5N27|Hl^9k29cW?=hJfl*YhnM{V7yU}5V1FVksV@15<+8wg?V6}=(P6Lh z%RF7ZkUPoHiY$fpRtAt@pWsmg5JhZnZf;h5`($7!p`%;BA|Zvo>O zPQvCpHSJ7)`7Ky{-59@1I-(62%g(Ih@7>8(dHR8L?+g7plyNHxu?@ipvhGecMr6%3 z>3Y_0k~2JV3t)_wzG7S5wb%ycmiYTc0ye6+WX4)=qz}HT=*IwbV`z>1(fm|>`x9H* z+H1Ype^5@R_C2eO!1C9dm_sg>8am7=N5Jq@WeUKYvw9|cA-lWEFvMtMyxFnz;^WK4V!Eh#{pLt|0QX;?aH+~tbk8GkPe$Xj(a1c zjCYvzOR?3+WQHNaN41?fI6-QoUZy3C)X&Co%)t++BvvLyoR(9X_i;|Z`M=?x+w8(5 zw7x}=o9@KTI308|2YfpC!@as2cQrBr-jx*zj|eOtAPmU{e%a545~TtL1O+WRg);9~ zAAr$iR!D>Vq<<+8{xLayVTgt%$ISWpe|}0Ma53N=#3?FJ^K*n%0hiXR|Hn%b{>32m zUoCv7$rJv)S`cug05Ele=ac%Rr;q}}A>ukfWeAOtdD?I^8fcS$?f#Cr@HBJ^9nig& z-F1>`%{3NZ$Hc{vayw+}Fdx3nEje>O1&i4h90LyL2?Xgc@kfD@Z`}wmXv?PM2s6iy7G`Ol(+x?W5ks)FEg1;f;an%i&(SbUO(aAsT zS7j9{B2qO(?105_yD_5KW<}D%^s|}lsM+uZ8AFPLi(dT}U@;k1;b0nrGQzpv^#Cj? zOLcBj`V+5%gO7QgN~Wc=@jBim6hMg|tbRWEoctbS@r>1;6w_$ zgZH!{jrgbX&D#Q#Ro^!|`plp$W+se^gwK)@oK1Vgp!n#AnLXB7DE<~E4t9%Wz^sLe zjVSrfbPZVH0F?Yr0M|88*R#`G44#26ED{C`gkD!$1-KzUeo;UHwXY%k-u~j$c*QgU z4I)+xsDkuh)+$%Gls5NOv{<~#$?oQwm&;d_xf>P6T)bzOKIx&MLxB-#OAXFx4MZAX z%Y}_`pr*93VYDoT`3FtCAM{lM4*?4$zLKAi(uY)ET^+7);W6rEsM7gpL4TZ_Fj>dY($dl9>87IBzrlX6cx)oI7PG92V6?C%RwM29v-;gcfE|H zEsE51=wf%jP&1$bQ>b$c2$rG^pu}{|fIkWF*(M*X-O?7!;_nj>2;5%*D<=8?EENjj zByQvf3OIv`K+-}$BPEvrByRwJBW%G!r*l$7slaBLkr^H&(0#m~Z||5Q)82rRR)wkC?2jw~u$Mi`8J-5SU-$m7O=w86Z@6e~6Y&kjZ z*RS*(C7l1l+*w6cp@w~48a5!CE`d#Vmq=|I0j0aUq>&CcT@orK0swSsH1-azUUy~%~oKH()3o9$5pwwo$~~n!>fIwWiPPJ0=^#} zo`+U2l$M_64U6#+Pd*kCTQo$(MPng+RY_M!-Ti{7P(<;c@xn_VY}|+#`WHvAx zR!`*eGs)g)C2oI`yq%TLmGjV&OFhJ+;PHI;H40ElT_B^2?@_)d`fC>whf zN?Vw+@%Nsp6uGg2%wsDr-kIB+*Z%J7eQM{9^@z5lI(D%Yl$ZA}5P5j9(<~6Cw1fS>9JQOX5m%oTPa`=D|4M`-mkv11-KVg;Hs^m5KCtV}ExvWEY-C zCZt@;_;g_prQ|l(G_4Ml)M0j}k8`O!+@v|qu<(waqLLkQgx1bFPRiD?zCc z1s&J_h=~2?M?`4kZxU&Cz|H&dsS8HM_k`!2oG z$oyi)>la&YR>DV+L`TNRul57VU`N%fi=(pmF=9Tvu=+L!&cniEhC<6^($?wzX8-3T z%oyM{yqBLgG~#Fdu|2rdZb+E&;H}d?OW-Z0q+d~%LVV6lChhDeCVuy=jQ%)N3PtW? zEoQL{n3@A7c2H-qpMSnmac#Y zrn*L2I%CnL$wDY07(2s?lsV?L-ivUu7FDNI&i2s78|R6dZ~Y!nRS6`^Xp!8R39f90 zpa$YZ9}T%0!O%Z1rx$fTi4yO0Cu=D9;Ztp>r{O6F!cR|VJOp<>=g3m>N!&27HSpP` zf)4vVi+6*L9aR+F01VCj?pQ1rN;*eo62KZn6zK z4t8)BA(`K_XfhmO))7VIy*o2}^O4kijf0cjawrCkDmV=5ZQW6lC9|3Mj8}}(u|o!D zYVCtRm3EsDR_(v65LCT32hM#nP##j;HDBiDphr#KYbLJio+L%tsTdi{*-b<4NbGK$ z1AA?7*dLL(2NU-@ZE`Lgmi4#xs*itT4Nea>* z+I`ZWd6Q{2yI|;*NIk7K^n5XK-1S|xm^j)8KkiNXL~ShzNy_>UQ?Z~U0R~8Lpk=Rd z6x%ipQ(m+^ds}FjN^UZ*|4$BM6^qUwMl?{b+L$DpjZ0JJ6*%Y2$OE;Nl5(2>e$Jh; zUmto`E&GOab==I_O1|XA&MAOt(sgqS^Lv#P5jTAiL z@C+wwW#yR$mX&J8OWrH$Rm|bHu4o!M3l_&2N$vL zH@UvKGtd#fIcw>~73K?Fi9xFv>Ul*GQENAzgZ)|4W`akzMq%T5r|=K8;!cs*WfsNx z@K2yt!uhc;h70)}#Sd}L8#1jK?tRw#M`r}=}4Q$!Y1 z+f_k0+x>bOGOYz8G`&LS0I=Hlc?`LqJ>WZ%OXEV5Kh2rz%7p%BxZ2xB=oX^@s?l^e z*C1Fog5}8g7!#yANX>gHHkgJq6j%<=u15lYTRmYWhSy?#>yIn==?j8pBt57Tf?A7&!$#=fX5o1pkKu(*8G z^Nt9>h&U8B-`6oz6w-t)I4NP;Y)~=_pYtiHZ&;GSnZ|P5A#AV8NF$^fx=wX|L^_sR zf9=`T`4b~w2$vIQkC`7E>Qu+z`~PJ8vn5r9pfVj1}-U`Vw!;_16y_y%tW7 z$E~?UQHF^z-O+~CK8dL_!Dt`UzSq{yfv40s{>9)pXjax|W}bZ6hJYlT}# znlnMK*PL#c8%}b+K~O^oOHkyk=y_SAm#Ur8*@%0$9LYhw$ci;zTK==P`rCzh;>-mi zgB$`6Hk*V`9~waSV}Bk0PNBf{mR>&x8ULx45rU`1zrv3}*URKZUfF-YkmeKK7-jQLF)HiDJbWo{G^M>b@d zf<@d5?%?uq)TG2z^bGvp0Tqcv*z?*@g2(qX{y7^0+4oY#A8+;j8Lka)4>2Z6HDo(3 zD12}N*UUbn}<~5Tz^gHT+C%15>PIe0jmwgQHZw>E|md5U9FZQ9x6oy zE42RANt>H8JExH3aX<{-V&Aw8=y8#&R)E?owWwDf^F~{REgwn=)?T$uEBiPb9XQ!n zAXbyJxYtPu`^L_Ba@0>Tu6Dl_+)2-~KxD=Ew}qR}Hpbh*o6mXAFuzebvJtt+x%p)i zh6W?pXN3hjVFFD@8%1 zXq`cP^lu8IkbOz=0tk#R-Xu|}$ibII5>p&4{9MZBks6_;TtTm-TeZPA0#i;kS@rO? zx=KAY2Rt4`H$>Xvs2erjdI87`^r0M-ppj;0USx_G%xb9A{AqISb=N@;dfj@IbU{I} zo20xS9_K3{x_f$lpI-M2?2yzC11`uJ#%0tTa?*G}HDn8+XG;v}>;x(GE|O2SRv)p> z*NZ>GpXi;K{UrO9wiKo#%B0hQ6B&iv5ylaqTn#duQ@D-DeSJgWiqQAcgX_I07KG|B zZj%Vic8-ogt`us6KQXF`FJ?O}=DUkJ8z?slqcCoAxBzQED`UfD+{EM=sgvH|8m)6p zybcFb$0u3DFjjtT3=$~1K!@7 zJ3UwpyoT+t)p<9N&70krl+xiNnSA zItcze5d#xFNmh=ix4(ou*e&`1(x330+aKRFj_%q6aeZ@@@I03efa1kLS187A3Oawg z=tLwdz*jw=z#_f2;9?t5@GhjJ!utA1=2q@ijxgY1^a2E0L4!3mr5rB&)#~AK&SYi) zc*O-zgR4p$G6{ER%5(4s3AbQp{C^ByC z48o=<9H!xYnm@Hp8mJ<2A}8HSrE?Y^YziknYe^#q@7}cyfsFjlK8^`M)L(eNFlh-0 z|8#L>L?&^oj9R8}5)Qh}fLP*vUPne+G4)MZw{&l6;63MC^A@wZ^ed2Oq)bn{z(CEN zoURc0us*2Jp*Ii}p4evC^wZ^e15cqx%~Z+;u_CJD7O3k@ z*VluECWfc&`#S~iD0-}e!)s^uxV3FuxflJ?3ebTY{E0Fc52@}0x_+?Z8SnbHaEQz{aWh4kgPWvRIk*t zd%fBbp%Fq&Y;_EOlpDg40F$r+I*!r7JASuNDND6bV zX8!?)C5@QhBPdze)4YZ{CtzN9OTLi;^4#E}0a61E8}`L`5ZQftRN296BEMv4yrUc1 z7?fU*ZIcltRLSr*ttjf`Ku?KBQiqLC_i2(K*Re=SZ2v- zDh9l!Cu0;`Y(_Ky!Tp{;nD;nTpQyoAVAaGrw>V*Y3FOkHn%Rax5DOxay3|=H@LlkG zz`20JZ)NVX4gu-t9$MCGTl;oi)9*eBxlKG0GC zdpydNEVYAN%Cz1<1x)nR7<$X1qZ1+ zCfWsnOWyTdz5FAhC-ZeD(zg^;d3X*-$XJW)HxBH)RRWu{Q)lXIB}w!vo!=G=nF%EY zK6%qBFiK}5l)T38*O@86!C>yqW7!pBJ`*p2-VX7LV_)r{cqJmuK{S{okR zv|zPKwjp~jEo1}eq=e5o%LEEGT`ruDzoznIM2~_Y{0h`qBB=CkHvD1M)_TJh6p?6Q zV$`cC1Z??iU3C};aj#AyJDxcD ziPMfQg%c(uN92qFZIV^G!7%%QdONDZ!;FSNHQgP0=4*dgBFlTcz|ueMaQyrG0$Z{Y z4zE@8Ye5o`E82ug&leBqu*8a|K8_rH`0xR2hB)C;ZG-=7U@KpKzn0LB2^+fz8xL%Yz;YYskd=bm&^qhXRw3%tv@Zo#U0h<|H zL`d;eU-K}9ip@r{09}F>gzkl@QfHKp8x2J5aX_%6v;U!omP+Xg$bCu%oQs7& zo^tVQcP*OTH`&GpKUwI-V*SDhU;&TREYbLU8maCUORLoQ(JbCwtnLN2gM@C71%rGX z__?zW?zmN6o41PJg6582UmKo$VmzS6fl0;*AVc8Vnz=rx`mCe}66Tryhpz%;#DEe6 z2!s^3y~$0{DLNm}PB6;e3h$*xQm`k^!iR`3b4)7T##16r+ua=F-px0F;=NzG_PPG8 zvUewGXao^8b_u z{9iMNlB8$^P|b4}&CURs<1KM!ZJW)PA+tBLCG&p6<~K*GKkx^*^QZiU;sz*i0M`^n zLy=y)JyE8nf3!(%H}knGW%r9iU7W<(^{nBE9r)(p2PO9WA9lYz5Bpsr%=d0(l<=;( z$Tq8-#C9l481(s?`(#3MN9S5U7Wx1>0LT?413fp3g=e4eGCmWF0K|#oTn^|Dol%Jy z)QFKe{83f?`zz`9or8rzjZxXl1uG|h2Ih*d8?O~77+Di3_*uVLeQ}Xjc~9^YQ5Amo z1^#2+Q3i3{!zi6%q(zxeR?8lgZK~tc-SQ8HSTA4oFI8Aa)P(8C1Lw&(*|H727&*HQ zRUL*?u|Ua~95ZsHxMlcijuUP7=i2(8=)%N|4@O1_xsFMy9rM_s=BwF1X17!RMHzW5 z!YGBDc1LaDUe0ZM^wE&+!0mV&n=%@S(*#wOB7N#Gh^)orQSv&GJ&hTH`7ZDi&Xka=2M#>YB>_Urk-1y2%J8B|L$-`ZS$eX zz39l`pes=9u+l!S9iDoemCs13=^F$3>*>gckU{b`?pyD8K2*=gNm_bF_&Qm+k6J`; z6P_>M)0p*QTL)c`?e<&0Sr=O^FCQPvr1^l%@AUia;?KqAAkTJh`aqAXY)Uq-JngER zKKiZ(#>d~Dd#h{wRPI~n+Zdlg@FKHKh?nRW(#H>Pp`8Onx7@OVofFR%X`w`Q^Y7x46_r*6ByNcwPaSL#u|F1Ry-Ep4ajj|RuYK&y53&QKc3&PkxHx9WGue=& zWb$Tg8l%J{q&i%*|M9=?BoZG+GynJ?Q_fe-{;~-4#GW|enpNQs;MC6{SU~({f;1DWYqK z)wF1^j|vF8@Y~PE^={~u&F4mhBV~)@fz10iH7y<|7NRW@#!iAO0O1-u4U15qqb@a{ z*}YKKb@K;^%JTR+g4?GVkQ%=)u>3A4AgEkFTU-Dyx6oaiTsiiY&{iyog@UwB08{}? znex^~*&7=GPzPA2$=5~=Li0lYwGCSc%u#tBhe4_m%f~iN#2}!}qLAFA9mRdFRi^iLE)U1o4?u@EiuyjO3uvw_W^3(9amykZU<8Y6Uj|rxj}ZNLTdwy*`E0X)S=yUN_f2U zhs3ZBgh)}{Z3Z+*-X`d*d5nf@$zl@HWb5N>4`V8vxBr!17&dn>7w~sd7kkb2if9uA zJepa)z+Y6gT$wPvuntQ495WVc{^)Lp0Ksv1En|PckwY}D%5-;jt!VXNln-sp!g?ZQ zj{KnJ(t*NRRYIHn^?c_T;C*0X&aFTE$#s*S_TuE5qrK79@>+Q+RG!_7J?7r?kN|#^ zUKS(&#|W*d?L0q4y^*fI9g~O?4>_Ey{$vJn^Anr|sZoxDWPSEq8nr->b=*>NH3b0T zG;NTwBnfOZS>Jl7jNxQ9(?q$W_42!N-F4SgTqX}ODIirVe|Bn9#}!$p?g5Wnr&e}K zlAz5sQClOWu)RTp$yAyMK(WAf4cG5jt5z5!=pD2OL=7!j+992du-t-=7 z_BIWROO`RHIoL?RiI5s9{dP{Li)u#RvY@Gw3Zm5UblE>VLb-`nk})V`*E7dtm>{dD ztuY}@lF@odK?=bo$iMq&KG;j40W(N){Nu6NUsu{^mE`^o%?mQ4DQs;c!*M=+vIbBssxfjd8Zvq^UKP?s zWIcS$$Md?DSswQZo`$UBi}{vaQ0?1EB2gD%p=y^KJiuB;yvgODYCc_sbgMDK<_hIK ziG4z={Z7Tmq~;s;eCT80sbqrA1eC=}_7K^UEj2DwDO@{iL%&=jM3h!hPA+e=%N*i~ zaQ_TvE+#le0C^~jY4YfC=2Pbuff(bi4_Mx0-)NM&Lt5!1H+%GYj}_KR@(S!YG7mTh z``L@YQ$AAAHVC@g;z83&h%>GjZ~vXWpYQ4g#QALv`z3+OLAxq$mxU?A@r&RG?r1-u z5Aahzj2eQ<7C%wTNGDxv09N1TL%gDws+ zYrn5*Z>w-wvhl8{M_xd6U(|%N12xS(!@NGnswUctMWJ4#4(t3?I?-FK!H;dOGfJ27 z&J5sau8t1}M9mIdvxLFB?d1?avCio^J{~CU6FEgqQoxEf^?6A2)^u?YBF9x0e^kvQ z%tU!)bgbn0`D>B|N%paxCP(_1Gm>(a_;7Y|j@DE8o0WQCv-zP--EJ?`V`?VE#mimm z%~j9Um1nrda#R_n{h*-~{!V8sJSTpIyPETt4VqM#m_I}<>Z?_W-@LzV?%VWKy1v1A z33q$2q<3*t|KjkrWoRS`oN9Ut%=w>d414)a?Den{sD;xDLP*x_y3)3yq1@*AGKaG6(ZQ9$&brhhIck@7Kv8h4z?2ac1&NBCv-7J>MUZYIglNFJVMY zS#(|hLa6lmPq>*~tw2mh3zu_MWmD%My+|aX_Pf84a!1dE$K8;yR^5fH0X#j5LFkI@ ze{Tc_t8ouCwy39nqhJA0c;3O8T-cpcz@;kM|_Q-u%T<1b+1U z(x{b&`v6Go<1G;BgsKn96~ZC!tTEeGE%KKwMHvbNPhJ%ExkHq59^5&atZtRqC;UN^ z3&{ngi4MVf&=ERGfQ5ROEV1ySb)I>R9V@vGEUA#^f)+-WA3O_i?a9b0MNBMx~0*j!4|R1|WKC?m3|P)=y;4Ck>02~vh) z;OCU_EHm2n`?-&=t6&g@8={7ojHrUgeuYVE^;%Adqn5awuE@(GfTyCUwAPR~If7AA z3p!PHjZgQpWeLbJCg2D$pKF|s8*1^Q!FqXV*F%&l)X;D_fu##lFXh7@HierW$Jn%e zAHUb{&tju-iA{9R1r{#o<-}_{Xnp8XsS7fLpx(T0vW)r0SzV?r@Rw^@^q~Nua}G-Q zO$saYPzf4?WJSz|x$p~YbS>j;Nkz8xpvX)Y?T%(qs8sU8ROs_Znc_i$Lrp!9@=h9{ zq^kM;4^IAM>>%*)PDJ=ZIsJr>Qyo0URxG8}?gPE7bdYEUD{QQn%EXiJ8fdvjJ|8u50$pTk%w&PZfB$|9+>MF)x4C@J- z#iurv(pkCGfA&nzkzG64<1G@P9}lp_C?|(NW8B zeS-Re>qV{343$mOhRqixG&%xeijA+!mM`32UCuW8QnH66x<&W-Kt!XgAMK6OR<|-OgEsjUGld_UI zqz1a?xG^V`!d=Ck`K{V`ZBKjVS^-#~Ss;p46Z6^D!u;&SD@yQJ@(q-;JA(EUmxS2?7E9z>UyFE)&^u4u~9b0Hb)9+ zZyq4Dzy(X=2;{0P6Y-z$v&nb3R9${GAUh@6w%DU#YE(iyf{D?fZ?u&jF`~@_frtl^ z2#QE)Lkl!IlK7m$qHXgj>(&9Wxiu&d=JlJ z0(}c65Qes@vcZ#WROh*{BOt`0Y?0J}(bB}%urabjqj)Exb$Idd{0;PsrfiH=yuHzs z+%Dwg7C~Tw`k?nhB}NBlM-8+AmIH`QA1}Mo(FKr{J%7gz)oPofR-`|nj%o(-%&1-w zs2f_f|B?bkmW0(7g6iAJP~+E1xyC{}qinwUTP|1ilsu7toeQ!=hvn^un@)T8;AC#s zb~yArk89xys6`ir1A*-zT9CU~?i?ZtJ117^A2#5Lf5e|uL_vGfhA7rRC`Ln09fxma zdLs_VoU91~CnL3z`oVeN_GQs&05mzwGt@N7Jd?+WF#n=+!~;`<1aG)u0O4^0QLjpB zlQvsoWWvo%38c)zqFmFVKJ7*1>qp|we2@)~GYRZ}7Qi!EglmLc@2KG~>g%o7l?&>} zAfW)#Nw!C-An><{(#Jh9i-JhBgvhoKgjtx)f3jCW zV>^=T@_-QcYvvFvu)vdKHx2wjc>4VOJxVu(iggXkMD?qV!^J3L%BiB;!im5wUEbvT z4RDGq_qHK{2z2GO?IO6s5{0L9JG9Xi?+cxL?%wlHFXVNOo!QjPK`uHv6HOId3?WL+ zkX(K$cdb3~jdC*)m4#@4&Hu222=nd&ivi*<(wSyhDB;PrXw{p%e%wzesPb*+ry@l; z+$K{e8)aD`n3%i=L=p{yjmrptGL^x3WZT7(W`K3*cYQ_Ol+jy>r+l`<|2J~!*dSvc|UuE$IhHLN-s zg5-eU!pTCdwLjqhUXT|$kIx6BF-)_TeX7EdmFv*(AXVx0!<*GEg5$^~rzHLHy{#Uh zGO#{vk!ya+VOaOWcTbw3dnygwC8XcN!wzcdKr}sTrY>r?zMh<|RzbJbWd&c0rkqpM zo3QOr!2oP_^rQqQSh#~GD?ETJKjOS>#dw%U>-y!#B-Mb!>55E=VT`AcOny{cd~48e zA#Yp0wc2$w^Dh-f+YaFEEh#;?XvG`IsEz=tjHaz2<0l3u1X(EQPZpy8Jth#e^xrE{ z#NtM50wg=^e_R9f{vuCqK!;od77^4$|EXK{{@wV`auG>vw%E;-4R3XBV!C{0F`Czl z%z*%rp|Az>3SFG^n)AUGkh1Eq^(;P;R(n2o!dv+RWRNVzV_$;&_>%HXy>)k6|8C&v zHeN5;ZETv|Yb~?(a8TY@lr(5%eo%8BTSQ!-(qmuGM)B=^wq2$#+r=G8ZxamP#(rp0 zfFbbe88t_B6fy$h(9BWX)6WtGT}8Ecl}#1+S!Ar~_jB~P#}<3dtSRhJ$)PFemGx^y zXV4jgTgjvtdHz*DrOE816?;dK`6|X*iJrgxZ#FhtunH=c@TFO&r7zNv*Q_KZ8>Y3? zVwOBH{7Py~ikJnLJ<+h@SS_8hW!&T&amWBy5hYq#DG>|wFVd%w6o^h?-Y&RciBJ@X zxNzjcyRkB2^BsT1LI=CSH;Vm8g-Sv7gFKU&FmI0=8nQozTXo=>1PDg@q1#ZA7@cG5 zv;LNg5&n#uQmU7Cg;^sms^id$W4`7B`jfZ0)-mU@X*P4_UV74}R6J2sn-iDRy%En0 zdGqMl_CjPqCrj$vfoV4j!Gy1kq*=!i&Dg^p1%|ZTbi|ZJGI+vhrA?YYq7_kVz(2C% z;CVJ^nElw}xiHp#hJ+fL9k$Aq(om9d_ehSTYTG8K77RpIww;^^LB2|mJ{O!FCURk- zXOCWuA}%&SJ4>>ZZ^qoFB1lM)ot@dG=KJ#ju7xIKeEIU^K5(7AH-tiTs0p{vHn85C zjn$GXy;he&;q{2d9Q|nY80!ltWAJOmU?c$Xn%BN4W;recTj2v4O(r1!U zy1QP65_urj*qIveyVyFp_G+CYVF;r=K6**U7gv0B-xzC6{&=m2Q#$i2;&U(<7oQwH zYsUAx^rzg!a9gNClKBJ{-&)`R>C0CB23y@a zaaN>Yx4^fA%q~3?k&2QoAwdwZ9Myj!D0_uXH;4TNSeVRh6aCznUBiTS(7& z4xCXd;a<)k69xw()rHEMTL913`vzC?ySj&^LJkB?auw6{mUvc_cQc=P+{;vs_T^yG zL-y;FgU)o8dK1U|uZ08lV0dRV5>s0#beYdS5rJx<;T(<>0~nH!Ymp?rrZByynuP{K zDKy6vV}Z6AGZ`aF4H~K(RUJ*j=C7r-NHt``#xreXL}_7!RB7gc0%-vX8F@Ly{B zh7J4Q4yZ-V*{s-hME|}TpGVsuP{VFCORBlVudlA$!U@Ea^}8>XMigs(vQrwOL3=alur~weIs7?oOnA!WXV6Ku0_IYTy>9O78zqmt$ef(GDtW`QQuIP$jri1}t zG&Te=l31Q6-Mzj__Q)&|y>Xd;@*DiBRACfAK{@% zT*2R3O27mvsI1NnrCjOm+3tQ5oI!93tSH^R;eh#c;&!Aol9lZbwzDFDl3DfIK6l;& zc9&nw0xCKSy@(X2Cp*)vKh*{Ybjt04$q5*O0XTfM*reOa7eJLL0bgtjjJ27q*@q7i z6jw8Egr5z~VJ0VM8rR4og~{PWVf_65{KKU#;W&kYHAj@E0W#u1Kkt;NcXy-{cySy^ z>T_5VcXGY`_iPJR+XO9ErCpN}Gcvr7{>}hnW$U6z3(h78NT>$Sfwtl?DR(>8q-NFr zVk@PDgV7b&0=IF~>EHDB;|~{-LeBB44qETI$xV}yqu&kOXM27Z*1nnsz9Ie4R}oJ* z5%BZ*QJ$qv0RgmJ(*329#S}_r+8o7^)DizQej}BauJd5T$w6!?U`74ZbxuhvP~1Q{ zC9Mh8R8Lhp)m^hmLE`1KW zkR$2%^FIemM0TFmR^LQS??18v8Yq!7BZE!D6OmP>!0xgPIcPt!&I%_ub=kJ{{^n(4WGMF=kUYgZ6h(WhrkN7nVc!`c6{lfY=>zsoh zjj_7U7|UDUA7+qO$8sMH^lN+k$iE%F?gasvJ8|x@KQGwWJHL4EFK(eIvj}oJbrM~H zEwJ8s$rq4!eoLLxqECiA)3>WEy~jyNz~F$djEs!h`HNV-jOE}4Sx)f6?%w&Rx?rZ#9r32K70sy zA`5+&3j+4?^Uc8JUKa_Tr1$9vUQ?>yggTi1fxn;8IuE0*Evu`@&$!t3exp|MqbO^E zez>zGt$VEgR0kGy*S;oq*$G%?Ny9NAdGS%22*S-1_Dg77$e5C zL69bJ1X8B-fP)P;qks?{oU~zcQag&Dav-;E@Cl4#fzm4F6A;JCOO5lm0Gx(`$8P#< z0ne=z3I^WyUEs$8Ij`C^AfbVYSrEqnVhDy+{;#`MK-E)a2k_pzqTU`^{HDU$ibRWM z+snIqfs(7TVCFX4t3}tPE&S^h#v=}bi;fKsKiIi*513kpaJ{pz@gHrAYv9;nfG()T=5VEpa z##%|6QeOy~n{=rglk?xne@aw#Dq$U^R$#37Q zrK4G_3#AyT+~waWM5^9CF&w7GBvKszlWeiJLHKe|@zTglB9(E)=kF@(+Vt0tW_v3e zVhUgd;f&yNmBVG}bT?TNfeNwgmz@p=bJeHG1v1(~iDwAR;mJ~u1*^##ZZ0$7jQUFO zx8)FKAD1nFf9!e`l*-bP5xM98dR4U}#uUc^cT`J2@x*-)2*EDO#Mpr5&OAftmEvj| zs$-?CKYMm5x=z$XIO7)FP4 zFnQ#~E!ZxAc0vah8ZmPyj1A&tX(s1oV15`I6&iBK*Dh&<%9HnlT)&?j1-LO-}7WJi?> zL0zxY_}xUU0ANhlO&Q!z71J0&+Ec&v$K*d=3;-WPqyPDIyueg1a0r(tv!K>1(Z|G7 zOZG7_0%eh~%Ut?0$7Qm0i|jc&AlWK+8vjT%Cj$d) zOCQy2*WrKJ62X{&pnWnEEdySBs^Ir?GtUn9ZWJI^e>*+_eTsHWS0B-5I8nMa5Lmbj zXa{Fdbr30L9W69GtTsMlQ+4^go*LU8q8{jz-6^b{wgn^_Mt(^&8Tw7zUoH*4-EnH| zOLq4#!x=URGzBK!yJkl9)dMj;$kEazmB{u?D3v z)QvL32trzzIxMoek@ed0-5Grh^kNC;0}4JHSadPKSAIx8e$XR@u5B3@RiKDH|Mz zgHlj`59kt`G8neJVC*eVq8ob?USg`-vG?nJtEXlW9_@!w_VhLeGGoM7=hGe0kHBsV zma6=hJY;{vxm>Amaip?P$6D^o2lHT}7HA&a52V@ut?nbc3Yg(9p8G?@y+d;ncAAgB zu@Q}wfcwk{J0!NYeS1J?NT<{!QV0AWJl~toA3uHt^UD+; zt}=j;4f#C0F1wpArTl6LFvI+$ZrGs7Yp=0h+<-NCpY&Wea&SvOJ%h(6Ep>gq8)dx) z_+aDX3X$8SJdtCpmk0*vDWH~8OrM*&^Jd9-Grvnr!xSBx?tU~de2-W+c!RN3 zV8Rx-sy6R?PS*?Zdx2~TG{MLkb)o?o_j2IBaq%L%UYuFUk{~T6Rs*9SkM_$%-8TyY@>E ztV|d=92rlu1anWqNRBqEG;iXW7zJ^g(fW}VVg3OD`+P3oZ|7f7V_phv-4{kyNm`Sd z+9AI804<=ufm%hD4QwXK(<-RQIn<*(?a@kwTxJ{&`#r)cS*>}RoN~9mi2pupvkeD_ z+WC7sp1o)3(nb*ADhy(-kCFcauWVyOtNyRn#{=?T1Jw5;IMq_mi-{DU|EJ0^rvd|7 z{4G`dp3= zOG~n?9RJy_bZ#wuW>{AuwOX;*8)Rp7v=QBI;!+`FP542Hvrst*v;!|IFFioV`kM5wHKf z-ua)B$<%Vcu2IW%>ZDh`X#Ma1lxhB4oUC3b%~tOua@fqSR@S z1TvN&`O=IAp0*rcP91sBId-g83EGq^{}YiGtw6B6x14cEni}=}2syTH^jz))uJeAf{quDlv|+beg@pouuo7t$3gjIe zS}81OF1RCq%jUdK+jbqnyC2lWm0m+%&g}qQ5QafLfDty>#L)k{oO0B5hbq(Z_k>Jz z`{8oypKkJD>OgeZV~zApK4H*gY;t^wZq7{f^zX9e9q8}iH-S=82fe%`KnhEYfO_;m z43x~RAgI+OPw6rH>wuR|$Kk;DSFHMPCfYlYw8JA4`+!Znpus~e?nd!mq~T-K0+(Jj za*#=6_;EoYu2oyJi@AJ4Mx67~XtAy(;W2PB9^SAd`9U@GUfQAIEP?#@0zD4Vu-0zm+vbG0(B^cx7Qc}Fal>8vk6So2;tMK8zdz5^cHmG4sidiTnSF7exT&y( zZYOm&Rt{LMT!PZ`fmaOxy_*q*39turQgkxU8IEt^bUwFZ83iiKG@t1}vYVed)nE(l zp!6)QG}0?JZ3&=?MsLMIe71&s0&|9xDV{503j;+Qj9D^V?Ftk zqrs+FHTo5O>CMD$<93Bod#EJX%ho$VP1T`@^>^de-|Ky|z9{>@j^F^D2x!cUJa_%&BEGB4fUIR~JA*t7wpWK=i z$QMAl3Phg1g+M3A{pDT1i+akm=ZQRqjw+HAcip*xrS%Wv#*n@+niDIJB9IDy6w>q2 zS>ivwU!SQR-?VCwq_xzFLsmWlFz{61($%AjO~@+nVczMcti8* z{Jqg?2%xW2ht6pTja4i)4pD~VcfP5kC}|a>oG;$NGpgbBR;eyz(SUUihlA&Nny|)r z4cX`}@5=+j`uJZEt2W&&7u$fpnz5213Yb8a?cB5Y!p{WD8BbEHJ#^z2#az#BUiO&4 zKVr{Ec*Lpdhw+x1JrgdU!~bAE3{!dh!LFK4N$d{1NSd8A4(80{a%j=`PV}rZES3PZT*Z%3>O%G08GTU6SFofJ4|2X>;BRRl-~Oi z%%fhmYG@(8x~h7mMPu6$>$&#k0CnyPNgpkye~F$k8eQ$gX8H`K`>zAuB)^dugf5jQ zwwT#y2hFq0JqE3NXXBAV$&}O1SROamM;7RZ_H<-YPDAU_a>5GndTWM7fyC-YpXloS)Pfm_@u0aY=D}5T z5yjxkN`S9~O;d*NX7;8r8A-|#Gb%b=PT+%}xUQb!_z((alvzEtb zB=y~sOoX>|lI$VTH|LvgLp+(T_AZlM+bh}&VjFDtXc@=BjE6U0RY92y9z0v3efZ zcE5NGu2rMgz%t%;5lE|iZQ0xia}68=>Q;0(4yd8frR5cEnIn| zICny`ix5lTZNvZtj}M3GJ>`p=U?z-5dvZCEI7aoNQ|y!w+GnbJpr^NoSP__s13Kw2 zQ_Z^Bzz1jr@UH)XK1$L#gi?ipkRR_O`3C_PLa6!Yemrb zCb+%*-OEmLz{KZ+Ln0Tw+6RQT5j1#k6Fl5rDoYEUy{hr77 zrKvn3f}Z>lWnYXa9UHeB=VgX=LMly|bzULzRGqg$@i)rvSN9-c!BLh_lB?s|P@fBc zw*62HmPC+FpZHq9cQIi^&@IqV6FDnB_jtq*wYKIM7Dv8L4ZU6% z(O{e5k^y7siDNw1R3b?0ocg~2iL;^ei(JvglU%UGoU>AWk3bdxXFZ@>{h423^JpsV zI4H+VdT?kQKDvy=t+j+Nlv+OiBiW?>wPT~_f}qtvlRSDxvzt4hwb%87qWcy1XYqF* z=S6=ifkTK96=C#(ZmG&WM^!CO2&jduWz<3&Z6DEQhAgJL* zp1T4ML|pb-mIr5ja+4}jfCeW)dgSYZ^;uIebYj6OE?pH?!VkIF@#d-y+wcX-?)<%3 z>hb2=Q_XfpDnTFQiP3ziWV9FB6?o&AFS3d6dif~8bl<|-#8tiu*j1Sr?!0xtDmK2U zEKeG+_$YQFV3@1DlYmbXPoGGelAhYFW4U0+GU4?Jy8Jv6K%jg^69YKb&TdJjQ(Exh z950xct_o3`|7Nb!-5j`}qwGrRw(%$FpH+JH4c^Kd)xl;Gxtm^5oUmIbU4Kx4Q??$T zKY*&iU~leu8G{n&Qg~l z<1}VKlQtomDPH09ZGA!;DifbQli`uZSqicDL%k2@)^pjiqS1JQkCOSWScE3QaPZ4E zvGboyIpXJM)WcODHF}FL;^fTCmf`%_!uX6FE`2kzwSNP3L#@A+iM?8T90Cb47ZG({ zVlzXiDweH|l zxN40e4SfjzSF7kg!FHm-Sy66Q9@+5LHx0eh;-=2M%y-F&Rnv zXD+`6_|*ujqb{!AeQF&A(qYGwp2FCWCIU0{RbPBr#G4Zind! zcuV%6DwytV818+iC7^h|Ee^C`h0XF-4ZL$=_50pRi-jmy&7L@M3cPFUS z>7q^_r=RfFIvztR~Z6NCy`QJ5n{NHO&EXWAc2f+3H zzvuJ*AFE=appqly!RR($!lmtix&V4a09rK8w)3`OsyT&RdsdZKIq#_fl~FZOv%EYt z%z3`)COe@g!w&r{D z*FrV>TgAxc9lzr5>m&dXA}GJ{kMMfwW2mDIgkGIvZ}O|PW4mE742||J_+2)*3WhR@ zV^fOTL6aFEzyLI^63od)JMddc228^N>`z9f_oJm$q4>Xs>!;c|;1DmasAz|c-3LxT zzuBHIvUaWClH`~C$l!%0Yn_70=`C5r8wmMFRgoN*afSIz~aCQSQwj7+vPyGzfnx-b(h56WD?rB8I07*f^n+e9h#4c!w@7~3f zJ&{4k-wzIBE`X54)!?k+ix>8fQ5K73W`BfwGjZ}55Z?eP_2ywAg)>B`u2Weg1Lth^ ztom+=0O9TjAYu2_qUO-Uwm4TWoVb-qf79Y8Uha=GOB80+sJ;8Z1p)7=?0u^ko7 zDr>0yp?(l>&w~W_{uERHiN-(}0pV2>7!J0Pcv?LCn4&k)X)P&9<8itbom%@C;G{JA zQi6nDA>p~4BTOH4geBBCB&=tRLpSCcs9?%Ie_mN!X0*YyF?Fl{@#D=wMMMDLOsYqf z)Vfw>{Ja22Ql`v->2IE!a};xILhixx3%*3OBALwb*0)36n)fYS^*=={k+W*Jhp%&N z!#`ma?OSEbCc(9?j@Kr7G)mRWMMNpxzayV4O$9TDFIsUM;xV5Ckq>C)HU^YS3Ik}yXW4vy? zW`5rbc%eY(EW#>8v9_?XSzUm)y;iFdb- zG{Rj8q-ra^XQEUz1crE^>9{ybOy*W6UJI(Xi|&i+C6b6s>93y-jzmoH! zf`j1ivyjA3HvpZv9m_SW28I`J0GfMKbYwHTjis3ws2%MrgC;+&L1@ZG`V{j6_L|b{ z<3lDgz7%(-x44!H{6`TMK*(1vX`K6Pf$$)g(Pq`KP+S$_mH|pdS$8Yz>$%T=5a|bg zI67#I?!DK~fyh?tGPKZm1vd)Y504T{VLO(FU4-&`qxW=p0~t$|{JOO0$h(csI`OVa z-vuaY3`htTs?-QclM~LdU_nsRSAYl6g83<1Nmd1P*CwIp;oEwFGk0K%Uy?Depb&Zm1ZqC4@#0VkN~U-qGlOSmai<8y5IKEEZsAiR^9}jR>ja;F z_4m!Q6VQyT7~E0Qh6^ao3GU%gMR}tDkm$mPJzsJ5r~2d_r@GQyHae30XT8ByRqxbo zs0?9|psH5whmzG(#l(b*f7gFmUCRZsTHW;0*k{i!bPw-~a(rw;H6#sTlj2O_NyO?H zK3KJdj}CV|gM?c0dKJC3npHjV*=mW@Hq1BXn77%p66qfGe=T}X-t5qEY zGUXBBT?+};L-H2`tY^Q8=tb!0R!%64s-7^iQ3hZKTavCd`ugK}t%R+?b!E?2wmBzB zbvrxyw4;8f;j8hY1%=X=siYrR#KC@=z62av0Im^+tz7_Yab4hMI~^0+E#`YJ&_cZb zolQgG_%OA)p-^y#5Fugz>0$1jmY&q+1pfiWI}8Sd54wB$rYNXPgvl`%Z7IJ`NQit= z!9}sNPm|G#H$Nlp3hZ3b?_bcr&`-ta*EfLJKlp~nY`1Fo0s(60ZOQw9wY-`KUFzj? z*37pp_5eh~0QPjHL3xpy5k0^YrN;pwxaD|Bzj6cfwCTSk}cI|`w0kBLa_*2R1AodlEExo8t zC%;o*TabCSe1f%h4iBHX@^^LD&tM6XbMau6LwF-o%NX|L z#g?RU03T@H(=xDRcr$@rvBZ#8Z?spKD_}&Otm!Mo3~+6(sbB+d4RFieZVWbF8M0w< z+io2LcyU2qK{0(G<>`X2&||RH$qxJoFrlgV=Y0(|dyqt5?*=$(Fkf9i5HL*@`2t`l ziT6*ljl7V}$h~rUx%~A^`g3;@e254XQ~jPy1Ym5LZ-;f@s{cl&5Xh_`d@-A3!Oe-^Jb&zsnIg_fSwP%syn(y9s=U9S^Y4V5be4rC`8{2J)dJI# zD8z^t?RD-)K$Jv?1%(90o03Y2mhq!ALs09nM<6DqF9kmI6GeE9z$81VwKLn`hrMb||@kjD|5gfbj=M3o9Cg+owyHR?IRN>8dUuYs>1^x*#lD zmT~}Okxn))I_fRlF@y}*YgP$%J3001gYKWrdYQ0W0gwqzQwL&`*&mJ#W$a_>FdtAc z2-!n8xDZaGNGNBOnGzP&)oG_x^5!R0@;OdS8>ofIdWuEy3AXBZR;(}PebH9$%$?{pD1WXd zqeXBvpHpf=#XA0Z&?*S=*O8BEcrK{3s0#q zrD0%rUB(>bIQ_ipg6((at>oUlk4{HX)5;SEBIu9d+}>5*USMU^WosjXJSr}17#bW` zLU1LuFt~;R<~yiwff$!r#(J@{>1Nb~!=K-f4&!;>`MNwU-g+?=E{lfwMqiB33jf>& zZ5+VI2V{qe+!$e^enE|YlV(ux2!O|iokvdFG*v_##hli z1E)j&clhsd#J~Ze__1dVhGgNRt%b+k60xQWS4T)uW~Ht$AL4EY6;Q5Rs*2j=XK%g+ zOIp8^U1)vL$b;;j_pF{WR*%HQ%`gEZ6WipGc<1$eYn1!T3n60E&cnVT1(@7QsC7Mf7PI|8sZ zUOl95$XSmj();21nmaJ@7O=KMa5?=!N%g`%C_AGZPw8W1(4>jfje1)Zh0%EF`J9QU<%z!z*@R%or+#SXZW&~v3yvlTZ zbzctU6#cgx3S1OWtb1kk22oQ7;|r5~7Wh|%5vz1T%=WgM2-?XhZVcAGrt_Rj9Rc}9 z#k(C-_L675-rN9E4Y*(N;Gx9kw5w$CS$G?z@d!jJ_BVtuQva5LC$2ERc_`9!-3Sa5 zsJzsc&gB8(&%9e}fBHN2nAI@dLe3R>z(GX5bwwD0gm9ybfj8eWP^}nCT#Rg5+A!A$ zNj8>CKKOFFBR1LH-Y*7&5`vau>N9g~Ac>u1%Ttd$(E)Q9fKZNv54HaZE=B;eL?!sT zB&t0oocxX?AM75*RDPySm9I6O1CJ>{q7E?;NNt}+1Es<2Fm|gN3#`x9F4MzHdp&!_ z@MSgi?g(r!+c$n85r3P!r!iz9e}igF%d@%vxbNueYN9Sr1NktJVylmh0tP>s@Eal_ zla`0kOC)oqgeJ{c=^_DYU1cKR#~Dd`Vsv2vW>4uc2tqZFnqKt*t4qOew9-#NO9~gy zsP)+?Ij8E5HBfKDNX$rR;ol|0AqH+El!%0TGB!P;{sxRVohJ5y2NR13 z(+yceV#jhAw57pa>cq;}46s+cb|!IYkVeoBBG&?i6whvNu2{M#X=^;)zEtsGp|X#I zY+G3<(RB^|7D)L5mAvp<^=HN;9fKB8Owb3SLXMh0Gj0df(9sSVip-LwSl=mDOYy9= zoryy)wC7n?!nfKOrA@OEitjQ=@4X6Q(BjJqwPjY;l2Nf^6#%D%zVLh6?7B!j5EzJ9 z2^^Np*2Mvz0L_m^n3!0aXz!@DQvcFn5o3-Uk@9yqTXo0hxz9ZUL{P#V{BbmWTsYV{ z%`R5mEK=@1bg7Q0q5zNjU4{Hx)p*)xLd%xSTFuBW6cu+z3d9^@y9Q@L;OB_`*B7og zAJXgp{;3WaBf*>GJe9vO3c84%^u&U;W#@JkEA`!9c_JgVaH=V=M<#$igg3(&pir$o z$Vejqhf^XO)ietqO5WLZ#^L%Kw?nMyz?GMG0I+izHnrAP%>7cS zY2cyx?017b5a1YQs?gKL&$ZOOg~yrx7$(tGZL2%l`xIdT?k(WT5|_?}CR=)c>mCaZ zkK0-UeB#em3)aDpq@&nI1wzeWKz88sAT$(u(&&m;isKIX8kQpCBdP-%M!EMq2z07^ z(|L4GCI6LR6;Lh*pz`>~NKZZA%b3rj2zcHu73lCS+Dpy8Aq0H%Pt7XK-dDG^ycR-e zR~NWY?7;#)eR8c;$&CH4*_|k;FZ36k#2Bu@CKL0HS@JJ3veHUgA?gXgT7z4Ga}I%B zAjk)JE1r<{0Naz-dsTu&U7l0bQE->mculd9npd$hYIIiB3})^)Dxx@_5Hv}Sdj-aT z)ysY;Q2a!$5qK=}Pi_b$r8@8HW^v@!|BT+5-jS|>!I{fJ%*ATy*&W1r7gOmoW|;8p z#^>ATUjno;=XfB`X1cHawd;)aA^zsYp`gA5X6?<6{(hNX9!JNqB>QoFSbWYOfcuz_ z3I^0f)rMwxUv1K3yFZ`^b65QW^}oE(EF8dod)_f#;WK1lbU3Qz4AS(B zQ$oLdmA`a=XbhG{ep;>VJkUkIO3H8ap(_rS2Hb$G{{m(!1OaviCslT0bO|J7- z-^#xZ41c3+$hWro?NJYK+q=^qGY7s*7V?Gq%olS3fex(OGqT$+Yk}HXQGYFAxnPMP zX*=JI0JIw99bnfp^Q|ky6I`Z}|H)Op=xcm<4{Wpb&#sy)21IqAsp8C+UKZn%SQ<}Q z;(r98Cmj84IOB7g<6+OuxiAj@^0(-Weg2O!7~KKPboN)yCtqKv@JjoR`(dH||A0c`bVdvk* ztCId)v=O5}4N|UissOa;&KhJvciQ|7>AUEtf``(CSN?*M1&D)XKd+tF{2bAvnjG3o zApDWX@0VM_)W5;K790&p^)F+eE`XEG#=%U~bbtRoC~^)0F|#0-7qb(gwhX%Mrfgt_ z-ZBn3$RzeLFMh&*5Q8@EPvp9D7lWAJT_9|~fqJV&2f3ljCqWd2JrS45D%V;-K$K_N zm%%&=dtztxO>iBc-|w<>K?tz(&!blyCXE@yV~$`ZBLcJGc%yF&4L*K}`#6T+WJhQL zBt(PdVltY&1bjc&{zxeX$#$i*#eQ>fE0CXqMT%VErGEYPWBCkvii`zjq^8HV35L9N zLq1_B4E0J7r$2Wsd)OH*ow)>Q9|k9pSnSUBPS7luy~%xXyurJ04?x5Z0|3N~@Ho~b zfq+dGCy;b`^5#-_U&ejD^?Ig%XX*$Bc%e2t@SEU`c$?=n*xR;K-!JO9F*PKl+R{K) zo9WM|i)auMij|8(b@!tULkW*7b#?DT%TP|)fo7((nspCw8aB@18j%V}1WZ@hvg+(@ zfYo^azFG!oVYGVc?Tl}Mp;0T`DFz9&7mq)X8UYB00URlT!^}MLbrU9*Or+DroYasU z21$9|WS#WNk4W2M;2`$c6W|SHlIQ_ZC{82blv8spfK}YaGZy7LuWbRqOlD zA4~MnwgRD7+0;Vk+GE;EL^b%_zxL?)w>nF%<-*U_y!vqi7_dKi7^V-G0fOHHFt!iK z5NpKm*@ZJNUtCobYM$U60VJXj#?->>D^R30`-^|(+vRd<)8LH0<3BVI#mea_MHmeT zSXRY30lM_fREZQNOf_N|s4dVe?^?46dF%rzfAM{K3ldgbCTKXJLUSt3^m;OJqH2UR z{@=j{JH)#Loy+jl#iX|YmkN_<88^3cR+xH{(s0~#X{}9hh;lRsB7|IoAVP>H(~**2 z@3!aqdv9dB!lhq1#bpwX-YlmAwd?qJ!u9w*p-bWP3L%%`!X*=z{u~#b1GceRp=K`R zxt*R=@XKnL3@kG(y~{oT$Co0OTAv~~izOQ{*P55YwM>viWBbQ_D=gATmu3mF0tkR9 z+Y4Rm879)2IMLMFhws+C0qjC0;mEvTu$5AwrlR68w-0jF*@~X{okSZ~i&<+IUBY1w ztRhgw_k^MXxutw=fm|D_({j8{fvbI(tU~&JwAkC2Kb(}qM2a}Oe#`WS{IMPi z8trJ^J`Otu7CuN}L*%|@vDYls?2P(dl{N18fa^w`yIV$|(}-ZjZ<|AqwXDG>$Ilb@ zA4aI%mGp3!G$0m+aSB~04VgkfA;#StnvXmdH~BX6R2u)8?@owg2OSQouw?iS$RB>B zSRP!VDzbxpA*D!NNS~@-dhAQz?-{*jr%`GTP3g)obNyXCLR2gd+m~Ea>q(tpko- zd<&3WQjDc_wEA_qUzt?re<6rdlqFwi9kUIw#Mk*79=)j5@)#iMGFV1;!u$Vuj2=TG}zUp?@R;| z-3R1h_tjT2lLM0crIo-kWQ87Pi73z#ID`>CWW23;4k5iA32k)%vDR6i^yE|%NOWA} zi{uoJ1;_gYqf&*Jbv73rd~V^2sxTeo>Zd%A#wCH-{({BoYS+&YQQ|&}O4mVZ67eXB zewqpadWm%D>m2Pn7}y==VIwU*>>z_UE9y%XGg-5fTn8>C;_+!so>PwcvLuioOY$== z5C`}c6dVg>LHa-figv4Lm3D1JQLkGF9RF0M3z(6}K*=6@U~9xwl>^oCdl53Hk}Fl) z&aHY{U^_=_N)KT7oUWg+ASHB$`Ug&|CFGi2a3HPkct=;1Sp5c}k;!^LejJhp_m8~u zb0br#^|TOFe^c2h_FsDyF#uxRaq^Rf4kRJk{CqN+aWZv(+jqc}(3Ui8zS7iyVlTkP z2JP0k{ajeAlUIBxr!og<6ah7Mv$DE#GeNW@QQqcH-#vkn&d}yAyVq=4$|J~F_BLK6 zdCy9A<{G&X!=4fZ0p20q@MEh)=6XMG^5S z@)#dZ2p3zvcD}fDFLutI=|{B1*2}oVU>W(LFTz6(jzUD(vhZs-{%f{Vc=M#OgyYdz z0CqJ9uI3>=$sL<}I9LNLdHZSA5QTo2pKtXGj zmXx`f#sTajED@@M2IpBdJ$7=|fYnRfQZg@=ZeC8IWkg$72qa|Bfr*a?1+5G1nB_XF z`9My0p>6f++EY%+gHnP7w%G&Ui0Cer%p*B4ZUF#pPTqR;5t)u$RDe4;s(i+Wp#cNQ z=yIMHKvKSdY)^QLSyaImiNoQ6%^e9xwk4v8BhjwfhZ3A*Cxu8Cx{r?im+K5XGn~K0_G8$r%LAV?&fDm%6ZuEgLI0h&= zlD4)cm+E6Qz;LEZlfgI(?W*NWl^?0_&Wvkd16MRm*y8!P6I)fUGfI$&Ud=Y@OLhK3 zDLp^5rAk-4o$`2xT=8-OsI6fNZ;HdS4Nyz%2+}#@;@t+c2p%$te1Y&-a^GLuW=ami zGgAqPpxBpP)DcB>G9=B`U#zWtQAwzrp{S_OzyYFXbRO!VtWce^($?&eJYQ-)f}T;Wy|g;$t*$TNErB_(+8>Go<(+_t((NX+!ZA%YLaPCT3KLYL z-U+jPz+rnq8ytNhZMo!eZQ)z0ND@U-J3xi0%TE_1e@*mn)^jz<&dDFH851;L^&VLV z<|?dl%f)L*b_zx#0o&~@1yIYA7oCYOxl6JCcLlxKy7)T+qKG&vyp@$Pw$c<=h?t=J z9ZQo->!S4e8xkWX|A*2q5Dur4ky?K#^g`mRZ1z5~`Tm3H|{V8$&Kxn8RQCPZH$OsOY#$CAm1dyeI~&TT?0~~$ z3ybYvGw#!!V$si05R*#T+0|bSj;YOF-vK|`Y8W?=`i?*>~- ztx5G5VPbh{!yOTq6fr@!V^E}Cxt01W0`*u3Pc?@#C9qx09F6@!S)_PK(AQU{Q#KU{ z55FLiuSwT%Gp*Z8MIK=7D;!xC^ukgV4KwlwSsvA1aX^|3S<58(XUc6w!L zxw_J_yOH<^pB*g-D`bz6SF)or_YjcjJ!`f)W}l z)eFzFQX$h8_`n%uNrmc`D~w@nMi5wei7Mevq`zdp63P2mJ)^ZKSRf-z(wO2nh~&+1 zP>K1Df!esTe!o7_p5W(p+B4`j^gQHErK`rgzQ*$998!+VLa#rm@<`bxW8G+Co7af{6Ig7dla&!MkP3F~v@D0f(PVZasz^eMbUk(%`j0|-9)dr~N)1km@1j2?B%*1cK1Z8LN>7rXP|+#G zaki;C0(r#17+MuhSqpt@M)MVXvOdtRjO=^=ISM+I>iTB$JJM3Y!iAZyV1S0*1-ob- zT$g+$dRX+lZc(MM)V0mzo)By&{Qs6{)yYFvv-8IemR1q&k*(o3Sx+sCsXA4qmi~Ss zi0A*ztDrH46*bvN{Vrr(#*nyyLmv`y^9;3}0FPlB3 zu2TC?C~EaG9!>4JCO}^g#$A9x@pqX?-lxKtap&c>A#tDMNFzn*x;vDO>OX?HodwX)gp48ek;ON2U4ziYm9{(jAUpVykPi{4&A>> zlJ%YZ2bldUTw8qTb+7F%vSx%a8m+op(yI-A77-2E2I`i4~w(DDKZ7 zLThaXuz-U&Z@Y<*$5nFS)K(Hl*B)Uz0O&ql7WbXZ@Z`4%_*5tQQJe1~pZdk@HeP|r zst~bOB7h(OB;*o-YRess58#KyAj227v-(A@!D>)diQ;f=O;=cikdg(1&Dn)@M6%Z4 zasvjmI@+t~ZHI)EW_XMx0EF@X3vF>^Vy|J{6|nwp^X@zsjn zgI=^?@CRetP*q=4xSiOZt)LHaG=rcfh}XheLAv?K+&^iD(%p4%aGus#shK;IiL?4U zZ2D%6dLAm8C~8c9S#oeD?na?ggddXI^)igz3Gg$%INf8|aznKxVox?SycfRLe#MP} z%_9Mmo&*bMk+vzGQasl!zJ33Z)98598Qb$*!ga%sn?~sguMnQpgVmtB)#BfoC-vuT z;pUyR_q8d^VqY?+cg0}XlS=4p--xqRl~yl^S*~bgdwA@b;}pmBdD!tG3tvM*cXPJN z9=Mz(ut~5>WwudDBAXNHxBl@cJYSH+&wA^1z&$)^#ZYWv;ofS2ar_uaq0_$oI+%kc z=<@#eAg(&uZfQ_0g*3a_Db&CFW4Z`7R_WrM$f9fkI?{>%8>vq{wvVn2ZJhjRtaiXq z(>U8Y->vKujY!jg3*UK zl?>O3=$L@!_KUOG6wI5Gr~j`Gn2&40zfF!w&$v z2Gtxvgo%Jr{-2n$de=T^z|~kz7mZo}@{~P>G4gv(_3{DE6EC;32BZ( zgX%UZJK?enAS1aU3M}*Yfnst#6I}dV0}&sCX%bRW`|sA4*11+((DvZuKZx#ziEDm>Z_Ko9?+T;INAGA1HIUcg62+*H-iTKeSlFGweKnKG2@#k?Ut zPbBI#F{Cx)?b{L}MOV|;{$_R}2!i;a#cUG@S($C{1SS;w`Mi6?eTL|fX9n*b*iTG; z;1un>;bS9{K}h$mg1j*yp8xgA=67ro9if1)4_3Yb{?!ET$->Ao=rFCQjnv1{vp_)r zZ{Gt@=*~mhxAF&p{TH`Dv^aXm2qC{C29f|a+s836g58P6m`ACJiGNyK4-Y4{Pu{1N zV}RqsT(eFiJHJoKpMx&T_czn;D#A*{C5@X~5>>M!D8y{_f%6JVk+KheKFLmk>?ovL zI=i6V{N2umD+)OQ^wBoAw>Dk*w6wmf93(dmNf!b=&fZiq4o^RcO|kj;cOZ(o!x)%f6#T=wLf={NU1jvfGeV3XMslIwh_Nk zwo$W#pa1KGVwSrLjJuWuYsCSGQp)CdQ~+S{2{VSjr3w$PULVYj{Tcduz8xFGrfIa!CMyh|x1COiB##vcfS zG)Ue6+o{VU7L6F@Yv56ai`Y+CD=1)bcPw+Jf9i}LDbd+Y!QCMT{7yy7* z=oMQ0S_)%8tgH}82PM*mf!P7f+E(Gl!8Wv$z$o_&UNJhlr0=|F>Z-aCFyB+kh1(Z> zy~B<(&zvw-W$hhV&^|j( zv0c9{0Pe_0rfh(Zh!MY|EE4cPcD?BidJOvddNL~F;nGOlzq1=zrU!p&Vto<{!2gP< z-(X;__~K!t+JE#|Cx#5jK06wc;){QOr_BPR6l5AemxfRq92%nLf5pOJ@WEQ? zH<@S(g}E8=#$-yW9`r#FD&%6z-C4;5NI4}O02xfg{}6|8P4M?iGKP)H{SPVcLIkYA zRbI)BrhFcp%^v!oON8*zm5CEYJ(qslL;Wa_YTtKXUc?9_k}fM=A|g3h1kn@BB|B$Y zC0jU5f0$0@TU&hooUeDXF$QA8{pRr^OxT^Uv?5p~lsAKRJzg+npZhiUse3iz0yXZ- z8@>InEp-soC?dk!#MR&~ejNdGL&gUNYcB=Ue;X$s*ZFoWRRX zm-E>{5Lxvhl-R~|?a`P!2*Qj+3{!x?jFh2^)F|KsZ}HC-%Wa0wh26rhjPws!|4B)k z{(v!VbPm7p^64DIJ`(VuW4l^d%yq-A^O{nOfcW=G!kK8o0e&jm#t=c)D?A!%`;+c? zE+`0@KDO%Ta4u0HlLheyv>QVJ>$90)3?sJa-b_T>hovBmftTRbQ^jhkAf@wbpJkxpMNEG+Kv@lwvCAm*wm1ryi*X3V3YV#P%e zJsR(3+!}D|58={#eoU~`qM4Jyzm5#Tnq3S@2W zTAsUMZfZvoEu6yztzhUS}rXw#eGQ!ol6k2VHFr6M9HI*E%-tCpbQ(K0@3io`tI z5yN~R@q7_CUDa7MyL>pG)|=stpq&aLMlk*yAU$_-qB^eLls{#P|Abe2pyy1(t9-S- z=+iap5P<=b^S-lAI=VwflaD1{9c}+vH`EigUygg#^1;IMk&}k|S_1BDyrSz~smZVIm9{Dml`3eV8 zatJ&{V|sDo@tL@Te=Y>6<-E^=_HMVvzWnEJ!(e$wN4 zHc3lr>Z1KLwpm3&w@;bXRjR1LDneUkfqq+jP~9;z-{iM_CmiT5(|_kPPhPRxa*2Xc zLO>opZ?=hn*U$8G29p~8t0N{hBX0HY-Ta(yxYmfn=2F0nfc0R1>UYmU=QUAlr<7FR zy*CP)(yHRzrX<8DYoA=-MhGxU%V=_~$LMjJO3JiEM1GQZ{gC3|=<0ND))zij&nt2n|1B;kg~VW-@?DbFXA!GJT8A`(_xBt%QkG7=JY9K zQ`;nSt{7B!JqqiTR7|LWq2;K0TMRdbjttE%8m161BR!ya9-^9~RUl6EM+4mw&8**f z0U9LwnT}H31(~e+#Y+n1;25IZlf~T5NH-owRFhI^#Dc%fvdzif`{6--ncOCqO~}JY z8gw^0k630X->u`spA%@ASt2_>Cmz2tWzS@(!c`oy1>|#OX|RhZ6t5M}{-lvyM6WoY z={Xut$j;Mob(i-WuT@oZo(h-TV8m(a4h>{XJEYa#nhiYCLV!^Q?Z~%^?ZKUd zqzx-sSx|DeSdxor@AlePamgR{$65<*yWA54fke8;c}aCltFqCPULs07ucS`1=^1n5 z0^RG~x+HVmCQSqr%4|c!i-5`(=}91+?P*Xm-egJPh4b-QrTwD(lxg<<=n~sw$-4r_ z*FI;vV#8aOyy#)0eP92MYbj9>j5Ecj)$TEpXzNcC`7SVRi`SIv**B*%*^PvzFS0$Oi(j(Jvz#Au9o)b}U7&lb7Z(rM4^pZIklvboW-&64MMB~6)hjK7FKsIeFlMd2bN z6`@9P{QFxA)_INoF!BOgnnM`q5E#-XB{4%J`7oRCA;vf6Lptr8eGp2wc>+PT!|?Pu z-*{DOT(Y$2vo{{Jy=-slNWW3i=DVo!N_b)5r}G8{cn}ol#&hcv88bBUY~tG-bg$+KP3<}V zXWv;ClPL6;LGRpks&V>~nW3TXu#GvF$fb53m7IWd5!bi&N7{dbf~b?O!)_FbF+Do; zo})=*e(RA$+1+F#Vt8O}2Dhb)kkYUoOn8<~jz(+jYTrlHt?uyY`6_mtPw$xn98Tkr zAeS#5Qu(tuw>1a#)7$mD2|V|Nm--?^m<9B&TNl9vp~5_Qw`Z?uu{`Gso|OqkVp1Bm zCqyT*9{@Iq#w>dw(r$PkaRW8py9+#5DK$pOFAHJCktyJXK(wYz6e$14&Ghd|i2!|69wV;(*|yGS}w#Ou{O2r8)zlLS;{s5@&SgD*!s z<^p$$295E-NazQeb=!&0Qw%DcGuQ(H@&-5`QJHJDr0NOW|CD?ORT2E5Xz8pVwQ}7? zWkCX@KkmC$N{GS(=UJcA)Ti$G$L$~+Ix3m|@4J}rjgbgby`6&yvv=HI9i~3}5F!1Z zdyS>259`&FP`C&@ru$P`vUN%-oFk<~oGVe%nTFPw&NR~K<4z)T$SKvq+uZ|rQJy-( z`c^#?uwRJE6bD?4{x;ypI1C?J7au)zcZJP)x`MZiC7!bkrD!-Qi?Qv!!fziM7aeWH zPcfXwg2+ZjirlXhx%3bq5tgtMExuc+4r#X!$LnOS+Un>?9(W0lN4r2I!-p<#BbbbS@TA#0ZEb}bt!G`F2DR_` zzdjg3jAMRrr;N~~sY`!(SL>ZXO<%l4JE|BkR;;5A(=jGiug^a|3rHdOb}WhhEv+QV z{f~On!pExAed-cg}f=|b^dO1)w~BR@@nJ5U$kLh@yqJ*c!fEt_G7}`sG`o#+WOZugsU7` zK}j);1-eO;F!ZS*YeKGHpv*)Yrf>9yn$54==yEaG%MTq5S%LXs%Yj*7OjoQNju;#9 zG?YdAWm@i?W}&$Lx4-h!oRY>O0r<2JM+h|9HhHEnNRMVn6n-O2KVP>MxWgdtlUblR zh42{KX^%Z4TJg+75tM3TkxXMotwM1Y2bD)wL#}Pl^>;Y*ntD;ec7^pb?^Cmv-p7Zf zL7gL8%|c1CO8U+Ke%Q&1JIn;h z-8FSXR<98Q@ofmrehH0p7T^!!?spBE}Ry5sA#+}mZ81szByD!0?j7PAF&RqgZuHvMrlFFdh5GLM{=0r zYSGE1^k-hXtujm;fGhH0Aeiiq;R$%k^ri)Ngj_JgxsJma=NGHfSY$uDhdswGpcZ-+ zr6}}zC&WfP1m|(inNyXNJHdOfMTKvW1+~Ow+B`|XZ z<#3jg>X5_?f}erSiW+aw`po#4-;fApbglG{+HeSR%d@S(>Rt4iu5%r)!_XHWmPhDD zvndu1CTi^z_v~@{lz;Yte$94?DlYOedtFQp0Jfmqep= zR6$k5LHcZOgnCLX9F*^M^o%Iq?dWv&q4FRD6VzNetD*vW8eJD76q+P~2A*`~i;Rga z#_N%X4W~PDbYgFaX7YoRbQNf?M4&eGF~@4Kmwfibv4V{Jq>`&!EK}0cOI_?oZ_Otckn@?L=hhooL~lJhCq~#TL?LB~+Coxe ztvymW%S4wfy%ialNHt$V)cnrvfb#NAB>rKVTQkOCoJQ;8UmZq%8sCBndi&lQylPK#*+-OcGyZo((Z;qE2QEqFo8gTt`dV+UxD5^E+K+sK!jfp3lKqvMV%;kqJTrltOBxZk*G zq5QOu8+HnaKZkG8vlNS4e6}^VwFnWD-VxWSv>U}~L=!}eRwArXqvj*%$UN{$Mg86X zj!@hZlA}~={m{;Jhp}pxO9=|n%Z4tY;L6K+*}Bo6yL6o@&k1=Z#dERU%{CAn6CT%> zPB-R>rJyhe*(bCmOW0|k9&;FCTQ5>6@J0}GcCv69L~iX?qUlKMO6;+-u}E4D+dTD| z{ccU|Bjf}~$oNFvHd_jR21idd&jG%J>0KPAGHH;wq_W-96Nt3^43_CT#KH64@Fa=i z-Pr)uPeER>MDnUL`O`U;OA0+im_|B+@Eks;aq)$=tii!XRfmSbSs3LN9+h%tPj`%d zV}S4JHCmA9RvZTs8o?vtyf^>#5ny12j$@F7+y*-_Yvu(Nw~s6{s^s!*@T<2w_HHRO zV@NiWv=)kvhnZN0BVV+gLw;5J=>%qGb57Yan(iEHp9yunO2jpn z{1@8LV;xzqo4I22gPdmzi&YTAccBS4ZwYe+e?mf9RPnT7Ta{C;2Fbg`*UpBWXIS85 zTJrH(c|7rL)h?;pOGwBq|L&3{>wqy&8}uuHs*}w_CdJ8c#^N(g;@^ETq!}9>Yknh| z%MnD38Jtb!0K-8KhI3RP!@0(TaYI^6x%$zxVK`wv72tp3gnj?_dp?7r2e)vM>VmIr zwV=0}a*?eevqI6OMDAZ1z0J@Rt<|&;g90!xp*q_$d9|97Cfx<6qw*^AEQgeQQL}_9X%FQ zZ5h>#n{g@loT|Vvf#H;0E+%#V@TG1nKfVTH3wK4Ydz*SoPk&lqg_xx8A-i5BdiXD2 z2kz2`8}!d_TG|%Kons*a@ZNrKZv5@Vx22w>{egdPZhNkwS%&WU`)~HM{G>#-O@rWq+QId)T^pv;ehITwb36J@-{%vv}s@xL!-01st$|S0FvOmd( zXAP%RC1zKeQH26;(Cq45_mHM&#y`Id=O|RiDA;B68&X>W+ikk<$-n?-Nq&KY@vkRn zhhSxbGrxA`%+*8)$FlzM5Gqzrt|LlZzj~Vd&38|JhB&_Tc4jG2J^3~`4?-`xneKS> z>joXK`PFvWd~Dia<0YT{1P2{!L8n2YZ4B6paLK3tFW%nzEz0ow_fVg`@~3F(kdrAxXLq(eH+&F8z%IeTB%`DLHI&-n+quHku} z`(Eq4Uhnt1Fgr^5LgBFRh-bXk(XkRuMPo?J{me-Am1=CQVnhi(#Aapu6Bzpy3TUX# z`R@0Y_`6yRo?NZduvtuDs?lRgNvsFbQ~OPbotEp$9c*aW4;i|35YS5ip`&I?Z>E@& zGr^mt)@yt85o`JP{RF`HRJ=5ib85VVx4rEv)OTix{mT);3HdOyooWl!LE*zuzrc0)TA;Yf--ha36Vib7TTuT4?X z?|@@g%`Aa(w70Qp)nBXY-On8(Sb-}rCb{(Q__wI~UrH}2<|{mTt5t0^>Hh-rE`f^} zmqoMrcKeXD-|$H@R=m5?V&}Vnf9wgFvkxyXn0drfP6&0|H6fFJjQ$THpsT~joDidDwfD~ zUeT-vW-{BmN!c(?Yd6aqZ=cR?C#qF~=F5DC<$}Svu|gGN7Ks`b)P9I>?A(!x1EQ91 zd2nguI6t9u_#ET78aAQs3%EptUJ83Nop#_4WQ#s1<#+;uU)e`ND5t z0Dloanq9$7i%{-aB5grA#V^Rh#e*-bdJ+7T#a7`HIYVzu?w=04;xYY&a_QNgd-AQx zyD>g5*38Sf$tyZ=^w{|0mmlGEE|W!OLB(IdFh^ye*StB{n&dM1=?OQ;8`JpH9*^8V zY(!{{I?U6EmBx6wq}M7sWHkH>PuZHRBJA&(rlNnC|Bh0iE!FNs!nd!lo+5I#h9J)U zrhM@iPFs`3(FE07Jmt{xqP^3MXk9!P=n$l9$*?3@ON91} zLYE1pp7|Vmm#J5zOow7e9QDj}{3kw^Ctt24&e|UJ5F@l>7tkYN)1@#tR41pVizN@G z3-aqKD@xHJpT#_P-;?Brqw${*UEFTEehl>d_G6BJ!%pE7`O;8A5Z2gvy|~6|n-t#4 z8M(jFBzmLm#h9yHjPG%~NuH!zu=Oy#%K+f6p#c`8xdo*~YKX;Ofsy zqaD0?UY!um)M|Jx#rw{+lH*IAym_#CK;Qc)(cW{uA|e*H@%~h_^Ti{k+o7uhIk;%S zs93AlT7?No;JUuKkId#f684Zx+T;&8oCa(O8-n&7B8ZHmjPVN3ZwZU6 zKW0$RW0Yk)eo;+HP8G2Xb}4yn=d#^jm+Q{f?~BT6^;7Wm#p#g3@F+rR%Q zN*C5Xgio!TuFUQ>`jid?;=D;n%={$byjBNMYGH%)+np60uyHeq86b-o%jLBFW;N$w z!R9i=)#UUf5j9QiR@G0#u~4kfA694$hW7U>X?!-j(D=lU_3Z(=E*$YCd-RXt5X$H?_l(-K5Hmnm=X#zDWo3lhI-7c62Ss(}_wmR;2Vh3HiBA@!BpwquvJ< zbjN3+nsB245_0%+8D(6zaz%J=1Dha+Cj6XJoEWTaIY435VZINoQGi6F%m{~E_{w{ zqUMd?T_Wb~KMqQZ`CKc9i#H&3%T!+JW@!WIbnu*sfT^re`EFz!C%$o?SBL;v_%bLz z+^|1!!E8Aj+EcCzk(04nqh$8#@bANXB1P^<(yEiMl@JVVw@LBZ_tvaBs4`YThX=Rp zq}V8&IYcTm5<3*ia@c{@-lq9kj3nm;b!Xq)Gb`a0>h&m^PCkqA`#ik^fhoV$AQ-b& zl(->rW(QwrBuRcQ?(ahBvq?I6y2C_b!aurK!5%A<9?=(AUH<%e9FTV0@ic4RYol_} zd(*5#z*?_(q%mkta;36vSiF`6@fa1ZVNx3-mmpTXbpJ<;oK^Jfub(n$_!S-d5-lYv z#E022{jM4eGM(y)&~G&KL^~XMNsz^_eY&)=A3t<9fNVelMjwP6b`H!cay<+zCc0QL zp@g`w8Kfaxp{1$R9GpbfJJvuJ+eD2f6~Jm%xCcQ^;~~1C^DCm_%6_ExbdDu9SZrjn zO?#svhcyVe_4h`fgp0Ar;-iYJe1Dq?>p&rd#HMv#EQ854BRx=Dh1aYS3CBDd^_%jS zy$uD_{iN8&pO4q6zt!^zJHIeAo)~|SRw6x|yFn%|jxAU?o!4~>!~U0&*lK0JN-W)__4lb=Xmtu4p9i zyH1CQ7$Tn&-+Fu^Gni?)&(hzQDKMqwI7;<>g8|0NG}&_$8u3Hy4lxYO z_aq;TnoP;VhkEFOo=%h#zNRSOSg67kj?t#9RFUd@Bjx*QH}5=`p|cqN28%GSytL2Z zk?lM#-UltAEjnH+Rb!kF3cB`KiRJw6d!D8gvO}QgxbgXp-m&+A!*$erT|>1kqBALR z+_jJW<$?;bNUyHCh;!2U4Nv=nP`dUquj~ep6Fd966n|hU)db#4Ten?MiN-$(K21a# zkE1#qh=`DU<*mst)`n@r8v^bd3B=a&V$G=ndeHKP;1f%Ni+et`e*Q6dmxOeWFj4zN zLRp+d?=Zz{&$A!53RaWbUOwiMt>0|T(^6xRyAkr zp5#jZTn`E(L5e!4h*tERsFXeIXLrgu|z$vkP1YJ}P<_3^zY z_QwL6pdQNYDx0l~An5C#D$s=*i=K;Yb#5Nk@@?oHcZGB155foH{<|-&n-rUV3lz;Z z5-y<35*g2HjL{qHWPNN1HaIXyCrZ;E|rWi>z{@gc{LT<3)R!Hql~#8E)Q0Av_6cX5;OKYtq+OVKDu z#iEPtGQaxV1rhij#{AMN?Pm*!nmuKwz8;|H4A_X3dM%0dFa?>8J`*4?_Vp@F9|~YJ zK&#{7%KEa5GCGTgoGa#7z%VE=KW|VI9v|~8N$=NwA?*d{ zz$GCSkCT4dE00YnBQY%5EteK?EFBngIyzjM<-dIp;G21j#~@^$C@oQ=4ySYj`{@%9 z1(e3OQM9t?(S3trQdoxy{iN-nR7V`1e;9gY@tB-!^N)lw{Bw}O$upW6%)DDZ7UyN- z4EnFeRAUah=VA#YZ4K*R2$^v42UszgTFUtqk2n%C?!WYZ@e?8PWHfDb7{NB31I2@w zkcw4H^Q; zDLc_vjd!+2?()pmX3Mz~<1~1!lfCx^@lOyKuS1538WFvfsjf^*H8fH$<`;S>jN5nI z@y89tuZh&M1riq?-?Cp9jXIwwOYE1<)&l9c%;SlT6gyCs%3OTo!gD`q!mOMvY(Ud4 z-~f+RI}QM+Ohtbot!13z8wUa&*sB527GxX=pFCT^xsI**vpHOCX15CK;gmaF%oDpo zj~!vZx@ohoHeH4W(2bqyW>BzsDQ}X5E9D(fXXbd(VdLQBY)Lb3Qj)2%YISR6%0T3o z86AOrKL`syOf<%s@)4r&VZ@h@>_mT291dqfuIX`R+AI}7xRuBA>~zhr_|Nk|3&It6 zVQA&9K2n^E%KI}$bgiN$jdNGw4*c^FURYZl{wkp&a?B*d`ixMr_Z*bEPGz}r&(E6s zZ?$UKDpKVQf~EcLb1(QkhZ z63aIw{C&+*A?FYBX~kdB*1*S>9~2iz^O)B|R94rUIk}!de8n6tN^DDi_04ew;i50# z;zdWt9)afR*H5@PR)HRr`nnbeW}l$Wc7LYfWJAKXowVbj;6qHb$y!G-r_9+git>d# zTO%QtI9PYJcR#QrK+PYQw(vzV00Ru5Z;;T>r_DSs)>b zND#_#?^8H@bV?7pVR)x$y9}Eia}NS>n!jI;WZ67nr>~00=BSnAO)=N=8c5W>O-3Nq zHTi>o`Mh7=0&T`x{+=hcKV7twXpQfM%ptdW1flj(JsLbyzEu`i&aZ<*#rE^D1lBWs zd$G-^zo-}#;nF82o`g5=iK*ClvfB&pxqNh3dWFrf(0KAdA~^0@sKf%`YCdl)*W(N8 zT;@-5-e=%WjR4J=faE76jNPMO|JHxKTMWa&IeS1$mbjI0m zzHsGetSH4CSDd!D10z`M7BcY8&c{nCGS8Mp9gjKJVO(hhL*se3FE(jdj@gtg=GaG7 zY{%@LJShXM7X()AZ!R+e%2xx8wB?7xS6;ryrKpOif^$=NHhZ^5X55&^KW_5{`(-e9 zlVg_w%|XVvV6K_o@~L$0fOjyTQLQIfNYKlA!9um^BpG|-BqStYEA;c%e)0C>s}SfEauzlM;&VP6tQONb9SlYGa$L+weyLE0B-^(W&k2r~J zUmEw^9PA3KM%>1l^wfdA@YZdP+D6mT!AP}&pFBw~5Hr;~)%*LMGFp}Vb(fv!an(id z|7+3oe_okIA%U3t3COyAR}fIQa05{p?SGH9{J$(wS8=&ZkJk=lKjnF_CZPgk%FqL`2wKUo{QAfR#$Az*nI~h8+D#5lc)f6e;Vo& zISDnVXHlbs3^q}B8}a1mO={8%q7c1opKsPS1;#YX3C_$K;T$jjtfl5v1A6OPZ!x+i zeY$q;ceCzwebNt$^!Ev=f*>%FGDH8P?U?P4AA^GzVpFB6m+3yyco`Xi+-4QOrbjN} zgdfz)}FwY^Tuqvak7?0;vN(K2i}QNr+YeNM*8Kx7O>YFM1K=E@EKFd#(-J z2NP%TN(T@h7U}302^5r|!E-+1JgsKEQU~hXW6p%8rYoS)+1l8q`2=`N=b?#$mCbYK zxUELdZS=+uKIS_#RxWQ3*5kS@q`CT9+^=f{cy$oJiHeHKmQMzl=Fp$_Nu_T>(NupR1Nhw(g*UPQ%a7!gI53^jg9Z3;y>PeN!`2T)y1TrsRbK3V}X`gAc5h3s? zx0|ux)wn@%_Zk8+0w=akxKWj0C&k7AWwYuSa)mE+YjAR-`vjepm%YdQx z=C01NwN9aQnfd9|zX>gTCp7RIThy$He1(@gBSHBrtn;f*R&0%bUeqtAKSMLdKMs@U%a%>EWSip3(IBgg!~+NdFiix zJZZ9?QQuz6ddd`I;)dv{zx8%B0>#n&_gxmw&5(g}uy!R=xQdld;~Hqu_WZR~o5m3g zW|XVxkAKL>@e|pL3PC#Kyb>>n(G-t+vA$b;?`N8N^@9 zZ{ntKxy{t%DCQu|_A(l|UA8|gHh*l1_$21}bDXLQNt0gdXt-Fk2?BACj&LX4=EA?b zST9;19=Z9s6_i zsJM4jQs-dEH4@PMmvG6}cX#GbjXjksZM=7T;-+YQy;nhXwb#xALcQ&j$Vop(z}Ax` zvv7xWbaSJKPw2!=ErYPf?0(3_sObLk*$yR#iF6T_1G_=Q{?u2Zh?Byv*Au5CVk~TD z6?M92B&97w&L?w`!1PwLGfrkm{4L;OTa*iJbLZJJImQ=D7D%)Y$u8o}KFU=%vluT1>e|W$PW2xZNMfS--&25}Ad0*guA1dn+fA4yrxOxjkF+Zt8UNJ zlPaWm-ZfAekf!N~{WIdw>)*056Z+s8qOgqEo>36H9-9zAF09y_3Nw`+FLj9PWilt% zFs;LmZ+x*MaexN3&O`nvW%zxL_c^M2AHgAHLKF4N zQ8gsXQ)~y|2Cx2gMeDj(X&819%q6`$>6vd^32#VYLZwGToDG#%{8GtAZ zeO^sVNnxO&i2v2#b|~2Ntj;+6Id**Ancp}hEC4BO|E}J0^>^yD2;K!uBJs-v;RfHN z+zW-8cm}D_xnGkm3zYL6LysWP2inVIiqcmR^xt=wnIFqAKdW}Nu@n_9Zf@tt{fv@dNsvBML^uhr732MaX3mlEDywK7?DORl<_m>W;%SkjEK(aDd}C zHymx1341O{Z3$9R5$yID;sFsiVKuU!MiW6HD3j0r*$O*?uLz7(YFaOXW%IKKIfJK; zk)qXK3$QnbJBHC)?1plNUgQ!AzgkHwH(2B!{u&k)3&F=F^gnk5;nr+OSxmH-Y-A1b zS>heL{X$zFxV3u^vb(~8^c%HLDeA*CNK`B3zJYj3_j!2fD=s#-ja-JM1!OY+PN5cb zr4l=;T-1+X1>Sr<6H|qv!h6+&;7W9OcGjnBBR%l?z&Ioayys7Bw4N~4VSg)Y*@Qvs zvwTRZLLvr5=s%ZFD5+!U%Ik<7FXxbpQhc89M&Bai&v?p;c*5JvCI9ogeXQlV;Ua0F zKdvX25v!iE;k^;624CS^=_~Us2*nY7>vdVgAZ3UM<}Bh&gn6MocRfU%mo20soK0%e zeugU=`RYw#d;O{8kHD)7?Lc8vUEMKm+GHvk{0!+*%^XcO)kSA1%x3WD8RkQUrU>|Q zM>ZbL?8sjV$u_}JfhX17WZ1NBw{0CDf#)s$`o)yKo&g+6|0AQ-{rF5JvA}8V@sFj` za5R}!IWvUH!$W2Fc_yhjV%qIQ5Qx5nLMEugUx@S2V}<(Vmr2OeE%gQY>`er#z+cd0 zW)ZYySsQW%$Sb{}5pHVq$!JueIQ-#Z#wLs2J-)%bGJGDB;(=%i*t-eqN))2L|9qu( zv45K)Nv5WRYu?K$f|$q>P42limltj*!m=xum;{qaS;dWN$H5QMiT9w@$`EdOe`=%s z!AzPsb*Iuz5i(yDwHCJPHO4z#Mk;~GQsDu@*GK;*W+o&c<{@Ogl}S!ZuRC``y9S`D zeL?q`xs~B1i*+~<`FEu+tU&!0`er2frW@9FG0sM`^T+HtK3Hsd4KX}u^*2ew!e^s~ z6g`+iA(b-10lH0yJCuSgj26P=)3^KIquaNG)>qYhj=wz2?y+DpWi(2w?=?Td(ZS$& z*_C&=PK3DZtzXrQvpnY@>qU7|g*-c`TBo`dYXtNp#l>nkZ1Y1>MU)OTcl-!7TLMtC zeGk;nK-U7+*L^Rm^v#IuU%oDHow9g%y?4YkW%eT=8HRc#_9GSTlc$)*8q$I4muCOS zk5SV=-CQ9csl7qUfcj5CsvHJidTZ?$%E*WoRTNkd!zTluBYch6m#23-5f?r*l!f0D zzH7IgS zt%BMm9wk?!5T%Ib%x<$A@%vJj*xu~jIo};7-gmN3b z@qj8`-Q;JpVa>-`p@y4;Bzj&JPjb%40cE{$)k%di+1_R}{8WL+Q>TF{%lFp@>5kXD zeH^&<4|Ac3G|A;UaCNEokxM)p=l_iy8iO^EU6_Mk&C!Uz0I}GIVq76M!dC4D4 zWrV=#o}hm=vg0g9N&z{SI(p>rTZsy&$E1n9VWTH=LwPQMiX|gMw2LKtqY=L#pyhaw z8wqyz#(0?a@XUW)4C=5@)29R6ABGUPw25+%qx?KMUE#8Dc}0b`>vmyaGlH_Mdi0WF zCqB^W79L9Is6m~ffC^uF!=kD`uoPxF0CPrfCW7!KwW z3=dp28kyXslW$p#TO|3fm%FvjGr76AI(NZ8FOdvkAoWPl_R1zkQ3EC^W*-rQ^O9J1 z&d@mg`dCaIGFJ`@>;I>;tm7fuzN*lxCeQC2t|T8VmyqG5Y|vux4Gmsj&tt@;A+t{> zrE)_ai4q^-BMtr^9%jPxVmk-!=ShjIHXUGNN3NA(ah7E<3@+`ao+hTd?XxptQdA50 zEHL}yx*b8i-)59;ag+j5*yO1pLO9--ANnF8&{iCP%^(Rtc&JE54YZkWQAJL5cMUVDaBl;XEKb55~CWD5_2)~A*E0It**pxD_L>dF2%{}z0 zZJUfLs^xEDlXMj@QC|siy&He>8KsiFAFYttW8kj|mFiTMDQUcPwG2fY`5ST%BdoG` z>Kd>Xj~RGK{~NCzZq4cfCB+tGj7$br*)ZLQi!!O%(kI)O>hR949zzBA_l1|9P_S;C zr92LjQ$$of{7`4KBx2kw9+2kAXb*`lTMDGH!OC^}KESYQd=~5YIs=5sMDURvuywtq zY#7}NQ<6CpO&AC^WN&iR0AVM8>Q%Bz3~u=`B{bMyG_@a4-}rQH3A??tB;7H11PPyX zJ~M0PaWXn)In~Il6eXg$BzOEReSt^Glz|RMBZb%i4h59R31%_oc`9Ux(7RHTiVS2ddfJQ#<*d?tL|gvFk~Sq@=0)4jNqQpYg~kfCt= ze!pq+2#PyDcQW3?#}U z{wVq@IuX6d>t;+$zckn%hk3Y7Yq69vjEbyxKj`HUX%LO&NCIVUPj^?xdq{gQ*xMJ1 z|C}qTg3`;+)tp6Av8cgA>J z?L7Pb_aGQWf@WFT5~8KHhYjHCd(6dNXK&vZ?*C0tug?4gyJN~-qENrO~MlgH;!bQY(fd z(PYL{T6q_~*-6R2_d|AXNvlVyGyeCqc=UcWo62)E;-h#HS#U5CBDlJd?=KgZVMax+ zhs%EMH;eBGy<0OQM1na>&Z022t@z)TTtTnLF`^&-MakNb1J2Jn^eWy+7^8~<0+i0i#fmc-n(pm1qwU$%9#-Ex=)TiXn0#X&UX zh59s1bcthnzwSL*=5t6{(`Ot^S>OD7p6m%cnK-e@J>ptyeOx7-Zk5W5?ctFTkNkG_ zXXr?;j9^^KmkTd|ocz~9uHz$u;RzXJP4l~iO_;2*nwHe-W07C;K<`&jGbAM?{q8Lc z^!`O<;4J}rJsdT3pneFEyROT88AA428z^bc^Km@^!b_5oe^K8kc#K_L{76xCryU^W=>Ue@2Y@fh&o<}k;4wHeJoA4>_D4 zgQvIW0Y4hfyGiK9t%DVtP4{O0IwuR*#_`SQVQj(me@BhWNqPNKf1|mv@+n)t^9SEN zVSM)Ytbagcca)4d(oY2o=Urqa0?Gu2$t6+zIBvC&qga)2x(AQe(rL-msHlw zesTLHO4uxKOOuQPe4zeyLZ5H6#@anrgUfMSrvrZLK}~Wx8j#qqd$0>56ckKq13Q#TO{?gM?Y<`vuaJf_lAf`# zO=Do9CbUEz*+`Fq5r3#^-ExQ;aGtSqb9f#(xqn2%38|)B`3xP%INW@cYsH? zH@yBkH(_PQsYiY%R*3mF2F$nKE-jN4J+UVfC*6Ey<;PkLwk+d&;r2OSECEwhEE;aR zwJiEdfnPbJ$y>+43(_>rUy`FdrTc-<(RH!NEgz^rz&|=fqjc4hR|UOR@oj<9k9RY* zF?Ztw{i}1>gVo~Y^qX4DcN{3O;A}F-ukD!J?;!WrXG-m|#IA77bigMpSmRB!XS2op zUxYSfEl|;$?XJYi&64FyeE)?@geV!{6x^?E+NJ2?D~CAWY-!9@Ar!uxCtl>hgz;Q#YujsF2Szq)|f zES1Sec~=MpuUgoIv5b%qgwzZ1M6O-;T=lkQk)A*+_wQy50h0J{wX9-p2I_{>-Hx2D zcv64A%)?`T#Mxs#P@`!UX!L7ZsIp>ju5^l=cQ2F)pDsf(&^!w+=X4b}*mab062sPnT}0DslE`B$!mtX7{{qVg9=1N|c$DL@33%D!!q?UJ`jwpYl$JHNO+aDYWVC+1Y_Q$px4NN`j{ZBIiPEKtA{c?C# zSfyprbO9+9^!Pgn5_9$PFxJf*TvwCh%mUWd$SCQ7#{J?0e(BCG)&thZ`Dq4ng=pIT ztsJ}nHNU^Q@)2mIpCtoF-f2~(ok?&eAQG)M!Z|n+BGqzw7(UopW9k?dE=Zd8Hhi@u!&YtpFHL_SBog+Jvfi{M1u;Rs~Wners`86%GKZlDa%TyNQ`F2Rw{L%XOCtPr2 zw+)xP4H_6(&6k(&8s20J8Lj>#@(Unipij$9l22Ot!$0n5V=d+Vdk(NhI0p%zKRmUL zD-IfXiXa9W%WQM`>zbKgKkqjJ4*H^AX0`gAbA)WJo*%B~LH`6e+ClLXlUDxx4?$Fn z+#QC51Y_p!6ChQnxJ9*ivcW{i;W3@TDv>L#e$r$VDPr+oI+)5Sbo>$%;W2MX1E=r}W|dyncuIl$rFK*8#Q045&<$$< zuD8d*{6B~GYHspjX}3(pWdP#|%~OA|8eiEhA-DNpphFppz9gUuLgxxWwEXb^&V z1=u7|AL{zI{c#gW?2t964+twFWp|IdV~_|4+%n9a=vFd-+jUPz5^MKpWhmGvz0R#7 zf)c4u1v>kaUXkADB8k|++Qzlc%lP^&ZmEcH##>xVUPY6lYU7d zw>R-{@Cz19ERoEWCK6dX(#8*enDL^{4>Jm7y-Mr?K%6&r@a}CX8h8Gvi=T%HP(3KLQA8L%)Ppzu87sL8XZ7h<|v9QRBzryj=-lg))hq z{Q5DAodZ}K8Xs|_Gy#KD1T-R9rmq0H!kejJDqCr(wYxM<*N)zRElPZ-9OOVshTY%B zSgoZR@Yu&?+e8q^`8D^vW1}WY^q+|s4#a$hCAwwaUSot7tIlJayI4>9n5(Mqftd=Cou7AN44iA8%q&+A2} zDf7~1BH2t2sfG<4&Cz78u_EqlMSL20twrnxS!m~AGHSJghKJ3I7#RM?1YE{i1Zw>p zTiT82mBiUq5Y_hp3cj)e&k~%{fbMBxn!kWxY@r^St<=fw{m#@>xJb9jXgY2A_z#r+ zT`a0XoAulkrGe*sYYMU>1M>589ukfc1_*lcD(g%s#b_ zC~{ClUhKXWmP}OWdqpXhC-z3?MamdL7`h#1E<+ZUkUJmeVW8S2PPnnpr6dztYP;kHNk%3?kGiYE;Ftdl? zjN`hf<*OzLJbo%;(_!Ydt@F5Mf{keAngbS~9l^s$is0uoXb~ccS|VvN%1X-vD*Fy0 z=OfhpkqxVThlP!~E5{cbbf_Up5}AM1H`u#rQ%$sDE!A3W8#1YFo? z)s6Q_${%S#3ms@g8exKd%+I7o$vJicI>MiQ+#FraSF=sM0D4Bxfg~xARwWN(yp6LQ z0C@^ZvFUit_q8ftPl%~1on=#C$m4OaSI*T_An^G|AeoKsnCxs(R-K>+W5bfHAo6n%AppDK((p$ZzLvR=J}RSRxbI6W(o`sz#~xl=*cqA*3T=Y%UlGVTenT z4pcCnbw^oH;$2q)T-Q-bpQ6Z(heS2TwuJf{P)H63lDp-&F7r)3e-x;He7Y!v<5r#il?)cA5Ar%f=wPKcIeR&d+Uo)@J8Aw=D!NxY%Ga(+J*! z<+w@LX$*>}htI2bl*2rJ{Asx!uK38d)BARe%D91E`Notj0mAwA9xI)9X#S8n^T9pC z?dgTW+k|B{coTzaLgeK?dJ}sSB+-l+8(Tu-DY`-p0NS~^Tm&C*DohxvT zjtE6sF^bYA`5a0kFU4Qdqz*@5>wl4cJv49#*3Kq-Wk7$0|Ekx4$QR`(+v=t~m4Qn; zE4!?HSQOeuNg?pcaFbz)`Sd13qtC19y8`URfBdm}0Ss9`o_~{*&Ywu%cnHWtHZPn_ zu>?q|(fOp{#k$;dUajnZtO>n_A{b2c#=x&Qoz(nKbCAOr*f48JXl(?|#K zRnu5urD#IPCt`DNOdY+$`&~c9-(N5xl~rc~;#1x#)$e2gyl2*syNq06ST zC}}l_QPCuS)Yk^g0jW*S7giuLmzh4hT;83Li9?@qmkjb=-&_WcSf{1FHhh5aqDGI% zZc*)AFP{8I&xbJ~O-mS4vZN3hiUzl5EPTY$EU0a7cV{g2gd$1-UO+%(U{L0rLZ+-s z+bx;j-^W=8X#JHXCvVOg~>O}0^yY3=Vh=*Mqx~uw)JRK!p23?P@2I! zY0?Jyh{bm0|2#48AOiVMh4p)u zOVnIQyd|wHoBEOtah*0Txv*YNaTKk(_}B33QbR$iGHYq&Gw5ZEq0J<8f(9Ff1PtI4 zAx$}{v}R%QIeuH2rH^8Ab*?~^>HGMiE=q>zGo{A1oz0(ijh$bCU&C~LJH({X+9qPm zAa)$nEesd;O5G7M=dZ>O{VfpP(t( z;&yL)bA_ypFe+PmvgDL##{CiE20TMpA%}xxGseu`PnjA9L;5obGQIVj>o?}By`QB`eLVzR$#F2OXtBY| z7m1)HCJU3>m`K!Iv;zZ`)RYc|yciep8t0DG49UNsZRRx_%)WfBf|8c!O{#RJ>&>Td zr@U2V9dlPAA|zcGsC?zl_&iHpT~mc*j~zVNql*#LNK2R!n}mcwqeGQJZl&M_*%Gj- zQ?LNpqCFM3Rr%j1f+4{FbufP^+}e^({FHo2zjFV>sw(q-h;8i z=hzoh7JuXf@D@rvk@uG|>yCfZd?LaFF6mnrN53t6kJEPCg#4Lb)3=s!-q2}D`p-wg zt8#{Bsv${w;gcJy8E37(6>Y&`t?#b1bu}vYFj{&8l#&!U!1z%NlnbKAcg|iT8lDwE z4eyW62AzCo6gmB?gquei+PKx8H|aw_M1##nsSnayIBdTH)_OUG_LmpY?o_?uB2X@J z7csF{8hW>zo%Uw;m5CT}T4EH9I+V2BU+w+_9DVzBk@qf4BtA3?^^tT-TA7RB{Q3nr=MLsT;Hhj>uGKxXLSO+O)?>3=8rBAL0PJC>XKb(Ma9uHGhpp?X zk#}vxUvb+Ny#rZ!)y=ye83u(Il(;)lUw_Dju(mmp74Mm(UJ^&piLW5pfJS80+%>Xw z{iHvws}8M?lOx0X3EBM%Fpxs>7?`SmEE{re;CLXq8AeU?3%xNvYc06q@xdn+&?H|E zi4p^$=fdrXsfQsTB{QGq1F55=h)Z15&&?*|)55(ZL;nPlg!@vPA%wYI7e;I-Uh*3- z&KSAKN82frG4x4&zSlfabNavS{AYg|eb=g#myEdD1m zalEQpaY@mXgg4Sg3ybMio*`{5oaTK7_Qevt4YlCf>|;5v7Z|yE95-RXgGNzw4BWU zS~_30Zx|gW#AjK3?`c7b&UGF{KA^Qbm{8vO>(zu&N3!F@3%&R45>LDU}1qQw+~@3r&q2zkckPPOy07hI;bJJKh=Uoi6H+ zNr^jTQH{6yV`KV^x?C&6();RJ6R5^wuPsvdJ|BlzcG5m~v7LuOLGgL>M50Odr@a>Ea)fg_`zCM>UrURxaFjpALy^YeQM0=|-6`n_G*t_O@K6Gvn%`UnZn?(E3pt$vwl>t_(_FX*8;Pc)Fq;%?Fx!nJs zaz8$Zq`4b6sQ)(1R)^bD;YAYve~^&#KR*?b1%jHf=buv=!IDZlp$fP9AA$Mxf4{#- zrAT^`(B9r&I@<*JIR^*psow5|zL}Ser)3r)*GX|{ws*ll+IIiR_lZ}fQU-8s`Zwo5 z5K~FPSe_{vNFa2mCg%irs7*GI^b>ZF5%!-bpTGFbPdNTY1tc4mU#gJ+M0l$4_C>5> z&Py-?;%f=iD@LOd^jgEeH38@5RITH$`Mi+c0Yk5iDT|Q#?fOy>vJY%mvp#A0ekJ`x~V*UAu8B1PnYV6YUkJmj}|z*u*d&7$%o0#5UH z07L)1&fS4>KDSUnS9gr<8sxEcD8@$oTb?rqQ4|llHnlP(J$EOj+DE^5)@I&6rI(iB zHm&?j@bcx$q0B##D0fmjiPxkhl}JjwZr>P3eW;6=NGzqq&1Tgf5R}*c67FRW$nLxN zn@kA?3Wg8>DPq3^kkMuW><(nPu9va)YwyfmYezAOtTAv?0}d>;H~=pa2j&LNW01_g zeH6zaF(~5PU!~e6r@8^8l)TP4(aYbi@o=G|N9+hk8wIa96rb+-UA+% z^IrFw*PPdHD&B>lx3O1Oxvp%Qm+vv*zs**H1H7%R30n*>3e&mDVfc>2R=7ve5Y8XR z?3jeFS#*SLpF;>vV1hgvoO;_HuZXac>2$Y13&(B@#w=h0{jPK0U-5a?R)sf2+644m z;KR+9ks2Ku$|b-z3rk3t%3U{*>V>m#?l~r`%L%F^!6p(9$=0ltM%o00OsjBr^r^~# z_?i?_fToH-(yxZ{v+PU>MFMO+*rafUCP2|Rg?v0OH}{%^^Tn*QgX*;V$C5*#i3wVexEF3ngxDWK z0BJx{R<=tF1Thwm^P&B_)n#DS^%~9WJpx7-(;*kOUrkJ~P|h%t=zdNwc-T#&-S_`& zTJ*J${^;>QHNj!C{B3Q#jEh zVz+tKyoqIud}y;Y&NDm3I$vaJZmn-F`~dESkq)t5GgP3c$Z!BG5)gupMC8+BF-%9;tFgBZJgRoLqo za8B#i4KjXiG$ihc}E&7EdSAT&FGEfr}t^fpp_CGpBXAZ5Ty{5i2T3zv=3)go1(5JY3BJo0hDEVC&|L#pwfW{6#~5_MeKj z7sf!2Y4X!zX7_r*~FcFt=>Nc?%UtR>)y30j@mW9tHp-;_kq29n=*(?1#b z%k_HJ9|vUZrp@#M*7Y{mHfGlK4#OVAVESgZ_O?x>_zv}~3Fv8>DP55;-StNAc7}W; zMVPoI`B>We^1!(c)40#t%@$ysF4@&!#LvpP!k367=U_Mn`+Kdnh6a+c!_Cg=w=yhn zTe)<+Z~~*}4as%Mf`Wn~tx4X>r{TUL#U#b#>UGwCO>`eIH1w?;4_vDHUzf7^$0S$4 zp%cNb>05ulw^u%8IeP&ELRpjnGN1*;|C7BP{|zP>3?P3m$F8^Mv5 zJ54~V-rxjAj__LkA_UgktC)WP4);)B;CuiRmHfu!?<4A+fTnO zl*oZD3V@z;6_x7wR_AlzArK#%7-0R+0(1xe0;pVT)X}`F@I6xpq}gRxyQx`8eh#zr zq*&CIdqB#|?j23{yzFW$Tj0t#<7Ghl=&-H~5*!5yz)}OXZ&?|+f{WRPZZLH*_oZ1n zW^HvGdmYDc#+X?}sRdA*e+ydyT!7X$PN(i!FdJ;Lu48b`-n}&O({6?V7Za#TTQL{is@`)0ld3lfrrS z#!cHZJpI_7jKJZ2#+2=SOw3Hqi5@VKVZJ|M*?2eF{yS(;&E9O-Bf5Sqwhv+j_EErn zwRn~2pB2&sF`tuoJCBnt`OKj956@=fJ6l9cH>dd(Hgt`1mheb^_ZBn#1apig-8q2i zcul~GQ_lI3`L2D<5QF8(6)K@((CCLz0SZi9HW1+qI4HQbK)~Fik&aVeiCs8~>{Z1V zE}^5y$;ql!`U9#)w<~p|DMbYZ`fr((iN4=_^c0^z8Pm3Z?whVT7NCwSO@BcAWWrwO z?CT}O9Sqm-9tdvlw-;~20bq~c@d*n}knr>T><2I&9W4iKShK#3e0X=T9HNjGmszZM5IJc&8sFNgSm|$EGEI3GE{T#5fz4ZgYxctm z794VJ4+^zI$qqn`NmLne0GwzGGv`#9#L@(){(*kr17A4!8Q?PR`3^uWZ_eak<(}hsdC)* zJYnoEnr&d)=j}eK z`eYijCaVrpcMK0_*bGXlV9@2*jx#dWnhzbFHO%GuT8dbO0Kk!ACX=s769$K_Eu1KB zP&mZ2nm$v!Adqk>NO;&hKn+xxw=WZ9`D^?C3}54Sh~tM$?K55)pY8uVC;gRHg@Bzf zT~$!@XQFKv1Dc=YSA@>79R=JnUmOHwn8P?IK}zsPhp+!%F(I9huh_QBEg=aYG(gW# z{MT1w&K+1vxZ{u$h0WZ`2bnh@Aq(dYk7_=4i*i1CD4ons_ z51y&)uVXuJ(0QPuir;}P3bYsH$mi#CZ38pRMX&@wC(i`FXUXAMt=MXjH7kSM&h5qfQB14LX>>hG*oA5FYX4G-S|-xsAEx(o$>G znhzg>l+$adJSgu5@kIqU%S{3J8e&Wm=>>qA0d$`UdNDiD$_z?n1>>?J*LhW>v2a>o zPsukm$>Mf|#1bVYWVK?IZKKxu$9pA|u$KfsOfH5Dp>-k)QgJ5|d>f=PJj2Ek(s2D~5!uP=m=$Cd`KCr&?U0>wxkg%#4?VO= z>@MPR>8h>t@x^g(@k4u)tU)8-fH#~-4#xmas6TFYh;StN^Zu9}4zt%qAm9VN`JS(` zgar6LR?YNU7S`Lo6avatiy){K$f`!V0lNbS?eJprc96hvyWVO>^6mqQ8v`SPX-AS` zCn#E5KCHcfg@^W@M415%_d-Yg8$uR{9BI%s4)k5aw{p1HmCUf~fY8JY!{>p58ZZa zohC9y5}89Hh2!<(6jTfO?F)rT`TeVEwvHcw{=PJl6+os=HDv%&6yJs7M+9dkw;MBH zJOXCz$g~!{`9p55Ns6U^K~ntp4i`PMe`nDFB*tB7MqAi`(X`zE4S?hSD-S;Z{Y+L1 z0MH2kubmJ79X7qDsZ1UcMSNe}svW>!L8jIdfn%-ve$}gCX zXam0e)JK(4IpxzNpdq6C{N$&Xesh1^HskaGABAg*2*HWj{}QA^6Wst;e0jvLo;PmR z_61f+l(Wti3n~9(%X4OUy<;^MFd41u9ybu5-?kQPddXu7`6B z%~C*FIB>TC+d_LN7znh9?N^qyXe$kOzJrNkNSd zL6lGBqhzD#n8j?N9=>-4AM2nJ93=n$}2EA1UJ^ zH1gY@fte4R2p@NSEI2aF&|o75(#8dtNCpf+cjZ90;ovmL-dE{Y6INl4coAeIWSX$; zMsu7!f$eM_F!O-?x!O&yeHtDu&k59)?%#XPM-sjCriZ~@Onleznhg`kxtai=0PFRgx~*& zyAb<#=3Goou^t%cQ8urD!Jj}y)^2bLa-pDEr5!_{5+%nK0S@NDc~_TdZ^AN(3}~mk zDd%4Z?m<}j^;(x6%=jqQpy2u-3GRPPdQ5uJgNf!iP#~}-A@0{a0s}`fvE4yfYV)?Z zggTh9Ivobfr3?50_p%f*Wfmyh5w}@#yl8PvppnyYyyTTV!c$~Ag*z@`BE~A^sw2%L zJ4!I|TM4HNv5V&ydB!$dzFeo-Zvs#pMzVZcrIfUC)IM<{qax4j;qt8$QgQd3HlE{+ zq#RnfITw-dzyp1xCp_A`=C1|6IbyM&z&82W4=%7+2-84MQ*}H3mo{pX?gq5=GJ9C4 zAc)DN)(=5C{?!xSUk`vjn;_>Q_Uk^z09egp1ZsJ`C#Ep-dJUlu!yW`XqD9#W?*)!y zD`Mngn&{Q7#*6yFt>uRvkY5qk^C7JOL{XO!>;x!htf|Ds#dBCK(z*0kjV->7gat-r z?osR5t9V|aKmg)Fpxo+X%Fy+PI-RXn@xZ;A1>0&D(JGGH$br?8nH)974M#c=DdzjL z72rru08^y;OG2+l=9yuurxMr=82NH&;sZma08cenbHW3CPHIZi^#X~CO*Ti(usI<9 zd@Zk6AAu3F=n+h{8P#nNDbbxZZ&-%#Yn6rn4pNDBeDgPm<Z7;k+WfLVZiC_CDB^LV|Y=*K`4lV~};Fk2t<>ZM-N#474?`oZzDQJY==NmGLe zD8p(&p`y+B`9+v5dn8SF9%kEcYvYj^?$9zSaJ$`5H*%t6u)BMVJO7Ub!g@stDK0|y z;e)LAwcNqi&nxA;9){h?N#$u<*?7hHZ0#ptsFSaBLR=vy3NAuUe*Wg3^YcGFy27-I z7 z22T_j>@Z;0svZ>FL)aBETc`?G_LIOHDA#Dt4D7~3@BfE{Sd9qzau9r(21Qrs3D}Jo z%G6SK^ya74i9m9m9}sbgGv%;dYIN#BM+#JJGo%*5CSe|hUNPRG9S9%jpKE?5*Lqd9 zid%1$1a6fGi$_A&kWm|yxmCvl4Ne1f!IuX_CbwZ-AGCNzOp3??I86GSyC^v{qF>Li zO*Uzpf{A;Zf43eNv#S7YiEa<#vsq$AqY0mnbfbD(>bsyt~5y4nYOmzGR94vaaS@PfHhm!$?j?Hcd zfi1)cY4d6cVs{{dr{i)8jeIZi2C7-WP|#5@#d0!3q##Hkh3)YP0lr_~oVixjVakKvRz7(4!n@3c9GjnG>QOrOcl~1(?Zd`vP$h^0>2?1+q)PKp^vlD&$;J4~E*_a^8Dj z5kESb$Vz&J|A|~0#zmrHtHLud3``3(ty^5EQ4x+?}t2wLI3M|*;Ej@^nRtLT9aLx zmmuPp_|IdwQRsbjhrjBxCpkVd=q{+MvSsoJ@J< z_INP3cK1=r_$t4;;|i1e=E4Nt3kr*i^>!~eKSS6P)Cp)niRVZv@CN>kOsk(zX?5#6 zxfW1TQhFzwG1vE-G{{i+7rMjsEYx_AZ&Veujn}@*F|f6QvBtd=^TGYXpI+XW`7VCq zDvmnu)VJs1g#?}AzRcw0XP~j;C~0WWVD%jPt;Tqd-&+vg;NN{suFydzV?+B{12~TZ z767M`@HBVqmy(wW&aYAPw`oNvVuvCbOc+7B9BdotS>OQ`4D}BSqoOGah?9VhBKv=o z#Pde*5nig$iW~n;9RByi|9_h_^S{52{=aRUO^3qE=$RMep*QSw!p+Nw8!#9LjKld~ z|0L7(jIIzNMTcZ;W8~=MV61Qb^2*l00ttzUi;{N*JFCle$4zkQwQUtjX~k@e+!xtZe@lh^+r35dSNR*j}ROKLpXgM@L4CpmaAQM$qvs zuA>fPYpP^CoK%O+VaI|{M}XU;iV?00!_${{3pT}cIzs|Lzqvodax1iTrNa1_UzqR* zUJgg-;#-Pb#gV4BX6f>T5V&brw|O6y!TUHs-f{p)J3CQ zDQErpS~A29~NsEV}9~l(7h&<&)iNN~swH{OPGV zDrpLal}6>CrROeosLr(Cr$W-A>>$q{yMMY~);i;{Yd z{Ko}xCPDM2;+$m_6gN;wDz8x9~n~ZS%xe}ZLCVF9fsCL#LM7@Z(ym#II z*b|TGI1wjkU(VhZcIDGF;Wv9-?fu}r&aB!9T+0=uuoS`x_?+> z^Gw(}XE@ZeBJcsa_Kt`{;o5E+r_j|V%`NfGsZdJtT%4KrB-OOBP0d?F>+|wb&r3M9 z6%Yh6pI`1? z38H75iLaFB?uaDhhTej*fzsSuPjVZK5bf_U~^ zII5=*iowF|&|zQe>D(&z)xy3u?<4N7Bf6hWPmanU^xZvv@jkvE<>^0{aaD8v$A^mR zyGT^zAEBwNm`Q;q!{JkH_4fegM`4Qzb@dsU$k=7-J~hSWb>L^NX77<-vhWo=(gmu8!FY zdH#-)57Yjg9{#$R{+SZXfo=MoPbOYt)ssiv*NzA8p~0WA?kbKl(po7#(HN7pcTHv+ za1--_eSuoIIx7k)KHGg?LKtks-#!9`hRSGq<4=CDfRyU!!>m|}+ zI>JxSw`(iwE0pyo!`-5+r9kK){$2Lia*2Oq)>N{YMbdI2}ES{24X0C*!R|s(vNuZ`izc%MuY1x3E zh`xu%OuX*HoDToRFPWLE@(tVB`OU%Q5M;3VGq%amTgQ{IcJaP#!mA(rF@K-;qsJm# zI{I6R_Y``Y2b4A+4T*D16$pEU)#TF%>C;&4J8$d@3@b=jJf_%QOPABr6EbpTvqur4Xno2rKP*gEuIL5jM z(qW&@C0pm2I|i)lWP3 zl5&wYF|Sf0x*oeqBED4jk>(-Bzm@6nxZS@NsK^n(mZ``U^u*7_`(sk|T{Lz;eYc@H z7c*`Y?Y!(}hUU>nqc<$HP=BR-j5nLA@rgQ` zK3FMA50Wrxl20%2Q%>I(ej+_^SD_o^&!v8)P#i_LGB;9$EGrZ-T6wpXM26_n`@B?- zmn^dWMkx4FJol~P&TUMTo{9 znCK0S3fd6fv~puvehZs-ZsBJ1wxrvA*S~FBwXo@*&e)R}TN0bd<`6L|LZM$)j;mlh zMe{-Ro8+D3{heGV9J94cV|%obGPmec?$?{+P78Fb7{#$Skg}L>lX`?+Gh%-27B4lE zw?Uf@RbKV|6OkQ2FnBuCoBpJqkylc!qRf&Lp&F(Z&K1%t(NpSHrY?t>q2{0{-GdMb zo0#OIH8)8$J6`uai|!CP&YS9^kf;l~_=iC{i}xkzBWOgjyD;eh};bpv4{(lRW{DuAf$V>6ob5aU0BE=_xiC;#rxCe3`xk>(Cogu}6fe z(#3=`t&y?AtT1T@lakRQr6>LP%3~F(1&1Z6_nN3`*+KD7C}-xkwovMdACo6>Fl>Uu zlo@Mp;usDl`My-+!wjAVR|V_fT1Y|#njk@XOpUI+sg+195LfYN9MauFzc1NRFRGO} zOrs&C*=k@c8rm>qJI&R?)6Yo>MehiUpczuP7ucg&oc+VPlKP<$<|8v?lIF#eBDRL| z`V*(1e|mHTrb>`7v^CaG*uB83yu-vY&Vt=Qn>lQx;`m077^!al>gpc;94mw#F;9nZ zr}+7#j0k^4?2yZTp-FbDXfoBP1#JIB?7}2oYf)XBt?ud;6vi&v;GpaL*QE#MsWBKI zjHi@-Dh&5oh!wDsvUq%D;3c8V4-?|j5IC{lm}t^ln3Eh%no9fyOQ7@nJ0Y<_Z$tKqC{kiMl=ZcpNq0r*=CP6i9Q`}`>=IB`o>YWcmy(LFUt0|=K(HG$RrR+-LhKKma(DC z>W7geT&%2|3#WwpYzJnG3fV;R-pp?OuKdozg$GM`^k-`HG?HqVNlE>7G5^f;GlEHm z{Fq3if#3mz3vzZ^#DORyzw>Je)3dVfutC0Tp-nAd4%9lr4^k!i%|M^B% z@Qo?lhn}P2B_+>%mxB{b=doDv1Z;-a(Uk8|w=nV)r|gLt&XTCG5lS<&z39d){8C`+ zK4i*ASAUh&OE8)qCKB=| z{?3y!ll2xR>h=avv~j<0{Ck$q^=)%vRz`iMd!RL6+f~p^RNH`RX50O#Zj$pJscz5% zeoS7eLUj;_L47(sB%7R`yRq(|JC~OS5k{*o4+3hVr0KsA}4mx7;Q>L1Soqd6Vd29_d$N=IC(V!Yb1m(5dt}n zVmAR%1{X@8R|5GBMZp$=fzSjxeHUup#Mc=PUs`aILGdUUE^@BH!Se41{vCtZKPvav z$J<-l&EA$9a2cMk?%zsf^yMA%LS?G^rxgkq=JZY+tQgWFFRL55%#)1rSo%{H30*Ye zp$gWhIK~r$wTTgkQ#dJu90W&#HX1PogPd7q9da&==xhIW&T7pjANrjzEX;d

w>#fSW&NmCJP_HOlpiNy7P_Rz7^iIbBf-QKo8xS)?(3`9_8AfZ z)2yKd9Rznr5&?CrJ9LXlaF^!E2=olCLfTZEx_Ew<`veCgRPYcJ#;W9u#GEb_~hl`G5e^D~v$XnFZazo+F_&Q(3p&e9{<4f*F$NH&A{pe{z8c6e96 z1{M05cC>awT~OS#*BeP-3F1D3H2w@sENEdJe^@>+d%GPMZSH#qi$w= z14F&l__Y6fk`)KVDOmpgH?Bc%2U|S%oyw`C*#|YWinVlBY%=ZFY;00zomzT>oVkhK z%RoshX=520#K&2&e=^7C&A*snw6Fi$QTI_j8D7?1AqyVYUEv#iV{K*pR^V0?kLJ1c zl|S)t6doLXHRC*1a_UNj55?y7pa|^5W$nH4&m5^Eq2bYku;B0S=96dzle@Ds{NPFF zpZevWi`(q&%XS;B)SsqxEAZ3zi0qxWSOuxMIi05qPX?uvag%vmt=+8J+EI0u8NGj? zPGl|R86`(e{?WADv(0quow|P)$o00~LF;o6yPC!cTS7TDvhar8(l(b?m)6ck?WrB} z8l?4BPS_of4k_IfH1}K&myntn9Xd(v0HVfnnAd5ji#99$S+E9>?jNTaI?#J5`QKK* zWfixD$m{6CjF;?nNH@Fs8bq1bI?#g_TNA3`P~3+Xnu8cGP1F6>K5dpJ6XQ0X5<_v& zQKa^3qX9LV74~Q-90@e{>+kg^fsUAX4xiLhv>;ffQc2rgp`(btQLqYK1zN5`ldy$h zutKDjEY^5Ed*9q>8&f^twq|{&+gjl!(-(R3{gLlLSg^PL08(qaoIEjyf;%UKRu&5} zRtpNR56iQXG`gNO{clzEZ>0<0rD;0y&vtK-=c}{XkZG#3-yJu*9zrwR5bsnKeCMed>XFMYmh=a>I=T4if_)>Nn>J!ryitK%}< zYYcofy~B_Rf- zR?=hdv2>&%lBA9$A(o|{qPcKm24y@>c9%Pk?(L6H9v`t*(p%^qmU3Ih`IfgmHrhya z*~Yuuw4G384-b9GzWu3&woTTf);`aIB9}H-iPza} z_@`(qujk0*;*69Cmt3NG#Mk!maSBP1Vzm9FUzE(%ZH+S;rkd*A^)leUeN;I1LqbpR zAfJJL$D2{}%>0y}n3Ea6Fj5|~dR2eib`RP5u(jVsd*q`xyyr=#HSDA&_g*&u-Abn1 zLF2acaCqbSyd&gYEf+WZb|Aq<$B~hlgxqV%S1l!JgF>7YrSj6%3$o*t+VE77`E0@C zYSag;oG^c`bKMwH_!H#SiL4VH-sadtW{k4EyZH`Z&mO7W$mvnx)^~dze(b|#@whOa zxRe?%jd##||2Iud&c>?AxYfGXvVx!YsRQ11q@lv?b)x3`f#K+1sS4O0LFq0X5f111 z_;llyg1t?-`s`b6gFWR)Z)1NmZ9TL-ZS$M9L7(lr!q0rX>09!duXE--_perI#3s~x zwFogodreK0!!VmjmcWsCtzckIokdd}M!V)>&?PLy3maUSE;stu;Zh5`*FixdDekA) z3e0jR4zu%+>R-+-7OFR<9*k~Q9;8o71ee1kF}A*5b}Ch$M)^CvtIS_d2_C*R{#_L) zKZ>W6)v7B&`IgruYD>l}eXN3G&#vPyxtB=HQa91zSl7F!@s-7t&9q>V_fUw-*SuV{kZ31tZ{##s3SUY)EF(aSTys%Q4 zfs%#Nw{AjSG34JQa_s%B^r%Un)P69discKovBpfcr^1;QS2(kx)_n^6%~~W85Qfw7 z4Ni-2h)cBNeo~JYHhJQ17biGzB`T@NZnhk3`l7NeY_&f!-_*7J z?reD55pHF?Wk#6($~xk_IKxnW<8JRQZ{McEiVfBK{x~}IK&Q5)pre|wKl{cOXG$vZ z_4FirlO1VjB)eltXl1+h;j;8!Gn#_2ek_niCwo~mOnpLq9rrlLSyQW!`HhU7|9CAe zss+OJ!(3)B<9(2JY5C(Z$8uFw!B%Txcvfj9lH3X7Bbcm+!jSHGuw!fe3u>>8^KQ8x zUDuQ39%J_==^4XX4$I@FF-JLhS?EGUie+xF>uuC|LI{^QHc8R$^M~KZi~H64rQH>W z{#%$&T_gkJ==@4L-Y~<%Y-F7=;<`%SyypRD$SJKn$RE%5-VHppFyWuSj|kBuRm;4^ zaf&H;kiAvB{p=1723-2&BCb3mVK|&*dnfrjkiMMG>|>f8COvZ{(AXu|k#GThT%X+D zJO6}H+8>sdMxtsE^2b4pzL9`*j?+u5Rh*}&;*e5!-9f%fX#S)7Dv4YL zss`rIA(j_y$2+WFZ#wi5Nt5-$VI(e15N%>sxe>)A8AbekVa%~os5luqIItd~VQi&N zw4ky|WA%z*&Z(%A^&()nlybVA;@c@9C-`M|$-ZB>O53%;SgI^)Qkf9;kkSc~9R$PV z!a$Eoo@Bs~N!!UF{pqN|`bg1Xf>`PIrq)k!f;H@YHcEj)uy+B<7a@WPZaeD&-VmS}eTmBTjKebZtCtA8xnKo4pC? zpPVwnwYLp#x5gQMt6@UztXPWaMCvMDf0tL&om##hPk-xYp+j=C`Q#FE$EHUu5c9lU zT$6b)brJPRYV*$(UutG&7TOc10=opSz%xy=)4F)1=1AU8-j#>hWsTKYuI=ZGwU(!y zr30N|yw$|_psNnUzN=UvMA)`!PBB?MJmZ{dpX8Nz^{^fV{wCHgDf;4HKQVM=54~UT z!S2~v@Dsdx*AN?iHKd$dey$%+a^bH$^_t`wx1Dv1k&EIvPG?gEr!j7O-t6$qJ8?7 zE&6fno85jTV=uI-#wkvU{PcO6}RR$`|_b*x9ED2B>~KtKvNIQ7_iCpd!ww zBbhS@ag4Z>*E5^OCj9J^g)(NmJ?|n-!rMG`it(2l#8M5Kgm1Xox9X2&_HK)Bm}|Bd zY2^=6#t7g&$J&0z<5W{CA5{W)ZSl^eQsi(9Q;8QT9c5y zL0)2vrh^@ET5^m^umuJeD?uuTw&M*+L!}{s{3E@BqM9#ce}uf_jZs?3J5&Xy)x}!x zj&BL@lmmvQBN_Kd0OMGF6lF{Vdvlx0VUlpMOWtr(;7`z0-?nP*{_wQ)?U)PmaXoX2 z;YjdzNVOO9yk$7bpbj4Y>VFvUJkD%ByPUD7ckPlxSzBp` zaI!AaaPoyf*;v=os$MXAk4l874@(Rgq6eAG!S&AF%EA3?V)JLeX1sIKrjX2$9ABIl z^Q}|0jU87ZKI(4`3}=oH+wsEjw9;|Hyfsprn~R%Yjo1?+#-+%8F^^C@)`d8h*7prF zUtQ#e7g-nIoCmOem2oN7K86#-n>u(t&$4a)qTI&!l$L=%fgihaV{%HMI)eyn7qUqGe4KgeR>}S)ZIl5k?%h@s+ZmzOgZ}9&FvEG z3h&`n3lnLe8JA{Sd(GZ-K3&ygStEE`<#8;2wY0Jo@`B5Zx0N@U;2 z`2p^dAhd)TA`eOd-&X+Q7i1;OY8pg3N_!2Y+ee5J=t?RGXGnaRoI(h#=v9vQZXB=- zsO_~75vaa6zK)Qbvb3(0rRcuX0=|@Xkeo!m(b)M_N2riH;)1hw9b8CV-xkb<#iTrx z{n@as1uVUJwxk235_ZBM7|Uw^HbE#C5eLb{5c#G<#Q4@NWY|eF)a(p5lvXvR`$-M$ z{p!v%?SOsvb-u_yF#4N&YRl-z2L&Ifk+}ZL@rCQ2dLel0lx8DqLLR&Qhr{cm46Qah zg7eKsj^B0Kv$&CR8SY)bzP8x@Xdb#=X}D)NwA^XPdt=D4HgD>insbh#fvN|~Ys!p7 z7jhn0<15F@L|%R^V>bnJFI%|;voBk@2ow3Xh_yomJG`SKP#Pg5@+I`u{_+C}g2!eI0F{UYjmV51UCXuf@b*RpPI z<@{237#lsADQ8jid7=B_W+7~^@$ZLGJ&Y{~A~)BiWY){OZMG*h^5>OozJj>3F}-FT zTYsESQs0cWcbWV&od`m=p3hQzVHo&ys@vd{@;9WQ%+k^YautVU-_H74~@`RftEbB*_@@E%bMfnKYv3OzrR(&)} z{^v)`E83&Ms~Ys$wjmDN@y)o1^8?ESwFZqD_0>)w@Q`Nta2+nT3`Y=S$)Hf3PVUt$7u2IFMMWrC z=rhJ8QBSl8TDoO=j%C9(+bbDA&EGlW5V5f z(zRcQK4VU4ud)NUjZl1p+~V8nNJ`~UM#aDwgh!DW(QFmZS>87bB6?FE1qLle2FTn8 zjNc6jTJ$I)N*txdBWVV{!#By~p9KdCbVbm!99*-rV^U^!$Q-~DwA(7wYfqIKWu1kc zoraH%LsgGsd{(~|Kz`)M%=AS1T!Ag zy^0=^W>f8av~e?s>_>igjCR>$?RIb1L~*{0J+R=3zBgf=)n>=J;7Rwp_IRfzj~8#d zZS;JT?V$E5VOy=H*hx-K{P_{@!udX?SxARvH|eh{^2cMj*IIIQb9;8l5v(D@Y$nqN zaL+kWEICkgG*|LhqgOS#WJBq5qlNi>TWd`=7)Nk0BPGaow_^m9!ACprSs9!<)@sF9U) zmd8=QsVl$zO@G%t!MmH)G7fp_&jT|998y=!wjE3-lwVjT(6zEhbN59!^Q5vWCkie) z2K2-a*=Ykvo0fjVRQhdaEJpiUwEFAxDmyjZfDf5DESYV&d-m-A0~Lr1Oo5BX;rcC?NmutYMBgF4oZZJ^WZhRAk;HTc&8X_#{O zYekp_VzVZJmtsX6LIs#YVmsoB8DivOMO>DFpAe@W#b#{+oyE+Uh4L_IA`~nFF~wru zvtx-F<=^Z0AGt`?$4+EONNy`l1R9VQQvji6_6AKJmKWK5oZ8x#5wKyr(D({9qQ%sA)d*NQZV-)__)g{naCwxKyqeb0mBF z=EEc>xn`kX&`3^txn}u=5C-39>&1lh0cvk_R@?QBy^5MdZ@mm8ucr&Kky~!&M;>K1 z7>z+#LEm9?YBssnLypfq->u`LG5NWS@~>|ZtTM$yr&Ipc{wVW$s45JfT!mptDi-&$ z?F-%;c^!75%84cu)$}1PPrF1(UWj;SS1zE&&S0UA-t|l-pCX|&^Lz)9$^LCkk>NmB z0k_$t-;qMEX^vHIUr&mS>Yms9)H1y5qz?LE;(MZ6g+ zmvwnAIo;y&U%mD+S|pn7HWAJjFim7V6Kri(dSo7~i>K>76W+_%CS*hz1*h*Q*KjtX zv_ImDQJnDyhdJqQYc{`G6NpCNZ94M1Z@rUB&D9)x*#Bk{3FdkVr%4i~Vh+^veC(Hd zXTJjz-6a#cKw-Dk^j#x&ZAy81SH=c~2X-0*b#&ZM6JBwNnI!L1^bMBf@8gdnZnb84 zgny|n^6xqYeMgQ3ToY8#OU7NE9)<_``{0pUTRiW(T%&&dWK8P1n@^TR&ir`F^2@zC z;J~Br^6Ds(w$2n?&wIW|i|vwbt-mj-rqlC*keC+vs_`9S-20pd)(K&W>XaUxsDlKY z5Hrlsn3d6`Yk}E4KGtEvc3b)|+(WoyKSoPV*2v*@+o@jywc0=VPrO@=- z1be6EzYv;AA+;wvJ<<6pjrV_x*FE1Zt_~j*-j8N1Hkt23qgyR?%agHK&o@*}4*bsI zVe#0Dn3&ivj0k8UdpfU?m& z+Q%Q|bF=nsj`2{1NlzG3`3BF^rV$rMO`TP~Uh0Ub;`AligFtI5`_ z9W6-a@!3}4HNJs?yVh43f3u`+MamitFVzPzBd+oHSJ>jAiHCkE>M|ja+zjxQ< zdNW3f%24VloHC(Wk>csMAV`a}yS+&kLJZ2x9<#>Lkk8R5(l4-=5lllkRvfI%(13f# zK0{r-i!bt_cUms&*ZhTtRUGoT8TtKC(xTIF=b@0s*9dn#JB#Qm_7-=UY*Z(GXR z+yn(Al5aL9W&>zHbxQ3vM~GLoAk(fTxh5V(gcaL7vz+q}bsds1w=9^}m1riA_=svx z9>r<&kLGCaB-sJI#-v`|sc@oFZh}66w7v_Ir}QUumGF`|PkMH$5RcQWemzOugcS*I z8QQq8#T?qZLyVd(b`J;MB+BivJ2iuhNgS_q1M-G`v`d$h`3|A?7TK>8YE=o47tBh^ zv||`v4H{4PN^kvfH^Of_OP|G5nPE)hUh@3=Zj#gc&l8a?aXd$@S++~B^WN`QT^2d{ z-#pbPc}e6-b?q})JDqcMeG%YZ4>J14vZbO%h(gSmu+VV`2NAserXNUP#KJk;o|-d^ za-6zWL{OKi|JcJx*h!39+R+5XSGYyEWL~S))ZoSTflPEz)&$?zmxBQg=P8S6BJA7~ zrf>>{%cSz#|HRl^096ts?b-|s?l8DBxVyW%ySuwPgS)%C+u-i*?(PnQJ6vXVXLr9F zd;jkzqNBU3va;(0m382p=gpj64ZoC6&@N5!W`Rkv*P;6SD5XbyLfAu1LlG`0Hqj8AW80ZlHv$U_i>*H~1K4*<{edLwLE3f=; zX&FIf!sF*Zl8=v=yh@(FDi`)YB^LpUJXDp~Rhyml&ifX*TkkoRdg~2s_*E^JThDXk zn%>o%d}^F3<)FQlvYKhUD--2P56R4RxtedWp~)jNEu!;_>h?>EcaLvnE`34GB4yMFyM|stP#(%= z^_aUIA~Zs;#l$3H_q`EMgU`F=%?1Swd67D~H>639 zYvL+@_Tj?F%F5Y@-vqReN6{VoPGk6;c`qzOJM+dO|4{dgTtfc!((x6KeDvt6P#2QI z028nVF@&F55L*@W<8t;h&En=hM?QttE?Zv*;3S#guX3i%DnT4F;N2T71EpdfViD6y z>?6**p`V4|e3#^O7D{RLv=%okRv3QNsQT60JEpbOv5Ti6f$ePb1v9V3eZX?=uLS3G zWrqRe-c~q{`GC>h-FaebX9y0J7hMIf*HN%+9FzHehWiJcQ4^WX?>R`L$Zx~1@i&Jk zn=c0)j<9`mDlY-O4VzZl*p?eJYc$@=l8&O%ZI5E!t!)8D05x?=5Fl|iGxNUWB6QoCk1>P}XB!B(Fp+*pocvhpl+N@f( zL98@CU6A?i1MG43nsGiq7TQ}ya+>UwYp3l^{t6H<0x9D{?7sDS)Vd_t110>@xX4n% zjU=QgQsCX05cw(rVF>!QD*0rn>(_uK957yE)#_B9a+DTiPa^gfoZGEV#X=phZdv4c zZT6{Wb7fFT(jtHZC+MEB-$DF9Q2P0ycvBY4I8uG-hQbN;$8+1R58*V@hu2MCr?qvP zes9r;^{0fW#qb#7BayL;iT9Gb!cURk|q9|{(Si8`g!xm5OZk!gzrqo||WqGJ)^e$YcFH!L7bufOKg3)A^g zEA#VA5-9VU*Xcp$n%k-yi<6wJ4pDfJno5bs!Fs{_`b6DzEsll9p7c0u#?tzeGvB;z zr?VId=$KJZx6ig#tWR*RkA57d(SQ$LRxdAt6jinP1Ggcpj51!;uj`CpVa}8O&PSZ8 zk~|=bp5grqfiRY9F#FAiF6>vx@|XSTmxOMcvyPyYm~+slgNM&Q&;9D|JAZCcnOc1W zjI;voTME0DJy;S4*0iqDa`6LwUs?{AsGZ#5XH{=QCJL!nQArXH4b+?~B+xG|4KPkR zQ6O&3c;U>bPFd%LRVh|lZUyrsv2ofz#KG}m{8{#qGtSI@w9!EXxM1E zH05x9uAeL&@1BsRWSyvo>t}kxvBmY8uesdeet5OZ3B<*8o@_ib+d_`Xi1H#)%L?uK z`<2-T_ip`ERT{#FIq#j8W8=-qa5eURvFFcBt71D!w2dcfw5?e0X`2Y1A=-CExp8Tt zC|ck>nnIl2+&$V?FCNLV{a<9N0fuo`&5*WjkL?JZ;19sV1GnG&8*Ti#fRnYc2Q&Pn zNgKlyN*I1^`)9=88|3^Da4-+%Z3ie_7&OM8IUP77Acr?5OqA{trquSa>4DW7kCY#iUv@=XRTMOdt;!ZXZZ03 z*&C}<6V4wafJw9A!f5@bh5lLMO)@Yf5J+fZZc@X{OGu)h<%nlSYg96^Q~gENc-8K_ z`Th`-6LS}9G$Ud{a-w~LIsL;1+F{&=^AP(ebKC2C^FrRkE2E*&$aB0Vskb;`Nqxzw ze3Y24L*DH}-C7;A>EyI5mf$mdrinMSo}jx27EuHJ(VC2jbMZOm3u%Vi4=$JkTrF{7 zqrq7UQNo)YQyANe;3C&LJd7PvAA*>m9aF64kh74YyFPFqmldAaY?@3aKIrg}B1wV> z)~Tl~*P0aP9n+Y-TJVin5wf(Xbbuf)O4nE{3~8X_iH5;hDAApKmsG;Hrj08G;THSZ zUDM2bJMmB7`L+)Ovut*WtBBI4qSWu(pU!6<^{?t;T!TKyGMQq0o{e`+>6@iKvRu>% z7BN1*W{L3%EE1j@D={r^E-96(3}+D9Q+2!x!!SEgU><2Vx=XzIM7u|n7w5-Q)Cpm$ z%!{kcgBcd)=8Z-Nwv%@Dhj(LyMDuCIu~pg0-5tiq$e>j-;YuPRt5R!qtn#-@kIG9| zMoK}NqddTS2$zQyp=B8}lGd5o9{|q~#!`zhV=yrA6BKXop_zvqYpD--t%_6S5iQHj zx_VO8T;=ZlEt(l-R1{Z9gw4qJLo$#CCo(nZ%R-SSO3h5daqTqq8EahMd;?QW496+z z>rI@9A2bDMbE?gB6F7)wmQ;``%CL|_^wfuz6`>h#PHOf9=NW5D_XT5$HB^x*Qsl$B zQo{DbPKUrEbhORPPm%G50~A$<9?k+wO&lf9Fz7}r!mDp;yl zR7{X{#3ic^v#&;A;%KbA0I4UhJw=ah9~n5|(tOO&R9+2MJlzv9B)mrhR%ABs=5P#_ z>4^Y8z^_F=fm7mUo(Wbs5Uef3z&Hin-=k2gBVk9tNl;}WSr%bEjM9k+J1yJcpU##` zVRmMS^r&DngFKol%}A!PtK(?E-j@#_8@BbQV9km1tbG|sOA!oglR zCAOqcHa#b3mXL>4&sIh3(4zniPWK#zobbu8-V9H5X|;lqAL0x~=Zy%}aafc@rBFGW z|78C&9aWHHu(tFjyjWx8T&#sZD(P9&@xHE^M|u>38aJf;_n01vd|LF=aRC$M5xSHg z&1wh*cL&kHL&9HaD|=#9Rpi3z=FsVm{U&kbAN7w6AVQoH5AlROuZG(#+PMo={oqnY znqv4Aun%QBth;L1G$`IhVCZ%fr)|UV^Ft5FNEH+A3Hp+Gs>Mtt6+t5E>eWISujnWv z`;m?H-&7r-5R+?3EEQ20MjVqXBgJpr;vInYvtt*;Zz)45KeXK6Kgb+N=n;sOlf( zgPPEj%reTG+KgwN;~Uh&EQgX822={uOV`Fb{2^1sDERiPBAz(>ndH_~Rk%>Rkq3=e zIO3xgPR1TJ)C7!;9E~^OHy8aP&wy1;R_NF()95HG1|6{WIq}-L90U~J%Se>X$oPz( zCCX`&8uG4WB^~kkgzLz-dLrUi{o~1Y+vQlxiwHeM;O9Xcos|0tS%J@cjz;C?^5+%5 z&&MQ-KSem@Xo@#i#41)F41DUIu9Qwm zgcBa~B5Dg|9aWsaU@=-Eo3gDvvJVRudz|jvos=M%h2PLcO@x}2I^P+oZsq#$LHF570>zgL}>c+AU#J7pk2XS9v+V+#)+dRQK6s81O#5DDo4s%1{kiOmh( z6|qpUJ|RGyXf)4B-4{4r?`WBjQ`I4=t?D|nM?29( za)Ms7K33NyJp}D&ZFr+-Z*$6H{z}Z!a!ajF$98Xdy;YKefZ2Yx|mL~?K2^j_S4gL!8>UX8UT^2`t>^1Q3^mV7n_Pq~Gi z*?!v_iHnm0WIvuIUl#r7b#kG+bl)^SBEJn3CgXa?$F#!Q@yubEeObF{Z^M%2KhAmP zmkd(5t5F@qbJwbV(An;;20ewL;%vIxy6|J0{8GHxYH4jjZN3b7n(4bFuj2}Fo9G$v zB6X>srgy3*L9u|&4zF+TgmPijzzOf}YwEevhbS>o*`qnOFqq?b7?Lrzgk|nb!^(c* zgt~+vRh?>0;%j%H-h&R!f>`3&zPJQ-$F| zMZiKm@dBOxB}HfLh1C814$S2O(oYXnZEO9yDUANexp|nY1>{3_`EGhr!lRUY$eOsX zXKuhfBUjCpO;ye-a|o9TuTFc*#8)KPR8biWNx<~%{#fG^hSo+;v%7433A@QtO|L%v zIksr+p;1XaLwd{VzVTH9#?G|q6kM8P3`lD zDs~k5l#Yq@iE)WAVU=*BQtC@=fchbBmf=DCKdmM|--Nr0`CB5d^7L9}OleinMw7EU z_;(8j{1a&DOi$`+I02jkl*?85106AtM$=@F%Z`w-k;?i6L?jt>dsZx?(x4!PG4diH z0Z%~dzM4XP&6Q;YHlxb!Hh}3nI zBp9J+QxqH{*~kCad@&<@gkC$zOvpgm%^2rc_|=dF~k<)`A8_xBIEgsGmPovwqawUxZCmHnqS*h1IX z9+%Xl-@jFUpR@R1G^d(#<5p=r-+;F`rMu}g1-jP0APm>+EmiLcdMgyc{?I+c zpZ`Il^?1&Hn7OKSf_C9ZEAd*Y2%P7zsTk|DBs3( zu`x{Z_~U*>LKOKB8>f*_1Gd*yqayaq-NQ-!K=`@tctHL!-az}1YV6HMG|S5(>gw4g zt5ACzJ&e8^$pCMPWFW&aAZ=oRDFRWjenZ3}JzR;x`~D%04w z4frtG)pghHjOAeY;h*9=ct0 zsq%eCcZ7H@#`t`8RJCn;o5Z&G+JgKhHK_hEZ}BFK z{0t0|v)N63%YG|)fBI7n-w=Ww_(22)pIyZ3%P&@u>4E=|?`H#&0_oDol z#$LhB(eO_zpRT>(pPv6$$e7yMJMf$6+Wig%3Eh8QGk?a=AA!ETIx{29r%Im=mx+l9 zmyVhF&ov_>)1ULd+CTe$xBWhT+x$H<(b7Qtx&Gb%8Ge6`f7<=EXJn!O>@AL1r-*$iJ z$il+<=lb`v|Gd7x^ZY%>&v||N`ty8xMuvaArhm=*pReP$zrSso|JWM-y<>gu55Kpx z&$I;!){0i9fASIhV}JO+wv4}e>VIz;bf2X?{}*8}EdvcJ-G2&$*WKJb6#ADx#+uLG z64wpvmkHdN(!TZ(Ek^_M!3}T6GSc!ef%{O1#1bw?&l9v7puj1J2*iWHcZ(=0bcs`v z)W8>CMXo4$mLXMD)Kku>o0d^mAZeEw-Eh$#5_}bV^W^HBysX+3onW0DM~aALS=^$ z+(>88b-U(vL)WZ1yVCb~Z_0SjbszKZpQ)K34e|Y^5RYI$(rPDo(5%i6L|D*Q{i2BB z$j%AQV>Wd1&mX9-Wi~zqh(2sk+gg-vCUQb_frlCE!#dtA}ZhXVi0%E7#{DruQ3vMR+YCam}it`s~Z$B%= z-{(C{!?nP^eLLrE%(gT^oa1oP(xS*lnHoKkCE*CW&&4{LB3zu08b2aMtw7=Qfyw1{ zU|#y=z0-<*&KK2tMn1*&jsN@+Xbsk}m*zCX1ORk;Q6<3sC#a{-J0Lwb6rE@AhCtO9 z%}5R0b$`eY@XkOdzq7@z8&Q`F!uqi!lOM|wZpjbJUdg+{Q$=W{-u$f`{>nVZLdhu_ z<0Qd7DB#V|N>4N^E?&SP(ogTx-uQ11!qdnrEuaBY=y%j&&?8W^9Vk1B($o*~tElNg6QBp=mqa_c9SSul zdkX&ZBbuW_RCgr0Y;)bjR+-Tc-U<}WP_JOf;kBw@=!lNEC8(N@FLe(L*;j=w{h|Bs zg#(1pca9w^{b9%p8mgL(0gZOuudep}p{z-h9TrMYV>M{AMTt#eVGzX9Ba@?!2P|i% z!=glayjAnXiekW%)lfnKe3*?&1IrwE!x%P7Y(R>F0epsPhrYQzVnvONRA2pB+L}C! z6_G0JKz8`b;3k8Vb@&|3HNH+nhOr2S$YUP%5$Q6eN*3BcTrnfF1n9Q4Re~R3L8g1* zy#p7Z$fk}K0ds!CggN3Zz@LFgu)S=V@EK8xhKDs}yvexnOU>nD$e#u*0Vd;GMnmg~ zJJb=Qi6b|LrWGk5p6wAM2RgUa)|B4|OzYjICM%D`NQX2*OqC7_CqEcWa1g;05D;Ds z$mu}@YJ^FfDpg9VTwlg+DkYr&$-V?oXQiBTPVM9?E&@`A! zeZF!vn~)CK^~fA1g-YlDiFt^UrLBS(ZT`)*&^|cY*2oKUk(qVK@CI-J2uQ1F3(Eux z3@Ylr!VZGyuq#@M8Ls4OQ%n_jAS$+}TPx*7`#cVFz0;1Wm+SGyb81t8m7sk3@C`)9 zmtvnyh$8*M@fe1Q-52R`Fr6Fd zqKD8{@)B+E1fU8?0{9`7iI&2mXye=4DTZ#RIln@@55OLa3|OT^ZPux|4fw{!m6h&G zHh-eD?^Mscy~);4K?{Ch25(1jculd6v1;mfxFja)aV1t262I3 zfWphJ75EVK_20Tod?C6a{p~j_Tm}+c$(keqSSknu*{vI<{4GtwG5Ug0z!JKF>2OH3 zX-K5UOugopOd#a^Z4Z=}F};EukdWx6D25REVUfPno0Wt2d}Ao?;yP5GCi68!r*+F2 zMss-1$l%ksWsIqZcOe;}L;Ys2sw_@LA_)Mg!v|x6O%6x1tCeJl-*iQ8;@YO-C~JSG zQcIIoDUaCe*(OE<&ql3nY8`yn5 z^;vm9KKu$p5y}z*V4rV8B6l(}vREC3 z@E0mlgEk`!8c$w^{h(|*o##3*ICa)%*4aUnTm}U^HV3o%6vJ71nLtuMQKJZm`rL^s zd295DLBNP*K(ka5nvTUk? zVl_o|5+z-U13zqMq0!R#7hAN)UG6~EuSshuEQhhgN6eBl)H`17Mn6Ak%#aMMFpciY ze#*`>h9qbB31rAK=^HzWa&=Dh6+OMSQG|&j1LouMZ5a&w$iN+j zx`C1|Q8cwXAW4olC@XS+=}maPcs=i$Kc)Vq9vm>ed8Lse{&}GO9H#C8+PtUMyoYO&u%G z{}$i#@=B`2AF37+UYt9pDZ4F3mv>D-PnGmDrVnVFK*T6sm7|>RIGrhPj1(O5=eB3s zm@sn&+yd5%XwAM%Xso3R0h^2Qh>_L8kfWqMHtQAK?CaZhqUA~jukqeMAoLP@wV$5tf_mqm$vIRkIb6;}WJyYLJhW=J zg{EP1FeGDxt;asDPxP@yQ-V(5kVelI=7~+0DC5>LE~m!oi7FAS(v_1Al`9t5Ths{V zN$Ey#ahu0hjPBAFB`Uj6`D|iBUFQ>!s}>m!+?wKklS$SIVIH-?N|NOW4bW#iplHzM zGbb3aC?JXC=<3W|n!_d_+Kl$? z8t(cs2u~$#pCycLlaNjHC}t!9j7XFKPeT54wo8VaULH~mID3>sXbhbOdvGO1zYA(3 zhJ|C7_mI4CoqUhRUTuN8&{BDE^Zt#x!y{{ay{Zmz0(Dkqin%=W{53+A4z38Dj(7?q|^`Wz3btR_q;psG@BC~e%qtKOX+(mS# z7G&CFOoe)sX{lzl-A?-Sk|Q_89NErD<^C5enRPcYVJ?ZQ8dAQCuJz)pQ!X0g<9^?Z z>U>3ayY(%!^%6joR?uzGTCEMgSDCoz%~lBiL_bWg)>v=z$~zCqm7nB#4&4{C%ox{A zc0NnETQ$@05%h6qmq-J`5xw2`Jc(L04^szFB za#3A953e{;eFZW(9#f>6qgdN0Vf&v=9;6=XWIuzxa!H$#-JJI9Om&}S>ci%z!Ll~H zdWwe@)dbykdK>IHI!*9g;xss+O(jF6BkhDhYvLVLn~IY832j8x(kZg=r}d4d)eL7d zuP~T>jg3!C^kt}_`DmzRnYbiQL^I4Z2p~XUL^+5MzZ~0ThghZ2)y57Hqsxq{pY6j$ z{(7M9x;B`#m!gKf>dM?1#og1{6?F{(#UaoI(PlTEs>NF9_7jv{2Ua|NNBhGGJzN>Q z=>ut?7GL&TEK>9p?X!Ys>P)Vpi6mDiGM-ZR!c!cQ5QzL%N$1c6buV|~_ilXAM5drG zQwdh-c{IK-zYwLd+)paQTjk`Fz&6|EY}_Nk1~h6+-@niInVr0f5sJSq zQ5Hn&Zx?IaZ(e0*NH7o7SafAQUgYc1?4V)uO7Y9Z*4mme^;&%#R7G{l+63vptYr9M z!9LtkvfRLEDL!U9?w*`BN|mfPH+Mp4zjwvdrx`Il0g@jwxD-BCHtQ{V<{j5>tdx@0 zhK3R?3KwU3{7UxYir=9<3OR(^Xa$UMfl}gA{IZ%hc~^7V3(E_fXWga6gmlJ@B`I{% zzvfZqDCRR`WuRCJh^&QdFr0m*Y_3phL1N4|o2_+1U0EVrC$`Iwrs&tTfeMehY1PWI1eB>v_Nnw9CSznD0;COjSxeIC$--IrQCE^ zE5_Cjg~lY{Z+Je2NISd@WVz+p=zhJic10D?rSK31FOon$2_)f>5^84j6&&5A^Nlap zBB_G#D}`-F8D6`uk8?L5L*maR{Qld0ZolBeF4$gskIfOQ~puSFOsVC zLlyK6qzLH6W~aiN00wp~!G-avF{byCOv7&#L7Oo014MYk%XKp&WZmOqn;j8HJMnp| z<$+7DNatYrGVr4599{2n>_`ht(3r=GPy{wcpbRKYnJfb22lO=#Z0e@KJJAM)>lr(K!K5NJ6Fcpz0Q3N+3}%8`q6^)>dctF zFBhXc#zd89-UT8q|&{Poa#gT|G+PD`^m{L9n zSZxXuIAy6Lp;&t^$Tvz=b?!&}eE_N){@0bVkQL;nov>cYwvpnd5VJCe-H`K|5t8b5 zt9D0|^Yr6JVX;qp1z2O~X3D%!#I(+o3FNG51K9rRxya}zt=CF>VZTdwk(>s<#-fUE zZO6UGb>Ox5mY{xYr+r`)y}D8`&SSJ zlXWWQn+y!^odNgtPCNRUquI5kJ>)eg5n${j)vX)j)S2-UzVy?nlh+1!iElxW{6N$wAXR z%?_{e2&`+;c&3gv?>&HNMi+uc2n*RDqcFgy*`Qe2lX|ucUYcN#tenZN&jj4Gqo^@$ zMdC~%6gC{$-E8SPu1f4wXz4HH2irFJ4%g%>^{z(zx22LtH~vl)?iW;?KS(q@OXzg;QV z1_Eyr_+iINR;U%o@h((~?ZnE*535WPsUs>81~bbV@>UPk|&YhOjMMYwye6rwbU}JUjg={SZC-O zj>4#Y=o#Lt*f!U%oHSbfv{NE~PeSUnej6L{&wl+*&h7^#COln`uXx_zJF8Nypu31( z8omHQp6B1&0TC;#7@IgxHc!TbKEe0ZA}Vc15_(Y58j80Fcx;l<$YAc5hFmvrMBi2{ z$2G6R{?{<_0hQ@Eq@o#z*8#E(@^gx30imnV|}{hO>^vn!pwZt2KaE!kv5xgbIDZ>0gqW(K30DFA}V~q6X=?Kqcgu zG$V?3<0;RsFTH!bJSNv!!rd=K89MR$IqbOFknjB@<|q=?@E~{TB!%>eW^7m>jg5`S z5{_lLixhgK%tD@Hh7I(f%7^o%g)PRU^IK{1B;uIJSq}9klTSyR36}{B4uxQRu%ziS zSjC972H0wZ8g3IeHfUaDcO39zmZopB-`?xFS()J6Z9LO2JK1TS#fIGnJEYRP=PNgU z(MMUfaf<9ye|Z9mmTs2GIvSN$H2>PFN#7qkg5n!5h`ji1F+O>7zvkFd3Qn5_Ja-F` zg%6D93}vTh6SzPN&f-|;_yv+ex?$Rc8IcIMI5 zIncpBXfM+MVUI^6e6nbsN@HNm<@zyj>si=7GdZAslH+C-C2EVZmD$71d2{k*7H1?< zyHS5L^Zm3|b@f7B*~t0_dI~i{`!5A4kG8 z3%hVA#{B8ixlGeJd}=hDiSxY0a%Oc9jAaXHx4xP1cU*6#oMpuC7L+aJ5Iu0P$h|QJ z-C$UC`e`Bo#ESQNXZSE|(?r3>HA^KRQ3S3~H#6!XXUH^sOL-pa;)O4jd@U2I?Wy)^p5 zcEmp_G$S5l`61^d^_Tn7RmqyxD&`k<=hPC6gFQJ_lpxa=BR9?ivI!??Dhh5YKj%N3 zJkQVp^iwju=Ke7NsiB)tb@4IFrH9TW*+HsF6SO~@7zL6 z5*at8_lr%ynGew}uWXCOiP9a+wvG|wVdw)Za7qr%^_qbXe6;-=3CS$Q2+!gW18C80 z1>Jb>ut}8!IlxucNF9Quz~pcpgk3gWiqdzW${15<7~M_@b6KK24gHS_rLkAp!aEbT zvN%(q5uHO{f@FFAV_K&G3H|tSQo~eUHY({tRfdQ(vRO>BJzu)-^>rR$CSwC zdf^m(RB~k2XO-G$>c~j0AfSCRO&lqvkj&CBEFtgfK-~lIw{!2qLVf!>8I~{z6$|?1 z!^9_Q;Ue)v^!Ykv6u`i$H+bBCvQN23z+E)S;N~zlv3-jGcF&=k`_6#O{0*{$hhhm4 z5s>q|C-y3`9t$g{0k^^e@_qoY3p3KucS^bH99nRd-_oGLUtp$~}BGBY^qwF?f|9-Xbt0 z??vQ>P96PRty(aGNpAOsOb~}Z+$mJw&`7Ia^@fakc9}U4$xn7bO=X{fg&@5QgL|IE z96eEp9|b@>NPO!t8^74dv}Eflm{HGsTmjF06mu$NpazbhZb4Q6D0nF5kPCDGK==rz z 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 and #include "..." . +You can set in configuration file: + +```json +{ + "report" : [ "different_type" ] +} +``` + +or in arguments: + +`cppinclude --report=different_type` + +Example from [simple_example_for_different_type_report](docs/examples/simple_example_for_different_type_report) + +``` +cppinclude --report=different_type +... +Files that are included by different ways: +1. base_char.hpp +With double quotation marks ( #include "..." ) in files: + 1. base_char_factory.hpp line 3 + 2. char_b.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a.hpp line 3 +2. base_char_factory.hpp +With double quotation marks ( #include "..." ) in files: + 1. char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in files: + 1. char_a_factory.hpp line 3 +... +``` + +### All arguments in configuration file + +Now you can set in configuration file *report*, *report_limit* +and *report_details_limit* + +Example from [lua](docs/examples/lua) + +```json +{ + "report" : [ + "most_impact", "unresolved" + ], + + "report_limit" : 30, + "report_details_limit" : 30 +} +``` + +## Fixed + +### Fixed bug in analyzing raw string + +Example: + +```c++ +std::string str = R"( + #include + )"; + +``` + +**Before:** File header.hpp was detected + +**After:** It's detected as string + +### Fixed bug in analyzing comments after #include + +Example: + +```c++ +#include "lib1" // + +``` + +**Before:** lib2 was detected + +**After:** lib1 is detected + diff --git a/src/3rd-part/std_fs/include/std_fs b/src/3rd-part/std_fs/include/std_fs index b47759d..0b648a5 100644 --- a/src/3rd-part/std_fs/include/std_fs +++ b/src/3rd-part/std_fs/include/std_fs @@ -35,7 +35,7 @@ namespace stdfs STDFS_NAMESPACE_VISIBILITY using path = fs_real::path; using directory_iterator = fs_real::directory_iterator; static decltype( auto ) hash_value = &fs_real::hash_value; - static bool (*exists)( const path& ) = &fs_real::exists; + static bool (*exists)( const path&, std::error_code & ) = &fs_real::exists; static bool (*is_directory)( const path& ) = &fs_real::is_directory; static path (*current_path)() = &fs_real::current_path; @@ -60,14 +60,14 @@ namespace stdfs STDFS_NAMESPACE_VISIBILITY return _path.filename().empty(); } - static int compare( const path & _r, const path & _l ) + static int compare( const path & _l, const path & _r ) { - return _r.compare( _l ); + return _l.compare( _r ); } - static bool less( const path & _r, const path & _l ) + static bool less( const path & _l, const path & _r ) { - return _r < _l; + return _l < _r; } #elif __has_include() @@ -163,24 +163,24 @@ namespace stdfs STDFS_NAMESPACE_VISIBILITY return pathStr.back() == path::preferred_separator || pathStr == "."; } - static int compare( const path & _r, const path & _l ) + static int compare( const path & _l, const path & _r ) { int result = 1; - if( _r.has_root_directory() != _l.has_root_directory() ) + if( _l.has_root_directory() != _r.has_root_directory() ) { - if( !_r.has_root_directory() ) - return -result; - else + if( !_l.has_root_directory() ) return +result; + else + return -result; } - auto rightBegin = _r.begin(); - auto rightEnd = _r.end(); - auto leftBegin = _l.begin(); auto leftEnd = _l.end(); + auto rightBegin = _r.begin(); + auto rightEnd = _r.end(); + while( rightBegin != rightEnd && leftBegin != leftEnd ) { if( rightBegin->native() < leftBegin->native() ) @@ -202,9 +202,9 @@ namespace stdfs STDFS_NAMESPACE_VISIBILITY return +result; } - static bool less( const path & _r, const path & _l ) + static bool less( const path & _l, const path & _r ) { - return compare( _r, _l ) < 0; + return compare( _l, _r ) > 0; } diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6a0061e..61f2d63 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -45,6 +45,8 @@ add_subdirectory(project) add_subdirectory(application) add_subdirectory(3rd-part/fmt) add_subdirectory(json) +add_subdirectory(compilation_db) +add_subdirectory(cmake_project) target_link_libraries(${PROJECT_NAME} application_lib) diff --git a/src/application/CMakeLists.txt b/src/application/CMakeLists.txt index dc87ef4..a72320a 100644 --- a/src/application/CMakeLists.txt +++ b/src/application/CMakeLists.txt @@ -3,13 +3,10 @@ project(application) include_directories(.) include_directories(../3rd-part/cxxopts/include) -file(GLOB all_sources - "*.cpp" - "tools/*.cpp" - "resources/*.cpp" - "exceptions/*.cpp" -) -add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + +add_library(${PROJECT_NAME}_lib STATIC ${all_sources}) target_link_libraries( ${PROJECT_NAME}_lib @@ -20,6 +17,8 @@ target_link_libraries( project_lib file_system_lib json_lib + cmake_project_lib + compilation_db_lib fmt ) diff --git a/src/application/app_con.cpp b/src/application/app_con.cpp index ff04a44..98874a6 100644 --- a/src/application/app_con.cpp +++ b/src/application/app_con.cpp @@ -2,7 +2,11 @@ #include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_project_builder.hpp" +#include "application/tools/app_cmake_project_builder.hpp" #include "application/tools/app_log.hpp" +#include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_configuration_file_loader.hpp" +#include "application/tools/app_report_settings_loader.hpp" #include "application/resources/app_resources_messages.hpp" #include "application/resources/app_resources_version.hpp" @@ -10,7 +14,7 @@ #include "application/exceptions/app_cant_create_model_impl.hpp" #include "application/exceptions/app_cant_create_analyzer.hpp" #include "application/exceptions/app_cant_create_report_impl.hpp" -#include "application/exceptions/app_cant_create_parser_impl.hpp" +#include "application/exceptions/app_cant_load_reporter_settings.hpp" #include "project/ih/prj_project_accesso_impl.hpp" #include "project/api/prj_project.hpp" @@ -28,9 +32,15 @@ #include "reporter/ih/rp_accessor_impl.hpp" #include "reporter/api/rp_factory.hpp" #include "reporter/api/rp_reporter.hpp" +#include "reporter/api/rp_settings.hpp" #include "json/ih/json_accessor_impl.hpp" +#include "cmake_project/api/cprj_project.hpp" +#include "cmake_project/ih/cprj_accessor_impl.hpp" + +#include "compilation_db/ih/cdb_accessor_impl.hpp" + #include #include @@ -52,48 +62,62 @@ ConcoleApplication::~ConcoleApplication() = default; int ConcoleApplication::run( int _argc, char * _argv[] ) { - ParserArgWrapper parser; - parser.init(); - parser.parse( _argc, _argv ); + ParserArgWrapper arguments; + arguments.init(); + arguments.parse( _argc, _argv ); - if( parser.isHelp() ) + if( arguments.isHelp() ) { - parser.showHelp( std::cout ); + arguments.showHelp( std::cout ); return EXIT_SUCCESS; } - if( parser.isVersion() ) + if( arguments.isVersion() ) { showVersion(); return EXIT_SUCCESS; } - auto kindsOpt = parser.getReporterKinds(); + auto configurationFilePtr = loadConfigurationFile( arguments ); - ProjectPtr projectPtr = createProject( parser ); + ProjectPtr projectPtr = createProject( arguments, configurationFilePtr.get() ); if( !projectPtr ) { - throw CantCreateProjectImpl(); + throw CantCreateProjectImpl{}; } Project & project = *projectPtr; - if( parser.isVerbose() ) + if( arguments.isVerbose() ) dump( project ); - ModelPtr modelPtr = runAnalyzer( project ); + CMakeProjectPtr cmakeProjectPtr = + createCMakeProject( arguments, configurationFilePtr.get() ); + + if( arguments.isVerbose() && cmakeProjectPtr ) + dump( *cmakeProjectPtr ); + + ModelPtr modelPtr = runAnalyzer( project, cmakeProjectPtr.get() ); if( !modelPtr ) { - throw CantCreateModelImpl(); + throw CantCreateModelImpl{}; } Model & model = *modelPtr; - const int maxFiles = getReportLimit( parser ); - const int maxDetails = getReportDetailsLimit( parser ); - const bool showStdFile = getShowStdFile( parser ); + ReportSettingsLoader reportSettingsLoader{ getReporterFactory() }; + auto reports = reportSettingsLoader.loadReports( + arguments, + configurationFilePtr.get() + ); + auto settingsPtr = reportSettingsLoader.load( + arguments, + configurationFilePtr.get() + ); + + if( !settingsPtr ) + { + throw CantLoadReporterSettingsImpl{}; + } - if( kindsOpt ) - runReporters( model, *kindsOpt, maxFiles, maxDetails, showStdFile ); - else - runReporters( model, parser.getDefaultReporterKinds(), maxFiles, maxDetails, showStdFile ); + runReporters( model, reports, *settingsPtr ); return EXIT_SUCCESS; @@ -102,82 +126,61 @@ int ConcoleApplication::run( int _argc, char * _argv[] ) //------------------------------------------------------------------------------ ConcoleApplication::ProjectPtr ConcoleApplication::createProject( - const ParserArgWrapper & _arguments + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile ) { - getLog().printLine( resources::messages::StartConfigurateProject ); - - ProjectBuilder projectBuilder( - ensureProjectAccessor(), - ensureJsonAccessor(), - ensureFileSystem() - ); - return projectBuilder.build( _arguments ); + ProjectBuilder projectBuilder( ensureProjectAccessor(), ensureFileSystem() ); + return projectBuilder.build( _arguments, _configurationFile ); } //------------------------------------------------------------------------------ -ConcoleApplication::ModelPtr ConcoleApplication::runAnalyzer( - const Project & _project +ConcoleApplication::CMakeProjectPtr ConcoleApplication::createCMakeProject( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile ) { - getLog().printLine( resources::messages::StartAnalyzeSources ); - - AnalyzerPtr analyzerPtr = createAnalyzer(); - if( !analyzerPtr ) - { - throw CantCreateAnalyzerImpl(); - return nullptr; - } - return analyzerPtr->analyze( _project ); + CMakeProjectBuilder projectBuilder{ + ensureCMakeAccessor(), + ensureCompilationDbAccessor(), + ensureJsonAccessor(), + ensureFileSystem() + }; + return projectBuilder.build( _arguments, _configurationFile ); } //------------------------------------------------------------------------------ -int ConcoleApplication::getReportLimit( const ParserArgWrapper & _arg ) const +ConcoleApplication::ConfigurationFilePtr +ConcoleApplication::loadConfigurationFile( const ParserArgWrapper & _arguments ) { - int result = 0; - if( auto limitOpt = _arg.getReportLimit(); limitOpt ) - { - result = *limitOpt; - } - else - { - result = _arg.getDefaultReportLimit(); - } - return result; -} - -//------------------------------------------------------------------------------ + getLog().printLine( resources::messages::StartConfigurateProject ); -int ConcoleApplication::getReportDetailsLimit( const ParserArgWrapper & _arg ) const -{ - int result = 0; - if( auto limitOpt = _arg.getReportDetailsLimit(); limitOpt ) - { - result = *limitOpt; - } - else - { - result = _arg.getDefaultReportDetailsLimit(); - } - return result; + ConfigurationFileLoader loader( ensureJsonAccessor(), ensureFileSystem() ); + return loader.load( _arguments ); } //------------------------------------------------------------------------------ -bool ConcoleApplication::getShowStdFile( const ParserArgWrapper & _arg ) const +ConcoleApplication::ModelPtr ConcoleApplication::runAnalyzer( + const Project & _project, + const CMakeProject * _cmakeProject +) { - bool result = false; - if( auto valueOpt = _arg.getShowStdFile(); valueOpt ) + getLog().printLine( resources::messages::StartAnalyzeSources ); + + AnalyzerPtr analyzerPtr = createAnalyzer(); + if( !analyzerPtr ) { - result = *valueOpt; + throw CantCreateAnalyzerImpl(); + return nullptr; } + + if( _cmakeProject ) + return analyzerPtr->analyze( _project, *_cmakeProject ); else - { - result = _arg.getDefaultShowStdfile(); - } - return result; + return analyzerPtr->analyze( _project ); } //------------------------------------------------------------------------------ @@ -185,9 +188,7 @@ bool ConcoleApplication::getShowStdFile( const ParserArgWrapper & _arg ) const void ConcoleApplication::runReporters( const Model & _model, const ReporterKinds & _kinds, - int _limit, - int _maxDetails, - bool _showStdFile + const reporter::Settings & _reporterSettings ) { using namespace reporter; @@ -206,9 +207,7 @@ void ConcoleApplication::runReporters( } Report & report = *reportPtr; - report.setMaxFilesCount( _limit ); - report.setMaxDetailsCount( _maxDetails ); - report.setShowStdFile( _showStdFile ); + report.copySettings( _reporterSettings ); report.report( _model, std::cout ); } } @@ -225,9 +224,9 @@ ConcoleApplication::ProjectAccessor & ConcoleApplication::ensureProjectAccessor( ConcoleApplication::ModelIncludesAccessor & ConcoleApplication::ensureModelIncludesAccessor() { - return m_modelIncludesAccessor.ensure< - model_includes::ModelIncludesAccessorImpl - >(); + using namespace model_includes; + + return m_modelIncludesAccessor.ensure< ModelIncludesAccessorImpl >(); } //------------------------------------------------------------------------------ @@ -283,6 +282,13 @@ ConcoleApplication::ReporterAccessor & ConcoleApplication::ensureReporterAccesso //------------------------------------------------------------------------------ +reporter::Factory & ConcoleApplication::getReporterFactory() +{ + return ensureReporterAccessor().getReporterFactory(); +} + +//------------------------------------------------------------------------------ + ConcoleApplication::JsonAccessor & ConcoleApplication::ensureJsonAccessor() { return m_jsonAccessor.ensure< json::JsonAccesorImpl >(); @@ -290,6 +296,21 @@ ConcoleApplication::JsonAccessor & ConcoleApplication::ensureJsonAccessor() //------------------------------------------------------------------------------ +ConcoleApplication::CMakeAccessor & ConcoleApplication::ensureCMakeAccessor() +{ + return m_cmakeAccessor.ensure< cmake_project::AccessorImpl >(); +} + +//------------------------------------------------------------------------------ + +ConcoleApplication::CompilationDbAccessor & +ConcoleApplication::ensureCompilationDbAccessor() +{ + return m_compilationDbAccessor.ensure< compilation_db::AccessorImpl >(); +} + +//------------------------------------------------------------------------------ + Log & ConcoleApplication::getLog() { if( !m_log ) @@ -349,6 +370,31 @@ void ConcoleApplication::dump( const Project & _project ) const //------------------------------------------------------------------------------ +void ConcoleApplication::dump( const CMakeProject & _project ) const +{ + std::cout << "cmake project dump:" << std::endl; + int fileNumber = 1; + _project.forEachFilePath( [&]( const CMakeProject::Path & _path ) + { + std::cout << fileNumber << " : " << _path << std::endl; + std::cout << "includes:" << std::endl; + int includeNumber = 1; + _project.forEachIncludes( _path, [&]( const CMakeProject::Path & _include ) + { + + std::cout << '\t' << includeNumber << " : " << _include << std::endl; + ++includeNumber; + return true; + } + ); + + ++fileNumber; + return true; + }); +} + +//------------------------------------------------------------------------------ + void ConcoleApplication::showVersion() { using namespace resources; diff --git a/src/application/app_con.hpp b/src/application/app_con.hpp index 14ef0e6..401ff2d 100644 --- a/src/application/app_con.hpp +++ b/src/application/app_con.hpp @@ -27,9 +27,20 @@ namespace project { class Project; } +namespace cmake_project { + class Project; + class Accessor; +} + +namespace compilation_db { + class Accessor; +} + namespace reporter { class ReporterAccessor; class Reporter; + class Settings; + class Factory; enum class ReporterKind; } @@ -41,6 +52,7 @@ namespace json { namespace application { class ParserArgWrapper; + class ConfigurationFile; class Log; //------------------------------------------------------------------------------ @@ -60,6 +72,10 @@ class ConcoleApplication using Project = project::Project; using ProjectPtr = std::unique_ptr< Project >; + using CMakeProject = cmake_project::Project; + using CMakeProjectPtr = std::unique_ptr< CMakeProject >; + using CMakeAccessor = cmake_project::Accessor; + using ModelIncludesAccessor = model_includes::ModelIncludesAccessor; using Model = model_includes::Model; using ModelPtr = std::unique_ptr< Model>; @@ -77,21 +93,34 @@ class ConcoleApplication using JsonAccessor = json::JsonAccessor; - ModelPtr runAnalyzer( const Project & _project ); + using CompilationDbAccessor = compilation_db::Accessor; + + using ConfigurationFilePtr = std::unique_ptr< ConfigurationFile >; - int getReportLimit( const ParserArgWrapper & _arg ) const; - int getReportDetailsLimit( const ParserArgWrapper & _arg ) const; - bool getShowStdFile( const ParserArgWrapper & _arg ) const; + ModelPtr runAnalyzer( + const Project & _project, + const CMakeProject * _cmakeProject + ); void runReporters( const Model & _model, const ReporterKinds & _kinds, - int _maxFiles, - int _maxDetails, - bool _showStdFile + const reporter::Settings & _reporterSettings + ); + + ProjectPtr createProject( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile ); - ProjectPtr createProject( const ParserArgWrapper & _arguments ); + CMakeProjectPtr createCMakeProject( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + ConfigurationFilePtr loadConfigurationFile( + const ParserArgWrapper & _arguments + ); ProjectAccessor & ensureProjectAccessor(); @@ -105,12 +134,17 @@ class ConcoleApplication const Parser & ensureParser(); ReporterAccessor & ensureReporterAccessor(); + reporter::Factory & getReporterFactory(); JsonAccessor & ensureJsonAccessor(); + CMakeAccessor & ensureCMakeAccessor(); + CompilationDbAccessor & ensureCompilationDbAccessor(); + Log & getLog(); void dump( const Project & _project ) const; + void dump( const CMakeProject & _project ) const; void showVersion(); @@ -122,6 +156,8 @@ class ConcoleApplication PluginPtr< ParserAccessor > m_parserAccessor; PluginPtr< ReporterAccessor > m_reporterAccessor; PluginPtr< JsonAccessor > m_jsonAccessor; + PluginPtr< CMakeAccessor > m_cmakeAccessor; + PluginPtr< CompilationDbAccessor > m_compilationDbAccessor; ParserPtr m_parser; std::unique_ptr< Log > m_log; diff --git a/src/application/exceptions/app_cant_create_report_impl.cpp b/src/application/exceptions/app_cant_create_report_impl.cpp index bae2d3d..b482c54 100644 --- a/src/application/exceptions/app_cant_create_report_impl.cpp +++ b/src/application/exceptions/app_cant_create_report_impl.cpp @@ -3,6 +3,8 @@ #include "application/resources/app_resources_exceptions.hpp" #include "application/resources/app_resources_arguments.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" + #include "exception/ih/exc_internal_error.hpp" //------------------------------------------------------------------------------ @@ -29,20 +31,7 @@ std::string CantCreateReportImpl::getMessage() const noexcept std::string CantCreateReportImpl::toString( reporter::ReporterKind _kind ) { - using namespace reporter; - using namespace resources; - - static_assert( static_cast< int >( ReporterKind::Count ) == 3 ); - switch( _kind ) - { - case ReporterKind::Dump : return arguments::report::DumpReport; - case ReporterKind::MostImpact : return arguments::report::MostImpactReport; - case ReporterKind::Unresolved : return arguments::report::UnresolvedReport; - default: - THROW_INTERNAL_ERROR - } - THROW_INTERNAL_ERROR - return ""; + return reporter::reporterKindToString( _kind ); } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_parser_impl.cpp b/src/application/exceptions/app_cant_load_reporter_settings.cpp similarity index 59% rename from src/application/exceptions/app_cant_create_parser_impl.cpp rename to src/application/exceptions/app_cant_load_reporter_settings.cpp index dd129aa..6e5dc9b 100644 --- a/src/application/exceptions/app_cant_create_parser_impl.cpp +++ b/src/application/exceptions/app_cant_load_reporter_settings.cpp @@ -1,4 +1,4 @@ -#include "application/exceptions/app_cant_create_parser_impl.hpp" +#include "application/exceptions/app_cant_load_reporter_settings.hpp" #include "application/resources/app_resources_exceptions.hpp" @@ -8,10 +8,10 @@ namespace application { //------------------------------------------------------------------------------ -CantCreateParserImpl::CantCreateParserImpl() +CantLoadReporterSettingsImpl::CantLoadReporterSettingsImpl() : BaseClass( - resources::exceptions::CantCreateParser::Code, - resources::exceptions::CantCreateParser::Msg + resources::exceptions::CantLoadReporterSettings::Code, + resources::exceptions::CantLoadReporterSettings::Msg ) { diff --git a/src/application/exceptions/app_cant_create_parser_impl.hpp b/src/application/exceptions/app_cant_load_reporter_settings.hpp similarity index 67% rename from src/application/exceptions/app_cant_create_parser_impl.hpp rename to src/application/exceptions/app_cant_load_reporter_settings.hpp index 362369e..c54fda2 100644 --- a/src/application/exceptions/app_cant_create_parser_impl.hpp +++ b/src/application/exceptions/app_cant_load_reporter_settings.hpp @@ -9,14 +9,14 @@ namespace application { //------------------------------------------------------------------------------ -class CantCreateParserImpl : - public BaseExceptionWithMessageImpl< CantCreateParser > +class CantLoadReporterSettingsImpl : + public BaseExceptionWithMessageImpl< CantLoadReporterSettings > { - using BaseClass = BaseExceptionWithMessageImpl< CantCreateParser >; + using BaseClass = BaseExceptionWithMessageImpl< CantLoadReporterSettings >; public: - CantCreateParserImpl(); + CantLoadReporterSettingsImpl(); }; //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_exceptions.hpp b/src/application/exceptions/app_exceptions.hpp index 5ad9be0..2a66f3e 100644 --- a/src/application/exceptions/app_exceptions.hpp +++ b/src/application/exceptions/app_exceptions.hpp @@ -12,15 +12,11 @@ class Exception : public exception::Exception {}; //------------------------------------------------------------------------------ -class CantCreateProject : public Exception {}; -class CantCreateModel : public Exception {}; -class CantCreateAnalyzer : public Exception {}; -class CantCreateReport : public Exception {}; -class CantCreateParser : public Exception {}; - -//------------------------------------------------------------------------------ - -class IncorrectReport : public Exception {}; +class CantCreateProject : public Exception {}; +class CantCreateModel : public Exception {}; +class CantCreateAnalyzer : public Exception {}; +class CantCreateReport : public Exception {}; +class CantLoadReporterSettings : public Exception {}; //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_incorrect_report_impl.cpp b/src/application/exceptions/app_incorrect_report_impl.cpp deleted file mode 100644 index 1cbfb67..0000000 --- a/src/application/exceptions/app_incorrect_report_impl.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "application/exceptions/app_incorrect_report_impl.hpp" - -#include "application/resources/app_resources_exceptions.hpp" -#include "application/resources/app_resources_arguments.hpp" - -#include - -//------------------------------------------------------------------------------ - -namespace application { - -//------------------------------------------------------------------------------ - -IncorrectReportImpl::IncorrectReportImpl( - std::string_view _name, - const Names & _names -) - : BaseClass( resources::exceptions::IncorrectReport::Code ) - , m_possibleNames( _names ) - , m_name( _name ) -{ - -} - -//------------------------------------------------------------------------------ - -std::string IncorrectReportImpl::getMessage() const noexcept -{ - return fmt::format( - resources::exceptions::IncorrectReport::MsgFmt, - m_name, - getNames() - ); -} - -//------------------------------------------------------------------------------ - -std::string IncorrectReportImpl::getNames() const -{ - std::string result; - for( const auto & pair : m_possibleNames ) - { - if( !result.empty() ) - result += ", "; - - result += pair.first; - } - return result; -} - -//------------------------------------------------------------------------------ - -} diff --git a/src/application/resources/app_resources_arguments.cpp b/src/application/resources/app_resources_arguments.cpp index 8588d23..04f17d2 100644 --- a/src/application/resources/app_resources_arguments.cpp +++ b/src/application/resources/app_resources_arguments.cpp @@ -2,6 +2,13 @@ #include "application/resources/app_resources_configuration_file.hpp" +#include "reporter/resources/rp_most_impact_report_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" +#include "reporter/resources/rp_unincluded_report_resources.hpp" +#include "reporter/resources/rp_dump_resources.hpp" + +#include "reporter/api/enums/rp_reporter_kind.hpp" + //------------------------------------------------------------------------------ namespace application::resources::arguments { @@ -80,6 +87,15 @@ namespace configurationFile { //------------------------------------------------------------------------------ +namespace compileCommands { + + const char * const FullName = configuration_file::CompileCommands; + const char * const Description = "Path to JSON Compilation Database"; + const char * const DefaultValue = "compile_commands.json"; +} + +//------------------------------------------------------------------------------ + namespace help { const char * const FullName = "help"; @@ -106,25 +122,33 @@ namespace version { namespace report { - const char * const FullName = "report"; - const char * const Description = "List of reports"; + using namespace reporter::resources; + + const char * const FullName = configuration_file::Report; + + static_assert( static_cast< int >( reporter::ReporterKind::Count ) == 5 ); + const char * const Description = + "List of reports. Name of reports: " + "unresolved, " + "most_impact, " + "unincluded, " + "different_type" + ; + const char * const DefaultValue[] = { - UnresolvedReport, - MostImpactReport, + unresolved_report::Name, + most_impact_report::Name, + unincluded_report::Name, nullptr }; - - const char * const UnresolvedReport = "unresolved"; - const char * const MostImpactReport = "most_impact"; - const char * const DumpReport = "dump"; } //------------------------------------------------------------------------------ namespace report_limit { - const char * const FullName = "report_limit"; + const char * const FullName = configuration_file::ReportLimit; const char * const Description = "Maximum elements in report, 0 - unlimited"; const int DefaultValue = 10; } @@ -133,7 +157,7 @@ namespace report_limit { namespace report_details_limit { - const char * const FullName = "report_details_limit"; + const char * const FullName = configuration_file::ReportDetailsLimit; const char * const Description = "Maximum details in report, 0 - unlimited"; const int DefaultValue = 10; } @@ -142,9 +166,9 @@ namespace report_details_limit { namespace show_std_files { - const char * const FullName = "show_std_files"; - const char * const Description = "Show standard library headers in output (default: false)"; - const bool DefaultValue = false; + const char * const FullName = configuration_file::ShowStdFiles; + const char * const Description = "Show standard library headers in output (default: false)"; + const bool DefaultValue = false; } //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_arguments.hpp b/src/application/resources/app_resources_arguments.hpp index 27ea3a1..85e752c 100644 --- a/src/application/resources/app_resources_arguments.hpp +++ b/src/application/resources/app_resources_arguments.hpp @@ -78,6 +78,15 @@ namespace configurationFile { //------------------------------------------------------------------------------ +namespace compileCommands { + + extern const char * const FullName; + extern const char * const Description; + extern const char * const DefaultValue; +} + +//------------------------------------------------------------------------------ + namespace help { extern const char * const FullName; @@ -108,9 +117,6 @@ namespace report { extern const char * const Description; extern const char * const DefaultValue[]; - extern const char * const UnresolvedReport; - extern const char * const MostImpactReport; - extern const char * const DumpReport; } //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_configuration_file.cpp b/src/application/resources/app_resources_configuration_file.cpp index 0f98cf0..ee17045 100644 --- a/src/application/resources/app_resources_configuration_file.cpp +++ b/src/application/resources/app_resources_configuration_file.cpp @@ -15,6 +15,14 @@ namespace application::resources::configuration_file { const char * const IgnoreSystemIncludes = "ignore_system_includes"; const char * const IgnoreFiles = "ignore_files"; + const char * const CompileCommands = "compile_commands"; + + const char * const Report = "report"; + + const char * const ReportLimit = "report_limit"; + const char * const ReportDetailsLimit = "report_details_limit"; + const char * const ShowStdFiles = "show_std_files"; + //------------------------------------------------------------------------------ } diff --git a/src/application/resources/app_resources_configuration_file.hpp b/src/application/resources/app_resources_configuration_file.hpp index 25bea40..96d140b 100644 --- a/src/application/resources/app_resources_configuration_file.hpp +++ b/src/application/resources/app_resources_configuration_file.hpp @@ -15,6 +15,14 @@ namespace application::resources::configuration_file { extern const char * const IgnoreSystemIncludes; extern const char * const IgnoreFiles; + extern const char * const CompileCommands; + + extern const char * const Report; + + extern const char * const ReportLimit; + extern const char * const ReportDetailsLimit; + extern const char * const ShowStdFiles; + //------------------------------------------------------------------------------ } diff --git a/src/application/resources/app_resources_exceptions.cpp b/src/application/resources/app_resources_exceptions.cpp index 2ec58dc..1233f9c 100644 --- a/src/application/resources/app_resources_exceptions.cpp +++ b/src/application/resources/app_resources_exceptions.cpp @@ -42,19 +42,10 @@ namespace CantCreateReport { //------------------------------------------------------------------------------ -namespace CantCreateParser { +namespace CantLoadReporterSettings { - const char * const Code = "CREATE_PARSER"; - const char * const Msg = "Can't create parser"; -} - -//------------------------------------------------------------------------------ - -namespace IncorrectReport { - - const char * const Code = "INCORRECT_REPORT"; - const char * const MsgFmt = - "Incorrect report name: {}, possible names: {}"; + const char * const Code = "LOAD_REPORTER_SETTINGS"; + const char * const Msg = "Can't load settings for reporters"; } //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_exceptions.hpp b/src/application/resources/app_resources_exceptions.hpp index 82a92f3..c05450b 100644 --- a/src/application/resources/app_resources_exceptions.hpp +++ b/src/application/resources/app_resources_exceptions.hpp @@ -42,7 +42,7 @@ namespace CantCreateReport { //------------------------------------------------------------------------------ -namespace CantCreateParser { +namespace CantLoadReporterSettings { extern const char * const Code; extern const char * const Msg; @@ -50,12 +50,4 @@ namespace CantCreateParser { //------------------------------------------------------------------------------ -namespace IncorrectReport { - - extern const char * const Code; - extern const char * const MsgFmt; -} - -//------------------------------------------------------------------------------ - } diff --git a/src/application/resources/app_resources_version.cpp b/src/application/resources/app_resources_version.cpp index affd6b7..c7714f4 100644 --- a/src/application/resources/app_resources_version.cpp +++ b/src/application/resources/app_resources_version.cpp @@ -7,8 +7,8 @@ namespace application::resources::version { //------------------------------------------------------------------------------ const int Major = 0; - const int Minor = 2; - const int Path = 1; + const int Minor = 3; + const int Path = 0; const char * const VersionFormat = "{}.{}.{}\n"; diff --git a/src/application/test/CMakeLists.txt b/src/application/test/CMakeLists.txt index 3d803fa..95e88b6 100644 --- a/src/application/test/CMakeLists.txt +++ b/src/application/test/CMakeLists.txt @@ -1,8 +1,4 @@ -file(GLOB_RECURSE all_sources - "*.cpp" - "fixtures/*.cpp" - "suits/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp" ) add_executable(${PROJECT_NAME}_test ${all_sources}) include(TestConfig) @@ -11,6 +7,7 @@ target_link_libraries( ${PROJECT_NAME}_test ${Boost_LIBRARIES} ${PROJECT_NAME}_lib + reporter_lib ) add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) diff --git a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp new file mode 100644 index 0000000..672e8ff --- /dev/null +++ b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp @@ -0,0 +1,247 @@ +#include "application/test/fixtures/app_test_cmake_project_builder_fixture.hpp" + +#include "application/tools/app_cmake_project_builder.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_configuration_file.hpp" + +#include "cmake_project/api/cprj_project.hpp" +#include "cmake_project/ih/cprj_accessor_impl.hpp" + +#include "compilation_db/ih/cdb_accessor_impl.hpp" +#include "json/ih/json_accessor_impl.hpp" + +#include "fs/api/fs_file_system.hpp" +#include "fs/api/fs_file.hpp" +#include "fs/api/fs_factory.hpp" +#include "fs/ih/fs_accessor_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "tools/path_string_tools.hpp" + +#include + +#include +#include +#include +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace application::test { + +//------------------------------------------------------------------------------ + +CMakeProjectBuilderFixture::CMakeProjectBuilderFixture() = default; +CMakeProjectBuilderFixture::~CMakeProjectBuilderFixture() = default; + +//------------------------------------------------------------------------------ + +void CMakeProjectBuilderFixture::buildProject() +{ + CMakeProjectBuilder & builder = ensureBuilder(); + + m_cmakeProject = builder.build( + ensureArguments(), + m_configurationFile.get() + ); +} + +//------------------------------------------------------------------------------ + +bool CMakeProjectBuilderFixture::isInitializedProject() const +{ + return m_cmakeProject.get(); +} + +//------------------------------------------------------------------------------ + +void CMakeProjectBuilderFixture::addCMakeFile( + std::string_view _path, + std::string_view _text +) +{ + fs::FileSystem & fs = ensureFileSystem(); + auto filePtr = fs.createFile( toRelativePath( _path ) ); + INTERNAL_CHECK_ERROR( filePtr ); + fs::File & file = *filePtr; + file << _text; +} + +//------------------------------------------------------------------------------ + +void CMakeProjectBuilderFixture::setCompilationFileInConfigurationFile( + std::string_view _path +) +{ + ConfigurationFile & configurationFile = ensureConfigurationFile(); + configurationFile.setCompileCommands( _path ); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilderFixture::Strings +CMakeProjectBuilderFixture::getResultsFiles() +{ + INTERNAL_CHECK_ERROR( m_cmakeProject ); + const cmake_project::Project & project = *m_cmakeProject; + Strings result; + project.forEachFilePath( [&]( const Path & _path ){ + auto pair = result.insert( tools::toPath( _path.string() ) ); + INTERNAL_CHECK_ERROR( pair.second ); + return true; + } ); + + return result; +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilderFixture::Strings +CMakeProjectBuilderFixture::getResultIncludes( std::string_view _file ) +{ + Strings result; + INTERNAL_CHECK_ERROR( m_cmakeProject ); + m_cmakeProject->forEachIncludes( + _file, + [&]( const Path & _include ) + { + result.insert( tools::toPath( _include.string() ) ); + return true; + } + ); + + return result; +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilderFixture::Strings CMakeProjectBuilderFixture::toExceptedFiles( + const Strings & _strings +) +{ + Strings result; + for( const std::string & str : _strings ) + { + result.insert( tools::toPath( str ) ); + } + return result; +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilderFixture::Path CMakeProjectBuilderFixture::toRelativePath( + std::string_view _path +) +{ + return ensureFileSystem().getCurrentPath() / _path; +} + +//------------------------------------------------------------------------------ + +void CMakeProjectBuilderFixture::parserArgument( + std::string_view _argument +) +{ + ParserArgWrapper & arguments = ensureArguments(); + + std::vector< std::string > argumentsStr; + argumentsStr.push_back( "./application" ); + argumentsStr.push_back( std::string{ _argument } ); + + arguments.parse( argumentsStr ); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder & CMakeProjectBuilderFixture::ensureBuilder() +{ + if( !m_builder ) + { + m_builder.reset( new CMakeProjectBuilder{ + ensureCMakeAccessor(), + ensureCompilationDbAccessor(), + ensureJsonAccessor(), + ensureFileSystem() + } ); + } + + return *m_builder; + +} + +//------------------------------------------------------------------------------ + +ParserArgWrapper & CMakeProjectBuilderFixture::ensureArguments() +{ + if( !m_arguments ) + { + m_arguments.reset( new ParserArgWrapper ); + m_arguments->init(); + } + + return *m_arguments; +} + +//------------------------------------------------------------------------------ + +ConfigurationFile & CMakeProjectBuilderFixture::ensureConfigurationFile() +{ + if( !m_configurationFile ) + m_configurationFile.reset( new ConfigurationFile ); + + return *m_configurationFile; +} + +//------------------------------------------------------------------------------ + +fs::FileSystem & CMakeProjectBuilderFixture::ensureFileSystem() +{ + return ensureFileSystemAccessor().getFactory().getMemoryFileSystem(); +} + +//------------------------------------------------------------------------------ + +fs::FileSystemAccessor & CMakeProjectBuilderFixture::ensureFileSystemAccessor() +{ + if( !m_fsAccessor ) + m_fsAccessor.reset( new fs::FileSystemAccessorImpl ); + + return *m_fsAccessor; +} + +//------------------------------------------------------------------------------ + +cmake_project::Accessor & CMakeProjectBuilderFixture::ensureCMakeAccessor() +{ + if( !m_cmakeAccessor ) + m_cmakeAccessor.reset( new cmake_project::AccessorImpl ); + + return *m_cmakeAccessor; +} + +//------------------------------------------------------------------------------ + +compilation_db::Accessor & CMakeProjectBuilderFixture::ensureCompilationDbAccessor() +{ + if( !m_compilationDbAccessor ) + m_compilationDbAccessor.reset( new compilation_db::AccessorImpl ); + + return *m_compilationDbAccessor; +} + +//------------------------------------------------------------------------------ + +json::JsonAccessor & CMakeProjectBuilderFixture::ensureJsonAccessor() +{ + if( !m_jsonAccessor ) + m_jsonAccessor.reset( new json::JsonAccesorImpl ); + + return *m_jsonAccessor; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp new file mode 100644 index 0000000..4739efb --- /dev/null +++ b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp @@ -0,0 +1,94 @@ +#pragma once + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class Project; + class Accessor; +} + +namespace compilation_db { + class Accessor; +} + +namespace fs { + class FileSystem; + class FileSystemAccessor; +} + +namespace application { + class CMakeProjectBuilder; + class ParserArgWrapper; + class ConfigurationFile; +} + +namespace json { + class JsonAccessor; +} + + +//------------------------------------------------------------------------------ + +namespace application::test { + +//------------------------------------------------------------------------------ + +class CMakeProjectBuilderFixture +{ +public: + + using Strings = stdfwd::set< std::string >; + using Path = stdfs::path; + + CMakeProjectBuilderFixture(); + ~CMakeProjectBuilderFixture(); + + void buildProject(); + bool isInitializedProject() const; + + void parserArgument( std::string_view _argument ); + void addCMakeFile( std::string_view _path, std::string_view _text ); + void setCompilationFileInConfigurationFile( std::string_view _path ); + + Strings getResultsFiles(); + Strings getResultIncludes( std::string_view _file ); + Strings toExceptedFiles( const Strings & _strings ); + +private: + + Path toRelativePath( std::string_view _path ); + + CMakeProjectBuilder & ensureBuilder(); + ParserArgWrapper & ensureArguments(); + ConfigurationFile & ensureConfigurationFile(); + + fs::FileSystem & ensureFileSystem(); + fs::FileSystemAccessor & ensureFileSystemAccessor(); + + cmake_project::Accessor & ensureCMakeAccessor(); + + compilation_db::Accessor & ensureCompilationDbAccessor(); + json::JsonAccessor & ensureJsonAccessor(); + +private: + + std::unique_ptr< CMakeProjectBuilder > m_builder; + std::unique_ptr< ParserArgWrapper > m_arguments; + std::unique_ptr< ConfigurationFile > m_configurationFile; + + std::unique_ptr< cmake_project::Project > m_cmakeProject; + std::unique_ptr< cmake_project::Accessor > m_cmakeAccessor; + + std::unique_ptr< compilation_db::Accessor > m_compilationDbAccessor; + std::unique_ptr< json::JsonAccessor > m_jsonAccessor; + + std::unique_ptr< fs::FileSystemAccessor > m_fsAccessor; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp index af61433..7a2b3ea 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp @@ -7,6 +7,9 @@ #include "json/ih/json_accessor_impl.hpp" #include "json/api/json_object.hpp" +#include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" + #include #include #include @@ -89,6 +92,45 @@ ConfigurationfileFixture::getIgnoreFiles() const //------------------------------------------------------------------------------ +ConfigurationfileFixture::PathOpt +ConfigurationfileFixture::getCompileCommands() const +{ + return getConfigurationFile().getCompileCommands(); +} + +//------------------------------------------------------------------------------ + +ConfigurationfileFixture::StringOpt ConfigurationfileFixture::getReports() const +{ + auto reportsOpt = getConfigurationFile().getReporterKinds(); + return toStirng( reportsOpt ); +} + +//------------------------------------------------------------------------------ + +ConfigurationfileFixture::IntOpt ConfigurationfileFixture::getReportLimit() const +{ + return getConfigurationFile().getReportLimit(); +} + +//------------------------------------------------------------------------------ + +ConfigurationfileFixture::IntOpt +ConfigurationfileFixture::getReportDetailsLimit() const +{ + return getConfigurationFile().getReportDetailsLimit(); +} + +//------------------------------------------------------------------------------ + +ConfigurationfileFixture::BoolOpt +ConfigurationfileFixture::getShowStdFile() const +{ + return getConfigurationFile().getShowStdFiles(); +} + +//------------------------------------------------------------------------------ + ConfigurationfileFixture::StringOpt ConfigurationfileFixture::toStirng( const StringsOpt & _arrayOpt ) { @@ -112,21 +154,50 @@ ConfigurationfileFixture::toStirng( const StringsOpt & _arrayOpt ) ConfigurationfileFixture::StringOpt ConfigurationfileFixture::toStirng( const PathsArrayOpt & _arrayOpt ) +{ + return arrayToString( _arrayOpt ); +} + +//------------------------------------------------------------------------------ + +ConfigurationfileFixture::StringOpt +ConfigurationfileFixture::toStirng( const ReporterKindsOpt & _arrayOpt ) +{ + return arrayToString( _arrayOpt ); +} + +//------------------------------------------------------------------------------ + +template< class _ArrayTypeOpt > +ConfigurationfileFixture::StringOpt +ConfigurationfileFixture::arrayToString( const _ArrayTypeOpt & _arrayOpt ) { if( !_arrayOpt ) return std::nullopt; - std::string result; + Strings strings; - for( const Path & path : *_arrayOpt ) + for( const auto & value : *_arrayOpt ) { - if( !result.empty() ) - result += ','; - - result += path.string(); + const std::string valueStr = toString( value ); + strings.push_back( valueStr ); } - return result; + return toStirng( strings ); +} + +//------------------------------------------------------------------------------ + +std::string ConfigurationfileFixture::toString( const Path & _path ) +{ + return _path.string(); +} + +//------------------------------------------------------------------------------ + +std::string ConfigurationfileFixture::toString( reporter::ReporterKind _kind ) +{ + return reporter::reporterKindToString( _kind ); } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp index 5065748..914b121 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp @@ -11,12 +11,14 @@ namespace json { class JsonAccessor; } -//------------------------------------------------------------------------------ - namespace application { class ConfigurationFile; } +namespace reporter { + enum class ReporterKind; +} + //------------------------------------------------------------------------------ namespace application::test { @@ -28,8 +30,8 @@ class ConfigurationfileFixture public: using StringOpt = stdfwd::optional< std::string >; - using StringsArray = stdfwd::vector< std::string >; - using StringsOpt = std::optional< StringsArray >; + using Strings = stdfwd::vector< std::string >; + using StringsOpt = std::optional< Strings >; using Path = stdfs::path; using PathOpt = std::optional< Path >; @@ -37,6 +39,10 @@ class ConfigurationfileFixture using PathsArrayOpt = std::optional< PathsArray >; using BoolOpt = std::optional< bool >; + using IntOpt = std::optional< int >; + + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + using ReporterKindsOpt = std::optional< ReporterKinds >; ConfigurationfileFixture(); ~ConfigurationfileFixture(); @@ -52,8 +58,23 @@ class ConfigurationfileFixture BoolOpt getIgnoreSystemIncludes() const; StringOpt getIgnoreFiles() const; + PathOpt getCompileCommands() const; + + StringOpt getReports() const; + + IntOpt getReportLimit() const; + IntOpt getReportDetailsLimit() const; + BoolOpt getShowStdFile() const; + static StringOpt toStirng( const StringsOpt & _arrayOpt ); static StringOpt toStirng( const PathsArrayOpt & _arrayOpt ); + static StringOpt toStirng( const ReporterKindsOpt & _arrayOpt ); + + template< class _ArrayTypeOpt > + static StringOpt arrayToString( const _ArrayTypeOpt & _arrayOpt ); + + static std::string toString( reporter::ReporterKind _kind ); + static std::string toString( const Path & _path ); private: diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp index 153f5c3..69323d7 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp @@ -4,6 +4,7 @@ #include "application/resources/app_resources_arguments.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -21,18 +22,23 @@ ParserWrapperFixture::~ParserWrapperFixture() = default; //------------------------------------------------------------------------------ +void ParserWrapperFixture::parse( std::string_view _argument ) +{ + Arguments arguments; + arguments.push_back( _argument.data() ); + + parse( arguments ); +} + +//------------------------------------------------------------------------------ + void ParserWrapperFixture::parse( const Arguments & _arguments ) { Arguments arguments{ _arguments }; arguments.insert( arguments.begin(), "./application" ); - std::vector< char * > arg; - arg.reserve( arguments.size() ); - for( std::string & str : arguments ) - arg.push_back( str.data() ); - ParserArgWrapper & parser = getParser(); - parser.parse( static_cast< int >( arg.size() ), arg.data() ); + parser.parse( arguments ); } //------------------------------------------------------------------------------ @@ -177,6 +183,24 @@ ParserWrapperFixture::Path ParserWrapperFixture::getConfigurationFile() const //------------------------------------------------------------------------------ +ParserWrapperFixture::Path ParserWrapperFixture::getCompileCommandsFile() const +{ + auto valueOpt = getParser().getCompileCommandsFile(); + if( valueOpt ) + return *valueOpt; + + return Path{}; +} + +//------------------------------------------------------------------------------ + +ParserWrapperFixture::Path ParserWrapperFixture::getDefaultCompileCommandsFile() const +{ + return getParser().getDefaultCompileCommandsFile(); +} + +//------------------------------------------------------------------------------ + ParserWrapperFixture::Path ParserWrapperFixture::getDefaultConfigurationFile() const { return getParser().getDefaultConfigurationFile(); @@ -318,24 +342,7 @@ std::string ParserWrapperFixture::toString( const ReporterKinds & _array ) const std::string ParserWrapperFixture::toString( reporter::ReporterKind _kind ) const { - using namespace reporter; - using namespace resources::arguments; - - static_assert( static_cast< int >( ReporterKind::Count ) == 3 ); - switch( _kind ) - { - case ReporterKind::Unresolved : return report::UnresolvedReport; - case ReporterKind::MostImpact : return report::MostImpactReport; - case ReporterKind::Dump : return report::DumpReport; - case ReporterKind::Count : - { - THROW_INTERNAL_ERROR - return ""; - } - } - - THROW_INTERNAL_ERROR - return ""; + return reporter::reporterKindToString( _kind ); } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp index 25ba0d4..922e410 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp @@ -36,7 +36,8 @@ class ParserWrapperFixture ParserWrapperFixture(); ~ParserWrapperFixture(); - void parse( const Arguments & _arguments ); + void parse( std::string_view _argument ); + void parse( const Arguments & _arguments ); std::string getProjectDir() const; std::string getDefaultProjectDir() const; @@ -62,6 +63,9 @@ class ParserWrapperFixture Path getConfigurationFile() const; Path getDefaultConfigurationFile() const; + Path getCompileCommandsFile() const; + Path getDefaultCompileCommandsFile() const; + ReporterKinds getReporterKinds() const; ReporterKinds getDefaultReporterKinds() const; diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.cpp b/src/application/test/fixtures/app_test_project_builder_fixture.cpp index 8dfff5e..a50dace 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.cpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.cpp @@ -2,6 +2,8 @@ #include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_project_builder.hpp" +#include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_configuration_file_loader.hpp" #include "application/resources/app_resources_arguments.hpp" #include "project/api/prj_project.hpp" @@ -38,19 +40,25 @@ void ProjectBuilderFixture::parserArguments( const Arguments & _arguments ) Arguments arguments{ _arguments }; arguments.insert( arguments.begin(), "./application" ); - std::vector< char * > arg; - arg.reserve( arguments.size() ); - for( std::string & str : arguments ) - arg.push_back( str.data() ); - - getArgumentParser().parse( static_cast< int >( arg.size() ), arg.data() ); + getArgumentParser().parse( arguments ); } //------------------------------------------------------------------------------ void ProjectBuilderFixture::buildProject() { - m_project = getBuilder().build( getArgumentParser() ); + const ConfigurationFile * configurationFile = loadConfigurationFile(); + + m_project = getBuilder().build( getArgumentParser(), configurationFile ); +} + +//------------------------------------------------------------------------------ + +ConfigurationFile * ProjectBuilderFixture::loadConfigurationFile() +{ + ConfigurationFileLoader loader{ getJsonAccessor(), getFileSystem() }; + m_configurationFile = loader.load( getArgumentParser() ); + return m_configurationFile.get(); } //------------------------------------------------------------------------------ @@ -109,13 +117,6 @@ std::size_t ProjectBuilderFixture::getFileFiltersCount() const //------------------------------------------------------------------------------ -const std::regex & ProjectBuilderFixture::getFileFilter( int _index ) const -{ - return getProject().getFileFilter( _index ); -} - -//------------------------------------------------------------------------------ - bool ProjectBuilderFixture::getIgnoreSystemIncludes() const { return getProject().getIgnoreSystemIncludes(); @@ -232,11 +233,7 @@ ProjectBuilder & ProjectBuilderFixture::getBuilder() if( !m_builder ) { m_builder.reset( - new ProjectBuilder( - getProjectAccessor(), - getJsonAccessor(), - getFileSystem() - ) + new ProjectBuilder( getProjectAccessor(), getFileSystem() ) ); } return *m_builder; diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_project_builder_fixture.hpp index 91703ed..cf910c7 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.hpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.hpp @@ -12,25 +12,20 @@ namespace project { class Project; } -//------------------------------------------------------------------------------ - namespace json { class JsonAccessor; } -//------------------------------------------------------------------------------ - namespace fs { class FileSystemAccessor; class FileSystem; class File; } -//------------------------------------------------------------------------------ - namespace application { class ParserArgWrapper; class ProjectBuilder; + class ConfigurationFile; } //------------------------------------------------------------------------------ @@ -63,7 +58,6 @@ class ProjectBuilderFixture std::string getIgnoreDirs() const; std::size_t getFileFiltersCount() const; - const std::regex & getFileFilter( int _index ) const; bool getIgnoreSystemIncludes() const; std::string getFileExtensions() const; @@ -82,6 +76,8 @@ class ProjectBuilderFixture template< class _Strings > static std::string toString( const _Strings & _strings ); + ConfigurationFile * loadConfigurationFile(); + ParserArgWrapper & getArgumentParser(); ProjectBuilder & getBuilder(); @@ -96,6 +92,8 @@ class ProjectBuilderFixture std::unique_ptr< project::Project > m_project; std::unique_ptr< ParserArgWrapper > m_parser; std::unique_ptr< ProjectBuilder > m_builder; + std::unique_ptr< ConfigurationFile > m_configurationFile; + PluginPtr< project::ProjectAccessor > m_projectAccessor; PluginPtr< json::JsonAccessor > m_json; diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp new file mode 100644 index 0000000..a7b621d --- /dev/null +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp @@ -0,0 +1,235 @@ +#include "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" + +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_report_settings_loader.hpp" +#include "application/tools/app_configuration_file.hpp" + +#include "reporter/api/rp_settings.hpp" +#include "reporter/ih/rp_accessor_impl.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "json/ih/json_accessor_impl.hpp" +#include "json/api/json_object.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace application::test { + +//------------------------------------------------------------------------------ + +ReportSettingsLoaderFixture::ReportSettingsLoaderFixture() = default; +ReportSettingsLoaderFixture::~ReportSettingsLoaderFixture() = default; + +//------------------------------------------------------------------------------ + +void ReportSettingsLoaderFixture::parserArguments( std::string_view _argument ) +{ + std::vector< std::string > arguments; + arguments.push_back( "./application" ); + arguments.push_back( std::string{ _argument.data() } ); + + ParserArgWrapper & parserArguments = ensureParserArguments(); + parserArguments.parse( arguments ); +} + +//------------------------------------------------------------------------------ + +void ReportSettingsLoaderFixture::createConfigurationFile( std::string_view _json ) +{ + std::stringstream stream; + stream << _json; + auto jsonPtr = ensureJsonAccessor().createJson( stream ); + INTERNAL_CHECK_ERROR( jsonPtr ); + const json::JsonObject & json = *jsonPtr; + ensureConfigurationFile().loadFromJson( json ); +} + +//------------------------------------------------------------------------------ + +void ReportSettingsLoaderFixture::load() +{ + ParserArgWrapper & arguments = ensureParserArguments(); + ConfigurationFile * configurationFile = getConfigurationFile(); + + ReportSettingsLoader & loader = ensureLoader(); + + m_settings = loader.load( arguments, configurationFile ); + m_reportKinds = loader.loadReports( arguments, configurationFile ); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoaderFixture::CountType +ReportSettingsLoaderFixture::getMaxFilesCount() const +{ + return getSettings().getMaxFilesCount(); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoaderFixture::CountType +ReportSettingsLoaderFixture::getDefaultMaxFilesCount() const +{ + return getArguments().getDefaultReportLimit(); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoaderFixture::CountType +ReportSettingsLoaderFixture::getMaxDetailsCount() const +{ + return getSettings().getMaxDetailsCount(); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoaderFixture::CountType +ReportSettingsLoaderFixture::getDefaultMaxDetailsCount() const +{ + return getArguments().getDefaultReportDetailsLimit(); +} + +//------------------------------------------------------------------------------ + +bool ReportSettingsLoaderFixture::getShowStdFiles() const +{ + return getSettings().getShowStdFiles(); +} + +//------------------------------------------------------------------------------ + +bool ReportSettingsLoaderFixture::getDefaultShowStdFiles() const +{ + return getArguments().getDefaultShowStdfile(); +} + +//------------------------------------------------------------------------------ + +std::string ReportSettingsLoaderFixture::getReports() const +{ + return toString( m_reportKinds ); +} + +//------------------------------------------------------------------------------ + +std::string ReportSettingsLoaderFixture::getDefaultReports() const +{ + return toString( getArguments().getDefaultReporterKinds() ); +} + +//------------------------------------------------------------------------------ + +ConfigurationFile * ReportSettingsLoaderFixture::getConfigurationFile() const +{ + return m_configurationFile.get(); +} + +//------------------------------------------------------------------------------ + +ConfigurationFile & ReportSettingsLoaderFixture::ensureConfigurationFile() +{ + if( !m_configurationFile ) + m_configurationFile.reset( new ConfigurationFile ); + + return *m_configurationFile; +} + +//------------------------------------------------------------------------------ + +reporter::Settings & ReportSettingsLoaderFixture::getSettings() const +{ + INTERNAL_CHECK_ERROR( m_settings ); + return *m_settings; +} + +//------------------------------------------------------------------------------ + +ParserArgWrapper & ReportSettingsLoaderFixture::getArguments() const +{ + INTERNAL_CHECK_ERROR( m_arguments ); + return *m_arguments; +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader & ReportSettingsLoaderFixture::ensureLoader() +{ + if( !m_loader ) + m_loader.reset( new ReportSettingsLoader{ ensureReportFactory() } ); + + return *m_loader; +} + +//------------------------------------------------------------------------------ + +json::JsonAccessor & ReportSettingsLoaderFixture::ensureJsonAccessor() +{ + if( !m_json ) + m_json.reset( new json::JsonAccesorImpl ); + + return *m_json; +} + +//------------------------------------------------------------------------------ + +ParserArgWrapper & ReportSettingsLoaderFixture::ensureParserArguments() +{ + if( !m_arguments ) + { + m_arguments.reset( new ParserArgWrapper ); + m_arguments->init(); + } + + return *m_arguments; +} + +//------------------------------------------------------------------------------ + +reporter::Factory & ReportSettingsLoaderFixture::ensureReportFactory() +{ + return ensureReporterAccessor().getReporterFactory(); +} + +//------------------------------------------------------------------------------ + +reporter::ReporterAccessor & ReportSettingsLoaderFixture::ensureReporterAccessor() +{ + if( !m_reporterAccessor ) + m_reporterAccessor.reset( new reporter::ReporterAccessorImpl ); + + return *m_reporterAccessor; +} + +//------------------------------------------------------------------------------ + +std::string ReportSettingsLoaderFixture::toString( + const ReporterKinds & _reports +) +{ + std::set< std::string > names; + for( reporter::ReporterKind kind : _reports ) + { + const std::string name = reporter::reporterKindToString( kind ); + names.insert( name ); + } + + std::string result; + for( const std::string & name : names ) + { + if( !result.empty() ) + result += ','; + + result += name; + } + return result; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp new file mode 100644 index 0000000..4c72e54 --- /dev/null +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "reporter/api/enums/rp_reporter_kind.hpp" + +#include + +#include +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + class Settings; + class Factory; + class ReporterAccessor; +} + +namespace json { + class JsonAccessor; +} + +namespace application { + class ReportSettingsLoader; + class ParserArgWrapper; + class ConfigurationFile; +} + +//------------------------------------------------------------------------------ + +namespace application::test { + +//------------------------------------------------------------------------------ + +class ReportSettingsLoaderFixture +{ +public: + + using CountType = std::size_t; + + ReportSettingsLoaderFixture(); + ~ReportSettingsLoaderFixture(); + + void parserArguments( std::string_view _argument ); + void createConfigurationFile( std::string_view _json ); + + void load(); + + CountType getMaxFilesCount() const; + CountType getDefaultMaxFilesCount() const; + + CountType getMaxDetailsCount() const; + CountType getDefaultMaxDetailsCount() const; + + bool getShowStdFiles() const; + bool getDefaultShowStdFiles() const; + + std::string getReports() const; + std::string getDefaultReports() const; + +private: + + using ReporterKinds = std::vector< reporter::ReporterKind >; + + ConfigurationFile * getConfigurationFile() const; + ConfigurationFile & ensureConfigurationFile(); + + reporter::Settings & getSettings() const; + reporter::Factory & ensureReportFactory(); + reporter::ReporterAccessor & ensureReporterAccessor(); + + ParserArgWrapper & getArguments() const; + ParserArgWrapper & ensureParserArguments(); + + ReportSettingsLoader & ensureLoader(); + + json::JsonAccessor & ensureJsonAccessor(); + + static std::string toString( const ReporterKinds & _reports ); + +private: + + std::unique_ptr< reporter::ReporterAccessor > m_reporterAccessor; + std::unique_ptr< ReportSettingsLoader > m_loader; + std::unique_ptr< ParserArgWrapper > m_arguments; + + std::unique_ptr< json::JsonAccessor > m_json; + + std::unique_ptr< reporter::Settings > m_settings; + std::unique_ptr< ConfigurationFile > m_configurationFile; + + ReporterKinds m_reportKinds; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/test/suits/app_test_cmake_project_builder.cpp b/src/application/test/suits/app_test_cmake_project_builder.cpp new file mode 100644 index 0000000..28dc1c6 --- /dev/null +++ b/src/application/test/suits/app_test_cmake_project_builder.cpp @@ -0,0 +1,285 @@ +#include "application/test/fixtures/app_test_cmake_project_builder_fixture.hpp" + +#include "cmake_project/api/cprj_project.hpp" + +#include "application/resources/app_resources_arguments.hpp" + +#include + +#include +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN +1. File not exist +2. Default compilation file exist +3. Compilation file from arguments +4. Compilation file from configuration file +5. Include files + 5.1 Several includes + 5.2 Different includes in different files + +------------------------------------------------------------------------------*/ + +namespace application::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(CMakeProjectBuildersTets, CMakeProjectBuilderFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_file_not_exist) +{ + //Run + buildProject(); + + //Check + BOOST_CHECK( !isInitializedProject() ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_default_compilation_file_exist) +{ + // Init + addCMakeFile( + resources::arguments::compileCommands::DefaultValue, + R"([ + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file1.cpp.o -c file1.cpp", + "file": "file1.cpp" + }, + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file2.cpp.o -c file2.cpp", + "file": "file2.cpp" + } + ])" + ); + + //Run + buildProject(); + + //Check + BOOST_REQUIRE( isInitializedProject() ); + + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { + "/tmp/project/file1.cpp", + "/tmp/project/file2.cpp" + } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_compilation_file_from_arguments) +{ + // Init + std::string compilationFile = "build/compile_commands.json"; + + addCMakeFile( + compilationFile, + R"([ + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file1.cpp.o -c file1.cpp", + "file": "file1.cpp" + }, + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file2.cpp.o -c file2.cpp", + "file": "file2.cpp" + } + ])" + ); + + //Run + parserArgument( "--compile_commands=" + compilationFile ); + buildProject(); + + //Check + BOOST_REQUIRE( isInitializedProject() ); + + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { + "/tmp/project/file1.cpp", + "/tmp/project/file2.cpp" + } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_compilation_file_from_configuration_file) +{ + //Init + std::string compilationFile = "build/compile_commands.json"; + + addCMakeFile( + compilationFile, + R"([ + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file1.cpp.o -c file1.cpp", + "file": "file1.cpp" + }, + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file2.cpp.o -c file2.cpp", + "file": "file2.cpp" + } + ])" + ); + + //Run + setCompilationFileInConfigurationFile( compilationFile ); + buildProject(); + + //Check + BOOST_REQUIRE( isInitializedProject() ); + + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { + "/tmp/project/file1.cpp", + "/tmp/project/file2.cpp" + } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_1_include_files_several_includes) +{ + //Init + addCMakeFile( + resources::arguments::compileCommands::DefaultValue, + R"([ + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file1.cpp.o -I./lib1/ -I./lib2/ -c file1.cpp", + "file": "file1.cpp" + } + ])" + ); + + //Run + buildProject(); + + //Check + BOOST_REQUIRE( isInitializedProject() ); + + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { "/tmp/project/file1.cpp" } ); + + BOOST_REQUIRE_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); + + const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); + const auto exceptedIncludes = toExceptedFiles( { "./lib1/" , "./lib2/" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludesFile.begin(), + resultIncludesFile.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) +{ + //Init + addCMakeFile( + resources::arguments::compileCommands::DefaultValue, + R"([ + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file1.cpp.o -I./lib1/ -c file1.cpp", + "file": "file1.cpp" + }, + { + "directory": "/tmp/project", + "command": "/usr/bin/c++ -o file2.cpp.o -I./lib2/ -c file2.cpp", + "file": "file2.cpp" + } + ])" + ); + + //Run + buildProject(); + + //Check + BOOST_REQUIRE( isInitializedProject() ); + + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { + "/tmp/project/file1.cpp", + "/tmp/project/file2.cpp" + } ); + + BOOST_REQUIRE_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); + + { + const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); + const auto exceptedIncludes = toExceptedFiles( { "./lib1/" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludesFile.begin(), + resultIncludesFile.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } + { + const auto resultIncludesFile = getResultIncludes( "/tmp/project/file2.cpp" ); + const auto exceptedIncludes = toExceptedFiles( { "./lib2/" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludesFile.begin(), + resultIncludesFile.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} + diff --git a/src/application/test/suits/app_test_configuration_file_suits.cpp b/src/application/test/suits/app_test_configuration_file_suits.cpp index 40fd249..f09e94c 100644 --- a/src/application/test/suits/app_test_configuration_file_suits.cpp +++ b/src/application/test/suits/app_test_configuration_file_suits.cpp @@ -16,6 +16,15 @@ TEST PLAN 6. Ignore system includes 7. Ignore files 8. Analyze without extension +9. Reports + 9.1 Unresolved + 9.2 MostImpact + 9.3 Dump + 9.4 Several reports +10. Report limit +11. Report details limit +12. Show std files +13. Compile commands -------------------------------------------------------------------------------*/ @@ -148,6 +157,126 @@ BOOST_AUTO_TEST_CASE(t8_analyze_without_extension) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t9_1_report_unresolved) +{ + + // Run + loadFromJson( R"({ "report" : [ "unresolved" ] })" ); + + // Check + auto valueOpt = getReports(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, "unresolved" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t9_2_report_most_impact) +{ + + // Run + loadFromJson( R"({ "report" : [ "most_impact" ] })" ); + + // Check + auto valueOpt = getReports(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, "most_impact" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t9_3_report_dump) +{ + + // Run + loadFromJson( R"({ "report" : [ "dump" ] })" ); + + // Check + auto valueOpt = getReports(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, "dump" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t9_4_several_reports) +{ + + // Run + loadFromJson( R"({ "report" : [ "unresolved" , "most_impact", "dump" ] })" ); + + // Check + auto valueOpt = getReports(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, "unresolved,most_impact,dump" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t10_report_limit) +{ + + // Run + loadFromJson( R"({ "report_limit" : 10 })" ); + + // Check + auto valueOpt = getReportLimit(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, 10 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t11_report_details_limit) +{ + + // Run + loadFromJson( R"({ "report_details_limit" : 10 })" ); + + // Check + auto valueOpt = getReportDetailsLimit(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, 10 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t12_show_std_files) +{ + + // Run + loadFromJson( R"({ "show_std_files" : true })" ); + + // Check + auto valueOpt = getShowStdFile(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t13_compile_commands) +{ + + // Run + loadFromJson( R"({ "compile_commands" : "compile_commands.json" })" ); + + // Check + auto valueOpt = getCompileCommands(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, stdfs::path{ "compile_commands.json" } ); +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp index f222138..0a383ad 100644 --- a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp +++ b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp @@ -4,6 +4,7 @@ #include "application/exceptions/app_exceptions.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/exceptions/rp_exceptions.hpp" #include @@ -56,6 +57,9 @@ TEST PLAN 15. Show std files 15.1 From arguments 15.2 Default +16. Compile commands + 16.1 From arguments + 16.2 Default -------------------------------------------------------------------------------*/ @@ -63,23 +67,17 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(ParserWrapperTets, ParserWrapperFixture) +BOOST_FIXTURE_TEST_SUITE( ParserWrapperTets, ParserWrapperFixture ) //------------------------------------------------------------------------------ BOOST_AUTO_TEST_CASE(t1_1_project_dir_from_argument) { - // Init - const std::string argumentName = resources::arguments::projectDir::FullName; - const std::string argumentValue = "test_value"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--project_dir=test_value" ); // Check - BOOST_CHECK_EQUAL( argumentValue, getProjectDir() ); + BOOST_CHECK_EQUAL( "test_value", getProjectDir() ); } //------------------------------------------------------------------------------ @@ -87,7 +85,7 @@ BOOST_AUTO_TEST_CASE(t1_1_project_dir_from_argument) BOOST_AUTO_TEST_CASE(t1_2_project_dir_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -101,33 +99,24 @@ BOOST_AUTO_TEST_CASE(t1_2_project_dir_default) BOOST_AUTO_TEST_CASE(t1_3_project_dir_from_argument_without_full_name) { // Init - const std::string projectDir = "project_dir"; - - // Run - parse({ projectDir }); + parse( "project_dir" ); // Check - BOOST_CHECK_EQUAL( projectDir, getProjectDir() ); + BOOST_CHECK_EQUAL( "project_dir", getProjectDir() ); } //------------------------------------------------------------------------------ BOOST_AUTO_TEST_CASE(t2_1_file_extensions_from_argument) { - // Init - const std::string argumentName = resources::arguments::fileExtensions::FullName; - const std::string argumentValue = "*.cpp,*.hpp"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--file_extensions=*.cpp,*.hpp" ); // Check auto fileExtensions = getFileExtensions(); BOOST_REQUIRE_EQUAL( fileExtensions.size(), 2 ); - BOOST_CHECK_EQUAL(fileExtensions.at( 0 ), "*.cpp"); - BOOST_CHECK_EQUAL(fileExtensions.at( 1 ), "*.hpp"); + BOOST_CHECK_EQUAL( fileExtensions.at( 0 ), "*.cpp"); + BOOST_CHECK_EQUAL( fileExtensions.at( 1 ), "*.hpp"); } //------------------------------------------------------------------------------ @@ -135,7 +124,7 @@ BOOST_AUTO_TEST_CASE(t2_1_file_extensions_from_argument) BOOST_AUTO_TEST_CASE(t2_2_file_extensions_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -148,20 +137,14 @@ BOOST_AUTO_TEST_CASE(t2_2_file_extensions_default) BOOST_AUTO_TEST_CASE(t3_1_include_dirs_from_argument) { - // Init - const std::string argumentName = resources::arguments::includeDirs::FullName; - const std::string argumentValue = "/include/dir1,/include/dir2"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--include_dirs=/include/dir1,/include/dir2" ); // Check auto includeDirs = getIncludeDirs(); BOOST_REQUIRE_EQUAL( includeDirs.size(), 2 ); - BOOST_CHECK_EQUAL(includeDirs.at( 0 ), "/include/dir1"); - BOOST_CHECK_EQUAL(includeDirs.at( 1 ), "/include/dir2"); + BOOST_CHECK_EQUAL( includeDirs.at( 0 ), "/include/dir1" ); + BOOST_CHECK_EQUAL( includeDirs.at( 1 ), "/include/dir2" ); } //------------------------------------------------------------------------------ @@ -169,7 +152,7 @@ BOOST_AUTO_TEST_CASE(t3_1_include_dirs_from_argument) BOOST_AUTO_TEST_CASE(t3_2_include_dirs_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -182,14 +165,8 @@ BOOST_AUTO_TEST_CASE(t3_2_include_dirs_default) BOOST_AUTO_TEST_CASE(t4_1_ignore_dirs_from_argument) { - // Init - const std::string argumentName = resources::arguments::ignoreDirs::FullName; - const std::string argumentValue = "/include/dir1,/include/dir2"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--ignore_dirs=/include/dir1,/include/dir2" ); // Check auto includeDirs = getIgnoreDirs(); @@ -203,7 +180,7 @@ BOOST_AUTO_TEST_CASE(t4_1_ignore_dirs_from_argument) BOOST_AUTO_TEST_CASE(t4_2_ignore_dirs_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -216,17 +193,11 @@ BOOST_AUTO_TEST_CASE(t4_2_ignore_dirs_default) BOOST_AUTO_TEST_CASE(t5_1_configuration_file_from_arguments) { - // Init - const std::string argumentName = resources::arguments::configurationFile::FullName; - const std::string argumentValue = "./file"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--configuration_file=./file" ); // Check - BOOST_CHECK_EQUAL(getConfigurationFile().string(), argumentValue ); + BOOST_CHECK_EQUAL(getConfigurationFile().string(), "./file" ); } //------------------------------------------------------------------------------ @@ -234,7 +205,7 @@ BOOST_AUTO_TEST_CASE(t5_1_configuration_file_from_arguments) BOOST_AUTO_TEST_CASE(t5_2_configuration_file_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -247,12 +218,8 @@ BOOST_AUTO_TEST_CASE(t5_2_configuration_file_default) BOOST_AUTO_TEST_CASE(t6_1_help_from_arguments) { - // Init - const std::string argumentName = resources::arguments::help::FullName; - const std::string argument = "--" + argumentName; - // Run - parse({ argument }); + parse( "--help" ); // Check BOOST_CHECK( isHelp() ); @@ -262,12 +229,8 @@ BOOST_AUTO_TEST_CASE(t6_1_help_from_arguments) BOOST_AUTO_TEST_CASE(t7_verbose) { - // Init - const std::string argumentName = resources::arguments::verbose::FullName; - const std::string argument = "--" + argumentName; - // Run - parse({ argument }); + parse( "--verbose" ); // Check BOOST_CHECK( isVerbose() ); @@ -277,29 +240,19 @@ BOOST_AUTO_TEST_CASE(t7_verbose) BOOST_AUTO_TEST_CASE(t8_1_report_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = report::FullName; - const std::string argumentValue = report::UnresolvedReport; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--report=unresolved" ); // Check - BOOST_CHECK_EQUAL( - toString( getReporterKinds() ), - toString( reporter::ReporterKind::Unresolved ) - );} + BOOST_CHECK_EQUAL( "unresolved" , toString( getReporterKinds() ) ); +} //------------------------------------------------------------------------------ BOOST_AUTO_TEST_CASE(t8_2_report_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -312,38 +265,21 @@ BOOST_AUTO_TEST_CASE(t8_2_report_default) BOOST_AUTO_TEST_CASE(t8_3_report_incorrect_name) { - // Init - using namespace resources::arguments; - - const std::string argumentName = report::FullName; - const std::string argumentValue = "incorrect_name"; - - const std::string argument = "--" + argumentName + "=" + argumentValue; - // Check - parse({ argument }); + parse( "--report=incorrect_name" ); - BOOST_CHECK_THROW( getReporterKinds(), IncorrectReport ); + BOOST_CHECK_THROW( getReporterKinds(), reporter::IncorrectReport ); } //------------------------------------------------------------------------------ BOOST_AUTO_TEST_CASE(t9_1_report_limit_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = report_limit::FullName; - const int argumentValue = 42; - - const std::string argument = - "--" + argumentName + "=" + std::to_string( argumentValue ); - // Run - parse({ argument }); + parse( "--report_limit=42" ); // Check - BOOST_CHECK_EQUAL( getReportLimit(), argumentValue ); + BOOST_CHECK_EQUAL( getReportLimit(), 42 ); } //------------------------------------------------------------------------------ @@ -351,7 +287,7 @@ BOOST_AUTO_TEST_CASE(t9_1_report_limit_from_argument) BOOST_AUTO_TEST_CASE(t9_2_report_limit_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -364,22 +300,13 @@ BOOST_AUTO_TEST_CASE(t9_2_report_limit_default) BOOST_AUTO_TEST_CASE(t10_1_ignore_system_includes_from_arguments) { - // Init - using namespace resources::arguments; - - const std::string argumentName = ignoreSystemIncludes ::FullName; - const bool argumentValue = true; - - const std::string argument = - "--" + argumentName + "=" + ( argumentValue ? "true" : "false" ); - // Run - parse({ argument }); + parse( "--ignore_system_includes=true" ); // Check auto valueOpt = getIgnoreSystemIncludes(); BOOST_REQUIRE( valueOpt.has_value() ); - BOOST_CHECK_EQUAL( *valueOpt, argumentValue ); + BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ @@ -387,7 +314,7 @@ BOOST_AUTO_TEST_CASE(t10_1_ignore_system_includes_from_arguments) BOOST_AUTO_TEST_CASE(t10_2_ignore_system_includes_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -400,21 +327,12 @@ BOOST_AUTO_TEST_CASE(t10_2_ignore_system_includes_default) BOOST_AUTO_TEST_CASE(t11_1_ignore_files_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = ignoreFiles::FullName; - const std::string argumentValue = "lib1_*,lib2_*"; - - const std::string argument = - "--" + argumentName + "=" + argumentValue; - // Run - parse({ argument }); + parse( "--ignore_files=lib1_*,lib2_*" ); // Check - BOOST_CHECK_EQUAL( getIgnoreFiles(), argumentValue ); + BOOST_CHECK_EQUAL( getIgnoreFiles(), "lib1_*,lib2_*" ); } //------------------------------------------------------------------------------ @@ -422,7 +340,7 @@ BOOST_AUTO_TEST_CASE(t11_1_ignore_files_from_argument) BOOST_AUTO_TEST_CASE(t11_2_ignore_files_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -435,13 +353,8 @@ BOOST_AUTO_TEST_CASE(t11_2_ignore_files_default) BOOST_AUTO_TEST_CASE(t12_version) { - // Init - const std::string argumentName = resources::arguments::version::FullName; - - const std::string argument = "--" + argumentName; - // Run - parse({ argument }); + parse( "--version" ); // Check @@ -452,20 +365,11 @@ BOOST_AUTO_TEST_CASE(t12_version) BOOST_AUTO_TEST_CASE(t13_1_report_details_limit_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = report_details_limit::FullName; - const int argumentValue = 42; - - const std::string argument = - "--" + argumentName + "=" + std::to_string( argumentValue ); - // Run - parse({ argument }); + parse( "--report_details_limit=42"); // Check - BOOST_CHECK_EQUAL( getReportDetailsLimit(), argumentValue ); + BOOST_CHECK_EQUAL( getReportDetailsLimit(), 42 ); } //------------------------------------------------------------------------------ @@ -473,7 +377,7 @@ BOOST_AUTO_TEST_CASE(t13_1_report_details_limit_from_argument) BOOST_AUTO_TEST_CASE(t13_2_report_details_limit_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -486,20 +390,11 @@ BOOST_AUTO_TEST_CASE(t13_2_report_details_limit_default) BOOST_AUTO_TEST_CASE(t14_1_analyze_without_extension_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = analyze_without_extension::FullName; - const bool argumentValue = true; - - const std::string argument = - "--" + argumentName + "=" + std::to_string( argumentValue ); - // Run - parse({ argument }); + parse( "--analyze_without_extension=true" ); // Check - BOOST_CHECK_EQUAL( getAnalyzeWithoutExtension(), argumentValue ); + BOOST_CHECK_EQUAL( getAnalyzeWithoutExtension(), true ); } //------------------------------------------------------------------------------ @@ -507,7 +402,7 @@ BOOST_AUTO_TEST_CASE(t14_1_analyze_without_extension_from_argument) BOOST_AUTO_TEST_CASE(t14_2_analyze_without_extension_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -520,22 +415,13 @@ BOOST_AUTO_TEST_CASE(t14_2_analyze_without_extension_default) BOOST_AUTO_TEST_CASE(t15_1_show_std_files_from_argument) { - // Init - using namespace resources::arguments; - - const std::string argumentName = show_std_files::FullName; - const bool argumentValue = true; - - const std::string argument = - "--" + argumentName + "=" + std::to_string( argumentValue ); - // Run - parse({ argument }); + parse( "--show_std_files=true" ); // Check auto valueOpt = getShowStdFile(); BOOST_REQUIRE( valueOpt.has_value() ); - BOOST_CHECK_EQUAL( *valueOpt, argumentValue ); + BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ @@ -543,7 +429,7 @@ BOOST_AUTO_TEST_CASE(t15_1_show_std_files_from_argument) BOOST_AUTO_TEST_CASE(t15_1_show_std_files_default) { // Run - parse({ "" }); + parse( "" ); // Check BOOST_CHECK_EQUAL( @@ -554,6 +440,31 @@ BOOST_AUTO_TEST_CASE(t15_1_show_std_files_default) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t16_1_compile_commands_from_arguments) +{ + // Run + parse( "--compile_commands=build/compile_commands.json" ); + + // Check + BOOST_CHECK_EQUAL(getCompileCommandsFile().string(), "build/compile_commands.json" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t16_2_compile_commands_default) +{ + // Run + parse( "" ); + + // Check + BOOST_CHECK_EQUAL( + resources::arguments::compileCommands::DefaultValue, + getDefaultCompileCommandsFile().string() + ); +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_report_settings_loader.cpp b/src/application/test/suits/app_test_report_settings_loader.cpp new file mode 100644 index 0000000..f7ed075 --- /dev/null +++ b/src/application/test/suits/app_test_report_settings_loader.cpp @@ -0,0 +1,205 @@ +#include "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN: + +1. Empty +2. Load settings + 2.1 max files + 2.1.1 from arguments + 2.1.2 from configuration file + 2.1.3 mix + 2.2 max details + 2.2.1 from arguments + 2.2.2 from configuration file + 2.2.3 mix + 3.3 show std files + 2.3.1 from arguments + 2.3.2 from configuration file + 2.3.3 mix +3. Load report kinds + 3.1 From arguments + 3.2 From configuration file + +------------------------------------------------------------------------------*/ + +namespace application::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(ReportSettingsLoaderTests, ReportSettingsLoaderFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_empty_arguments_and_configuration_file) +{ + //Run + parserArguments( "" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxFilesCount(), getDefaultMaxFilesCount() ); + BOOST_CHECK_EQUAL( getMaxDetailsCount(), getDefaultMaxDetailsCount() ); + BOOST_CHECK_EQUAL( getShowStdFiles(), getDefaultShowStdFiles() ); + BOOST_CHECK_EQUAL( getReports(), getDefaultReports() ); + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_1_1_load_max_files_from_arguments) +{ + //Run + parserArguments( "--report_limit=42" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxFilesCount(), 42 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_1_2_load_max_files_from_configuration_file) +{ + //Run + createConfigurationFile( R"({ "report_limit" : 42 })" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxFilesCount(), 42 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_1_3_load_max_files_from_mix) +{ + //Run + createConfigurationFile( R"({ "report_limit" : 1 })" ); + parserArguments( "--report_limit=2" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxFilesCount(), 2); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_2_1_load_max_details_from_arguments) +{ + //Run + parserArguments( "--report_details_limit=42" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxDetailsCount(), 42 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_2_2_load_max_details_from_configuration_file) +{ + //Run + createConfigurationFile( R"({ "report_details_limit" : 42 })" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxDetailsCount(), 42 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_2_2_load_max_details_from_mix) +{ + //Run + createConfigurationFile( R"({ "report_details_limit" : 1 })" ); + parserArguments( "--report_details_limit=2" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getMaxDetailsCount(), 2 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_3_1_load_show_std_files_from_arguments) +{ + //Run + parserArguments( "--show_std_files=true" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getShowStdFiles(), true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_3_2_load_show_std_files_from_configuration_file) +{ + //Run + createConfigurationFile( R"({ "show_std_files" : true })" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getShowStdFiles(), true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_3_3_load_show_std_files_from_mix) +{ + //Run + createConfigurationFile( R"({ "show_std_files" : true })" ); + parserArguments( "--show_std_files=false" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getShowStdFiles(), false ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_3_1_load_reports_from_arguments) +{ + //Run + parserArguments( "--report=most_impact,unresolved" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getReports(), "most_impact,unresolved" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_3_2_load_reports_from_configuration_file) +{ + //Run + createConfigurationFile( R"({ "report" : [ "most_impact","unresolved" ] })" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getReports(), "most_impact,unresolved" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_3_3_load_reports_from_mix) +{ + //Run + createConfigurationFile( R"({ "report" : [ "most_impact" ] })" ); + parserArguments( "--report=unresolved" ); + load(); + + //Check + BOOST_CHECK_EQUAL( getReports(), "unresolved" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_cmake_project_builder.cpp b/src/application/tools/app_cmake_project_builder.cpp new file mode 100644 index 0000000..688fcdb --- /dev/null +++ b/src/application/tools/app_cmake_project_builder.cpp @@ -0,0 +1,163 @@ +#include "application/tools/app_cmake_project_builder.hpp" + +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_configuration_file.hpp" + +#include "compilation_db/api/cdb_database.hpp" +#include "compilation_db/api/cdb_loader.hpp" +#include "compilation_db/ih/cdb_accessor.hpp" + +#include "cmake_project/api/cprj_project.hpp" +#include "cmake_project/api/cprj_loader.hpp" +#include "cmake_project/ih/cprj_accessor.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "json/api/json_object.hpp" +#include "json/ih/json_accessor.hpp" + +#include "fs/api/fs_file_system.hpp" +#include "fs/api/fs_file.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace application { + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CMakeProjectBuilder( + cmake_project::Accessor & _cmakeAccessor, + compilation_db::Accessor & _compilationDbAccessor, + json::JsonAccessor & _jsonAccessor, + fs::FileSystem & _fs +) + : m_cmakeAccessor{ _cmakeAccessor } + , m_compilationDbAccessor{ _compilationDbAccessor } + , m_jsonAccessor{ _jsonAccessor } + , m_fs{ _fs } +{ + +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CMakeProjectPtr CMakeProjectBuilder::build( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + const Path path = getPathToCmake( _arguments, _configurationFile ); + if( isExistFile( path ) ) + { + auto projectPtr = loadProject( path ); + INTERNAL_CHECK_WARRING( projectPtr ); + return projectPtr; + } + + return nullptr; +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::Path CMakeProjectBuilder::getPathToCmake( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + if( auto pathOpt = _arguments.getCompileCommandsFile(); pathOpt ) + return *pathOpt; + + if( _configurationFile ) + { + if( auto pathOpt = _configurationFile->getCompileCommands(); pathOpt ) + return *pathOpt; + } + + return _arguments.getDefaultCompileCommandsFile(); +} + +//------------------------------------------------------------------------------ + +bool CMakeProjectBuilder::isExistFile( const Path & _path ) const +{ + return m_fs.isExistFile( _path ); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CMakeProjectPtr CMakeProjectBuilder::loadProject( + const Path & _path +) const +{ + auto compilationDbPtr = loadCompilationDb( _path ); + INTERNAL_CHECK_WARRING( compilationDbPtr ); + if( !compilationDbPtr ) + return nullptr; + + auto loaderPtr = createCmakeLoader(); + INTERNAL_CHECK_WARRING( loaderPtr ); + if( !loaderPtr ) + return nullptr; + + return loaderPtr->load( *compilationDbPtr ); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CMakeProjectLoaderPtr +CMakeProjectBuilder::createCmakeLoader() const +{ + return m_cmakeAccessor.createLoader(); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CompilationDbPtr CMakeProjectBuilder::loadCompilationDb( + const Path & _path +) const +{ + auto jsonPtr = loadJson( _path ); + INTERNAL_CHECK_WARRING( jsonPtr ); + if( !jsonPtr ) + return nullptr; + + auto loaderPtr = createCompilationDbLoader(); + INTERNAL_CHECK_WARRING( loaderPtr ); + if( !loaderPtr ) + return nullptr; + + return loaderPtr->load( *jsonPtr ); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::CompilationLoaderPtr +CMakeProjectBuilder::createCompilationDbLoader() const +{ + return m_compilationDbAccessor.createLoader(); +} + +//------------------------------------------------------------------------------ + +CMakeProjectBuilder::JsonPtr CMakeProjectBuilder::loadJson( + const Path & _path +) const +{ + auto filePtr = m_fs.openFile( _path ); + INTERNAL_CHECK_WARRING( filePtr ); + if( !filePtr ) + return nullptr; + + fs::File & file = *filePtr; + + JsonPtr json = m_jsonAccessor.createJson( file.toInputStream() ); + return json; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_cmake_project_builder.hpp b/src/application/tools/app_cmake_project_builder.hpp new file mode 100644 index 0000000..39e1781 --- /dev/null +++ b/src/application/tools/app_cmake_project_builder.hpp @@ -0,0 +1,91 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class Database; + class Loader; + class Accessor; +} + +namespace cmake_project { + class Project; + class Loader; + class Accessor; +} + +namespace fs { + class FileSystem; +} + +namespace json { + class JsonObject; + class JsonAccessor; +} + +//------------------------------------------------------------------------------ + +namespace application { + class ConfigurationFile; + class ParserArgWrapper; + +//------------------------------------------------------------------------------ + +class CMakeProjectBuilder +{ +public: + + using CMakeProjectPtr = stdfwd::unique_ptr< cmake_project::Project >; + using CMakeProjectLoaderPtr = stdfwd::unique_ptr< cmake_project::Loader >; + + using CompilationDbPtr = stdfwd::unique_ptr< compilation_db::Database >; + using CompilationLoaderPtr = stdfwd::unique_ptr< compilation_db::Loader >; + + using Path = stdfs::path; + + using JsonPtr = stdfwd::unique_ptr< json::JsonObject >; + + CMakeProjectBuilder( + cmake_project::Accessor & _cmakeAccessor, + compilation_db::Accessor & _compilationDbAccessor, + json::JsonAccessor & _jsonAccessor, + fs::FileSystem & _fs + ); + + CMakeProjectPtr build( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + +private: + + static Path getPathToCmake( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + bool isExistFile( const Path & _path ) const; + + CMakeProjectPtr loadProject( const Path & _path ) const; + CMakeProjectLoaderPtr createCmakeLoader() const; + + CompilationDbPtr loadCompilationDb( const Path & _path ) const; + CompilationLoaderPtr createCompilationDbLoader() const; + + JsonPtr loadJson( const Path & _path ) const; + +private: + + cmake_project::Accessor & m_cmakeAccessor; + compilation_db::Accessor & m_compilationDbAccessor; + json::JsonAccessor & m_jsonAccessor; + + fs::FileSystem & m_fs; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_configuration_file.cpp b/src/application/tools/app_configuration_file.cpp index b54c8df..b3ec06e 100644 --- a/src/application/tools/app_configuration_file.cpp +++ b/src/application/tools/app_configuration_file.cpp @@ -4,6 +4,8 @@ #include "exception/ih/exc_internal_error.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" + #include "json/api/json_object.hpp" #include "json/api/json_value.hpp" #include "json/api/json_array.hpp" @@ -24,6 +26,14 @@ void ConfigurationFile::loadFromJson( const json::JsonObject & _json ) loadIgnoreDirs( _json ); loadIgnoreSystemIncludes( _json ); loadIgnoreFiles( _json ); + + loadCompileCommands( _json ); + + loadReports( _json ); + loadReportLimit( _json ); + loadReportDetailsLimit( _json ); + loadShowStdFiles( _json ); + } //------------------------------------------------------------------------------ @@ -77,14 +87,53 @@ ConfigurationFile::StringsOpt ConfigurationFile::getIgnoreFiles() const //------------------------------------------------------------------------------ +ConfigurationFile::PathOpt ConfigurationFile::getCompileCommands() const +{ + return m_compileCommands; +} + +//------------------------------------------------------------------------------ + +void ConfigurationFile::setCompileCommands( const Path & _path ) +{ + m_compileCommands = _path; +} + +//------------------------------------------------------------------------------ + +ConfigurationFile::ReporterKindsOpt ConfigurationFile::getReporterKinds() const +{ + return m_reports; +} + +//------------------------------------------------------------------------------ + +ConfigurationFile::IntOpt ConfigurationFile::getReportLimit() const +{ + return m_reportLimit; +} + +//------------------------------------------------------------------------------ + +ConfigurationFile::IntOpt ConfigurationFile::getReportDetailsLimit() const +{ + return m_reportDetailsLimit; +} + +//------------------------------------------------------------------------------ + +ConfigurationFile::BoolOpt ConfigurationFile::getShowStdFiles() const +{ + return m_showStdFiles; +} + +//------------------------------------------------------------------------------ + void ConfigurationFile::loadProjectDir( const json::JsonObject & _json ) { using namespace resources; - StringOpt pathStrOpt; - loadStringValue( _json, configuration_file::ProjectDir, pathStrOpt); - - m_projectDir = pathStrOpt; + loadPathOpt( _json, configuration_file::ProjectDir, m_projectDir); } //------------------------------------------------------------------------------ @@ -154,6 +203,63 @@ void ConfigurationFile::loadIgnoreFiles( const json::JsonObject & _json ) //------------------------------------------------------------------------------ +void ConfigurationFile::loadCompileCommands( const json::JsonObject & _json ) +{ + using namespace resources; + + loadPathOpt( _json, configuration_file::CompileCommands, m_compileCommands ); +} + +//------------------------------------------------------------------------------ + +void ConfigurationFile::loadReports( const json::JsonObject & _json ) +{ + using namespace resources; + + StringsOpt stringsOpt; + + loadArrayOpt( _json, configuration_file::Report, stringsOpt ); + if( !stringsOpt ) + return; + + m_reports = ReporterKinds{}; + m_reports->reserve( stringsOpt->size() ); + for( const std::string str : *stringsOpt ) + { + const reporter::ReporterKind kind = reporter::toReporterKind( str ); + m_reports->push_back( kind ); + } +} + +//------------------------------------------------------------------------------ + +void ConfigurationFile::loadReportLimit( const json::JsonObject & _json ) +{ + using namespace resources; + + loadIntOpt( _json, configuration_file::ReportLimit, m_reportLimit ); +} + +//------------------------------------------------------------------------------ + +void ConfigurationFile::loadReportDetailsLimit( const json::JsonObject & _json ) +{ + using namespace resources; + + loadIntOpt( _json, configuration_file::ReportDetailsLimit, m_reportDetailsLimit ); +} + +//------------------------------------------------------------------------------ + +void ConfigurationFile::loadShowStdFiles( const json::JsonObject & _json ) +{ + using namespace resources; + + loadBoolOpt( _json, configuration_file::ShowStdFiles, m_showStdFiles ); +} + +//------------------------------------------------------------------------------ + void ConfigurationFile::loadStringValue( const json::JsonObject & _json, std::string_view _name, @@ -214,6 +320,20 @@ void ConfigurationFile::loadArrayOpt( //------------------------------------------------------------------------------ +void ConfigurationFile::loadPathOpt( + const json::JsonObject & _json, + std::string_view _name, + PathOpt & _valueOpt +) +{ + StringOpt pathStrOpt; + loadStringValue( _json, _name, pathStrOpt); + + _valueOpt = pathStrOpt; +} + +//------------------------------------------------------------------------------ + void ConfigurationFile::loadPathsOpt( const json::JsonObject & _json, std::string_view _name, @@ -252,4 +372,20 @@ void ConfigurationFile::loadBoolOpt( //------------------------------------------------------------------------------ +void ConfigurationFile::loadIntOpt( + const json::JsonObject & _json, + std::string_view _name, + IntOpt & _valueOpt +) +{ + if( auto valuePtr = _json.getAttributeValue( _name ); valuePtr ) + { + const json::JsonValue & value = *valuePtr; + const int valueInt = value.asInt(); + _valueOpt = valueInt; + } +} + +//------------------------------------------------------------------------------ + } diff --git a/src/application/tools/app_configuration_file.hpp b/src/application/tools/app_configuration_file.hpp index d2a0966..385d599 100644 --- a/src/application/tools/app_configuration_file.hpp +++ b/src/application/tools/app_configuration_file.hpp @@ -13,6 +13,10 @@ namespace json { class JsonObject; } +namespace reporter { + enum class ReporterKind; +} + //------------------------------------------------------------------------------ namespace application { @@ -33,6 +37,10 @@ class ConfigurationFile using PathsOpt = std::optional< Paths >; using BoolOpt = std::optional< bool >; + using IntOpt = std::optional< int >; + + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + using ReporterKindsOpt = std::optional< ReporterKinds >; void loadFromJson( const json::JsonObject & _json ); @@ -45,6 +53,15 @@ class ConfigurationFile BoolOpt getIgnoreSystemIncludes() const; StringsOpt getIgnoreFiles() const; + PathOpt getCompileCommands() const; + void setCompileCommands( const Path & _path ); + + ReporterKindsOpt getReporterKinds() const; + + IntOpt getReportLimit() const; + IntOpt getReportDetailsLimit() const; + BoolOpt getShowStdFiles() const; + private: void loadProjectDir( const json::JsonObject & _json ); @@ -56,6 +73,13 @@ class ConfigurationFile void loadIgnoreSystemIncludes( const json::JsonObject & _json ); void loadIgnoreFiles( const json::JsonObject & _json ); + void loadCompileCommands( const json::JsonObject & _json ); + + void loadReports( const json::JsonObject & _json ); + void loadReportLimit( const json::JsonObject & _json ); + void loadReportDetailsLimit( const json::JsonObject & _json ); + void loadShowStdFiles( const json::JsonObject & _json ); + void loadStringValue( const json::JsonObject & _json, std::string_view _name, @@ -68,6 +92,12 @@ class ConfigurationFile StringsOpt & _valueOpt ); + void loadPathOpt( + const json::JsonObject & _json, + std::string_view _name, + PathOpt & _valueOpt + ); + void loadPathsOpt( const json::JsonObject & _json, std::string_view _name, @@ -80,6 +110,12 @@ class ConfigurationFile BoolOpt & _valueOpt ); + void loadIntOpt( + const json::JsonObject & _json, + std::string_view _name, + IntOpt & _valueOpt + ); + private: PathOpt m_projectDir; @@ -90,6 +126,14 @@ class ConfigurationFile PathsOpt m_ignoreDirs; BoolOpt m_ignoreSystemIncludes; StringsOpt m_ignoreFiles; + + PathOpt m_compileCommands; + + ReporterKindsOpt m_reports; + + IntOpt m_reportLimit; + IntOpt m_reportDetailsLimit; + BoolOpt m_showStdFiles; }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file_loader.cpp b/src/application/tools/app_configuration_file_loader.cpp new file mode 100644 index 0000000..042e397 --- /dev/null +++ b/src/application/tools/app_configuration_file_loader.cpp @@ -0,0 +1,81 @@ +#include "application/tools/app_configuration_file_loader.hpp" + +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_configuration_file.hpp" + +#include "json/ih/json_accessor.hpp" +#include "json/api/json_object.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "fs/api/fs_file_system.hpp" +#include "fs/api/fs_file.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace application { + +//------------------------------------------------------------------------------ + +ConfigurationFileLoader::ConfigurationFileLoader( + JsonAccessor & _jsonAccessor, + const fs::FileSystem & _fs +) + : m_jsonAccessor{ _jsonAccessor } + , m_fs{ _fs } +{ + +} + +//------------------------------------------------------------------------------ + +ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( + const ParserArgWrapper & _arguments +) +{ + auto configurationPathOpt = _arguments.getConfigurationFile(); + if( !configurationPathOpt ) + configurationPathOpt = _arguments.getDefaultConfigurationFile(); + + INTERNAL_CHECK_WARRING( configurationPathOpt ); + if( !configurationPathOpt ) + return nullptr; + + if( !m_fs.isExistFile( *configurationPathOpt ) ) + return nullptr; + + auto filePtr = m_fs.openFile( *configurationPathOpt ); + INTERNAL_CHECK_WARRING( filePtr ) + if( !filePtr ) + return nullptr; + + return load( *filePtr ); +} + +//------------------------------------------------------------------------------ + +ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( + fs::File & _file +) +{ + auto jsonObjectPtr = m_jsonAccessor.createJson( _file.toInputStream() ); + INTERNAL_CHECK_WARRING( jsonObjectPtr ) + if( !jsonObjectPtr ) + return nullptr; + + ConfigurationFilePtr resultPtr{ new ConfigurationFile }; + INTERNAL_CHECK_WARRING( resultPtr ) + if( !resultPtr ) + return nullptr; + + resultPtr->loadFromJson( *jsonObjectPtr ); + return resultPtr; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_configuration_file_loader.hpp b/src/application/tools/app_configuration_file_loader.hpp new file mode 100644 index 0000000..61abd0d --- /dev/null +++ b/src/application/tools/app_configuration_file_loader.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace json { + class JsonAccessor; + class JsonObject; +} + +namespace fs { + class FileSystem; + class File; +} + +//------------------------------------------------------------------------------ + +namespace application { + class ConfigurationFile; + class ParserArgWrapper; + +//------------------------------------------------------------------------------ + +class ConfigurationFileLoader +{ +public: + + using ConfigurationFilePtr = stdfwd::unique_ptr< ConfigurationFile >; + using Path = stdfs::path; + + using JsonAccessor = json::JsonAccessor; + using JsonObject = json::JsonObject; + using JsonObjectPtr = stdfwd::unique_ptr< JsonObject >; + + ConfigurationFileLoader( + JsonAccessor & _jsonAccessor, + const fs::FileSystem & _fs + ); + + ConfigurationFilePtr load( const ParserArgWrapper & _arguments ); + ConfigurationFilePtr load( fs::File & _file ); + +private: + + JsonAccessor & m_jsonAccessor; + const fs::FileSystem & m_fs; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_parser_arg_wrapper.cpp b/src/application/tools/app_parser_arg_wrapper.cpp index 8d5de44..2b66805 100644 --- a/src/application/tools/app_parser_arg_wrapper.cpp +++ b/src/application/tools/app_parser_arg_wrapper.cpp @@ -1,17 +1,19 @@ #include "application/tools/app_parser_arg_wrapper.hpp" #include "application/resources/app_resources_arguments.hpp" -#include "application/exceptions/app_incorrect_report_impl.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" #include "exception/ih/exc_internal_error.hpp" #include "tools/is_vector.hpp" +#include "reporter/tools/rp_reporter_kind_functins.hpp" + #include #include #include #include #include +#include //------------------------------------------------------------------------------ @@ -60,6 +62,11 @@ ParserArgWrapper::ParserArgWrapper() resources::arguments::configurationFile::Description, Path( resources::arguments::configurationFile::DefaultValue ) } + , m_compileCommandsFileArg{ + resources::arguments::compileCommands::FullName, + resources::arguments::compileCommands::Description, + Path( resources::arguments::compileCommands::DefaultValue ) +} , m_helpArg{ resources::arguments::help::FullName, resources::arguments::help::Description @@ -122,6 +129,7 @@ void ParserArgWrapper::parse( int _argc, char * _argv[] ) setArgumentValue( m_ignoreFilesArg, &ParserArgWrapper::getStrings ); setArgumentValue( m_configurationFileArg, &ParserArgWrapper::getPath ); + setArgumentValue( m_compileCommandsFileArg, &ParserArgWrapper::getPath ); setArgumentValue( m_reportArg, &ParserArgWrapper::getStrings ); setArgumentValue( m_reportLimitArg, &ParserArgWrapper::getInt ); @@ -131,8 +139,28 @@ void ParserArgWrapper::parse( int _argc, char * _argv[] ) //------------------------------------------------------------------------------ +void ParserArgWrapper::parse( const stdfwd::vector< std::string > & _arguments ) +{ + std::vector< std::string >arguments{ _arguments }; + + std::vector< char * > arg; + arg.reserve( arguments.size() ); + + for( std::string & str : arguments ) + arg.push_back( str.data() ); + + parse( static_cast< int >( arg.size() ), arg.data() ); +} + +//------------------------------------------------------------------------------ + void ParserArgWrapper::init() { + addArgument< Strings >( m_reportArg ); + + addArgument< Path >( m_configurationFileArg ); + addArgument< Path >( m_compileCommandsFileArg ); + addArgument< Path >( m_projectDirArg ); addArgument< Strings >( m_fileExtensionsArg ); addArgument< bool >( m_analyzeWithoutextension ); @@ -142,9 +170,6 @@ void ParserArgWrapper::init() addArgument< bool >( m_ignoreSystemIncludes ); addArgument< Strings >( m_ignoreFilesArg ); - addArgument< Path >( m_configurationFileArg ); - - addArgument< Strings >( m_reportArg ); addArgument< int >( m_reportLimitArg ); addArgument< int >( m_reportDetailsLimitArg ); addArgument< bool >( m_showStdFilesArg ); @@ -255,13 +280,6 @@ ParserArgWrapper::PathsOpt ParserArgWrapper::getIgnoreDirs() const //------------------------------------------------------------------------------ -ParserArgWrapper::Path ParserArgWrapper::getDefaultConfigurationFile() const -{ - return getDefaultValue< Path >( m_configurationFileArg ); -} - -//------------------------------------------------------------------------------ - ParserArgWrapper::ReporterKinds ParserArgWrapper::getDefaultReporterKinds() const { Strings strings = getDefaultValue< Strings >( m_reportArg ); @@ -329,6 +347,27 @@ ParserArgWrapper::PathOpt ParserArgWrapper::getConfigurationFile() const //------------------------------------------------------------------------------ +ParserArgWrapper::Path ParserArgWrapper::getDefaultConfigurationFile() const +{ + return getDefaultValue< Path >( m_configurationFileArg ); +} + +//------------------------------------------------------------------------------ + +ParserArgWrapper::PathOpt ParserArgWrapper::getCompileCommandsFile() const +{ + return m_compileCommandsFileArg.getValue< Path >(); +} + +//------------------------------------------------------------------------------ + +ParserArgWrapper::Path ParserArgWrapper::getDefaultCompileCommandsFile() const +{ + return getDefaultValue< Path >( m_compileCommandsFileArg ); +} + +//------------------------------------------------------------------------------ + template< class _ValueType > void ParserArgWrapper::addArgument( const Argument & _argument ) { @@ -443,7 +482,8 @@ void ParserArgWrapper::showHelp( std::ostream & _stream ) const //------------------------------------------------------------------------------ ParserArgWrapper::Strings ParserArgWrapper::toStrings( - const char * const _values[] ) + const char * const _values[] +) { Strings array; const char * const * it = _values; @@ -497,24 +537,7 @@ ParserArgWrapper::ReporterKinds ParserArgWrapper::toReporterKinds( reporter::ReporterKind ParserArgWrapper::toReporterKind( std::string_view _str ) { - using namespace resources::arguments; - using namespace reporter; - - static_assert( static_cast< int >( ReporterKind::Count ) == 3 ); - - static std::unordered_map< std::string, reporter::ReporterKind > names{ - { report::UnresolvedReport, ReporterKind::Unresolved }, - { report::MostImpactReport, ReporterKind::MostImpact }, - { report::DumpReport, ReporterKind::Dump }, - }; - - const std::string str{ _str }; - if( !names.count( str ) ) - { - throw IncorrectReportImpl( _str, names ); - } - - return names[ str ]; + return reporter::toReporterKind( _str ); } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_parser_arg_wrapper.hpp b/src/application/tools/app_parser_arg_wrapper.hpp index bad06d1..76bece1 100644 --- a/src/application/tools/app_parser_arg_wrapper.hpp +++ b/src/application/tools/app_parser_arg_wrapper.hpp @@ -24,6 +24,7 @@ class ParserArgWrapper ParserArgWrapper(); void parse( int _argc, char * _argv[] ); + void parse( const stdfwd::vector< std::string > & _arguments ); void init(); using Path = stdfs::path; @@ -66,6 +67,9 @@ class ParserArgWrapper PathOpt getConfigurationFile() const; Path getDefaultConfigurationFile() const; + PathOpt getCompileCommandsFile() const; + Path getDefaultCompileCommandsFile() const; + ReporterKindsOpt getReporterKinds() const; ReporterKinds getDefaultReporterKinds() const; @@ -128,6 +132,7 @@ class ParserArgWrapper Argument m_ignoreFilesArg; Argument m_configurationFileArg; + Argument m_compileCommandsFileArg; Argument m_helpArg; Argument m_verboseArg; diff --git a/src/application/tools/app_project_builder.cpp b/src/application/tools/app_project_builder.cpp index 889db30..bed0886 100644 --- a/src/application/tools/app_project_builder.cpp +++ b/src/application/tools/app_project_builder.cpp @@ -6,11 +6,7 @@ #include "project/api/prj_project.hpp" #include "project/ih/prj_project_accessor.hpp" -#include "json/api/json_object.hpp" -#include "json/ih/json_accessor.hpp" - #include "fs/api/fs_file_system.hpp" -#include "fs/api/fs_file.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -25,11 +21,9 @@ namespace application { ProjectBuilder::ProjectBuilder( ProjectAccessor & _projectAccessor, - JsonAccessor & _jsonAccessor, FileSystem & _fs ) : m_projectAccessor{ _projectAccessor } - , m_jsonAccessor{ _jsonAccessor } , m_fs{ _fs } { @@ -38,7 +32,8 @@ ProjectBuilder::ProjectBuilder( //------------------------------------------------------------------------------ ProjectBuilder::ProjectPtr ProjectBuilder::build( - const ParserArgWrapper & _arguments + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile ) { ProjectPtr projectPtr = createProject(); @@ -48,14 +43,10 @@ ProjectBuilder::ProjectPtr ProjectBuilder::build( } Project & project = *projectPtr; - m_ignoreSystemIncludesChanged = false; - - auto configFileOpt = _arguments.getConfigurationFile(); - if( !configFileOpt ) - configFileOpt = _arguments.getDefaultConfigurationFile(); + reset(); - if( configFileOpt ) - initFromConfigurationFile( *configFileOpt, project ); + if( _configurationFile ) + initProject( *_configurationFile, project ); initProject( _arguments, project ); initProjectWithDefaultValues( _arguments, project ); @@ -140,26 +131,6 @@ void ProjectBuilder::initProject( //------------------------------------------------------------------------------ -void ProjectBuilder::initFromConfigurationFile( - const Path & _file, - Project & _project -) -{ - if( !m_fs.isExistFile( _file ) ) - return; - - JsonObjectPtr jsonObjectPtr = createJson( _file ); - INTERNAL_CHECK_WARRING( jsonObjectPtr ) - if( !jsonObjectPtr ) - return; - - ConfigurationFile configurationFile; - configurationFile.loadFromJson( *jsonObjectPtr ); - initProject( configurationFile, _project ); -} - -//------------------------------------------------------------------------------ - ProjectBuilder::ProjectPtr ProjectBuilder::createProject() { return m_projectAccessor.createProject(); @@ -167,14 +138,10 @@ ProjectBuilder::ProjectPtr ProjectBuilder::createProject() //------------------------------------------------------------------------------ -ProjectBuilder::JsonObjectPtr ProjectBuilder::createJson( const Path & _file ) +void ProjectBuilder::reset() { - auto filePtr = m_fs.openFile( _file ); - INTERNAL_CHECK_WARRING( filePtr ) - if( !filePtr ) - return nullptr; - - return m_jsonAccessor.createJson( filePtr->toInputStream() ); + m_ignoreSystemIncludesChanged = false; + m_analyzeWithoutExtensionChanged = false; } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_project_builder.hpp b/src/application/tools/app_project_builder.hpp index e285718..b509034 100644 --- a/src/application/tools/app_project_builder.hpp +++ b/src/application/tools/app_project_builder.hpp @@ -9,15 +9,6 @@ namespace project { class Project; } -//------------------------------------------------------------------------------ - -namespace json { - class JsonAccessor; - class JsonObject; -} - -//------------------------------------------------------------------------------ - namespace fs { class FileSystem; } @@ -38,20 +29,18 @@ class ProjectBuilder using Project = project::Project; using ProjectPtr = stdfwd::unique_ptr< Project >; - using JsonAccessor = json::JsonAccessor; - using JsonObject = json::JsonObject; - using JsonObjectPtr = stdfwd::unique_ptr< JsonObject >; - using Path = stdfs::path; using FileSystem = fs::FileSystem; ProjectBuilder( ProjectAccessor & _projectAccessor, - JsonAccessor & _jsonAccessor, FileSystem & _fs ); - ProjectPtr build( const ParserArgWrapper & _arguments ); + ProjectPtr build( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); private: @@ -67,12 +56,11 @@ class ProjectBuilder ProjectPtr createProject(); - JsonObjectPtr createJson( const Path & _file ); + void reset(); private: ProjectAccessor & m_projectAccessor; - JsonAccessor & m_jsonAccessor; FileSystem & m_fs; bool m_ignoreSystemIncludesChanged; bool m_analyzeWithoutExtensionChanged; diff --git a/src/application/tools/app_report_settings_loader.cpp b/src/application/tools/app_report_settings_loader.cpp new file mode 100644 index 0000000..5863335 --- /dev/null +++ b/src/application/tools/app_report_settings_loader.cpp @@ -0,0 +1,154 @@ +#include "application/tools/app_report_settings_loader.hpp" + +#include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" + +#include "reporter/api/rp_factory.hpp" +#include "reporter/api/rp_settings.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include +#include + +//------------------------------------------------------------------------------ + +namespace application { + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::ReportSettingsLoader( + reporter::Factory & _reporterFactory +) + : m_reporterFactory{ _reporterFactory } +{ + +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::SettingsPtr ReportSettingsLoader::load( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + auto settingsPtr = createSettings(); + INTERNAL_CHECK_WARRING( settingsPtr ); + if( !settingsPtr ) + return nullptr; + + reporter::Settings & settings = *settingsPtr; + + const auto maxFiles = loadMaxFilesCount( _arguments, _configurationFile ); + const auto maxDetails = loadMaxDetailsCount( _arguments, _configurationFile ); + const bool showStdFiles = loadShowStdFiles( _arguments, _configurationFile ); + + settings.setMaxFilesCount( maxFiles ); + settings.setMaxDetailsCount( maxDetails ); + settings.setShowStdFiles( showStdFiles ); + + return settingsPtr; +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::ReporterKinds ReportSettingsLoader::loadReports( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + if( auto reportsOpt = _arguments.getReporterKinds(); reportsOpt ) + return *reportsOpt; + + if( _configurationFile ) + { + if( auto kindOpt = _configurationFile->getReporterKinds(); kindOpt ) + return *kindOpt; + } + + return _arguments.getDefaultReporterKinds(); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::SettingsPtr ReportSettingsLoader::createSettings() +{ + return m_reporterFactory.createSettings(); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::CountType ReportSettingsLoader::loadMaxFilesCount( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + return getValue( + _arguments, + &ParserArgWrapper::getReportLimit, + &ParserArgWrapper::getDefaultReportLimit, + _configurationFile, + &ConfigurationFile::getReportLimit + ); +} + +//------------------------------------------------------------------------------ + +ReportSettingsLoader::CountType ReportSettingsLoader::loadMaxDetailsCount( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + return getValue( + _arguments, + &ParserArgWrapper::getReportDetailsLimit, + &ParserArgWrapper::getDefaultReportDetailsLimit, + _configurationFile, + &ConfigurationFile::getReportDetailsLimit + ); +} + +//------------------------------------------------------------------------------ + +bool ReportSettingsLoader::loadShowStdFiles( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + return getValue( + _arguments, + &ParserArgWrapper::getShowStdFile, + &ParserArgWrapper::getDefaultShowStdfile, + _configurationFile, + &ConfigurationFile::getShowStdFiles + ); +} + + +//------------------------------------------------------------------------------ + +template< typename _ValueType > +_ValueType ReportSettingsLoader::getValue( + const ParserArgWrapper & _arguments, + std::optional< _ValueType > (ParserArgWrapper::*_getValueFromArg)() const, + _ValueType (ParserArgWrapper::*_getDefaultValueFromArg)() const, + const ConfigurationFile * _configurationFile, + std::optional< _ValueType > (ConfigurationFile::*_getValueFromFile)() const +) +{ + if( auto valueFromArgOpt = ( _arguments.*_getValueFromArg )(); valueFromArgOpt ) + return *valueFromArgOpt; + + if( _configurationFile ) + { + auto valueFromFileOpt = ( *_configurationFile.*_getValueFromFile )(); + if( valueFromFileOpt ) + return *valueFromFileOpt; + } + + return ( _arguments.*_getDefaultValueFromArg )(); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/tools/app_report_settings_loader.hpp b/src/application/tools/app_report_settings_loader.hpp new file mode 100644 index 0000000..72ae227 --- /dev/null +++ b/src/application/tools/app_report_settings_loader.hpp @@ -0,0 +1,77 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + class Settings; + class Factory; + enum class ReporterKind; +} + +//------------------------------------------------------------------------------ + +namespace application { + class ParserArgWrapper; + class ConfigurationFile; + +//------------------------------------------------------------------------------ + +class ReportSettingsLoader +{ +public: + + using SettingsPtr = stdfwd::unique_ptr< reporter::Settings >; + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + + using CountType = std::size_t; + + ReportSettingsLoader( reporter::Factory & _reporterFactory ); + + SettingsPtr load( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + ReporterKinds loadReports( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + +private: + + SettingsPtr createSettings(); + + static CountType loadMaxFilesCount( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + static CountType loadMaxDetailsCount( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + static bool loadShowStdFiles( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + + template< typename _ValueType > + static _ValueType getValue( + const ParserArgWrapper & _arguments, + std::optional< _ValueType > (ParserArgWrapper::*_getValueFromArg)() const, + _ValueType (ParserArgWrapper::*_getDefaultValueFromArg)() const, + const ConfigurationFile * _configurationFile, + std::optional< _ValueType > (ConfigurationFile::*_getValueFromFile)() const + ); + +private: + + reporter::Factory & m_reporterFactory; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/CMakeLists.txt b/src/cmake_project/CMakeLists.txt new file mode 100644 index 0000000..54286eb --- /dev/null +++ b/src/cmake_project/CMakeLists.txt @@ -0,0 +1,15 @@ +project(cmake_project) + +include_directories(.) + +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + +add_library(${PROJECT_NAME}_lib STATIC ${all_sources}) + +TARGET_SPECIFIC(${PROJECT_NAME}_lib) + +if(CPPINCLUDE_BUILD_WITH_TESTS) + enable_testing() + add_subdirectory(test) +endif() diff --git a/src/cmake_project/api/cprj_loader.hpp b/src/cmake_project/api/cprj_loader.hpp new file mode 100644 index 0000000..ffc6fe4 --- /dev/null +++ b/src/cmake_project/api/cprj_loader.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class Database; +} + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class Project; + +//------------------------------------------------------------------------------ + +class Loader +{ +public: + + using ProjectPtr = stdfwd::unique_ptr< Project >; + + virtual ~Loader() = default; + + virtual ProjectPtr load( const compilation_db::Database & _db ) = 0; + virtual ProjectPtr createEmptyProject() = 0; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/api/cprj_project.hpp b/src/cmake_project/api/cprj_project.hpp new file mode 100644 index 0000000..91d50f7 --- /dev/null +++ b/src/cmake_project/api/cprj_project.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +class Project +{ +public: + + using CountType = std::size_t; + using Path = stdfs::path; + using PathCallback = std::function< bool ( const Path & ) >; + + virtual ~Project() = default; + + virtual CountType getFilePathsCount() const = 0; + virtual void forEachFilePath( PathCallback _callback ) const = 0; + + virtual void forEachIncludes( + const Path & _file, + PathCallback _callback + ) const = 0; + + virtual void addFilePath( const Path & _file ) = 0; + virtual void addIncludeToFile( const Path & _file, const Path & _include ) = 0; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/ih/cprj_accessor.hpp b/src/cmake_project/ih/cprj_accessor.hpp new file mode 100644 index 0000000..5c4ec1a --- /dev/null +++ b/src/cmake_project/ih/cprj_accessor.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class Loader; + +//------------------------------------------------------------------------------ + +class Accessor +{ +public: + + using LoaderPtr = stdfwd::unique_ptr< Loader >; + + virtual ~Accessor() = default; + + virtual LoaderPtr createLoader() = 0; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/ih/cprj_accessor_impl.cpp b/src/cmake_project/ih/cprj_accessor_impl.cpp new file mode 100644 index 0000000..8ba818b --- /dev/null +++ b/src/cmake_project/ih/cprj_accessor_impl.cpp @@ -0,0 +1,20 @@ +#include "cmake_project/ih/cprj_accessor_impl.hpp" + +#include "cmake_project/impl/cprj_loader_impl.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +AccessorImpl::LoaderPtr AccessorImpl::createLoader() +{ + return LoaderPtr{ new LoaderImpl }; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/ih/cprj_accessor_impl.hpp b/src/cmake_project/ih/cprj_accessor_impl.hpp new file mode 100644 index 0000000..5dc61bd --- /dev/null +++ b/src/cmake_project/ih/cprj_accessor_impl.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "cmake_project/ih/cprj_accessor.hpp" + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +class AccessorImpl final : public Accessor +{ +public: + + LoaderPtr createLoader() override; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_includes_parser.cpp b/src/cmake_project/impl/cprj_includes_parser.cpp new file mode 100644 index 0000000..831719e --- /dev/null +++ b/src/cmake_project/impl/cprj_includes_parser.cpp @@ -0,0 +1,203 @@ +#include "cmake_project/impl/cprj_includes_parser.hpp" + +#include "cmake_project/impl/cprj_includes_parser_context.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +IncludesParser::Includes IncludesParser::parse( std::string_view _command ) +{ + IncludeParserContext context{ _command }; + + const IndexType size = context.getCommandSize(); + const std::string & command = context.getCommand(); + for( IndexType i = 0; i < size; ++i ) + { + const char currentChar = command.at( i ); + switch( currentChar ) + { + case '\\' : + { + if( getIgnoreSpace( context, i ) ) + { + const IndexType nextPostWithSpace = i + getSizeSpecialChar(); + i = getFinishIgnoreSpace( context, nextPostWithSpace ); + } + } + break; + case ' ' : + { + i = getNotSpacePos( context, i ); + i = parseArgument( context, i ); + } + break; + } + + } + return context.getIncludes(); +} + +//------------------------------------------------------------------------------ + +IncludesParser::IndexType IncludesParser::parseArgument( + IncludeParserContext & _context, + IndexType startPos +) +{ + const IndexType minusPos = startPos; + const IndexType prefixPos = minusPos + 1; + const IndexType size = _context.getCommandSize(); + const std::string & command = _context.getCommand(); + if( minusPos < size && prefixPos < size ) + { + const char minusChar = command.at( minusPos ); + const char prefixChar = command.at( prefixPos ); + if( minusChar == '-' && prefixChar == 'I' ) + { + return parseInclude( _context, prefixPos + 1 ); + } + else + { + return prefixPos + 1; + } + } + + return size; +} + +//------------------------------------------------------------------------------ + +IncludesParser::IndexType IncludesParser::parseInclude( + IncludeParserContext & _context, + IndexType startPos +) +{ + const IndexType size = _context.getCommandSize(); + const std::string & command = _context.getCommand(); + + std::string includeStr; + IndexType finishPos; + bool stopLoop = false; + for( IndexType i = startPos; i < size && !stopLoop; ++i ) + { + const char currentChar = command.at( i ); + switch( currentChar ) + { + case '\\' : + { + if( getIgnoreSpace( _context, i ) ) + { + const IndexType nextPostWithSpace = i + getSizeSpecialChar(); + i = getFinishIgnoreSpace( _context, nextPostWithSpace ); + if( i < size ) + { + const IndexType sizeInclude = + i - nextPostWithSpace + 1 - getSizeSpecialChar(); + const std::string include = command.substr( nextPostWithSpace, sizeInclude ); + includeStr += include; + } + } + } + break; + case ' ' : + { + --i; + stopLoop = true; + } + break; + default: + includeStr += currentChar; + } + + finishPos = i; + } + + if( !includeStr.empty() ) + _context.addInclude( includeStr ); + + return finishPos; +} + +//------------------------------------------------------------------------------ + +bool IncludesParser::getIgnoreSpace( + IncludeParserContext & _context, + IndexType currentPos +) +{ + const std::string & command = _context.getCommand(); + const IndexType size = _context.getCommandSize(); + const IndexType nextPos = currentPos + 1; + if( nextPos >= size ) + return false; + + const char nextChar = command.at( nextPos ); + const bool result = nextChar == '"'; + + return result; +} + +//------------------------------------------------------------------------------ + +IncludesParser::IndexType IncludesParser::getFinishIgnoreSpace( + IncludeParserContext & _context, + IndexType startPos +) +{ + const std::string & command = _context.getCommand(); + const IndexType size = _context.getCommandSize(); + + for( IndexType i = startPos; i < size; ++i ) + { + const char currentChar = command.at( i ); + if( currentChar == '\\' ) + { + const IndexType nextPos = i + 1; + if( nextPos < size ) + { + const char nextChar = command.at( nextPos ); + if( nextChar == '"' ) + return nextPos; + } + } + } + + return size; +} + +//------------------------------------------------------------------------------ + +IncludesParser::IndexType IncludesParser::getSizeSpecialChar() +{ + return 2; +} + +//------------------------------------------------------------------------------ + +IncludesParser::IndexType IncludesParser::getNotSpacePos( + IncludeParserContext & _context, + IndexType startPos +) +{ + const std::string & command = _context.getCommand(); + const IndexType size = _context.getCommandSize(); + for( IndexType i = startPos; i < size; ++i ) + { + const char currentChar = command.at( i ); + if( currentChar != ' ' ) + return i; + } + + return size; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_includes_parser.hpp b/src/cmake_project/impl/cprj_includes_parser.hpp new file mode 100644 index 0000000..f80403d --- /dev/null +++ b/src/cmake_project/impl/cprj_includes_parser.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class IncludeParserContext; + +//------------------------------------------------------------------------------ + +class IncludesParser +{ + +public: + + using Path = stdfs::path; + using Includes = stdfwd::vector< Path >; + using IndexType = std::size_t; + + Includes parse( std::string_view _command ); + +private: + + static IndexType parseArgument( + IncludeParserContext & _context, + IndexType startPos + ); + + static IndexType parseInclude( + IncludeParserContext & _context, + IndexType startPos + ); + + static bool getIgnoreSpace( + IncludeParserContext & _context, + IndexType currentPos + ); + + static IndexType getFinishIgnoreSpace( + IncludeParserContext & _context, + IndexType startPos + ); + + static IndexType getSizeSpecialChar(); + + static IndexType getNotSpacePos( + IncludeParserContext & _context, + IndexType startPos + ); + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_includes_parser_context.cpp b/src/cmake_project/impl/cprj_includes_parser_context.cpp new file mode 100644 index 0000000..8b31865 --- /dev/null +++ b/src/cmake_project/impl/cprj_includes_parser_context.cpp @@ -0,0 +1,48 @@ +#include "cmake_project/impl/cprj_includes_parser_context.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +IncludeParserContext::IncludeParserContext( std::string_view _command ) + : m_size{ _command.size() } + , m_command{ _command } +{ + +} + +//------------------------------------------------------------------------------ + +const std::string & IncludeParserContext::getCommand() const +{ + return m_command; +} + +//------------------------------------------------------------------------------ + +IncludeParserContext::IndexType IncludeParserContext::getCommandSize() const +{ + return m_size; +} + +//------------------------------------------------------------------------------ + +const IncludeParserContext::Includes & IncludeParserContext::getIncludes() const +{ + return m_includes; +} + +//------------------------------------------------------------------------------ + +void IncludeParserContext::addInclude( const Path & _path ) +{ + m_includes.push_back( _path ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_includes_parser_context.hpp b/src/cmake_project/impl/cprj_includes_parser_context.hpp new file mode 100644 index 0000000..b83cb65 --- /dev/null +++ b/src/cmake_project/impl/cprj_includes_parser_context.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +class IncludeParserContext +{ +public: + + using Path = stdfs::path; + using Includes = stdfwd::vector< Path >; + using IndexType = std::size_t; + + IncludeParserContext( std::string_view _command ); + + const std::string & getCommand() const; + IndexType getCommandSize() const; + + const Includes & getIncludes() const; + + void addInclude( const Path & _path ); + +private: + + IndexType m_size; + std::string m_command; + + Includes m_includes; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_loader_impl.cpp b/src/cmake_project/impl/cprj_loader_impl.cpp new file mode 100644 index 0000000..6372980 --- /dev/null +++ b/src/cmake_project/impl/cprj_loader_impl.cpp @@ -0,0 +1,97 @@ +#include "cmake_project/impl/cprj_loader_impl.hpp" + +#include "cmake_project/impl/cprj_project_impl.hpp" +#include "cmake_project/impl/cprj_includes_parser.hpp" + +#include "compilation_db/api/cdb_database.hpp" +#include "compilation_db/api/cdb_command_object.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +LoaderImpl::LoaderImpl() = default; +LoaderImpl::~LoaderImpl() = default; + +//------------------------------------------------------------------------------ + +LoaderImpl::ProjectPtr LoaderImpl::load( const compilation_db::Database & _db ) +{ + ProjectPtr result{ createEmptyProject() }; + + const compilation_db::Database::IndexType count = _db.getCount(); + for( compilation_db::Database::IndexType i = 0; i < count; ++i ) + { + const compilation_db::CommandObject & command = _db.getObject( i ); + + const Path file = loadFile( command, *result ); + loadCommand( command, file, *result ); + } + + return result; +} + +//------------------------------------------------------------------------------ + +LoaderImpl::ProjectPtr LoaderImpl::createEmptyProject() +{ + return ProjectPtr{ new ProjectImpl }; +} + +//------------------------------------------------------------------------------ + +LoaderImpl::Path LoaderImpl::loadFile( + const compilation_db::CommandObject & _commnad, + Project & _project +) +{ + const std::string & fileStr = _commnad.getFile(); + Path filePath{ fileStr }; + if( filePath.is_relative() ) + { + const std::string & dirStr = _commnad.getDirectory(); + stdfs::path dirPath{ dirStr }; + filePath = dirPath / filePath; + } + filePath = stdfs::lexically_normal( filePath ); + + _project.addFilePath( filePath ); + return filePath; +} + +//------------------------------------------------------------------------------ + +IncludesParser & LoaderImpl::ensureIncludesParser() +{ + if( !m_includeParser ) + m_includeParser.reset( new IncludesParser ); + + return *m_includeParser; +} + +//------------------------------------------------------------------------------ + +void LoaderImpl::loadCommand( + const compilation_db::CommandObject & _commnad, + const Path & _currentFile, + Project & _project +) +{ + IncludesParser & parser = ensureIncludesParser(); + const std::string & cmd = _commnad.getCommand(); + auto includes = parser.parse( cmd ); + for( const Path & include : includes ) + { + _project.addIncludeToFile( _currentFile, include ); + } +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_loader_impl.hpp b/src/cmake_project/impl/cprj_loader_impl.hpp new file mode 100644 index 0000000..9098973 --- /dev/null +++ b/src/cmake_project/impl/cprj_loader_impl.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include "cmake_project/api/cprj_loader.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class CommandObject; +} + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class IncludesParser; + +//------------------------------------------------------------------------------ + +class LoaderImpl final : public Loader +{ +public: + + using Path = stdfs::path; + + LoaderImpl(); + ~LoaderImpl(); + + ProjectPtr load( const compilation_db::Database & _db ) override; + + ProjectPtr createEmptyProject() override; + +private: + + Path loadFile( + const compilation_db::CommandObject & _commnad, + Project & _project + ); + + void loadCommand( + const compilation_db::CommandObject & _commnad, + const Path & _currentFile, + Project & _project + ); + + IncludesParser & ensureIncludesParser(); + +private: + + std::unique_ptr< IncludesParser > m_includeParser; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_project_impl.cpp b/src/cmake_project/impl/cprj_project_impl.cpp new file mode 100644 index 0000000..0799e8e --- /dev/null +++ b/src/cmake_project/impl/cprj_project_impl.cpp @@ -0,0 +1,84 @@ +#include "cmake_project/impl/cprj_project_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +ProjectImpl::CountType ProjectImpl::getFilePathsCount() const +{ + return m_files.size(); +} + +//------------------------------------------------------------------------------ + +void ProjectImpl::forEachFilePath( PathCallback _callback ) const +{ + for( const Path & path : m_files ) + { + if( !_callback( path )) + break; + } +} + +//------------------------------------------------------------------------------ + +void ProjectImpl::forEachIncludes( + const Path & _file, + PathCallback _callback +) const +{ + if( !m_includesByFiles.count( _file ) ) + return; + + const IncludesForFile & includes = m_includesByFiles.at( _file ); + for( const Path * include : includes ) + { + if( !include ) + { + INTERNAL_CHECK_WARRING(false); + continue; + } + + if( !_callback( *include ) ) + break; + } +} + +//------------------------------------------------------------------------------ + +void ProjectImpl::addFilePath( const Path & _path ) +{ + Path path = stdfs::lexically_normal( _path ); + m_files.insert( path ); +} + +//------------------------------------------------------------------------------ + +void ProjectImpl::addIncludeToFile( const Path & _file, const Path & _include ) +{ + Path file = stdfs::lexically_normal( _file ); + IncludesForFile & includes = m_includesByFiles[ file ]; + + const Path & include = addInclude( _include ); + includes.push_back( &include ); +} + +//------------------------------------------------------------------------------ + +const ProjectImpl::Path & ProjectImpl::addInclude( const Path & _include ) +{ + auto pair = m_includes.insert( _include ); + return *pair.first; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/impl/cprj_project_impl.hpp b/src/cmake_project/impl/cprj_project_impl.hpp new file mode 100644 index 0000000..14a0e53 --- /dev/null +++ b/src/cmake_project/impl/cprj_project_impl.hpp @@ -0,0 +1,50 @@ +#pragma once + +#include "cmake_project/api/cprj_project.hpp" + +#include "tools/std_hash_fs_path.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + +//------------------------------------------------------------------------------ + +class ProjectImpl final : public Project +{ +public: + + CountType getFilePathsCount() const override; + void forEachFilePath( PathCallback _callback ) const override; + void forEachIncludes( + const Path & _file, + PathCallback _callback + ) const override; + + void addFilePath( const Path & _path ) override; + void addIncludeToFile( const Path & _file, const Path & _include ) override; + +private: + + const Path & addInclude( const Path & _include ); + +private: + + using Files = std::unordered_set< Path >; + using Includes = std::unordered_set< Path >; + using IncludesForFile = std::vector< const Path * >; + using IncludesByFiles = std::unordered_map< Path, IncludesForFile >; + + Files m_files; + Includes m_includes; + IncludesByFiles m_includesByFiles; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/test/CMakeLists.txt b/src/cmake_project/test/CMakeLists.txt new file mode 100644 index 0000000..11aea16 --- /dev/null +++ b/src/cmake_project/test/CMakeLists.txt @@ -0,0 +1,15 @@ +file(GLOB_RECURSE all_sources "*.cpp" ) +add_executable(${PROJECT_NAME}_test ${all_sources}) + +include(TestConfig) + +target_link_libraries( + ${PROJECT_NAME}_test + ${Boost_LIBRARIES} + ${PROJECT_NAME}_lib + compilation_db_lib + tools_lib +) + +add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) + diff --git a/src/cmake_project/test/cprj_test_main.cpp b/src/cmake_project/test/cprj_test_main.cpp new file mode 100644 index 0000000..7016363 --- /dev/null +++ b/src/cmake_project/test/cprj_test_main.cpp @@ -0,0 +1,10 @@ +#include "test_tools/boost_macroses.hpp" + +#define BOOST_TEST_MODULE cmake_project_test +#include + +int main(int argc, char* argv[]) +{ + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); +} + diff --git a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp new file mode 100644 index 0000000..c25d504 --- /dev/null +++ b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp @@ -0,0 +1,80 @@ +#include "cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp" + +#include "cmake_project/impl/cprj_includes_parser.hpp" + +#include "tools/path_string_tools.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +IncldesParserFixture::IncldesParserFixture() = default; +IncldesParserFixture::~IncldesParserFixture() = default; + +//------------------------------------------------------------------------------ + +IncldesParserFixture::Strings IncldesParserFixture::parseString( + std::string_view _str +) +{ + Paths includes = ensureParser().parse( _str ); + return toStrings( includes ); +} + +//------------------------------------------------------------------------------ + +IncldesParserFixture::Strings IncldesParserFixture::toPathStrings( + const Strings & _strings +) +{ + Strings result; + for( const std::string & str : _strings ) + { + std::string newStr = tools::toPath( str ); + result.push_back( newStr ); + } + + return result; +} + +//------------------------------------------------------------------------------ + +IncludesParser & IncldesParserFixture::ensureParser() +{ + if( !m_parserPtr ) + m_parserPtr.reset( new IncludesParser ); + + return *m_parserPtr; +} + +//------------------------------------------------------------------------------ + +IncldesParserFixture::Strings IncldesParserFixture::toStrings( + const Paths & _paths +) +{ + Strings result; + for( const Path & path : _paths ) + { + const std::string str = toString( path ); + result.push_back( str ); + } + return result; +} + +//------------------------------------------------------------------------------ + +std::string IncldesParserFixture::toString( const Path & _path ) +{ + return tools::toPath( _path.string() ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp new file mode 100644 index 0000000..9230571 --- /dev/null +++ b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class IncludesParser; +} + +//------------------------------------------------------------------------------ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +class IncldesParserFixture +{ +public: + + using Path = stdfs::path; + using Paths = stdfwd::vector< Path >; + + using Strings = stdfwd::vector< std::string >; + + IncldesParserFixture(); + ~IncldesParserFixture(); + + Strings parseString( std::string_view _str ); + + static Strings toPathStrings( const Strings & _strings ); + static Strings toStrings( const Paths & _paths ); + static std::string toString( const Path & _path ); + +private: + + IncludesParser & ensureParser(); + +private: + + std::unique_ptr< IncludesParser > m_parserPtr; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp new file mode 100644 index 0000000..32bf0cc --- /dev/null +++ b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp @@ -0,0 +1,192 @@ +#include "cmake_project/test/fixtures/cprj_test_loader_fixture.hpp" + +#include "cmake_project/api/cprj_loader.hpp" +#include "cmake_project/api/cprj_project.hpp" +#include "cmake_project/ih/cprj_accessor_impl.hpp" + +#include "compilation_db/api/cdb_database.hpp" +#include "compilation_db/api/cdb_loader.hpp" +#include "compilation_db/ih/cdb_accessor_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "tools/path_string_tools.hpp" + +#include + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +LoaderFixture::LoaderFixture() = default; +LoaderFixture::~LoaderFixture() = default; + +//------------------------------------------------------------------------------ + +void LoaderFixture::addCommand( + std::string_view _directory, + std::string_view _command, + std::string_view _file +) +{ + compilation_db::Database & db = ensureCompilationDb(); + db.addCommand( _directory, _command, _file ); +} + +//------------------------------------------------------------------------------ + +void LoaderFixture::addDefaultComandForFile( std::string_view _file ) +{ + addCommand( getDefaultFolder(), "/usr/bin/c++", _file ); +} + +//------------------------------------------------------------------------------ + +void LoaderFixture::addComandWithIncludes( + std::string_view _file, + const Strings & _includes +) +{ + std::string includesArg; + for( const auto & include : _includes ) + includesArg += " -I" + include; + + addCommand( getDefaultFolder(), "/usr/bin/c++" + includesArg, _file ); +} + +//------------------------------------------------------------------------------ + +void LoaderFixture::load() +{ + m_projectPtr = ensureLoader().load( ensureCompilationDb() ); +} + +//------------------------------------------------------------------------------ + +LoaderFixture::Strings LoaderFixture::getResultsFiles() const +{ + INTERNAL_CHECK_ERROR( m_projectPtr ); + const Project & project = *m_projectPtr; + Strings files; + project.forEachFilePath( [&]( const Path & _path ) + { + files.insert( tools::toPath( _path.string() ) ); + return true; + }); + return files; +} + +//------------------------------------------------------------------------------ + +LoaderFixture::Strings LoaderFixture::getResultsIncludes( + std::string_view _file +) const +{ + INTERNAL_CHECK_ERROR( m_projectPtr ); + const Project & project = *m_projectPtr; + Strings files; + const Path projectDir{ getDefaultFolder() }; + const Path filePath = projectDir / _file; + + project.forEachIncludes( filePath, [&]( const Path & _path ) + { + files.insert( tools::toPath( _path.string() ) ); + return true; + }); + return files; +} + +//------------------------------------------------------------------------------ + +LoaderFixture::Strings LoaderFixture::toExceptedFiles( const Strings & _files ) const +{ + Strings result; + Path projectDir{ getDefaultFolder() }; + for( const std::string & file : _files ) + { + Path filePath = projectDir / file; + result.insert( tools::toPath( filePath.string() ) ); + } + return result; +} + +//------------------------------------------------------------------------------ + +LoaderFixture::Strings LoaderFixture::toExceptedIncludes( + const Strings & _dirs +) const +{ + Strings result; + for( const std::string & dir : _dirs ) + { + result.insert( tools::toPath( dir ) ); + } + return result; +} + +//------------------------------------------------------------------------------ + +std::string LoaderFixture::getDefaultFolder() const +{ + return "/project"; +} + +//------------------------------------------------------------------------------ + +Loader & LoaderFixture::ensureLoader() +{ + if( !m_loaderPtr ) + m_loaderPtr = ensureCmakeProjectAccessor().createLoader(); + + return *m_loaderPtr; +} + +//------------------------------------------------------------------------------ + +Accessor & LoaderFixture::ensureCmakeProjectAccessor() +{ + if( !m_cmakeProjectAccessorPtr ) + m_cmakeProjectAccessorPtr.reset( new AccessorImpl ); + + return *m_cmakeProjectAccessorPtr; +} + +//------------------------------------------------------------------------------ + +compilation_db::Database & LoaderFixture::ensureCompilationDb() +{ + if( !m_dbPtr ) + m_dbPtr = ensureCompilationDbLoader().createEmptyDb(); + + return *m_dbPtr; +} + +//------------------------------------------------------------------------------ + +compilation_db::Loader & LoaderFixture::ensureCompilationDbLoader() +{ + if( !m_dbLoaderPtr ) + m_dbLoaderPtr = ensureCompilationDbAccessor().createLoader(); + + return *m_dbLoaderPtr; +} + +//------------------------------------------------------------------------------ + +compilation_db::Accessor & LoaderFixture::ensureCompilationDbAccessor() +{ + if( !m_dbAccessorPtr ) + m_dbAccessorPtr.reset( new compilation_db::AccessorImpl ); + + return *m_dbAccessorPtr; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp new file mode 100644 index 0000000..cf01eb4 --- /dev/null +++ b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp @@ -0,0 +1,87 @@ +#pragma once + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class Database; + class Loader; + class Accessor; +} + +//------------------------------------------------------------------------------ + +namespace cmake_project { + class Project; + class Loader; + class Accessor; +} + +//------------------------------------------------------------------------------ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +class LoaderFixture +{ +public: + + LoaderFixture(); + ~LoaderFixture(); + + using Strings = stdfwd::set< std::string >; + + void addCommand( + std::string_view _directory, + std::string_view _command, + std::string_view _file + ); + + void addDefaultComandForFile( std::string_view _file ); + void addComandWithIncludes( + std::string_view _file, + const Strings & _includes + ); + + void load(); + + Strings getResultsFiles() const; + Strings getResultsIncludes( std::string_view _file ) const; + + Strings toExceptedFiles( const Strings & _files ) const; + Strings toExceptedIncludes( const Strings & _dirs ) const; + +private: + + using Path = stdfs::path; + + std::string getDefaultFolder() const; + + Loader & ensureLoader(); + Accessor & ensureCmakeProjectAccessor(); + + compilation_db::Database & ensureCompilationDb(); + compilation_db::Loader & ensureCompilationDbLoader(); + compilation_db::Accessor & ensureCompilationDbAccessor(); + +private: + + std::unique_ptr< Project > m_projectPtr; + std::unique_ptr< Loader > m_loaderPtr; + std::unique_ptr< Accessor > m_cmakeProjectAccessorPtr; + + std::unique_ptr< compilation_db::Database > m_dbPtr; + std::unique_ptr< compilation_db::Loader > m_dbLoaderPtr; + std::unique_ptr< compilation_db::Accessor > m_dbAccessorPtr; +}; + +//------------------------------------------------------------------------------ + +} + +//------------------------------------------------------------------------------ + diff --git a/src/cmake_project/test/suits/cprj_test_includes_parser.cpp b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp new file mode 100644 index 0000000..683ccac --- /dev/null +++ b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp @@ -0,0 +1,172 @@ +#include "cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp" + +#include + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN +1. Without include parameter +2. Parameter in name +3. One parameter +4. Several parameters +5. Parameter in end of string +6. File name with space +7. Include with space +8. Double spaces + +------------------------------------------------------------------------------*/ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(IncldesParserTests, IncldesParserFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_without_include_paramter) +{ + //Run + auto actualResult = parseString( "/usr/bin/c++ -o file2.cpp.o -c file2.cpp" ); + Strings exceptedResult{}; + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_paramter_in_name) +{ + //Run + auto actualResult = parseString( "/bin/c++ -o f-I.cpp.o -c f-I.cpp" ); + Strings exceptedResult{}; + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_one_paramter) +{ + //Run + auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./include -c f.cpp" ); + Strings exceptedResult = toPathStrings( {"./include"} ); + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_several_parameters) +{ + //Run + auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./lib1 -I./lib2 -c f.cpp" ); + Strings exceptedResult = toPathStrings( { "./lib1", "./lib2" } ); + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_paramter_in_end_of_string) +{ + //Run + auto actualResult = parseString( "/bin/c++ -o f.cpp.o -c f.cpp -I./include" ); + Strings exceptedResult = toPathStrings( {"./include"} ); + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t6_file_with_space) +{ + //Run + auto actualResult = parseString( "/bin/c++ -o f.cpp.o -c \\\"space in file\\\".cpp" ); + Strings exceptedResult; + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t7_include_with_space) +{ + //Run + auto actualResult = + parseString( "/bin/c++ -o f.cpp.o -I\\\"./include with space\\\" -c f.cpp" ); + Strings exceptedResult = toPathStrings( {"./include with space"} ); + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t8_double_spaces) +{ + //Run + auto actualResult = parseString( "/bin/c++ -I./include -o f.cpp.o -c f.cpp" ); + Strings exceptedResult = toPathStrings( {"./include"} ); + + //Check + BOOST_CHECK_EQUAL_COLLECTIONS( + actualResult.begin(), + actualResult.end(), + exceptedResult.begin(), + exceptedResult.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/cmake_project/test/suits/cprj_test_loader.cpp b/src/cmake_project/test/suits/cprj_test_loader.cpp new file mode 100644 index 0000000..f32f0a2 --- /dev/null +++ b/src/cmake_project/test/suits/cprj_test_loader.cpp @@ -0,0 +1,148 @@ +#include "cmake_project/test/fixtures/cprj_test_loader_fixture.hpp" + +#include + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN +1. One file +2. Several files +3. Includes + +------------------------------------------------------------------------------*/ + +namespace cmake_project::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(CMakeProjectLoaderTests, LoaderFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_one_file) +{ + //Init + addDefaultComandForFile( "file.cpp" ); + + //Run + load(); + + //Check + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { "file.cpp" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_several_files) +{ + //Init + addDefaultComandForFile( "file1.cpp" ); + addDefaultComandForFile( "file2.cpp" ); + + //Run + load(); + + //Check + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { "file1.cpp", "file2.cpp" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_includes) +{ + //Init + addComandWithIncludes( "file1.cpp", { "./lib1" } ); + addComandWithIncludes( "file2.cpp", { "./lib2", "./lib3" } ); + addComandWithIncludes( "file3.cpp", {} ); + addComandWithIncludes( "file4.cpp", { "./lib4" } ); + + //Run + load(); + + //Check + const auto resultFiles = getResultsFiles(); + const auto exceptedFiles = toExceptedFiles( { + "file1.cpp", + "file2.cpp", + "file3.cpp", + "file4.cpp" + } ); + + BOOST_REQUIRE_EQUAL_COLLECTIONS( + resultFiles.begin(), + resultFiles.end(), + exceptedFiles.begin(), + exceptedFiles.end() + ); + + { + const auto resultIncludes = getResultsIncludes( "file1.cpp" ); + const auto exceptedIncludes = toExceptedIncludes( { "./lib1" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludes.begin(), + resultIncludes.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } + { + const auto resultIncludes = getResultsIncludes( "file2.cpp" ); + const auto exceptedIncludes = toExceptedIncludes( { "./lib2", "./lib3" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludes.begin(), + resultIncludes.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } + { + const auto resultIncludes = getResultsIncludes( "file3.cpp" ); + const auto exceptedIncludes = toExceptedIncludes( {} ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludes.begin(), + resultIncludes.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } + { + const auto resultIncludes = getResultsIncludes( "file4.cpp" ); + const auto exceptedIncludes = toExceptedIncludes( { "./lib4" } ); + + BOOST_CHECK_EQUAL_COLLECTIONS( + resultIncludes.begin(), + resultIncludes.end(), + exceptedIncludes.begin(), + exceptedIncludes.end() + ); + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/CMakeLists.txt b/src/compilation_db/CMakeLists.txt new file mode 100644 index 0000000..11b2de1 --- /dev/null +++ b/src/compilation_db/CMakeLists.txt @@ -0,0 +1,15 @@ +project(compilation_db) + +include_directories(.) + +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + +add_library(${PROJECT_NAME}_lib STATIC ${all_sources}) + +TARGET_SPECIFIC(${PROJECT_NAME}_lib) + +if(CPPINCLUDE_BUILD_WITH_TESTS) + enable_testing() + add_subdirectory(test) +endif() diff --git a/src/compilation_db/api/cdb_command_object.hpp b/src/compilation_db/api/cdb_command_object.hpp new file mode 100644 index 0000000..7a4d91b --- /dev/null +++ b/src/compilation_db/api/cdb_command_object.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +class CommandObject +{ +public: + + virtual const std::string & getDirectory() const = 0; + virtual const std::string & getCommand() const = 0; + virtual const std::string & getFile() const = 0; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/api/cdb_database.hpp b/src/compilation_db/api/cdb_database.hpp new file mode 100644 index 0000000..162a7ec --- /dev/null +++ b/src/compilation_db/api/cdb_database.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class CommandObject; + +//------------------------------------------------------------------------------ + +class Database +{ +public: + + using IndexType = std::size_t; + + virtual ~Database() = default; + + virtual IndexType getCount() const = 0; + virtual const CommandObject & getObject( IndexType _index ) const = 0; + + virtual void addCommand( + std::string_view _directory, + std::string_view _command, + std::string_view _file + ) = 0; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/api/cdb_loader.hpp b/src/compilation_db/api/cdb_loader.hpp new file mode 100644 index 0000000..3ff546f --- /dev/null +++ b/src/compilation_db/api/cdb_loader.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace json { + class JsonObject; +} + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class Database; + +//------------------------------------------------------------------------------ + +class Loader +{ +public: + + virtual ~Loader() = default; + + using DatabasePtr = stdfwd::unique_ptr< Database >; + + virtual DatabasePtr load( const json::JsonObject & _json ) = 0; + virtual DatabasePtr createEmptyDb() = 0; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/ih/cdb_accessor.hpp b/src/compilation_db/ih/cdb_accessor.hpp new file mode 100644 index 0000000..9969789 --- /dev/null +++ b/src/compilation_db/ih/cdb_accessor.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + class Loader; + +//------------------------------------------------------------------------------ + +class Accessor +{ +public: + + using LoaderPtr = stdfwd::unique_ptr< Loader >; + + virtual ~Accessor() = default; + + virtual LoaderPtr createLoader() = 0; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/ih/cdb_accessor_impl.cpp b/src/compilation_db/ih/cdb_accessor_impl.cpp new file mode 100644 index 0000000..11400e2 --- /dev/null +++ b/src/compilation_db/ih/cdb_accessor_impl.cpp @@ -0,0 +1,20 @@ +#include "compilation_db/ih/cdb_accessor_impl.hpp" + +#include "compilation_db/impl/cdb_loader_impl.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +AccessorImpl::LoaderPtr AccessorImpl::createLoader() +{ + return LoaderPtr{ new LoaderImpl }; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/ih/cdb_accessor_impl.hpp b/src/compilation_db/ih/cdb_accessor_impl.hpp new file mode 100644 index 0000000..a0b9340 --- /dev/null +++ b/src/compilation_db/ih/cdb_accessor_impl.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "compilation_db/ih/cdb_accessor.hpp" + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +class AccessorImpl final : public Accessor +{ +public: + + LoaderPtr createLoader() override; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_command_object_impl.cpp b/src/compilation_db/impl/cdb_command_object_impl.cpp new file mode 100644 index 0000000..b6cf210 --- /dev/null +++ b/src/compilation_db/impl/cdb_command_object_impl.cpp @@ -0,0 +1,44 @@ +#include "compilation_db/impl/cdb_command_object_impl.hpp" + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +CommandObjectImpl::CommandObjectImpl( + std::string_view _directory, + std::string_view _command, + std::string_view _file +) + : m_directory{ _directory } + , m_command{ _command } + , m_file{ _file } +{ + +} + +//------------------------------------------------------------------------------ + +const std::string & CommandObjectImpl::getDirectory() const +{ + return m_directory; +} + +//------------------------------------------------------------------------------ + +const std::string & CommandObjectImpl::getCommand() const +{ + return m_command; +} + +//------------------------------------------------------------------------------ + +const std::string & CommandObjectImpl::getFile() const +{ + return m_file; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_command_object_impl.hpp b/src/compilation_db/impl/cdb_command_object_impl.hpp new file mode 100644 index 0000000..37b96a4 --- /dev/null +++ b/src/compilation_db/impl/cdb_command_object_impl.hpp @@ -0,0 +1,36 @@ +#pragma once + +#include "compilation_db/api/cdb_command_object.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +class CommandObjectImpl final : public CommandObject +{ +public: + + CommandObjectImpl( + std::string_view _directory, + std::string_view _command, + std::string_view _file + ); + + const std::string & getDirectory() const override; + const std::string & getCommand() const override; + const std::string & getFile() const override; + +private: + + const std::string m_directory; + const std::string m_command; + const std::string m_file; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_database_impl.cpp b/src/compilation_db/impl/cdb_database_impl.cpp new file mode 100644 index 0000000..f6c11d7 --- /dev/null +++ b/src/compilation_db/impl/cdb_database_impl.cpp @@ -0,0 +1,49 @@ +#include "compilation_db/impl/cdb_database_impl.hpp" + +#include "compilation_db/impl/cdb_command_object_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +DatabaseImpl::DatabaseImpl() = default; +DatabaseImpl::~DatabaseImpl() = default; + +//------------------------------------------------------------------------------ + +DatabaseImpl::IndexType DatabaseImpl::getCount() const +{ + return m_objects.size(); +} + +//------------------------------------------------------------------------------ + +const CommandObject & DatabaseImpl::getObject( IndexType _index ) const +{ + const CommandObjectPtr & objectPtr = m_objects.at( _index ); + INTERNAL_CHECK_ERROR( objectPtr ); + return *objectPtr; +} + +//------------------------------------------------------------------------------ + +void DatabaseImpl::addCommand( + std::string_view _directory, + std::string_view _command, + std::string_view _file +) +{ + m_objects.emplace_back( + new CommandObjectImpl{ _directory, _command, _file } + ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_database_impl.hpp b/src/compilation_db/impl/cdb_database_impl.hpp new file mode 100644 index 0000000..e85617b --- /dev/null +++ b/src/compilation_db/impl/cdb_database_impl.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include "compilation_db/api/cdb_database.hpp" + +#include +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +class DatabaseImpl final : public Database +{ + +public: + + DatabaseImpl(); + ~DatabaseImpl() override; + + IndexType getCount() const override; + const CommandObject & getObject( IndexType _index ) const override; + + void addCommand( + std::string_view _directory, + std::string_view _command, + std::string_view _file + ) override; + +private: + + using CommandObjectPtr = std::unique_ptr< CommandObject >; + + std::vector< CommandObjectPtr > m_objects; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_loader_impl.cpp b/src/compilation_db/impl/cdb_loader_impl.cpp new file mode 100644 index 0000000..2bafd44 --- /dev/null +++ b/src/compilation_db/impl/cdb_loader_impl.cpp @@ -0,0 +1,99 @@ +#include "compilation_db/impl/cdb_loader_impl.hpp" + +#include "compilation_db/impl/cdb_database_impl.hpp" +#include "compilation_db/resources/cdb_resources.hpp" + +#include "json/api/json_object.hpp" +#include "json/api/json_value.hpp" +#include "json/api/json_array.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +LoaderImpl::DatabasePtr LoaderImpl::load( const json::JsonObject & _json ) +{ + DatabasePtr result{ createEmptyDb() }; + + auto valueObjectPtr = _json.asValue(); + if( !valueObjectPtr ) + { + INTERNAL_CHECK_WARRING( false ); + return result; + } + + auto arrayPtr = valueObjectPtr->asArray(); + if( !arrayPtr ) + { + INTERNAL_CHECK_WARRING( false ); + return result; + } + + const json::JsonArray & array = *arrayPtr; + const json::JsonArray::ArrayIndex size = array.getSize(); + for( json::JsonArray::ArrayIndex i = 0; i < size; ++i ) + { + auto itemPtr = array.at( i ); + INTERNAL_CHECK_WARRING( itemPtr ); + loadItem( *itemPtr, *result ); + } + + return result; +} + +//------------------------------------------------------------------------------ + +LoaderImpl::DatabasePtr LoaderImpl::createEmptyDb() +{ + return DatabasePtr { new DatabaseImpl }; +} + +//------------------------------------------------------------------------------ + +void LoaderImpl::loadItem( const json::JsonValue & _value, Database & _db ) +{ + auto objectPtr = _value.asObject(); + if( !objectPtr ) + { + INTERNAL_CHECK_WARRING( false ); + return; + } + + auto directoryPtr = objectPtr->getAttributeValue( resources::Directory ); + if( !directoryPtr ) + { + INTERNAL_CHECK_WARRING( false ); + return; + } + + auto commandPtr = objectPtr->getAttributeValue( resources::Command ); + if( !commandPtr ) + { + INTERNAL_CHECK_WARRING( false ); + return; + } + + auto filePtr = objectPtr->getAttributeValue( resources::File ); + if( !filePtr ) + { + INTERNAL_CHECK_WARRING( false ); + return; + } + + const std::string directory = directoryPtr->asString(); + const std::string command = commandPtr->asString(); + const std::string file = filePtr->asString(); + + _db.addCommand( directory, command, file ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/impl/cdb_loader_impl.hpp b/src/compilation_db/impl/cdb_loader_impl.hpp new file mode 100644 index 0000000..853c0f5 --- /dev/null +++ b/src/compilation_db/impl/cdb_loader_impl.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "compilation_db/api/cdb_loader.hpp" + +//------------------------------------------------------------------------------ + +namespace json { + class JsonValue; +} + +//------------------------------------------------------------------------------ + +namespace compilation_db { + +//------------------------------------------------------------------------------ + +class LoaderImpl final : public Loader +{ +public: + + DatabasePtr load( const json::JsonObject & _json ) override; + DatabasePtr createEmptyDb() override; + +private: + + void loadItem( const json::JsonValue & _value, Database & _db ); +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/resources/cdb_resources.cpp b/src/compilation_db/resources/cdb_resources.cpp new file mode 100644 index 0000000..b5c3050 --- /dev/null +++ b/src/compilation_db/resources/cdb_resources.cpp @@ -0,0 +1,15 @@ +#include "compilation_db/resources/cdb_resources.hpp" + +//------------------------------------------------------------------------------ + +namespace compilation_db::resources { + +//------------------------------------------------------------------------------ + + const char * const Directory = "directory"; + const char * const Command = "command"; + const char * const File = "file"; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/resources/cdb_resources.hpp b/src/compilation_db/resources/cdb_resources.hpp new file mode 100644 index 0000000..f5b9cf9 --- /dev/null +++ b/src/compilation_db/resources/cdb_resources.hpp @@ -0,0 +1,15 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace compilation_db::resources { + +//------------------------------------------------------------------------------ + + extern const char * const Directory; + extern const char * const Command; + extern const char * const File; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/test/CMakeLists.txt b/src/compilation_db/test/CMakeLists.txt new file mode 100644 index 0000000..5ba3fc5 --- /dev/null +++ b/src/compilation_db/test/CMakeLists.txt @@ -0,0 +1,14 @@ +file(GLOB_RECURSE all_sources "*.cpp" ) +add_executable(${PROJECT_NAME}_test ${all_sources}) + +include(TestConfig) + +target_link_libraries( + ${PROJECT_NAME}_test + ${Boost_LIBRARIES} + ${PROJECT_NAME}_lib + json_lib +) + +add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) + diff --git a/src/compilation_db/test/cdb_test_main.cpp b/src/compilation_db/test/cdb_test_main.cpp new file mode 100644 index 0000000..249c68d --- /dev/null +++ b/src/compilation_db/test/cdb_test_main.cpp @@ -0,0 +1,9 @@ +#include "test_tools/boost_macroses.hpp" + +#define BOOST_TEST_MODULE compilation_db +#include + +int main(int argc, char* argv[]) +{ + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); +} diff --git a/src/compilation_db/test/fixtures/cdb_test_fixture.cpp b/src/compilation_db/test/fixtures/cdb_test_fixture.cpp new file mode 100644 index 0000000..55da5cc --- /dev/null +++ b/src/compilation_db/test/fixtures/cdb_test_fixture.cpp @@ -0,0 +1,80 @@ +#include "compilation_db/test/fixtures/cdb_test_fixture.hpp" + +#include "compilation_db/api/cdb_database.hpp" +#include "compilation_db/api/cdb_loader.hpp" +#include "compilation_db/ih/cdb_accessor_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include "json/api/json_object.hpp" +#include "json/ih/json_accessor_impl.hpp" + +#include +#include + +//------------------------------------------------------------------------------ + +namespace compilation_db::test { + +//------------------------------------------------------------------------------ + +CompilationDbFixture::CompilationDbFixture() = default; +CompilationDbFixture::~CompilationDbFixture() = default; + +//------------------------------------------------------------------------------ + +const Database & CompilationDbFixture::parseJson( std::string_view _json ) +{ + auto jsonPtr = createJson( _json ); + INTERNAL_CHECK_ERROR( jsonPtr ) + + m_databasePtr = ensureLoader().load( *jsonPtr ); + + INTERNAL_CHECK_ERROR( m_databasePtr ); + return *m_databasePtr; +} + +//------------------------------------------------------------------------------ + +CompilationDbFixture::JsonObjectPtr CompilationDbFixture::createJson( + std::string_view _json +) +{ + std::stringstream stream; + stream << _json; + return ensureJsonAccessor().createJson( stream ); +} + +//------------------------------------------------------------------------------ + +json::JsonAccessor & CompilationDbFixture::ensureJsonAccessor() +{ + if( !m_jsonAccessorPtr ) + m_jsonAccessorPtr.reset( new json::JsonAccesorImpl ); + + return *m_jsonAccessorPtr; +} + +//------------------------------------------------------------------------------ + +Loader & CompilationDbFixture::ensureLoader() +{ + if( !m_loaderPtr ) + m_loaderPtr = ensureAccessor().createLoader(); + + return *m_loaderPtr; +} + +//------------------------------------------------------------------------------ + +Accessor & CompilationDbFixture::ensureAccessor() +{ + if( !m_accessorPtr ) + m_accessorPtr.reset( new AccessorImpl ); + + return *m_accessorPtr; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/test/fixtures/cdb_test_fixture.hpp b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp new file mode 100644 index 0000000..42a937e --- /dev/null +++ b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace json { + class JsonObject; + class JsonAccessor; +} + +namespace compilation_db { + class Accessor; + class Loader; + class Database; +} + +namespace compilation_db::test { + +//------------------------------------------------------------------------------ + +class CompilationDbFixture +{ +public: + + CompilationDbFixture(); + ~CompilationDbFixture(); + + const Database & parseJson( std::string_view _json ); + +private: + + using JsonObjectPtr = std::unique_ptr< json::JsonObject >; + + JsonObjectPtr createJson( std::string_view _json ); + json::JsonAccessor & ensureJsonAccessor(); + + Loader & ensureLoader(); + Accessor & ensureAccessor(); + +private: + + std::unique_ptr< Database > m_databasePtr; + + std::unique_ptr< Loader > m_loaderPtr; + std::unique_ptr< Accessor > m_accessorPtr; + + std::unique_ptr< json::JsonAccessor > m_jsonAccessorPtr; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/compilation_db/test/suits/cdb_test_suits.cpp b/src/compilation_db/test/suits/cdb_test_suits.cpp new file mode 100644 index 0000000..5ce4f2d --- /dev/null +++ b/src/compilation_db/test/suits/cdb_test_suits.cpp @@ -0,0 +1,116 @@ +#include "compilation_db/test/fixtures/cdb_test_fixture.hpp" + +#include "compilation_db/api/cdb_command_object.hpp" +#include "compilation_db/api/cdb_database.hpp" + +#include +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN: + +1. One compilation object +2. Sever compilation objects + +------------------------------------------------------------------------------*/ + +namespace compilation_db::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(CompilationDbTests, CompilationDbFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_one_compilation_object) +{ + // Run + const Database & db = parseJson( + R"([ + { + "directory": "/home/user/temp/project", + "command": "/usr/bin/c++ -I/home/user/temp/project file.o file.cpp", + "file": "file.cpp" + } + ])" + ); + + // Check + BOOST_REQUIRE_EQUAL( db.getCount(), 1 ); + { + const CommandObject & object = db.getObject( 0 ); + BOOST_CHECK_EQUAL( object.getDirectory(), "/home/user/temp/project" ); + BOOST_CHECK_EQUAL( object.getFile(), "file.cpp" ); + BOOST_CHECK_EQUAL( + object.getCommand(), + "/usr/bin/c++ -I/home/user/temp/project file.o file.cpp" + ); + } + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_several_compilation_objects) +{ + // Run + const Database & db = parseJson( + R"([ + { + "directory": "/home/user/temp/project", + "command": "/usr/bin/c++ -I/home/user/temp/project file1.o file1.cpp", + "file": "file1.cpp" + }, + { + "directory": "/home/user/temp/project", + "command": "/usr/bin/c++ -I/home/user/temp/project file2.o file2.cpp", + "file": "file2.cpp" + }, + { + "directory": "/home/user/temp/project", + "command": "/usr/bin/c++ -I/home/user/temp/project file3.o file3.cpp", + "file": "file3.cpp" + } + ])" + ); + + // Check + BOOST_REQUIRE_EQUAL( db.getCount(), 3 ); + { + const CommandObject & object = db.getObject( 0 ); + BOOST_CHECK_EQUAL( object.getDirectory(), "/home/user/temp/project" ); + BOOST_CHECK_EQUAL( object.getFile(), "file1.cpp" ); + BOOST_CHECK_EQUAL( + object.getCommand(), + "/usr/bin/c++ -I/home/user/temp/project file1.o file1.cpp" + ); + } + { + const CommandObject & object = db.getObject( 1 ); + BOOST_CHECK_EQUAL( object.getDirectory(), "/home/user/temp/project" ); + BOOST_CHECK_EQUAL( object.getFile(), "file2.cpp" ); + BOOST_CHECK_EQUAL( + object.getCommand(), + "/usr/bin/c++ -I/home/user/temp/project file2.o file2.cpp" + ); + } + { + const CommandObject & object = db.getObject( 2 ); + BOOST_CHECK_EQUAL( object.getDirectory(), "/home/user/temp/project" ); + BOOST_CHECK_EQUAL( object.getFile(), "file3.cpp" ); + BOOST_CHECK_EQUAL( + object.getCommand(), + "/usr/bin/c++ -I/home/user/temp/project file3.o file3.cpp" + ); + } + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/fs/CMakeLists.txt b/src/fs/CMakeLists.txt index eafebf9..a8c0260 100644 --- a/src/fs/CMakeLists.txt +++ b/src/fs/CMakeLists.txt @@ -2,13 +2,7 @@ project(file_system) include_directories(.) -file(GLOB all_sources - "ih/*.cpp" - "impl/*.cpp" - "impl/**/*.cpp" - "resources/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") +add_library(${PROJECT_NAME}_lib STATIC ${all_sources}) -add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) - -TARGET_SPECIFIC( ${PROJECT_NAME}_lib ) +TARGET_SPECIFIC(${PROJECT_NAME}_lib) diff --git a/src/fs/api/exceptions/fs_exceptions.hpp b/src/fs/api/fs_exceptions.hpp similarity index 91% rename from src/fs/api/exceptions/fs_exceptions.hpp rename to src/fs/api/fs_exceptions.hpp index cde2661..8fa884d 100644 --- a/src/fs/api/exceptions/fs_exceptions.hpp +++ b/src/fs/api/fs_exceptions.hpp @@ -14,6 +14,7 @@ class Exception : public exception::Exception {}; class CantOpenFile : public Exception {}; class CantCreateFile : public Exception {}; +class CheckingExistFileFail : public Exception {}; //------------------------------------------------------------------------------ diff --git a/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp b/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp index e689229..32c8a02 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp +++ b/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp @@ -1,6 +1,6 @@ #pragma once -#include "fs/api/exceptions/fs_exceptions.hpp" +#include "fs/api/fs_exceptions.hpp" #include "fs/impl/exceptions/fs_base_exception_impl.hpp" #include diff --git a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp index 9d4ed84..d1ecabe 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp +++ b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp @@ -1,6 +1,6 @@ #pragma once -#include "fs/api/exceptions/fs_exceptions.hpp" +#include "fs/api/fs_exceptions.hpp" #include "fs/impl/exceptions/fs_base_exception_impl.hpp" #include diff --git a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp new file mode 100644 index 0000000..f588963 --- /dev/null +++ b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp @@ -0,0 +1,37 @@ +#include "fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp" + +#include "fs/resources/fs_resources_exceptions.hpp" + +//------------------------------------------------------------------------------ + +namespace fs { + +//------------------------------------------------------------------------------ + +CheckingExistFileFailImpl::CheckingExistFileFailImpl( + const Path & _path, + const std::error_code & _code +) + : BaseClass( resources::exceptions::CheckingExistFileFail::Code ) + , m_path{ _path } + , m_originMsg{ _code.message() } +{ + +} + +//------------------------------------------------------------------------------ + +std::string CheckingExistFileFailImpl::getMessage() const noexcept +{ + using namespace resources; + return + exceptions::CheckingExistFileFail::Msg + + m_path.string() + + " ." + + m_originMsg + ; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp new file mode 100644 index 0000000..d031378 --- /dev/null +++ b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include "fs/api/fs_exceptions.hpp" +#include "fs/impl/exceptions/fs_base_exception_impl.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace fs { + +//------------------------------------------------------------------------------ + +class CheckingExistFileFailImpl : public BaseExceptionImpl< CheckingExistFileFail > +{ + using BaseClass = BaseExceptionImpl< CheckingExistFileFail >; + +public: + + using Path = stdfs::path; + + CheckingExistFileFailImpl( + const Path & _path, + const std::error_code & _code + ); + + std::string getMessage() const noexcept override; + +private: + + const Path m_path; + const std::string m_originMsg; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/fs/impl/physical/fs_physical_file_system.cpp b/src/fs/impl/physical/fs_physical_file_system.cpp index ba48ae6..1ad8143 100644 --- a/src/fs/impl/physical/fs_physical_file_system.cpp +++ b/src/fs/impl/physical/fs_physical_file_system.cpp @@ -5,6 +5,7 @@ #include "fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp" #include "fs/impl/exceptions/fs_exception_cant_create_file.hpp" +#include "fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp" #include #include @@ -47,7 +48,12 @@ PhysicalFileSystem::FilePtr PhysicalFileSystem::createFile( bool PhysicalFileSystem::isExistFile( const Path & _path ) const { - return stdfs::exists( _path ); + std::error_code errorCode; + const bool result = stdfs::exists( _path, errorCode ); + if( errorCode ) + throw CheckingExistFileFailImpl( _path, errorCode ); + + return result; } //------------------------------------------------------------------------------ diff --git a/src/fs/resources/fs_resources_exceptions.cpp b/src/fs/resources/fs_resources_exceptions.cpp index 51287b6..5dccc9b 100644 --- a/src/fs/resources/fs_resources_exceptions.cpp +++ b/src/fs/resources/fs_resources_exceptions.cpp @@ -26,4 +26,12 @@ namespace CantOpenFile //------------------------------------------------------------------------------ +namespace CheckingExistFileFail +{ + const char * const Code = "IS_EXIST_PATH"; + const char * const Msg = "Error during checking path: "; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/fs/resources/fs_resources_exceptions.hpp b/src/fs/resources/fs_resources_exceptions.hpp index cf22b81..428dc6a 100644 --- a/src/fs/resources/fs_resources_exceptions.hpp +++ b/src/fs/resources/fs_resources_exceptions.hpp @@ -26,4 +26,12 @@ namespace CantOpenFile //------------------------------------------------------------------------------ +namespace CheckingExistFileFail +{ + extern const char * const Code; + extern const char * const Msg; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/json/CMakeLists.txt b/src/json/CMakeLists.txt index d6d5801..f5e4eca 100644 --- a/src/json/CMakeLists.txt +++ b/src/json/CMakeLists.txt @@ -3,10 +3,9 @@ project(json) include_directories(.) include_directories(../3rd-part/json) -file(GLOB all_sources - "ih/*.cpp" - "impl/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) if(CPPINCLUDE_BUILD_WITH_TESTS) diff --git a/src/json/api/json_array.hpp b/src/json/api/json_array.hpp index bc40c61..e2c8832 100644 --- a/src/json/api/json_array.hpp +++ b/src/json/api/json_array.hpp @@ -5,8 +5,7 @@ //------------------------------------------------------------------------------ namespace json { - -class JsonValue; + class JsonValue; //------------------------------------------------------------------------------ diff --git a/src/json/api/json_object.hpp b/src/json/api/json_object.hpp index 214f23d..bb3362e 100644 --- a/src/json/api/json_object.hpp +++ b/src/json/api/json_object.hpp @@ -18,6 +18,7 @@ class JsonObject virtual ~JsonObject() = default; virtual JsonValuePtr getAttributeValue( std::string_view _name ) const = 0; + virtual JsonValuePtr asValue() const = 0; }; //------------------------------------------------------------------------------ diff --git a/src/json/ih/json_accessor.hpp b/src/json/ih/json_accessor.hpp index e9368ee..06dfe0b 100644 --- a/src/json/ih/json_accessor.hpp +++ b/src/json/ih/json_accessor.hpp @@ -5,8 +5,7 @@ //------------------------------------------------------------------------------ namespace json { - -class JsonObject; + class JsonObject; //------------------------------------------------------------------------------ diff --git a/src/json/impl/json_array_impl.hpp b/src/json/impl/json_array_impl.hpp index 67349e6..3403e3a 100644 --- a/src/json/impl/json_array_impl.hpp +++ b/src/json/impl/json_array_impl.hpp @@ -2,7 +2,7 @@ #include "json/api/json_array.hpp" -#include "nlohmann/json.hpp" +#include //------------------------------------------------------------------------------ diff --git a/src/json/impl/json_object_impl.cpp b/src/json/impl/json_object_impl.cpp index 7c8e797..3b83586 100644 --- a/src/json/impl/json_object_impl.cpp +++ b/src/json/impl/json_object_impl.cpp @@ -46,4 +46,12 @@ JsonObjectImpl::JsonValuePtr JsonObjectImpl::getAttributeValue( //------------------------------------------------------------------------------ +JsonObjectImpl::JsonValuePtr JsonObjectImpl::asValue() const +{ + JsonImpl copy = m_jsonImpl; + return JsonValuePtr{ new JsonValueImpl{ std::move( copy ) } }; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/json/impl/json_object_impl.hpp b/src/json/impl/json_object_impl.hpp index dfa04ca..105c034 100644 --- a/src/json/impl/json_object_impl.hpp +++ b/src/json/impl/json_object_impl.hpp @@ -2,7 +2,7 @@ #include "json/api/json_object.hpp" -#include "nlohmann/json.hpp" +#include //------------------------------------------------------------------------------ @@ -24,6 +24,7 @@ class JsonObjectImpl final : public JsonObject explicit JsonObjectImpl( std::istream & _stream ); JsonValuePtr getAttributeValue( std::string_view _name ) const override; + JsonValuePtr asValue() const override; private: diff --git a/src/json/impl/json_value_impl.hpp b/src/json/impl/json_value_impl.hpp index 983282d..39f486c 100644 --- a/src/json/impl/json_value_impl.hpp +++ b/src/json/impl/json_value_impl.hpp @@ -2,7 +2,7 @@ #include "json/api/json_value.hpp" -#include "nlohmann/json.hpp" +#include //------------------------------------------------------------------------------ diff --git a/src/json/test/CMakeLists.txt b/src/json/test/CMakeLists.txt index 3d803fa..0bf1146 100644 --- a/src/json/test/CMakeLists.txt +++ b/src/json/test/CMakeLists.txt @@ -1,8 +1,4 @@ -file(GLOB_RECURSE all_sources - "*.cpp" - "fixtures/*.cpp" - "suits/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") add_executable(${PROJECT_NAME}_test ${all_sources}) include(TestConfig) diff --git a/src/json/test/suits/json_test_suits.cpp b/src/json/test/suits/json_test_suits.cpp index c2609a6..03caa9f 100644 --- a/src/json/test/suits/json_test_suits.cpp +++ b/src/json/test/suits/json_test_suits.cpp @@ -20,6 +20,7 @@ TEST PLAN: 6.2 int 6.3 string 6.4 object + 6.5 root of document with objects 7. Not exist attribute ------------------------------------------------------------------------------*/ @@ -351,6 +352,57 @@ BOOST_AUTO_TEST_CASE(t6_4_array_object) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t6_4_array_root_of_object_with_objects) +{ + // Init + createJsonFile( + R"([ + { + "name" : "str1" + }, + { + "name" : "str2" + } + ])" + ); + + // Run + const JsonObject & json = loadJson(); + + // Check + auto arrayValuePtr = json.asValue(); + BOOST_REQUIRE( arrayValuePtr ); + + auto arrayPtr = arrayValuePtr->asArray(); + BOOST_REQUIRE( arrayPtr ); + const JsonArray & array = *arrayPtr; + + BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); + { + auto valPtr = array.at( 0 ); + BOOST_REQUIRE( valPtr ); + + auto objectPtr = valPtr->asObject(); + BOOST_REQUIRE( objectPtr ); + + auto namePtr = objectPtr->getAttributeValue( "name" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str1" ); + } + { + auto valPtr = array.at( 1 ); + BOOST_REQUIRE( valPtr ); + + auto objectPtr = valPtr->asObject(); + BOOST_REQUIRE( objectPtr ); + + auto namePtr = objectPtr->getAttributeValue( "name" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str2" ); + } + +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_CASE(t7_not_exist_attribute) { // Init diff --git a/src/model_includes/CMakeLists.txt b/src/model_includes/CMakeLists.txt index b4f6637..7a5aeae 100644 --- a/src/model_includes/CMakeLists.txt +++ b/src/model_includes/CMakeLists.txt @@ -2,10 +2,9 @@ project(model_includes) include_directories(.) -file(GLOB all_sources - "impl/*.cpp" - "ih/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) target_link_libraries( diff --git a/src/model_includes/api/mi_analyzer.hpp b/src/model_includes/api/mi_analyzer.hpp index f680aee..5f019c3 100644 --- a/src/model_includes/api/mi_analyzer.hpp +++ b/src/model_includes/api/mi_analyzer.hpp @@ -8,6 +8,10 @@ namespace project { class Project; } +namespace cmake_project { + class Project; +} + //------------------------------------------------------------------------------ namespace model_includes { @@ -20,11 +24,14 @@ class Analyzer public: using ModelPtr = stdfwd::unique_ptr< Model >; - using Project = project::Project; virtual ~Analyzer() = default; - virtual ModelPtr analyze( const Project & _project ) const = 0; + virtual ModelPtr analyze( const project::Project & _project ) const = 0; + virtual ModelPtr analyze( + const project::Project & _project, + const cmake_project::Project & _cmakeProject + ) const = 0; }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/api/mi_file.hpp b/src/model_includes/api/mi_file.hpp index 4c2dad4..cb5b525 100644 --- a/src/model_includes/api/mi_file.hpp +++ b/src/model_includes/api/mi_file.hpp @@ -19,7 +19,7 @@ class File virtual ~File() = default; - virtual Path getPath() const = 0; + virtual const Path & getPath() const = 0; virtual FileType getType() const = 0; virtual void addInclude( const Include & _include ) = 0; diff --git a/src/model_includes/impl/mi_analyzer_context.cpp b/src/model_includes/impl/mi_analyzer_context.cpp new file mode 100644 index 0000000..b27130c --- /dev/null +++ b/src/model_includes/impl/mi_analyzer_context.cpp @@ -0,0 +1,219 @@ +#include "model_includes/impl/mi_analyzer_context.hpp" + +#include "model_includes/api/mi_model.hpp" + +#include "project/api/prj_project.hpp" + +#include "parser/api/pr_include_file.hpp" + +#include + +#include +#include + +//------------------------------------------------------------------------------ + +namespace model_includes { + +//------------------------------------------------------------------------------ + +AnalyzerContext::AnalyzerContext( + const project::Project & _project, + Model & _model +) + : m_project{ _project } + , m_cmakeProject{ nullptr } + , m_model{ _model } + , needAnalyzeResolvedIncludes{ false } +{ + +} + +//------------------------------------------------------------------------------ + +AnalyzerContext::AnalyzerContext( + const project::Project & _project, + const cmake_project::Project & _cmakeProject, + Model & _model +) + : m_project{ _project } + , m_cmakeProject{ &_cmakeProject } + , m_model{ _model } + , needAnalyzeResolvedIncludes{ false } +{ + +} + +//------------------------------------------------------------------------------ + +const project::Project & AnalyzerContext::getProject() const +{ + return m_project; +} + +//------------------------------------------------------------------------------ + +const cmake_project::Project * AnalyzerContext::getCMakeProject() const +{ + return m_cmakeProject; +} + +//------------------------------------------------------------------------------ + +const AnalyzerContext::Path & AnalyzerContext::getProjectDir() const +{ + return getProject().getProjectDir(); +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isIgnoredDir( const Path & _path ) const +{ + return getProject().isIgnoredDir( _path ); +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isCppFile( const Path & _path ) const +{ + const project::Project & project = getProject(); + + if( !project.hasCppFileExtensions() ) + return true; + + const Path extension = _path.extension(); + + if( extension.empty() && project.getAnalyzeWithoutExtension() ) + return true; + + const bool result = project.isExistsCppExtension( extension.string() ); + return result; +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isIgnoredFile( const Path & _path ) const +{ + if( getModel().findFile( _path ) ) + return false; + + if( m_ignoredFiles.count( _path ) ) + return true; + + if( getProject().isIgnoredFile( _path ) ) + { + m_ignoredFiles.insert( _path ); + return true; + } + + return false; +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isIgnoreIncludeFile( + const parser::IncludeFile & _includesFile +) const +{ + return getProject().getIgnoreSystemIncludes() && _includesFile.isSystem(); +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isFileInIgnoreDir( const Path & _path ) const +{ + const project::Project & project = getProject(); + bool isFound = false; + project.forEachIgnoreDir( [&]( const Path & _ignoreDir ) + { + isFound = isFolderHasFile( _ignoreDir, _path ); + return !isFound; + }); + + return isFound; +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isFolderHasFile( const Path & _dir, const Path & _path ) +{ + const std::string dirStr = _dir.string(); + const std::string pathStr = _path.string(); + + const std::size_t dirSize = dirStr.size(); + const std::size_t pathSize = pathStr.size(); + + if( dirSize >= pathSize ) + return true; + + const std::string pathSubStr = pathStr.substr( 0, dirSize ); + const bool result = ( pathSubStr == dirStr ); + return result; +} + +//------------------------------------------------------------------------------ + +Model & AnalyzerContext::takeModel() +{ + return m_model; +} + +//------------------------------------------------------------------------------ + +const Model & AnalyzerContext::getModel() const +{ + return m_model; +} + +//------------------------------------------------------------------------------ + +void AnalyzerContext::setNeedAnalyzeResolvedIncludes( bool _enable) +{ + needAnalyzeResolvedIncludes = _enable; +} + +//------------------------------------------------------------------------------ + +bool AnalyzerContext::isNeedAnalyzeResolvedIncludes() const +{ + return needAnalyzeResolvedIncludes; +} + +//------------------------------------------------------------------------------ + +void AnalyzerContext::addResolvedFile( const Path & _path ) +{ + auto pair = m_resolvedFiles.insert( _path ); + if( pair.second ) + m_resolvedFilesStack.push( _path ); +} + +//------------------------------------------------------------------------------ + +AnalyzerContext::PathOpt AnalyzerContext::popResolvedFile() +{ + if( m_resolvedFilesStack.empty() ) + return std::nullopt; + + Path result = m_resolvedFilesStack.top(); + m_resolvedFilesStack.pop(); + return result; +} + +//------------------------------------------------------------------------------ + +void AnalyzerContext::setCurrentCMakeSourceFile( const Path & _path ) +{ + m_currentCMakeSourceFile = _path; +} + +//------------------------------------------------------------------------------ + +AnalyzerContext::PathOpt AnalyzerContext::getCurrentCMakeSourceFile() const +{ + return m_currentCMakeSourceFile; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/model_includes/impl/mi_analyzer_context.hpp b/src/model_includes/impl/mi_analyzer_context.hpp new file mode 100644 index 0000000..96ac518 --- /dev/null +++ b/src/model_includes/impl/mi_analyzer_context.hpp @@ -0,0 +1,97 @@ +#pragma once + +#include "tools/std_hash_fs_path.hpp" + +#include +#include + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace project { + class Project; +} + +namespace cmake_project { + class Project; +} + +namespace parser { + class IncludeFile; +} + +//------------------------------------------------------------------------------ + +namespace model_includes { + class Model; + +//------------------------------------------------------------------------------ + +class AnalyzerContext +{ +public: + + using Path = stdfs::path; + using PathOpt = std::optional< Path >; + using IgnoredFiles = std::unordered_set< Path >; + + using ResolvedFiles = std::unordered_set< Path >; + using ResolvedFilesStack = std::stack< Path >; + + AnalyzerContext( + const project::Project & _project, + Model & _model + ); + + AnalyzerContext( + const project::Project & _project, + const cmake_project::Project & _cmakeProject, + Model & _model + ); + + const project::Project & getProject() const; + const cmake_project::Project * getCMakeProject() const; + const Path & getProjectDir() const; + + const Model & getModel() const; + Model & takeModel(); + + bool isCppFile( const Path & _path ) const; + bool isIgnoredDir( const Path & _path ) const; + bool isIgnoredFile( const Path & _path ) const; + bool isIgnoreIncludeFile( const parser::IncludeFile & _includesFile ) const; + bool isFileInIgnoreDir( const Path & _path ) const; + static bool isFolderHasFile( const Path & _dir, const Path & _path ); + + void setNeedAnalyzeResolvedIncludes( bool _enable ); + bool isNeedAnalyzeResolvedIncludes() const; + + void addResolvedFile( const Path & _path ); + PathOpt popResolvedFile(); + + void setCurrentCMakeSourceFile( const Path & _path ); + PathOpt getCurrentCMakeSourceFile() const; + +private: + + const project::Project & m_project; + const cmake_project::Project * m_cmakeProject; + Model & m_model; + + mutable IgnoredFiles m_ignoredFiles; + + bool needAnalyzeResolvedIncludes; + + ResolvedFiles m_resolvedFiles; + ResolvedFilesStack m_resolvedFilesStack; + + std::optional< Path > m_currentCMakeSourceFile; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/model_includes/impl/mi_analyzer_impl.cpp b/src/model_includes/impl/mi_analyzer_impl.cpp index a7ae0fe..9ead8a8 100644 --- a/src/model_includes/impl/mi_analyzer_impl.cpp +++ b/src/model_includes/impl/mi_analyzer_impl.cpp @@ -8,6 +8,7 @@ #include "model_includes/impl/mi_model_impl.hpp" #include "model_includes/impl/mi_std_library.hpp" #include "model_includes/impl/mi_resolver.hpp" +#include "model_includes/impl/mi_analyzer_context.hpp" #include "parser/api/pr_parser.hpp" #include "parser/api/pr_include_file.hpp" @@ -15,12 +16,14 @@ #include "fs/api/fs_file_system.hpp" #include "fs/api/fs_file.hpp" #include "fs/api/enums/fs_item_type.hpp" -#include "fs/api/exceptions/fs_exceptions.hpp" +#include "fs/api/fs_exceptions.hpp" #include "project/api/prj_project.hpp" #include "exception/ih/exc_internal_error.hpp" +#include "cmake_project/api/cprj_project.hpp" + #include #include #include @@ -47,28 +50,68 @@ AnalyzerImpl::AnalyzerImpl( AnalyzerImpl::ModelPtr AnalyzerImpl::analyze( const project::Project & _project ) const +{ + ModelPtr modelPtr = initModel( _project ); + AnalyzerContext context{ _project, *modelPtr }; + + analyzeFolder( context, context.getProjectDir() ); + return modelPtr; +} + +//------------------------------------------------------------------------------ + +AnalyzerImpl::ModelPtr AnalyzerImpl::analyze( + const project::Project & _project, + const cmake_project::Project & _cmakeProject +) const +{ + ModelPtr modelPtr = initModel( _project ); + AnalyzerContext context{ _project, _cmakeProject, *modelPtr }; + + context.setNeedAnalyzeResolvedIncludes( true ); + + _cmakeProject.forEachFilePath( + [&]( const Path & _path ) + { + if( context.isFileInIgnoreDir( _path ) ) + return true; + + context.setCurrentCMakeSourceFile( _path ); + + analyzeFile( context, _path ); + + while( auto pathOpt = context.popResolvedFile() ) + { + analyzeFile( context, *pathOpt ); + } + + return true; + } + ); + + return modelPtr; +} + +//------------------------------------------------------------------------------ + +AnalyzerImpl::ModelPtr AnalyzerImpl::initModel( const project::Project & _project ) { ModelPtr modelPtr{ new ModelImpl }; const Path & projectDir = _project.getProjectDir(); INTERNAL_CHECK_WARRING( !projectDir.empty() ); modelPtr->setProjectDir( projectDir ); - - IgnoredFiles ignoreFiles; - analyzeFolder( _project, projectDir, *modelPtr, ignoreFiles ); return modelPtr; } //------------------------------------------------------------------------------ void AnalyzerImpl::analyzeFolder( - const Project & _project, - const Path & _folderPath, - Model & _model, - IgnoredFiles & _ignoreFiles + AnalyzerContext & _context, + const Path & _folderPath ) const { - if( _project.isIgnoredDir( _folderPath ) ) + if( _context.isIgnoredDir( _folderPath ) ) return; m_fs.forEachItem( @@ -79,11 +122,11 @@ void AnalyzerImpl::analyzeFolder( switch ( _type ) { case fs::ItemType::Folder : - analyzeFolder( _project, _path, _model, _ignoreFiles ); + analyzeFolder( _context, _path ); break; case fs::ItemType::File : - analyzeFile( _project, _path, _model, _ignoreFiles ); + analyzeFile( _context, _path ); break; default: @@ -96,16 +139,14 @@ void AnalyzerImpl::analyzeFolder( //------------------------------------------------------------------------------ void AnalyzerImpl::analyzeFile( - const Project & _project, - const Path & _path, - Model & _model, - IgnoredFiles & _ignoredFiles + AnalyzerContext & _context, + const Path & _path ) const { - if( !isCppFile( _project, _path ) ) + if( !_context.isCppFile( _path ) ) return; - if( isIgnoredFile( _path, _project, _model, _ignoredFiles ) ) + if( _context.isIgnoredFile( _path ) ) return; try @@ -116,11 +157,11 @@ void AnalyzerImpl::analyzeFile( return; auto includesFiles = m_parser.parseFile( *filePtr ); - analyzeIncludeFiles( _project, _path, includesFiles, _model, _ignoredFiles ); + analyzeIncludeFiles( _context, _path, includesFiles ); } catch( const fs::Exception & _exception ) { - std::cerr << _exception.what() << std::endl; + std::cout << _exception.what() << std::endl; return; } @@ -129,72 +170,114 @@ void AnalyzerImpl::analyzeFile( //------------------------------------------------------------------------------ void AnalyzerImpl::analyzeIncludeFiles( - const Project & _project, + AnalyzerContext & _context, const Path & _path, - const IncludeFiles & _includesFile, - Model & _model, - IgnoredFiles & _ignoreFiles + const IncludeFiles & _includesFile ) const { const FileType fileType = getFileType( _path ); - File & file = _model.ensureFile( _path, fileType ); + File & file = _context.takeModel().ensureFile( _path, fileType ); for( const parser::IncludeFile & includeFile : _includesFile ) { - analyzeIncludeFile( _project, _path, includeFile, file, _model, _ignoreFiles ); + analyzeIncludeFile( _context, _path, includeFile, file ); } } //------------------------------------------------------------------------------ void AnalyzerImpl::analyzeIncludeFile( - const Project & _project, + AnalyzerContext & _context, const Path & _path, - const parser::IncludeFile & _includesFile, - File & _file, - Model & _model, - IgnoredFiles & _ignoreFiles + const parser::IncludeFile & _includeFile, + File & _file ) const { - if( _project.getIgnoreSystemIncludes() && _includesFile.isSystem() ) - { + if( _context.isIgnoreIncludeFile( _includeFile ) ) return; - } - ResolvedPath pair = resolvePath( _project, _path, _includesFile ); + ResolvedPath pair = resolvePath( _context, _path, _includeFile ); const auto & includedFilePath = pair.first; - if( isIgnoredFile( includedFilePath, _project, _model, _ignoreFiles ) ) + if( _context.isIgnoredFile( includedFilePath ) ) return; - FileType fileType = getFileType( includedFilePath ); - File & includedFile = _model.ensureFile( includedFilePath, fileType ); + FileType fileType = getFileType( includedFilePath ); - const parser::IncludeFileLocation & location = _includesFile.getLocation(); + Model & model = _context.takeModel(); + File & includedFile = model.ensureFile( includedFilePath, fileType ); + + const parser::IncludeFileLocation & location = _includeFile.getLocation(); Model::IncludeLocationInfo locationInfo{ location.getLineNumber(), location.getBegin(), location.getEnd() }; - const IncludeType type = getIncludeType( _includesFile ); + const IncludeType type = getIncludeType( _includeFile ); const IncludeStatus status = getIncludeStatus( includedFile, pair ); - _model.createInclude( locationInfo, _file, includedFile, status, type ); + const auto & include = model.createInclude( + locationInfo, + _file, + includedFile, + status, + type + ); + + postProcesNewInclude( _context, include ); } //------------------------------------------------------------------------------ -bool AnalyzerImpl::isCppFile( const Project & _project, const Path & _path ) const +void AnalyzerImpl::postProcesNewInclude( + AnalyzerContext & _context, + const model_includes::Include & _include +) { - if( !_project.hasCppFileExtensions() ) - return true; + using namespace model_includes; - const Path extension = _path.extension(); + if( !_context.isNeedAnalyzeResolvedIncludes() ) + return; + + static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); + const IncludeStatus includeStatus = _include.getStatus(); + + switch( includeStatus ) + { + case IncludeStatus::Unresolved : + return; + + case IncludeStatus::Resolved : + { + const File & destinationFile = _include.getDestinationFile(); + + static_assert( static_cast< int >( FileType::Count ) == 2 ); + const FileType type = destinationFile.getType(); + switch( type ) + { + case FileType::ProjectFile : + { + _context.addResolvedFile( destinationFile.getPath() ); + } + break; - if( extension.empty() && _project.getAnalyzeWithoutExtension() ) - return true; + case FileType::StdLibraryFile : + return; - const bool result = _project.isExistsCppExtension( extension.string() ); - return result; + case FileType::Count : + { + INTERNAL_CHECK_WARRING( false ); + return; + } + } + } + break; + + case IncludeStatus::Count : + { + INTERNAL_CHECK_WARRING( false ); + return; + } + } } //------------------------------------------------------------------------------ @@ -231,32 +314,8 @@ IncludeStatus AnalyzerImpl::getIncludeStatus( //------------------------------------------------------------------------------ -bool AnalyzerImpl::isIgnoredFile( - const Path & _path, - const Project & _project, - const Model & _model, - IgnoredFiles & _ignoreFiles -) -{ - if( _model.findFile( _path ) ) - return false; - - if( _ignoreFiles.count( _path ) ) - return true; - - if( _project.isIgnoredFile( _path ) ) - { - _ignoreFiles.insert( _path ); - return true; - } - - return false; -} - -//------------------------------------------------------------------------------ - AnalyzerImpl::ResolvedPath AnalyzerImpl::resolvePath( - const Project & _project, + const AnalyzerContext & _context, const Path & _currentFile, const parser::IncludeFile & _includeFile ) const @@ -264,11 +323,14 @@ AnalyzerImpl::ResolvedPath AnalyzerImpl::resolvePath( std::string_view includeFileName = _includeFile.getName(); Path filePath = includeFileName; bool isResolved = false; - Resolver resolver{ m_fs, _project }; + const Resolver & resolver = ensureResolver(); auto pathOpt = resolver.resolvePath( + _context.getProject(), + _context.getCMakeProject(), _currentFile, - _includeFile.getName() + _includeFile.getName(), + _context.getCurrentCMakeSourceFile() ); if( pathOpt ) @@ -276,9 +338,20 @@ AnalyzerImpl::ResolvedPath AnalyzerImpl::resolvePath( filePath = *pathOpt; isResolved = true; } + return ResolvedPath{ filePath,isResolved }; } //------------------------------------------------------------------------------ +Resolver & AnalyzerImpl::ensureResolver() const +{ + if( !m_resolver ) + m_resolver.reset( new Resolver{ m_fs } ); + + return *m_resolver; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/model_includes/impl/mi_analyzer_impl.hpp b/src/model_includes/impl/mi_analyzer_impl.hpp index 56060c3..673502f 100644 --- a/src/model_includes/impl/mi_analyzer_impl.hpp +++ b/src/model_includes/impl/mi_analyzer_impl.hpp @@ -2,6 +2,8 @@ #include "model_includes/api/mi_analyzer.hpp" +#include + //------------------------------------------------------------------------------ namespace fs { @@ -20,6 +22,9 @@ namespace parser { namespace model_includes { class Model; class File; + class Include; + class AnalyzerContext; + class Resolver; enum class FileType; enum class IncludeType; enum class IncludeStatus; @@ -35,52 +40,47 @@ class AnalyzerImpl final : public Analyzer const parser::Parser & _parser ); - ModelPtr analyze( const Project & _project ) const override; + ModelPtr analyze( const project::Project & _project ) const override; + + ModelPtr analyze( + const project::Project & _project, + const cmake_project::Project & _cmakeProject + ) const override; private: using Path = stdfs::path; using IncludeFiles = stdfwd::vector< parser::IncludeFile >; - using IgnoredFiles = stdfwd::unordered_set< Path >; - void analyzeFolder( - const Project & _project, - const Path & _path, - Model & _model, - IgnoredFiles & _ignoreFiles - ) const; + static ModelPtr initModel( const project::Project & _project ); + + void analyzeFolder( AnalyzerContext & _context, const Path & _path ) const; - void analyzeFile( - const Project & _project, - const Path & _path, - Model & _model, - IgnoredFiles & _ignoreFiles - ) const; + void analyzeFile( AnalyzerContext & _context, const Path & _path ) const; void analyzeIncludeFiles( - const Project & _project, + AnalyzerContext & _context, const Path & _path, - const IncludeFiles & _includesFile, - Model & _model, - IgnoredFiles & _ignoreFiles + const IncludeFiles & _includesFile ) const; void analyzeIncludeFile( - const Project & _project, + AnalyzerContext & _context, const Path & _path, - const parser::IncludeFile & _includesFile, - File & _file, - Model & _model, - IgnoredFiles & _ignoreFiles + const parser::IncludeFile & _includeFile, + File & _file ) const; - bool isCppFile( const Project & _project, const Path & _path ) const; + static void postProcesNewInclude( + AnalyzerContext & _context, + const model_includes::Include & _include + ); const Path & getProjectDir() const; using ResolvedPath = std::pair< Path, bool >; ResolvedPath resolvePath( - const Project & _project, + const AnalyzerContext & _context, const Path & _currentFile, const parser::IncludeFile & _includeFile ) const; @@ -93,17 +93,13 @@ class AnalyzerImpl final : public Analyzer const ResolvedPath & _pair ) const; - static bool isIgnoredFile( - const Path & _path, - const Project & _project, - const Model & _model, - IgnoredFiles & _ignoreFiles - ); + Resolver & ensureResolver() const; private: const fs::FileSystem & m_fs; const parser::Parser & m_parser; + mutable std::unique_ptr< Resolver > m_resolver; }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_file_impl.cpp b/src/model_includes/impl/mi_file_impl.cpp index 8fcbd1b..7aa6ca3 100644 --- a/src/model_includes/impl/mi_file_impl.cpp +++ b/src/model_includes/impl/mi_file_impl.cpp @@ -23,7 +23,7 @@ FileImpl::FileImpl( const Path & _path, FileType _type ) //------------------------------------------------------------------------------ -FileImpl::Path FileImpl::getPath() const +const FileImpl::Path & FileImpl::getPath() const { return m_path; } diff --git a/src/model_includes/impl/mi_file_impl.hpp b/src/model_includes/impl/mi_file_impl.hpp index 2c6c719..1b866ad 100644 --- a/src/model_includes/impl/mi_file_impl.hpp +++ b/src/model_includes/impl/mi_file_impl.hpp @@ -18,7 +18,7 @@ class FileImpl final : public File FileImpl( const Path & _path, FileType _type ); - Path getPath() const override; + const Path & getPath() const override; FileType getType() const override; void addInclude( const Include & _include ) override; diff --git a/src/model_includes/impl/mi_resolver.cpp b/src/model_includes/impl/mi_resolver.cpp index 554e8f0..3606b31 100644 --- a/src/model_includes/impl/mi_resolver.cpp +++ b/src/model_includes/impl/mi_resolver.cpp @@ -1,14 +1,20 @@ #include "model_includes/impl/mi_resolver.hpp" #include "model_includes/impl/mi_std_library.hpp" +#include "model_includes/impl/mi_resolver_context.hpp" #include "model_includes/api/enums/mi_file_type.hpp" #include "fs/api/fs_file_system.hpp" +#include "fs/api/fs_exceptions.hpp" #include "project/api/prj_project.hpp" +#include "cmake_project/api/cprj_project.hpp" + +#include "exception/ih/exc_internal_error.hpp" #include #include +#include //------------------------------------------------------------------------------ @@ -16,33 +22,36 @@ namespace model_includes { //------------------------------------------------------------------------------ -Resolver::Resolver( const fs::FileSystem & _fs, const project::Project & _project ) +Resolver::Resolver( const fs::FileSystem & _fs ) : m_fs{ _fs } - , m_project{ _project } { } //------------------------------------------------------------------------------ -const Resolver::Path & Resolver::getProjectFolder() const -{ - return m_project.getProjectDir(); -} - -//------------------------------------------------------------------------------ - Resolver::PathOpt Resolver::resolvePath( + const project::Project & _project, + const cmake_project::Project * _cmakeProject, const Path & _startFile, - stdfwd::string_view _fileName + stdfwd::string_view _fileName, + PathOpt _currentCMakeSourceFile ) const { - if( PathOpt pathOpt = checkInCurrentDir( _startFile, _fileName ); pathOpt ) - return pathOpt; + ResolverContext context{ + _project, + _cmakeProject, + _startFile, + _fileName, + _currentCMakeSourceFile + }; - if( PathOpt pathOpt = findInIncludeFolders( _fileName ); pathOpt ) - return pathOpt; + PathOpt pathOpt = checkInCurrentDir( context ); + if( pathOpt ) + return pathOpt; - return std::nullopt; + pathOpt = findInIncludeFolders( context ); + + return pathOpt; } //------------------------------------------------------------------------------ @@ -66,15 +75,14 @@ FileType Resolver::resolveFileType( const Path & _file ) //------------------------------------------------------------------------------ Resolver::PathOpt Resolver::checkInCurrentDir( - const Path & _startFile, - stdfwd::string_view _fileName + const ResolverContext & _context ) const { - Path startDir = _startFile.parent_path(); + Path startDir = _context.getStartFile().parent_path(); if( startDir.is_relative() ) - startDir = getProjectFolder() / startDir; + startDir = _context.getProject().getProjectDir() / startDir; - const Path file = startDir / _fileName; + const Path file = startDir / _context.getFileName(); if( isExistFile( file ) ) return PathOpt{ file }; @@ -84,21 +92,100 @@ Resolver::PathOpt Resolver::checkInCurrentDir( //------------------------------------------------------------------------------ -Resolver::PathOpt Resolver::findInIncludeFolders( std::string_view _fileName ) const +Resolver::PathOpt Resolver::findInIncludeFolders( + const ResolverContext & _context +) const +{ + PathOpt pathOpt = findInIncludeFoldersInProject( _context ); + if( pathOpt ) + return pathOpt; + + if( _context.getCMakeProject() ) + pathOpt = findInIncludeFoldersInCMakeProject( _context ); + + return pathOpt; +} + + +//------------------------------------------------------------------------------ + +Resolver::PathOpt Resolver::findInIncludeFoldersInProject( + const ResolverContext & _context +) const { - const project::Project::IncludeDirIndex count = m_project.getIncludeDirsCount(); + const std::string & fileName = _context.getFileName(); + const project::Project & project = _context.getProject(); + const project::Project::IncludeDirIndex count = project.getIncludeDirsCount(); + const auto projectDir = project.getProjectDir(); + for( project::Project::IncludeDirIndex i = 0; i < count; ++i ) { - Path includeDir = m_project.getIncludeDir( i ); - if( includeDir.is_relative() ) - includeDir = getProjectFolder() / includeDir; + Path includeDir = project.getIncludeDir( i ); - const Path file = includeDir / _fileName; + PathOpt fileOpt = findFile( projectDir, includeDir, fileName ); + if( fileOpt ) + return fileOpt; + } + + return std::nullopt; +} + +//------------------------------------------------------------------------------ - if( isExistFile( file ) ) - return PathOpt{ file }; +Resolver::PathOpt Resolver::findInIncludeFoldersInCMakeProject( + const ResolverContext & _context +) const +{ + const cmake_project::Project * projectOpt = _context.getCMakeProject(); + if( !projectOpt ) + { + INTERNAL_CHECK_WARRING( false ); + return std::nullopt; } + const cmake_project::Project & project = *projectOpt; + const auto projectDir = _context.getProject().getProjectDir(); + const std::string & fileName = _context.getFileName(); + + const Path & startFile = _context.getStartFile(); + + PathOpt sourceFile = _context.getCurrentCMakeSourceFile(); + if( !sourceFile ) + sourceFile = startFile; + + PathOpt result; + + project.forEachIncludes( + *sourceFile, + [&]( const Path & _includedir ) + { + result = findFile( projectDir, _includedir, fileName ); + return !result; + } + ); + + return result; +} + +//------------------------------------------------------------------------------ + +Resolver::PathOpt Resolver::findFile( + const Path & _projectDir, + const Path & _includeDir, + const std::string & _fileName +) const +{ + Path includeDir{ _includeDir }; + if( includeDir.is_relative() ) + includeDir = _projectDir / includeDir; + + Path file = includeDir / _fileName; + + file = stdfs::lexically_normal( file ); + + if( isExistFile( file ) ) + return PathOpt{ file }; + return std::nullopt; } @@ -106,7 +193,15 @@ Resolver::PathOpt Resolver::findInIncludeFolders( std::string_view _fileName ) c bool Resolver::isExistFile( const Path & _filePath ) const { - return m_fs.isExistFile( _filePath ); + try + { + return m_fs.isExistFile( _filePath ); + } + catch( const fs::CheckingExistFileFail & _exception ) + { + std::cout << _exception.what() << std::endl; + return false; + } } //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_resolver.hpp b/src/model_includes/impl/mi_resolver.hpp index 6a91d10..aeb74cb 100644 --- a/src/model_includes/impl/mi_resolver.hpp +++ b/src/model_includes/impl/mi_resolver.hpp @@ -8,16 +8,19 @@ namespace fs { class FileSystem; } -//------------------------------------------------------------------------------ - namespace project { class Project; } +namespace cmake_project { + class Project; +} + //------------------------------------------------------------------------------ namespace model_includes { class StdLibrary; + class ResolverContext; enum class FileType; //------------------------------------------------------------------------------ @@ -29,37 +32,43 @@ class Resolver using Path = stdfs::path; using PathOpt = std::optional< Path >; - Resolver( - const fs::FileSystem & _fs, - const project::Project & _project - ); + explicit Resolver( const fs::FileSystem & _fs ); PathOpt resolvePath( + const project::Project & _project, + const cmake_project::Project * _cmakeProject, const Path & _startFile, - stdfwd::string_view _fileName + stdfwd::string_view _fileName, + PathOpt currentCMakeSourceFile ) const; static FileType resolveFileType( const Path & _startFile ); private: - PathOpt checkInCurrentDir( - const Path & _startFile, - stdfwd::string_view _fileName + PathOpt checkInCurrentDir( const ResolverContext & _context ) const; + + PathOpt findInIncludeFolders( const ResolverContext & _context ) const; + PathOpt findInIncludeFoldersInProject( + const ResolverContext & _context + ) const; + PathOpt findInIncludeFoldersInCMakeProject( + const ResolverContext & _context ) const; - PathOpt findInIncludeFolders( stdfwd::string_view _fileName ) const; + PathOpt findFile( + const Path & _projectDir, + const Path & _includeDir, + const std::string & _fileName + ) const; bool isExistFile( const Path & _filePath ) const; static const StdLibrary & getStdLibrary(); - const Path & getProjectFolder() const; - private: const fs::FileSystem & m_fs; - const project::Project & m_project; }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_resolver_context.cpp b/src/model_includes/impl/mi_resolver_context.cpp new file mode 100644 index 0000000..868813e --- /dev/null +++ b/src/model_includes/impl/mi_resolver_context.cpp @@ -0,0 +1,63 @@ +#include "model_includes/impl/mi_resolver_context.hpp" + +//------------------------------------------------------------------------------ + +namespace model_includes { + +//------------------------------------------------------------------------------ + +ResolverContext::ResolverContext( + const project::Project & _project, + const cmake_project::Project * _cmakeProject, + const Path & _startFile, + stdfwd::string_view _fileName, + PathOpt _currentCMakeSourceFile +) + : m_project{ _project } + , m_cmakeProject{ _cmakeProject } + , m_startFile{ _startFile } + , m_fileName{ _fileName } + , m_currentCMakeSourceFile{ _currentCMakeSourceFile } +{ + +} + +//------------------------------------------------------------------------------ + +const project::Project & ResolverContext::getProject() const +{ + return m_project; +} + +//------------------------------------------------------------------------------ + +const cmake_project::Project * ResolverContext::getCMakeProject() const +{ + return m_cmakeProject; +} + +//------------------------------------------------------------------------------ + +const ResolverContext::Path & ResolverContext::getStartFile() const +{ + return m_startFile; +} + +//------------------------------------------------------------------------------ + +const std::string & ResolverContext::getFileName() const +{ + return m_fileName; +} + +//------------------------------------------------------------------------------ + +ResolverContext::PathOpt ResolverContext::getCurrentCMakeSourceFile() const +{ + return m_currentCMakeSourceFile; +} + +//------------------------------------------------------------------------------ + + +} diff --git a/src/model_includes/impl/mi_resolver_context.hpp b/src/model_includes/impl/mi_resolver_context.hpp new file mode 100644 index 0000000..d45b658 --- /dev/null +++ b/src/model_includes/impl/mi_resolver_context.hpp @@ -0,0 +1,61 @@ +#pragma once + +#include + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace project { + class Project; +} + +namespace cmake_project { + class Project; +} + +//------------------------------------------------------------------------------ + +namespace model_includes { + +//------------------------------------------------------------------------------ + +class ResolverContext +{ +public: + + using Path = stdfs::path; + using PathOpt = std::optional< Path >; + + ResolverContext( + const project::Project & _project, + const cmake_project::Project * _cmakeProject, + const Path & _startFile, + stdfwd::string_view _fileName, + PathOpt _currentCMakeSourceFile + ); + + const project::Project & getProject() const; + const cmake_project::Project * getCMakeProject() const; + + const Path & getStartFile() const; + const std::string & getFileName() const; + + PathOpt getCurrentCMakeSourceFile() const; + +private: + + const project::Project & m_project; + const cmake_project::Project * m_cmakeProject; + + const Path m_startFile; + const std::string m_fileName; + + const PathOpt m_currentCMakeSourceFile; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/model_includes/test/CMakeLists.txt b/src/model_includes/test/CMakeLists.txt index e4fa4b0..a8866b8 100644 --- a/src/model_includes/test/CMakeLists.txt +++ b/src/model_includes/test/CMakeLists.txt @@ -1,8 +1,4 @@ -file(GLOB_RECURSE all_sources - "*.cpp" - "fixtures/**/.cpp" - "suits/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") add_executable(${PROJECT_NAME}_test ${all_sources}) @@ -16,6 +12,7 @@ target_link_libraries( file_system_lib parser_lib test_tools_lib + cmake_project_lib ) add_test(NAME ${PROJECT_NAME}_test COMMAND ${PROJECT_NAME}_test) diff --git a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp index b1aad80..7839820 100644 --- a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp +++ b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp @@ -19,6 +19,10 @@ #include "project/api/prj_project.hpp" #include "project/ih/prj_project_accesso_impl.hpp" +#include "cmake_project/api/cprj_project.hpp" +#include "cmake_project/api/cprj_loader.hpp" +#include "cmake_project/ih/cprj_accessor_impl.hpp" + #include "exception/ih/exc_internal_error.hpp" #include @@ -54,6 +58,13 @@ void ModelIncludesFixture::addFileToProject( //------------------------------------------------------------------------------ +void ModelIncludesFixture::addFileToCmake( std::string_view _file ) +{ + ensureCmakeProject().addFilePath( _file ); +} + +//------------------------------------------------------------------------------ + void ModelIncludesFixture::addFile( std::string_view _path, std::string_view _text @@ -110,12 +121,39 @@ void ModelIncludesFixture::setAnalyzeWithoutExtension( bool _enable ) //------------------------------------------------------------------------------ +void ModelIncludesFixture::addIncludePathToCMake( + std::string_view _file, + std::string_view _includeDir +) +{ + ensureCmakeProject().addIncludeToFile( _file, _includeDir ); +} + +//------------------------------------------------------------------------------ + ModelIncludesFixture::PathOpt ModelIncludesFixture::resolvePath( const Path & _startFile, - stdfwd::string_view _fileName + std::string_view _fileName ) { - return ensureResolver().resolvePath( _startFile, _fileName ); + return resolvePath( _startFile, _fileName, std::nullopt ); +} + +//------------------------------------------------------------------------------ + +ModelIncludesFixture::PathOpt ModelIncludesFixture::resolvePath( + const Path & _startFile, + stdfwd::string_view _fileName, + const PathOpt & _currentCMakeFile +) +{ + return ensureResolver().resolvePath( + ensureProject(), + m_cmakeProject.get(), + _startFile, + _fileName, + _currentCMakeFile + ); } //------------------------------------------------------------------------------ @@ -150,8 +188,20 @@ BoostPredicate ModelIncludesFixture::checkFileType( ModelWrapper ModelIncludesFixture::analyze() { - ensureProject().changeAllPathsToAbsolute(); - return ensureAnalyzer().analyze( ensureProject() ); + project::Project & project = ensureProject(); + project.changeAllPathsToAbsolute(); + + return ensureAnalyzer().analyze( project ); +} + +//------------------------------------------------------------------------------ + +ModelWrapper ModelIncludesFixture::analyzeCmake() +{ + project::Project & project = ensureProject(); + project.changeAllPathsToAbsolute(); + + return ensureAnalyzer().analyze( project, ensureCmakeProject() ); } //------------------------------------------------------------------------------ @@ -216,9 +266,7 @@ fs::FileSystem & ModelIncludesFixture::ensureFileSystem() Resolver & ModelIncludesFixture::ensureResolver() { if( !m_resolverPtr ) - m_resolverPtr.reset( - new Resolver{ ensureFileSystem(), ensureProject() } - ); + m_resolverPtr.reset( new Resolver{ ensureFileSystem() } ); return *m_resolverPtr; } @@ -261,11 +309,33 @@ project::ProjectAccessor & ModelIncludesFixture::ensureProjectAccessor() project::Project & ModelIncludesFixture::ensureProject() { if( !m_project ) + m_project = ensureProjectAccessor().createProject(); + + return *m_project; +} + +//------------------------------------------------------------------------------ + +cmake_project::Accessor & ModelIncludesFixture::ensureCmakeProjectAccessor() +{ + if( !m_cmakeProjectAccessor ) + m_cmakeProjectAccessor.reset( new cmake_project::AccessorImpl ); + + return *m_cmakeProjectAccessor; +} + +//------------------------------------------------------------------------------ + +cmake_project::Project & ModelIncludesFixture::ensureCmakeProject() +{ + if( !m_cmakeProject ) { - auto newProject{ ensureProjectAccessor().createProject() }; - m_project.swap( newProject ); + auto loaderPtr = ensureCmakeProjectAccessor().createLoader(); + INTERNAL_CHECK_ERROR( loaderPtr ); + m_cmakeProject = loaderPtr->createEmptyProject(); } - return *m_project; + + return *m_cmakeProject; } //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp index 364011c..d420823 100644 --- a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp +++ b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp @@ -12,8 +12,6 @@ namespace fs { class File; } -//------------------------------------------------------------------------------ - namespace model_includes { class ModelIncludesAccessor; class Model; @@ -22,20 +20,21 @@ namespace model_includes { enum class FileType; } -//------------------------------------------------------------------------------ - namespace parser { class ParserAccessor; class Parser; } -//------------------------------------------------------------------------------ - namespace project { class ProjectAccessor; class Project; } +namespace cmake_project { + class Project; + class Accessor; +} + //------------------------------------------------------------------------------ namespace model_includes::test { @@ -60,15 +59,28 @@ class ModelIncludesFixture void addFile( std::string_view _path, std::string_view _text = "" ); void addFileToProject( std::string_view _file, std::string_view _text = "" ); + void addFileToCmake( std::string_view _file ); void addIncludePath( std::string_view _file ); void addIgnoredDir( std::string_view _dir ); void addFileFilter( std::string_view _filter ); + void setIgnoreSystemIncludes( bool _ignoreSystemIncludes ); void addCppExtensions( const Strings & _extensions ); void setAnalyzeWithoutExtension( bool _enable ); - PathOpt resolvePath( const Path & _startFile, std::string_view _fileName ); + void addIncludePathToCMake( std::string_view _file, std::string_view _includeDir ); + + PathOpt resolvePath( + const Path & _startFile, + std::string_view _fileName + ); + + PathOpt resolvePath( + const Path & _startFile, + std::string_view _fileName, + const PathOpt & _currentCMakeSource + ); FileType resolveFileType( stdfwd::string_view _file ); @@ -78,6 +90,7 @@ class ModelIncludesFixture ); ModelWrapper analyze(); + ModelWrapper analyzeCmake(); ModelWrapper createModel(); @@ -99,6 +112,9 @@ class ModelIncludesFixture project::ProjectAccessor & ensureProjectAccessor(); project::Project & ensureProject(); + cmake_project::Accessor & ensureCmakeProjectAccessor(); + cmake_project::Project & ensureCmakeProject(); + std::string toString( FileType _fileType ) const; private: @@ -115,6 +131,9 @@ class ModelIncludesFixture std::unique_ptr< project::ProjectAccessor > m_projectAccessor; std::unique_ptr< project::Project > m_project; + + std::unique_ptr< cmake_project::Accessor > m_cmakeProjectAccessor; + std::unique_ptr< cmake_project::Project > m_cmakeProject; }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp index a5cb2ca..6ee61aa 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp @@ -82,7 +82,8 @@ BoostPredicate FileWrapper::checkIncludedByCountRecursive( int _exceptCount ) co IncludeWrapper FileWrapper::getIncludedBy( std::string_view _sourcePath ) const { - const stdfs::path sourcePath = _sourcePath; + Path sourcePath = _sourcePath; + sourcePath = stdfs::lexically_normal( sourcePath ); const File & file = getFile(); for( File::IncludeIndex i = 0; i < file.getIncludedByCount(); ++i ) { diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp index fd2b44c..adb2b91 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp @@ -2,6 +2,8 @@ #include "test_tools/boost_predicate_wrapper.hpp" +#include + //------------------------------------------------------------------------------ namespace model_includes { @@ -34,6 +36,8 @@ class FileWrapper private: + using Path = stdfs::path; + const File & getFile() const; std::string dumpIncludes() const; diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp index 9ac4b41..571e62b 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp @@ -109,8 +109,9 @@ BoostPredicate IncludeWrapper::checkFile( std::string_view _path ) const { - const stdfs::path filePath = _file.getPath(); - const stdfs::path excpectedPath{ std::string{ _path } }; + const Path filePath = _file.getPath(); + Path excpectedPath{ std::string{ _path } }; + excpectedPath = toLexicallyNormal( excpectedPath ); if( filePath == excpectedPath ) return true; @@ -166,4 +167,11 @@ std::string IncludeWrapper::toString( IncludeStatus _status ) const //------------------------------------------------------------------------------ +IncludeWrapper::Path IncludeWrapper::toLexicallyNormal( const Path & _path ) +{ + return stdfs::lexically_normal( _path ); +} + +//------------------------------------------------------------------------------ + } diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp index a995e98..3d54f12 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp @@ -38,6 +38,8 @@ class IncludeWrapper private: + using Path = stdfs::path; + const Include & getInclude() const; BoostPredicate checkFile( const File & _file, std::string_view _path ) const; @@ -45,6 +47,8 @@ class IncludeWrapper std::string toString( IncludeType _type ) const; std::string toString( IncludeStatus _status ) const; + static Path toLexicallyNormal( const Path & _path ); + private: const Include * m_include; diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp index c767f30..2101d9a 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp @@ -48,7 +48,8 @@ BoostPredicate ModelWrapper::checkFilesCount( std::size_t _expectCount ) const FileWrapper ModelWrapper::findFile( std::string_view _path ) const { - const stdfs::path path{ _path }; + Path path{ _path }; + path = stdfs::lexically_normal( path ); return getModel().findFile( path ); } diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp index 14bce9c..927bc77 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp @@ -27,6 +27,7 @@ class ModelWrapper public: using ModelPtr = stdfwd::unique_ptr< Model >; + using Path = stdfs::path; ModelWrapper( ModelPtr && _modelPtr ); ~ModelWrapper(); diff --git a/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp new file mode 100644 index 0000000..a64756f --- /dev/null +++ b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp @@ -0,0 +1,543 @@ +#include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" + +#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" +#include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" +#include "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" + +#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/enums/mi_include_status.hpp" +#include "model_includes/api/enums/mi_include_type.hpp" + +#include +#include + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN: + +1. One cpp file in cmake + 1.1 Only one cpp file + 1.2 Cpp file with header + 1.3 Cpp file with header that include header + 1.4 cpp file with system include +2. Several cpp files in cmake + 2.1 Several files + 2.2 Several files with same header +3. Ignore files + 3.1 Ignore destination + 3.2 Ignore source + +------------------------------------------------------------------------------*/ + +namespace model_includes::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(AnalyzerforCmakeTests, ModelIncludesFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_1_only_one_cpp_file) +{ + // Init + const std::string projectDir{ "/test_project/" }; + const std::string classACppName{ "class_a.cpp" }; + const std::string classACppPath{ projectDir + classACppName }; + + setProjectDir( projectDir ); + + addFileToProject( classACppName, "void f(){}" ); + addFileToCmake( classACppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 1 ) ); + { + FileWrapper classACpp = model.findFile( classACppPath ); + BOOST_REQUIRE( classACpp.isAvailable() ); + { + BOOST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_2_cpp_file_with_header) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string classAHppName{ "class_a.hpp" }; + const std::string classACppName{ "class_a.cpp" }; + + const std::string classAHppPath{ projectDir + classAHppName }; + const std::string classACppPath{ projectDir + classACppName }; + + setProjectDir( projectDir ); + + addFileToProject( classAHppName, "class A{ A(); };" ); + addFileToProject( + classACppName, + "#include \"" + classAHppName + "\" \n" + "A::A();" + ); + + addFileToCmake( classACppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper classAHeader = model.findFile( classAHppPath ); + BOOST_REQUIRE( classAHeader.isAvailable() ); + { + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + + IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + } + } + { + FileWrapper classACpp = model.findFile( classACppPath ); + BOOST_REQUIRE( classACpp.isAvailable() ); + { + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_4_cpp_file_with_system_include) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string systemHeaderName{ "iostream" }; + const std::string classACppName{ "class_a.cpp" }; + + const std::string classACppPath{ projectDir + classACppName }; + + setProjectDir( projectDir ); + + addFileToProject( + classACppName, + "#include <" + systemHeaderName + ">\n" + "void f(){}" + ); + + addFileToCmake( classACppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper systemHeader = model.findFile( systemHeaderName ); + BOOST_REQUIRE( systemHeader.isAvailable() ); + { + BOOST_REQUIRE( systemHeader.checkIncludesCount( 0 ) ); + + BOOST_REQUIRE( systemHeader.checkIncludedByCount( 1 ) ); + + IncludeWrapper includedByClassA = systemHeader.getIncludedBy( classACppPath ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( systemHeaderName ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::System ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + } + } + { + FileWrapper classACpp = model.findFile( classACppPath ); + BOOST_REQUIRE( classACpp.isAvailable() ); + { + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( systemHeaderName ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::System ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_3_cpp_file_with_header_that_include_header) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string classBaseHppName{ "class_base.hpp" }; + const std::string classAHppName{ "class_a.hpp" }; + const std::string classACppName{ "class_a.cpp" }; + + const std::string classBaseHppPath{ projectDir + classBaseHppName }; + const std::string classAHppPath{ projectDir + classAHppName }; + const std::string classACppPath{ projectDir + classACppName }; + + setProjectDir( projectDir ); + + addFileToProject( classBaseHppName, "class Base {};" ); + addFileToProject( classAHppName, + "#include \"" + classBaseHppName + "\" \n" + "class A : public Base { A(); };" + ); + addFileToProject( + classACppName, + "#include \"" + classAHppName + "\" \n" + "A::A();" + ); + + addFileToCmake( classACppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + { + FileWrapper classBaseHeader = model.findFile( classBaseHppPath ); + BOOST_REQUIRE( classBaseHeader.isAvailable() ); + { + BOOST_REQUIRE( classBaseHeader.checkIncludesCount( 0 ) ); + + BOOST_REQUIRE( classBaseHeader.checkIncludedByCount( 1 ) ); + + IncludeWrapper includedByClassA = classBaseHeader.getIncludedBy( classAHppPath ); + BOOST_CHECK( includedByClassA.checkSource( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classBaseHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + } + } + { + FileWrapper classAHeader = model.findFile( classAHppPath ); + BOOST_REQUIRE( classAHeader.isAvailable() ); + { + BOOST_REQUIRE( classAHeader.checkIncludesCount( 1 ) ); + + IncludeWrapper includeToBaseClass = classAHeader.getInclude( 0 ); + BOOST_CHECK( includeToBaseClass.checkSource( classAHppPath ) ); + BOOST_CHECK( includeToBaseClass.checkDestination( classBaseHppPath ) ); + BOOST_CHECK( includeToBaseClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeToBaseClass.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + + IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + } + } + { + FileWrapper classACpp = model.findFile( classACppPath ); + BOOST_REQUIRE( classACpp.isAvailable() ); + { + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_1_several_files) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string classACppName{ "class_a.cpp" }; + const std::string classBCppName{ "class_b.cpp" }; + + const std::string classACppPath{ projectDir + classACppName }; + const std::string classBCppPath{ projectDir + classBCppName }; + + setProjectDir( projectDir ); + + addFileToProject( classACppName, "void f(){}" ); + addFileToProject( classBCppName, "void f(){}" ); + + addFileToCmake( classACppPath ); + addFileToCmake( classBCppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper classACpp = model.findFile( classACppPath ); + BOOST_REQUIRE( classACpp.isAvailable() ); + { + BOOST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper classBCpp = model.findFile( classBCppPath ); + BOOST_REQUIRE( classBCpp.isAvailable() ); + { + BOOST_REQUIRE( classBCpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classBCpp.checkIncludedByCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_2_several_files_with_same_header) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string classACppName{ "class_a.cpp" }; + const std::string classBCppName{ "class_b.cpp" }; + const std::string classHeaderName{ "class_header.hpp" }; + + const std::string classACppPath{ projectDir + classACppName }; + const std::string classBCppPath{ projectDir + classBCppName }; + const std::string classHeaderPath{ projectDir + classHeaderName }; + + setProjectDir( projectDir ); + + addFileToProject( + classACppName, + "#include \"" + classHeaderName + "\" \n" + "void bar(){ f(); }" + ); + addFileToProject( + classBCppName, + "#include \"" + classHeaderName + "\" \n" + "void foo(){ f(); }" + ); + addFileToProject( classHeaderName, "void f(){}" ); + + addFileToCmake( classACppPath ); + addFileToCmake( classBCppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + { + FileWrapper classAFile = model.findFile( classACppPath ); + BOOST_REQUIRE( classAFile.isAvailable() ); + { + BOOST_REQUIRE( classAFile.checkIncludesCount( 1 ) ); + + IncludeWrapper includeMainToClassA = classAFile.getInclude( 0 ); + BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classAFile.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper classBFile = model.findFile( classACppPath ); + BOOST_REQUIRE( classBFile.isAvailable() ); + { + BOOST_REQUIRE( classBFile.checkIncludesCount( 1 ) ); + + IncludeWrapper includeMainToClassA = classBFile.getInclude( 0 ); + BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( classBFile.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper headerFile = model.findFile( classHeaderPath ); + BOOST_REQUIRE( headerFile.isAvailable() ); + { + BOOST_REQUIRE( headerFile.checkIncludesCount( 0 ) ); + + BOOST_REQUIRE( headerFile.checkIncludedByCount( 2 ) ); + + IncludeWrapper includedByClassA = headerFile.getIncludedBy( classACppPath ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + + IncludeWrapper includedByClassB = headerFile.getIncludedBy( classBCppPath ); + BOOST_CHECK( includedByClassB.checkSource( classBCppPath ) ); + BOOST_CHECK( includedByClassB.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includedByClassB.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassB.checkStatus( IncludeStatus::Resolved ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_1_ignore_files_ignore_destination) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( + "main.cpp", + R"( + #include + #include "lib/classA.hpp" + )" + ); + + addFileFilter( "boost/.*" ); + + addFileToCmake( "/test_project/main.cpp" ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); + BOOST_REQUIRE( mainCpp.isAvailable() ); + { + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); + BOOST_REQUIRE( classAHpp.isAvailable() ); + { + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + + IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_2_ignore_files_ignore_source) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( + "main.cpp", + R"( + #include + #include "lib/classA.hpp" + )" + ); + addFileToProject( + "lib_impl/classA.cpp", + R"( + #include "lib/classA.hpp" + )" + ); + + addFileFilter( "boost/.*" ); + addFileFilter( "lib_impl/.*" ); + + addFileToCmake( "/test_project/main.cpp" ); + addFileToCmake( "/test_project/lib/classA.hpp" ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); + BOOST_REQUIRE( mainCpp.isAvailable() ); + { + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); + BOOST_REQUIRE( classAHpp.isAvailable() ); + { + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + + IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + } + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp index 3a6ffdd..ca3c12b 100644 --- a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp +++ b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp @@ -21,6 +21,7 @@ TEST PLAN: 1.1 Current directory 1.2 Include directory 1.3 File with std library name in project + 1.4 Include in local file 2. Include type 2.1 User 2.2 System @@ -31,6 +32,8 @@ TEST PLAN: 3.3 Mix 3.4 Std lib 4. Ignored folders + 4.1 Regular project + 4.2 CMake project 5. Ignore system includes 6. Ignore files 6.1 Ignore destination @@ -286,6 +289,68 @@ BOOST_AUTO_TEST_CASE(t1_3_file_with_std_library_name_in_project) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t1_4_include_in_local_folder) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string includeDir{ "./i/" }; + + const std::string classIncludeHppName{ "class_i.hpp" }; + const std::string classIncludeCppName{ "class_i.cpp" }; + + const std::string classIncludeHppPath{ projectDir + includeDir + classIncludeHppName }; + const std::string classIncludeCppPath{ projectDir + includeDir + classIncludeCppName }; + + setProjectDir( projectDir ); + + addFile( classIncludeHppPath, "class I{ I(); };" ); + addFile( classIncludeCppPath, + "#include \"" + includeDir + classIncludeHppName + "\"" + "I::I(){}" + ); + + addIncludePath( "." ); + + // Run + ModelWrapper model = analyze(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper file = model.findFile( classIncludeHppPath ); + BOOST_REQUIRE( file.isAvailable() ); + { + BOOST_REQUIRE( file.checkIncludesCount( 0 ) ); + + BOOST_REQUIRE( file.checkIncludedByCount( 1 ) ); + IncludeWrapper include = file.getIncludedBy( classIncludeCppPath ); + BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); + BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); + BOOST_CHECK( include.checkType( IncludeType::User ) ); + BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + } + } + { + FileWrapper file = model.findFile( classIncludeCppPath ); + BOOST_REQUIRE( file.isAvailable() ); + { + BOOST_REQUIRE( file.checkIncludesCount( 1 ) ); + IncludeWrapper include = file.getInclude( 0 ); + BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); + BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); + BOOST_CHECK( include.checkType( IncludeType::User ) ); + BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( file.checkIncludedByCount( 0 ) ); + + } + } +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_CASE(t2_1_include_type_user) { // Init @@ -715,7 +780,7 @@ BOOST_AUTO_TEST_CASE(t3_4_include_status_std_lib) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_ignored_folders) +BOOST_AUTO_TEST_CASE(t4_1_ignored_folders_regular_project) { // Init const std::string projectDir{ "/test_project/" }; @@ -740,7 +805,7 @@ BOOST_AUTO_TEST_CASE(t4_ignored_folders) addFile( classAHppPath, "class A{ A(){} };" ); addFile( classIgnoreHppPath, "class I{ I(); };" ); addFile( classIgnoreCppPath, - "#include \"" + ignoredDir + classIgnoreHppName + "\"" + "#include \"" + classIgnoreHppName + "\"" "I::I(){}" ); @@ -783,6 +848,77 @@ BOOST_AUTO_TEST_CASE(t4_ignored_folders) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t4_2_ignored_folders_cmake_project) +{ + // Init + const std::string projectDir{ "/test_project/" }; + + const std::string ignoredDir{ "./i/" }; + + const std::string classAHppName{ "class_a.hpp" }; + const std::string mainCppName{ "main.cpp" }; + + const std::string classIgnoreHppName{ "class_i.hpp" }; + const std::string classIgnoreCppName{ "class_i.cpp" }; + + const std::string classAHppPath{ projectDir + classAHppName }; + const std::string mainCppPath{ projectDir + mainCppName }; + const std::string classIgnoreHppPath{ projectDir + ignoredDir + classIgnoreHppName }; + const std::string classIgnoreCppPath{ projectDir + ignoredDir + classIgnoreCppName }; + + setProjectDir( projectDir ); + addIgnoredDir( ignoredDir ); + + addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFile( classAHppPath, "class A{ A(){} };" ); + addFile( classIgnoreHppPath, "class I{ I(); };" ); + addFile( classIgnoreCppPath, + "#include \"" + classIgnoreHppName + "\"" + "I::I(){}" + ); + + addFileToCmake( mainCppPath ); + addFileToCmake( classIgnoreCppPath ); + + // Run + ModelWrapper model = analyzeCmake(); + + // Check + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + { + FileWrapper mainCpp = model.findFile( mainCppPath ); + BOOST_REQUIRE( mainCpp.isAvailable() ); + { + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + + IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + } + } + { + FileWrapper classAHeader = model.findFile( classAHppPath ); + BOOST_REQUIRE( classAHeader.isAvailable() ); + { + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + + IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + } + } +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_CASE(t5_ignore_system_includes) { // Init diff --git a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp index 28862e8..58d2cb2 100644 --- a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp +++ b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp @@ -16,6 +16,13 @@ TEST PLAN: 3.2. in include subdir 3.3. out of project 4. Not Found +5. CMake project + 5.1 one file in include directory + 5.2 several files in difference directories + 5.3 not found + 5.4 mix with general project + 5.5 header includes file from cmake include + 5.6 header includes file from project include ------------------------------------------------------------------------------*/ @@ -158,6 +165,181 @@ BOOST_AUTO_TEST_CASE(t4_not_found) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t5_1_cmake_project_one_file_in_include_dir) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "main.cpp" ); + + addIncludePathToCMake( "/test_project/main.cpp", "./lib/" ); + addFileToProject( "lib/include.hpp" ); + + // Run + PathOpt resolvedPath = resolvePath( + "/test_project/main.cpp", + "include.hpp" + ); + + // Check + BOOST_REQUIRE( resolvedPath.has_value() ); + + const Path exceptedPath{ "/test_project/lib/include.hpp" }; + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_2_cmake_project_two_files_in_different_include_dirs) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "file1.cpp" ); + addFileToProject( "file2.cpp" ); + + addIncludePathToCMake( "/test_project/file1.cpp", "./lib1/" ); + addIncludePathToCMake( "/test_project/file2.cpp", "./lib2/" ); + + addFileToProject( "lib1/include.hpp" ); + addFileToProject( "lib2/include.hpp" ); + + { + // Check + PathOpt resolvedPath = resolvePath( + "/test_project/file1.cpp", + "include.hpp" + ); + + BOOST_REQUIRE( resolvedPath.has_value() ); + + const Path exceptedPath{ "/test_project/lib1/include.hpp" }; + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); + } + { + + // Check + PathOpt resolvedPath = resolvePath( + "/test_project/file2.cpp", + "include.hpp" + ); + + BOOST_REQUIRE( resolvedPath.has_value() ); + + const Path exceptedPath{ "/test_project/lib2/include.hpp" }; + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); + } +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_3_cmake_project_not_found) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "main.cpp" ); + + addIncludePathToCMake( "/test_project/main.cpp", "./lib_fake/" ); + addFileToProject( "lib/include.hpp" ); + + // Run + PathOpt resolvedPath = resolvePath( + "/test_project/main.cpp", + "include.hpp" + ); + + // Check + BOOST_REQUIRE( !resolvedPath.has_value() ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_4_cmake_project_mix_with_general_project) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "main.cpp" ); + + addIncludePath( "./lib1/" ); + addIncludePathToCMake( "/test_project/main.cpp", "./lib2/" ); + addFileToProject( "lib1/include1.hpp" ); + addFileToProject( "lib2/include2.hpp" ); + + // Run + PathOpt resolvedPath1 = resolvePath( + "/test_project/main.cpp", + "include1.hpp" + ); + PathOpt resolvedPath2 = resolvePath( + "/test_project/main.cpp", + "include2.hpp" + ); + + // Check + BOOST_REQUIRE( resolvedPath1.has_value() ); + BOOST_REQUIRE( resolvedPath2.has_value() ); + + const Path exceptedPath1{ "/test_project/lib1/include1.hpp" }; + const Path exceptedPath2{ "/test_project/lib2/include2.hpp" }; + + BOOST_CHECK_EQUAL( *resolvedPath1, exceptedPath1 ); + BOOST_CHECK_EQUAL( *resolvedPath2, exceptedPath2 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_5_cmake_header_include_file_from_cmake_include) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "classA.cpp" ); + addFileToProject( "classA.hpp" ); + addFileToProject( "lib/base_class.hpp" ); + + addIncludePathToCMake( "/test_project/classA.cpp", "./lib/" ); + + // Run + PathOpt resolvedPath = resolvePath( + "/test_project/classA.hpp", + "base_class.hpp", + "/test_project/classA.cpp" + ); + + // Check + BOOST_REQUIRE( resolvedPath.has_value() ); + + const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_6_cmake_header_include_file_from_project_include) +{ + // Init + setProjectDir( "/test_project/" ); + addFileToProject( "classA.cpp" ); + addFileToProject( "classA.hpp" ); + addFileToProject( "lib/base_class.hpp" ); + + addIncludePath( "./lib/" ); + + addIncludePathToCMake( "/test_project/classA.cpp", "./fake_lib/" ); + + // Run + PathOpt resolvedPath = resolvePath( + "/test_project/classA.hpp", + "base_class.hpp", + "/test_project/classA.cpp" + ); + + // Check + BOOST_REQUIRE( resolvedPath.has_value() ); + + const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt index 38752b3..cba6b81 100644 --- a/src/parser/CMakeLists.txt +++ b/src/parser/CMakeLists.txt @@ -2,12 +2,10 @@ project(parser) include_directories(.) -file(GLOB parser_sources - "ih/*.cpp" - "impl/*.cpp" - "resources/*.cpp" -) -add_library( ${PROJECT_NAME}_lib STATIC ${parser_sources} ) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + +add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) if(CPPINCLUDE_BUILD_WITH_TESTS) enable_testing() diff --git a/src/parser/impl/pr_parser_context.cpp b/src/parser/impl/pr_parser_context.cpp index 73bc404..f44edef 100644 --- a/src/parser/impl/pr_parser_context.cpp +++ b/src/parser/impl/pr_parser_context.cpp @@ -10,6 +10,7 @@ ParserContext::ParserContext() : m_lineNumber{1} , m_isEnableMultilineComment{ false } , m_isEnableMultilineString{ false } + , m_isEnableRawString{ false } { } @@ -72,4 +73,18 @@ void ParserContext::setMultilineString( bool _enable ) noexcept //------------------------------------------------------------------------------ +bool ParserContext::isEnableRawString() const noexcept +{ + return m_isEnableRawString; +} + +//------------------------------------------------------------------------------ + +void ParserContext::seEnableRawString( bool _enable ) noexcept +{ + m_isEnableRawString = _enable; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/parser/impl/pr_parser_context.hpp b/src/parser/impl/pr_parser_context.hpp index 425b52e..55ed87b 100644 --- a/src/parser/impl/pr_parser_context.hpp +++ b/src/parser/impl/pr_parser_context.hpp @@ -27,13 +27,17 @@ class ParserContext bool isEnableMultilineString() const noexcept; void setMultilineString( bool _enable ) noexcept; + bool isEnableRawString() const noexcept; + void seEnableRawString( bool _enable ) noexcept; + private: std::string m_currentLine; - std::size_t m_lineNumber = 1; + std::size_t m_lineNumber; - bool m_isEnableMultilineComment = false; - bool m_isEnableMultilineString = false; + bool m_isEnableMultilineComment; + bool m_isEnableMultilineString; + bool m_isEnableRawString; }; diff --git a/src/parser/impl/pr_parser_impl.cpp b/src/parser/impl/pr_parser_impl.cpp index eb45604..2ed886c 100644 --- a/src/parser/impl/pr_parser_impl.cpp +++ b/src/parser/impl/pr_parser_impl.cpp @@ -9,6 +9,7 @@ #include #include #include +#include //------------------------------------------------------------------------------ @@ -53,17 +54,21 @@ ParserImpl::IncludeFileOpt ParserImpl::parseLine( ParserContext & _context ) for( size_t i = startPos; i < size; ++i ) { - const char str_char = line[i]; - switch( str_char ) + const char currentChar = line[i]; + switch( currentChar ) { case '/' : i = findComentEnd( _context, i); break; - case '\"': + case '"': i = findEndOfString( _context, i ); break; + case 'R': + i = findEndOfRawString( _context, i ); + break; + case '#' : if( auto indexOpt = findInclude( line, i ); indexOpt ) return parseInclude( _context, *indexOpt ); @@ -79,17 +84,16 @@ ParserImpl::IncludeFileOpt ParserImpl::parseLine( ParserContext & _context ) std::size_t ParserImpl::getStartPos( ParserContext & _context ) noexcept { + const std::size_t index = 0; + if( _context.isEnableMultilineComment() ) - { - const std::size_t index = 0; return findComentEnd( _context, index ); - } if( _context.isEnableMultilineString() ) - { - const std::size_t index = 0; return findEndOfString( _context, index ); - } + + if( _context.isEnableRawString() ) + return findEndOfRawString( _context, index ); return 0; } @@ -167,6 +171,40 @@ std::size_t ParserImpl::findEndOfString( //------------------------------------------------------------------------------ +std::size_t ParserImpl::findEndOfRawString( + ParserContext & _context, + std::size_t _index +) noexcept +{ + const std::string & line = _context.getCurrentLine(); + + if( !_context.isEnableRawString() ) + { + const auto pos = line.find( "\"(", _index + 1 ); + if( pos == std::string::npos ) + { + return _index; + } + else + { + _index += 3; + _context.seEnableRawString( true ); + } + } + + const auto pos = line.find( ")\"", _index ); + if( pos != std::string::npos ) + { + _context.seEnableRawString( false ); + return pos + 2; + } + + return line.size(); + +} + +//------------------------------------------------------------------------------ + std::optional< std::size_t > ParserImpl::findInclude( std::string_view _line, std::size_t _index @@ -224,7 +262,12 @@ ParserImpl::IncludeFileOpt ParserImpl::parseInclude( return std::nullopt; } - const bool isSystem = startPosSystem != std::string::npos; + const size_t startPos = std::min( startPosSystem, startPosUser ); + + const bool isSystem = + startPosSystem != std::string::npos + && startPosSystem == startPos + ; const size_t startPosName = ( isSystem ? startPosSystem : startPosUser ) + 1; const char endChar = isSystem ? '>' : '"'; diff --git a/src/parser/impl/pr_parser_impl.hpp b/src/parser/impl/pr_parser_impl.hpp index 1993be9..d781e7c 100644 --- a/src/parser/impl/pr_parser_impl.hpp +++ b/src/parser/impl/pr_parser_impl.hpp @@ -37,6 +37,11 @@ class ParserImpl final : public Parser ParserContext & _context, std::size_t _index ) noexcept; + static std::size_t findEndOfRawString( + ParserContext & _context, + std::size_t _index + ) noexcept; + static std::optional< std::size_t > findInclude( std::string_view _line, std::size_t _index diff --git a/src/parser/test/CMakeLists.txt b/src/parser/test/CMakeLists.txt index 73840c0..c506ff1 100644 --- a/src/parser/test/CMakeLists.txt +++ b/src/parser/test/CMakeLists.txt @@ -1,8 +1,4 @@ -file(GLOB_RECURSE all_sources - "*.cpp" - "fixtures/*.cpp" - "suits/*.cpp" -) +file( GLOB_RECURSE all_sources "*.cpp") add_executable(${PROJECT_NAME}_test ${all_sources}) diff --git a/src/parser/test/suits/pr_test_suits.cpp b/src/parser/test/suits/pr_test_suits.cpp index 27341c4..55e59fa 100644 --- a/src/parser/test/suits/pr_test_suits.cpp +++ b/src/parser/test/suits/pr_test_suits.cpp @@ -22,6 +22,9 @@ TEST PLAN: 11. Include in multiline string 12. First line \n 13. String with quotation marks +14. Raw string +15. Raw string with separator +16. Brackets in comments ------------------------------------------------------------------------------*/ @@ -305,6 +308,74 @@ BOOST_AUTO_TEST_CASE(t13_string_with_quotation_marks) } +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t14_raw_string) +{ + // Init + file()<< + " R\"( \n" + "#include " + ")\" \n" + "#include " + ; + + // Run + parse(); + + // Check + const auto & files = getResults(); + BOOST_REQUIRE_EQUAL( files.size(), 1 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t15_raw_string_with_seperator) +{ + // Init + file()<< + " R\"( \n" + "some text ) #include " + ")\" \n" + "#include " + ; + + // Run + parse(); + + // Check + const auto & files = getResults(); + BOOST_REQUIRE_EQUAL( files.size(), 1 ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t16_brackets_in_comments) +{ + // Init + file()<< + R"( + #include "file.hpp" // <-> + )" + ; + + // Run + parse(); + + // Check + const auto & files = getResults(); + BOOST_REQUIRE_EQUAL( files.size(), 1 ); + + const auto & file = files.at( 0 ); + BOOST_CHECK_EQUAL( file.getName(), "file.hpp"); + BOOST_CHECK_EQUAL( file.isSystem(), false ); + + const auto & location = file.getLocation(); + BOOST_CHECK_EQUAL( location.getLineNumber(), 2 ); + BOOST_CHECK_EQUAL( location.getBegin(), 13 ); + BOOST_CHECK_EQUAL( location.getEnd(), 21 ); +} + //------------------------------------------------------------------------------ BOOST_AUTO_TEST_SUITE_END() diff --git a/src/project/CMakeLists.txt b/src/project/CMakeLists.txt index b8529a9..09dff94 100644 --- a/src/project/CMakeLists.txt +++ b/src/project/CMakeLists.txt @@ -2,10 +2,8 @@ project(project) include_directories(.) -file(GLOB all_sources - "ih/*.cpp" - "impl/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) diff --git a/src/project/api/prj_exceptions.hpp b/src/project/api/prj_exceptions.hpp new file mode 100644 index 0000000..898ee0b --- /dev/null +++ b/src/project/api/prj_exceptions.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "exception/api/exc_exception.hpp" + +//------------------------------------------------------------------------------ + +namespace project { + +//------------------------------------------------------------------------------ + +class Exception : public exception::Exception {}; + +//------------------------------------------------------------------------------ + +class InvalidRegex : public Exception {}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/api/prj_project.hpp b/src/project/api/prj_project.hpp index 1effe44..527ce6d 100644 --- a/src/project/api/prj_project.hpp +++ b/src/project/api/prj_project.hpp @@ -51,7 +51,6 @@ class Project virtual void setIgnoreSystemIncludes( bool _ignore ) = 0; virtual FileFilterIndex getFileFilterCount() const = 0; - virtual const std::regex & getFileFilter( FileFilterIndex _index ) const = 0; virtual void addFileFilter( std::string_view _filter ) = 0; virtual void addFileFilters( const Strings & _filters ) = 0; virtual bool hasFileFilters() const = 0; diff --git a/src/project/impl/exceptions/prj_base_exception_impl.hpp b/src/project/impl/exceptions/prj_base_exception_impl.hpp new file mode 100644 index 0000000..51c7161 --- /dev/null +++ b/src/project/impl/exceptions/prj_base_exception_impl.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "project/resources/prj_resources_exceptions.hpp" + +#include "exception/ih/exc_exception_impl.hpp" + +//------------------------------------------------------------------------------ + +namespace project { + +//------------------------------------------------------------------------------ + +template < class _BaseException > +class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > +{ + using BaseClass = ::exception::ExceptionImpl< _BaseException >; + +public: + + explicit BaseExceptionImpl( std::string_view _code ) + : BaseClass( resources::exceptions::ModuleName, _code ) + { + } +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/impl/exceptions/prj_exception_invalid_regex.cpp b/src/project/impl/exceptions/prj_exception_invalid_regex.cpp new file mode 100644 index 0000000..eb801ba --- /dev/null +++ b/src/project/impl/exceptions/prj_exception_invalid_regex.cpp @@ -0,0 +1,32 @@ +#include "project/impl/exceptions/prj_exception_invalid_regex.hpp" + +#include "project/resources/prj_resources_exceptions.hpp" + +//------------------------------------------------------------------------------ + +namespace project { + +//------------------------------------------------------------------------------ + +InvalidRegexImpl::InvalidRegexImpl( + const std::string & _filter, + const std::exception & _originException +) + : BaseClass{ resources::exceptions::InvalidRegex::Code } + , m_filter{ _filter } + , m_originMsg{ _originException.what() } +{ + +} + +//------------------------------------------------------------------------------ + +std::string InvalidRegexImpl::getMessage() const noexcept +{ + using namespace resources; + return exceptions::InvalidRegex::Msg + m_filter + " " + m_originMsg; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/impl/exceptions/prj_exception_invalid_regex.hpp b/src/project/impl/exceptions/prj_exception_invalid_regex.hpp new file mode 100644 index 0000000..ab6fdb5 --- /dev/null +++ b/src/project/impl/exceptions/prj_exception_invalid_regex.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "project/api/prj_exceptions.hpp" +#include "project/impl/exceptions/prj_base_exception_impl.hpp" + +//------------------------------------------------------------------------------ + +namespace project { + +//------------------------------------------------------------------------------ + +class InvalidRegexImpl : public BaseExceptionImpl< InvalidRegex > +{ + using BaseClass = BaseExceptionImpl< InvalidRegex >; + +public: + + InvalidRegexImpl( + const std::string & _filter, + const std::exception & _originException + ); + + std::string getMessage() const noexcept override; + +private: + + const std::string m_filter; + const std::string m_originMsg; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/impl/prj_project_impl.cpp b/src/project/impl/prj_project_impl.cpp index 125ba9a..049e9f9 100644 --- a/src/project/impl/prj_project_impl.cpp +++ b/src/project/impl/prj_project_impl.cpp @@ -1,5 +1,7 @@ #include "project/impl/prj_project_impl.hpp" +#include "project/impl/exceptions/prj_exception_invalid_regex.hpp" + #include "tools/path_string_tools.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -203,17 +205,18 @@ ProjectImpl::FileFilterIndex ProjectImpl::getFileFilterCount() const //------------------------------------------------------------------------------ -const std::regex & ProjectImpl::getFileFilter( FileFilterIndex _index ) const -{ - return m_fileFilters.at( _index ); -} - -//------------------------------------------------------------------------------ - void ProjectImpl::addFileFilter( std::string_view _filter ) { std::string str{ _filter }; - m_fileFilters.push_back( std::regex( str ) ); + try + { + m_fileFilters.push_back( tools::Regex{ str } ); + } + catch (const std::regex_error& _exception) + { + throw InvalidRegexImpl{ str, _exception }; + } + } //------------------------------------------------------------------------------ @@ -235,7 +238,7 @@ bool ProjectImpl::hasFileFilters() const bool ProjectImpl::isIgnoredFile( const Path & _path ) const { - for( const std::regex & filter : m_fileFilters ) + for( const tools::Regex & filter : m_fileFilters ) { if( isIgnoredFile( _path, filter ) ) return true; @@ -300,23 +303,34 @@ void ProjectImpl::changeToAbsolute( const Path & _currentDir, Path & _path ) //------------------------------------------------------------------------------ -bool ProjectImpl::isIgnoredFile( const Path & _path, const std::regex & _filter) +bool ProjectImpl::isIgnoredFile( const Path & _path, const tools::Regex & _filter ) { const std::string originStr = _path.string(); const std::string unixStr = tools::toUnixPath( originStr ); - if( regex_search( unixStr, _filter ) ) + if( checkFilter( unixStr, _filter ) ) { return true; } else { const std::string windowsStr = tools::toWindowsPath( originStr ); - return regex_search( windowsStr, _filter ); + return checkFilter( windowsStr, _filter ); } } //------------------------------------------------------------------------------ +bool ProjectImpl::checkFilter( + const std::string & _str, + const tools::Regex & _filter +) +{ + const bool result = _filter.search( _str ); + return result; +} + +//------------------------------------------------------------------------------ + void ProjectImpl::changeToProjectPath( Path & _path ) { if( !_path.is_absolute() ) diff --git a/src/project/impl/prj_project_impl.hpp b/src/project/impl/prj_project_impl.hpp index dc2b58d..6a93834 100644 --- a/src/project/impl/prj_project_impl.hpp +++ b/src/project/impl/prj_project_impl.hpp @@ -3,6 +3,7 @@ #include "project/api/prj_project.hpp" #include "tools/std_hash_fs_path.hpp" +#include "tools/regex.hpp" #include #include @@ -49,7 +50,6 @@ class ProjectImpl final : public Project void setIgnoreSystemIncludes( bool _ignore ) override; FileFilterIndex getFileFilterCount() const override; - const std::regex & getFileFilter( FileFilterIndex _index ) const override; void addFileFilter( std::string_view _filter ) override; void addFileFilters( const Strings & _filters ) override; bool hasFileFilters() const override; @@ -65,14 +65,15 @@ class ProjectImpl final : public Project void changeToAbsolute( const Path & currentDir, Path & _path ); void changeToProjectPath( Path & _path ); - static bool isIgnoredFile( const Path & _path, const std::regex & _filter ); + static bool isIgnoredFile( const Path & _path, const tools::Regex & _filter ); + static bool checkFilter( const std::string & _str, const tools::Regex & _filter ); private: std::vector< Path > m_includeDirs; std::unordered_set< Path > m_ignoredDirs; std::unordered_set< std::string > m_extensions; - std::vector< std::regex > m_fileFilters; + std::vector< tools::Regex > m_fileFilters; Path m_projectDir; diff --git a/src/project/resources/prj_resources_exceptions.cpp b/src/project/resources/prj_resources_exceptions.cpp new file mode 100644 index 0000000..edad832 --- /dev/null +++ b/src/project/resources/prj_resources_exceptions.cpp @@ -0,0 +1,21 @@ +#include "project/resources/prj_resources_exceptions.hpp" + +//------------------------------------------------------------------------------ + +namespace project::resources::exceptions { + +//------------------------------------------------------------------------------ + + const char * const ModuleName = "PROJECT"; + +//------------------------------------------------------------------------------ + +namespace InvalidRegex +{ + const char * const Code = "INVALID_REGEX"; + const char * const Msg = "Invalid regex: "; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/resources/prj_resources_exceptions.hpp b/src/project/resources/prj_resources_exceptions.hpp new file mode 100644 index 0000000..afc59e6 --- /dev/null +++ b/src/project/resources/prj_resources_exceptions.hpp @@ -0,0 +1,21 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace project::resources::exceptions { + +//------------------------------------------------------------------------------ + + extern const char * const ModuleName; + +//------------------------------------------------------------------------------ + +namespace InvalidRegex +{ + extern const char * const Code; + extern const char * const Msg; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/project/test/suits/prj_test_suits.cpp b/src/project/test/suits/prj_test_suits.cpp index 923b8a7..e99cea7 100644 --- a/src/project/test/suits/prj_test_suits.cpp +++ b/src/project/test/suits/prj_test_suits.cpp @@ -1,5 +1,7 @@ #include "project/test/fixture/prj_test_ficture.hpp" +#include "project/api/prj_exceptions.hpp" + #include #include @@ -25,7 +27,10 @@ TEST PLAN: 5.1 Empty 5.2 Library 5.3 File name - + 5.4 Sub string + 5.5 Only begin part + 5.6 Invalid regex + 5.7 Double plus ------------------------------------------------------------------------------*/ @@ -221,7 +226,7 @@ BOOST_AUTO_TEST_CASE(t5_2_ignore_files_library) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_3_file_name_5_3) +BOOST_AUTO_TEST_CASE(t5_3_ignore_file_name) { // Init addFileFilter( "Q.*" ); @@ -233,6 +238,51 @@ BOOST_AUTO_TEST_CASE(t5_3_file_name_5_3) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t5_4_ignore_sub_string) +{ + // Init + addFileFilter( "/ui.*.h" ); + + //Check + BOOST_CHECK( isIgnoredFile( "/tmp/ui/file.h" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_5_ignore_only_begin_part) +{ + // Init + addFileFilter( "^ui.*.h" ); + + //Check + BOOST_CHECK( !isIgnoredFile( "/tmp/ui/file.h" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); + BOOST_CHECK( isIgnoredFile( "ui/file.h" ) ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_6_invalid_regex) +{ + // Check + BOOST_CHECK_THROW( addFileFilter( "[" ), project::InvalidRegex ); + +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_7_double_plus) +{ + // Init + addFileFilter( "lib\\+\\+v3/include/.*" ); + + //Check + BOOST_CHECK( isIgnoredFile( "lib++v3/include/folder/file.h" ) ); +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/CMakeLists.txt b/src/reporter/CMakeLists.txt index 7d00fb2..609e6a0 100644 --- a/src/reporter/CMakeLists.txt +++ b/src/reporter/CMakeLists.txt @@ -2,12 +2,9 @@ project(reporter) include_directories(.) -file(GLOB all_sources - "ih/*.cpp" - "impl/*.cpp" - "impl/**/*.cpp" - "resources/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") +list(FILTER all_sources EXCLUDE REGEX "test/*") + add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) target_link_libraries( diff --git a/src/reporter/api/enums/rp_reporter_kind.hpp b/src/reporter/api/enums/rp_reporter_kind.hpp index 63da472..63e812b 100644 --- a/src/reporter/api/enums/rp_reporter_kind.hpp +++ b/src/reporter/api/enums/rp_reporter_kind.hpp @@ -10,7 +10,9 @@ enum class ReporterKind { Unresolved, MostImpact, + Unincluded, Dump, + DifferentType, Count }; diff --git a/src/reporter/api/rp_factory.hpp b/src/reporter/api/rp_factory.hpp index 64747e7..7deb0ae 100644 --- a/src/reporter/api/rp_factory.hpp +++ b/src/reporter/api/rp_factory.hpp @@ -6,6 +6,7 @@ namespace reporter { class Reporter; + class Settings; enum class ReporterKind; //------------------------------------------------------------------------------ @@ -15,6 +16,7 @@ class Factory public: using ReporterPtr = stdfwd::unique_ptr< Reporter >; + using SettingsPtr = stdfwd::unique_ptr< Settings >; virtual ~Factory() = default; @@ -23,6 +25,10 @@ class Factory virtual ReporterPtr createDumpReporter() = 0; virtual ReporterPtr createUnresolvedReporter() = 0; virtual ReporterPtr createMostImpactReporter() = 0; + virtual ReporterPtr createUnincludedReporter() = 0; + virtual ReporterPtr createDifferentTypeReporter() = 0; + + virtual SettingsPtr createSettings() = 0; }; //------------------------------------------------------------------------------ diff --git a/src/reporter/api/rp_reporter.hpp b/src/reporter/api/rp_reporter.hpp index 0cb0572..d06e2af 100644 --- a/src/reporter/api/rp_reporter.hpp +++ b/src/reporter/api/rp_reporter.hpp @@ -1,6 +1,6 @@ #pragma once -#include "stdfwd.hpp" +#include #include @@ -13,6 +13,7 @@ namespace model_includes { //------------------------------------------------------------------------------ namespace reporter { + class Settings; enum class ReporterKind; //------------------------------------------------------------------------------ @@ -25,9 +26,8 @@ class Reporter virtual ReporterKind getKind() const = 0; - virtual void setMaxFilesCount( size_t _count ) = 0; - virtual void setMaxDetailsCount( size_t _count ) = 0; - virtual void setShowStdFile( bool _enable ) = 0; + virtual const Settings & getSettings() const = 0; + virtual void copySettings( const Settings & _settings ) = 0; virtual void report( const model_includes::Model & _model, diff --git a/src/reporter/api/rp_settings.hpp b/src/reporter/api/rp_settings.hpp new file mode 100644 index 0000000..e466df8 --- /dev/null +++ b/src/reporter/api/rp_settings.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class Settings +{ +public: + + virtual ~Settings() = default; + + using CountType = std::size_t; + + virtual CountType getMaxFilesCount() const = 0; + virtual void setMaxFilesCount( CountType _count ) = 0; + + virtual CountType getMaxDetailsCount() const = 0; + virtual void setMaxDetailsCount( CountType _count ) = 0; + + virtual bool getShowStdFiles() const = 0; + virtual void setShowStdFiles( bool _enable ) = 0; + + virtual void copy( const Settings & _other ) = 0; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/exceptions/rp_base_exception_impl.hpp b/src/reporter/exceptions/rp_base_exception_impl.hpp new file mode 100644 index 0000000..bb6473e --- /dev/null +++ b/src/reporter/exceptions/rp_base_exception_impl.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "exception/ih/exc_exception_impl.hpp" + +#include "reporter/resources/rp_resources_exceptions.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +template< class _BaseException > +class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > +{ +public: + + using BaseClass = ::exception::ExceptionImpl< _BaseException >; + + explicit BaseExceptionImpl( std::string_view _code ) + : BaseClass{ resources::exceptions::ModuleName, _code } + { + + } + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/exceptions/rp_exceptions.hpp b/src/reporter/exceptions/rp_exceptions.hpp new file mode 100644 index 0000000..456d728 --- /dev/null +++ b/src/reporter/exceptions/rp_exceptions.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "exception/api/exc_exception.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class Exception : public exception::Exception {}; + +//------------------------------------------------------------------------------ + +class IncorrectReport : public Exception {}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/exceptions/rp_incorrect_report_impl.cpp b/src/reporter/exceptions/rp_incorrect_report_impl.cpp new file mode 100644 index 0000000..c488178 --- /dev/null +++ b/src/reporter/exceptions/rp_incorrect_report_impl.cpp @@ -0,0 +1,69 @@ +#include "reporter/exceptions/rp_incorrect_report_impl.hpp" + +#include "reporter/resources/rp_resources_exceptions.hpp" +#include "reporter/resources/rp_most_impact_report_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" +#include "reporter/resources/rp_unincluded_report_resources.hpp" +#include "reporter/resources/rp_different_type_report_resources.hpp" +#include "reporter/resources/rp_dump_resources.hpp" + +#include "reporter/api/enums/rp_reporter_kind.hpp" + +#include + +#include +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +IncorrectReportImpl::IncorrectReportImpl( std::string_view _name ) + : BaseClass( resources::exceptions::IncorrectReport::Code ) + , m_name( _name ) +{ + +} + +//------------------------------------------------------------------------------ + +std::string IncorrectReportImpl::getMessage() const noexcept +{ + using namespace resources; + + return fmt::format( + exceptions::IncorrectReport::MsgFmt, + m_name, + getPossiblesValues() + ); +} + +//------------------------------------------------------------------------------ + +std::string IncorrectReportImpl::getPossiblesValues() +{ + static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + + static const std::string seperator = ", "; + + static const std::string result = + std::string() + + resources::most_impact_report::Name + + seperator + + resources::unresolved_report::Name + + seperator + + resources::unincluded_report::Name + + seperator + + resources::dump_reporter::Name + + seperator + + resources::different_type_report::Name + ; + + return result; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/application/exceptions/app_incorrect_report_impl.hpp b/src/reporter/exceptions/rp_incorrect_report_impl.hpp similarity index 54% rename from src/application/exceptions/app_incorrect_report_impl.hpp rename to src/reporter/exceptions/rp_incorrect_report_impl.hpp index aed6dfc..6250364 100644 --- a/src/application/exceptions/app_incorrect_report_impl.hpp +++ b/src/reporter/exceptions/rp_incorrect_report_impl.hpp @@ -1,15 +1,11 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" -#include "application/exceptions/app_base_exception_impl.hpp" - -#include "reporter/api/enums/rp_reporter_kind.hpp" - -#include +#include "reporter/exceptions/rp_exceptions.hpp" +#include "reporter/exceptions/rp_base_exception_impl.hpp" //------------------------------------------------------------------------------ -namespace application { +namespace reporter { //------------------------------------------------------------------------------ @@ -19,20 +15,16 @@ class IncorrectReportImpl : public BaseExceptionImpl< IncorrectReport > public: - using Names = std::unordered_map< std::string, reporter::ReporterKind >; - - explicit IncorrectReportImpl( std::string_view _name, const Names & _names ); + explicit IncorrectReportImpl( std::string_view _name ); std::string getMessage() const noexcept override; private: - std::string getNames() const; + static std::string getPossiblesValues(); private: - const Names m_possibleNames; - const std::string m_name; }; diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp new file mode 100644 index 0000000..d2e1515 --- /dev/null +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp @@ -0,0 +1,257 @@ +#include "reporter/impl/different_type_reporter/rp_different_type_reporter.hpp" + +#include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp" +#include "reporter/impl/tools/rp_file_with_count_container.hpp" +#include "reporter/impl/tools/rp_sorted_includes_by_source_container.hpp" +#include "reporter/resources/rp_different_type_report_resources.hpp" + +#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_include.hpp" +#include "model_includes/api/mi_include_location.hpp" +#include "model_includes/api/enums/mi_file_type.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +DifferentTypeReporter::DifferentTypeReporter( SettingsPtr && _settingsPtr ) + : BaseClass{ std::move( _settingsPtr ) } +{ + +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporter::report( + const model_includes::Model & _model, + std::ostream & _stream +) +{ + Files files = collectFiles( _model ); + + const std::size_t originSize = files.getSize(); + files.resizeByLimit( getMaxFilesCount() ); + + printFiles( files, _model.getProjectDir(), originSize, _stream ); +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporter::printFiles( + const Files & _files, + const Path & _projectDir, + CountType _originSize, + std::ostream & _stream +) const +{ + if( _files.isEmpty() ) + return; + + _stream << resources::different_type_report::Header; + + CountType currentNumber = 1; + _files.forEachFile( [&]( const File & _file ) + { + if( isLimitFiles( currentNumber ) ) + { + printFileLimitLine( _files.getSize(), _stream ); + return false; + } + + printFile( _file, _projectDir, currentNumber, _stream ); + + ++currentNumber; + + return true; + }); + + if( isLimitFilesWithOriginSize( currentNumber, _originSize ) ) + printFileLimitLine( _originSize, _stream ); + +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporter::printFile( + const File & _file, + const Path & _projectDir, + CountType _currentNumber, + std::ostream & _stream +) const +{ + std::string filePath = getPathWithoutProject( _file.getPath(), _projectDir ); + + _stream << fmt::format( + resources::different_type_report::FileFmt, + _currentNumber, + filePath + ); + + Details details = collectDetails( _file ); + printDetails( details, _projectDir, _stream ); +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporter::printDetails( + const Details & _details, + const Path & _projectDir, + std::ostream & _stream +) const +{ + printDetails( + _details.getUserIncludes(), + resources::different_type_report::UserIncludeLabel, + _projectDir, + _stream + ); + + printDetails( + _details.getSystemIncludes(), + resources::different_type_report::SystemIncludeLabel, + _projectDir, + _stream + ); +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporter::printDetails( + const Includes & _details, + std::string_view _header, + const Path & _projectDir, + std::ostream & _stream +) const +{ + _stream << _header; + CountType currentUserNumber = 1; + + _details.forEachInclude( + [&]( const Include & _include ) + { + if( isLimitDetails( currentUserNumber ) ) + { + printDetailsLimitLine( _details.getCount(), _stream ); + return false; + } + + const File & file = _include.getSourceFile(); + const auto lineNumber = _include.getLocation().getLineNumber(); + const auto filePath = getPathWithoutProject( + file.getPath(), + _projectDir + ); + + _stream << fmt::format( + resources::different_type_report::DetailFmt, + currentUserNumber, + filePath, + lineNumber + ); + + ++currentUserNumber; + + return true; + } + ); +} + +//------------------------------------------------------------------------------ + +ReporterKind DifferentTypeReporter::getKind() const +{ + return ReporterKind::DifferentType; +} + +//------------------------------------------------------------------------------ + +DifferentTypeReporter::Files DifferentTypeReporter::collectFiles( + const model_includes::Model & _model +) const +{ + Files result; + _model.forEachFile( + [&]( const model_includes::File & _file ) + { + if( isIgnoredFile( _file ) ) + return true; + + if( isIncludedByDifferentType( _file ) ) + result.insert( { _file, _file.getIncludedByCount() } ); + + return true; + } + ); + return result; +} + +//------------------------------------------------------------------------------ + +DifferentTypeReporter::Details DifferentTypeReporter::collectDetails( + const File & _file +) const +{ + Details result; + for( File::IncludeIndex i = 0; i < _file.getIncludedByCount(); ++i ) + { + const Include & include = _file.getIncludedBy( i ); + result.insertInclude( include ); + } + return result; +} + +//------------------------------------------------------------------------------ + +bool DifferentTypeReporter::isIncludedByDifferentType( const File & _file ) +{ + if( _file.getIncludedByCount() < 2) + return false; + + const auto firstType = _file.getIncludedBy( 0 ).getType(); + + for( File::IncludeIndex i = 1; i < _file.getIncludedByCount(); ++i ) + { + const auto currentType = _file.getIncludedBy( i ).getType(); + if( firstType != currentType ) + return true; + } + + return false; +} + +//------------------------------------------------------------------------------ + +bool DifferentTypeReporter::isIgnoredFile( const File & _file ) const +{ + using namespace model_includes; + + if( getShowStdFiles() ) + return false; + + const FileType type = _file.getType(); + static_assert( static_cast< int >( FileType::Count ) == 2 ); + switch( type ) + { + case FileType::ProjectFile : return false; + case FileType::StdLibraryFile : return true; + default: + INTERNAL_CHECK_WARRING( false ); + return false; + } +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp new file mode 100644 index 0000000..95e6e91 --- /dev/null +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp @@ -0,0 +1,82 @@ +#pragma once + +#include "reporter/impl/rp_base_reporter_impl.hpp" + +//------------------------------------------------------------------------------ + +namespace model_includes { + class File; + class Include; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + class FileWithCountContainer; + class DifferentTypeReporterDetails; + class SortedIncludesBySourceContainer; + +//------------------------------------------------------------------------------ + +class DifferentTypeReporter final : public BaseReporterImpl +{ + using BaseClass = BaseReporterImpl; + +public: + + explicit DifferentTypeReporter( SettingsPtr && _settingsPtr ); + + void report( + const model_includes::Model & _model, + std::ostream & _stream + ) override; + + ReporterKind getKind() const override; + +private: + + using File = model_includes::File; + using Files = FileWithCountContainer; + using Path = stdfs::path; + using Details = DifferentTypeReporterDetails; + using Include = model_includes::Include; + using Includes = SortedIncludesBySourceContainer; + + Files collectFiles( const model_includes::Model & _model ) const; + Details collectDetails( const File & _file ) const; + + void printFiles( + const Files & _files, + const Path & _projectDir, + CountType _originSize, + std::ostream & _stream + ) const; + + void printFile( + const model_includes::File & _file, + const Path & _projectDir, + CountType _currentNumber, + std::ostream & _stream + ) const; + + void printDetails( + const Details & _details, + const Path & _projectDir, + std::ostream & _stream + ) const; + + void printDetails( + const Includes & _details, + std::string_view _header, + const Path & _projectDir, + std::ostream & _stream + ) const; + + static bool isIncludedByDifferentType( const File & _file ); + bool isIgnoredFile( const File & _file ) const; + +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp new file mode 100644 index 0000000..2473272 --- /dev/null +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp @@ -0,0 +1,52 @@ +#include "reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp" + +#include "model_includes/api/mi_include.hpp" +#include "model_includes/api/enums/mi_include_type.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +const DifferentTypeReporterDetails::Includes & +DifferentTypeReporterDetails::getUserIncludes() const +{ + return m_userIncludes; +} + +//------------------------------------------------------------------------------ + +const DifferentTypeReporterDetails::Includes & +DifferentTypeReporterDetails::getSystemIncludes() const +{ + return m_systemIncludes; +} + +//------------------------------------------------------------------------------ + +void DifferentTypeReporterDetails::insertInclude( const Include & _include ) +{ + using namespace model_includes; + + static_assert( static_cast< int >( IncludeType::Count ) == 2 ); + const auto type = _include.getType(); + switch( type ) + { + case IncludeType::User : + m_userIncludes.insert( _include ); + break; + case IncludeType::System : + m_systemIncludes.insert( _include ); + break; + + default: + INTERNAL_CHECK_WARRING( false ); + } +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp new file mode 100644 index 0000000..0257a84 --- /dev/null +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include "reporter/impl/tools/rp_sorted_includes_by_source_container.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class DifferentTypeReporterDetails +{ +public: + + using Include = model_includes::Include; + using Includes = SortedIncludesBySourceContainer; + + const Includes & getUserIncludes() const; + const Includes & getSystemIncludes() const; + + void insertInclude( const Include & _include ); + +private: + + Includes m_userIncludes; + Includes m_systemIncludes; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/rp_dump_reporter.cpp b/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp similarity index 96% rename from src/reporter/impl/rp_dump_reporter.cpp rename to src/reporter/impl/dump_reporter/rp_dump_reporter.cpp index ae66d21..25e2eb5 100644 --- a/src/reporter/impl/rp_dump_reporter.cpp +++ b/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp @@ -1,4 +1,4 @@ -#include "reporter/impl/rp_dump_reporter.hpp" +#include "reporter/impl/dump_reporter/rp_dump_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/resources/rp_dump_resources.hpp" @@ -43,6 +43,14 @@ bool DumpReporter::FileSorter::operator()( //------------------------------------------------------------------------------ +DumpReporter::DumpReporter( SettingsPtr && _settingsPtr ) + : BaseClass{ std::move( _settingsPtr ) } +{ + +} + +//------------------------------------------------------------------------------ + void DumpReporter::report( const model_includes::Model & _model, std::ostream & _stream diff --git a/src/reporter/impl/rp_dump_reporter.hpp b/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp similarity index 95% rename from src/reporter/impl/rp_dump_reporter.hpp rename to src/reporter/impl/dump_reporter/rp_dump_reporter.hpp index 036cde1..9910949 100644 --- a/src/reporter/impl/rp_dump_reporter.hpp +++ b/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp @@ -24,8 +24,12 @@ namespace reporter { class DumpReporter final : public BaseReporterImpl { + using BaseClass = BaseReporterImpl; + public: + explicit DumpReporter( SettingsPtr && _settingPtr ); + void report( const model_includes::Model & _model, std::ostream & _stream diff --git a/src/reporter/impl/rp_most_impact_reporter.cpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp similarity index 68% rename from src/reporter/impl/rp_most_impact_reporter.cpp rename to src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp index 0bd8741..30ba578 100644 --- a/src/reporter/impl/rp_most_impact_reporter.cpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp @@ -1,10 +1,11 @@ -#include "reporter/impl/rp_most_impact_reporter.hpp" +#include "reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" -#include "reporter/impl/impact_reporter/rp_file_info.hpp" -#include "reporter/impl/impact_reporter/rp_most_impact_reporter_detail.hpp" -#include "reporter/resources/rp_most_impact_reporter_resources.hpp" -#include "reporter/resources/rp_report_resources.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" +#include "reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp" +#include "reporter/resources/rp_most_impact_report_resources.hpp" +#include "reporter/impl/tools/rp_file_with_count_container.hpp" +#include "reporter/impl/tools/rp_file_with_count_sorter.hpp" #include "model_includes/api/mi_model.hpp" #include "model_includes/api/mi_file.hpp" @@ -14,9 +15,10 @@ #include "exception/ih/exc_internal_error.hpp" +#include + #include #include -#include //------------------------------------------------------------------------------ @@ -24,30 +26,20 @@ namespace reporter { //------------------------------------------------------------------------------ -bool MostImpcatReporter::FileWithCountSorter::operator()( - const FileInfo & _r, - const FileInfo & _l +bool MostImpcatReporter::DetailsSorter::operator()( + const MostImpactReporterDetail & _r, + const MostImpactReporterDetail & _l ) const { - if( _r.getIncludedByCount() != _l.getIncludedByCount() ) - { - // max is first - return _r.getIncludedByCount() > _l.getIncludedByCount(); - } - else - { - return _r.getFile().getPath() < _l.getFile().getPath(); - } + return FileWithCountSorter()( _r.getFileInfo(), _l.getFileInfo() ); } //------------------------------------------------------------------------------ -bool MostImpcatReporter::DetailsSorter::operator()( - const MostImpactReporterDetail & _r, - const MostImpactReporterDetail & _l -) const +MostImpcatReporter::MostImpcatReporter( SettingsPtr && _settingsPtr ) + : BaseClass{ std::move( _settingsPtr ) } { - return FileWithCountSorter()( _r.getFileInfo(), _l.getFileInfo() ); + } //------------------------------------------------------------------------------ @@ -60,9 +52,9 @@ void MostImpcatReporter::report( FilesContainer files; collectFiles( _model, files ); - const size_t originSize = files.size(); + const size_t originSize = files.getSize(); - resizeByLimit( files ); + files.resizeByLimit( getMaxFilesCount() ); printIncludesByFiles( files, originSize, _model.getProjectDir(), _stream ); } @@ -88,11 +80,10 @@ void MostImpcatReporter::collectFiles( if( !isCollectFile( _file ) ) return true; - const auto count = _file.getIncludedByFilesCountRecursive(); - if( count > 0 ) - { + const File::IncludeIndex count = _file.getIncludedByFilesCountRecursive(); + if( count ) _files.insert( { _file, count } ); - } + return true; } ); @@ -100,21 +91,6 @@ void MostImpcatReporter::collectFiles( //------------------------------------------------------------------------------ -void MostImpcatReporter::resizeByLimit( FilesContainer & _files ) const -{ - const size_t limit = getMaxFilesCount(); - if( limit && _files.size() >= limit ) - { - auto it = _files.begin(); - for( size_t i = 0; i < limit; ++i ) - ++it; - - _files.erase( it, _files.end() ); - } -} - -//------------------------------------------------------------------------------ - void MostImpcatReporter::printIncludesByFiles( const FilesContainer & _files, size_t _originSize, @@ -124,24 +100,24 @@ void MostImpcatReporter::printIncludesByFiles( { using namespace model_includes; - if( _files.empty() ) + if( _files.isEmpty() ) return; - _stream << resources::most_impact_reporter::Header; + _stream << resources::most_impact_report::Header; - size_t currentNumber = 1; + std::size_t currentNumber = 1; - for( const FileInfo & fileInfo : _files ) + for( const FileWithCount & fileInfo : _files ) { const File & includedByFile = fileInfo.getFile(); + const Path & includedByPath = includedByFile.getPath(); - const std::string path = - getPathWithoutProject( includedByFile.getPath(), _projectDir ); + const std::string path = getPathWithoutProject( includedByPath, _projectDir ); - const File::IncludeIndex count = fileInfo.getIncludedByCount(); + const File::IncludeIndex count = fileInfo.getCount(); _stream << fmt::format( - resources::most_impact_reporter::LineForFileFmt, + resources::most_impact_report::LineForFileFmt, currentNumber, path, count @@ -151,16 +127,9 @@ void MostImpcatReporter::printIncludesByFiles( ++currentNumber; } - const size_t limit = getMaxFilesCount(); - if( - limit && - currentNumber >= limit && - currentNumber - 1 != _originSize - ) - { - _stream << fmt::format( resources::LimitLineFmt, limit, _originSize ); - } + if( isLimitFilesWithOriginSize( currentNumber, _originSize ) ) + printFileLimitLine( _originSize, _stream ); } //------------------------------------------------------------------------------ @@ -179,21 +148,15 @@ void MostImpcatReporter::printDetails( if( details.empty() ) return; - _stream << resources::most_impact_reporter::HeaderForDetails; + _stream << resources::most_impact_report::HeaderForDetails; - size_t currentNumber = 1; - const size_t limit = getMaxDetailsCount(); + CountType currentNumber = 1; for( const MostImpactReporterDetail & detail : details ) { - if( limit && currentNumber > limit ) + if( isLimitDetails( currentNumber ) ) { - const size_t detailsCount = details.size(); - _stream << fmt::format( - resources::LimitDetailLineFmt, - limit, - detailsCount - ); + printDetailsLimitLine( details.size(), _stream ); break; } @@ -226,7 +189,7 @@ void MostImpcatReporter::printDetail( if( count ) { _stream << fmt::format( - resources::most_impact_reporter::LineForDetailFmt, + resources::most_impact_report::LineForDetailFmt, currentNumber, path, line, @@ -236,7 +199,7 @@ void MostImpcatReporter::printDetail( else { _stream << fmt::format( - resources::most_impact_reporter::LineForNotImpactDetailFmt, + resources::most_impact_report::LineForNotImpactDetailFmt, currentNumber, path, line diff --git a/src/reporter/impl/rp_most_impact_reporter.hpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp similarity index 76% rename from src/reporter/impl/rp_most_impact_reporter.hpp rename to src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp index 9b20fc2..fad8188 100644 --- a/src/reporter/impl/rp_most_impact_reporter.hpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp @@ -2,7 +2,7 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" -#include +#include //------------------------------------------------------------------------------ @@ -14,15 +14,20 @@ namespace model_includes { //------------------------------------------------------------------------------ namespace reporter { - class FileInfo; + class FileWithCount; class MostImpactReporterDetail; + class FileWithCountContainer; //------------------------------------------------------------------------------ class MostImpcatReporter final : public BaseReporterImpl { + using BaseClass = BaseReporterImpl; + public: + explicit MostImpcatReporter( SettingsPtr && _settingsPtr ); + void report( const model_includes::Model & _model, std::ostream & _stream @@ -32,31 +37,23 @@ class MostImpcatReporter final : public BaseReporterImpl private: - class FileWithCountSorter - { - public: - bool operator()( const FileInfo & _r, const FileInfo & _l ) const; - }; - class DetailsSorter { public: bool operator()( - const MostImpactReporterDetail & _r, - const MostImpactReporterDetail & _l + const MostImpactReporterDetail & _l, + const MostImpactReporterDetail & _r ) const; }; - using FilesContainer = std::set< FileInfo, FileWithCountSorter >; - using DetailsContainer = std::set< MostImpactReporterDetail, DetailsSorter >; + using FilesContainer = FileWithCountContainer; + using DetailsContainer = stdfwd::set< MostImpactReporterDetail, DetailsSorter >; void collectFiles( const model_includes::Model & _model, FilesContainer & _files ) const; - void resizeByLimit( FilesContainer & _files ) const; - void addFileToContainer( const model_includes::File & _file, FilesContainer & _files @@ -89,7 +86,7 @@ class MostImpcatReporter final : public BaseReporterImpl bool isCollectFile( const model_includes::File & _file ) const; - static FileInfo makeFileInfo( const model_includes::File & _file ); + static FileWithCount makeFileInfo( const model_includes::File & _file ); }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.cpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.cpp similarity index 81% rename from src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.cpp rename to src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.cpp index 2229c07..33e7cf5 100644 --- a/src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.cpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.cpp @@ -1,4 +1,4 @@ -#include "reporter/impl/impact_reporter/rp_most_impact_reporter_detail.hpp" +#include "reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp" //------------------------------------------------------------------------------ @@ -25,14 +25,14 @@ const model_includes::File & MostImpactReporterDetail::getFile() const //------------------------------------------------------------------------------ -FileInfo::CountType MostImpactReporterDetail::getIncludedByCount() const +FileWithCount::CountType MostImpactReporterDetail::getIncludedByCount() const { - return getFileInfo().getIncludedByCount(); + return getFileInfo().getCount(); } //------------------------------------------------------------------------------ -const FileInfo & MostImpactReporterDetail::getFileInfo() const +const FileWithCount & MostImpactReporterDetail::getFileInfo() const { return m_fileInfo; } diff --git a/src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.hpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp similarity index 78% rename from src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.hpp rename to src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp index beee98a..573cbf3 100644 --- a/src/reporter/impl/impact_reporter/rp_most_impact_reporter_detail.hpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp @@ -1,6 +1,6 @@ #pragma once -#include "reporter/impl/impact_reporter/rp_file_info.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" //------------------------------------------------------------------------------ @@ -19,7 +19,7 @@ class MostImpactReporterDetail { public: - using CountType = FileInfo::CountType; + using CountType = FileWithCount::CountType; MostImpactReporterDetail( const model_includes::File & _file, @@ -30,14 +30,14 @@ class MostImpactReporterDetail public: const model_includes::File & getFile() const; - FileInfo::CountType getIncludedByCount() const; + FileWithCount::CountType getIncludedByCount() const; const model_includes::IncludeLocation & getIncludeLocation() const; - const FileInfo & getFileInfo() const; + const FileWithCount & getFileInfo() const; private: - const FileInfo m_fileInfo; + const FileWithCount m_fileInfo; const model_includes::IncludeLocation & m_includeLocation; }; diff --git a/src/reporter/impl/rp_base_reporter_impl.cpp b/src/reporter/impl/rp_base_reporter_impl.cpp index 3b9c0f7..b7b0933 100644 --- a/src/reporter/impl/rp_base_reporter_impl.cpp +++ b/src/reporter/impl/rp_base_reporter_impl.cpp @@ -1,7 +1,15 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" -#include +#include "reporter/api/rp_settings.hpp" + +#include "reporter/resources/rp_report_resources.hpp" + +#include "exception/ih/exc_internal_error.hpp" + #include +#include + +#include //------------------------------------------------------------------------------ @@ -9,53 +17,50 @@ namespace reporter { //------------------------------------------------------------------------------ -BaseReporterImpl::BaseReporterImpl() - : m_maxFilesCount{ 0 } - , m_maxDetailsCount{ 0 } - , m_showStdFile{ false } +BaseReporterImpl::BaseReporterImpl( SettingsPtr && _settingsPtr ) + : m_settings{ std::move( _settingsPtr ) } { } //------------------------------------------------------------------------------ -void BaseReporterImpl::setMaxFilesCount( size_t _count ) -{ - m_maxFilesCount = _count; -} +BaseReporterImpl::~BaseReporterImpl() = default; //------------------------------------------------------------------------------ -void BaseReporterImpl::setMaxDetailsCount( size_t _count ) +const Settings & BaseReporterImpl::getSettings() const { - m_maxDetailsCount = _count; + INTERNAL_CHECK_ERROR( m_settings ); + return *m_settings; } //------------------------------------------------------------------------------ -size_t BaseReporterImpl::getMaxFilesCount() const +void BaseReporterImpl::copySettings( const Settings & _settings ) { - return m_maxFilesCount; + INTERNAL_CHECK_ERROR( m_settings ); + m_settings->copy( _settings ); } //------------------------------------------------------------------------------ -size_t BaseReporterImpl::getMaxDetailsCount() const +size_t BaseReporterImpl::getMaxFilesCount() const { - return m_maxDetailsCount; + return getSettings().getMaxFilesCount(); } //------------------------------------------------------------------------------ -void BaseReporterImpl::setShowStdFile( bool _enable ) +size_t BaseReporterImpl::getMaxDetailsCount() const { - m_showStdFile = _enable; + return getSettings().getMaxDetailsCount(); } //------------------------------------------------------------------------------ bool BaseReporterImpl::getShowStdFiles() const { - return m_showStdFile; + return getSettings().getShowStdFiles(); } //------------------------------------------------------------------------------ @@ -63,14 +68,16 @@ bool BaseReporterImpl::getShowStdFiles() const std::string BaseReporterImpl::getPathWithoutProject( const Path & _filePath, const Path & _dirPath -) const +) { if( _dirPath.empty() ) return _filePath.string(); + if( !isFromSameDirectory( _filePath, _dirPath ) ) + return _filePath.string(); + Path result = stdfs::lexically_relative( _filePath, _dirPath ); - // if file out of project then return full path - if( ( !result.empty() ) && (*result.begin()) != ".." ) + if( ( !result.empty() ) ) return result.string(); else { @@ -80,4 +87,103 @@ std::string BaseReporterImpl::getPathWithoutProject( //------------------------------------------------------------------------------ +bool BaseReporterImpl::isFromSameDirectory( + const Path & _path1, + const Path & _path2 +) +{ + const Path root = _path1.root_path(); + if( root != _path2.root_path() ) + return false; + + Path commonPath = getCommonPath( _path1, _path2 ); + const bool result = commonPath != root; + return result; +} + +//------------------------------------------------------------------------------ + +BaseReporterImpl::Path BaseReporterImpl::getCommonPath( + const Path & _path1, + const Path & _path2 +) +{ + Path resutl; + + auto itCurrentFirst = _path1.begin(); + auto itEndFirst = _path1.end(); + + auto itCurrentSecond = _path2.begin(); + auto itEndSecond = _path2.end(); + + while( + itCurrentFirst != itEndFirst && + itCurrentSecond != itEndSecond && + *itCurrentFirst == *itCurrentSecond + ) + { + resutl /= *itCurrentFirst; + + ++itCurrentFirst; + ++itCurrentSecond; + } + + return resutl; +} + +//------------------------------------------------------------------------------ + +bool BaseReporterImpl::isLimitFiles( CountType _currentNumber ) const +{ + return isLimit( _currentNumber, getMaxFilesCount() ); +} + +//------------------------------------------------------------------------------ + +bool BaseReporterImpl::isLimitFilesWithOriginSize( + CountType _currentNumber, + CountType _originSize +) const +{ + return isLimitFiles( _currentNumber ) && _currentNumber - 1 != _originSize; +} + +//------------------------------------------------------------------------------ + +void BaseReporterImpl::printFileLimitLine( + CountType _filesCount, + std::ostream & _stream +) const +{ + const CountType limit = getMaxFilesCount(); + _stream << fmt::format( resources::LimitLineFmt, limit, _filesCount ); +} + +//------------------------------------------------------------------------------ + +bool BaseReporterImpl::isLimitDetails( CountType _currentNumber ) const +{ + return isLimit( _currentNumber, getMaxDetailsCount() ); +} + +//------------------------------------------------------------------------------ + +void BaseReporterImpl::printDetailsLimitLine( + CountType _detailsCount, + std::ostream & _stream +) const +{ + const CountType limit = getMaxDetailsCount(); + _stream << fmt::format( resources::LimitDetailLineFmt, limit, _detailsCount ); +} + +//------------------------------------------------------------------------------ + +bool BaseReporterImpl::isLimit( CountType _currentNumber, CountType _limit ) +{ + return _limit && _currentNumber > _limit; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/reporter/impl/rp_base_reporter_impl.hpp b/src/reporter/impl/rp_base_reporter_impl.hpp index 703eb7b..e4cf56a 100644 --- a/src/reporter/impl/rp_base_reporter_impl.hpp +++ b/src/reporter/impl/rp_base_reporter_impl.hpp @@ -2,6 +2,8 @@ #include "reporter/api/rp_reporter.hpp" +#include + //------------------------------------------------------------------------------ namespace reporter { @@ -12,30 +14,56 @@ class BaseReporterImpl : public Reporter { public: - BaseReporterImpl(); + using SettingsPtr = std::unique_ptr< Settings >; + + BaseReporterImpl( SettingsPtr && _settingsPtr ); + ~BaseReporterImpl(); - void setMaxFilesCount( size_t _count ) override; - void setMaxDetailsCount( size_t _count ) override; - void setShowStdFile( bool _enable ) override; + const Settings & getSettings() const override; + void copySettings( const Settings & _settings ) override; protected: using Path = stdfs::path; + using CountType = size_t; - size_t getMaxFilesCount() const; - size_t getMaxDetailsCount() const; + CountType getMaxFilesCount() const; + CountType getMaxDetailsCount() const; bool getShowStdFiles() const; - std::string getPathWithoutProject( + static std::string getPathWithoutProject( const Path & _filePath, const Path & _dirPath + ); + + static bool isFromSameDirectory( const Path & _path1, const Path & _path2 ); + + static Path getCommonPath( const Path & _path1, const Path & _path2 ); + + bool isLimitFiles( CountType _currentNumber ) const; + bool isLimitFilesWithOriginSize( + CountType _currentNumber, + CountType _originSize + ) const; + void printFileLimitLine( + CountType _filesCount, + std::ostream & _stream ) const; + bool isLimitDetails( CountType _currentNumber ) const; + void printDetailsLimitLine( + CountType _detailsCount, + std::ostream & _stream + ) const; + +private: + + static bool isLimit( CountType _currentNumber, CountType _limit ); + private: - size_t m_maxFilesCount; - size_t m_maxDetailsCount; - bool m_showStdFile; + SettingsPtr m_settings; + }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_factpory_impl.cpp b/src/reporter/impl/rp_factpory_impl.cpp index 5323b62..3ecdd20 100644 --- a/src/reporter/impl/rp_factpory_impl.cpp +++ b/src/reporter/impl/rp_factpory_impl.cpp @@ -2,9 +2,13 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" -#include "reporter/impl/rp_dump_reporter.hpp" -#include "reporter/impl/rp_unresolved_reporter.hpp" -#include "reporter/impl/rp_most_impact_reporter.hpp" +#include "reporter/impl/dump_reporter/rp_dump_reporter.hpp" +#include "reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp" +#include "reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp" +#include "reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp" +#include "reporter/impl/different_type_reporter/rp_different_type_reporter.hpp" + +#include "reporter/impl/rp_settings_impl.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -18,12 +22,14 @@ namespace reporter { FactoryImpl::ReporterPtr FactoryImpl::createReporter( ReporterKind _kind ) { - static_assert( static_cast< int >( ReporterKind::Count ) == 3 ); + static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); switch( _kind ) { - case ReporterKind::Unresolved : return createUnresolvedReporter(); - case ReporterKind::MostImpact : return createMostImpactReporter(); - case ReporterKind::Dump : return createDumpReporter(); + case ReporterKind::Unresolved : return createUnresolvedReporter(); + case ReporterKind::MostImpact : return createMostImpactReporter(); + case ReporterKind::Unincluded : return createUnincludedReporter(); + case ReporterKind::Dump : return createDumpReporter(); + case ReporterKind::DifferentType : return createDifferentTypeReporter(); case ReporterKind::Count : { INTERNAL_CHECK_WARRING(false); @@ -38,21 +44,42 @@ FactoryImpl::ReporterPtr FactoryImpl::createReporter( ReporterKind _kind ) FactoryImpl::ReporterPtr FactoryImpl::createDumpReporter() { - return ReporterPtr{ new DumpReporter }; + return ReporterPtr{ new DumpReporter{ createSettings() } }; } //------------------------------------------------------------------------------ FactoryImpl::ReporterPtr FactoryImpl::createUnresolvedReporter() { - return ReporterPtr{ new UnresolvedReporter }; + return ReporterPtr{ new UnresolvedReporter{ createSettings() } }; } //------------------------------------------------------------------------------ FactoryImpl::ReporterPtr FactoryImpl::createMostImpactReporter() { - return ReporterPtr{ new MostImpcatReporter }; + return ReporterPtr{ new MostImpcatReporter{ createSettings() } }; +} + +//------------------------------------------------------------------------------ + +FactoryImpl::ReporterPtr FactoryImpl::createUnincludedReporter() +{ + return ReporterPtr{ new UnincludedReporter{ createSettings() } }; +} + +//------------------------------------------------------------------------------ + +FactoryImpl::ReporterPtr FactoryImpl::createDifferentTypeReporter() +{ + return ReporterPtr{ new DifferentTypeReporter{ createSettings() } }; +} + +//------------------------------------------------------------------------------ + +FactoryImpl::SettingsPtr FactoryImpl::createSettings() +{ + return SettingsPtr{ new SettingsImpl }; } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_factpory_impl.hpp b/src/reporter/impl/rp_factpory_impl.hpp index b349aec..a372eec 100644 --- a/src/reporter/impl/rp_factpory_impl.hpp +++ b/src/reporter/impl/rp_factpory_impl.hpp @@ -15,6 +15,10 @@ class FactoryImpl final : public Factory ReporterPtr createDumpReporter() override; ReporterPtr createUnresolvedReporter() override; ReporterPtr createMostImpactReporter() override; + ReporterPtr createUnincludedReporter() override; + ReporterPtr createDifferentTypeReporter() override; + + SettingsPtr createSettings() override; }; diff --git a/src/reporter/impl/rp_settings_impl.cpp b/src/reporter/impl/rp_settings_impl.cpp new file mode 100644 index 0000000..9536be8 --- /dev/null +++ b/src/reporter/impl/rp_settings_impl.cpp @@ -0,0 +1,70 @@ +#include "reporter/impl/rp_settings_impl.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +SettingsImpl::SettingsImpl() + : m_maxFilesCount{ 0 } + , m_maxDetailsCount{ 0 } + , m_showStdFiles{ true } +{ + +} + +//------------------------------------------------------------------------------ + +SettingsImpl::CountType SettingsImpl::getMaxFilesCount() const +{ + return m_maxFilesCount; +} + +//------------------------------------------------------------------------------ + +void SettingsImpl::setMaxFilesCount( CountType _count ) +{ + m_maxFilesCount = _count; +} + +//------------------------------------------------------------------------------ + +SettingsImpl::CountType SettingsImpl::getMaxDetailsCount() const +{ + return m_maxDetailsCount; +} + +//------------------------------------------------------------------------------ + +void SettingsImpl::setMaxDetailsCount( CountType _count ) +{ + m_maxDetailsCount = _count; +} + +//------------------------------------------------------------------------------ + +bool SettingsImpl::getShowStdFiles() const +{ + return m_showStdFiles; +} + +//------------------------------------------------------------------------------ + +void SettingsImpl::setShowStdFiles( bool _enable ) +{ + m_showStdFiles = _enable; +} + +//------------------------------------------------------------------------------ + +void SettingsImpl::copy( const Settings & _other ) +{ + setMaxFilesCount( _other.getMaxFilesCount() ); + setMaxDetailsCount( _other.getMaxDetailsCount() ); + setShowStdFiles( _other.getShowStdFiles() ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/rp_settings_impl.hpp b/src/reporter/impl/rp_settings_impl.hpp new file mode 100644 index 0000000..39ea726 --- /dev/null +++ b/src/reporter/impl/rp_settings_impl.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include "reporter/api/rp_settings.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class SettingsImpl final : public Settings +{ +public: + + SettingsImpl(); + + CountType getMaxFilesCount() const override; + void setMaxFilesCount( CountType _count ) override; + + CountType getMaxDetailsCount() const override; + void setMaxDetailsCount( CountType _count ) override; + + bool getShowStdFiles() const override; + void setShowStdFiles( bool _enable ) override; + + void copy( const Settings & _other ) override; + +private: + + CountType m_maxFilesCount; + CountType m_maxDetailsCount; + bool m_showStdFiles; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_file_sorter.cpp b/src/reporter/impl/tools/rp_file_sorter.cpp new file mode 100644 index 0000000..c2249c9 --- /dev/null +++ b/src/reporter/impl/tools/rp_file_sorter.cpp @@ -0,0 +1,37 @@ +#include "reporter/impl/tools/rp_file_sorter.hpp" + +#include "model_includes/api/mi_file.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +bool FileSorter::operator()( const File * _l, const File * _r ) const +{ + INTERNAL_CHECK_WARRING( _l ); + INTERNAL_CHECK_WARRING( _r ); + if( _l == nullptr || _r == nullptr ) + return false; + + return operator()( *_l, *_r ); +} + +//------------------------------------------------------------------------------ + +bool FileSorter::operator()( const File & _l, const File & _r ) const +{ + const auto lPath = _l.getPath(); + const auto rPath = _r.getPath(); + + return stdfs::less( lPath, rPath ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_file_sorter.hpp b/src/reporter/impl/tools/rp_file_sorter.hpp new file mode 100644 index 0000000..649ee7a --- /dev/null +++ b/src/reporter/impl/tools/rp_file_sorter.hpp @@ -0,0 +1,25 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace model_includes { + class File; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +struct FileSorter +{ + using File = model_includes::File; + + bool operator()( const File * _l, const File * _r ) const; + bool operator()( const File & _l, const File & _r ) const; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/impact_reporter/rp_file_info.cpp b/src/reporter/impl/tools/rp_file_with_count.cpp similarity index 64% rename from src/reporter/impl/impact_reporter/rp_file_info.cpp rename to src/reporter/impl/tools/rp_file_with_count.cpp index bf2a08a..476b7d3 100644 --- a/src/reporter/impl/impact_reporter/rp_file_info.cpp +++ b/src/reporter/impl/tools/rp_file_with_count.cpp @@ -1,4 +1,4 @@ -#include "reporter/impl/impact_reporter/rp_file_info.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" //------------------------------------------------------------------------------ @@ -6,27 +6,27 @@ namespace reporter { //------------------------------------------------------------------------------ -FileInfo::FileInfo( +FileWithCount::FileWithCount( const model_includes::File & _file, - CountType _includedByCount + CountType _count ) : m_file{ _file } - , m_includedByCount{ _includedByCount } + , m_count{ _count } { } //------------------------------------------------------------------------------ -const model_includes::File & FileInfo::getFile() const +const model_includes::File & FileWithCount::getFile() const { return m_file; } //------------------------------------------------------------------------------ -FileInfo::CountType FileInfo::getIncludedByCount() const +FileWithCount::CountType FileWithCount::getCount() const { - return m_includedByCount; + return m_count; } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/impact_reporter/rp_file_info.hpp b/src/reporter/impl/tools/rp_file_with_count.hpp similarity index 75% rename from src/reporter/impl/impact_reporter/rp_file_info.hpp rename to src/reporter/impl/tools/rp_file_with_count.hpp index 5c4c8c9..0f5d57b 100644 --- a/src/reporter/impl/impact_reporter/rp_file_info.hpp +++ b/src/reporter/impl/tools/rp_file_with_count.hpp @@ -14,28 +14,22 @@ namespace reporter { //------------------------------------------------------------------------------ -class FileInfo +class FileWithCount { public: using CountType = std::size_t; - FileInfo( - const model_includes::File & _file, - CountType _includedByCount - ); - -public: + FileWithCount( const model_includes::File & _file, CountType _count ); const model_includes::File & getFile() const; - - CountType getIncludedByCount() const; + CountType getCount() const; private: const model_includes::File & m_file; - const CountType m_includedByCount; + const CountType m_count; }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/tools/rp_file_with_count_container.cpp b/src/reporter/impl/tools/rp_file_with_count_container.cpp new file mode 100644 index 0000000..bc3b5e3 --- /dev/null +++ b/src/reporter/impl/tools/rp_file_with_count_container.cpp @@ -0,0 +1,76 @@ +#include "reporter/impl/tools/rp_file_with_count_container.hpp" + +#include "model_includes/api/mi_file.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +void FileWithCountContainer::insert( const FileWithCount & _file ) +{ + m_files.insert( _file ); +} + +//------------------------------------------------------------------------------ + +std::size_t FileWithCountContainer::getSize() const +{ + return m_files.size(); +} + +//------------------------------------------------------------------------------ + +bool FileWithCountContainer::isEmpty() const +{ + return m_files.empty(); +} + +//------------------------------------------------------------------------------ + +void FileWithCountContainer::resizeByLimit( std::size_t _limit ) +{ + if( _limit && m_files.size() >= _limit ) + { + auto it = m_files.begin(); + for( std::size_t i = 0; i < _limit; ++i ) + ++it; + + m_files.erase( it, m_files.end() ); + } +} + +//------------------------------------------------------------------------------ + +void FileWithCountContainer::forEachFile( FileCallback _callback ) const +{ + for( const FileWithCount & fileInfo : m_files ) + { + const File & file = fileInfo.getFile(); + if( !_callback( file ) ) + break; + } +} + +//------------------------------------------------------------------------------ + +FileWithCountContainer::Iterator +FileWithCountContainer::begin() const +{ + return m_files.begin(); +} + +//------------------------------------------------------------------------------ + +FileWithCountContainer::Iterator +FileWithCountContainer::end() const +{ + return m_files.end(); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_file_with_count_container.hpp b/src/reporter/impl/tools/rp_file_with_count_container.hpp new file mode 100644 index 0000000..0673b80 --- /dev/null +++ b/src/reporter/impl/tools/rp_file_with_count_container.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "reporter/impl/tools/rp_file_with_count.hpp" +#include "reporter/impl/tools/rp_file_with_count_sorter.hpp" + +#include +#include + +//------------------------------------------------------------------------------ + +namespace model_includes { + class File; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class FileWithCountContainer +{ +public: + + using File = model_includes::File; + using Files = std::set< FileWithCount, FileWithCountSorter >; + using FileCallback = stdfwd::function< bool ( const File & ) >; + using Iterator = Files::iterator; + + std::size_t getSize() const; + bool isEmpty() const; + + void insert( const FileWithCount & _file ); + void resizeByLimit( std::size_t _limit ); + + void forEachFile( FileCallback _callback ) const; + + Iterator begin() const; + Iterator end() const; + +private: + + Files m_files; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_file_with_count_sorter.cpp b/src/reporter/impl/tools/rp_file_with_count_sorter.cpp new file mode 100644 index 0000000..62c5f37 --- /dev/null +++ b/src/reporter/impl/tools/rp_file_with_count_sorter.cpp @@ -0,0 +1,30 @@ +#include "reporter/impl/tools/rp_file_with_count_sorter.hpp" + +#include "reporter/impl/tools/rp_file_with_count.hpp" +#include "reporter/impl/tools/rp_file_sorter.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +bool FileWithCountSorter::operator()( + const FileWithCount & _l, + const FileWithCount & _r +) const +{ + if( _l.getCount() != _r.getCount() ) + { + // max is first + return _l.getCount() > _r.getCount(); + } + else + { + return FileSorter()( _l.getFile(), _r.getFile() ); + } +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_file_with_count_sorter.hpp b/src/reporter/impl/tools/rp_file_with_count_sorter.hpp new file mode 100644 index 0000000..43a6423 --- /dev/null +++ b/src/reporter/impl/tools/rp_file_with_count_sorter.hpp @@ -0,0 +1,17 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace reporter { + class FileWithCount; + +//------------------------------------------------------------------------------ + +struct FileWithCountSorter +{ + bool operator()( const FileWithCount & _l, const FileWithCount & _r ) const; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp b/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp new file mode 100644 index 0000000..a113bce --- /dev/null +++ b/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp @@ -0,0 +1,41 @@ +#include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" + +#include "reporter/impl/tools/rp_file_sorter.hpp" + +#include "model_includes/api/mi_include.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +bool IncludesBySourceSorter::operator()( + const Include * _l, + const Include * _r +) const +{ + INTERNAL_CHECK_WARRING( _l ); + INTERNAL_CHECK_WARRING( _r ); + + if( _l == nullptr || _r == nullptr ) + return false; + + return operator()( *_l, *_r ); +} + +//------------------------------------------------------------------------------ + +bool IncludesBySourceSorter::operator()( + const Include & _l, + const Include & _r +) const +{ + return FileSorter()( _l.getSourceFile(), _r.getSourceFile() ); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_includes_by_source_sorter.hpp b/src/reporter/impl/tools/rp_includes_by_source_sorter.hpp new file mode 100644 index 0000000..4493db2 --- /dev/null +++ b/src/reporter/impl/tools/rp_includes_by_source_sorter.hpp @@ -0,0 +1,25 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace model_includes { + class Include; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +struct IncludesBySourceSorter +{ + using Include = model_includes::Include; + + bool operator()( const Include * _l, const Include * _r ) const; + bool operator()( const Include & _l, const Include & _r ) const; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp b/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp new file mode 100644 index 0000000..434f84c --- /dev/null +++ b/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp @@ -0,0 +1,59 @@ +#include "reporter/impl/tools/rp_sorted_files_by_name_container.hpp" + +#include "model_includes/api/mi_file.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +SortedFilesByNameContainer::SortedFilesByNameContainer() = default; + +//------------------------------------------------------------------------------ + +void SortedFilesByNameContainer::insert( const model_includes::File & _file ) +{ + m_files.insert( &_file ); +} + +//------------------------------------------------------------------------------ + +bool SortedFilesByNameContainer::isEmpty() const +{ + return m_files.empty(); +} + +//------------------------------------------------------------------------------ + +void SortedFilesByNameContainer::forEachFile( FileCallback _callback ) const +{ + for( const File * filePtr : m_files ) + { + if( !filePtr ) + { + INTERNAL_CHECK_WARRING( false ); + continue; + } + + if( !_callback( *filePtr ) ) + break; + } +} + +//------------------------------------------------------------------------------ + +std::size_t SortedFilesByNameContainer::getSize() const +{ + return m_files.size(); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp new file mode 100644 index 0000000..8d65f6d --- /dev/null +++ b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "reporter/impl/tools/rp_file_sorter.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace model_includes { + class File; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class SortedFilesByNameContainer +{ + +public: + + using File = model_includes::File; + using FileCallback = stdfwd::function< bool ( const File & ) >; + + SortedFilesByNameContainer(); + + void insert( const File & _file ); + bool isEmpty() const; + + void forEachFile( FileCallback _callback ) const; + + std::size_t getSize() const; + +private: + + using Path = stdfs::path; + + using FilesContainer = std::set< const File *, FileSorter >; + + FilesContainer m_files; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp new file mode 100644 index 0000000..71e93b0 --- /dev/null +++ b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp @@ -0,0 +1,58 @@ +#include "reporter/impl/tools/rp_sorted_includes_by_source_container.hpp" + +#include "model_includes/api/mi_include.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +void SortedIncludesBySourceContainer::insert( const Include & _include ) +{ + m_includes.insert( &_include ); +} + +//------------------------------------------------------------------------------ + +void SortedIncludesBySourceContainer::forEachInclude( + IncludeCallback _callback +) const +{ + for( const Include * include : m_includes ) + { + INTERNAL_CHECK_WARRING( include ); + if( !include ) + continue; + + if( !_callback( *include ) ) + break; + } +} + +//------------------------------------------------------------------------------ + +void SortedIncludesBySourceContainer::forEachSource( FileCallback _callback ) const +{ + forEachInclude( + [&]( const Include & _include ) + { + return _callback( _include.getSourceFile() ); + } + ); +} + +//------------------------------------------------------------------------------ + +std::size_t SortedIncludesBySourceContainer::getCount() const +{ + return m_includes.size(); +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp new file mode 100644 index 0000000..9d6c251 --- /dev/null +++ b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp @@ -0,0 +1,49 @@ +#pragma once + +#include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" + +#include + +#include + +//------------------------------------------------------------------------------ + +namespace model_includes { + class Include; + class File; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +class SortedIncludesBySourceContainer +{ + +public: + + using Include = model_includes::Include; + using IncludeCallback = std::function< bool ( const Include & ) >; + + using File = model_includes::File; + using FileCallback = std::function< bool ( const File & ) >; + + void insert( const Include & _include ); + + void forEachInclude( IncludeCallback _callback ) const; + void forEachSource( FileCallback _callback ) const; + + std::size_t getCount() const; + +private: + + using Includes = std::set< const Include *, IncludesBySourceSorter >; + + Includes m_includes; +}; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp new file mode 100644 index 0000000..328e8d3 --- /dev/null +++ b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp @@ -0,0 +1,127 @@ +#include "reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp" + +#include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/resources/rp_unincluded_report_resources.hpp" +#include "reporter/impl/tools/rp_sorted_files_by_name_container.hpp" + +#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/mi_file.hpp" + +#include +#include + +#include +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +UnincludedReporter::UnincludedReporter( SettingsPtr && _settingsPtr ) + : BaseClass{ std::move( _settingsPtr ) } +{ + +} + +//------------------------------------------------------------------------------ + +void UnincludedReporter::report( + const model_includes::Model & _model, + std::ostream & _stream +) +{ + FilesContainer files = collectFiles( _model ); + printFiles( files, _model.getProjectDir(), _stream ); +} + +//------------------------------------------------------------------------------ + +UnincludedReporter::FilesContainer UnincludedReporter::collectFiles( + const model_includes::Model & _model +) const +{ + FilesContainer files; + _model.forEachFile( [&]( const model_includes::File & _file ) + { + if( isHeader( _file ) && !_file.getIncludedByCount() ) + { + files.insert( _file ); + } + return true; + }); + + return files; +} + +//------------------------------------------------------------------------------ + +ReporterKind UnincludedReporter::getKind() const +{ + return ReporterKind::Unincluded; +} + +//------------------------------------------------------------------------------ + +bool UnincludedReporter::isHeader( const model_includes::File & _file ) const +{ + const std::string extensionStr =_file.getPath().extension().string(); + + if(extensionStr.empty()) + return true; + + if( extensionStr.size() > 1 ) + { + const bool result = extensionStr.at( 1 ) == 'h'; + return result; + } + return false; +} + +//------------------------------------------------------------------------------ + +void UnincludedReporter::printFiles( + const FilesContainer & _files, + const Path & _projectDir, + std::ostream & _stream +) const +{ + if( _files.isEmpty() ) + return; + + _stream << resources::unincluded_report::Header; + + CountType currentNumber = 1; + _files.forEachFile( + [&]( const model_includes::File & _file ) + { + if( isLimitFiles( currentNumber ) ) + { + const size_t filesCount = _files.getSize(); + printFileLimitLine( filesCount, _stream ); + return false; + } + + const std::string path = getPathWithoutProject( + _file.getPath(), + _projectDir + ); + + _stream << fmt::format( + resources::unincluded_report::LineForFileFmt, + currentNumber, + path + ); + + ++currentNumber; + + return true; + } + ); +} + +//------------------------------------------------------------------------------ + + +} diff --git a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp new file mode 100644 index 0000000..907e517 --- /dev/null +++ b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp @@ -0,0 +1,55 @@ +#pragma once + +#include "reporter/impl/rp_base_reporter_impl.hpp" + +#include + +//------------------------------------------------------------------------------ + +namespace model_includes { + class File; +} + +//------------------------------------------------------------------------------ + +namespace reporter { + class SortedFilesByNameContainer; + +//------------------------------------------------------------------------------ + +class UnincludedReporter final : public BaseReporterImpl +{ + + using BaseClass = BaseReporterImpl; + +public: + + explicit UnincludedReporter( SettingsPtr && _settingPtr ); + + void report( + const model_includes::Model & _model, + std::ostream & _stream + ) override; + + ReporterKind getKind() const override; + +private: + + using Path = stdfs::path; + + using FilesContainer = SortedFilesByNameContainer; + + FilesContainer collectFiles( const model_includes::Model & _model ) const; + bool isHeader( const model_includes::File & _file ) const; + + void printFiles( + const FilesContainer & _files, + const Path & _projectDir, + std::ostream & _stream + ) const; +}; + +//------------------------------------------------------------------------------ + +} + diff --git a/src/reporter/impl/rp_unresolved_reporter.cpp b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp similarity index 69% rename from src/reporter/impl/rp_unresolved_reporter.cpp rename to src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp index 2f33549..5ec150e 100644 --- a/src/reporter/impl/rp_unresolved_reporter.cpp +++ b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp @@ -1,9 +1,12 @@ -#include "reporter/impl/rp_unresolved_reporter.hpp" - -#include "reporter/resources/rp_unresolved_reporter_resources.hpp" -#include "reporter/resources/rp_report_resources.hpp" +#include "reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" +#include "reporter/resources/rp_report_resources.hpp" +#include "reporter/impl/tools/rp_file_sorter.hpp" +#include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" +#include "reporter/impl/tools/rp_file_with_count_container.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" #include "model_includes/api/mi_model.hpp" #include "model_includes/api/mi_file.hpp" @@ -27,36 +30,10 @@ namespace reporter { //------------------------------------------------------------------------------ -bool UnresolvedReporter::SourceOrder::operator()( - const model_includes::Include * _r, - const model_includes::Include * _l -) const +UnresolvedReporter::UnresolvedReporter( SettingsPtr && _settingsPtr ) + : BaseClass{ std::move( _settingsPtr ) } { - INTERNAL_CHECK_ERROR( _r ); - INTERNAL_CHECK_ERROR( _l ); - const model_includes::File & sourceRight = _r->getSourceFile(); - const model_includes::File & sourceLeft = _l->getSourceFile(); - - return sourceRight.getPath() < sourceLeft.getPath(); -} - -//------------------------------------------------------------------------------ -bool UnresolvedReporter::DestinationFileInfoorder::operator()( - const DestinationFileInfo & _r, - const DestinationFileInfo & _l -) const -{ - if( _r.m_count != _l.m_count ) - { - return _r.m_count > _l.m_count; - } - else - { - INTERNAL_CHECK_ERROR( _r.m_file ); - INTERNAL_CHECK_ERROR( _l.m_file ); - return _r.m_file->getPath() < _l.m_file->getPath(); - } } //------------------------------------------------------------------------------ @@ -122,11 +99,7 @@ UnresolvedReporter::DestinationFileByCount UnresolvedReporter::orderDestinationB const model_includes::File * destinationFile = pair.first; const auto & includes = pair.second; - auto pairInsert = result.insert( { destinationFile, includes.size() } ); - if( !pairInsert.second ) - { - INTERNAL_CHECK_WARRING( false ); - } + result.insert( { *destinationFile, includes.size() } ); } return result; } @@ -145,39 +118,34 @@ void UnresolvedReporter::report( if( _unorderedIncludesByDestination.empty() ) return; - _stream << resources::unresolved_reporter::Header; + _stream << resources::unresolved_report::Header; - size_t number = 1; - const size_t limit = getMaxFilesCount(); - for( const DestinationFileInfo & info : _destinationFileByCount ) + CountType currentNumber = 1; + for( const FileWithCount & info : _destinationFileByCount ) { - if( limit && number > limit ) + if( isLimitFiles( currentNumber ) ) { - const size_t detailsCount = _destinationFileByCount.size(); - _stream << fmt::format( resources::LimitLineFmt, limit, detailsCount ); + const size_t filesCount = _destinationFileByCount.getSize(); + printFileLimitLine( filesCount, _stream ); break; } - const File * destinationFilePtr = info.m_file; - INTERNAL_CHECK_WARRING( destinationFilePtr ); - if( !destinationFilePtr ) - continue; + const File & destinationFile = info.getFile(); - const File & destinationFile = *destinationFilePtr; + reportDestinationFile( destinationFile, currentNumber, _projectDir, _stream ); - reportDestinationFile( destinationFile, number, _projectDir, _stream ); - - if( !_unorderedIncludesByDestination.count( destinationFilePtr ) ) + if( !_unorderedIncludesByDestination.count( &destinationFile ) ) { INTERNAL_CHECK_WARRING( false ); continue; } const UnorderedIncludes & includes = - _unorderedIncludesByDestination.at( destinationFilePtr ); + _unorderedIncludesByDestination.at( &destinationFile ); reportSourceFiles( includes, _projectDir, _stream ); - ++number; + ++currentNumber; + } } @@ -196,7 +164,7 @@ void UnresolvedReporter::reportDestinationFile( INTERNAL_CHECK_WARRING( !destinationPath.empty() ); _stream << fmt::format( - resources::unresolved_reporter::UnresolvedDestinationFmt, + resources::unresolved_report::UnresolvedDestinationFmt, _number, destinationPath ); @@ -211,26 +179,21 @@ void UnresolvedReporter::reportSourceFiles( ) const { OrderedIncludes orderedIncludes{ _includes.begin(), _includes.end() }; - size_t number = 1; - const size_t limit = getMaxDetailsCount(); + CountType currentNumber = 1; for( const model_includes::Include * includePtr : orderedIncludes ) { - if( limit && number > limit ) + if( isLimitDetails( currentNumber ) ) { - _stream << fmt::format( - resources::LimitDetailLineFmt, - limit, - orderedIncludes.size() - ); + printDetailsLimitLine( orderedIncludes.size(), _stream ); break; } INTERNAL_CHECK_WARRING( includePtr ); if( !includePtr ) continue; - reportSourceFile( *includePtr, number, _projectDir, _stream ); + reportSourceFile( *includePtr, currentNumber, _projectDir, _stream ); - ++number; + ++currentNumber; } } @@ -245,7 +208,7 @@ void UnresolvedReporter::reportSourceFile( { using namespace model_includes; - _stream << resources::unresolved_reporter::Intend; + _stream << resources::unresolved_report::Intend; const File & sourceFile = _include.getSourceFile(); const IncludeLocation & location = _include.getLocation(); @@ -257,7 +220,7 @@ void UnresolvedReporter::reportSourceFile( INTERNAL_CHECK_WARRING( !sourcePath.empty() ); _stream << fmt::format( - resources::unresolved_reporter::UnresolvedSourceFmt, + resources::unresolved_report::UnresolvedSourceFmt, _number, sourcePath, line diff --git a/src/reporter/impl/rp_unresolved_reporter.hpp b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp similarity index 79% rename from src/reporter/impl/rp_unresolved_reporter.hpp rename to src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp index c512104..7820b60 100644 --- a/src/reporter/impl/rp_unresolved_reporter.hpp +++ b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp @@ -2,8 +2,6 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" -#include - //------------------------------------------------------------------------------ namespace model_includes { @@ -14,13 +12,19 @@ namespace model_includes { //------------------------------------------------------------------------------ namespace reporter { + struct IncludesBySourceSorter; + class FileWithCountContainer; //------------------------------------------------------------------------------ class UnresolvedReporter final : public BaseReporterImpl { + using BaseClass = BaseReporterImpl; + public: + explicit UnresolvedReporter( SettingsPtr && _settingsPtr ); + void report( const model_includes::Model & _model, std::ostream & _stream @@ -30,44 +34,17 @@ class UnresolvedReporter final : public BaseReporterImpl private: - class SourceOrder - { - public: - bool operator()( - const model_includes::Include * _r, - const model_includes::Include * _l - ) const; - }; - using UnorderedIncludes = stdfwd::vector< const model_includes::Include * >; using OrderedIncludes = stdfwd::set< const model_includes::Include *, - SourceOrder + IncludesBySourceSorter >; using UnorderedIncludesByDestination = stdfwd::unordered_map< const model_includes::File *, UnorderedIncludes >; - struct DestinationFileInfo - { - const model_includes::File * m_file; - std::size_t m_count; - }; - - class DestinationFileInfoorder - { - public: - bool operator()( - const DestinationFileInfo & _r, - const DestinationFileInfo & _l - ) const; - }; - - using DestinationFileByCount = stdfwd::set< - DestinationFileInfo, - DestinationFileInfoorder - >; + using DestinationFileByCount = FileWithCountContainer; void collectIncludes( const model_includes::Model & _model, diff --git a/src/reporter/resources/rp_different_type_report_resources.cpp b/src/reporter/resources/rp_different_type_report_resources.cpp new file mode 100644 index 0000000..952d2e8 --- /dev/null +++ b/src/reporter/resources/rp_different_type_report_resources.cpp @@ -0,0 +1,23 @@ +#include "reporter/resources/rp_different_type_report_resources.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter::resources::different_type_report { + +//------------------------------------------------------------------------------ + + const char * const Name = "different_type"; + + const char * const Header = + "Files that are included by different ways:\n"; + const char * const UserIncludeLabel = + "With double quotation marks ( #include \"...\" ) in files:\n"; + const char * const SystemIncludeLabel = + "With angle brackets ( #include <...> ) in files:\n"; + + const char * const FileFmt = "{}. {}\n"; + const char * const DetailFmt = "\t{}. {} line {}\n"; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_different_type_report_resources.hpp b/src/reporter/resources/rp_different_type_report_resources.hpp new file mode 100644 index 0000000..9889638 --- /dev/null +++ b/src/reporter/resources/rp_different_type_report_resources.hpp @@ -0,0 +1,20 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace reporter::resources::different_type_report { + +//------------------------------------------------------------------------------ + + extern const char * const Name; + + extern const char * const Header; + extern const char * const UserIncludeLabel; + extern const char * const SystemIncludeLabel; + + extern const char * const FileFmt; + extern const char * const DetailFmt; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_dump_resources.cpp b/src/reporter/resources/rp_dump_resources.cpp index e1715e7..c400454 100644 --- a/src/reporter/resources/rp_dump_resources.cpp +++ b/src/reporter/resources/rp_dump_resources.cpp @@ -6,6 +6,8 @@ namespace reporter::resources::dump_reporter { //------------------------------------------------------------------------------ + const char * const Name = "dump"; + const char * const Indent = "\t"; //------------------------------------------------------------------------------ diff --git a/src/reporter/resources/rp_dump_resources.hpp b/src/reporter/resources/rp_dump_resources.hpp index 8529e01..01edf98 100644 --- a/src/reporter/resources/rp_dump_resources.hpp +++ b/src/reporter/resources/rp_dump_resources.hpp @@ -6,6 +6,8 @@ namespace reporter::resources::dump_reporter { //------------------------------------------------------------------------------ + extern const char * const Name; + extern const char * const Indent; //------------------------------------------------------------------------------ diff --git a/src/reporter/resources/rp_most_impact_reporter_resources.cpp b/src/reporter/resources/rp_most_impact_report_resources.cpp similarity index 78% rename from src/reporter/resources/rp_most_impact_reporter_resources.cpp rename to src/reporter/resources/rp_most_impact_report_resources.cpp index e698bc0..7d19ac8 100644 --- a/src/reporter/resources/rp_most_impact_reporter_resources.cpp +++ b/src/reporter/resources/rp_most_impact_report_resources.cpp @@ -1,11 +1,13 @@ -#include "reporter/resources/rp_most_impact_reporter_resources.hpp" +#include "reporter/resources/rp_most_impact_report_resources.hpp" //------------------------------------------------------------------------------ -namespace reporter::resources::most_impact_reporter { +namespace reporter::resources::most_impact_report { //------------------------------------------------------------------------------ + const char * const Name = "most_impact"; + const char * const Header = "Most impact files:\n"; const char * const LineForFileFmt = "{} : \"{}\" impact on {} file(s)\n"; diff --git a/src/reporter/resources/rp_most_impact_reporter_resources.hpp b/src/reporter/resources/rp_most_impact_report_resources.hpp similarity index 84% rename from src/reporter/resources/rp_most_impact_reporter_resources.hpp rename to src/reporter/resources/rp_most_impact_report_resources.hpp index eaf26bf..be33381 100644 --- a/src/reporter/resources/rp_most_impact_reporter_resources.hpp +++ b/src/reporter/resources/rp_most_impact_report_resources.hpp @@ -2,10 +2,12 @@ //------------------------------------------------------------------------------ -namespace reporter::resources::most_impact_reporter { +namespace reporter::resources::most_impact_report { //------------------------------------------------------------------------------ + extern const char * const Name; + extern const char * const Header; extern const char * const LineForFileFmt; diff --git a/src/reporter/resources/rp_resources_exceptions.cpp b/src/reporter/resources/rp_resources_exceptions.cpp new file mode 100644 index 0000000..473bad6 --- /dev/null +++ b/src/reporter/resources/rp_resources_exceptions.cpp @@ -0,0 +1,22 @@ +#include "reporter/resources/rp_resources_exceptions.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter::resources::exceptions { + +//------------------------------------------------------------------------------ + + const char * const ModuleName = "REPORT"; + +//------------------------------------------------------------------------------ + +namespace IncorrectReport { + + const char * const Code = "INCORRECT_REPORT"; + const char * const MsgFmt = + "Incorrect report name: {}, possible names: {}"; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_resources_exceptions.hpp b/src/reporter/resources/rp_resources_exceptions.hpp new file mode 100644 index 0000000..0444285 --- /dev/null +++ b/src/reporter/resources/rp_resources_exceptions.hpp @@ -0,0 +1,21 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace reporter::resources::exceptions { + +//------------------------------------------------------------------------------ + + extern const char * const ModuleName; + +//------------------------------------------------------------------------------ + +namespace IncorrectReport { + + extern const char * const Code; + extern const char * const MsgFmt; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_unincluded_report_resources.cpp b/src/reporter/resources/rp_unincluded_report_resources.cpp new file mode 100644 index 0000000..c276fbf --- /dev/null +++ b/src/reporter/resources/rp_unincluded_report_resources.cpp @@ -0,0 +1,17 @@ +#include "reporter/resources/rp_unincluded_report_resources.hpp" + +//------------------------------------------------------------------------------ + +namespace reporter::resources::unincluded_report { + +//------------------------------------------------------------------------------ + + const char * const Name = "unincluded"; + + const char * const Header = "Unincluded headers:\n"; + + const char * const LineForFileFmt = "{} : \"{}\"\n"; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_unincluded_report_resources.hpp b/src/reporter/resources/rp_unincluded_report_resources.hpp new file mode 100644 index 0000000..8172557 --- /dev/null +++ b/src/reporter/resources/rp_unincluded_report_resources.hpp @@ -0,0 +1,17 @@ +#pragma once + +//------------------------------------------------------------------------------ + +namespace reporter::resources::unincluded_report { + +//------------------------------------------------------------------------------ + + extern const char * const Name; + + extern const char * const Header; + + extern const char * const LineForFileFmt; + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/resources/rp_unresolved_reporter_resources.cpp b/src/reporter/resources/rp_unresolved_report_resources.cpp similarity index 75% rename from src/reporter/resources/rp_unresolved_reporter_resources.cpp rename to src/reporter/resources/rp_unresolved_report_resources.cpp index 452123f..42fc00f 100644 --- a/src/reporter/resources/rp_unresolved_reporter_resources.cpp +++ b/src/reporter/resources/rp_unresolved_report_resources.cpp @@ -1,11 +1,13 @@ -#include "reporter/resources/rp_unresolved_reporter_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" //------------------------------------------------------------------------------ -namespace reporter::resources::unresolved_reporter { +namespace reporter::resources::unresolved_report { //------------------------------------------------------------------------------ + const char * const Name = "unresolved"; + const char * const Header = "Unresolved files:\n"; const char * const Intend = "\t"; diff --git a/src/reporter/resources/rp_unresolved_reporter_resources.hpp b/src/reporter/resources/rp_unresolved_report_resources.hpp similarity index 83% rename from src/reporter/resources/rp_unresolved_reporter_resources.hpp rename to src/reporter/resources/rp_unresolved_report_resources.hpp index 5d836a0..713498c 100644 --- a/src/reporter/resources/rp_unresolved_reporter_resources.hpp +++ b/src/reporter/resources/rp_unresolved_report_resources.hpp @@ -2,10 +2,12 @@ //------------------------------------------------------------------------------ -namespace reporter::resources::unresolved_reporter { +namespace reporter::resources::unresolved_report { //------------------------------------------------------------------------------ + extern const char * const Name; + extern const char * const Header; extern const char * const Intend; diff --git a/src/reporter/test/CMakeLists.txt b/src/reporter/test/CMakeLists.txt index d98b4c3..7510bc2 100644 --- a/src/reporter/test/CMakeLists.txt +++ b/src/reporter/test/CMakeLists.txt @@ -1,8 +1,4 @@ -file(GLOB_RECURSE all_sources - "*.cpp" - "fixtures/*.cpp" - "suits/*.cpp" -) +file(GLOB_RECURSE all_sources "*.cpp") add_executable(${PROJECT_NAME}_test ${all_sources}) diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp index 4dc9201..84cc9f8 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp @@ -4,6 +4,7 @@ #include "reporter/api/rp_factory.hpp" #include "reporter/api/rp_reporter.hpp" +#include "reporter/api/rp_settings.hpp" #include "model_includes/ih/mi_accessor_impl.hpp" #include "model_includes/api/mi_model.hpp" @@ -23,16 +24,7 @@ namespace reporter::test { //------------------------------------------------------------------------------ -ReporterFixture::ReporterFixture() - : m_maxFilesCount{ 0 } - , m_maxDetailsCount{ 0 } - , m_showStdFiles{ false } -{ - -} - -//------------------------------------------------------------------------------ - +ReporterFixture::ReporterFixture() = default; ReporterFixture::~ReporterFixture() = default; //------------------------------------------------------------------------------ @@ -54,6 +46,26 @@ void ReporterFixture::addInclude( //------------------------------------------------------------------------------ +void ReporterFixture::addUserInclude( + std::string_view _sourceFile, + std::string_view _destinationFile +) +{ + addInclude( _sourceFile, _destinationFile, IncludeType::User ); +} + +//------------------------------------------------------------------------------ + +void ReporterFixture::addSystemInclude( + std::string_view _sourceFile, + std::string_view _destinationFile +) +{ + addInclude( _sourceFile, _destinationFile, IncludeType::System ); +} + +//------------------------------------------------------------------------------ + void ReporterFixture::addInclude( std::string_view _sourceFile, std::string_view _destinationFile, @@ -91,23 +103,30 @@ void ReporterFixture::setProjectDir( std::string_view _dir ) //------------------------------------------------------------------------------ +ReporterFixture::Path ReporterFixture::getProjectDir() +{ + return getModel().getProjectDir(); +} + +//------------------------------------------------------------------------------ + void ReporterFixture::setMaxFilesCount( int _count ) { - m_maxFilesCount = _count; + ensureSettings().setMaxFilesCount( _count ); } //------------------------------------------------------------------------------ void ReporterFixture::setMaxDetailsCount( int _count ) { - m_maxDetailsCount = _count; + ensureSettings().setMaxDetailsCount( _count ); } //------------------------------------------------------------------------------ -void ReporterFixture::setShowStdFile( bool _enable ) +void ReporterFixture::setShowStdFiles( bool _enable ) { - m_showStdFiles = _enable; + ensureSettings().setShowStdFiles( _enable ); } //------------------------------------------------------------------------------ @@ -139,6 +158,24 @@ std::string ReporterFixture::runMostImpactReporter() //------------------------------------------------------------------------------ +std::string ReporterFixture::runUnincludedReporter() +{ + auto reporterPtr = getFactory().createUnincludedReporter(); + INTERNAL_CHECK_ERROR( reporterPtr ); + return runReporter( *reporterPtr ); +} + +//------------------------------------------------------------------------------ + +std::string ReporterFixture::runDifferentTypeReport() +{ + auto reporterPtr = getFactory().createDifferentTypeReporter(); + INTERNAL_CHECK_ERROR( reporterPtr ); + return runReporter( *reporterPtr ); +} + +//------------------------------------------------------------------------------ + model_includes::File & ReporterFixture::addFile( std::string_view _file, FileType _type @@ -149,6 +186,16 @@ model_includes::File & ReporterFixture::addFile( //------------------------------------------------------------------------------ +model_includes::File & ReporterFixture::addFileToProject( + std::string_view _file +) +{ + Path filePah = getProjectDir() / _file; + return addFile( filePah.string() ); +} + +//------------------------------------------------------------------------------ + std::string ReporterFixture::toPath( std::string_view _str ) { return tools::toPath( std::string{ _str } ); @@ -156,14 +203,13 @@ std::string ReporterFixture::toPath( std::string_view _str ) //------------------------------------------------------------------------------ -std::string ReporterFixture::runReporter( Reporter & _reporter) +std::string ReporterFixture::runReporter( Reporter & _reporter ) { std::stringstream stream; const model_includes::Model & model = getModel(); - _reporter.setMaxFilesCount( m_maxFilesCount ); - _reporter.setMaxDetailsCount( m_maxDetailsCount ); - _reporter.setShowStdFile( m_showStdFiles ); + const Settings & settings = ensureSettings(); + _reporter.copySettings( settings ); _reporter.report( model, stream ); return stream.str(); @@ -171,7 +217,7 @@ std::string ReporterFixture::runReporter( Reporter & _reporter) //------------------------------------------------------------------------------ -ReporterAccessor & ReporterFixture::getAccessor() +ReporterAccessor & ReporterFixture::ensureReportAccessor() { if( !m_accessor ) m_accessor.reset( new ReporterAccessorImpl ); @@ -183,7 +229,20 @@ ReporterAccessor & ReporterFixture::getAccessor() Factory & ReporterFixture::getFactory() { - return getAccessor().getReporterFactory(); + return ensureReportAccessor().getReporterFactory(); +} + +//------------------------------------------------------------------------------ + +Settings & ReporterFixture::ensureSettings() +{ + if( !m_settings ) + { + auto newSettings = getFactory().createSettings(); + m_settings.swap( newSettings ); + } + + return *m_settings; } //------------------------------------------------------------------------------ diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp index 9e803d9..51ce94b 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp @@ -21,6 +21,7 @@ namespace reporter { class ReporterAccessor; class Factory; class Reporter; + class Settings; } //------------------------------------------------------------------------------ @@ -39,6 +40,7 @@ class ReporterFixture using IncludeStatus = model_includes::IncludeStatus; using IncludeType = model_includes::IncludeType; using FileType = model_includes::FileType; + using Path = stdfs::path; struct LocationInfo { @@ -52,7 +54,14 @@ class ReporterFixture std::string_view _destinationFile, IncludeType _type ); - + void addUserInclude( + std::string_view _sourceFile, + std::string_view _destinationFile + ); + void addSystemInclude( + std::string_view _sourceFile, + std::string_view _destinationFile + ); void addInclude( std::string_view _sourceFile, std::string_view _destinationFile, @@ -63,25 +72,31 @@ class ReporterFixture void setMaxFilesCount( int _count ); void setMaxDetailsCount( int _count ); - void setShowStdFile( bool _enable ); + void setShowStdFiles( bool _enable ); void setProjectDir( std::string_view _dir ); + Path getProjectDir(); std::string runDumpReporter(); std::string runUnresolvedReporter(); std::string runMostImpactReporter(); + std::string runUnincludedReporter(); + std::string runDifferentTypeReport(); model_includes::File & addFile( std::string_view _file, model_includes::FileType _type = FileType::ProjectFile ); + model_includes::File & addFileToProject( std::string_view _file ); + static std::string toPath( std::string_view _str ); private: - ReporterAccessor & getAccessor(); + ReporterAccessor & ensureReportAccessor(); Factory & getFactory(); + Settings & ensureSettings(); std::string runReporter( Reporter & _reporter ); @@ -90,11 +105,8 @@ class ReporterFixture private: - int m_maxFilesCount; - int m_maxDetailsCount; - bool m_showStdFiles; - std::unique_ptr< ReporterAccessor > m_accessor; + std::unique_ptr< Settings > m_settings; std::unique_ptr< model_includes::ModelIncludesAccessor > m_modelAccessor; std::unique_ptr< model_includes::Model > m_model; }; diff --git a/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp new file mode 100644 index 0000000..b08f437 --- /dev/null +++ b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp @@ -0,0 +1,238 @@ +#include "reporter/test/fixture/rp_test_reporter_fixture.hpp" + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN: +1. Empty +2. One include +3. Several includes with same type + 3.1 user type + 3.2 system type +4. Several includes with different types + 4.1 system and user + 4.2 std + 4.3 hide std +5. Limits + 5.1 max files + 5.2 max details + +------------------------------------------------------------------------------*/ + +namespace reporter::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(DifferentTypeReporterTests, ReporterFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_empty) +{ + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_one_include) +{ + // Init + addInclude( "/test_project/main.cpp", "/test_project/header.hpp" ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_1_several_includes_with_user_type) +{ + // Init + addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); + addUserInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_2_several_includes_with_system_type) +{ + // Init + addSystemInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_1_several_includes_system_and_user) +{ + // Init + setProjectDir( "/test_project/" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Files that are included by different ways:\n" + "1. header.hpp\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file2.cpp line 1\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_2_several_includes_std) +{ + // Init + setProjectDir( "/test_project/" ); + + addFile( "vector", model_includes::FileType::StdLibraryFile ); + + addUserInclude( "/test_project/file1.cpp", "vector" ); + addSystemInclude( "/test_project/file2.cpp", "vector" ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Files that are included by different ways:\n" + "1. vector\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file2.cpp line 1\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_3_several_includes_hide_std) +{ + // Init + setProjectDir( "/test_project/" ); + + addFile( "vector", model_includes::FileType::StdLibraryFile ); + + addUserInclude( "/test_project/file1.cpp", "vector" ); + addSystemInclude( "/test_project/file2.cpp", "vector" ); + + setShowStdFiles( false ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_1_limit_max_files) +{ + // Init + setProjectDir( "/test_project/" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); + + setMaxFilesCount( 1 ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Files that are included by different ways:\n" + "1. header1.hpp\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file2.cpp line 1\n" + "... 1 of 2 files\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_2_limit_max_details) +{ + // Init + setProjectDir( "/test_project/" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); + addUserInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file3.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file4.cpp", "/test_project/header1.hpp" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); + addUserInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file3.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file4.cpp", "/test_project/header2.hpp" ); + + + setMaxDetailsCount( 1 ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Files that are included by different ways:\n" + "1. header1.hpp\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "\t... 1 of 2 details\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file3.cpp line 1\n" + "\t... 1 of 2 details\n" + "2. header2.hpp\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "\t... 1 of 2 details\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file3.cpp line 1\n" + "\t... 1 of 2 details\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp index aa0dbab..17d69b6 100644 --- a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp @@ -20,6 +20,9 @@ TEST PLAN: 7. Std Files 7.1 Don't show 7.2 Show +8. Files out of project + 8.1 in sub directory + 8.2 in other directory ------------------------------------------------------------------------------*/ @@ -419,7 +422,7 @@ BOOST_AUTO_TEST_CASE(t7_1_std_file_dont_show) addInclude( runB1file, classBFile ); - setShowStdFile( false ); + setShowStdFiles( false ); // Run std::string result = runMostImpactReporter(); @@ -463,7 +466,7 @@ BOOST_AUTO_TEST_CASE(t7_2_std_file_show) addInclude( runB1file, classBFile ); - setShowStdFile( true ); + setShowStdFiles( true ); // Run std::string result = runMostImpactReporter(); @@ -488,6 +491,96 @@ BOOST_AUTO_TEST_CASE(t7_2_std_file_show) //------------------------------------------------------------------------------ +BOOST_AUTO_TEST_CASE(t8_1_files_out_of_project_in_subdir) +{ + // Init + const std::string projectDir = "/test_project/"; + const std::string subdir = "build/"; + + const std::string classAFileName = "classA.hpp"; + const std::string classAFile = projectDir + classAFileName; + const std::string classBFileName = "classB.hpp"; + const std::string classBFile = projectDir + classBFileName; + + const std::string runA1fileName = "runA1.cpp"; + const std::string runA1file = projectDir + runA1fileName; + const std::string runA2fileName = "runA2.cpp"; + const std::string runA2file = projectDir + runA2fileName; + + const std::string runB1fileName = "runB1.cpp"; + const std::string runB1file = projectDir + runB1fileName; + + setProjectDir( projectDir + subdir ); + + addInclude( runA1file, classAFile ); + addInclude( runA2file, classAFile ); + + addInclude( runB1file, classBFile ); + + // Run + std::string result = runMostImpactReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Most impact files:\n" + "1 : \"" + toPath( "../" + classAFileName ) + "\" impact on 2 file(s)\n" + "Included by:\n" + "\t1 : \"" + toPath( "../" + runA1fileName ) + "\" line 1\n" + "\t2 : \"" + toPath( "../" + runA2fileName ) + "\" line 1\n" + "2 : \"" + toPath( "../" + classBFileName ) + "\" impact on 1 file(s)\n" + "Included by:\n" + "\t1 : \"" + toPath( "../" + runB1fileName ) +"\" line 1\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t8_2_files_out_of_project_in_other_dir) +{ + // Init + const std::string projectDir = "/test_project/"; + const std::string otherDir = "/tmp/"; + + const std::string classAFileName = "classA.hpp"; + const std::string classAFile = otherDir + classAFileName; + const std::string classBFileName = "classB.hpp"; + const std::string classBFile = otherDir + classBFileName; + + const std::string runA1fileName = "runA1.cpp"; + const std::string runA1file = projectDir + runA1fileName; + const std::string runA2fileName = "runA2.cpp"; + const std::string runA2file = projectDir + runA2fileName; + + const std::string runB1fileName = "runB1.cpp"; + const std::string runB1file = projectDir + runB1fileName; + + setProjectDir( projectDir ); + + addInclude( runA1file, classAFile ); + addInclude( runA2file, classAFile ); + + addInclude( runB1file, classBFile ); + + // Run + std::string result = runMostImpactReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Most impact files:\n" + "1 : \"" + toPath( classAFile ) + "\" impact on 2 file(s)\n" + "Included by:\n" + "\t1 : \"" + toPath( runA1fileName ) + "\" line 1\n" + "\t2 : \"" + toPath( runA2fileName ) + "\" line 1\n" + "2 : \"" + toPath( classBFile ) + "\" impact on 1 file(s)\n" + "Included by:\n" + "\t1 : \"" + toPath( runB1fileName ) +"\" line 1\n" + ); +} + +//------------------------------------------------------------------------------ + BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp new file mode 100644 index 0000000..bea461c --- /dev/null +++ b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp @@ -0,0 +1,204 @@ +#include "reporter/test/fixture/rp_test_reporter_fixture.hpp" + +#include + +/*------------------------------------------------------------------------------ + +TEST PLAN: +1. Empty +2. One header +3. Several header +4. Extension + 4.1 hpp + 4.2 h + 4.3 Mix extensions + 4.4 empty +5. Limit + +------------------------------------------------------------------------------*/ + +namespace reporter::test { + +//------------------------------------------------------------------------------ + +BOOST_FIXTURE_TEST_SUITE(UnincludedReporterTests, ReporterFixture) + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t1_empty) +{ + // Init + addInclude( "/test_project/main.cpp", "/test_project/classA.hpp" ); + addInclude( "/test_project/main.cpp", "/test_project/classB.hpp" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( result, "" ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t2_one_header) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "header.hpp" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"header.hpp\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t3_several_headers) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "classA.hpp" ); + addFileToProject( "classB.hpp" ); + addFileToProject( "classC.hpp" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"classA.hpp\"\n" + "2 : \"classB.hpp\"\n" + "3 : \"classC.hpp\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_1_extension_hpp) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "classA.hpp" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"classA.hpp\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_2_extension_h) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "classA.h" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"classA.h\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_3_mix_extensions) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "classA.h" ); + addFileToProject( "classB.hpp" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"classA.h\"\n" + "2 : \"classB.hpp\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t4_4_empty_extension) +{ + // Init + addFileToProject( "main.cpp" ); + addFileToProject( "header" ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"header\"\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE(t5_limit) +{ + // Init + setProjectDir( "/tmp/" ); + + addFileToProject( "main.cpp" ); + addFileToProject( "classA.hpp" ); + addFileToProject( "classB.hpp" ); + addFileToProject( "classC.hpp" ); + + setMaxFilesCount( 2 ); + + // Run + std::string result = runUnincludedReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Unincluded headers:\n" + "1 : \"classA.hpp\"\n" + "2 : \"classB.hpp\"\n" + "... 2 of 3 files\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/tools/rp_reporter_kind_functins.cpp b/src/reporter/tools/rp_reporter_kind_functins.cpp new file mode 100644 index 0000000..4910293 --- /dev/null +++ b/src/reporter/tools/rp_reporter_kind_functins.cpp @@ -0,0 +1,75 @@ +#include "reporter/tools/rp_reporter_kind_functins.hpp" + +#include "reporter/api/enums/rp_reporter_kind.hpp" + +#include "reporter/resources/rp_most_impact_report_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" +#include "reporter/resources/rp_unincluded_report_resources.hpp" +#include "reporter/resources/rp_dump_resources.hpp" +#include "reporter/resources/rp_different_type_report_resources.hpp" + +#include "reporter/exceptions/rp_incorrect_report_impl.hpp" + +#include "exception/ih/exc_internal_error.hpp" + +#include +#include +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +ReporterKind toReporterKind( std::string_view _str ) +{ + using namespace resources; + + static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + + static std::unordered_map< std::string, reporter::ReporterKind > names{ + { unresolved_report::Name, ReporterKind::Unresolved }, + { most_impact_report::Name, ReporterKind::MostImpact }, + { unincluded_report::Name, ReporterKind::Unincluded}, + { dump_reporter::Name, ReporterKind::Dump }, + { different_type_report::Name, ReporterKind::DifferentType }, + }; + + const std::string str{ _str }; + if( !names.count( str ) ) + { + throw IncorrectReportImpl( str ); + } + + return names[ str ]; +} + +//------------------------------------------------------------------------------ + +std::string reporterKindToString( ReporterKind _kind ) +{ + using namespace resources; + + static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + + switch( _kind ) + { + case ReporterKind::MostImpact : return most_impact_report::Name; + case ReporterKind::Unresolved : return unresolved_report::Name; + case ReporterKind::Dump : return dump_reporter::Name; + case ReporterKind::Unincluded : return unincluded_report::Name; + case ReporterKind::DifferentType: return different_type_report::Name; + case ReporterKind::Count : + { + INTERNAL_CHECK_WARRING( false ); + return ""; + } + } + INTERNAL_CHECK_WARRING( false ); + return ""; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/reporter/tools/rp_reporter_kind_functins.hpp b/src/reporter/tools/rp_reporter_kind_functins.hpp new file mode 100644 index 0000000..9807ca7 --- /dev/null +++ b/src/reporter/tools/rp_reporter_kind_functins.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace reporter { + +//------------------------------------------------------------------------------ + +enum class ReporterKind; + +//------------------------------------------------------------------------------ + +ReporterKind toReporterKind( std::string_view _str ); +std::string reporterKindToString( ReporterKind _kind ); + +//------------------------------------------------------------------------------ + +} diff --git a/src/test_tools/CMakeLists.txt b/src/test_tools/CMakeLists.txt index 1ab39b1..359202c 100644 --- a/src/test_tools/CMakeLists.txt +++ b/src/test_tools/CMakeLists.txt @@ -1,7 +1,7 @@ project(test_tools) -find_package (Boost COMPONENTS unit_test_framework REQUIRED) +find_package(Boost COMPONENTS unit_test_framework REQUIRED) include_directories(. ${Boost_INCLUDE_DIRS}) -file(GLOB all_sources "*.cpp" ) -add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) +file(GLOB_RECURSE all_sources "*.cpp") +add_library(${PROJECT_NAME}_lib STATIC ${all_sources}) diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt index e6fa473..7962223 100644 --- a/src/tools/CMakeLists.txt +++ b/src/tools/CMakeLists.txt @@ -1,4 +1,4 @@ project(tools) -file(GLOB all_sources "*.cpp" ) +file(GLOB_RECURSE all_sources "*.cpp") add_library( ${PROJECT_NAME}_lib STATIC ${all_sources} ) diff --git a/src/tools/regex.cpp b/src/tools/regex.cpp new file mode 100644 index 0000000..f13665d --- /dev/null +++ b/src/tools/regex.cpp @@ -0,0 +1,41 @@ +#include "tools/regex.hpp" + +//------------------------------------------------------------------------------ + +namespace tools { + +//------------------------------------------------------------------------------ + +Regex::Regex( const std::string & _str ) + : m_regex{ _str } + , m_str{ _str } +{ + +} + +//------------------------------------------------------------------------------ + +Regex::Regex( const Regex & _other ) + : m_regex{ _other.m_regex } + , m_str{ _other.m_str } +{ + +} + +//------------------------------------------------------------------------------ + +bool Regex::search( const std::string & _str ) const +{ + return std::regex_search( _str, m_regex ); +} + +//------------------------------------------------------------------------------ + +const std::string & Regex::toString() const +{ + return m_str; +} + +//------------------------------------------------------------------------------ + +} diff --git a/src/tools/regex.hpp b/src/tools/regex.hpp new file mode 100644 index 0000000..d2ca623 --- /dev/null +++ b/src/tools/regex.hpp @@ -0,0 +1,31 @@ +#pragma once + +#include + +//------------------------------------------------------------------------------ + +namespace tools { + +//------------------------------------------------------------------------------ + +class Regex +{ +public: + + explicit Regex( const std::string & _str ); + Regex( const Regex & _other ); + + bool search( const std::string & _str ) const; + + const std::string & toString() const; + +private: + + const std::regex m_regex; + const std::string m_str; + +}; + +//------------------------------------------------------------------------------ + +} From 77e39174e25bb5119e3f012874edc2a70fcbb23f Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Mon, 22 Mar 2021 03:48:46 +0200 Subject: [PATCH 2/6] Public version 0.3.1 --- .clang-format | 49 ++ .clang-tidy | 49 ++ .cspell.json | 6 +- .gitlab-ci.yml | 54 +- CHANGELOG.md | 6 + CMakeLists.txt | 68 ++ build.bat | 7 +- build.sh | 4 +- check_code_style.sh | 14 + docs/examples/llvm-project/output_unix.txt | 70 +- docs/examples/simple_example/base_char.hpp | 1 - .../simple_example/base_char_factory.hpp | 1 - docs/examples/simple_example/char_a.hpp | 1 - .../simple_example/char_a_factory.hpp | 1 - docs/examples/simple_example/char_b.hpp | 1 - .../simple_example/char_b_factory.cpp | 1 - .../simple_example/char_b_factory.hpp | 1 - docs/examples/simple_example/main.cpp | 14 +- .../simple_example_cmake/base_char.hpp | 1 - .../base_char_factory.hpp | 1 - docs/examples/simple_example_cmake/char_a.hpp | 1 - .../simple_example_cmake/char_a_factory.hpp | 1 - docs/examples/simple_example_cmake/char_b.hpp | 1 - .../simple_example_cmake/char_b_factory.cpp | 1 - .../simple_example_cmake/char_b_factory.hpp | 1 - docs/examples/simple_example_cmake/main.cpp | 14 +- .../base_char.hpp | 1 - .../base_char_factory.hpp | 1 - .../char_a.hpp | 1 - .../char_a_factory.hpp | 1 - .../char_b.hpp | 1 - .../char_b_factory.cpp | 1 - .../char_b_factory.hpp | 1 - .../main.cpp | 14 +- .../base_char.hpp | 1 - .../base_char_factory.hpp | 1 - .../char_a.hpp | 1 - .../char_a_factory.hpp | 1 - .../char_b.hpp | 1 - .../char_b_factory.cpp | 1 - .../char_b_factory.hpp | 1 - .../main.cpp | 16 +- .../lib/a/char_a.hpp | 1 - .../lib/a/char_a_factory.hpp | 1 - .../lib/b/char_b.hpp | 1 - .../lib/b/char_b_factory.cpp | 1 - .../lib/b/char_b_factory.hpp | 1 - .../lib/base/base_char.hpp | 1 - .../lib/base/base_char_factory.hpp | 1 - .../main.cpp | 14 +- .../base_char.hpp | 1 - .../base_char_factory.hpp | 1 - .../char_a.hpp | 1 - .../char_a_factory.hpp | 1 - .../char_b.hpp | 1 - .../char_b_factory.cpp | 1 - .../char_b_factory.hpp | 1 - .../main.cpp | 14 +- docs/versions/VERSION_0.3.1.md | 19 + src/3rd-part/cxxopts/include/cxxopts.hpp | 2 + src/3rd-part/fmt/src/format.cc | 44 +- src/3rd-part/fmt/src/posix.cc | 58 +- src/3rd-part/std_fs/include/std_fs | 393 +++++---- src/CMakeLists.txt | 56 -- src/application/app_con.cpp | 52 +- src/application/app_con.hpp | 3 - .../exceptions/app_base_exception_impl.hpp | 11 +- .../app_base_exception_with_message_impl.hpp | 7 +- .../exceptions/app_cant_create_analyzer.cpp | 5 +- .../exceptions/app_cant_create_analyzer.hpp | 11 +- .../exceptions/app_cant_create_model_impl.cpp | 5 +- .../exceptions/app_cant_create_model_impl.hpp | 7 +- .../app_cant_create_project_impl.cpp | 5 +- .../app_cant_create_project_impl.hpp | 7 +- .../app_cant_create_report_impl.cpp | 7 +- .../app_cant_create_report_impl.hpp | 9 +- .../app_cant_load_reporter_settings.cpp | 5 +- .../app_cant_load_reporter_settings.hpp | 7 +- src/application/exceptions/app_exceptions.hpp | 4 +- .../resources/app_resources_arguments.cpp | 32 +- .../resources/app_resources_version.cpp | 2 +- src/application/test/app_test_main.cpp | 6 +- ...app_test_cmake_project_builder_fixture.cpp | 55 +- ...app_test_cmake_project_builder_fixture.hpp | 4 - .../app_test_configuration_file_fixture.cpp | 18 +- .../app_test_configuration_file_fixture.hpp | 4 +- .../test/fixtures/app_test_parser_fixture.cpp | 22 +- .../test/fixtures/app_test_parser_fixture.hpp | 6 +- .../app_test_parser_wrapper_fixture.cpp | 160 ++-- .../app_test_parser_wrapper_fixture.hpp | 46 +- .../app_test_project_builder_fixture.cpp | 39 +- .../app_test_project_builder_fixture.hpp | 7 +- ...pp_test_report_settings_loader_fixture.cpp | 30 +- ...pp_test_report_settings_loader_fixture.hpp | 8 +- .../suits/app_test_cmake_project_builder.cpp | 82 +- .../app_test_configuration_file_suits.cpp | 100 +-- .../test/suits/app_test_parser_arguments.cpp | 137 ++- ...pp_test_parser_arguments_wrapper_suits.cpp | 186 ++-- .../test/suits/app_test_project_builder.cpp | 114 +-- .../suits/app_test_report_settings_loader.cpp | 87 +- src/application/tools/app_argument.cpp | 10 +- src/application/tools/app_argument.hpp | 22 +- .../tools/app_cmake_project_builder.cpp | 23 +- .../tools/app_cmake_project_builder.hpp | 3 - .../tools/app_configuration_file.cpp | 27 +- .../tools/app_configuration_file.hpp | 6 +- .../tools/app_configuration_file_loader.cpp | 19 +- .../tools/app_configuration_file_loader.hpp | 1 - src/application/tools/app_log.cpp | 2 - src/application/tools/app_log.hpp | 4 +- src/application/tools/app_parser_arg.cpp | 40 +- src/application/tools/app_parser_arg.hpp | 12 +- .../tools/app_parser_arg_wrapper.cpp | 59 +- .../tools/app_parser_arg_wrapper.hpp | 4 +- src/application/tools/app_plugin_ptr.hpp | 8 +- src/application/tools/app_project_builder.cpp | 36 +- src/application/tools/app_project_builder.hpp | 6 +- .../tools/app_report_settings_loader.cpp | 22 +- .../tools/app_report_settings_loader.hpp | 7 +- src/cmake_project/api/cprj_loader.hpp | 2 - src/cmake_project/api/cprj_project.hpp | 1 - src/cmake_project/ih/cprj_accessor.hpp | 2 - src/cmake_project/ih/cprj_accessor_impl.hpp | 1 - .../impl/cprj_includes_parser.cpp | 29 +- .../impl/cprj_includes_parser.hpp | 1 - .../impl/cprj_includes_parser_context.cpp | 1 - .../impl/cprj_includes_parser_context.hpp | 6 +- src/cmake_project/impl/cprj_loader_impl.cpp | 11 +- src/cmake_project/impl/cprj_loader_impl.hpp | 6 +- src/cmake_project/impl/cprj_project_impl.cpp | 16 +- src/cmake_project/impl/cprj_project_impl.hpp | 5 +- src/cmake_project/test/cprj_test_main.cpp | 6 +- .../cprj_test_includes_parser_fixture.cpp | 8 +- .../cprj_test_includes_parser_fixture.hpp | 5 +- .../fixtures/cprj_test_loader_fixture.cpp | 20 +- .../fixtures/cprj_test_loader_fixture.hpp | 4 - .../test/suits/cprj_test_includes_parser.cpp | 85 +- .../test/suits/cprj_test_loader.cpp | 46 +- src/compilation_db/api/cdb_command_object.hpp | 1 + src/compilation_db/api/cdb_database.hpp | 1 - src/compilation_db/api/cdb_loader.hpp | 1 - src/compilation_db/ih/cdb_accessor.hpp | 1 - src/compilation_db/ih/cdb_accessor_impl.hpp | 1 - .../impl/cdb_command_object_impl.cpp | 1 - .../impl/cdb_command_object_impl.hpp | 2 - src/compilation_db/impl/cdb_database_impl.hpp | 5 +- src/compilation_db/impl/cdb_loader_impl.cpp | 4 +- src/compilation_db/impl/cdb_loader_impl.hpp | 2 - src/compilation_db/test/cdb_test_main.cpp | 5 +- .../test/fixtures/cdb_test_fixture.cpp | 12 +- .../test/fixtures/cdb_test_fixture.hpp | 3 - .../test/suits/cdb_test_suits.cpp | 14 +- src/exception/api/exc_exception.hpp | 4 +- src/exception/ih/exc_exception_impl.hpp | 7 +- .../ih/exc_exception_with_message_impl.hpp | 3 - src/exception/ih/exc_internal_error.hpp | 23 +- src/fs/api/enums/fs_item_type.hpp | 1 - src/fs/api/fs_factory.hpp | 1 - src/fs/api/fs_file.hpp | 1 - src/fs/ih/fs_accessor.hpp | 2 - src/fs/ih/fs_accessor_impl.cpp | 6 +- src/fs/ih/fs_accessor_impl.hpp | 3 - .../exceptions/fs_base_exception_impl.hpp | 3 +- .../fs_exception_cant_create_file.cpp | 5 +- .../fs_exception_cant_create_file.hpp | 4 +- .../fs_exception_cant_open_file_impl.cpp | 5 +- .../fs_exception_cant_open_file_impl.hpp | 4 +- .../fs_exception_checking_exist_file_fail.cpp | 5 +- .../fs_exception_checking_exist_file_fail.hpp | 7 +- src/fs/impl/fs_factory_impl.cpp | 8 +- src/fs/impl/fs_factory_impl.hpp | 2 - src/fs/impl/memory/fs_memory_file.cpp | 2 +- src/fs/impl/memory/fs_memory_file.hpp | 3 - src/fs/impl/memory/fs_memory_file_system.cpp | 28 +- src/fs/impl/memory/fs_memory_file_system.hpp | 5 +- src/fs/impl/memory/fs_memory_folder.cpp | 19 +- src/fs/impl/memory/fs_memory_folder.hpp | 6 +- src/fs/impl/physical/fs_physical_file.cpp | 2 +- src/fs/impl/physical/fs_physical_file.hpp | 4 - .../impl/physical/fs_physical_file_system.cpp | 10 +- .../impl/physical/fs_physical_file_system.hpp | 2 - src/json/api/json_object.hpp | 1 - src/json/ih/json_accessor.hpp | 1 - src/json/ih/json_accessor_impl.hpp | 1 - src/json/impl/json_array_impl.cpp | 2 +- src/json/impl/json_array_impl.hpp | 2 - src/json/impl/json_object_impl.cpp | 6 +- src/json/impl/json_object_impl.hpp | 3 - src/json/impl/json_value_impl.cpp | 6 +- src/json/impl/json_value_impl.hpp | 3 - src/json/test/fixtures/json_test_fixture.cpp | 4 +- src/json/test/fixtures/json_test_fixture.hpp | 7 +- src/json/test/json_test_main.cpp | 5 +- src/json/test/suits/json_test_suits.cpp | 176 ++-- src/main.cpp | 4 +- src/model_includes/api/mi_analyzer.hpp | 3 +- src/model_includes/api/mi_file.hpp | 1 - src/model_includes/api/mi_include.hpp | 1 - .../api/mi_include_location.hpp | 1 - src/model_includes/ih/mi_accessor_impl.hpp | 4 +- .../impl/mi_analyzer_context.cpp | 24 +- .../impl/mi_analyzer_context.hpp | 6 +- src/model_includes/impl/mi_analyzer_impl.cpp | 71 +- src/model_includes/impl/mi_analyzer_impl.hpp | 4 +- src/model_includes/impl/mi_file_impl.cpp | 18 +- src/model_includes/impl/mi_file_impl.hpp | 9 +- src/model_includes/impl/mi_include_impl.cpp | 2 - src/model_includes/impl/mi_include_impl.hpp | 2 - .../impl/mi_include_location_impl.cpp | 1 - .../impl/mi_include_location_impl.hpp | 2 - src/model_includes/impl/mi_model_impl.cpp | 12 +- src/model_includes/impl/mi_model_impl.hpp | 4 - src/model_includes/impl/mi_resolver.cpp | 43 +- src/model_includes/impl/mi_resolver.hpp | 7 +- .../impl/mi_resolver_context.cpp | 8 +- .../impl/mi_resolver_context.hpp | 5 +- src/model_includes/impl/mi_std_library.cpp | 77 +- src/model_includes/impl/mi_std_library.hpp | 6 +- .../mi_test_model_includes_fixture.cpp | 50 +- .../mi_test_model_includes_fixture.hpp | 7 +- .../wrappers/mi_test_file_wrapper.cpp | 13 +- .../wrappers/mi_test_file_wrapper.hpp | 7 +- .../wrappers/mi_test_include_wrapper.cpp | 41 +- .../wrappers/mi_test_include_wrapper.hpp | 5 +- .../wrappers/mi_test_model_wrapper.cpp | 10 +- .../wrappers/mi_test_model_wrapper.hpp | 3 - .../test/model_includes_test_main.cpp | 5 +- .../mi_test_analyzer_for_cmake_suits.cpp | 291 ++++--- .../test/suits/mi_test_analyzer_suits.cpp | 821 +++++++++--------- .../suits/mi_test_model_includes_suits.cpp | 60 +- .../mi_test_resolver_file_type_suits.cpp | 23 +- .../suits/mi_test_resolver_path_suits.cpp | 69 +- src/parser/api/pr_include_file.hpp | 22 +- src/parser/api/pr_include_file_location.hpp | 17 +- src/parser/api/pr_parser.hpp | 1 - src/parser/ih/pr_accessor.hpp | 1 - src/parser/ih/pr_accessor_impl.hpp | 1 - src/parser/impl/pr_parser_context.cpp | 3 +- src/parser/impl/pr_parser_context.hpp | 4 - src/parser/impl/pr_parser_impl.cpp | 149 +++- src/parser/impl/pr_parser_impl.hpp | 9 +- .../test/fixtures/pr_test_file_wrapper.cpp | 4 +- .../test/fixtures/pr_test_file_wrapper.hpp | 5 +- src/parser/test/fixtures/pr_test_fixture.cpp | 4 +- src/parser/test/fixtures/pr_test_fixture.hpp | 4 - src/parser/test/parser_test_main.cpp | 5 +- src/parser/test/suits/pr_test_suits.cpp | 125 +-- src/project/api/prj_project.hpp | 2 +- src/project/ih/prj_project_accesso_impl.hpp | 1 - src/project/ih/prj_project_accessor.hpp | 2 - .../exceptions/prj_base_exception_impl.hpp | 3 +- .../prj_exception_invalid_regex.cpp | 5 +- .../prj_exception_invalid_regex.hpp | 4 +- src/project/impl/prj_project_impl.cpp | 53 +- src/project/impl/prj_project_impl.hpp | 9 +- src/project/test/fixture/prj_test_ficture.cpp | 12 +- src/project/test/fixture/prj_test_ficture.hpp | 2 - src/project/test/prj_test_main.cpp | 5 +- src/project/test/suits/prj_test_suits.cpp | 136 ++- src/reporter/api/rp_factory.hpp | 1 - src/reporter/api/rp_reporter.hpp | 1 - src/reporter/api/rp_settings.hpp | 1 - .../exceptions/rp_base_exception_impl.hpp | 3 - .../exceptions/rp_incorrect_report_impl.cpp | 4 +- .../exceptions/rp_incorrect_report_impl.hpp | 6 +- src/reporter/ih/rp_accessor.hpp | 2 - src/reporter/ih/rp_accessor_impl.cpp | 4 + src/reporter/ih/rp_accessor_impl.hpp | 4 +- .../rp_different_type_reporter.cpp | 30 +- .../rp_different_type_reporter.hpp | 2 - .../rp_different_type_reporter_details.cpp | 10 +- .../rp_different_type_reporter_details.hpp | 1 - .../impl/dump_reporter/rp_dump_reporter.cpp | 98 +-- .../impl/dump_reporter/rp_dump_reporter.hpp | 35 +- .../rp_most_impact_reporter.cpp | 40 +- .../rp_most_impact_reporter.hpp | 2 - .../rp_most_impact_reporter_detail.hpp | 3 - src/reporter/impl/rp_base_reporter_impl.cpp | 20 +- src/reporter/impl/rp_base_reporter_impl.hpp | 5 - src/reporter/impl/rp_factpory_impl.cpp | 9 +- src/reporter/impl/rp_factpory_impl.hpp | 2 - src/reporter/impl/rp_settings_impl.cpp | 1 - src/reporter/impl/rp_settings_impl.hpp | 2 - src/reporter/impl/tools/rp_file_sorter.cpp | 6 +- .../impl/tools/rp_file_with_count.hpp | 5 +- .../tools/rp_file_with_count_container.cpp | 16 +- .../tools/rp_file_with_count_container.hpp | 5 +- .../impl/tools/rp_file_with_count_sorter.cpp | 8 +- .../impl/tools/rp_file_with_count_sorter.hpp | 2 +- .../tools/rp_includes_by_source_sorter.cpp | 2 + .../rp_sorted_files_by_name_container.cpp | 6 +- .../rp_sorted_files_by_name_container.hpp | 4 +- ...rp_sorted_includes_by_source_container.cpp | 12 +- ...rp_sorted_includes_by_source_container.hpp | 6 +- .../rp_unincluded_reporter.cpp | 16 +- .../rp_unincluded_reporter.hpp | 6 +- .../rp_unresolved_reporter.cpp | 30 +- .../rp_unresolved_reporter.hpp | 2 - .../rp_unresolved_report_resources.cpp | 1 - .../test/fixture/rp_test_reporter_fixture.cpp | 14 +- .../test/fixture/rp_test_reporter_fixture.hpp | 9 +- src/reporter/test/reporter_test_main.cpp | 5 +- .../rp_test_different_type_reporter_tests.cpp | 59 +- .../suits/rp_test_dump_reporter_suits.cpp | 21 +- .../rp_test_most_impact_reporter_suits.cpp | 108 +-- .../rp_test_unincluded_reporter_suits.cpp | 24 +- .../rp_test_unresolved_reporter_tests.cpp | 26 +- .../tools/rp_reporter_kind_functins.cpp | 18 +- src/test_tools/boost_predicate_wrapper.cpp | 8 +- src/test_tools/boost_predicate_wrapper.hpp | 4 +- src/test_tools/test_macros.hpp | 30 + src/tools/path_string_tools.cpp | 28 +- src/tools/path_string_tools.hpp | 6 +- src/tools/regex.cpp | 8 +- src/tools/regex.hpp | 3 - 315 files changed, 3386 insertions(+), 3034 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 CMakeLists.txt create mode 100755 check_code_style.sh create mode 100644 docs/versions/VERSION_0.3.1.md delete mode 100644 src/CMakeLists.txt create mode 100644 src/test_tools/test_macros.hpp diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..77841e7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,49 @@ +--- +AccessModifierOffset: '-4' +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: 'true' +AlignEscapedNewlines: Left +AlignTrailingComments: 'true' +AllowAllArgumentsOnNextLine: 'false' +AllowAllParametersOfDeclarationOnNextLine: 'true' +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: 'false' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +BinPackParameters: 'false' +BreakBeforeBraces: Allman +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +CompactNamespaces: 'false' +ExperimentalAutoDetectBinPacking: 'false' +FixNamespaceComments: 'false' +IndentCaseLabels: 'true' +IndentPPDirectives: BeforeHash +IndentWidth: '4' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +Language: Cpp +MaxEmptyLinesToKeep: '1' +PointerAlignment: Middle +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterLogicalNot: 'false' +SpaceAfterTemplateKeyword: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCpp11BracedList: 'false' +SpaceBeforeInheritanceColon: 'true' +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: 'false' +SpaceInEmptyParentheses: 'false' +SpacesInAngles: 'true' +SpacesInCStyleCastParentheses: 'true' +SpacesInContainerLiterals: 'true' +SpacesInParentheses: 'true' +SpacesInSquareBrackets: 'false' +Standard: Cpp11 +TabWidth: '4' +UseTab: Always + +... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..77841e7 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,49 @@ +--- +AccessModifierOffset: '-4' +AlignAfterOpenBracket: AlwaysBreak +AlignConsecutiveMacros: 'true' +AlignEscapedNewlines: Left +AlignTrailingComments: 'true' +AllowAllArgumentsOnNextLine: 'false' +AllowAllParametersOfDeclarationOnNextLine: 'true' +AllowShortBlocksOnASingleLine: 'false' +AllowShortCaseLabelsOnASingleLine: 'false' +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: 'false' +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +BinPackParameters: 'false' +BreakBeforeBraces: Allman +BreakConstructorInitializers: BeforeComma +BreakInheritanceList: BeforeComma +CompactNamespaces: 'false' +ExperimentalAutoDetectBinPacking: 'false' +FixNamespaceComments: 'false' +IndentCaseLabels: 'true' +IndentPPDirectives: BeforeHash +IndentWidth: '4' +KeepEmptyLinesAtTheStartOfBlocks: 'false' +Language: Cpp +MaxEmptyLinesToKeep: '1' +PointerAlignment: Middle +SortUsingDeclarations: 'true' +SpaceAfterCStyleCast: 'false' +SpaceAfterLogicalNot: 'false' +SpaceAfterTemplateKeyword: 'false' +SpaceBeforeAssignmentOperators: 'true' +SpaceBeforeCpp11BracedList: 'false' +SpaceBeforeInheritanceColon: 'true' +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: 'false' +SpaceInEmptyParentheses: 'false' +SpacesInAngles: 'true' +SpacesInCStyleCastParentheses: 'true' +SpacesInContainerLiterals: 'true' +SpacesInParentheses: 'true' +SpacesInSquareBrackets: 'false' +Standard: Cpp11 +TabWidth: '4' +UseTab: Always + +... diff --git a/.cspell.json b/.cspell.json index 51e9863..4fb59e0 100644 --- a/.cspell.json +++ b/.cspell.json @@ -22,6 +22,10 @@ "ccomplex", "stdfs", "cmake", - "unincluded" + "unincluded", + "NOLINTNEXTLINE", + "hicpp", + "NOLINT", + "clazy" ], } diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2c87ee3..0124628 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,7 +11,21 @@ build_gcc10: # Build with boost - apt-get install libboost-test-dev -y - cd build - - cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake --build . --config Release + # Run tests + - ctest . -C Release + +build_gcc8: + stage: build + image: ubuntu + script: + - apt-get update + - apt-get install cmake gcc-8 g++-8 libboost-test-dev -y + - export CC=gcc-8 + - export CXX=g++-8 + - cd build + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cmake --build . --config Release # Run tests - ctest . -C Release @@ -21,15 +35,11 @@ build_gcc7: image: ubuntu script: - apt-get update - - apt-get install cmake gcc-7 g++-7 -y + - apt-get install cmake gcc-7 g++-7 libboost-test-dev -y - export CC=gcc-7 - export CXX=g++-7 - # Build without boost - - ./build.sh - # Build with boost - - apt-get install libboost-test-dev -y - cd build - - cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cmake --build . --config Release # Run tests - ctest . -C Release @@ -39,15 +49,11 @@ build_clang: image: ubuntu script: - apt-get update - - apt-get install cmake clang -y + - apt-get install cmake clang libboost-test-dev -y - export CC=/usr/bin/clang - export CXX=/usr/bin/clang++ - # Build without boost - - ./build.sh - # Build with boost - - apt-get install libboost-test-dev -y - cd build - - cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cmake --build . --config Release # Run tests - ctest . -C Release @@ -68,7 +74,7 @@ build_windows: # Build with boost #- vcpkg install boost-test:x64-windows #- vcpkg install boost-system:x64-windows - - cmake ../src/ -G "Visual Studio 16" -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake + - cmake .. -G "Visual Studio 16" -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake - cmake --build . --config Release # Run tests - ctest . -C Release @@ -83,7 +89,7 @@ build_vs2017: #- choco install cmake -y - $env:PATH="C:\Program Files\CMake\bin;$env:PATH" - cd build - - cmake -G "Visual Studio 15" ../src/ -DCMAKE_BUILD_TYPE=Release + - cmake -G "Visual Studio 15" .. -DCMAKE_BUILD_TYPE=Release - cmake --build . --config Release build_macos: @@ -96,11 +102,22 @@ build_macos: # Build with boost # brew install boost - cd build - - cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cmake --build . --config Release # Run tests - ctest . -C Release +build_arm_linux: + stage: build + tags: + - arm-linux + script: + - cd build + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake --build . --config Release -j4 + # Run tests + - ctest . -C Release + check_typos: stage: build image: ubuntu @@ -119,9 +136,8 @@ cppcheck: image: ubuntu script: - apt-get update - - apt-get install cmake gcc g++ libboost-test-dev -y - - apt-get install cppcheck -y + - apt-get install cmake gcc g++ libboost-test-dev cppcheck -y - cd build - - cmake ../src/ -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cppcheck --project=compile_commands.json --enable=all --suppressions-list=../.cppcheck-suppressions-list --error-exitcode=1 --quiet diff --git a/CHANGELOG.md b/CHANGELOG.md index c3c4009..0e77188 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [v0.3.1](docs/versions/VERSION_0.3.1.md) + +### Fixed (v0.3.1) + +* Fixed detect file name after comments /**/ in include + ## [v0.3.0](docs/versions/VERSION_0.3.0.md) ### Added (v0.3.0) diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..be4185f --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,68 @@ +cmake_minimum_required(VERSION 3.10) + +project(cppinclude) + +include_directories(src/) +include_directories(src/3rd-part/fmt/include/) +include_directories(src/3rd-part/cpp-std-fwd/) +include_directories(src/3rd-part/std_fs/include) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/src/cmake") + +if(CMAKE_COMPILER_IS_GNUCC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wno-unused-function") +endif() +if(MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4") +endif() + +option(CPPINCLUDE_BUILD_WITH_TESTS "Build with tests") +option(CPPINCLUDE_BUILD_WITH_CLANG_TIDY "Build with clang-tidy") + +if(CPPINCLUDE_BUILD_WITH_CLANG_TIDY) + set(CMAKE_CXX_CLANG_TIDY "clang-tidy") +endif() + +file(GLOB all_sources "src/*.cpp") +add_executable(${PROJECT_NAME} ${all_sources}) + +if(CPPINCLUDE_BUILD_WITH_TESTS) + set(BOOST_LIBRARYDIR "/usr/lib/x86_64-linux-gnu/" ) + enable_testing() + add_subdirectory(src/test_tools) +endif() + +if(MSVC) + if(NOT CPPINCLUDE_BUILD_WITH_TESTS) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") + endif() + add_compile_options(/W3 /WX) +endif() + +macro(TARGET_SPECIFIC targetName) + if(CMAKE_COMPILER_IS_GNUCXX) + target_link_libraries(${targetName} stdc++fs) + endif() +endmacro() + +add_subdirectory(src/parser) +add_subdirectory(src/fs) +add_subdirectory(src/model_includes) +add_subdirectory(src/reporter) +add_subdirectory(src/tools) +add_subdirectory(src/project) +add_subdirectory(src/application) +add_subdirectory(src/3rd-part/fmt) +add_subdirectory(src/json) +add_subdirectory(src/compilation_db) +add_subdirectory(src/cmake_project) + +target_link_libraries(${PROJECT_NAME} application_lib) + +if(MSVC) + set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/INCREMENTAL:NO") +endif() + diff --git a/build.bat b/build.bat index fd6b1dc..9ac3002 100755 --- a/build.bat +++ b/build.bat @@ -1,6 +1,9 @@ -cd build +set buildDir=build +IF not exist %buildDir% (mkdir %buildDir%) -cmake ..\src\ -DCMAKE_BUILD_TYPE=Release && cmake --build . --config Release +cd %buildDir% + +cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build . --config Release cd .. copy build\Release\cppinclude.exe cppinclude.exe && echo "File cppinclude.exe compiled" diff --git a/build.sh b/build.sh index eded31e..325ff04 100755 --- a/build.sh +++ b/build.sh @@ -1,6 +1,8 @@ +mkdir -p build + cd build -cmake ../src/ -DCMAKE_BUILD_TYPE=Release && \ +cmake .. -DCMAKE_BUILD_TYPE=Release && \ cmake --build . --config Release cd - diff --git a/check_code_style.sh b/check_code_style.sh new file mode 100755 index 0000000..36ebfa8 --- /dev/null +++ b/check_code_style.sh @@ -0,0 +1,14 @@ +tempDir=${TMPDIR:-/tmp}/cppinclude + +echo "Prepare sources..." +[[ -d $tempDir ]] && rm -r $tempDir +mkdir -p $tempDir && echo "Created new folder $tempDir" + +cp .clang-tidy $tempDir && echo "Copied .clang-tidy" +cp -r ./src $tempDir && echo "Copied src folder" + +echo "Run clang-format..." +find $tempDir -regex '.*\.\(cpp\|hpp\)' ! -path '$tempDir/src/3rd-part/**' -exec clang-format -style=file -i {} \; + +echo "Run meld..." +meld $tempDir/src ./src diff --git a/docs/examples/llvm-project/output_unix.txt b/docs/examples/llvm-project/output_unix.txt index 98a6172..6e15e1a 100644 --- a/docs/examples/llvm-project/output_unix.txt +++ b/docs/examples/llvm-project/output_unix.txt @@ -2,22 +2,22 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "libcxx/include/__config" impact on 19234 file(s) +1 : "libcxx/include/__config" impact on 18982 file(s) Included by: - 1 : "libcxx/include/math.h" line 294, impact on 17549 file(s) - 2 : "libcxx/include/stdlib.h" line 91, impact on 17549 file(s) - 3 : "libcxx/include/stdint.h" line 106, impact on 11797 file(s) - 4 : "libcxx/include/stddef.h" line 39, impact on 11047 file(s) - 5 : "libcxx/include/inttypes.h" line 238, impact on 9940 file(s) - 6 : "libcxx/include/setjmp.h" line 28, impact on 7916 file(s) + 1 : "libcxx/include/math.h" line 294, impact on 17505 file(s) + 2 : "libcxx/include/stdlib.h" line 91, impact on 17505 file(s) + 3 : "libcxx/include/stdint.h" line 106, impact on 11752 file(s) + 4 : "libcxx/include/stddef.h" line 39, impact on 11042 file(s) + 5 : "libcxx/include/inttypes.h" line 238, impact on 9937 file(s) + 6 : "libcxx/include/setjmp.h" line 28, impact on 7910 file(s) 7 : "libcxx/test/support/test_macros.h" line 18, impact on 5744 file(s) - 8 : "libcxx/include/stdio.h" line 101, impact on 3591 file(s) - 9 : "libcxx/include/string.h" line 54, impact on 1898 file(s) - 10 : "libcxx/include/limits.h" line 40, impact on 1069 file(s) + 8 : "libcxx/include/stdio.h" line 101, impact on 3356 file(s) + 9 : "libcxx/include/string.h" line 54, impact on 1882 file(s) + 10 : "libcxx/include/limits.h" line 40, impact on 1068 file(s) ... 10 of 48 details -2 : "libcxx/include/type_traits" impact on 17813 file(s) +2 : "libcxx/include/type_traits" impact on 17768 file(s) Included by: - 1 : "libcxx/include/math.h" line 311, impact on 17549 file(s) + 1 : "libcxx/include/math.h" line 311, impact on 17505 file(s) 2 : "llvm/include/llvm/Support/type_traits.h" line 17, impact on 9534 file(s) 3 : "llvm/include/llvm/ADT/iterator.h" line 16, impact on 9419 file(s) 4 : "llvm/include/llvm/ADT/STLExtras.h" line 35, impact on 9405 file(s) @@ -27,10 +27,10 @@ Included by: 8 : "llvm/include/llvm/ADT/SmallVector.h" line 32, impact on 9242 file(s) 9 : "llvm/include/llvm/ADT/ArrayRef.h" line 24, impact on 8875 file(s) 10 : "llvm/include/llvm/Support/PointerLikeTypeTraits.h" line 19, impact on 8498 file(s) - ... 10 of 1373 details -3 : "libcxx/include/limits" impact on 17721 file(s) + ... 10 of 1372 details +3 : "libcxx/include/limits" impact on 17677 file(s) Included by: - 1 : "libcxx/include/math.h" line 312, impact on 17549 file(s) + 1 : "libcxx/include/math.h" line 312, impact on 17505 file(s) 2 : "llvm/include/llvm/ADT/STLExtras.h" line 32, impact on 9405 file(s) 3 : "llvm/include/llvm/ADT/StringRef.h" line 19, impact on 9312 file(s) 4 : "llvm/include/llvm/Support/MathExtras.h" line 22, impact on 9305 file(s) @@ -41,9 +41,9 @@ Included by: 9 : "llvm/include/llvm/ADT/SparseSet.h" line 28, impact on 746 file(s) 10 : "clang/include/clang/ASTMatchers/ASTMatchers.h" line 89, impact on 695 file(s) ... 10 of 379 details -4 : "libcxx/include/math.h" impact on 17549 file(s) +4 : "libcxx/include/math.h" impact on 17505 file(s) Included by: - 1 : "libcxx/include/stdlib.h" line 100, impact on 17549 file(s) + 1 : "libcxx/include/stdlib.h" line 100, impact on 17505 file(s) 2 : "llvm/include/llvm-c/DataTypes.h" line 30, impact on 9481 file(s) 3 : "compiler-rt/lib/builtins/int_math.h" line 27, impact on 66 file(s) 4 : "openmp/runtime/src/kmp_stats.h" line 30, impact on 18 file(s) @@ -54,20 +54,20 @@ Included by: 9 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c" line 19 10 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmple_test.c" line 21 ... 10 of 127 details -5 : "libcxx/include/stdlib.h" impact on 17549 file(s) +5 : "libcxx/include/stdlib.h" impact on 17505 file(s) Included by: - 1 : "libcxx/include/math.h" line 301, impact on 17549 file(s) + 1 : "libcxx/include/math.h" line 301, impact on 17505 file(s) 2 : "llvm/include/llvm-c/DataTypes.h" line 63, impact on 9481 file(s) 3 : "llvm/include/llvm/Support/SwapByteOrder.h" line 22, impact on 9323 file(s) - 4 : "clang/lib/Headers/mm_malloc.h" line 13, impact on 7947 file(s) + 4 : "clang/lib/Headers/mm_malloc.h" line 13, impact on 7943 file(s) 5 : "libcxx/test/support/test_macros.h" line 301, impact on 5744 file(s) 6 : "polly/lib/External/isl/include/isl/arg.h" line 14, impact on 316 file(s) 7 : "polly/lib/External/isl/include/isl/ctx.h" line 14, impact on 315 file(s) 8 : "compiler-rt/test/tsan/test.h" line 2, impact on 169 file(s) 9 : "llgo/third_party/gofrontend/libffi/testsuite/libffi.call/ffitest.h" line 1, impact on 144 file(s) 10 : "libcxx/test/support/platform_support.h" line 55, impact on 137 file(s) - ... 10 of 1044 details -6 : "libcxx/include/cassert" impact on 14770 file(s) + ... 10 of 1003 details +6 : "libcxx/include/cassert" impact on 14768 file(s) Included by: 1 : "llvm/include/llvm/ADT/Optional.h" line 21, impact on 9448 file(s) 2 : "llvm/include/llvm/ADT/STLExtras.h" line 25, impact on 9405 file(s) @@ -79,8 +79,8 @@ Included by: 8 : "llvm/include/llvm/ADT/Twine.h" line 15, impact on 8386 file(s) 9 : "llvm/include/llvm/Support/raw_ostream.h" line 18, impact on 8269 file(s) 10 : "llvm/include/llvm/Support/Alignment.h" line 27, impact on 8063 file(s) - ... 10 of 6044 details -7 : "libcxx/include/cstddef" impact on 11858 file(s) + ... 10 of 6042 details +7 : "libcxx/include/cstddef" impact on 11856 file(s) Included by: 1 : "llvm/include/llvm-c/DataTypes.h" line 59, impact on 9481 file(s) 2 : "llvm/include/llvm/ADT/iterator.h" line 14, impact on 9419 file(s) @@ -92,21 +92,21 @@ Included by: 8 : "llvm/include/llvm/ADT/ArrayRef.h" line 20, impact on 8875 file(s) 9 : "llvm/include/llvm/Support/raw_ostream.h" line 19, impact on 8269 file(s) 10 : "llvm/include/llvm/ADT/SmallString.h" line 18, impact on 8032 file(s) - ... 10 of 892 details -8 : "libcxx/include/stdint.h" impact on 11797 file(s) + ... 10 of 890 details +8 : "libcxx/include/stdint.h" impact on 11752 file(s) Included by: 1 : "compiler-rt/include/sanitizer/common_interface_defs.h" line 16, impact on 10001 file(s) - 2 : "libcxx/include/inttypes.h" line 255, impact on 9940 file(s) + 2 : "libcxx/include/inttypes.h" line 255, impact on 9937 file(s) 3 : "llvm/include/llvm-c/DataTypes.h" line 34, impact on 9481 file(s) - 4 : "lldb/include/lldb/lldb-types.h" line 15, impact on 1725 file(s) + 4 : "lldb/include/lldb/lldb-types.h" line 15, impact on 1722 file(s) 5 : "llvm/include/llvm/IR/FPEnv.h" line 20, impact on 1196 file(s) 6 : "lldb/include/lldb/Utility/Status.h" line 18, impact on 1129 file(s) 7 : "lldb/include/lldb/Utility/FileSpec.h" line 23, impact on 1128 file(s) 8 : "lldb/include/lldb/Utility/Stream.h" line 21, impact on 983 file(s) 9 : "lldb/include/lldb/Core/Address.h" line 18, impact on 845 file(s) 10 : "lldb/include/lldb/Utility/Endian.h" line 14, impact on 751 file(s) - ... 10 of 470 details -9 : "libcxx/include/memory" impact on 11547 file(s) + ... 10 of 430 details +9 : "libcxx/include/memory" impact on 11478 file(s) Included by: 1 : "llvm/include/llvm/ADT/Optional.h" line 22, impact on 9448 file(s) 2 : "llvm/include/llvm/ADT/STLExtras.h" line 33, impact on 9405 file(s) @@ -118,8 +118,8 @@ Included by: 8 : "llvm/include/llvm/ADT/APFloat.h" line 22, impact on 5376 file(s) 9 : "llvm/include/llvm/Support/MemoryBuffer.h" line 25, impact on 5178 file(s) 10 : "llvm/include/llvm/Support/SourceMgr.h" line 28, impact on 4601 file(s) - ... 10 of 1326 details -10 : "libcxx/include/cstdlib" impact on 11516 file(s) + ... 10 of 1310 details +10 : "libcxx/include/cstdlib" impact on 11439 file(s) Included by: 1 : "llvm/include/llvm-c/DataTypes.h" line 60, impact on 9481 file(s) 2 : "llvm/include/llvm/ADT/STLExtras.h" line 28, impact on 9405 file(s) @@ -131,8 +131,8 @@ Included by: 8 : "llvm/include/llvm/Support/Error.h" line 32, impact on 6869 file(s) 9 : "llvm/include/llvm/ADT/SmallPtrSet.h" line 23, impact on 5164 file(s) 10 : "llvm/include/llvm/ADT/BitVector.h" line 23, impact on 4074 file(s) - ... 10 of 583 details -... 10 of 6002 files + ... 10 of 570 details +... 10 of 5969 files Unincluded headers: 1 : "clang/include/clang/Analysis/AnalysisDiagnostic.h" 2 : "clang/include/clang/Analysis/FlowSensitive/DataflowValues.h" @@ -144,4 +144,4 @@ Unincluded headers: 8 : "clang/lib/Headers/inttypes.h" 9 : "clang/lib/Headers/limits.h" 10 : "clang/lib/Headers/msa.h" -... 10 of 231 files +... 10 of 210 files diff --git a/docs/examples/simple_example/base_char.hpp b/docs/examples/simple_example/base_char.hpp index ba6b66f..8289d39 100644 --- a/docs/examples/simple_example/base_char.hpp +++ b/docs/examples/simple_example/base_char.hpp @@ -5,7 +5,6 @@ class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example/base_char_factory.hpp b/docs/examples/simple_example/base_char_factory.hpp index a01d9e7..2ae60ce 100644 --- a/docs/examples/simple_example/base_char_factory.hpp +++ b/docs/examples/simple_example/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example/char_a.hpp b/docs/examples/simple_example/char_a.hpp index 8cf9a2a..6a1967a 100644 --- a/docs/examples/simple_example/char_a.hpp +++ b/docs/examples/simple_example/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example/char_a_factory.hpp b/docs/examples/simple_example/char_a_factory.hpp index 856083b..e35f9b6 100644 --- a/docs/examples/simple_example/char_a_factory.hpp +++ b/docs/examples/simple_example/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example/char_b.hpp b/docs/examples/simple_example/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example/char_b.hpp +++ b/docs/examples/simple_example/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example/char_b_factory.cpp b/docs/examples/simple_example/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example/char_b_factory.cpp +++ b/docs/examples/simple_example/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example/char_b_factory.hpp b/docs/examples/simple_example/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example/char_b_factory.hpp +++ b/docs/examples/simple_example/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example/main.cpp b/docs/examples/simple_example/main.cpp index 2586464..56053b1 100644 --- a/docs/examples/simple_example/main.cpp +++ b/docs/examples/simple_example/main.cpp @@ -1,8 +1,8 @@ #include "char_a_factory.hpp" #include "char_b_factory.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -32,16 +32,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/examples/simple_example_cmake/base_char.hpp b/docs/examples/simple_example_cmake/base_char.hpp index ba6b66f..8289d39 100644 --- a/docs/examples/simple_example_cmake/base_char.hpp +++ b/docs/examples/simple_example_cmake/base_char.hpp @@ -5,7 +5,6 @@ class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example_cmake/base_char_factory.hpp b/docs/examples/simple_example_cmake/base_char_factory.hpp index a01d9e7..2ae60ce 100644 --- a/docs/examples/simple_example_cmake/base_char_factory.hpp +++ b/docs/examples/simple_example_cmake/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example_cmake/char_a.hpp b/docs/examples/simple_example_cmake/char_a.hpp index 8cf9a2a..6a1967a 100644 --- a/docs/examples/simple_example_cmake/char_a.hpp +++ b/docs/examples/simple_example_cmake/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_cmake/char_a_factory.hpp b/docs/examples/simple_example_cmake/char_a_factory.hpp index 856083b..e35f9b6 100644 --- a/docs/examples/simple_example_cmake/char_a_factory.hpp +++ b/docs/examples/simple_example_cmake/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_cmake/char_b.hpp b/docs/examples/simple_example_cmake/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example_cmake/char_b.hpp +++ b/docs/examples/simple_example_cmake/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_cmake/char_b_factory.cpp b/docs/examples/simple_example_cmake/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example_cmake/char_b_factory.cpp +++ b/docs/examples/simple_example_cmake/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example_cmake/char_b_factory.hpp b/docs/examples/simple_example_cmake/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example_cmake/char_b_factory.hpp +++ b/docs/examples/simple_example_cmake/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_cmake/main.cpp b/docs/examples/simple_example_cmake/main.cpp index 2586464..56053b1 100644 --- a/docs/examples/simple_example_cmake/main.cpp +++ b/docs/examples/simple_example_cmake/main.cpp @@ -1,8 +1,8 @@ #include "char_a_factory.hpp" #include "char_b_factory.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -32,16 +32,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/examples/simple_example_for_different_type_report/base_char.hpp b/docs/examples/simple_example_for_different_type_report/base_char.hpp index ba6b66f..8289d39 100644 --- a/docs/examples/simple_example_for_different_type_report/base_char.hpp +++ b/docs/examples/simple_example_for_different_type_report/base_char.hpp @@ -5,7 +5,6 @@ class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp b/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp index a01d9e7..2ae60ce 100644 --- a/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp +++ b/docs/examples/simple_example_for_different_type_report/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example_for_different_type_report/char_a.hpp b/docs/examples/simple_example_for_different_type_report/char_a.hpp index 99b9f62..8673099 100644 --- a/docs/examples/simple_example_for_different_type_report/char_a.hpp +++ b/docs/examples/simple_example_for_different_type_report/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp b/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp index bda76a5..72c8497 100644 --- a/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp +++ b/docs/examples/simple_example_for_different_type_report/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_for_different_type_report/char_b.hpp b/docs/examples/simple_example_for_different_type_report/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example_for_different_type_report/char_b.hpp +++ b/docs/examples/simple_example_for_different_type_report/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp b/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp +++ b/docs/examples/simple_example_for_different_type_report/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp b/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp +++ b/docs/examples/simple_example_for_different_type_report/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_for_different_type_report/main.cpp b/docs/examples/simple_example_for_different_type_report/main.cpp index 2586464..56053b1 100644 --- a/docs/examples/simple_example_for_different_type_report/main.cpp +++ b/docs/examples/simple_example_for_different_type_report/main.cpp @@ -1,8 +1,8 @@ #include "char_a_factory.hpp" #include "char_b_factory.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -32,16 +32,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/examples/simple_example_with_forward_declaration/base_char.hpp b/docs/examples/simple_example_with_forward_declaration/base_char.hpp index 9f31542..7aa0339 100644 --- a/docs/examples/simple_example_with_forward_declaration/base_char.hpp +++ b/docs/examples/simple_example_with_forward_declaration/base_char.hpp @@ -5,7 +5,6 @@ enum class CharKind; class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example_with_forward_declaration/base_char_factory.hpp b/docs/examples/simple_example_with_forward_declaration/base_char_factory.hpp index 17182fa..cc1809e 100644 --- a/docs/examples/simple_example_with_forward_declaration/base_char_factory.hpp +++ b/docs/examples/simple_example_with_forward_declaration/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseChar; class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example_with_forward_declaration/char_a.hpp b/docs/examples/simple_example_with_forward_declaration/char_a.hpp index 8cf9a2a..6a1967a 100644 --- a/docs/examples/simple_example_with_forward_declaration/char_a.hpp +++ b/docs/examples/simple_example_with_forward_declaration/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_forward_declaration/char_a_factory.hpp b/docs/examples/simple_example_with_forward_declaration/char_a_factory.hpp index 856083b..e35f9b6 100644 --- a/docs/examples/simple_example_with_forward_declaration/char_a_factory.hpp +++ b/docs/examples/simple_example_with_forward_declaration/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_forward_declaration/char_b.hpp b/docs/examples/simple_example_with_forward_declaration/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example_with_forward_declaration/char_b.hpp +++ b/docs/examples/simple_example_with_forward_declaration/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_forward_declaration/char_b_factory.cpp b/docs/examples/simple_example_with_forward_declaration/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example_with_forward_declaration/char_b_factory.cpp +++ b/docs/examples/simple_example_with_forward_declaration/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example_with_forward_declaration/char_b_factory.hpp b/docs/examples/simple_example_with_forward_declaration/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example_with_forward_declaration/char_b_factory.hpp +++ b/docs/examples/simple_example_with_forward_declaration/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_forward_declaration/main.cpp b/docs/examples/simple_example_with_forward_declaration/main.cpp index 44df747..a5863d6 100644 --- a/docs/examples/simple_example_with_forward_declaration/main.cpp +++ b/docs/examples/simple_example_with_forward_declaration/main.cpp @@ -1,10 +1,10 @@ +#include "base_char.hpp" #include "char_a_factory.hpp" #include "char_b_factory.hpp" #include "char_kind.hpp" -#include "base_char.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -34,16 +34,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp index 8cf9a2a..6a1967a 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp index 856083b..e35f9b6 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/a/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/b/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp index ba6b66f..8289d39 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char.hpp @@ -5,7 +5,6 @@ class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp index a01d9e7..2ae60ce 100644 --- a/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp +++ b/docs/examples/simple_example_with_include_path_cmake/lib/base/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example_with_include_path_cmake/main.cpp b/docs/examples/simple_example_with_include_path_cmake/main.cpp index 2586464..56053b1 100644 --- a/docs/examples/simple_example_with_include_path_cmake/main.cpp +++ b/docs/examples/simple_example_with_include_path_cmake/main.cpp @@ -1,8 +1,8 @@ #include "char_a_factory.hpp" #include "char_b_factory.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -32,16 +32,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/examples/simple_example_with_unincluded_headers/base_char.hpp b/docs/examples/simple_example_with_unincluded_headers/base_char.hpp index ba6b66f..8289d39 100644 --- a/docs/examples/simple_example_with_unincluded_headers/base_char.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/base_char.hpp @@ -5,7 +5,6 @@ class BaseChar { public: - virtual ~BaseChar() = default; virtual CharKind getKind() const noexcept = 0; diff --git a/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp index a01d9e7..2ae60ce 100644 --- a/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/base_char_factory.hpp @@ -7,7 +7,6 @@ class BaseCharFactory { public: - virtual ~BaseCharFactory() = default; virtual std::unique_ptr< BaseChar > createObject() = 0; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a.hpp b/docs/examples/simple_example_with_unincluded_headers/char_a.hpp index 8cf9a2a..6a1967a 100644 --- a/docs/examples/simple_example_with_unincluded_headers/char_a.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/char_a.hpp @@ -5,6 +5,5 @@ class CharA : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp index 856083b..e35f9b6 100644 --- a/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/char_a_factory.hpp @@ -5,6 +5,5 @@ class CharAFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b.hpp b/docs/examples/simple_example_with_unincluded_headers/char_b.hpp index e6b0f20..5da436e 100644 --- a/docs/examples/simple_example_with_unincluded_headers/char_b.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/char_b.hpp @@ -5,6 +5,5 @@ class CharB : public BaseChar { public: - CharKind getKind() const noexcept override; }; diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp index 6276ca2..d181f86 100644 --- a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp +++ b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.cpp @@ -6,4 +6,3 @@ std::unique_ptr< BaseChar > CharBFactory::createObject() { return std::unique_ptr< BaseChar >{ new CharB }; } - diff --git a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp index 1e06696..9e976a7 100644 --- a/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp +++ b/docs/examples/simple_example_with_unincluded_headers/char_b_factory.hpp @@ -5,6 +5,5 @@ class CharBFactory : public BaseCharFactory { public: - std::unique_ptr< BaseChar > createObject() override; }; diff --git a/docs/examples/simple_example_with_unincluded_headers/main.cpp b/docs/examples/simple_example_with_unincluded_headers/main.cpp index 2586464..56053b1 100644 --- a/docs/examples/simple_example_with_unincluded_headers/main.cpp +++ b/docs/examples/simple_example_with_unincluded_headers/main.cpp @@ -1,8 +1,8 @@ #include "char_a_factory.hpp" #include "char_b_factory.hpp" -#include #include +#include std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ); std::string enumToString( CharKind _kind ); @@ -32,16 +32,18 @@ std::unique_ptr< BaseChar > createChar( BaseCharFactory & _factory ) return _factory.createObject(); } - std::string enumToString( CharKind _kind ) { - static_assert( static_cast< int >( CharKind::Count ) == 2, ""); + static_assert( static_cast< int >( CharKind::Count ) == 2, "" ); switch( _kind ) { - case CharKind::A : return "CharKind::A"; - case CharKind::B : return "CharKind::B"; + case CharKind::A: + return "CharKind::A"; + case CharKind::B: + return "CharKind::B"; - case CharKind::Count : return "CharKind::Count"; + case CharKind::Count: + return "CharKind::Count"; } assert( false ); diff --git a/docs/versions/VERSION_0.3.1.md b/docs/versions/VERSION_0.3.1.md new file mode 100644 index 0000000..9be977f --- /dev/null +++ b/docs/versions/VERSION_0.3.1.md @@ -0,0 +1,19 @@ +# VERSION 0.3.1 + +## Fixed + +### Fixed detect file name after comments + +Example: + +```c++ +#include /**/ "filename1" +#include /*"text2"*/ + + +``` + +**Before:** File text1 and text2 were file names + +**After:** filename1 and filename2 are file names + diff --git a/src/3rd-part/cxxopts/include/cxxopts.hpp b/src/3rd-part/cxxopts/include/cxxopts.hpp index 2fb5c8c..d81d6e5 100644 --- a/src/3rd-part/cxxopts/include/cxxopts.hpp +++ b/src/3rd-part/cxxopts/include/cxxopts.hpp @@ -25,6 +25,8 @@ THE SOFTWARE. #ifndef CXXOPTS_HPP_INCLUDED #define CXXOPTS_HPP_INCLUDED +// clazy:excludeall=non-pod-global-static + #include #include #include diff --git a/src/3rd-part/fmt/src/format.cc b/src/3rd-part/fmt/src/format.cc index 44ba77f..073b957 100644 --- a/src/3rd-part/fmt/src/format.cc +++ b/src/3rd-part/fmt/src/format.cc @@ -24,41 +24,41 @@ int format_float(char* buf, std::size_t size, const char* format, int precision, : snprintf_ptr(buf, size, format, precision, value); } struct sprintf_specs { - int precision; - char type; - bool alt : 1; + int precision; // NOLINT + char type;// NOLINT + bool alt : 1; // NOLINT template - constexpr sprintf_specs(basic_format_specs specs) + constexpr sprintf_specs(basic_format_specs specs) // NOLINT : precision(specs.precision), type(specs.type), alt(specs.alt) {} - constexpr bool has_precision() const { return precision >= 0; } + constexpr bool has_precision() const { return precision >= 0; } // NOLINT }; // This is deprecated and is kept only to preserve ABI compatibility. template -char* sprintf_format(Double value, internal::buffer& buf, +char* sprintf_format(Double value, internal::buffer& buf, // NOLINT sprintf_specs specs) { // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. FMT_ASSERT(buf.capacity() != 0, "empty buffer"); // Build format string. enum { max_format_size = 10 }; // longest format: %#-*.*Lg - char format[max_format_size]; + char format[max_format_size]; // NOLINT char* format_ptr = format; - *format_ptr++ = '%'; - if (specs.alt || !specs.type) *format_ptr++ = '#'; + *format_ptr++ = '%'; // NOLINT + if (specs.alt || !specs.type) *format_ptr++ = '#'; // NOLINT if (specs.precision >= 0) { - *format_ptr++ = '.'; - *format_ptr++ = '*'; + *format_ptr++ = '.'; // NOLINT + *format_ptr++ = '*'; // NOLINT } - if (std::is_same::value) *format_ptr++ = 'L'; + if (std::is_same::value) *format_ptr++ = 'L'; // NOLINT char type = specs.type; - if (type == '%') + if (type == '%') // NOLINT type = 'f'; - else if (type == 0 || type == 'n') + else if (type == 0 || type == 'n') // NOLINT type = 'g'; #if FMT_MSC_VER if (type == 'F') { @@ -66,7 +66,7 @@ char* sprintf_format(Double value, internal::buffer& buf, type = 'f'; } #endif - *format_ptr++ = type; + *format_ptr++ = type; // NOLINT *format_ptr = '\0'; // Format using snprintf. @@ -81,21 +81,21 @@ char* sprintf_format(Double value, internal::buffer& buf, unsigned n = internal::to_unsigned(result); if (n < buf.capacity()) { // Find the decimal point. - auto p = buf.data(), end = p + n; - if (*p == '+' || *p == '-') ++p; + auto p = buf.data(), end = p + n; // NOLINT + if (*p == '+' || *p == '-') ++p; // NOLINT if (specs.type != 'a' && specs.type != 'A') { - while (p < end && *p >= '0' && *p <= '9') ++p; + while (p < end && *p >= '0' && *p <= '9') ++p; // NOLINT if (p < end && *p != 'e' && *p != 'E') { decimal_point_pos = p; if (!specs.type) { // Keep only one trailing zero after the decimal point. ++p; - if (*p == '0') ++p; - while (p != end && *p >= '1' && *p <= '9') ++p; + if (*p == '0') ++p; // NOLINT + while (p != end && *p >= '1' && *p <= '9') ++p; // NOLINT char* where = p; - while (p != end && *p == '0') ++p; + while (p != end && *p == '0') ++p; // NOLINT if (p == end || *p < '0' || *p > '9') { - if (p != end) std::memmove(where, p, to_unsigned(end - p)); + if (p != end) std::memmove(where, p, to_unsigned(end - p)); // NOLINT n -= static_cast(p - where); } } diff --git a/src/3rd-part/fmt/src/posix.cc b/src/3rd-part/fmt/src/posix.cc index 3db72b7..d6f9529 100644 --- a/src/3rd-part/fmt/src/posix.cc +++ b/src/3rd-part/fmt/src/posix.cc @@ -69,22 +69,22 @@ inline std::size_t convert_rwcount(std::size_t count) { return count; } FMT_BEGIN_NAMESPACE buffered_file::~buffered_file() FMT_NOEXCEPT { - if (file_ && FMT_SYSTEM(fclose(file_)) != 0) + if (file_ && FMT_SYSTEM(fclose(file_)) != 0) // NOLINT report_system_error(errno, "cannot close file"); } -buffered_file::buffered_file(cstring_view filename, cstring_view mode) { +buffered_file::buffered_file(cstring_view filename, cstring_view mode) { // NOLINT FMT_RETRY_VAL(file_, FMT_SYSTEM(fopen(filename.c_str(), mode.c_str())), nullptr); - if (!file_) + if (!file_) // NOLINT FMT_THROW(system_error(errno, "cannot open file {}", filename.c_str())); } void buffered_file::close() { - if (!file_) return; - int result = FMT_SYSTEM(fclose(file_)); + if (!file_) return; // NOLINT + int result = FMT_SYSTEM(fclose(file_)); // NOLINT file_ = nullptr; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); // NOLINT } // A macro used to prevent expansion of fileno on broken versions of MinGW. @@ -92,40 +92,40 @@ void buffered_file::close() { int buffered_file::fileno() const { int fd = FMT_POSIX_CALL(fileno FMT_ARGS(file_)); - if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor")); + if (fd == -1) FMT_THROW(system_error(errno, "cannot get file descriptor")); // NOLINT return fd; } #if FMT_USE_FCNTL -file::file(cstring_view path, int oflag) { - int mode = S_IRUSR | S_IWUSR; +file::file(cstring_view path, int oflag) { // NOLINT + int mode = S_IRUSR | S_IWUSR; // NOLINT #if defined(_WIN32) && !defined(__MINGW32__) fd_ = -1; FMT_POSIX_CALL(sopen_s(&fd_, path.c_str(), oflag, _SH_DENYNO, mode)); #else - FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); + FMT_RETRY(fd_, FMT_POSIX_CALL(open(path.c_str(), oflag, mode))); // NOLINT #endif - if (fd_ == -1) + if (fd_ == -1) // NOLINT FMT_THROW(system_error(errno, "cannot open file {}", path.c_str())); } file::~file() FMT_NOEXCEPT { // Don't retry close in case of EINTR! // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html - if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) + if (fd_ != -1 && FMT_POSIX_CALL(close(fd_)) != 0) // NOLINT report_system_error(errno, "cannot close file"); } void file::close() { - if (fd_ == -1) return; + if (fd_ == -1) return; // NOLINT // Don't retry close in case of EINTR! // See http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html int result = FMT_POSIX_CALL(close(fd_)); fd_ = -1; - if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); + if (result != 0) FMT_THROW(system_error(errno, "cannot close file")); // NOLINT } -long long file::size() const { +long long file::size() const { // NOLINT #ifdef _WIN32 // Use GetFileSize instead of GetFileSizeEx for the case when _WIN32_WINNT // is less than 0x0500 as is the case with some default MinGW builds. @@ -143,9 +143,9 @@ long long file::size() const { #else using Stat = struct stat; Stat file_stat = Stat(); - if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) + if (FMT_POSIX_CALL(fstat(fd_, &file_stat)) == -1) // NOLINT FMT_THROW(system_error(errno, "cannot get file attributes")); - static_assert(sizeof(long long) >= sizeof(file_stat.st_size), + static_assert(sizeof(long long) >= sizeof(file_stat.st_size), // NOLINT "return type of file::size is not large enough"); return file_stat.st_size; #endif @@ -154,22 +154,22 @@ long long file::size() const { std::size_t file::read(void* buffer, std::size_t count) { RWResult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(read(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot read from file")); + if (result < 0) FMT_THROW(system_error(errno, "cannot read from file")); // NOLINT return internal::to_unsigned(result); } std::size_t file::write(const void* buffer, std::size_t count) { RWResult result = 0; FMT_RETRY(result, FMT_POSIX_CALL(write(fd_, buffer, convert_rwcount(count)))); - if (result < 0) FMT_THROW(system_error(errno, "cannot write to file")); + if (result < 0) FMT_THROW(system_error(errno, "cannot write to file")); // NOLINT return internal::to_unsigned(result); } file file::dup(int fd) { // Don't retry as dup doesn't return EINTR. // http://pubs.opengroup.org/onlinepubs/009695399/functions/dup.html - int new_fd = FMT_POSIX_CALL(dup(fd)); - if (new_fd == -1) + int new_fd = FMT_POSIX_CALL(dup(fd)); // NOLINT + if (new_fd == -1) // NOLINT FMT_THROW(system_error(errno, "cannot duplicate file descriptor {}", fd)); return file(new_fd); } @@ -186,7 +186,7 @@ void file::dup2(int fd) { void file::dup2(int fd, error_code& ec) FMT_NOEXCEPT { int result = 0; FMT_RETRY(result, FMT_POSIX_CALL(dup2(fd_, fd))); - if (result == -1) ec = error_code(errno); + if (result == -1) ec = error_code(errno); // NOLINT } void file::pipe(file& read_end, file& write_end) { @@ -194,7 +194,7 @@ void file::pipe(file& read_end, file& write_end) { // and there are no leaks. read_end.close(); write_end.close(); - int fds[2] = {}; + int fds[2] = {}; // NOLINT #ifdef _WIN32 // Make the default pipe capacity same as on Linux 2.6.11+. enum { DEFAULT_CAPACITY = 65536 }; @@ -202,9 +202,9 @@ void file::pipe(file& read_end, file& write_end) { #else // Don't retry as the pipe function doesn't return EINTR. // http://pubs.opengroup.org/onlinepubs/009696799/functions/pipe.html - int result = FMT_POSIX_CALL(pipe(fds)); + int result = FMT_POSIX_CALL(pipe(fds)); // NOLINT #endif - if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe")); + if (result != 0) FMT_THROW(system_error(errno, "cannot create pipe")); // NOLINT // The following assignments don't throw because read_fd and write_fd // are closed. read_end = file(fds[0]); @@ -214,7 +214,7 @@ void file::pipe(file& read_end, file& write_end) { buffered_file file::fdopen(const char* mode) { // Don't retry as fdopen doesn't return EINTR. FILE* f = FMT_POSIX_CALL(fdopen(fd_, mode)); - if (!f) + if (!f) // NOLINT FMT_THROW( system_error(errno, "cannot associate stream with file descriptor")); buffered_file bf(f); @@ -222,14 +222,14 @@ buffered_file file::fdopen(const char* mode) { return bf; } -long getpagesize() { +long getpagesize() { // NOLINT #ifdef _WIN32 SYSTEM_INFO si; GetSystemInfo(&si); return si.dwPageSize; #else - long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); - if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size")); + long size = FMT_POSIX_CALL(sysconf(_SC_PAGESIZE)); // NOLINT + if (size < 0) FMT_THROW(system_error(errno, "cannot get memory page size")); // NOLINT return size; #endif } diff --git a/src/3rd-part/std_fs/include/std_fs b/src/3rd-part/std_fs/include/std_fs index 0b648a5..914aba5 100644 --- a/src/3rd-part/std_fs/include/std_fs +++ b/src/3rd-part/std_fs/include/std_fs @@ -3,211 +3,242 @@ //------------------------------------------------------------------------------ #if __has_include() - #include +#include #elif __has_include() - #include +#include #else - #error Compiler does not have or +#error Compiler does not have or #endif //------------------------------------------------------------------------------ #if defined(__GLIBCXX__) - #define STDFS_IS_LIBSTDCPP +#define STDFS_IS_LIBSTDCPP #endif #if defined(STDFWD_IS_LIBSTDCPP) - #define STDFS_NAMESPACE_VISIBILITY _GLIBCXX_VISIBILITY(default) +#define STDFS_NAMESPACE_VISIBILITY _GLIBCXX_VISIBILITY(default) #else - #define STDFS_NAMESPACE_VISIBILITY +#define STDFS_NAMESPACE_VISIBILITY +#endif + +//------------------------------------------------------------------------------ + +#if __has_include() +#ifdef __GNUC__ +#if ( __GNUC__ == 8 ) +#define STDFS_USE_ALTERNATIVE_COMAPRE +#endif +#endif +#else +#define STDFS_USE_ALTERNATIVE_COMAPRE #endif //------------------------------------------------------------------------------ namespace stdfs STDFS_NAMESPACE_VISIBILITY { - #if __has_include() - namespace fs_real = std::filesystem; - #elif __has_include() - namespace fs_real = std::experimental::filesystem; - #endif - - using path = fs_real::path; - using directory_iterator = fs_real::directory_iterator; - static decltype( auto ) hash_value = &fs_real::hash_value; - static bool (*exists)( const path&, std::error_code & ) = &fs_real::exists; - static bool (*is_directory)( const path& ) = &fs_real::is_directory; - static path (*current_path)() = &fs_real::current_path; +#if __has_include() +namespace fs_real = std::filesystem; +#elif __has_include() +namespace fs_real = std::experimental::filesystem; +#endif + +#if __cpp_lib_filesystem >= 201606 +#endif + +using path = fs_real::path; +using directory_iterator = fs_real::directory_iterator; +#ifndef _MSC_VER +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#endif +static decltype( auto ) hash_value = &fs_real::hash_value; +static bool (*exists)( const path&, std::error_code & ) = &fs_real::exists; +static bool (*is_directory)( const path& ) = &fs_real::is_directory; +static path (*current_path)() = &fs_real::current_path; +#ifndef _MSC_VER +#pragma GCC diagnostic pop +#endif #if __has_include() - static path lexically_relative( const path & _path, const path & _dir ) - { - return _path.lexically_relative( _dir ); - } - - static path lexically_normal( const path & _path ) - { - return _path.lexically_normal(); - } - - static path absolute( const path & _path ) - { - return fs_real::absolute( _path ); - } - - static bool is_dir_filename( const path & _path ) - { - return _path.filename().empty(); - } - - static int compare( const path & _l, const path & _r ) - { - return _l.compare( _r ); - } - - static bool less( const path & _l, const path & _r ) - { - return _l < _r; - } +static path lexically_relative( const path & _path, const path & _dir ) +{ + return _path.lexically_relative( _dir ); +} + +static path lexically_normal( const path & _path ) +{ + return _path.lexically_normal(); +} + +static path absolute( const path & _path ) +{ + return fs_real::absolute( _path ); +} + +static bool is_dir_filename( const path & _path ) +{ + return _path.filename().empty(); +} + #elif __has_include() - static path lexically_relative( const path & _path, const path & _dir ) - { - fs_real::path path = fs_real::absolute( _path ); - fs_real::path dir = fs_real::absolute( _dir ); - - if( path.root_path() != dir.root_path() ) - return dir; - - fs_real::path result; - - auto itPath = path.begin(); - auto itDir = dir.begin(); - while( - itPath != path.end() && - itDir != dir.end() && - *itPath == *itDir - ) - { - ++itPath; - ++itDir; - } - - if( itDir != dir.end() ) - { - ++itDir; - while( itDir != dir.end() ) - { - result /= ".."; - ++itDir; - } - } - - while( itPath != path.end() ) - { - result /= *itPath; - ++itPath; - } - - return result; - } - - static path lexically_normal( const path & _path ) - { - if( _path.empty() ) - return _path; - - std::vector< std::string > items{ _path.begin(), _path.end() }; - std::string & lastItem = items.back(); - // path { "/tmp/" } has ele,emts: { "/", "tmp", "." } - if( lastItem == "." ) - lastItem = std::string{ path::preferred_separator }; - - std::vector< std::string > resultItems; - for( std::string s : items ) - { - if (s == ".") - continue; - - if (s == ".." && !resultItems.empty()) - { - resultItems.pop_back(); - continue; - } - - resultItems.push_back( s ); - } - - path result; - for( std::string s : resultItems ) - { - result /= s; - } - - return result; - } - - static path absolute( const path & _path ) - { - return fs_real::absolute( _path, fs_real::current_path() ); - } - - static bool is_dir_filename( const path & _path ) - { - if( _path.empty() ) - return false; - - const std::string pathStr = _path.string(); - - return pathStr.back() == path::preferred_separator || pathStr == "."; - } - - static int compare( const path & _l, const path & _r ) - { - int result = 1; - - if( _l.has_root_directory() != _r.has_root_directory() ) - { - if( !_l.has_root_directory() ) - return +result; - else - return -result; - } - - auto leftBegin = _l.begin(); - auto leftEnd = _l.end(); - - auto rightBegin = _r.begin(); - auto rightEnd = _r.end(); - - while( rightBegin != rightEnd && leftBegin != leftEnd ) - { - if( rightBegin->native() < leftBegin->native() ) - return -result; - - if( rightBegin->native() > leftBegin->native() ) - return +result; - - ++rightBegin; - ++leftBegin; - ++result; - } - if( rightBegin == rightEnd) - { - if (leftBegin == leftEnd) - return 0; - return -result; - } - return +result; - } - - static bool less( const path & _l, const path & _r ) - { - return compare( _l, _r ) > 0; - } +static path lexically_relative( const path & _path, const path & _dir ) +{ + fs_real::path path = fs_real::absolute( _path ); + fs_real::path dir = fs_real::absolute( _dir ); + + if( path.root_path() != dir.root_path() ) + return dir; + + fs_real::path result; + + auto itPath = path.begin(); + auto itDir = dir.begin(); + while( + itPath != path.end() && + itDir != dir.end() && + *itPath == *itDir + ) + { + ++itPath; + ++itDir; + } + + if( itDir != dir.end() ) + { + ++itDir; + while( itDir != dir.end() ) + { + result /= ".."; + ++itDir; + } + } + + while( itPath != path.end() ) + { + result /= *itPath; + ++itPath; + } + + return result; +} + +static path lexically_normal( const path & _path ) +{ + if( _path.empty() ) + return _path; + + std::vector< std::string > items{ _path.begin(), _path.end() }; + std::string & lastItem = items.back(); + // path { "/tmp/" } has ele,emts: { "/", "tmp", "." } + if( lastItem == "." ) + lastItem = std::string{ path::preferred_separator }; + + std::vector< std::string > resultItems; + for( std::string s : items ) + { + if (s == ".") + continue; + + if (s == ".." && !resultItems.empty()) + { + resultItems.pop_back(); + continue; + } + + resultItems.push_back( s ); + } + + path result; + for( std::string s : resultItems ) + { + result /= s; + } + + return result; +} + +static path absolute( const path & _path ) +{ + return fs_real::absolute( _path, fs_real::current_path() ); +} + +static bool is_dir_filename( const path & _path ) +{ + if( _path.empty() ) + return false; + + const std::string pathStr = _path.string(); + + return pathStr.back() == path::preferred_separator || pathStr == "."; +} + + #endif +#ifndef STDFS_USE_ALTERNATIVE_COMAPRE +static int compare( const path & _l, const path & _r ) +{ + return _l.compare( _r ); } + +static bool less( const path & _l, const path & _r ) +{ + return _l < _r; +} +#else + +static int compare( const path & _l, const path & _r ) +{ + int result = 1; + + if( _l.has_root_directory() != _r.has_root_directory() ) + { + if( !_l.has_root_directory() ) + return +result; + else + return -result; + } + + auto leftBegin = _l.begin(); + auto leftEnd = _l.end(); + + auto rightBegin = _r.begin(); + auto rightEnd = _r.end(); + + while( rightBegin != rightEnd && leftBegin != leftEnd ) + { + if( rightBegin->native() < leftBegin->native() ) + return -result; + + if( rightBegin->native() > leftBegin->native() ) + return +result; + + ++rightBegin; + ++leftBegin; + ++result; + } + if( rightBegin == rightEnd) + { + if (leftBegin == leftEnd) + return 0; + return -result; + } + return +result; +} + +static bool less( const path & _l, const path & _r ) +{ + return compare( _l, _r ) > 0; +} + +#endif + +} + +#undef STDFS_VARIABLE_IS_NOT_USED diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 61f2d63..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,56 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -project(cppinclude) - -include_directories(.) -include_directories(./3rd-part/fmt/include/) -include_directories(./3rd-part/cpp-std-fwd/) -include_directories(./3rd-part/std_fs/include) - -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake") - -option(CPPINCLUDE_BUILD_WITH_TESTS "Build with tests") - -file(GLOB all_sources "*.cpp") -add_executable(${PROJECT_NAME} ${all_sources}) - -if(CPPINCLUDE_BUILD_WITH_TESTS) - set(BOOST_LIBRARYDIR "/usr/lib/x86_64-linux-gnu/" ) - enable_testing() - add_subdirectory(test_tools) -endif() - -if(MSVC) - if(NOT CPPINCLUDE_BUILD_WITH_TESTS) - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") - set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") - endif() - add_compile_options(/W3 /WX) -endif() - -macro(TARGET_SPECIFIC targetName) - if(CMAKE_COMPILER_IS_GNUCXX) - target_link_libraries(${targetName} stdc++fs) - endif() -endmacro() - -add_subdirectory(parser) -add_subdirectory(fs) -add_subdirectory(model_includes) -add_subdirectory(reporter) -add_subdirectory(tools) -add_subdirectory(project) -add_subdirectory(application) -add_subdirectory(3rd-part/fmt) -add_subdirectory(json) -add_subdirectory(compilation_db) -add_subdirectory(cmake_project) - -target_link_libraries(${PROJECT_NAME} application_lib) - -if(MSVC) - set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/INCREMENTAL:NO") -endif() - diff --git a/src/application/app_con.cpp b/src/application/app_con.cpp index 98874a6..3c73386 100644 --- a/src/application/app_con.cpp +++ b/src/application/app_con.cpp @@ -1,38 +1,38 @@ #include "application/app_con.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" -#include "application/tools/app_project_builder.hpp" +#include "application/resources/app_resources_messages.hpp" +#include "application/resources/app_resources_version.hpp" #include "application/tools/app_cmake_project_builder.hpp" -#include "application/tools/app_log.hpp" #include "application/tools/app_configuration_file.hpp" #include "application/tools/app_configuration_file_loader.hpp" +#include "application/tools/app_log.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_project_builder.hpp" #include "application/tools/app_report_settings_loader.hpp" -#include "application/resources/app_resources_messages.hpp" -#include "application/resources/app_resources_version.hpp" -#include "application/exceptions/app_cant_create_project_impl.hpp" -#include "application/exceptions/app_cant_create_model_impl.hpp" #include "application/exceptions/app_cant_create_analyzer.hpp" +#include "application/exceptions/app_cant_create_model_impl.hpp" +#include "application/exceptions/app_cant_create_project_impl.hpp" #include "application/exceptions/app_cant_create_report_impl.hpp" #include "application/exceptions/app_cant_load_reporter_settings.hpp" -#include "project/ih/prj_project_accesso_impl.hpp" #include "project/api/prj_project.hpp" +#include "project/ih/prj_project_accesso_impl.hpp" -#include "model_includes/ih/mi_accessor_impl.hpp" #include "model_includes/api/mi_analyzer.hpp" #include "model_includes/api/mi_model.hpp" +#include "model_includes/ih/mi_accessor_impl.hpp" -#include "fs/ih/fs_accessor_impl.hpp" #include "fs/api/fs_factory.hpp" +#include "fs/ih/fs_accessor_impl.hpp" -#include "parser/ih/pr_accessor_impl.hpp" #include "parser/api/pr_parser.hpp" +#include "parser/ih/pr_accessor_impl.hpp" -#include "reporter/ih/rp_accessor_impl.hpp" #include "reporter/api/rp_factory.hpp" #include "reporter/api/rp_reporter.hpp" #include "reporter/api/rp_settings.hpp" +#include "reporter/ih/rp_accessor_impl.hpp" #include "json/ih/json_accessor_impl.hpp" @@ -43,11 +43,11 @@ #include -#include -#include #include -#include #include +#include +#include +#include //------------------------------------------------------------------------------ @@ -60,6 +60,7 @@ ConcoleApplication::~ConcoleApplication() = default; //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) int ConcoleApplication::run( int _argc, char * _argv[] ) { ParserArgWrapper arguments; @@ -87,13 +88,17 @@ int ConcoleApplication::run( int _argc, char * _argv[] ) Project & project = *projectPtr; if( arguments.isVerbose() ) + { dump( project ); + } CMakeProjectPtr cmakeProjectPtr = createCMakeProject( arguments, configurationFilePtr.get() ); if( arguments.isVerbose() && cmakeProjectPtr ) + { dump( *cmakeProjectPtr ); + } ModelPtr modelPtr = runAnalyzer( project, cmakeProjectPtr.get() ); if( !modelPtr ) @@ -120,7 +125,6 @@ int ConcoleApplication::run( int _argc, char * _argv[] ) runReporters( model, reports, *settingsPtr ); return EXIT_SUCCESS; - } //------------------------------------------------------------------------------ @@ -177,10 +181,16 @@ ConcoleApplication::ModelPtr ConcoleApplication::runAnalyzer( return nullptr; } - if( _cmakeProject ) - return analyzerPtr->analyze( _project, *_cmakeProject ); + ModelPtr result; + if( _cmakeProject != nullptr) + { + result = analyzerPtr->analyze( _project, *_cmakeProject ); + } else - return analyzerPtr->analyze( _project ); + { + result = analyzerPtr->analyze( _project ); + } + return result; } //------------------------------------------------------------------------------ @@ -315,7 +325,7 @@ Log & ConcoleApplication::getLog() { if( !m_log ) { - m_log.reset( new Log{ std::cout, std::cerr } ); + m_log = std::make_unique< Log >( std::cout, std::cerr ); } return *m_log; } @@ -327,7 +337,7 @@ void ConcoleApplication::dump( const Project & _project ) const std::cout << "project directory : " << _project.getProjectDir() << std::endl; const Project::IncludeDirIndex includeDirsCount = _project.getIncludeDirsCount(); - if( includeDirsCount ) + if( includeDirsCount > 0 ) { std::cout << "Include dirs:\n"; for( Project::IncludeDirIndex i = 0; i < includeDirsCount; ++i ) diff --git a/src/application/app_con.hpp b/src/application/app_con.hpp index 401ff2d..7aedd61 100644 --- a/src/application/app_con.hpp +++ b/src/application/app_con.hpp @@ -60,7 +60,6 @@ namespace application { class ConcoleApplication { public: - ConcoleApplication(); ~ConcoleApplication(); @@ -149,7 +148,6 @@ class ConcoleApplication void showVersion(); private: - PluginPtr< ProjectAccessor > m_projectAccessor; PluginPtr< ModelIncludesAccessor > m_modelIncludesAccessor; PluginPtr< fs::FileSystemAccessor > m_fileSystemAccessor; @@ -161,7 +159,6 @@ class ConcoleApplication ParserPtr m_parser; std::unique_ptr< Log > m_log; - }; //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_base_exception_impl.hpp b/src/application/exceptions/app_base_exception_impl.hpp index c318496..66f46a0 100644 --- a/src/application/exceptions/app_base_exception_impl.hpp +++ b/src/application/exceptions/app_base_exception_impl.hpp @@ -6,23 +6,20 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ template< class _BaseException > class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > { public: - - using BaseClass = ::exception::ExceptionImpl< _BaseException >; + using BaseClass = ::exception::ExceptionImpl< _BaseException >; explicit BaseExceptionImpl( std::string_view _code ) - : BaseClass{ resources::exceptions::ModuleName, _code } + : BaseClass{ resources::exceptions::ModuleName, _code } { - } - }; //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_base_exception_with_message_impl.hpp b/src/application/exceptions/app_base_exception_with_message_impl.hpp index 39ddb87..039a9ce 100644 --- a/src/application/exceptions/app_base_exception_with_message_impl.hpp +++ b/src/application/exceptions/app_base_exception_with_message_impl.hpp @@ -6,8 +6,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ template< class _BaseException > @@ -15,7 +15,6 @@ class BaseExceptionWithMessageImpl : public ::exception::ExceptionWithMessageImpl< _BaseException > { public: - using BaseClass = ::exception::ExceptionWithMessageImpl< _BaseException >; BaseExceptionWithMessageImpl( @@ -24,9 +23,7 @@ class BaseExceptionWithMessageImpl : public ) : BaseClass{ resources::exceptions::ModuleName, _code, _message } { - } - }; //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_analyzer.cpp b/src/application/exceptions/app_cant_create_analyzer.cpp index 700af54..8803ee6 100644 --- a/src/application/exceptions/app_cant_create_analyzer.cpp +++ b/src/application/exceptions/app_cant_create_analyzer.cpp @@ -4,8 +4,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ CantCreateAnalyzerImpl::CantCreateAnalyzerImpl() @@ -14,7 +14,6 @@ CantCreateAnalyzerImpl::CantCreateAnalyzerImpl() resources::exceptions::CantCreateAnalyzer::Msg ) { - } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_analyzer.hpp b/src/application/exceptions/app_cant_create_analyzer.hpp index 5ccc62d..f4c825d 100644 --- a/src/application/exceptions/app_cant_create_analyzer.hpp +++ b/src/application/exceptions/app_cant_create_analyzer.hpp @@ -1,21 +1,20 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" #include "application/exceptions/app_base_exception_with_message_impl.hpp" +#include "application/exceptions/app_exceptions.hpp" //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ -class CantCreateAnalyzerImpl : - public BaseExceptionWithMessageImpl< CantCreateAnalyzer > +class CantCreateAnalyzerImpl + : public BaseExceptionWithMessageImpl< CantCreateAnalyzer > { using BaseClass = BaseExceptionWithMessageImpl< CantCreateAnalyzer >; public: - CantCreateAnalyzerImpl(); }; diff --git a/src/application/exceptions/app_cant_create_model_impl.cpp b/src/application/exceptions/app_cant_create_model_impl.cpp index 674adf9..885a6ad 100644 --- a/src/application/exceptions/app_cant_create_model_impl.cpp +++ b/src/application/exceptions/app_cant_create_model_impl.cpp @@ -3,8 +3,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ CantCreateModelImpl::CantCreateModelImpl() @@ -13,7 +13,6 @@ CantCreateModelImpl::CantCreateModelImpl() resources::exceptions::CantCreateModel::Msg ) { - } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_model_impl.hpp b/src/application/exceptions/app_cant_create_model_impl.hpp index 2473a21..a2dab1a 100644 --- a/src/application/exceptions/app_cant_create_model_impl.hpp +++ b/src/application/exceptions/app_cant_create_model_impl.hpp @@ -1,12 +1,12 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" #include "application/exceptions/app_base_exception_with_message_impl.hpp" +#include "application/exceptions/app_exceptions.hpp" //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ class CantCreateModelImpl : @@ -15,7 +15,6 @@ class CantCreateModelImpl : using BaseClass = BaseExceptionWithMessageImpl< CantCreateModel >; public: - CantCreateModelImpl(); }; diff --git a/src/application/exceptions/app_cant_create_project_impl.cpp b/src/application/exceptions/app_cant_create_project_impl.cpp index 5aa536f..f12d5b1 100644 --- a/src/application/exceptions/app_cant_create_project_impl.cpp +++ b/src/application/exceptions/app_cant_create_project_impl.cpp @@ -4,8 +4,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ CantCreateProjectImpl::CantCreateProjectImpl() @@ -14,7 +14,6 @@ CantCreateProjectImpl::CantCreateProjectImpl() resources::exceptions::CantCreateProject::Msg ) { - } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_project_impl.hpp b/src/application/exceptions/app_cant_create_project_impl.hpp index 7efb118..326494f 100644 --- a/src/application/exceptions/app_cant_create_project_impl.hpp +++ b/src/application/exceptions/app_cant_create_project_impl.hpp @@ -1,12 +1,12 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" #include "application/exceptions/app_base_exception_with_message_impl.hpp" +#include "application/exceptions/app_exceptions.hpp" //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ class CantCreateProjectImpl : @@ -15,7 +15,6 @@ class CantCreateProjectImpl : using BaseClass = BaseExceptionWithMessageImpl< CantCreateProject >; public: - CantCreateProjectImpl(); }; diff --git a/src/application/exceptions/app_cant_create_report_impl.cpp b/src/application/exceptions/app_cant_create_report_impl.cpp index b482c54..c48a72d 100644 --- a/src/application/exceptions/app_cant_create_report_impl.cpp +++ b/src/application/exceptions/app_cant_create_report_impl.cpp @@ -1,7 +1,7 @@ #include "application/exceptions/app_cant_create_report_impl.hpp" -#include "application/resources/app_resources_exceptions.hpp" #include "application/resources/app_resources_arguments.hpp" +#include "application/resources/app_resources_exceptions.hpp" #include "reporter/tools/rp_reporter_kind_functins.hpp" @@ -9,15 +9,14 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ CantCreateReportImpl::CantCreateReportImpl( reporter::ReporterKind _kind ) : BaseClass( resources::exceptions::CantCreateReport::Code ) , m_kind{ _kind } { - } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_create_report_impl.hpp b/src/application/exceptions/app_cant_create_report_impl.hpp index 1dde2e7..d711188 100644 --- a/src/application/exceptions/app_cant_create_report_impl.hpp +++ b/src/application/exceptions/app_cant_create_report_impl.hpp @@ -1,14 +1,14 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" #include "application/exceptions/app_base_exception_impl.hpp" +#include "application/exceptions/app_exceptions.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ class CantCreateReportImpl : public BaseExceptionImpl< CantCreateReport > @@ -16,17 +16,14 @@ class CantCreateReportImpl : public BaseExceptionImpl< CantCreateReport > using BaseClass = BaseExceptionImpl< CantCreateReport >; public: - CantCreateReportImpl( reporter::ReporterKind _kind ); std::string getMessage() const noexcept override; private: - static std::string toString( reporter::ReporterKind _kind ); private: - const reporter::ReporterKind m_kind; }; diff --git a/src/application/exceptions/app_cant_load_reporter_settings.cpp b/src/application/exceptions/app_cant_load_reporter_settings.cpp index 6e5dc9b..89afc6a 100644 --- a/src/application/exceptions/app_cant_load_reporter_settings.cpp +++ b/src/application/exceptions/app_cant_load_reporter_settings.cpp @@ -4,8 +4,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ CantLoadReporterSettingsImpl::CantLoadReporterSettingsImpl() @@ -14,7 +14,6 @@ CantLoadReporterSettingsImpl::CantLoadReporterSettingsImpl() resources::exceptions::CantLoadReporterSettings::Msg ) { - } //------------------------------------------------------------------------------ diff --git a/src/application/exceptions/app_cant_load_reporter_settings.hpp b/src/application/exceptions/app_cant_load_reporter_settings.hpp index c54fda2..89f2ed3 100644 --- a/src/application/exceptions/app_cant_load_reporter_settings.hpp +++ b/src/application/exceptions/app_cant_load_reporter_settings.hpp @@ -1,12 +1,12 @@ #pragma once -#include "application/exceptions/app_exceptions.hpp" #include "application/exceptions/app_base_exception_with_message_impl.hpp" +#include "application/exceptions/app_exceptions.hpp" //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ class CantLoadReporterSettingsImpl : @@ -15,7 +15,6 @@ class CantLoadReporterSettingsImpl : using BaseClass = BaseExceptionWithMessageImpl< CantLoadReporterSettings >; public: - CantLoadReporterSettingsImpl(); }; diff --git a/src/application/exceptions/app_exceptions.hpp b/src/application/exceptions/app_exceptions.hpp index 2a66f3e..02aabc5 100644 --- a/src/application/exceptions/app_exceptions.hpp +++ b/src/application/exceptions/app_exceptions.hpp @@ -4,8 +4,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ class Exception : public exception::Exception {}; diff --git a/src/application/resources/app_resources_arguments.cpp b/src/application/resources/app_resources_arguments.cpp index 04f17d2..8780c38 100644 --- a/src/application/resources/app_resources_arguments.cpp +++ b/src/application/resources/app_resources_arguments.cpp @@ -17,6 +17,7 @@ namespace application::resources::arguments { namespace projectDir { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::ProjectDir; const char * const Description = "Project directory"; const char * const DefaultValue = "."; @@ -26,15 +27,18 @@ namespace projectDir { namespace fileExtensions { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::FileExtensions; const char * const Description = "Extensions C++ files"; - const char * const DefaultValue[] = {"*.cpp", "*.hpp", "*.c", "*.h", "*.cxx", "*.hxx", nullptr}; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) + const char * const DefaultValue[] = { "*.cpp", "*.hpp", "*.c", "*.h", "*.cxx", "*.hxx", nullptr }; } //------------------------------------------------------------------------------ namespace analyze_without_extension { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::AnalyzeWithoutExtension; const char * const Description = "Analyze files without extension (default: false)"; const bool DefaultValue = false; @@ -44,24 +48,29 @@ namespace analyze_without_extension { namespace includeDirs { - const char * const FullName = configuration_file::IncludeDirs ; + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) + const char * const FullName = configuration_file::IncludeDirs; const char * const Description = "Include directories"; - const char * const DefaultValue[] = {".", nullptr}; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) + const char * const DefaultValue[] = { ".", nullptr }; } //------------------------------------------------------------------------------ namespace ignoreDirs { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::IgnoreDirs; const char * const Description = "Directories that will be ignored"; - const char * const DefaultValue[] = {nullptr}; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) + const char * const DefaultValue[] = { nullptr }; } //------------------------------------------------------------------------------ namespace ignoreSystemIncludes { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::IgnoreSystemIncludes; const char * const Description = "Ignore headers in <> (default: false)"; const bool DefaultValue = false; @@ -71,9 +80,11 @@ namespace ignoreSystemIncludes { namespace ignoreFiles { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::IgnoreFiles; const char * const Description = "Files will be ignored by regexp"; - const char * const DefaultValue[] = {nullptr}; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) + const char * const DefaultValue[] = { nullptr }; } //------------------------------------------------------------------------------ @@ -89,6 +100,7 @@ namespace configurationFile { namespace compileCommands { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::CompileCommands; const char * const Description = "Path to JSON Compilation Database"; const char * const DefaultValue = "compile_commands.json"; @@ -124,9 +136,11 @@ namespace report { using namespace reporter::resources; - const char * const FullName = configuration_file::Report; + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) + const char * const FullName = configuration_file::Report; - static_assert( static_cast< int >( reporter::ReporterKind::Count ) == 5 ); + constexpr int ReporterKindCount = 5; + static_assert( static_cast< int >( reporter::ReporterKind::Count ) == ReporterKindCount ); const char * const Description = "List of reports. Name of reports: " "unresolved, " @@ -135,6 +149,7 @@ namespace report { "different_type" ; + // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays, cppcoreguidelines-interfaces-global-init) const char * const DefaultValue[] = { unresolved_report::Name, most_impact_report::Name, @@ -148,6 +163,7 @@ namespace report { namespace report_limit { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::ReportLimit; const char * const Description = "Maximum elements in report, 0 - unlimited"; const int DefaultValue = 10; @@ -157,6 +173,7 @@ namespace report_limit { namespace report_details_limit { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::ReportDetailsLimit; const char * const Description = "Maximum details in report, 0 - unlimited"; const int DefaultValue = 10; @@ -166,6 +183,7 @@ namespace report_details_limit { namespace show_std_files { + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) const char * const FullName = configuration_file::ShowStdFiles; const char * const Description = "Show standard library headers in output (default: false)"; const bool DefaultValue = false; diff --git a/src/application/resources/app_resources_version.cpp b/src/application/resources/app_resources_version.cpp index c7714f4..7d13aec 100644 --- a/src/application/resources/app_resources_version.cpp +++ b/src/application/resources/app_resources_version.cpp @@ -8,7 +8,7 @@ namespace application::resources::version { const int Major = 0; const int Minor = 3; - const int Path = 0; + const int Path = 1; const char * const VersionFormat = "{}.{}.{}\n"; diff --git a/src/application/test/app_test_main.cpp b/src/application/test/app_test_main.cpp index f3534f5..ae9f217 100644 --- a/src/application/test/app_test_main.cpp +++ b/src/application/test/app_test_main.cpp @@ -1,10 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE app_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } - diff --git a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp index 672e8ff..911e0fd 100644 --- a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp +++ b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.cpp @@ -1,8 +1,8 @@ #include "application/test/fixtures/app_test_cmake_project_builder_fixture.hpp" #include "application/tools/app_cmake_project_builder.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" #include "cmake_project/api/cprj_project.hpp" #include "cmake_project/ih/cprj_accessor_impl.hpp" @@ -10,9 +10,9 @@ #include "compilation_db/ih/cdb_accessor_impl.hpp" #include "json/ih/json_accessor_impl.hpp" -#include "fs/api/fs_file_system.hpp" -#include "fs/api/fs_file.hpp" #include "fs/api/fs_factory.hpp" +#include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" #include "fs/ih/fs_accessor_impl.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -21,12 +21,12 @@ #include +#include #include -#include +#include #include +#include #include -#include -#include //------------------------------------------------------------------------------ @@ -53,7 +53,7 @@ void CMakeProjectBuilderFixture::buildProject() bool CMakeProjectBuilderFixture::isInitializedProject() const { - return m_cmakeProject.get(); + return m_cmakeProject != nullptr; } //------------------------------------------------------------------------------ @@ -65,7 +65,7 @@ void CMakeProjectBuilderFixture::addCMakeFile( { fs::FileSystem & fs = ensureFileSystem(); auto filePtr = fs.createFile( toRelativePath( _path ) ); - INTERNAL_CHECK_ERROR( filePtr ); + INTERNAL_CHECK_ERROR( filePtr != nullptr ); fs::File & file = *filePtr; file << _text; } @@ -85,7 +85,7 @@ void CMakeProjectBuilderFixture::setCompilationFileInConfigurationFile( CMakeProjectBuilderFixture::Strings CMakeProjectBuilderFixture::getResultsFiles() { - INTERNAL_CHECK_ERROR( m_cmakeProject ); + INTERNAL_CHECK_ERROR( m_cmakeProject != nullptr ); const cmake_project::Project & project = *m_cmakeProject; Strings result; project.forEachFilePath( [&]( const Path & _path ){ @@ -103,7 +103,7 @@ CMakeProjectBuilderFixture::Strings CMakeProjectBuilderFixture::getResultIncludes( std::string_view _file ) { Strings result; - INTERNAL_CHECK_ERROR( m_cmakeProject ); + INTERNAL_CHECK_ERROR( m_cmakeProject != nullptr ); m_cmakeProject->forEachIncludes( _file, [&]( const Path & _include ) @@ -141,15 +141,13 @@ CMakeProjectBuilderFixture::Path CMakeProjectBuilderFixture::toRelativePath( //------------------------------------------------------------------------------ -void CMakeProjectBuilderFixture::parserArgument( - std::string_view _argument -) +void CMakeProjectBuilderFixture::parserArgument( std::string_view _argument ) { ParserArgWrapper & arguments = ensureArguments(); std::vector< std::string > argumentsStr; - argumentsStr.push_back( "./application" ); - argumentsStr.push_back( std::string{ _argument } ); + argumentsStr.emplace_back( "./application" ); + argumentsStr.emplace_back( std::string{ _argument } ); arguments.parse( argumentsStr ); } @@ -160,16 +158,15 @@ CMakeProjectBuilder & CMakeProjectBuilderFixture::ensureBuilder() { if( !m_builder ) { - m_builder.reset( new CMakeProjectBuilder{ + m_builder = std::make_unique< CMakeProjectBuilder >( ensureCMakeAccessor(), ensureCompilationDbAccessor(), ensureJsonAccessor(), ensureFileSystem() - } ); + ); } return *m_builder; - } //------------------------------------------------------------------------------ @@ -178,7 +175,7 @@ ParserArgWrapper & CMakeProjectBuilderFixture::ensureArguments() { if( !m_arguments ) { - m_arguments.reset( new ParserArgWrapper ); + m_arguments = std::make_unique< ParserArgWrapper >(); m_arguments->init(); } @@ -190,7 +187,9 @@ ParserArgWrapper & CMakeProjectBuilderFixture::ensureArguments() ConfigurationFile & CMakeProjectBuilderFixture::ensureConfigurationFile() { if( !m_configurationFile ) - m_configurationFile.reset( new ConfigurationFile ); + { + m_configurationFile = std::make_unique< ConfigurationFile >(); + } return *m_configurationFile; } @@ -207,7 +206,9 @@ fs::FileSystem & CMakeProjectBuilderFixture::ensureFileSystem() fs::FileSystemAccessor & CMakeProjectBuilderFixture::ensureFileSystemAccessor() { if( !m_fsAccessor ) - m_fsAccessor.reset( new fs::FileSystemAccessorImpl ); + { + m_fsAccessor = std::make_unique< fs::FileSystemAccessorImpl >(); + } return *m_fsAccessor; } @@ -217,7 +218,9 @@ fs::FileSystemAccessor & CMakeProjectBuilderFixture::ensureFileSystemAccessor() cmake_project::Accessor & CMakeProjectBuilderFixture::ensureCMakeAccessor() { if( !m_cmakeAccessor ) - m_cmakeAccessor.reset( new cmake_project::AccessorImpl ); + { + m_cmakeAccessor = std::make_unique< cmake_project::AccessorImpl >(); + } return *m_cmakeAccessor; } @@ -227,7 +230,9 @@ cmake_project::Accessor & CMakeProjectBuilderFixture::ensureCMakeAccessor() compilation_db::Accessor & CMakeProjectBuilderFixture::ensureCompilationDbAccessor() { if( !m_compilationDbAccessor ) - m_compilationDbAccessor.reset( new compilation_db::AccessorImpl ); + { + m_compilationDbAccessor = std::make_unique< compilation_db::AccessorImpl >(); + } return *m_compilationDbAccessor; } @@ -237,7 +242,9 @@ compilation_db::Accessor & CMakeProjectBuilderFixture::ensureCompilationDbAccess json::JsonAccessor & CMakeProjectBuilderFixture::ensureJsonAccessor() { if( !m_jsonAccessor ) - m_jsonAccessor.reset( new json::JsonAccesorImpl ); + { + m_jsonAccessor = std::make_unique< json::JsonAccesorImpl >(); + } return *m_jsonAccessor; } diff --git a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp index 4739efb..27aa858 100644 --- a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp +++ b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp @@ -30,7 +30,6 @@ namespace json { class JsonAccessor; } - //------------------------------------------------------------------------------ namespace application::test { @@ -40,7 +39,6 @@ namespace application::test { class CMakeProjectBuilderFixture { public: - using Strings = stdfwd::set< std::string >; using Path = stdfs::path; @@ -59,7 +57,6 @@ class CMakeProjectBuilderFixture Strings toExceptedFiles( const Strings & _strings ); private: - Path toRelativePath( std::string_view _path ); CMakeProjectBuilder & ensureBuilder(); @@ -75,7 +72,6 @@ class CMakeProjectBuilderFixture json::JsonAccessor & ensureJsonAccessor(); private: - std::unique_ptr< CMakeProjectBuilder > m_builder; std::unique_ptr< ParserArgWrapper > m_arguments; std::unique_ptr< ConfigurationFile > m_configurationFile; diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp index 7a2b3ea..2475cad 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp @@ -4,15 +4,15 @@ #include "exception/ih/exc_internal_error.hpp" -#include "json/ih/json_accessor_impl.hpp" #include "json/api/json_object.hpp" +#include "json/ih/json_accessor_impl.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/tools/rp_reporter_kind_functins.hpp" #include -#include #include +#include //------------------------------------------------------------------------------ @@ -30,7 +30,7 @@ void ConfigurationfileFixture::loadFromJson( std::string_view _json ) std::stringstream stream; stream << _json; auto jsonPtr = getJsonAccessor().createJson( stream ); - INTERNAL_CHECK_ERROR( jsonPtr ); + INTERNAL_CHECK_ERROR( jsonPtr != nullptr ); const json::JsonObject & json = *jsonPtr; ensureConfigurationFile().loadFromJson( json ); } @@ -135,14 +135,18 @@ ConfigurationfileFixture::StringOpt ConfigurationfileFixture::toStirng( const StringsOpt & _arrayOpt ) { if( !_arrayOpt ) + { return std::nullopt; + } std::string result; for( const std::string & str : *_arrayOpt ) { if( !result.empty() ) + { result += ','; + } result += str; } @@ -173,7 +177,9 @@ ConfigurationfileFixture::StringOpt ConfigurationfileFixture::arrayToString( const _ArrayTypeOpt & _arrayOpt ) { if( !_arrayOpt ) + { return std::nullopt; + } Strings strings; @@ -204,7 +210,7 @@ std::string ConfigurationfileFixture::toString( reporter::ReporterKind _kind ) const ConfigurationFile & ConfigurationfileFixture::getConfigurationFile() const { - INTERNAL_CHECK_ERROR( m_file ); + INTERNAL_CHECK_ERROR( m_file != nullptr ); return *m_file; } @@ -213,7 +219,9 @@ const ConfigurationFile & ConfigurationfileFixture::getConfigurationFile() const ConfigurationFile & ConfigurationfileFixture::ensureConfigurationFile() { if( !m_file ) - m_file.reset( new ConfigurationFile ); + { + m_file = std::make_unique< ConfigurationFile >(); + } return *m_file; } diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp index 914b121..df4bb9b 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp @@ -2,8 +2,8 @@ #include "application/tools/app_plugin_ptr.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -77,14 +77,12 @@ class ConfigurationfileFixture static std::string toString( const Path & _path ); private: - const ConfigurationFile & getConfigurationFile() const; ConfigurationFile & ensureConfigurationFile(); json::JsonAccessor & getJsonAccessor(); private: - std::unique_ptr< ConfigurationFile > m_file; PluginPtr< json::JsonAccessor > m_json; diff --git a/src/application/test/fixtures/app_test_parser_fixture.cpp b/src/application/test/fixtures/app_test_parser_fixture.cpp index dc5540b..2bdf821 100644 --- a/src/application/test/fixtures/app_test_parser_fixture.cpp +++ b/src/application/test/fixtures/app_test_parser_fixture.cpp @@ -4,10 +4,10 @@ #include "exception/ih/exc_internal_error.hpp" -#include #include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -99,12 +99,14 @@ void ParserArgumentsFixture::addArgument( void ParserArgumentsFixture::parseArguments( const Strings & _arguments ) { Strings argument{ _arguments }; - argument.insert( argument.begin(), " " ); + argument.insert( argument.begin(), " " ); std::vector< char * > arg; arg.reserve( _arguments.size() ); for( std::string & str : argument ) + { arg.push_back( str.data() ); + } getPatser().parse( static_cast< int >( arg.size() ), arg.data() ); } @@ -124,7 +126,9 @@ ParserArgumentsFixture::getArgumentStringsValue( std::string_view _arg ) const { StringsOpt stringsOpt{ getPatser().getArgumentStringsValue( _arg ) }; if( stringsOpt ) + { return toString( *stringsOpt ); + } return std::nullopt; } @@ -155,7 +159,9 @@ ParserArgumentsFixture::StringOpt ParserArgumentsFixture::getArgumentPathValue( { PathOpt pathOpt{ getPatser().getArgumentPathValue( _arg ) }; if( pathOpt ) + { return pathOpt->string(); + } return std::nullopt; } @@ -168,7 +174,9 @@ ParserArgumentsFixture::StringOpt ParserArgumentsFixture::getArgumentPathsValue( { PathsOpt pathsOpt{ getPatser().getArgumentPathsValue( _arg ) }; if( pathsOpt ) + { return toString( *pathsOpt ); + } return std::nullopt; } @@ -191,7 +199,9 @@ std::string ParserArgumentsFixture::toString( const Strings & _strings ) for( const std::string & str : _strings ) { if( !result.empty() ) + { result += seperator; + } result += str; } return result; @@ -206,7 +216,9 @@ std::string ParserArgumentsFixture::toString( const Paths & _paths ) for( const Path & path : _paths ) { if( !result.empty() ) + { result += seperator; + } result += path.string(); } return result; @@ -232,7 +244,9 @@ const ParserArg & ParserArgumentsFixture::getPatser() const ParserArg & ParserArgumentsFixture::getPatser() { if( !m_parserPtr ) - m_parserPtr.reset( new ParserArg ); + { + m_parserPtr = std::make_unique< ParserArg >(); + } return *m_parserPtr; } diff --git a/src/application/test/fixtures/app_test_parser_fixture.hpp b/src/application/test/fixtures/app_test_parser_fixture.hpp index 3eaad7a..d0fc18e 100644 --- a/src/application/test/fixtures/app_test_parser_fixture.hpp +++ b/src/application/test/fixtures/app_test_parser_fixture.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -18,7 +18,6 @@ namespace application::test { class ParserArgumentsFixture { public: - ParserArgumentsFixture(); ~ParserArgumentsFixture(); @@ -88,14 +87,11 @@ class ParserArgumentsFixture static std::string toString( const Paths & _paths ); private: - const ParserArg & getPatser() const; ParserArg & getPatser(); private: - std::unique_ptr< ParserArg > m_parserPtr; - }; //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp index 69323d7..6f75734 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp @@ -1,7 +1,7 @@ #include "application/test/fixtures/app_test_parser_wrapper_fixture.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" #include "application/resources/app_resources_arguments.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/tools/rp_reporter_kind_functins.hpp" @@ -35,9 +35,9 @@ void ParserWrapperFixture::parse( std::string_view _argument ) void ParserWrapperFixture::parse( const Arguments & _arguments ) { Arguments arguments{ _arguments }; - arguments.insert( arguments.begin(), "./application" ); + arguments.insert( arguments.begin(), "./application" ); - ParserArgWrapper & parser = getParser(); + ParserArgWrapper & parser = getParser(); parser.parse( arguments ); } @@ -45,26 +45,27 @@ void ParserWrapperFixture::parse( const Arguments & _arguments ) std::string ParserWrapperFixture::getProjectDir() const { - auto valueOpt = getParser().getProjectDir(); - if( valueOpt ) - { - return valueOpt->string(); - } - else - { - return ""; - } + auto valueOpt = getParser().getProjectDir(); + if( valueOpt ) + { + return valueOpt->string(); + } + + return ""; } //------------------------------------------------------------------------------ -ParserWrapperFixture::StringsArray ParserWrapperFixture::getFileExtensions() const +ParserWrapperFixture::StringsArray +ParserWrapperFixture::getFileExtensions() const { auto valueOpt = getParser().getFileExtensions(); - if( valueOpt ) - return *valueOpt; + if( valueOpt ) + { + return *valueOpt; + } - return StringsArray{}; + return StringsArray{}; } //------------------------------------------------------------------------------ @@ -98,43 +99,47 @@ bool ParserWrapperFixture::getDefaultAnalyzeWithoutExtension() const std::string ParserWrapperFixture::getDefaultProjectDir() const { - return getParser().getDefaultProjectDir().string(); + return getParser().getDefaultProjectDir().string(); } //------------------------------------------------------------------------------ ParserWrapperFixture::Paths ParserWrapperFixture::getIncludeDirs() const { - auto valueOpt = getParser().getIncludeDirs(); - if( valueOpt ) - return *valueOpt; + auto valueOpt = getParser().getIncludeDirs(); + if( valueOpt ) + { + return *valueOpt; + } - return Paths{}; + return Paths{}; } //------------------------------------------------------------------------------ ParserWrapperFixture::Paths ParserWrapperFixture::getDefaultIncludeDirs() const { - return getParser().getDefaultIncludeDirs(); + return getParser().getDefaultIncludeDirs(); } //------------------------------------------------------------------------------ ParserWrapperFixture::Paths ParserWrapperFixture::getIgnoreDirs() const { - auto valueOpt = getParser().getIgnoreDirs(); - if( valueOpt ) - return *valueOpt; + auto valueOpt = getParser().getIgnoreDirs(); + if( valueOpt ) + { + return *valueOpt; + } - return Paths{}; + return Paths{}; } //------------------------------------------------------------------------------ ParserWrapperFixture::Paths ParserWrapperFixture::getDefaultIgnoreDirs() const { - return getParser().getDefaultIgnoreDirs(); + return getParser().getDefaultIgnoreDirs(); } //------------------------------------------------------------------------------ @@ -143,7 +148,9 @@ std::string ParserWrapperFixture::getIgnoreFiles() const { auto valueOpt = getParser().getIgnoreFiles(); if( valueOpt ) + { return toString( *valueOpt ); + } return std::string{}; } @@ -174,11 +181,13 @@ bool ParserWrapperFixture::getDefaultIgnoreSystemIncludes() const ParserWrapperFixture::Path ParserWrapperFixture::getConfigurationFile() const { - auto valueOpt = getParser().getConfigurationFile(); - if( valueOpt ) - return *valueOpt; + auto valueOpt = getParser().getConfigurationFile(); + if( valueOpt ) + { + return *valueOpt; + } - return Path{}; + return Path{}; } //------------------------------------------------------------------------------ @@ -187,7 +196,9 @@ ParserWrapperFixture::Path ParserWrapperFixture::getCompileCommandsFile() const { auto valueOpt = getParser().getCompileCommandsFile(); if( valueOpt ) + { return *valueOpt; + } return Path{}; } @@ -212,7 +223,9 @@ ParserWrapperFixture::ReporterKinds ParserWrapperFixture::getReporterKinds() con { auto kindsOpt = getParser().getReporterKinds(); if( kindsOpt ) + { return *kindsOpt; + } return ReporterKinds{}; } @@ -230,7 +243,9 @@ int ParserWrapperFixture::getReportLimit() const { auto numberOpt = getParser().getReportLimit(); if( numberOpt ) + { return *numberOpt; + } return -1; } @@ -247,7 +262,9 @@ int ParserWrapperFixture::getReportDetailsLimit() const { auto numberOpt = getParser().getReportDetailsLimit(); if( numberOpt ) + { return *numberOpt; + } return -1; } @@ -276,7 +293,7 @@ bool ParserWrapperFixture::getDefaultShowStdFile() const bool ParserWrapperFixture::isHelp() const { - return getParser().isHelp(); + return getParser().isHelp(); } //------------------------------------------------------------------------------ @@ -297,30 +314,34 @@ bool ParserWrapperFixture::isVersion() const std::string ParserWrapperFixture::toString( const StringsArray & _array ) const { - std::string result; - for( std::size_t i = 0; i < _array.size(); ++i ) - { - const std::string str = _array[i]; - result += str; - if( i != _array.size() - 1 ) - result += ','; - } - return result; + std::string result; + for( std::size_t i = 0; i < _array.size(); ++i ) + { + const std::string str = _array[i]; + result += str; + if( i != _array.size() - 1 ) + { + result += ','; + } + } + return result; } //------------------------------------------------------------------------------ std::string ParserWrapperFixture::toString( const Paths & _array ) const { - std::string result; - for( std::size_t i = 0; i < _array.size(); ++i ) - { - const std::string str = _array[i].string(); - result += str; - if( i != _array.size() - 1 ) - result += ','; - } - return result; + std::string result; + for( std::size_t i = 0; i < _array.size(); ++i ) + { + const std::string str = _array[i].string(); + result += str; + if( i != _array.size() - 1 ) + { + result += ','; + } + } + return result; } //------------------------------------------------------------------------------ @@ -347,33 +368,36 @@ std::string ParserWrapperFixture::toString( reporter::ReporterKind _kind ) const //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) std::string ParserWrapperFixture::toString( const char * const _values[] ) const { - std::string result; - const char * const * it = _values; - while( *it ) - { - if( !result.empty() ) - result += ',' ; - - const std::string str{ *it }; - ++it; - result += str; - - } - return result; + std::string result; + const char * const * it = _values; + while( *it != nullptr ) + { + if( !result.empty() ) + { + result += ','; + } + + const std::string str{ *it }; + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + ++it; + result += str; + } + return result; } //------------------------------------------------------------------------------ ParserArgWrapper & ParserWrapperFixture::getParser() const { - if( !m_parser ) - { - m_parser.reset( new ParserArgWrapper ); + if( !m_parser ) + { + m_parser = std::make_unique< ParserArgWrapper >(); m_parser->init(); - } - return *m_parser; + } + return *m_parser; } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp index 922e410..2f0fe9b 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -24,35 +24,34 @@ namespace application::test { class ParserWrapperFixture { public: + using Arguments = stdfwd::vector< std::string >; + using StringsArray = stdfwd::vector< std::string >; + using Path = stdfs::path; + using Paths = stdfwd::vector< Path >; + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; - using Arguments = stdfwd::vector< std::string >; - using StringsArray = stdfwd::vector< std::string >; - using Path = stdfs::path; - using Paths = stdfwd::vector< Path >; - using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + using BoolOpt = std::optional< bool >; - using BoolOpt = std::optional< bool >; - - ParserWrapperFixture(); - ~ParserWrapperFixture(); + ParserWrapperFixture(); + ~ParserWrapperFixture(); void parse( std::string_view _argument ); void parse( const Arguments & _arguments ); - std::string getProjectDir() const; - std::string getDefaultProjectDir() const; + std::string getProjectDir() const; + std::string getDefaultProjectDir() const; - StringsArray getFileExtensions() const; + StringsArray getFileExtensions() const; StringsArray getDefaultFileExtensions() const; bool getAnalyzeWithoutExtension() const; bool getDefaultAnalyzeWithoutExtension() const; - Paths getIncludeDirs() const; - Paths getDefaultIncludeDirs() const; + Paths getIncludeDirs() const; + Paths getDefaultIncludeDirs() const; - Paths getIgnoreDirs() const; - Paths getDefaultIgnoreDirs() const; + Paths getIgnoreDirs() const; + Paths getDefaultIgnoreDirs() const; std::string getIgnoreFiles() const; std::string getDefaultIgnoreFiles() const; @@ -60,8 +59,8 @@ class ParserWrapperFixture BoolOpt getIgnoreSystemIncludes() const; bool getDefaultIgnoreSystemIncludes() const; - Path getConfigurationFile() const; - Path getDefaultConfigurationFile() const; + Path getConfigurationFile() const; + Path getDefaultConfigurationFile() const; Path getCompileCommandsFile() const; Path getDefaultCompileCommandsFile() const; @@ -78,18 +77,17 @@ class ParserWrapperFixture BoolOpt getShowStdFile() const; bool getDefaultShowStdFile() const; - bool isHelp() const; + bool isHelp() const; bool isVerbose() const; bool isVersion() const; - std::string toString( const StringsArray & _array ) const; - std::string toString( const Paths & _array ) const; + std::string toString( const StringsArray & _array ) const; + std::string toString( const Paths & _array ) const; std::string toString( const ReporterKinds & _array ) const; std::string toString( reporter::ReporterKind _kind ) const; - std::string toString( const char * const _values[] ) const; + std::string toString( const char * const _values[] ) const; private: - ParserArgWrapper & getParser() const; mutable std::unique_ptr< ParserArgWrapper > m_parser; diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.cpp b/src/application/test/fixtures/app_test_project_builder_fixture.cpp index a50dace..e336d20 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.cpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.cpp @@ -1,28 +1,28 @@ #include "application/test/fixtures/app_test_project_builder_fixture.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" -#include "application/tools/app_project_builder.hpp" +#include "application/resources/app_resources_arguments.hpp" #include "application/tools/app_configuration_file.hpp" #include "application/tools/app_configuration_file_loader.hpp" -#include "application/resources/app_resources_arguments.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" +#include "application/tools/app_project_builder.hpp" #include "project/api/prj_project.hpp" #include "project/ih/prj_project_accesso_impl.hpp" #include "json/ih/json_accessor_impl.hpp" -#include "fs/ih/fs_accessor_impl.hpp" -#include "fs/api/fs_file_system.hpp" #include "fs/api/fs_factory.hpp" #include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" +#include "fs/ih/fs_accessor_impl.hpp" #include "exception/ih/exc_internal_error.hpp" -#include -#include -#include #include #include +#include +#include +#include //------------------------------------------------------------------------------ @@ -38,7 +38,7 @@ ProjectBuilderFixture::~ProjectBuilderFixture() = default; void ProjectBuilderFixture::parserArguments( const Arguments & _arguments ) { Arguments arguments{ _arguments }; - arguments.insert( arguments.begin(), "./application" ); + arguments.insert( arguments.begin(), "./application" ); getArgumentParser().parse( arguments ); } @@ -156,7 +156,7 @@ ProjectBuilderFixture::Path ProjectBuilderFixture::getProjectPath() const std::string ProjectBuilderFixture::toAbsolutePath( std::string_view _path ) { - const Path currentPath = getFileSystem().getCurrentPath(); + const Path currentPath = getFileSystem().getCurrentPath(); Path path = currentPath / _path; path = stdfs::lexically_normal( path ); return path.string(); @@ -181,12 +181,15 @@ std::string ProjectBuilderFixture::toString( const _Strings & _strings ) for( const std::string & str : _strings ) { if( first ) + { first = false; + } else + { result += ','; + } result += str; - } return result; } @@ -194,12 +197,13 @@ std::string ProjectBuilderFixture::toString( const _Strings & _strings ) //------------------------------------------------------------------------------ ProjectBuilderFixture::Strings ProjectBuilderFixture::toStrings( +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) const char * const _values[] ) { Strings result; const char * const * it = _values; - while( *it ) + while( *it != nullptr ) { const std::string str{ *it }; result.push_back( str ); @@ -209,6 +213,7 @@ ProjectBuilderFixture::Strings ProjectBuilderFixture::toStrings( //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) std::string ProjectBuilderFixture::toString( const char * const _values[] ) { return toString( toStrings( _values ) ); @@ -220,7 +225,7 @@ ParserArgWrapper & ProjectBuilderFixture::getArgumentParser() { if( !m_parser ) { - m_parser.reset( new ParserArgWrapper ); + m_parser = std::make_unique< ParserArgWrapper >(); m_parser->init(); } return *m_parser; @@ -232,8 +237,9 @@ ProjectBuilder & ProjectBuilderFixture::getBuilder() { if( !m_builder ) { - m_builder.reset( - new ProjectBuilder( getProjectAccessor(), getFileSystem() ) + m_builder = std::make_unique( + getProjectAccessor(), + getFileSystem() ); } return *m_builder; @@ -258,7 +264,8 @@ json::JsonAccessor & ProjectBuilderFixture::getJsonAccessor() fs::FileSystem & ProjectBuilderFixture::getFileSystem() { return m_fs.ensure< fs::FileSystemAccessorImpl >() - .getFactory().getMemoryFileSystem(); + .getFactory() + .getMemoryFileSystem(); } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_project_builder_fixture.hpp index cf910c7..86b32ea 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.hpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.hpp @@ -2,8 +2,8 @@ #include "application/tools/app_plugin_ptr.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -57,7 +57,7 @@ class ProjectBuilderFixture std::string getIncludeDirs() const; std::string getIgnoreDirs() const; - std::size_t getFileFiltersCount() const; + std::size_t getFileFiltersCount() const; bool getIgnoreSystemIncludes() const; std::string getFileExtensions() const; @@ -72,7 +72,6 @@ class ProjectBuilderFixture static std::string toString( const char * const _values[] ); private: - template< class _Strings > static std::string toString( const _Strings & _strings ); @@ -88,13 +87,11 @@ class ProjectBuilderFixture fs::File & getDefaultConfigurationFile(); private: - std::unique_ptr< project::Project > m_project; std::unique_ptr< ParserArgWrapper > m_parser; std::unique_ptr< ProjectBuilder > m_builder; std::unique_ptr< ConfigurationFile > m_configurationFile; - PluginPtr< project::ProjectAccessor > m_projectAccessor; PluginPtr< json::JsonAccessor > m_json; PluginPtr< fs::FileSystemAccessor > m_fs; diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp index a7b621d..f10661e 100644 --- a/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp @@ -1,8 +1,8 @@ #include "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" +#include "application/tools/app_configuration_file.hpp" #include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_report_settings_loader.hpp" -#include "application/tools/app_configuration_file.hpp" #include "reporter/api/rp_settings.hpp" #include "reporter/ih/rp_accessor_impl.hpp" @@ -10,12 +10,12 @@ #include "exception/ih/exc_internal_error.hpp" -#include "json/ih/json_accessor_impl.hpp" #include "json/api/json_object.hpp" +#include "json/ih/json_accessor_impl.hpp" -#include #include #include +#include //------------------------------------------------------------------------------ @@ -31,8 +31,8 @@ ReportSettingsLoaderFixture::~ReportSettingsLoaderFixture() = default; void ReportSettingsLoaderFixture::parserArguments( std::string_view _argument ) { std::vector< std::string > arguments; - arguments.push_back( "./application" ); - arguments.push_back( std::string{ _argument.data() } ); + arguments.emplace_back( "./application" ); + arguments.emplace_back( _argument.data() ); ParserArgWrapper & parserArguments = ensureParserArguments(); parserArguments.parse( arguments ); @@ -135,7 +135,9 @@ ConfigurationFile * ReportSettingsLoaderFixture::getConfigurationFile() const ConfigurationFile & ReportSettingsLoaderFixture::ensureConfigurationFile() { if( !m_configurationFile ) - m_configurationFile.reset( new ConfigurationFile ); + { + m_configurationFile = std::make_unique< ConfigurationFile >(); + } return *m_configurationFile; } @@ -161,7 +163,9 @@ ParserArgWrapper & ReportSettingsLoaderFixture::getArguments() const ReportSettingsLoader & ReportSettingsLoaderFixture::ensureLoader() { if( !m_loader ) - m_loader.reset( new ReportSettingsLoader{ ensureReportFactory() } ); + { + m_loader = std::make_unique( ensureReportFactory() ); + } return *m_loader; } @@ -171,7 +175,9 @@ ReportSettingsLoader & ReportSettingsLoaderFixture::ensureLoader() json::JsonAccessor & ReportSettingsLoaderFixture::ensureJsonAccessor() { if( !m_json ) - m_json.reset( new json::JsonAccesorImpl ); + { + m_json = std::make_unique< json::JsonAccesorImpl >(); + } return *m_json; } @@ -182,7 +188,7 @@ ParserArgWrapper & ReportSettingsLoaderFixture::ensureParserArguments() { if( !m_arguments ) { - m_arguments.reset( new ParserArgWrapper ); + m_arguments = std::make_unique< ParserArgWrapper >(); m_arguments->init(); } @@ -201,7 +207,9 @@ reporter::Factory & ReportSettingsLoaderFixture::ensureReportFactory() reporter::ReporterAccessor & ReportSettingsLoaderFixture::ensureReporterAccessor() { if( !m_reporterAccessor ) - m_reporterAccessor.reset( new reporter::ReporterAccessorImpl ); + { + m_reporterAccessor = std::make_unique< reporter::ReporterAccessorImpl >( ); + } return *m_reporterAccessor; } @@ -223,7 +231,9 @@ std::string ReportSettingsLoaderFixture::toString( for( const std::string & name : names ) { if( !result.empty() ) + { result += ','; + } result += name; } diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp index 4c72e54..b125799 100644 --- a/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp @@ -34,8 +34,7 @@ namespace application::test { class ReportSettingsLoaderFixture { public: - - using CountType = std::size_t; + using CountType = std::size_t; ReportSettingsLoaderFixture(); ~ReportSettingsLoaderFixture(); @@ -58,8 +57,7 @@ class ReportSettingsLoaderFixture std::string getDefaultReports() const; private: - - using ReporterKinds = std::vector< reporter::ReporterKind >; + using ReporterKinds = std::vector< reporter::ReporterKind >; ConfigurationFile * getConfigurationFile() const; ConfigurationFile & ensureConfigurationFile(); @@ -78,7 +76,6 @@ class ReportSettingsLoaderFixture static std::string toString( const ReporterKinds & _reports ); private: - std::unique_ptr< reporter::ReporterAccessor > m_reporterAccessor; std::unique_ptr< ReportSettingsLoader > m_loader; std::unique_ptr< ParserArgWrapper > m_arguments; @@ -89,7 +86,6 @@ class ReportSettingsLoaderFixture std::unique_ptr< ConfigurationFile > m_configurationFile; ReporterKinds m_reportKinds; - }; //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_cmake_project_builder.cpp b/src/application/test/suits/app_test_cmake_project_builder.cpp index 28dc1c6..d2b6675 100644 --- a/src/application/test/suits/app_test_cmake_project_builder.cpp +++ b/src/application/test/suits/app_test_cmake_project_builder.cpp @@ -4,7 +4,9 @@ #include "application/resources/app_resources_arguments.hpp" -#include +#include "test_tools/test_macros.hpp" + +#include "test_tools/test_macros.hpp" #include #include @@ -26,22 +28,23 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(CMakeProjectBuildersTets, CMakeProjectBuilderFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( CMakeProjectBuildersTets, CMakeProjectBuilderFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_file_not_exist) +TEST_CASE( t1_file_not_exist ) { - //Run + // Run buildProject(); - //Check - BOOST_CHECK( !isInitializedProject() ); + // Check + TEST_CHECK( !isInitializedProject() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_default_compilation_file_exist) +TEST_CASE( t2_default_compilation_file_exist ) { // Init addCMakeFile( @@ -60,11 +63,11 @@ BOOST_AUTO_TEST_CASE(t2_default_compilation_file_exist) ])" ); - //Run + // Run buildProject(); - //Check - BOOST_REQUIRE( isInitializedProject() ); + // Check + TEST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -72,7 +75,7 @@ BOOST_AUTO_TEST_CASE(t2_default_compilation_file_exist) "/tmp/project/file2.cpp" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -82,7 +85,7 @@ BOOST_AUTO_TEST_CASE(t2_default_compilation_file_exist) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_compilation_file_from_arguments) +TEST_CASE( t3_compilation_file_from_arguments ) { // Init std::string compilationFile = "build/compile_commands.json"; @@ -103,12 +106,12 @@ BOOST_AUTO_TEST_CASE(t3_compilation_file_from_arguments) ])" ); - //Run + // Run parserArgument( "--compile_commands=" + compilationFile ); buildProject(); - //Check - BOOST_REQUIRE( isInitializedProject() ); + // Check + TEST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -116,7 +119,7 @@ BOOST_AUTO_TEST_CASE(t3_compilation_file_from_arguments) "/tmp/project/file2.cpp" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -126,9 +129,9 @@ BOOST_AUTO_TEST_CASE(t3_compilation_file_from_arguments) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_compilation_file_from_configuration_file) +TEST_CASE( t4_compilation_file_from_configuration_file ) { - //Init + // Init std::string compilationFile = "build/compile_commands.json"; addCMakeFile( @@ -147,12 +150,12 @@ BOOST_AUTO_TEST_CASE(t4_compilation_file_from_configuration_file) ])" ); - //Run + // Run setCompilationFileInConfigurationFile( compilationFile ); buildProject(); - //Check - BOOST_REQUIRE( isInitializedProject() ); + // Check + TEST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -160,7 +163,7 @@ BOOST_AUTO_TEST_CASE(t4_compilation_file_from_configuration_file) "/tmp/project/file2.cpp" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -170,9 +173,9 @@ BOOST_AUTO_TEST_CASE(t4_compilation_file_from_configuration_file) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_include_files_several_includes) +TEST_CASE( t5_1_include_files_several_includes ) { - //Init + // Init addCMakeFile( resources::arguments::compileCommands::DefaultValue, R"([ @@ -184,16 +187,16 @@ BOOST_AUTO_TEST_CASE(t5_1_include_files_several_includes) ])" ); - //Run + // Run buildProject(); - //Check - BOOST_REQUIRE( isInitializedProject() ); + // Check + TEST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); - const auto exceptedFiles = toExceptedFiles( { "/tmp/project/file1.cpp" } ); + const auto exceptedFiles = toExceptedFiles( { "/tmp/project/file1.cpp" } ); - BOOST_REQUIRE_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -203,7 +206,7 @@ BOOST_AUTO_TEST_CASE(t5_1_include_files_several_includes) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib1/" , "./lib2/" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -213,9 +216,9 @@ BOOST_AUTO_TEST_CASE(t5_1_include_files_several_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) +TEST_CASE( t5_2_include_files_different_includes_in_different_files ) { - //Init + // Init addCMakeFile( resources::arguments::compileCommands::DefaultValue, R"([ @@ -232,11 +235,11 @@ BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) ])" ); - //Run + // Run buildProject(); - //Check - BOOST_REQUIRE( isInitializedProject() ); + // Check + TEST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -244,7 +247,7 @@ BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) "/tmp/project/file2.cpp" } ); - BOOST_REQUIRE_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -255,7 +258,7 @@ BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib1/" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -266,7 +269,7 @@ BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file2.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib2/" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -277,9 +280,8 @@ BOOST_AUTO_TEST_CASE(t5_2_include_files_different_includes_in_different_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ } - diff --git a/src/application/test/suits/app_test_configuration_file_suits.cpp b/src/application/test/suits/app_test_configuration_file_suits.cpp index f09e94c..7372c6b 100644 --- a/src/application/test/suits/app_test_configuration_file_suits.cpp +++ b/src/application/test/suits/app_test_configuration_file_suits.cpp @@ -1,10 +1,10 @@ #include "application/test/fixtures/app_test_configuration_file_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" #include -#include #include +#include /*------------------------------------------------------------------------------ @@ -32,252 +32,236 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(ConfigurationfileTests, ConfigurationfileFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ConfigurationfileTests, ConfigurationfileFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty) +TEST_CASE( t1_empty ) { - // Run loadFromJson( "{}" ); // Check - BOOST_CHECK( !getProjectDir().has_value() ); - BOOST_CHECK( !getFileExtensions().has_value() ); - BOOST_CHECK( !getAnalyzeWithoutExtension().has_value() ); - BOOST_CHECK( !getIncludeDirs().has_value() ); - BOOST_CHECK( !getIgnoreDirs().has_value() ); - BOOST_CHECK( !getIgnoreSystemIncludes().has_value() ); - + TEST_CHECK( !getProjectDir().has_value() ); + TEST_CHECK( !getFileExtensions().has_value() ); + TEST_CHECK( !getAnalyzeWithoutExtension().has_value() ); + TEST_CHECK( !getIncludeDirs().has_value() ); + TEST_CHECK( !getIgnoreDirs().has_value() ); + TEST_CHECK( !getIgnoreSystemIncludes().has_value() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_project_dir) +TEST_CASE( t2_project_dir ) { - // Run loadFromJson( R"({"project_dir":"/tmp/project"})" ); // Check - BOOST_REQUIRE( getProjectDir().has_value() ); + TEST_REQUIRE( getProjectDir().has_value() ); BOOST_CHECK_EQUAL( getProjectDir()->string(), "/tmp/project" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_file_extenstions) +TEST_CASE( t3_file_extenstions ) { - // Run loadFromJson( R"({ "file_extensions" : [ "*.cpp", "*.hpp" ] })" ); // Check auto valueOpt = getFileExtensions(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "*.cpp,*.hpp" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_include_dir) +TEST_CASE( t4_include_dir ) { - // Run loadFromJson( R"({ "include_dirs" : [ "include1", "include2" ] })" ); // Check auto valueOpt = getIncludeDirs(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "include1,include2" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_ignore_dir) +TEST_CASE( t5_ignore_dir ) { - // Run loadFromJson( R"({ "ignore_dirs" : [ "ignore1", "ignore2" ] })" ); // Check auto valueOpt = getIgnoreDirs(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "ignore1,ignore2" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_ignore_system_includes) +TEST_CASE( t6_ignore_system_includes ) { - // Run loadFromJson( R"({ "ignore_system_includes" : true })" ); // Check auto valueOpt = getIgnoreSystemIncludes(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_ignore_files) +TEST_CASE( t7_ignore_files ) { - // Run loadFromJson( R"({ "ignore_files" : [ "lib1_*", "lib2_*" ] })" ); // Check auto valueOpt = getIgnoreFiles(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "lib1_*,lib2_*" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_analyze_without_extension) +TEST_CASE( t8_analyze_without_extension ) { - // Run loadFromJson( R"({ "analyze_without_extension" : true })" ); // Check auto valueOpt = getAnalyzeWithoutExtension(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_1_report_unresolved) +TEST_CASE( t9_1_report_unresolved ) { - // Run loadFromJson( R"({ "report" : [ "unresolved" ] })" ); // Check auto valueOpt = getReports(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "unresolved" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_2_report_most_impact) +TEST_CASE( t9_2_report_most_impact ) { - // Run loadFromJson( R"({ "report" : [ "most_impact" ] })" ); // Check auto valueOpt = getReports(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "most_impact" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_3_report_dump) +TEST_CASE( t9_3_report_dump ) { - // Run loadFromJson( R"({ "report" : [ "dump" ] })" ); // Check auto valueOpt = getReports(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "dump" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_4_several_reports) +TEST_CASE( t9_4_several_reports ) { - // Run loadFromJson( R"({ "report" : [ "unresolved" , "most_impact", "dump" ] })" ); // Check auto valueOpt = getReports(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "unresolved,most_impact,dump" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_report_limit) +TEST_CASE( t10_report_limit ) { - // Run loadFromJson( R"({ "report_limit" : 10 })" ); // Check auto valueOpt = getReportLimit(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, 10 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t11_report_details_limit) +TEST_CASE( t11_report_details_limit ) { - // Run loadFromJson( R"({ "report_details_limit" : 10 })" ); // Check auto valueOpt = getReportDetailsLimit(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, 10 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t12_show_std_files) +TEST_CASE( t12_show_std_files ) { - // Run loadFromJson( R"({ "show_std_files" : true })" ); // Check auto valueOpt = getShowStdFile(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t13_compile_commands) +TEST_CASE( t13_compile_commands ) { - // Run loadFromJson( R"({ "compile_commands" : "compile_commands.json" })" ); // Check auto valueOpt = getCompileCommands(); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, stdfs::path{ "compile_commands.json" } ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_parser_arguments.cpp b/src/application/test/suits/app_test_parser_arguments.cpp index 0525adc..4c4e60c 100644 --- a/src/application/test/suits/app_test_parser_arguments.cpp +++ b/src/application/test/suits/app_test_parser_arguments.cpp @@ -1,10 +1,10 @@ #include "application/test/fixtures/app_test_parser_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" -#include #include #include +#include /*------------------------------------------------------------------------------ @@ -34,17 +34,18 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(ParserArgumentsTets, ParserArgumentsFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ParserArgumentsTets, ParserArgumentsFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_argument_with_value) +TEST_CASE( t1_argument_with_value ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "test_dir"; - const std::string argumentDefaultValue = ""; + const std::string argumentDefaultValue; const std::string argument = "--" + argumentName + "=" + argumentValue; addArgument( argumentName, argumentDescription, argumentDefaultValue ); @@ -55,18 +56,17 @@ BOOST_AUTO_TEST_CASE(t1_argument_with_value) // Check auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); - BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - + TEST_REQUIRE( valueOpt.has_value() ); + TEST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_argument_with_only_default_value) +TEST_CASE( t2_argument_with_only_default_value ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentDefaultValue = "test_dir"; addArgument( argumentName, argumentDescription, argumentDefaultValue ); @@ -76,17 +76,16 @@ BOOST_AUTO_TEST_CASE(t2_argument_with_only_default_value) // Check auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( !valueOpt.has_value() ); - + TEST_REQUIRE( !valueOpt.has_value() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_argument_with_value_and_default_value) +TEST_CASE( t3_argument_with_value_and_default_value ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentDefaultValue = "test_dir"; const std::string argumentValue = "new_dir"; @@ -99,30 +98,28 @@ BOOST_AUTO_TEST_CASE(t3_argument_with_value_and_default_value) // Check auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_unrecognized_argument) +TEST_CASE( t4_unrecognized_argument ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "new_dir"; const std::string argument = "--" + argumentName + "=" + argumentValue; // Run - BOOST_CHECK_THROW( parseArguments( { argument } ), std::logic_error ); - + TEST_CHECK_THROW( parseArguments( { argument } ), std::logic_error ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_help) +TEST_CASE( t5_help ) { // Init const std::string argumentName = "dir"; @@ -147,13 +144,13 @@ BOOST_AUTO_TEST_CASE(t5_help) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_value_with_quotation_mark) +TEST_CASE( t6_value_with_quotation_mark ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "new_dir"; - const std::string argumentDefaultValue = ""; + const std::string argumentDefaultValue; const std::string argument = "--" + argumentName + "=\"" + argumentValue + "\""; @@ -168,54 +165,51 @@ BOOST_AUTO_TEST_CASE(t6_value_with_quotation_mark) // Check auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_value_with_apostrophe) +TEST_CASE( t7_value_with_apostrophe ) { // Init const std::string argumentName = "dir"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "new_dir"; - const std::string argumentDefaultValue = ""; + const std::string argumentDefaultValue; const std::string argument = "--" + argumentName + "='" + argumentValue + "'"; addArgument( argumentName, argumentDescription, argumentDefaultValue ); - // Run parseArguments( { argument } ); // Check auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_several_arguments) +TEST_CASE( t8_several_arguments ) { // Init const std::string argumentNewName = "new"; - const std::string argumentNewDescription = ""; + const std::string argumentNewDescription; const std::string argumentNewValue = "new_dir"; - const std::string argumentNewDefaultValue = ""; + const std::string argumentNewDefaultValue; const std::string argumentNew = "--" + argumentNewName + "=" + argumentNewValue; const std::string argumentOldName = "old"; - const std::string argumentOldDescription = ""; + const std::string argumentOldDescription; const std::string argumentOldValue = "old_dir"; - const std::string argumentOldDefaultValue = ""; + const std::string argumentOldDefaultValue; const std::string argumentOld = "--" + argumentOldName + "=" + argumentOldValue; @@ -228,23 +222,22 @@ BOOST_AUTO_TEST_CASE(t8_several_arguments) // Check auto valueNewOpt = getArgumentStringValue( argumentNewName ); - BOOST_REQUIRE( valueNewOpt.has_value() ); + TEST_REQUIRE( valueNewOpt.has_value() ); BOOST_CHECK_EQUAL( argumentNewValue, *valueNewOpt ); auto valueOldOpt = getArgumentStringValue( argumentOldName ); - BOOST_REQUIRE( valueOldOpt.has_value() ); + TEST_REQUIRE( valueOldOpt.has_value() ); BOOST_CHECK_EQUAL( argumentOldValue, *valueOldOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_check_exist_argument) +TEST_CASE( t9_check_exist_argument ) { // Init const std::string argumentName = "help"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argument = "--" + argumentName; addArgument( argumentName, argumentDescription ); @@ -253,16 +246,16 @@ BOOST_AUTO_TEST_CASE(t9_check_exist_argument) parseArguments( { argument } ); // Check - BOOST_CHECK( isExistArgument( argumentName ) ); + TEST_CHECK( isExistArgument( argumentName ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_1_array_simple) +TEST_CASE( t10_1_array_simple ) { // Init const std::string argumentName = "array"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "a,b,c"; const Strings argumentDefaultValues{}; @@ -277,22 +270,22 @@ BOOST_AUTO_TEST_CASE(t10_1_array_simple) auto valueOpt = getArgumentStringsValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_2_array_with_default_value) +TEST_CASE( t10_2_array_with_default_value ) { // Init const std::string argumentName = "array"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const Strings argumentDefaultValues{ "a", "b", "c" }; addArgument( argumentName, argumentDescription, argumentDefaultValues ); - const std::string argument = ""; + const std::string argument; // Run parseArguments( { argument } ); @@ -301,16 +294,16 @@ BOOST_AUTO_TEST_CASE(t10_2_array_with_default_value) auto valueOpt = getArgumentStringValue( argumentName ); - BOOST_REQUIRE( !valueOpt.has_value() ); + TEST_REQUIRE( !valueOpt.has_value() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_3_array_with_quotes) +TEST_CASE( t10_3_array_with_quotes ) { // Init const std::string argumentName = "array"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const std::string argumentValue = "'a',\"b\",c"; const Strings argumentDefaultValues{}; @@ -325,17 +318,17 @@ BOOST_AUTO_TEST_CASE(t10_3_array_with_quotes) auto valueOpt = getArgumentStringsValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( "a,b,c", *valueOpt ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t11_int) +TEST_CASE( t11_int ) { // Init const std::string argumentName = "number"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const int argumentValue = 42; const int argumentDefaultValue = 1; @@ -350,18 +343,17 @@ BOOST_AUTO_TEST_CASE(t11_int) // Check auto valueOpt = getArgumentIntValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t12_bool) +TEST_CASE( t12_bool ) { // Init const std::string argumentName = "skip"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const bool argumentValue = true; const bool argumentDefaultValue = false; @@ -376,18 +368,17 @@ BOOST_AUTO_TEST_CASE(t12_bool) // Check auto valueOpt = getArgumentBoolValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t13_path) +TEST_CASE( t13_path ) { // Init const std::string argumentName = "number"; - const std::string argumentDescription = ""; + const std::string argumentDescription; const Path argumentValue{ "/dir" }; const std::string argumentValueStr{ argumentValue.string() }; const Path argumentDefaultValue{ "/usr" }; @@ -402,21 +393,20 @@ BOOST_AUTO_TEST_CASE(t13_path) // Check auto valueOpt = getArgumentPathValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValueStr, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t14_paths) +TEST_CASE( t14_paths ) { // Init const std::string argumentName = "number"; - const std::string argumentDescription = ""; - const Paths argumentValues{ "/dir1" , "/dir2" , "/dir3" }; + const std::string argumentDescription; + const Paths argumentValues{ "/dir1", "/dir2", "/dir3" }; const std::string argumentValueStr{ toString( argumentValues ) }; - const Paths argumentDefaultValues{ "/usr1" , "/usr2", "/usr3" }; + const Paths argumentDefaultValues{ "/usr1", "/usr2", "/usr3" }; const std::string argument = "--" + argumentName + "=" + argumentValueStr; @@ -428,17 +418,14 @@ BOOST_AUTO_TEST_CASE(t14_paths) // Check auto valueOpt = getArgumentPathsValue( argumentName ); - BOOST_REQUIRE( valueOpt.has_value() ); + TEST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValueStr, *valueOpt ); - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ } - - diff --git a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp index 0a383ad..a79bbf5 100644 --- a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp +++ b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp @@ -1,15 +1,15 @@ #include "application/test/fixtures/app_test_parser_wrapper_fixture.hpp" -#include "application/resources/app_resources_arguments.hpp" #include "application/exceptions/app_exceptions.hpp" +#include "application/resources/app_resources_arguments.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/exceptions/rp_exceptions.hpp" -#include +#include "test_tools/test_macros.hpp" -#include #include +#include /*------------------------------------------------------------------------------ @@ -67,11 +67,12 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE( ParserWrapperTets, ParserWrapperFixture ) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ParserWrapperTets, ParserWrapperFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_1_project_dir_from_argument) +TEST_CASE( t1_1_project_dir_from_argument ) { // Run parse( "--project_dir=test_value" ); @@ -82,21 +83,20 @@ BOOST_AUTO_TEST_CASE(t1_1_project_dir_from_argument) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_2_project_dir_default) +TEST_CASE( t1_2_project_dir_default ) { - // Run + // Run parse( "" ); - // Check - BOOST_CHECK_EQUAL( - resources::arguments::projectDir::DefaultValue, - getDefaultProjectDir() - ); + // Check + BOOST_CHECK_EQUAL( + resources::arguments::projectDir::DefaultValue, + getDefaultProjectDir() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_3_project_dir_from_argument_without_full_name) +TEST_CASE( t1_3_project_dir_from_argument_without_full_name ) { // Init parse( "project_dir" ); @@ -107,149 +107,149 @@ BOOST_AUTO_TEST_CASE(t1_3_project_dir_from_argument_without_full_name) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_file_extensions_from_argument) +TEST_CASE( t2_1_file_extensions_from_argument ) { - // Run + // Run parse( "--file_extensions=*.cpp,*.hpp" ); - // Check + // Check auto fileExtensions = getFileExtensions(); BOOST_REQUIRE_EQUAL( fileExtensions.size(), 2 ); - BOOST_CHECK_EQUAL( fileExtensions.at( 0 ), "*.cpp"); - BOOST_CHECK_EQUAL( fileExtensions.at( 1 ), "*.hpp"); + BOOST_CHECK_EQUAL( fileExtensions.at( 0 ), "*.cpp" ); + BOOST_CHECK_EQUAL( fileExtensions.at( 1 ), "*.hpp" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_file_extensions_default) +TEST_CASE( t2_2_file_extensions_default ) { - // Run + // Run parse( "" ); - // Check - BOOST_CHECK_EQUAL( + // Check + BOOST_CHECK_EQUAL( toString( resources::arguments::fileExtensions::DefaultValue ), toString( getDefaultFileExtensions() ) - ); + ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_include_dirs_from_argument) +TEST_CASE( t3_1_include_dirs_from_argument ) { - // Run + // Run parse( "--include_dirs=/include/dir1,/include/dir2" ); - // Check - auto includeDirs = getIncludeDirs(); - BOOST_REQUIRE_EQUAL( includeDirs.size(), 2 ); + // Check + auto includeDirs = getIncludeDirs(); + BOOST_REQUIRE_EQUAL( includeDirs.size(), 2 ); BOOST_CHECK_EQUAL( includeDirs.at( 0 ), "/include/dir1" ); BOOST_CHECK_EQUAL( includeDirs.at( 1 ), "/include/dir2" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_include_dirs_default) +TEST_CASE( t3_2_include_dirs_default ) { - // Run + // Run parse( "" ); - // Check - BOOST_CHECK_EQUAL( - toString( resources::arguments::includeDirs::DefaultValue ), - toString( getDefaultIncludeDirs() ) - ); + // Check + BOOST_CHECK_EQUAL( + toString( resources::arguments::includeDirs::DefaultValue ), + toString( getDefaultIncludeDirs() ) + ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_ignore_dirs_from_argument) +TEST_CASE( t4_1_ignore_dirs_from_argument ) { - // Run + // Run parse( "--ignore_dirs=/include/dir1,/include/dir2" ); - // Check - auto includeDirs = getIgnoreDirs(); - BOOST_REQUIRE_EQUAL( includeDirs.size(), 2 ); - BOOST_CHECK_EQUAL(includeDirs.at( 0 ), "/include/dir1"); - BOOST_CHECK_EQUAL(includeDirs.at( 1 ), "/include/dir2"); + // Check + auto includeDirs = getIgnoreDirs(); + BOOST_REQUIRE_EQUAL( includeDirs.size(), 2 ); + BOOST_CHECK_EQUAL( includeDirs.at( 0 ), "/include/dir1" ); + BOOST_CHECK_EQUAL( includeDirs.at( 1 ), "/include/dir2" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_2_ignore_dirs_default) +TEST_CASE( t4_2_ignore_dirs_default ) { - // Run + // Run parse( "" ); - // Check - BOOST_CHECK_EQUAL( - toString( resources::arguments::ignoreDirs::DefaultValue ), - toString( getDefaultIgnoreDirs() ) - ); + // Check + BOOST_CHECK_EQUAL( + toString( resources::arguments::ignoreDirs::DefaultValue ), + toString( getDefaultIgnoreDirs() ) + ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_configuration_file_from_arguments) +TEST_CASE( t5_1_configuration_file_from_arguments ) { - // Run + // Run parse( "--configuration_file=./file" ); - // Check - BOOST_CHECK_EQUAL(getConfigurationFile().string(), "./file" ); + // Check + BOOST_CHECK_EQUAL( getConfigurationFile().string(), "./file" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_configuration_file_default) +TEST_CASE( t5_2_configuration_file_default ) { - // Run + // Run parse( "" ); - // Check - BOOST_CHECK_EQUAL( - resources::arguments::configurationFile::DefaultValue, - getDefaultConfigurationFile().string() - ); + // Check + BOOST_CHECK_EQUAL( + resources::arguments::configurationFile::DefaultValue, + getDefaultConfigurationFile().string() + ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_1_help_from_arguments) +TEST_CASE( t6_1_help_from_arguments ) { - // Run + // Run parse( "--help" ); - // Check - BOOST_CHECK( isHelp() ); + // Check + TEST_CHECK( isHelp() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_verbose) +TEST_CASE( t7_verbose ) { // Run parse( "--verbose" ); // Check - BOOST_CHECK( isVerbose() ); + TEST_CHECK( isVerbose() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_1_report_from_argument) +TEST_CASE( t8_1_report_from_argument ) { // Run parse( "--report=unresolved" ); // Check - BOOST_CHECK_EQUAL( "unresolved" , toString( getReporterKinds() ) ); + BOOST_CHECK_EQUAL( "unresolved", toString( getReporterKinds() ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_2_report_default) +TEST_CASE( t8_2_report_default ) { // Run parse( "" ); @@ -263,17 +263,17 @@ BOOST_AUTO_TEST_CASE(t8_2_report_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_3_report_incorrect_name) +TEST_CASE( t8_3_report_incorrect_name ) { // Check parse( "--report=incorrect_name" ); - BOOST_CHECK_THROW( getReporterKinds(), reporter::IncorrectReport ); + TEST_CHECK_THROW( getReporterKinds(), reporter::IncorrectReport ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_1_report_limit_from_argument) +TEST_CASE( t9_1_report_limit_from_argument ) { // Run parse( "--report_limit=42" ); @@ -284,7 +284,7 @@ BOOST_AUTO_TEST_CASE(t9_1_report_limit_from_argument) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_2_report_limit_default) +TEST_CASE( t9_2_report_limit_default ) { // Run parse( "" ); @@ -298,20 +298,20 @@ BOOST_AUTO_TEST_CASE(t9_2_report_limit_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_1_ignore_system_includes_from_arguments) +TEST_CASE( t10_1_ignore_system_includes_from_arguments ) { // Run parse( "--ignore_system_includes=true" ); // Check auto valueOpt = getIgnoreSystemIncludes(); - BOOST_REQUIRE( valueOpt.has_value() ); - BOOST_CHECK_EQUAL( *valueOpt, true ); + TEST_REQUIRE( valueOpt.has_value() ); + TEST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_2_ignore_system_includes_default) +TEST_CASE( t10_2_ignore_system_includes_default ) { // Run parse( "" ); @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(t10_2_ignore_system_includes_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t11_1_ignore_files_from_argument) +TEST_CASE( t11_1_ignore_files_from_argument ) { // Run parse( "--ignore_files=lib1_*,lib2_*" ); @@ -337,7 +337,7 @@ BOOST_AUTO_TEST_CASE(t11_1_ignore_files_from_argument) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t11_2_ignore_files_default) +TEST_CASE( t11_2_ignore_files_default ) { // Run parse( "" ); @@ -351,22 +351,22 @@ BOOST_AUTO_TEST_CASE(t11_2_ignore_files_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t12_version) +TEST_CASE( t12_version ) { // Run parse( "--version" ); // Check - BOOST_CHECK( isVersion() ); + TEST_CHECK( isVersion() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t13_1_report_details_limit_from_argument) +TEST_CASE( t13_1_report_details_limit_from_argument ) { // Run - parse( "--report_details_limit=42"); + parse( "--report_details_limit=42" ); // Check BOOST_CHECK_EQUAL( getReportDetailsLimit(), 42 ); @@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(t13_1_report_details_limit_from_argument) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t13_2_report_details_limit_default) +TEST_CASE( t13_2_report_details_limit_default ) { // Run parse( "" ); @@ -388,7 +388,7 @@ BOOST_AUTO_TEST_CASE(t13_2_report_details_limit_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t14_1_analyze_without_extension_from_argument) +TEST_CASE( t14_1_analyze_without_extension_from_argument ) { // Run parse( "--analyze_without_extension=true" ); @@ -399,7 +399,7 @@ BOOST_AUTO_TEST_CASE(t14_1_analyze_without_extension_from_argument) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t14_2_analyze_without_extension_default) +TEST_CASE( t14_2_analyze_without_extension_default ) { // Run parse( "" ); @@ -413,20 +413,20 @@ BOOST_AUTO_TEST_CASE(t14_2_analyze_without_extension_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t15_1_show_std_files_from_argument) +TEST_CASE( t15_1_show_std_files_from_argument ) { // Run parse( "--show_std_files=true" ); // Check auto valueOpt = getShowStdFile(); - BOOST_REQUIRE( valueOpt.has_value() ); - BOOST_CHECK_EQUAL( *valueOpt, true ); + TEST_REQUIRE( valueOpt.has_value() ); + TEST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t15_1_show_std_files_default) +TEST_CASE( t15_1_show_std_files_default ) { // Run parse( "" ); @@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE(t15_1_show_std_files_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t16_1_compile_commands_from_arguments) +TEST_CASE( t16_1_compile_commands_from_arguments ) { // Run parse( "--compile_commands=build/compile_commands.json" ); @@ -451,7 +451,7 @@ BOOST_AUTO_TEST_CASE(t16_1_compile_commands_from_arguments) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t16_2_compile_commands_default) +TEST_CASE( t16_2_compile_commands_default ) { // Run parse( "" ); @@ -465,7 +465,7 @@ BOOST_AUTO_TEST_CASE(t16_2_compile_commands_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_project_builder.cpp b/src/application/test/suits/app_test_project_builder.cpp index b0ea2b8..d611fcf 100644 --- a/src/application/test/suits/app_test_project_builder.cpp +++ b/src/application/test/suits/app_test_project_builder.cpp @@ -2,7 +2,7 @@ #include "application/resources/app_resources_arguments.hpp" -#include +#include "test_tools/test_macros.hpp" #include @@ -33,28 +33,29 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(ProjectBuildersTets, ProjectBuilderFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ProjectBuildersTets, ProjectBuilderFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty_arguments_and_configuration_file) +TEST_CASE( t1_empty_arguments_and_configuration_file ) { - //Run + // Run parserArguments( {} ); buildProject(); - //Check - BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath("./") ); - BOOST_CHECK_EQUAL( getIncludeDirs(), toAbsolutePath("./") ); - BOOST_CHECK_EQUAL( getIgnoreDirs(), "" ); - BOOST_CHECK_EQUAL( getFileExtensions(), "*.c,*.cpp,*.cxx,*.h,*.hpp,*.hxx" ); + // Check + BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath( "./" ) ); + BOOST_CHECK_EQUAL( getIncludeDirs(), toAbsolutePath( "./" ) ); + BOOST_CHECK_EQUAL( getIgnoreDirs(), "" ); + BOOST_CHECK_EQUAL( getFileExtensions(), "*.c,*.cpp,*.cxx,*.h,*.hpp,*.hxx" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_only_arguments) +TEST_CASE( t2_only_arguments ) { - //Init + // Init using namespace resources::arguments; const std::string argPrefix = "--"; @@ -71,7 +72,7 @@ BOOST_AUTO_TEST_CASE(t2_only_arguments) const std::string fileExtensionsArgName = argPrefix + fileExtensions::FullName; const std::string fileExtensionsArgValue = "*.cpp,*.hpp"; - //Run + // Run parserArguments( { projectArgName, projectArgValue, @@ -87,8 +88,8 @@ BOOST_AUTO_TEST_CASE(t2_only_arguments) } ); buildProject(); - //Check - BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath( projectArgValue ) ); + // Check + BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath( projectArgValue ) ); BOOST_CHECK_EQUAL( getIncludeDirs(), toAbsolutePath("test_project/lib1/") + @@ -107,9 +108,9 @@ BOOST_AUTO_TEST_CASE(t2_only_arguments) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_only_configuration_file) +TEST_CASE( t3_only_configuration_file ) { - //Init + // Init createDefaultConfigurationFile( R"({ "project_dir" : "./src", @@ -119,12 +120,12 @@ BOOST_AUTO_TEST_CASE(t3_only_configuration_file) })" ); - //Run + // Run parserArguments( {} ); buildProject(); - //Check - BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath("src/") ); + // Check + BOOST_CHECK_EQUAL( getProjectDir(), toAbsolutePath( "src/" ) ); BOOST_CHECK_EQUAL( getIncludeDirs(), toAbsolutePath("src/include1/") + @@ -143,44 +144,44 @@ BOOST_AUTO_TEST_CASE(t3_only_configuration_file) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_ignore_system_includes_from_configuration_file) +TEST_CASE( t5_1_ignore_system_includes_from_configuration_file ) { - //Init + // Init createDefaultConfigurationFile( R"({ "ignore_system_includes" : true })" ); - //Run + // Run parserArguments( {} ); buildProject(); - //Check + // Check BOOST_CHECK_EQUAL( getIgnoreSystemIncludes(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_ignore_system_includes_from_arguments) +TEST_CASE( t5_2_ignore_system_includes_from_arguments ) { - //Run - parserArguments({ "--ignore_system_includes=true" }); + // Run + parserArguments( { "--ignore_system_includes=true" } ); buildProject(); - //Check + // Check BOOST_CHECK_EQUAL( getIgnoreSystemIncludes(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_3_ignore_system_includes_default) +TEST_CASE( t5_3_ignore_system_includes_default ) { - //Run - parserArguments({}); + // Run + parserArguments( {} ); buildProject(); - //Check + // Check BOOST_CHECK_EQUAL( getIgnoreSystemIncludes(), resources::arguments::ignoreSystemIncludes::DefaultValue @@ -189,41 +190,40 @@ BOOST_AUTO_TEST_CASE(t5_3_ignore_system_includes_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_1_ignore_files_from_configuration_file) +TEST_CASE( t6_1_ignore_files_from_configuration_file ) { - //Init + // Init createDefaultConfigurationFile( - R"({ + R"({ "ignore_files" : [ "boost.*" ] - })" - ); + })" ); - //Run + // Run parserArguments( {} ); buildProject(); - //Check + // Check BOOST_REQUIRE_EQUAL( getFileFiltersCount(), 1 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_2_ignore_files_from_arguments) +TEST_CASE( t6_2_ignore_files_from_arguments ) { - //Run - parserArguments({ "--ignore_files=boost.*" }); + // Run + parserArguments( { "--ignore_files=boost.*" } ); buildProject(); - //Check + // Check BOOST_REQUIRE_EQUAL( getFileFiltersCount(), 1 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_3_ignore_files_default) +TEST_CASE( t6_3_ignore_files_default ) { - //Run - parserArguments({}); + // Run + parserArguments( {} ); buildProject(); //Check @@ -234,41 +234,41 @@ BOOST_AUTO_TEST_CASE(t6_3_ignore_files_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_1_analyze_without_extension_from_configuration_file) +TEST_CASE( t7_1_analyze_without_extension_from_configuration_file ) { - //Init + // Init createDefaultConfigurationFile( R"({ "analyze_without_extension" : true })" ); - //Run + // Run parserArguments( {} ); buildProject(); - //Check + // Check BOOST_REQUIRE_EQUAL( getAnalyzeWithoutExtension(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_2_analyze_without_extension_from_arguments) +TEST_CASE( t7_2_analyze_without_extension_from_arguments ) { - //Run - parserArguments({ "--analyze_without_extension=true" }); + // Run + parserArguments( { "--analyze_without_extension=true" } ); buildProject(); - //Check + // Check BOOST_REQUIRE_EQUAL( getAnalyzeWithoutExtension(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_3_analyze_without_extension_default) +TEST_CASE( t7_3_analyze_without_extension_default ) { - //Run - parserArguments({}); + // Run + parserArguments( {} ); buildProject(); //Check @@ -279,7 +279,7 @@ BOOST_AUTO_TEST_CASE(t7_3_analyze_without_extension_default) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_report_settings_loader.cpp b/src/application/test/suits/app_test_report_settings_loader.cpp index f7ed075..4401e69 100644 --- a/src/application/test/suits/app_test_report_settings_loader.cpp +++ b/src/application/test/suits/app_test_report_settings_loader.cpp @@ -1,6 +1,6 @@ #include "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -30,13 +30,14 @@ namespace application::test { //------------------------------------------------------------------------------ -BOOST_FIXTURE_TEST_SUITE(ReportSettingsLoaderTests, ReportSettingsLoaderFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ReportSettingsLoaderTests, ReportSettingsLoaderFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty_arguments_and_configuration_file) +TEST_CASE( t1_empty_arguments_and_configuration_file ) { - //Run + // Run parserArguments( "" ); load(); @@ -50,155 +51,155 @@ BOOST_AUTO_TEST_CASE(t1_empty_arguments_and_configuration_file) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_1_load_max_files_from_arguments) +TEST_CASE( t2_1_1_load_max_files_from_arguments ) { - //Run + // Run parserArguments( "--report_limit=42" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getMaxFilesCount(), 42 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_2_load_max_files_from_configuration_file) +TEST_CASE( t2_1_2_load_max_files_from_configuration_file ) { - //Run + // Run createConfigurationFile( R"({ "report_limit" : 42 })" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getMaxFilesCount(), 42 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_3_load_max_files_from_mix) +TEST_CASE( t2_1_3_load_max_files_from_mix ) { - //Run - createConfigurationFile( R"({ "report_limit" : 1 })" ); + // Run + createConfigurationFile( R"({ "report_limit" : 1 })" ); parserArguments( "--report_limit=2" ); load(); - //Check - BOOST_CHECK_EQUAL( getMaxFilesCount(), 2); + // Check + BOOST_CHECK_EQUAL( getMaxFilesCount(), 2 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_1_load_max_details_from_arguments) +TEST_CASE( t2_2_1_load_max_details_from_arguments ) { - //Run + // Run parserArguments( "--report_details_limit=42" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getMaxDetailsCount(), 42 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_2_load_max_details_from_configuration_file) +TEST_CASE( t2_2_2_load_max_details_from_configuration_file ) { - //Run + // Run createConfigurationFile( R"({ "report_details_limit" : 42 })" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getMaxDetailsCount(), 42 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_2_load_max_details_from_mix) +TEST_CASE( t2_2_2_load_max_details_from_mix ) { - //Run + // Run createConfigurationFile( R"({ "report_details_limit" : 1 })" ); parserArguments( "--report_details_limit=2" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getMaxDetailsCount(), 2 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_3_1_load_show_std_files_from_arguments) +TEST_CASE( t2_3_1_load_show_std_files_from_arguments ) { - //Run + // Run parserArguments( "--show_std_files=true" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getShowStdFiles(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_3_2_load_show_std_files_from_configuration_file) +TEST_CASE( t2_3_2_load_show_std_files_from_configuration_file ) { - //Run + // Run createConfigurationFile( R"({ "show_std_files" : true })" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getShowStdFiles(), true ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_3_3_load_show_std_files_from_mix) +TEST_CASE( t2_3_3_load_show_std_files_from_mix ) { - //Run + // Run createConfigurationFile( R"({ "show_std_files" : true })" ); parserArguments( "--show_std_files=false" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getShowStdFiles(), false ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_1_load_reports_from_arguments) +TEST_CASE( t3_3_1_load_reports_from_arguments ) { - //Run + // Run parserArguments( "--report=most_impact,unresolved" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getReports(), "most_impact,unresolved" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_2_load_reports_from_configuration_file) +TEST_CASE( t3_3_2_load_reports_from_configuration_file ) { - //Run + // Run createConfigurationFile( R"({ "report" : [ "most_impact","unresolved" ] })" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getReports(), "most_impact,unresolved" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_3_load_reports_from_mix) +TEST_CASE( t3_3_3_load_reports_from_mix ) { - //Run + // Run createConfigurationFile( R"({ "report" : [ "most_impact" ] })" ); parserArguments( "--report=unresolved" ); load(); - //Check + // Check BOOST_CHECK_EQUAL( getReports(), "unresolved" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_argument.cpp b/src/application/tools/app_argument.cpp index 97fa6d5..95123a3 100644 --- a/src/application/tools/app_argument.cpp +++ b/src/application/tools/app_argument.cpp @@ -7,13 +7,13 @@ namespace application { //------------------------------------------------------------------------------ Argument::Argument( - const std::string & _fullName, - const std::string & _description, + std::string _fullName, + std::string _description, ValueOpt _defaultValue ) - : m_fullName{ _fullName } - , m_description{ _description } - , m_defaultValue{ _defaultValue } + : m_fullName{ std::move( _fullName ) } + , m_description{ std::move( _description )} + , m_defaultValue{ std::move(_defaultValue) } { } diff --git a/src/application/tools/app_argument.hpp b/src/application/tools/app_argument.hpp index 7b521ca..a1fb22b 100644 --- a/src/application/tools/app_argument.hpp +++ b/src/application/tools/app_argument.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -13,17 +13,15 @@ namespace application { class Argument { public: - using ValueOpt = std::optional< std::any >; Argument( - const std::string & _fullName, - const std::string & _description, + std::string _fullName, + std::string _description, ValueOpt _defaultValue = std::nullopt ); - template< class _Value > - void setValue( const _Value & _value ) + template< class _Value > void setValue( const _Value & _value ) { m_value = _value; } @@ -31,20 +29,17 @@ class Argument const std::string & getFullName() const; const std::string & getDescription() const; - template< class _Value > - std::optional< _Value > getValue() const + template< class _Value > std::optional< _Value > getValue() const { return getValue< _Value >( m_value ); } - template< class _Value > - std::optional< _Value > getDefaultValue() const + template< class _Value > std::optional< _Value > getDefaultValue() const { return getValue< _Value >( m_defaultValue ); } private: - template< class _Value > std::optional< _Value > getValue( const ValueOpt & _valueOpt ) const { @@ -56,15 +51,12 @@ class Argument } private: - std::string m_fullName; std::string m_description; ValueOpt m_defaultValue; ValueOpt m_value; - }; //------------------------------------------------------------------------------ - } diff --git a/src/application/tools/app_cmake_project_builder.cpp b/src/application/tools/app_cmake_project_builder.cpp index 688fcdb..69c3c5f 100644 --- a/src/application/tools/app_cmake_project_builder.cpp +++ b/src/application/tools/app_cmake_project_builder.cpp @@ -1,14 +1,14 @@ #include "application/tools/app_cmake_project_builder.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" #include "compilation_db/api/cdb_database.hpp" #include "compilation_db/api/cdb_loader.hpp" #include "compilation_db/ih/cdb_accessor.hpp" -#include "cmake_project/api/cprj_project.hpp" #include "cmake_project/api/cprj_loader.hpp" +#include "cmake_project/api/cprj_project.hpp" #include "cmake_project/ih/cprj_accessor.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -16,8 +16,8 @@ #include "json/api/json_object.hpp" #include "json/ih/json_accessor.hpp" -#include "fs/api/fs_file_system.hpp" #include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" #include @@ -40,7 +40,6 @@ CMakeProjectBuilder::CMakeProjectBuilder( , m_jsonAccessor{ _jsonAccessor } , m_fs{ _fs } { - } //------------------------------------------------------------------------------ @@ -69,12 +68,16 @@ CMakeProjectBuilder::Path CMakeProjectBuilder::getPathToCmake( ) { if( auto pathOpt = _arguments.getCompileCommandsFile(); pathOpt ) + { return *pathOpt; + } - if( _configurationFile ) + if( _configurationFile != nullptr ) { if( auto pathOpt = _configurationFile->getCompileCommands(); pathOpt ) + { return *pathOpt; + } } return _arguments.getDefaultCompileCommandsFile(); @@ -96,12 +99,16 @@ CMakeProjectBuilder::CMakeProjectPtr CMakeProjectBuilder::loadProject( auto compilationDbPtr = loadCompilationDb( _path ); INTERNAL_CHECK_WARRING( compilationDbPtr ); if( !compilationDbPtr ) + { return nullptr; + } auto loaderPtr = createCmakeLoader(); INTERNAL_CHECK_WARRING( loaderPtr ); if( !loaderPtr ) + { return nullptr; + } return loaderPtr->load( *compilationDbPtr ); } @@ -123,12 +130,16 @@ CMakeProjectBuilder::CompilationDbPtr CMakeProjectBuilder::loadCompilationDb( auto jsonPtr = loadJson( _path ); INTERNAL_CHECK_WARRING( jsonPtr ); if( !jsonPtr ) + { return nullptr; + } auto loaderPtr = createCompilationDbLoader(); INTERNAL_CHECK_WARRING( loaderPtr ); if( !loaderPtr ) + { return nullptr; + } return loaderPtr->load( *jsonPtr ); } @@ -150,7 +161,9 @@ CMakeProjectBuilder::JsonPtr CMakeProjectBuilder::loadJson( auto filePtr = m_fs.openFile( _path ); INTERNAL_CHECK_WARRING( filePtr ); if( !filePtr ) + { return nullptr; + } fs::File & file = *filePtr; diff --git a/src/application/tools/app_cmake_project_builder.hpp b/src/application/tools/app_cmake_project_builder.hpp index 39e1781..e02d178 100644 --- a/src/application/tools/app_cmake_project_builder.hpp +++ b/src/application/tools/app_cmake_project_builder.hpp @@ -60,7 +60,6 @@ class CMakeProjectBuilder ); private: - static Path getPathToCmake( const ParserArgWrapper & _arguments, const ConfigurationFile * _configurationFile @@ -77,13 +76,11 @@ class CMakeProjectBuilder JsonPtr loadJson( const Path & _path ) const; private: - cmake_project::Accessor & m_cmakeAccessor; compilation_db::Accessor & m_compilationDbAccessor; json::JsonAccessor & m_jsonAccessor; fs::FileSystem & m_fs; - }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file.cpp b/src/application/tools/app_configuration_file.cpp index b3ec06e..b08d83a 100644 --- a/src/application/tools/app_configuration_file.cpp +++ b/src/application/tools/app_configuration_file.cpp @@ -6,9 +6,9 @@ #include "reporter/tools/rp_reporter_kind_functins.hpp" +#include "json/api/json_array.hpp" #include "json/api/json_object.hpp" #include "json/api/json_value.hpp" -#include "json/api/json_array.hpp" //------------------------------------------------------------------------------ @@ -33,7 +33,6 @@ void ConfigurationFile::loadFromJson( const json::JsonObject & _json ) loadReportLimit( _json ); loadReportDetailsLimit( _json ); loadShowStdFiles( _json ); - } //------------------------------------------------------------------------------ @@ -133,7 +132,7 @@ void ConfigurationFile::loadProjectDir( const json::JsonObject & _json ) { using namespace resources; - loadPathOpt( _json, configuration_file::ProjectDir, m_projectDir); + loadPathOpt( _json, configuration_file::ProjectDir, m_projectDir ); } //------------------------------------------------------------------------------ @@ -220,11 +219,13 @@ void ConfigurationFile::loadReports( const json::JsonObject & _json ) loadArrayOpt( _json, configuration_file::Report, stringsOpt ); if( !stringsOpt ) + { return; + } m_reports = ReporterKinds{}; m_reports->reserve( stringsOpt->size() ); - for( const std::string str : *stringsOpt ) + for( const std::string & str : *stringsOpt ) { const reporter::ReporterKind kind = reporter::toReporterKind( str ); m_reports->push_back( kind ); @@ -272,7 +273,9 @@ void ConfigurationFile::loadStringValue( const json::JsonValue & value = *valuePtr; const std::string valueStr = value.asString(); if( !valueStr.empty() ) + { _valueOpt = valueStr; + } } } @@ -286,17 +289,23 @@ void ConfigurationFile::loadArrayOpt( { auto valuePtr = _json.getAttributeValue( _name ); if( !valuePtr ) + { return; + } const json::JsonValue & value = *valuePtr; auto arrayPtr = value.asArray(); if( !arrayPtr ) + { return; + } const json::JsonArray & array = *arrayPtr; if( array.empty() ) + { return; + } const json::JsonArray::ArrayIndex count = array.getSize(); if( !_arrayOpt ) @@ -310,7 +319,9 @@ void ConfigurationFile::loadArrayOpt( auto arrayValuePtr = array.at( i ); INTERNAL_CHECK_WARRING( arrayValuePtr ); if( !arrayValuePtr ) + { continue; + } const json::JsonValue & arrayValue = *arrayValuePtr; const std::string arrayValueStr = arrayValue.asString(); @@ -327,7 +338,7 @@ void ConfigurationFile::loadPathOpt( ) { StringOpt pathStrOpt; - loadStringValue( _json, _name, pathStrOpt); + loadStringValue( _json, _name, pathStrOpt ); _valueOpt = pathStrOpt; } @@ -343,15 +354,21 @@ void ConfigurationFile::loadPathsOpt( StringsOpt stringsOpt; loadArrayOpt( _json, _name, stringsOpt ); if( !stringsOpt ) + { return; + } if( !_valueOpt ) + { _valueOpt = Paths{}; + } _valueOpt->reserve( stringsOpt->size() ); for( const std::string & string : *stringsOpt ) + { _valueOpt->push_back( string ); + } } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file.hpp b/src/application/tools/app_configuration_file.hpp index 385d599..0540b38 100644 --- a/src/application/tools/app_configuration_file.hpp +++ b/src/application/tools/app_configuration_file.hpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include //------------------------------------------------------------------------------ @@ -63,7 +63,6 @@ class ConfigurationFile BoolOpt getShowStdFiles() const; private: - void loadProjectDir( const json::JsonObject & _json ); void loadFileExtensions( const json::JsonObject & _json ); void loadAnalyzeWithoutExtension( const json::JsonObject & _json ); @@ -89,7 +88,7 @@ class ConfigurationFile void loadArrayOpt( const json::JsonObject & _json, std::string_view _name, - StringsOpt & _valueOpt + StringsOpt & _arrayOpt ); void loadPathOpt( @@ -117,7 +116,6 @@ class ConfigurationFile ); private: - PathOpt m_projectDir; StringsOpt m_fileExtensions; BoolOpt m_analyzeWithoutExtension; diff --git a/src/application/tools/app_configuration_file_loader.cpp b/src/application/tools/app_configuration_file_loader.cpp index 042e397..c876ace 100644 --- a/src/application/tools/app_configuration_file_loader.cpp +++ b/src/application/tools/app_configuration_file_loader.cpp @@ -1,15 +1,15 @@ #include "application/tools/app_configuration_file_loader.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" -#include "json/ih/json_accessor.hpp" #include "json/api/json_object.hpp" +#include "json/ih/json_accessor.hpp" #include "exception/ih/exc_internal_error.hpp" -#include "fs/api/fs_file_system.hpp" #include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" #include #include @@ -28,7 +28,6 @@ ConfigurationFileLoader::ConfigurationFileLoader( : m_jsonAccessor{ _jsonAccessor } , m_fs{ _fs } { - } //------------------------------------------------------------------------------ @@ -39,19 +38,27 @@ ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( { auto configurationPathOpt = _arguments.getConfigurationFile(); if( !configurationPathOpt ) + { configurationPathOpt = _arguments.getDefaultConfigurationFile(); + } INTERNAL_CHECK_WARRING( configurationPathOpt ); if( !configurationPathOpt ) + { return nullptr; + } if( !m_fs.isExistFile( *configurationPathOpt ) ) + { return nullptr; + } auto filePtr = m_fs.openFile( *configurationPathOpt ); INTERNAL_CHECK_WARRING( filePtr ) if( !filePtr ) + { return nullptr; + } return load( *filePtr ); } @@ -65,12 +72,16 @@ ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( auto jsonObjectPtr = m_jsonAccessor.createJson( _file.toInputStream() ); INTERNAL_CHECK_WARRING( jsonObjectPtr ) if( !jsonObjectPtr ) + { return nullptr; + } ConfigurationFilePtr resultPtr{ new ConfigurationFile }; INTERNAL_CHECK_WARRING( resultPtr ) if( !resultPtr ) + { return nullptr; + } resultPtr->loadFromJson( *jsonObjectPtr ); return resultPtr; diff --git a/src/application/tools/app_configuration_file_loader.hpp b/src/application/tools/app_configuration_file_loader.hpp index 61abd0d..8c99a65 100644 --- a/src/application/tools/app_configuration_file_loader.hpp +++ b/src/application/tools/app_configuration_file_loader.hpp @@ -42,7 +42,6 @@ class ConfigurationFileLoader ConfigurationFilePtr load( fs::File & _file ); private: - JsonAccessor & m_jsonAccessor; const fs::FileSystem & m_fs; }; diff --git a/src/application/tools/app_log.cpp b/src/application/tools/app_log.cpp index d5254f9..3923f8a 100644 --- a/src/application/tools/app_log.cpp +++ b/src/application/tools/app_log.cpp @@ -13,7 +13,6 @@ Log::Log() : m_stream{ std::cout } , m_errorStream{ std::cerr } { - } //------------------------------------------------------------------------------ @@ -22,7 +21,6 @@ Log::Log( std::ostream & _stream, std::ostream & _errorStream ) : m_stream{ _stream } , m_errorStream{ _errorStream } { - } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_log.hpp b/src/application/tools/app_log.hpp index fd845f5..3d329e1 100644 --- a/src/application/tools/app_log.hpp +++ b/src/application/tools/app_log.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -12,7 +12,6 @@ namespace application { class Log { public: - Log(); Log( std::ostream & _stream, std::ostream & _errorStream ); @@ -20,7 +19,6 @@ class Log void printWarning( const std::exception & _exception ); private: - std::ostream & m_stream; std::ostream & m_errorStream; }; diff --git a/src/application/tools/app_parser_arg.cpp b/src/application/tools/app_parser_arg.cpp index 8f69aaf..a80a248 100644 --- a/src/application/tools/app_parser_arg.cpp +++ b/src/application/tools/app_parser_arg.cpp @@ -4,10 +4,10 @@ #include -#include #include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -20,6 +20,7 @@ ParserArg::~ParserArg() = default; //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) void ParserArg::parse( int _argc, char * _argv[] ) { try @@ -114,7 +115,7 @@ void ParserArg::addArg( const std::string description{ _description }; auto str{ toString( _defaultValues ) }; - auto value{ cxxopts::value<_DefaultValue>()->default_value( str) }; + auto value{ cxxopts::value< _DefaultValue >()->default_value( str ) }; getImpl().add_options()( fullName, description, value ); } @@ -168,7 +169,9 @@ ParserArg::BoolOpt ParserArg::getArgumentBoolValue( std::string_view _arg ) cons ParserArg::PathOpt ParserArg::getArgumentPathValue( std::string_view _arg ) const { if( StringOpt stirngOpt = getArgumentStringValue( _arg ); stirngOpt ) + { return PathOpt{ *stirngOpt }; + } return std::nullopt; } @@ -178,7 +181,9 @@ ParserArg::PathOpt ParserArg::getArgumentPathValue( std::string_view _arg ) cons ParserArg::PathsOpt ParserArg::getArgumentPathsValue( std::string_view _arg ) const { if( StringsOpt stringsOpt = getArgumentStringsValue( _arg ); stringsOpt ) + { return toPaths( *stringsOpt ); + } return std::nullopt; } @@ -188,7 +193,9 @@ ParserArg::PathsOpt ParserArg::getArgumentPathsValue( std::string_view _arg ) co cxxopts::Options & ParserArg::getImpl() { if( !m_impl ) - m_impl.reset( new cxxopts::Options{ "" } ) ; + { + m_impl = std::make_unique< cxxopts::Options >( "" ); + } return *m_impl; } @@ -213,11 +220,11 @@ _TypeOpt ParserArg::getArgValue( std::string_view _arg ) const if( isExistArgument( _arg ) ) { std::string argumentName{ _arg }; - value_type value = (*m_resultOpt)[argumentName].as< value_type >(); + value_type value = ( *m_resultOpt )[argumentName].as< value_type >(); if constexpr( std::is_same_v< _TypeOpt , StringOpt > || std::is_same_v< _TypeOpt , StringsOpt > - ) + ) // NOLINTNEXTLINE(google-readability-braces-around-statements) { return removeQuotes( value ); } @@ -237,7 +244,7 @@ bool ParserArg::isExistArgument( std::string_view _arg ) const if( m_resultOpt ) { std::string argumentName{ _arg }; - const bool found = m_resultOpt->count( argumentName ); + const bool found = m_resultOpt->count( argumentName ) > 0; return found; } return false; @@ -254,13 +261,15 @@ void ParserArg::printHelp( std::ostream & _stream ) const std::string ParserArg::toString( const Strings & _stringArray ) { - std::string result = ""; - const size_t size = _stringArray.size(); - for( size_t i = 0; i < size ; ++i) + std::string result; + const std::size_t size = _stringArray.size(); + for( std::size_t i = 0; i < size; ++i ) { result += _stringArray[i]; if( i != size - 1 ) + { result += ','; + } } return result; } @@ -298,19 +307,18 @@ std::string ParserArg::toString( const Path & _path ) std::string ParserArg::removeQuotes( std::string_view _str ) { if( _str.size() < 3 ) + { return std::string{ _str }; + } const char firstChar = _str.at( 0 ); const char lastChar = _str.at( _str.size() - 1 ); + std::string result{ _str }; if( firstChar == lastChar && ( firstChar == '\'' || firstChar == '"' ) ) { - std::string_view result = _str.substr( 1, _str.size() - 2 ); - return std::string{ result }; - } - else - { - return std::string{ _str }; + result = _str.substr( 1, _str.size() - 2 ); } + return result; } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_parser_arg.hpp b/src/application/tools/app_parser_arg.hpp index f8dda9b..08533fe 100644 --- a/src/application/tools/app_parser_arg.hpp +++ b/src/application/tools/app_parser_arg.hpp @@ -1,8 +1,8 @@ #pragma once -#include #include #include +#include //------------------------------------------------------------------------------ @@ -20,7 +20,6 @@ namespace application { class ParserArg { public: - ParserArg(); ~ParserArg(); @@ -74,20 +73,19 @@ class ParserArg std::string_view _description ); - StringOpt getArgumentStringValue ( std::string_view _arg ) const; + StringOpt getArgumentStringValue( std::string_view _arg ) const; StringsOpt getArgumentStringsValue( std::string_view _arg ) const; - IntOpt getArgumentIntValue ( std::string_view _arg ) const; + IntOpt getArgumentIntValue( std::string_view _arg ) const; BoolOpt getArgumentBoolValue( std::string_view _arg ) const; - PathOpt getArgumentPathValue ( std::string_view _arg ) const; + PathOpt getArgumentPathValue( std::string_view _arg ) const; PathsOpt getArgumentPathsValue( std::string_view _arg ) const; bool isExistArgument( std::string_view _arg ) const; void printHelp( std::ostream & _stream ) const; private: - cxxopts::Options & getImpl(); const cxxopts::Options & getImpl() const; @@ -114,10 +112,8 @@ class ParserArg static Paths toPaths( const Strings & _strings ); private: - std::unique_ptr< cxxopts::Options > m_impl; std::unique_ptr< cxxopts::ParseResult > m_resultOpt; - }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_parser_arg_wrapper.cpp b/src/application/tools/app_parser_arg_wrapper.cpp index 2b66805..2778c14 100644 --- a/src/application/tools/app_parser_arg_wrapper.cpp +++ b/src/application/tools/app_parser_arg_wrapper.cpp @@ -2,16 +2,15 @@ #include "application/resources/app_resources_arguments.hpp" -#include "reporter/api/enums/rp_reporter_kind.hpp" #include "exception/ih/exc_internal_error.hpp" +#include "reporter/api/enums/rp_reporter_kind.hpp" #include "tools/is_vector.hpp" #include "reporter/tools/rp_reporter_kind_functins.hpp" -#include #include #include -#include +#include #include #include @@ -100,19 +99,20 @@ ParserArgWrapper::ParserArgWrapper() resources::arguments::show_std_files::DefaultValue } { - } //------------------------------------------------------------------------------ +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) void ParserArgWrapper::parse( int _argc, char * _argv[] ) { m_parser.parse( _argc, _argv ); if( _argc == 2 ) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) const std::string str = _argv[1]; - if( str.size() >= 1 && str[0] != '-' ) + if( !str.empty() && str[0] != '-' ) { m_projectDirArg.setValue< Path >( Path{ str } ); return; @@ -141,13 +141,15 @@ void ParserArgWrapper::parse( int _argc, char * _argv[] ) void ParserArgWrapper::parse( const stdfwd::vector< std::string > & _arguments ) { - std::vector< std::string >arguments{ _arguments }; + std::vector< std::string > arguments{ _arguments }; std::vector< char * > arg; arg.reserve( arguments.size() ); for( std::string & str : arguments ) + { arg.push_back( str.data() ); + } parse( static_cast< int >( arg.size() ), arg.data() ); } @@ -156,23 +158,23 @@ void ParserArgWrapper::parse( const stdfwd::vector< std::string > & _arguments ) void ParserArgWrapper::init() { - addArgument< Strings >( m_reportArg ); + addArgument< Strings >( m_reportArg ); - addArgument< Path >( m_configurationFileArg ); - addArgument< Path >( m_compileCommandsFileArg ); + addArgument< Path >( m_configurationFileArg ); + addArgument< Path >( m_compileCommandsFileArg ); - addArgument< Path >( m_projectDirArg ); - addArgument< Strings >( m_fileExtensionsArg ); - addArgument< bool >( m_analyzeWithoutextension ); - addArgument< Paths >( m_includeDirsArg ); + addArgument< Path >( m_projectDirArg ); + addArgument< Strings >( m_fileExtensionsArg ); + addArgument< bool >( m_analyzeWithoutextension ); + addArgument< Paths >( m_includeDirsArg ); - addArgument< Paths >( m_ignoreDirsArg ); - addArgument< bool >( m_ignoreSystemIncludes ); - addArgument< Strings >( m_ignoreFilesArg ); + addArgument< Paths >( m_ignoreDirsArg ); + addArgument< bool >( m_ignoreSystemIncludes ); + addArgument< Strings >( m_ignoreFilesArg ); - addArgument< int >( m_reportLimitArg ); - addArgument< int >( m_reportDetailsLimitArg ); - addArgument< bool >( m_showStdFilesArg ); + addArgument< int >( m_reportLimitArg ); + addArgument< int >( m_reportDetailsLimitArg ); + addArgument< bool >( m_showStdFilesArg ); addArgument( m_helpArg ); addArgument( m_verboseArg ); @@ -195,8 +197,7 @@ ParserArgWrapper::PathOpt ParserArgWrapper::getProjectDir() const //------------------------------------------------------------------------------ -ParserArgWrapper::Strings -ParserArgWrapper::getDefaultFileExtensions() const +ParserArgWrapper::Strings ParserArgWrapper::getDefaultFileExtensions() const { return getDefaultValue< Strings >( m_fileExtensionsArg ); } @@ -282,7 +283,7 @@ ParserArgWrapper::PathsOpt ParserArgWrapper::getIgnoreDirs() const ParserArgWrapper::ReporterKinds ParserArgWrapper::getDefaultReporterKinds() const { - Strings strings = getDefaultValue< Strings >( m_reportArg ); + auto strings = getDefaultValue< Strings >( m_reportArg ); return toReporterKinds( strings ); } @@ -291,7 +292,9 @@ ParserArgWrapper::ReporterKinds ParserArgWrapper::getDefaultReporterKinds() cons ParserArgWrapper::ReporterKindsOpt ParserArgWrapper::getReporterKinds() const { if( StringsOpt strings = m_reportArg.getValue< Strings >(); strings ) + { return toReporterKinds( *strings ); + } return std::nullopt; } @@ -482,14 +485,16 @@ void ParserArgWrapper::showHelp( std::ostream & _stream ) const //------------------------------------------------------------------------------ ParserArgWrapper::Strings ParserArgWrapper::toStrings( +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) const char * const _values[] ) { Strings array; const char * const * it = _values; - while( *it ) + while( *it != nullptr ) { - const std::string str{ *it }; + const std::string str{ *it }; + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) ++it; array.push_back( str ); } @@ -497,7 +502,7 @@ ParserArgWrapper::Strings ParserArgWrapper::toStrings( } //------------------------------------------------------------------------------ - +// NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) ParserArgWrapper::Paths ParserArgWrapper::toPaths( const char * const _values[] ) { Strings strings{ toStrings( _values ) }; @@ -509,10 +514,10 @@ ParserArgWrapper::Paths ParserArgWrapper::toPaths( const char * const _values[] template< class _Value > void ParserArgWrapper::setArgumentValue( Argument & _argument, - std::optional< _Value >( ParserArgWrapper::*_getter)( const Argument & ) const + std::optional< _Value > ( ParserArgWrapper::*_getter )( const Argument & ) const ) { - if( auto valueOpt = (this->*_getter)( _argument ); valueOpt ) + if( auto valueOpt = ( this->*_getter )( _argument ); valueOpt ) { _argument.setValue< _Value >( *valueOpt ); } diff --git a/src/application/tools/app_parser_arg_wrapper.hpp b/src/application/tools/app_parser_arg_wrapper.hpp index 76bece1..ca598a1 100644 --- a/src/application/tools/app_parser_arg_wrapper.hpp +++ b/src/application/tools/app_parser_arg_wrapper.hpp @@ -1,7 +1,7 @@ #pragma once -#include "application/tools/app_parser_arg.hpp" #include "application/tools/app_argument.hpp" +#include "application/tools/app_parser_arg.hpp" #include @@ -20,7 +20,6 @@ namespace application { class ParserArgWrapper { public: - ParserArgWrapper(); void parse( int _argc, char * _argv[] ); @@ -119,7 +118,6 @@ class ParserArgWrapper static reporter::ReporterKind toReporterKind( std::string_view _str ); private: - ParserArg m_parser; Argument m_projectDirArg; diff --git a/src/application/tools/app_plugin_ptr.hpp b/src/application/tools/app_plugin_ptr.hpp index 24dbea2..daa4c94 100644 --- a/src/application/tools/app_plugin_ptr.hpp +++ b/src/application/tools/app_plugin_ptr.hpp @@ -8,12 +8,10 @@ namespace application { //------------------------------------------------------------------------------ -template< class _Plugin > -class PluginPtr +template< class _Plugin > class PluginPtr { public: - template< class _PluginImpl > - _Plugin & ensure() + template< class _PluginImpl > _Plugin & ensure() { if( !m_plugin ) m_plugin.reset( new _PluginImpl ); @@ -22,9 +20,7 @@ class PluginPtr } private: - std::unique_ptr< _Plugin > m_plugin; - }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_project_builder.cpp b/src/application/tools/app_project_builder.cpp index bed0886..5bdc2ad 100644 --- a/src/application/tools/app_project_builder.cpp +++ b/src/application/tools/app_project_builder.cpp @@ -1,7 +1,7 @@ #include "application/tools/app_project_builder.hpp" -#include "application/tools/app_parser_arg_wrapper.hpp" #include "application/tools/app_configuration_file.hpp" +#include "application/tools/app_parser_arg_wrapper.hpp" #include "project/api/prj_project.hpp" #include "project/ih/prj_project_accessor.hpp" @@ -26,7 +26,6 @@ ProjectBuilder::ProjectBuilder( : m_projectAccessor{ _projectAccessor } , m_fs{ _fs } { - } //------------------------------------------------------------------------------ @@ -45,8 +44,10 @@ ProjectBuilder::ProjectPtr ProjectBuilder::build( reset(); - if( _configurationFile ) + if( _configurationFile != nullptr ) + { initProject( *_configurationFile, project ); + } initProject( _arguments, project ); initProjectWithDefaultValues( _arguments, project ); @@ -63,10 +64,14 @@ void ProjectBuilder::initProjectWithDefaultValues( ) { if( auto projectDir = _project.getProjectDir(); projectDir.empty() ) + { _project.setProjectDir( _arguments.getDefaultProjectDir() ); + } if( !_project.hasCppFileExtensions() ) + { _project.addCppFileExtensions( _arguments.getDefaultFileExtensions() ); + } if( !m_analyzeWithoutExtensionChanged ) { @@ -75,43 +80,56 @@ void ProjectBuilder::initProjectWithDefaultValues( ); } - if( !_project.getIncludeDirsCount() ) + if( _project.getIncludeDirsCount() == 0U ) + { _project.addIncludeDirs( _arguments.getDefaultIncludeDirs() ); + } if( !_project.hasFileFilters() ) + { _project.addFileFilters( _arguments.getDefaultIgnoreFiles() ); + } if( !m_ignoreSystemIncludesChanged ) + { _project.setIgnoreSystemIncludes( _arguments.getDefaultIgnoreSystemIncludes() ); + } if( !_project.hasIgnoreDirs() ) + { _project.addIgnoredDirs( _arguments.getDefaultIgnoreDirs() ); + } } //------------------------------------------------------------------------------ template< class _Source > -void ProjectBuilder::initProject( - const _Source & _source, - Project & _project -) +void ProjectBuilder::initProject( const _Source & _source, Project & _project ) { if( auto dirOpt = _source.getProjectDir(); dirOpt ) { Path dirPath = *dirOpt; if( !dirPath.is_absolute() ) + { dirPath = m_fs.toAbsolute( dirPath ); + } _project.setProjectDir( dirPath ); } if( auto valueOpt = _source.getIncludeDirs(); valueOpt ) + { _project.addIncludeDirs( *valueOpt ); + } if( auto valueOpt = _source.getIgnoreDirs(); valueOpt ) + { _project.addIgnoredDirs( *valueOpt ); + } if( auto valueOpt = _source.getIgnoreFiles(); valueOpt ) + { _project.addFileFilters( *valueOpt ); + } if( auto valueOpt = _source.getIgnoreSystemIncludes(); valueOpt ) { @@ -120,7 +138,9 @@ void ProjectBuilder::initProject( } if( auto valueOpt = _source.getFileExtensions(); valueOpt ) + { _project.addCppFileExtensions( *valueOpt ); + } if( auto valueOpt = _source.getAnalyzeWithoutExtension(); valueOpt ) { diff --git a/src/application/tools/app_project_builder.hpp b/src/application/tools/app_project_builder.hpp index b509034..c5748bd 100644 --- a/src/application/tools/app_project_builder.hpp +++ b/src/application/tools/app_project_builder.hpp @@ -59,12 +59,10 @@ class ProjectBuilder void reset(); private: - ProjectAccessor & m_projectAccessor; FileSystem & m_fs; - bool m_ignoreSystemIncludesChanged; - bool m_analyzeWithoutExtensionChanged; - + bool m_ignoreSystemIncludesChanged{}; + bool m_analyzeWithoutExtensionChanged{}; }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_report_settings_loader.cpp b/src/application/tools/app_report_settings_loader.cpp index 5863335..e0d5903 100644 --- a/src/application/tools/app_report_settings_loader.cpp +++ b/src/application/tools/app_report_settings_loader.cpp @@ -13,8 +13,8 @@ //------------------------------------------------------------------------------ -namespace application { - +namespace application +{ //------------------------------------------------------------------------------ ReportSettingsLoader::ReportSettingsLoader( @@ -22,7 +22,6 @@ ReportSettingsLoader::ReportSettingsLoader( ) : m_reporterFactory{ _reporterFactory } { - } //------------------------------------------------------------------------------ @@ -35,7 +34,9 @@ ReportSettingsLoader::SettingsPtr ReportSettingsLoader::load( auto settingsPtr = createSettings(); INTERNAL_CHECK_WARRING( settingsPtr ); if( !settingsPtr ) + { return nullptr; + } reporter::Settings & settings = *settingsPtr; @@ -58,12 +59,16 @@ ReportSettingsLoader::ReporterKinds ReportSettingsLoader::loadReports( ) { if( auto reportsOpt = _arguments.getReporterKinds(); reportsOpt ) + { return *reportsOpt; + } - if( _configurationFile ) + if( _configurationFile != nullptr ) { if( auto kindOpt = _configurationFile->getReporterKinds(); kindOpt ) + { return *kindOpt; + } } return _arguments.getDefaultReporterKinds(); @@ -124,26 +129,29 @@ bool ReportSettingsLoader::loadShowStdFiles( ); } - //------------------------------------------------------------------------------ template< typename _ValueType > _ValueType ReportSettingsLoader::getValue( const ParserArgWrapper & _arguments, - std::optional< _ValueType > (ParserArgWrapper::*_getValueFromArg)() const, - _ValueType (ParserArgWrapper::*_getDefaultValueFromArg)() const, + std::optional< _ValueType > ( ParserArgWrapper::*_getValueFromArg )() const, + _ValueType ( ParserArgWrapper::*_getDefaultValueFromArg )() const, const ConfigurationFile * _configurationFile, std::optional< _ValueType > (ConfigurationFile::*_getValueFromFile)() const ) { if( auto valueFromArgOpt = ( _arguments.*_getValueFromArg )(); valueFromArgOpt ) + { return *valueFromArgOpt; + } if( _configurationFile ) { auto valueFromFileOpt = ( *_configurationFile.*_getValueFromFile )(); if( valueFromFileOpt ) + { return *valueFromFileOpt; + } } return ( _arguments.*_getDefaultValueFromArg )(); diff --git a/src/application/tools/app_report_settings_loader.hpp b/src/application/tools/app_report_settings_loader.hpp index 72ae227..3c29dac 100644 --- a/src/application/tools/app_report_settings_loader.hpp +++ b/src/application/tools/app_report_settings_loader.hpp @@ -21,9 +21,8 @@ namespace application { class ReportSettingsLoader { public: - - using SettingsPtr = stdfwd::unique_ptr< reporter::Settings >; - using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + using SettingsPtr = stdfwd::unique_ptr< reporter::Settings >; + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; using CountType = std::size_t; @@ -40,7 +39,6 @@ class ReportSettingsLoader ); private: - SettingsPtr createSettings(); static CountType loadMaxFilesCount( @@ -68,7 +66,6 @@ class ReportSettingsLoader ); private: - reporter::Factory & m_reporterFactory; }; diff --git a/src/cmake_project/api/cprj_loader.hpp b/src/cmake_project/api/cprj_loader.hpp index ffc6fe4..76c1bf8 100644 --- a/src/cmake_project/api/cprj_loader.hpp +++ b/src/cmake_project/api/cprj_loader.hpp @@ -18,14 +18,12 @@ namespace cmake_project { class Loader { public: - using ProjectPtr = stdfwd::unique_ptr< Project >; virtual ~Loader() = default; virtual ProjectPtr load( const compilation_db::Database & _db ) = 0; virtual ProjectPtr createEmptyProject() = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/api/cprj_project.hpp b/src/cmake_project/api/cprj_project.hpp index 91d50f7..0e21ebb 100644 --- a/src/cmake_project/api/cprj_project.hpp +++ b/src/cmake_project/api/cprj_project.hpp @@ -28,7 +28,6 @@ class Project virtual void addFilePath( const Path & _file ) = 0; virtual void addIncludeToFile( const Path & _file, const Path & _include ) = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/ih/cprj_accessor.hpp b/src/cmake_project/ih/cprj_accessor.hpp index 5c4ec1a..a7322c6 100644 --- a/src/cmake_project/ih/cprj_accessor.hpp +++ b/src/cmake_project/ih/cprj_accessor.hpp @@ -12,13 +12,11 @@ namespace cmake_project { class Accessor { public: - using LoaderPtr = stdfwd::unique_ptr< Loader >; virtual ~Accessor() = default; virtual LoaderPtr createLoader() = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/ih/cprj_accessor_impl.hpp b/src/cmake_project/ih/cprj_accessor_impl.hpp index 5dc61bd..9e82f4d 100644 --- a/src/cmake_project/ih/cprj_accessor_impl.hpp +++ b/src/cmake_project/ih/cprj_accessor_impl.hpp @@ -11,7 +11,6 @@ namespace cmake_project { class AccessorImpl final : public Accessor { public: - LoaderPtr createLoader() override; }; diff --git a/src/cmake_project/impl/cprj_includes_parser.cpp b/src/cmake_project/impl/cprj_includes_parser.cpp index 831719e..4bb08d5 100644 --- a/src/cmake_project/impl/cprj_includes_parser.cpp +++ b/src/cmake_project/impl/cprj_includes_parser.cpp @@ -2,9 +2,9 @@ #include "cmake_project/impl/cprj_includes_parser_context.hpp" +#include #include #include -#include //------------------------------------------------------------------------------ @@ -23,7 +23,7 @@ IncludesParser::Includes IncludesParser::parse( std::string_view _command ) const char currentChar = command.at( i ); switch( currentChar ) { - case '\\' : + case '\\': { if( getIgnoreSpace( context, i ) ) { @@ -32,14 +32,15 @@ IncludesParser::Includes IncludesParser::parse( std::string_view _command ) } } break; - case ' ' : + case ' ': { i = getNotSpacePos( context, i ); i = parseArgument( context, i ); } break; + default: + break; } - } return context.getIncludes(); } @@ -59,14 +60,16 @@ IncludesParser::IndexType IncludesParser::parseArgument( { const char minusChar = command.at( minusPos ); const char prefixChar = command.at( prefixPos ); + IndexType result; if( minusChar == '-' && prefixChar == 'I' ) { - return parseInclude( _context, prefixPos + 1 ); + result = parseInclude( _context, prefixPos + 1 ); } else { - return prefixPos + 1; + result = prefixPos + 1; } + return result; } return size; @@ -83,14 +86,14 @@ IncludesParser::IndexType IncludesParser::parseInclude( const std::string & command = _context.getCommand(); std::string includeStr; - IndexType finishPos; + IndexType finishPos = size; bool stopLoop = false; for( IndexType i = startPos; i < size && !stopLoop; ++i ) { const char currentChar = command.at( i ); switch( currentChar ) { - case '\\' : + case '\\': { if( getIgnoreSpace( _context, i ) ) { @@ -106,7 +109,7 @@ IncludesParser::IndexType IncludesParser::parseInclude( } } break; - case ' ' : + case ' ': { --i; stopLoop = true; @@ -120,7 +123,9 @@ IncludesParser::IndexType IncludesParser::parseInclude( } if( !includeStr.empty() ) + { _context.addInclude( includeStr ); + } return finishPos; } @@ -136,7 +141,9 @@ bool IncludesParser::getIgnoreSpace( const IndexType size = _context.getCommandSize(); const IndexType nextPos = currentPos + 1; if( nextPos >= size ) + { return false; + } const char nextChar = command.at( nextPos ); const bool result = nextChar == '"'; @@ -164,7 +171,9 @@ IncludesParser::IndexType IncludesParser::getFinishIgnoreSpace( { const char nextChar = command.at( nextPos ); if( nextChar == '"' ) + { return nextPos; + } } } } @@ -192,7 +201,9 @@ IncludesParser::IndexType IncludesParser::getNotSpacePos( { const char currentChar = command.at( i ); if( currentChar != ' ' ) + { return i; + } } return size; diff --git a/src/cmake_project/impl/cprj_includes_parser.hpp b/src/cmake_project/impl/cprj_includes_parser.hpp index f80403d..5dfd66f 100644 --- a/src/cmake_project/impl/cprj_includes_parser.hpp +++ b/src/cmake_project/impl/cprj_includes_parser.hpp @@ -11,7 +11,6 @@ namespace cmake_project { class IncludesParser { - public: using Path = stdfs::path; diff --git a/src/cmake_project/impl/cprj_includes_parser_context.cpp b/src/cmake_project/impl/cprj_includes_parser_context.cpp index 8b31865..f135074 100644 --- a/src/cmake_project/impl/cprj_includes_parser_context.cpp +++ b/src/cmake_project/impl/cprj_includes_parser_context.cpp @@ -12,7 +12,6 @@ IncludeParserContext::IncludeParserContext( std::string_view _command ) : m_size{ _command.size() } , m_command{ _command } { - } //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_includes_parser_context.hpp b/src/cmake_project/impl/cprj_includes_parser_context.hpp index b83cb65..63929db 100644 --- a/src/cmake_project/impl/cprj_includes_parser_context.hpp +++ b/src/cmake_project/impl/cprj_includes_parser_context.hpp @@ -1,10 +1,10 @@ #pragma once -#include #include +#include -#include #include +#include //------------------------------------------------------------------------------ @@ -30,12 +30,10 @@ class IncludeParserContext void addInclude( const Path & _path ); private: - IndexType m_size; std::string m_command; Includes m_includes; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_loader_impl.cpp b/src/cmake_project/impl/cprj_loader_impl.cpp index 6372980..dbaf818 100644 --- a/src/cmake_project/impl/cprj_loader_impl.cpp +++ b/src/cmake_project/impl/cprj_loader_impl.cpp @@ -2,9 +2,10 @@ #include "cmake_project/impl/cprj_project_impl.hpp" #include "cmake_project/impl/cprj_includes_parser.hpp" +#include "cmake_project/impl/cprj_project_impl.hpp" -#include "compilation_db/api/cdb_database.hpp" #include "compilation_db/api/cdb_command_object.hpp" +#include "compilation_db/api/cdb_database.hpp" #include @@ -31,7 +32,7 @@ LoaderImpl::ProjectPtr LoaderImpl::load( const compilation_db::Database & _db ) const compilation_db::CommandObject & command = _db.getObject( i ); const Path file = loadFile( command, *result ); - loadCommand( command, file, *result ); + loadCommand( command, file, *result ); } return result; @@ -70,9 +71,11 @@ LoaderImpl::Path LoaderImpl::loadFile( IncludesParser & LoaderImpl::ensureIncludesParser() { if( !m_includeParser ) - m_includeParser.reset( new IncludesParser ); + { + m_includeParser = std::make_unique< IncludesParser >(); + } - return *m_includeParser; + return *m_includeParser; } //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_loader_impl.hpp b/src/cmake_project/impl/cprj_loader_impl.hpp index 9098973..e21f71a 100644 --- a/src/cmake_project/impl/cprj_loader_impl.hpp +++ b/src/cmake_project/impl/cprj_loader_impl.hpp @@ -20,8 +20,7 @@ namespace cmake_project { class LoaderImpl final : public Loader { public: - - using Path = stdfs::path; + using Path = stdfs::path; LoaderImpl(); ~LoaderImpl(); @@ -31,7 +30,6 @@ class LoaderImpl final : public Loader ProjectPtr createEmptyProject() override; private: - Path loadFile( const compilation_db::CommandObject & _commnad, Project & _project @@ -46,9 +44,7 @@ class LoaderImpl final : public Loader IncludesParser & ensureIncludesParser(); private: - std::unique_ptr< IncludesParser > m_includeParser; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_project_impl.cpp b/src/cmake_project/impl/cprj_project_impl.cpp index 0799e8e..2ad530e 100644 --- a/src/cmake_project/impl/cprj_project_impl.cpp +++ b/src/cmake_project/impl/cprj_project_impl.cpp @@ -23,8 +23,10 @@ void ProjectImpl::forEachFilePath( PathCallback _callback ) const { for( const Path & path : m_files ) { - if( !_callback( path )) + if( !_callback( path ) ) + { break; + } } } @@ -35,20 +37,24 @@ void ProjectImpl::forEachIncludes( PathCallback _callback ) const { - if( !m_includesByFiles.count( _file ) ) + if( m_includesByFiles.count( _file ) == 0U ) + { return; + } const IncludesForFile & includes = m_includesByFiles.at( _file ); for( const Path * include : includes ) { - if( !include ) + if( include == nullptr ) { - INTERNAL_CHECK_WARRING(false); + INTERNAL_CHECK_WARRING( false ); continue; } if( !_callback( *include ) ) + { break; + } } } @@ -65,7 +71,7 @@ void ProjectImpl::addFilePath( const Path & _path ) void ProjectImpl::addIncludeToFile( const Path & _file, const Path & _include ) { Path file = stdfs::lexically_normal( _file ); - IncludesForFile & includes = m_includesByFiles[ file ]; + IncludesForFile & includes = m_includesByFiles[file]; const Path & include = addInclude( _include ); includes.push_back( &include ); diff --git a/src/cmake_project/impl/cprj_project_impl.hpp b/src/cmake_project/impl/cprj_project_impl.hpp index 14a0e53..bd55d21 100644 --- a/src/cmake_project/impl/cprj_project_impl.hpp +++ b/src/cmake_project/impl/cprj_project_impl.hpp @@ -4,8 +4,8 @@ #include "tools/std_hash_fs_path.hpp" -#include #include +#include #include //------------------------------------------------------------------------------ @@ -17,7 +17,6 @@ namespace cmake_project { class ProjectImpl final : public Project { public: - CountType getFilePathsCount() const override; void forEachFilePath( PathCallback _callback ) const override; void forEachIncludes( @@ -29,7 +28,6 @@ class ProjectImpl final : public Project void addIncludeToFile( const Path & _file, const Path & _include ) override; private: - const Path & addInclude( const Path & _include ); private: @@ -42,7 +40,6 @@ class ProjectImpl final : public Project Files m_files; Includes m_includes; IncludesByFiles m_includesByFiles; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/cprj_test_main.cpp b/src/cmake_project/test/cprj_test_main.cpp index 7016363..557041f 100644 --- a/src/cmake_project/test/cprj_test_main.cpp +++ b/src/cmake_project/test/cprj_test_main.cpp @@ -1,10 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage #define BOOST_TEST_MODULE cmake_project_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } - diff --git a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp index c25d504..d63942b 100644 --- a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp +++ b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.cpp @@ -4,9 +4,9 @@ #include "tools/path_string_tools.hpp" -#include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -48,7 +48,9 @@ IncldesParserFixture::Strings IncldesParserFixture::toPathStrings( IncludesParser & IncldesParserFixture::ensureParser() { if( !m_parserPtr ) - m_parserPtr.reset( new IncludesParser ); + { + m_parserPtr = std::make_unique< IncludesParser >(); + } return *m_parserPtr; } diff --git a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp index 9230571..cc2e7d1 100644 --- a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp +++ b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -34,13 +34,10 @@ class IncldesParserFixture static std::string toString( const Path & _path ); private: - IncludesParser & ensureParser(); private: - std::unique_ptr< IncludesParser > m_parserPtr; - }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp index 32bf0cc..c510a00 100644 --- a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp +++ b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.cpp @@ -14,9 +14,9 @@ #include -#include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -55,7 +55,9 @@ void LoaderFixture::addComandWithIncludes( { std::string includesArg; for( const auto & include : _includes ) + { includesArg += " -I" + include; + } addCommand( getDefaultFolder(), "/usr/bin/c++" + includesArg, _file ); } @@ -142,7 +144,9 @@ std::string LoaderFixture::getDefaultFolder() const Loader & LoaderFixture::ensureLoader() { if( !m_loaderPtr ) + { m_loaderPtr = ensureCmakeProjectAccessor().createLoader(); + } return *m_loaderPtr; } @@ -152,7 +156,9 @@ Loader & LoaderFixture::ensureLoader() Accessor & LoaderFixture::ensureCmakeProjectAccessor() { if( !m_cmakeProjectAccessorPtr ) - m_cmakeProjectAccessorPtr.reset( new AccessorImpl ); + { + m_cmakeProjectAccessorPtr = std::make_unique< AccessorImpl >(); + } return *m_cmakeProjectAccessorPtr; } @@ -162,7 +168,9 @@ Accessor & LoaderFixture::ensureCmakeProjectAccessor() compilation_db::Database & LoaderFixture::ensureCompilationDb() { if( !m_dbPtr ) + { m_dbPtr = ensureCompilationDbLoader().createEmptyDb(); + } return *m_dbPtr; } @@ -172,7 +180,9 @@ compilation_db::Database & LoaderFixture::ensureCompilationDb() compilation_db::Loader & LoaderFixture::ensureCompilationDbLoader() { if( !m_dbLoaderPtr ) + { m_dbLoaderPtr = ensureCompilationDbAccessor().createLoader(); + } return *m_dbLoaderPtr; } @@ -182,7 +192,9 @@ compilation_db::Loader & LoaderFixture::ensureCompilationDbLoader() compilation_db::Accessor & LoaderFixture::ensureCompilationDbAccessor() { if( !m_dbAccessorPtr ) - m_dbAccessorPtr.reset( new compilation_db::AccessorImpl ); + { + m_dbAccessorPtr = std::make_unique< compilation_db::AccessorImpl >(); + } return *m_dbAccessorPtr; } diff --git a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp index cf01eb4..dda0a2d 100644 --- a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp +++ b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp @@ -29,7 +29,6 @@ namespace cmake_project::test { class LoaderFixture { public: - LoaderFixture(); ~LoaderFixture(); @@ -56,7 +55,6 @@ class LoaderFixture Strings toExceptedIncludes( const Strings & _dirs ) const; private: - using Path = stdfs::path; std::string getDefaultFolder() const; @@ -69,7 +67,6 @@ class LoaderFixture compilation_db::Accessor & ensureCompilationDbAccessor(); private: - std::unique_ptr< Project > m_projectPtr; std::unique_ptr< Loader > m_loaderPtr; std::unique_ptr< Accessor > m_cmakeProjectAccessorPtr; @@ -84,4 +81,3 @@ class LoaderFixture } //------------------------------------------------------------------------------ - diff --git a/src/cmake_project/test/suits/cprj_test_includes_parser.cpp b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp index 683ccac..8e2434a 100644 --- a/src/cmake_project/test/suits/cprj_test_includes_parser.cpp +++ b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp @@ -1,6 +1,6 @@ #include "cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" #include @@ -21,19 +21,19 @@ TEST PLAN namespace cmake_project::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(IncldesParserTests, IncldesParserFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( IncldesParserTests, IncldesParserFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_without_include_paramter) +TEST_CASE( t1_without_include_paramter ) { - //Run + // Run auto actualResult = parseString( "/usr/bin/c++ -o file2.cpp.o -c file2.cpp" ); Strings exceptedResult{}; - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -44,14 +44,14 @@ BOOST_AUTO_TEST_CASE(t1_without_include_paramter) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_paramter_in_name) +TEST_CASE( t2_paramter_in_name ) { - //Run + // Run auto actualResult = parseString( "/bin/c++ -o f-I.cpp.o -c f-I.cpp" ); Strings exceptedResult{}; - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -62,14 +62,14 @@ BOOST_AUTO_TEST_CASE(t2_paramter_in_name) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_one_paramter) +TEST_CASE( t3_one_paramter ) { - //Run + // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./include -c f.cpp" ); Strings exceptedResult = toPathStrings( {"./include"} ); - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -79,14 +79,14 @@ BOOST_AUTO_TEST_CASE(t3_one_paramter) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_several_parameters) +TEST_CASE( t4_several_parameters ) { - //Run + // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./lib1 -I./lib2 -c f.cpp" ); Strings exceptedResult = toPathStrings( { "./lib1", "./lib2" } ); - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -96,14 +96,14 @@ BOOST_AUTO_TEST_CASE(t4_several_parameters) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_paramter_in_end_of_string) +TEST_CASE( t5_paramter_in_end_of_string ) { - //Run + // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -c f.cpp -I./include" ); Strings exceptedResult = toPathStrings( {"./include"} ); - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -113,14 +113,14 @@ BOOST_AUTO_TEST_CASE(t5_paramter_in_end_of_string) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_file_with_space) +TEST_CASE( t6_file_with_space ) { - //Run - auto actualResult = parseString( "/bin/c++ -o f.cpp.o -c \\\"space in file\\\".cpp" ); + // Run + auto actualResult = parseString( R"(/bin/c++ -o f.cpp.o -c \"space in file\".cpp)" ); Strings exceptedResult; - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -130,15 +130,15 @@ BOOST_AUTO_TEST_CASE(t6_file_with_space) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_include_with_space) +TEST_CASE( t7_include_with_space ) { - //Run - auto actualResult = - parseString( "/bin/c++ -o f.cpp.o -I\\\"./include with space\\\" -c f.cpp" ); - Strings exceptedResult = toPathStrings( {"./include with space"} ); + // Run + auto actualResult = parseString( + R"(/bin/c++ -o f.cpp.o -I\"./include with space\" -c f.cpp)" ); + Strings exceptedResult = toPathStrings( { "./include with space" } ); - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -148,14 +148,15 @@ BOOST_AUTO_TEST_CASE(t7_include_with_space) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_double_spaces) +TEST_CASE( t8_double_spaces ) { - //Run - auto actualResult = parseString( "/bin/c++ -I./include -o f.cpp.o -c f.cpp" ); - Strings exceptedResult = toPathStrings( {"./include"} ); + // Run + auto actualResult = + parseString( "/bin/c++ -I./include -o f.cpp.o -c f.cpp" ); + Strings exceptedResult = toPathStrings( { "./include" } ); - //Check - BOOST_CHECK_EQUAL_COLLECTIONS( + // Check + TEST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -165,7 +166,7 @@ BOOST_AUTO_TEST_CASE(t8_double_spaces) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/suits/cprj_test_loader.cpp b/src/cmake_project/test/suits/cprj_test_loader.cpp index f32f0a2..d12bfd5 100644 --- a/src/cmake_project/test/suits/cprj_test_loader.cpp +++ b/src/cmake_project/test/suits/cprj_test_loader.cpp @@ -1,6 +1,6 @@ #include "cmake_project/test/fixtures/cprj_test_loader_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" #include @@ -16,24 +16,24 @@ TEST PLAN namespace cmake_project::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(CMakeProjectLoaderTests, LoaderFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( CMakeProjectLoaderTests, LoaderFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_one_file) +TEST_CASE( t1_one_file ) { - //Init + // Init addDefaultComandForFile( "file.cpp" ); - //Run + // Run load(); - //Check + // Check const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "file.cpp" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -43,20 +43,20 @@ BOOST_AUTO_TEST_CASE(t1_one_file) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_several_files) +TEST_CASE( t2_several_files ) { - //Init + // Init addDefaultComandForFile( "file1.cpp" ); addDefaultComandForFile( "file2.cpp" ); - //Run + // Run load(); - //Check + // Check const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "file1.cpp", "file2.cpp" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -66,18 +66,18 @@ BOOST_AUTO_TEST_CASE(t2_several_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_includes) +TEST_CASE( t3_includes ) { - //Init + // Init addComandWithIncludes( "file1.cpp", { "./lib1" } ); addComandWithIncludes( "file2.cpp", { "./lib2", "./lib3" } ); addComandWithIncludes( "file3.cpp", {} ); addComandWithIncludes( "file4.cpp", { "./lib4" } ); - //Run + // Run load(); - //Check + // Check const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "file1.cpp", @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) "file4.cpp" } ); - BOOST_REQUIRE_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -97,7 +97,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) const auto resultIncludes = getResultsIncludes( "file1.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib1" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) const auto resultIncludes = getResultsIncludes( "file2.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib2", "./lib3" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -119,7 +119,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) const auto resultIncludes = getResultsIncludes( "file3.cpp" ); const auto exceptedIncludes = toExceptedIncludes( {} ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -130,7 +130,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) const auto resultIncludes = getResultsIncludes( "file4.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib4" } ); - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE(t3_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/compilation_db/api/cdb_command_object.hpp b/src/compilation_db/api/cdb_command_object.hpp index 7a4d91b..a174873 100644 --- a/src/compilation_db/api/cdb_command_object.hpp +++ b/src/compilation_db/api/cdb_command_object.hpp @@ -11,6 +11,7 @@ namespace compilation_db { class CommandObject { public: + virtual ~CommandObject() = default; virtual const std::string & getDirectory() const = 0; virtual const std::string & getCommand() const = 0; diff --git a/src/compilation_db/api/cdb_database.hpp b/src/compilation_db/api/cdb_database.hpp index 162a7ec..dace055 100644 --- a/src/compilation_db/api/cdb_database.hpp +++ b/src/compilation_db/api/cdb_database.hpp @@ -12,7 +12,6 @@ namespace compilation_db { class Database { public: - using IndexType = std::size_t; virtual ~Database() = default; diff --git a/src/compilation_db/api/cdb_loader.hpp b/src/compilation_db/api/cdb_loader.hpp index 3ff546f..91b9c40 100644 --- a/src/compilation_db/api/cdb_loader.hpp +++ b/src/compilation_db/api/cdb_loader.hpp @@ -18,7 +18,6 @@ namespace compilation_db { class Loader { public: - virtual ~Loader() = default; using DatabasePtr = stdfwd::unique_ptr< Database >; diff --git a/src/compilation_db/ih/cdb_accessor.hpp b/src/compilation_db/ih/cdb_accessor.hpp index 9969789..783c751 100644 --- a/src/compilation_db/ih/cdb_accessor.hpp +++ b/src/compilation_db/ih/cdb_accessor.hpp @@ -12,7 +12,6 @@ namespace compilation_db { class Accessor { public: - using LoaderPtr = stdfwd::unique_ptr< Loader >; virtual ~Accessor() = default; diff --git a/src/compilation_db/ih/cdb_accessor_impl.hpp b/src/compilation_db/ih/cdb_accessor_impl.hpp index a0b9340..b29af59 100644 --- a/src/compilation_db/ih/cdb_accessor_impl.hpp +++ b/src/compilation_db/ih/cdb_accessor_impl.hpp @@ -11,7 +11,6 @@ namespace compilation_db { class AccessorImpl final : public Accessor { public: - LoaderPtr createLoader() override; }; diff --git a/src/compilation_db/impl/cdb_command_object_impl.cpp b/src/compilation_db/impl/cdb_command_object_impl.cpp index b6cf210..ba0f9da 100644 --- a/src/compilation_db/impl/cdb_command_object_impl.cpp +++ b/src/compilation_db/impl/cdb_command_object_impl.cpp @@ -15,7 +15,6 @@ CommandObjectImpl::CommandObjectImpl( , m_command{ _command } , m_file{ _file } { - } //------------------------------------------------------------------------------ diff --git a/src/compilation_db/impl/cdb_command_object_impl.hpp b/src/compilation_db/impl/cdb_command_object_impl.hpp index 37b96a4..823c26f 100644 --- a/src/compilation_db/impl/cdb_command_object_impl.hpp +++ b/src/compilation_db/impl/cdb_command_object_impl.hpp @@ -13,7 +13,6 @@ namespace compilation_db { class CommandObjectImpl final : public CommandObject { public: - CommandObjectImpl( std::string_view _directory, std::string_view _command, @@ -25,7 +24,6 @@ class CommandObjectImpl final : public CommandObject const std::string & getFile() const override; private: - const std::string m_directory; const std::string m_command; const std::string m_file; diff --git a/src/compilation_db/impl/cdb_database_impl.hpp b/src/compilation_db/impl/cdb_database_impl.hpp index e85617b..bb5e61d 100644 --- a/src/compilation_db/impl/cdb_database_impl.hpp +++ b/src/compilation_db/impl/cdb_database_impl.hpp @@ -2,8 +2,8 @@ #include "compilation_db/api/cdb_database.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -13,9 +13,7 @@ namespace compilation_db { class DatabaseImpl final : public Database { - public: - DatabaseImpl(); ~DatabaseImpl() override; @@ -29,7 +27,6 @@ class DatabaseImpl final : public Database ) override; private: - using CommandObjectPtr = std::unique_ptr< CommandObject >; std::vector< CommandObjectPtr > m_objects; diff --git a/src/compilation_db/impl/cdb_loader_impl.cpp b/src/compilation_db/impl/cdb_loader_impl.cpp index 2bafd44..a54fa74 100644 --- a/src/compilation_db/impl/cdb_loader_impl.cpp +++ b/src/compilation_db/impl/cdb_loader_impl.cpp @@ -3,9 +3,9 @@ #include "compilation_db/impl/cdb_database_impl.hpp" #include "compilation_db/resources/cdb_resources.hpp" +#include "json/api/json_array.hpp" #include "json/api/json_object.hpp" #include "json/api/json_value.hpp" -#include "json/api/json_array.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -52,7 +52,7 @@ LoaderImpl::DatabasePtr LoaderImpl::load( const json::JsonObject & _json ) LoaderImpl::DatabasePtr LoaderImpl::createEmptyDb() { - return DatabasePtr { new DatabaseImpl }; + return DatabasePtr{ new DatabaseImpl }; } //------------------------------------------------------------------------------ diff --git a/src/compilation_db/impl/cdb_loader_impl.hpp b/src/compilation_db/impl/cdb_loader_impl.hpp index 853c0f5..f20ecca 100644 --- a/src/compilation_db/impl/cdb_loader_impl.hpp +++ b/src/compilation_db/impl/cdb_loader_impl.hpp @@ -17,12 +17,10 @@ namespace compilation_db { class LoaderImpl final : public Loader { public: - DatabasePtr load( const json::JsonObject & _json ) override; DatabasePtr createEmptyDb() override; private: - void loadItem( const json::JsonValue & _value, Database & _db ); }; diff --git a/src/compilation_db/test/cdb_test_main.cpp b/src/compilation_db/test/cdb_test_main.cpp index 249c68d..de640e1 100644 --- a/src/compilation_db/test/cdb_test_main.cpp +++ b/src/compilation_db/test/cdb_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE compilation_db #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/compilation_db/test/fixtures/cdb_test_fixture.cpp b/src/compilation_db/test/fixtures/cdb_test_fixture.cpp index 55da5cc..c916127 100644 --- a/src/compilation_db/test/fixtures/cdb_test_fixture.cpp +++ b/src/compilation_db/test/fixtures/cdb_test_fixture.cpp @@ -9,8 +9,8 @@ #include "json/api/json_object.hpp" #include "json/ih/json_accessor_impl.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -50,7 +50,9 @@ CompilationDbFixture::JsonObjectPtr CompilationDbFixture::createJson( json::JsonAccessor & CompilationDbFixture::ensureJsonAccessor() { if( !m_jsonAccessorPtr ) - m_jsonAccessorPtr.reset( new json::JsonAccesorImpl ); + { + m_jsonAccessorPtr = std::make_unique< json::JsonAccesorImpl >(); + } return *m_jsonAccessorPtr; } @@ -60,7 +62,9 @@ json::JsonAccessor & CompilationDbFixture::ensureJsonAccessor() Loader & CompilationDbFixture::ensureLoader() { if( !m_loaderPtr ) + { m_loaderPtr = ensureAccessor().createLoader(); + } return *m_loaderPtr; } @@ -70,7 +74,9 @@ Loader & CompilationDbFixture::ensureLoader() Accessor & CompilationDbFixture::ensureAccessor() { if( !m_accessorPtr ) - m_accessorPtr.reset( new AccessorImpl ); + { + m_accessorPtr = std::make_unique< AccessorImpl >(); + } return *m_accessorPtr; } diff --git a/src/compilation_db/test/fixtures/cdb_test_fixture.hpp b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp index 42a937e..69dd4d2 100644 --- a/src/compilation_db/test/fixtures/cdb_test_fixture.hpp +++ b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp @@ -24,14 +24,12 @@ namespace compilation_db::test { class CompilationDbFixture { public: - CompilationDbFixture(); ~CompilationDbFixture(); const Database & parseJson( std::string_view _json ); private: - using JsonObjectPtr = std::unique_ptr< json::JsonObject >; JsonObjectPtr createJson( std::string_view _json ); @@ -41,7 +39,6 @@ class CompilationDbFixture Accessor & ensureAccessor(); private: - std::unique_ptr< Database > m_databasePtr; std::unique_ptr< Loader > m_loaderPtr; diff --git a/src/compilation_db/test/suits/cdb_test_suits.cpp b/src/compilation_db/test/suits/cdb_test_suits.cpp index 5ce4f2d..54ffef7 100644 --- a/src/compilation_db/test/suits/cdb_test_suits.cpp +++ b/src/compilation_db/test/suits/cdb_test_suits.cpp @@ -3,7 +3,7 @@ #include "compilation_db/api/cdb_command_object.hpp" #include "compilation_db/api/cdb_database.hpp" -#include +#include "test_tools/test_macros.hpp" #include /*------------------------------------------------------------------------------ @@ -18,12 +18,12 @@ TEST PLAN: namespace compilation_db::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(CompilationDbTests, CompilationDbFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( CompilationDbTests, CompilationDbFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_one_compilation_object) +TEST_CASE( t1_one_compilation_object ) { // Run const Database & db = parseJson( @@ -47,12 +47,11 @@ BOOST_AUTO_TEST_CASE(t1_one_compilation_object) "/usr/bin/c++ -I/home/user/temp/project file.o file.cpp" ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_several_compilation_objects) +TEST_CASE( t2_several_compilation_objects ) { // Run const Database & db = parseJson( @@ -104,12 +103,11 @@ BOOST_AUTO_TEST_CASE(t2_several_compilation_objects) "/usr/bin/c++ -I/home/user/temp/project file3.o file3.cpp" ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/exception/api/exc_exception.hpp b/src/exception/api/exc_exception.hpp index b8ee02c..c91b3b8 100644 --- a/src/exception/api/exc_exception.hpp +++ b/src/exception/api/exc_exception.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -12,13 +12,11 @@ namespace exception { class Exception : public std::exception { public: - virtual ~Exception() = default; virtual std::string getModuleName() const noexcept = 0; virtual std::string getCode() const noexcept = 0; virtual std::string getMessage() const noexcept = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/exception/ih/exc_exception_impl.hpp b/src/exception/ih/exc_exception_impl.hpp index 7cffd28..5e2434b 100644 --- a/src/exception/ih/exc_exception_impl.hpp +++ b/src/exception/ih/exc_exception_impl.hpp @@ -10,17 +10,14 @@ namespace exception { //------------------------------------------------------------------------------ -template < class _BaseException > -class ExceptionImpl : public _BaseException +template< class _BaseException > class ExceptionImpl : public _BaseException { - public: ExceptionImpl( std::string_view _module, std::string_view _code ) : m_module{ _module } , m_code{ _code } { - } std::string getModuleName() const noexcept override @@ -50,12 +47,10 @@ class ExceptionImpl : public _BaseException } private: - mutable std::string m_msg; const std::string m_module; const std::string m_code; - }; //------------------------------------------------------------------------------ diff --git a/src/exception/ih/exc_exception_with_message_impl.hpp b/src/exception/ih/exc_exception_with_message_impl.hpp index 1bba01c..1bed7a3 100644 --- a/src/exception/ih/exc_exception_with_message_impl.hpp +++ b/src/exception/ih/exc_exception_with_message_impl.hpp @@ -14,7 +14,6 @@ class ExceptionWithMessageImpl : public ExceptionImpl< _BaseException > using BaseClass = ExceptionImpl< _BaseException >; public: - ExceptionWithMessageImpl( std::string_view _module, std::string_view _code, @@ -23,7 +22,6 @@ class ExceptionWithMessageImpl : public ExceptionImpl< _BaseException > : BaseClass{ _module, _code } , m_message{ _message } { - } std::string getMessage() const noexcept override @@ -32,7 +30,6 @@ class ExceptionWithMessageImpl : public ExceptionImpl< _BaseException > } private: - const std::string m_message; }; diff --git a/src/exception/ih/exc_internal_error.hpp b/src/exception/ih/exc_internal_error.hpp index 91de110..9568722 100644 --- a/src/exception/ih/exc_internal_error.hpp +++ b/src/exception/ih/exc_internal_error.hpp @@ -2,8 +2,8 @@ #include "exception/ih/exc_exception_impl.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -38,7 +38,6 @@ class InternalError : public ExceptionImpl< Exception > } private: - const std::string m_file; const std::string m_function; const int m_line; @@ -50,11 +49,8 @@ class InternalError : public ExceptionImpl< Exception > //------------------------------------------------------------------------------ -#define INTERNAL_ERROR ::exception::InternalError( \ - __FILE__, \ - __FUNCTION__, \ - __LINE__ \ -) +#define INTERNAL_ERROR \ + ::exception::InternalError( __FILE__, __FUNCTION__, __LINE__ ) //------------------------------------------------------------------------------ @@ -62,15 +58,14 @@ class InternalError : public ExceptionImpl< Exception > //------------------------------------------------------------------------------ -#define INTERNAL_CHECK_ERROR( _condition ) \ - if( !( _condition ) ) \ - THROW_INTERNAL_ERROR +#define INTERNAL_CHECK_ERROR( _condition ) \ + if( !( _condition ) ) \ + THROW_INTERNAL_ERROR //------------------------------------------------------------------------------ -#define INTERNAL_CHECK_WARRING( _condition ) \ - if( !( _condition ) ) \ - std::cout << INTERNAL_ERROR.what() << std::endl; \ +#define INTERNAL_CHECK_WARRING( _condition ) \ + if( !( _condition ) ) \ + std::cout << INTERNAL_ERROR.what() << std::endl; //------------------------------------------------------------------------------ - diff --git a/src/fs/api/enums/fs_item_type.hpp b/src/fs/api/enums/fs_item_type.hpp index 65fe9a2..a5f3559 100644 --- a/src/fs/api/enums/fs_item_type.hpp +++ b/src/fs/api/enums/fs_item_type.hpp @@ -19,4 +19,3 @@ enum class ItemType } //------------------------------------------------------------------------------ - diff --git a/src/fs/api/fs_factory.hpp b/src/fs/api/fs_factory.hpp index 7134449..ae0adcc 100644 --- a/src/fs/api/fs_factory.hpp +++ b/src/fs/api/fs_factory.hpp @@ -11,7 +11,6 @@ class FileSystem; class Factory { public: - virtual ~Factory() = default; virtual FileSystem & getPhysicalFileSystem() = 0; diff --git a/src/fs/api/fs_file.hpp b/src/fs/api/fs_file.hpp index 9ee83c0..f807a11 100644 --- a/src/fs/api/fs_file.hpp +++ b/src/fs/api/fs_file.hpp @@ -11,7 +11,6 @@ namespace fs { class File { public: - virtual ~File() = default; virtual bool eof() const = 0; diff --git a/src/fs/ih/fs_accessor.hpp b/src/fs/ih/fs_accessor.hpp index c753413..255ecf4 100644 --- a/src/fs/ih/fs_accessor.hpp +++ b/src/fs/ih/fs_accessor.hpp @@ -11,11 +11,9 @@ class Factory; class FileSystemAccessor { public: - virtual ~FileSystemAccessor() = default; virtual Factory & getFactory() = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/fs/ih/fs_accessor_impl.cpp b/src/fs/ih/fs_accessor_impl.cpp index afd5f14..338bb43 100644 --- a/src/fs/ih/fs_accessor_impl.cpp +++ b/src/fs/ih/fs_accessor_impl.cpp @@ -13,15 +13,11 @@ namespace fs { FileSystemAccessorImpl::FileSystemAccessorImpl() : m_factoryPtr{ new FactoryImpl } { - } //------------------------------------------------------------------------------ -FileSystemAccessorImpl::~FileSystemAccessorImpl() -{ - -}; +FileSystemAccessorImpl::~FileSystemAccessorImpl() = default; //------------------------------------------------------------------------------ diff --git a/src/fs/ih/fs_accessor_impl.hpp b/src/fs/ih/fs_accessor_impl.hpp index 69cb1c2..104531d 100644 --- a/src/fs/ih/fs_accessor_impl.hpp +++ b/src/fs/ih/fs_accessor_impl.hpp @@ -13,16 +13,13 @@ namespace fs { class FileSystemAccessorImpl final : public FileSystemAccessor { public: - FileSystemAccessorImpl(); ~FileSystemAccessorImpl() override; Factory & getFactory() override; private: - std::unique_ptr< Factory > m_factoryPtr; - }; //------------------------------------------------------------------------------ diff --git a/src/fs/impl/exceptions/fs_base_exception_impl.hpp b/src/fs/impl/exceptions/fs_base_exception_impl.hpp index 59c90dc..da9a677 100644 --- a/src/fs/impl/exceptions/fs_base_exception_impl.hpp +++ b/src/fs/impl/exceptions/fs_base_exception_impl.hpp @@ -10,13 +10,12 @@ namespace fs { //------------------------------------------------------------------------------ -template < class _BaseException > +template< class _BaseException > class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > { using BaseClass = ::exception::ExceptionImpl< _BaseException >; public: - explicit BaseExceptionImpl( std::string_view _code ) : BaseClass( resources::exceptions::ModuleName, _code ) { diff --git a/src/fs/impl/exceptions/fs_exception_cant_create_file.cpp b/src/fs/impl/exceptions/fs_exception_cant_create_file.cpp index ba333ee..fcaa451 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_create_file.cpp +++ b/src/fs/impl/exceptions/fs_exception_cant_create_file.cpp @@ -10,11 +10,10 @@ namespace fs { //------------------------------------------------------------------------------ -CantCreateFileImpl::CantCreateFileImpl( const Path & _path ) +CantCreateFileImpl::CantCreateFileImpl( Path _path ) : BaseClass( resources::exceptions::CantCreateFile::Code ) - , m_path{ _path } + , m_path{ std::move( _path ) } { - } //------------------------------------------------------------------------------ diff --git a/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp b/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp index 32c8a02..5756d58 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp +++ b/src/fs/impl/exceptions/fs_exception_cant_create_file.hpp @@ -16,15 +16,13 @@ class CantCreateFileImpl : public BaseExceptionImpl< CantCreateFile > using BaseClass = BaseExceptionImpl< CantCreateFile >; public: - using Path = stdfs::path; - explicit CantCreateFileImpl( const Path & _path ); + explicit CantCreateFileImpl( Path _path ); std::string getMessage() const noexcept override; private: - const Path m_path; }; diff --git a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.cpp b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.cpp index f4ed030..c568e6a 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.cpp +++ b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.cpp @@ -10,11 +10,10 @@ namespace fs { //------------------------------------------------------------------------------ -CantOpenFileImpl::CantOpenFileImpl( const Path & _path ) +CantOpenFileImpl::CantOpenFileImpl( Path _path ) : BaseClass( resources::exceptions::CantOpenFile::Code ) - , m_path{ _path } + , m_path{ std::move( _path ) } { - } //------------------------------------------------------------------------------ diff --git a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp index d1ecabe..a3ed32e 100644 --- a/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp +++ b/src/fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp @@ -16,15 +16,13 @@ class CantOpenFileImpl : public BaseExceptionImpl< CantOpenFile > using BaseClass = BaseExceptionImpl< CantOpenFile >; public: - using Path = stdfs::path; - explicit CantOpenFileImpl( const Path & _path ); + explicit CantOpenFileImpl( Path _path ); std::string getMessage() const noexcept override; private: - const Path m_path; }; diff --git a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp index f588963..24a77f0 100644 --- a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp +++ b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.cpp @@ -9,14 +9,13 @@ namespace fs { //------------------------------------------------------------------------------ CheckingExistFileFailImpl::CheckingExistFileFailImpl( - const Path & _path, + Path _path, const std::error_code & _code ) : BaseClass( resources::exceptions::CheckingExistFileFail::Code ) - , m_path{ _path } + , m_path{ std::move( _path ) } , m_originMsg{ _code.message() } { - } //------------------------------------------------------------------------------ diff --git a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp index d031378..73a6386 100644 --- a/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp +++ b/src/fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp @@ -18,18 +18,13 @@ class CheckingExistFileFailImpl : public BaseExceptionImpl< CheckingExistFileFai using BaseClass = BaseExceptionImpl< CheckingExistFileFail >; public: - using Path = stdfs::path; - CheckingExistFileFailImpl( - const Path & _path, - const std::error_code & _code - ); + CheckingExistFileFailImpl( Path _path, const std::error_code & _code ); std::string getMessage() const noexcept override; private: - const Path m_path; const std::string m_originMsg; }; diff --git a/src/fs/impl/fs_factory_impl.cpp b/src/fs/impl/fs_factory_impl.cpp index bcf20c5..3bc1896 100644 --- a/src/fs/impl/fs_factory_impl.cpp +++ b/src/fs/impl/fs_factory_impl.cpp @@ -16,7 +16,9 @@ FactoryImpl::~FactoryImpl() = default; FileSystem & FactoryImpl::getPhysicalFileSystem() { if( !m_physicalFs ) - m_physicalFs.reset( new physical::PhysicalFileSystem ); + { + m_physicalFs = std::make_unique< physical::PhysicalFileSystem >(); + } return *m_physicalFs; } @@ -26,7 +28,9 @@ FileSystem & FactoryImpl::getPhysicalFileSystem() FileSystem & FactoryImpl::getMemoryFileSystem() { if( !m_memoryFs ) - m_memoryFs.reset( new memory::MemoryFileSystem ); + { + m_memoryFs = std::make_unique< memory::MemoryFileSystem >(); + } return *m_memoryFs; } diff --git a/src/fs/impl/fs_factory_impl.hpp b/src/fs/impl/fs_factory_impl.hpp index 9c863bd..12358cf 100644 --- a/src/fs/impl/fs_factory_impl.hpp +++ b/src/fs/impl/fs_factory_impl.hpp @@ -14,14 +14,12 @@ namespace fs { class FactoryImpl final : public Factory { public: - ~FactoryImpl() override; FileSystem & getPhysicalFileSystem() override; FileSystem & getMemoryFileSystem() override; private: - using FsPtr = std::unique_ptr< FileSystem >; FsPtr m_physicalFs; diff --git a/src/fs/impl/memory/fs_memory_file.cpp b/src/fs/impl/memory/fs_memory_file.cpp index 81964d7..39c322a 100644 --- a/src/fs/impl/memory/fs_memory_file.cpp +++ b/src/fs/impl/memory/fs_memory_file.cpp @@ -26,7 +26,7 @@ bool MemoryFile::eof() const std::string MemoryFile::getLine() const { std::string result; - getline( m_buf, result); + getline( m_buf, result ); return result; } diff --git a/src/fs/impl/memory/fs_memory_file.hpp b/src/fs/impl/memory/fs_memory_file.hpp index b4408f8..7ce3bdb 100644 --- a/src/fs/impl/memory/fs_memory_file.hpp +++ b/src/fs/impl/memory/fs_memory_file.hpp @@ -13,7 +13,6 @@ namespace fs::memory { class MemoryFile final : public File { public: - MemoryFile(); bool eof() const override; @@ -22,7 +21,6 @@ class MemoryFile final : public File File & operator<<( std::string_view _str ) override; private: - mutable std::stringstream m_buf; }; @@ -31,4 +29,3 @@ class MemoryFile final : public File } //------------------------------------------------------------------------------ - diff --git a/src/fs/impl/memory/fs_memory_file_system.cpp b/src/fs/impl/memory/fs_memory_file_system.cpp index abbb159..58a085a 100644 --- a/src/fs/impl/memory/fs_memory_file_system.cpp +++ b/src/fs/impl/memory/fs_memory_file_system.cpp @@ -20,7 +20,9 @@ MemoryFileSystem::FilePtr MemoryFileSystem::openFile( const Path & _path ) const FolderPtr dirPtr = getFolder( path.parent_path() ); if( !dirPtr ) + { return nullptr; + } const Path fileName = _path.filename(); return dirPtr->getFile( fileName.string() ); @@ -41,7 +43,7 @@ MemoryFileSystem::FilePtr MemoryFileSystem::createFile( const Path & _path ) bool MemoryFileSystem::isExistFile( const Path & _path ) const { - return openFile( _path ).get(); + return openFile( _path ).get() != nullptr; } //------------------------------------------------------------------------------ @@ -66,9 +68,11 @@ void MemoryFileSystem::forEachItem( ) const { FolderPtr folderPtr = getFolder( _dirPath ); - INTERNAL_CHECK_WARRING( folderPtr ); - if( !folderPtr ) + INTERNAL_CHECK_WARRING( folderPtr != nullptr ); + if( folderPtr == nullptr ) + { return; + } MemoryFolder & folder = *folderPtr; folder.forEachItem( @@ -86,7 +90,7 @@ MemoryFolder & MemoryFileSystem::ensureRoot( const Path & _path ) { auto pair = m_roots.try_emplace( _path, - FolderPtr{ new MemoryFolder{ _path.string() } } + FolderPtr{ std::make_shared< MemoryFolder > ( _path.string() ) } ); auto it = pair.first; FolderPtr & rootPtr = it->second; @@ -99,7 +103,9 @@ MemoryFolder & MemoryFileSystem::ensureRoot( const Path & _path ) MemoryFileSystem::FolderPtr MemoryFileSystem::getRoot( const Path & _path ) const { if( auto it = m_roots.find( _path ); it != m_roots.end() ) + { return it->second; + } return nullptr; } @@ -110,21 +116,27 @@ MemoryFileSystem::FolderPtr MemoryFileSystem::getFolder( const Path & _path ) co { FolderPtr rootPtr = getRoot( _path.root_directory() ); if( !rootPtr ) + { return nullptr; + } FolderPtr currentFolder = rootPtr; const Path pathWitoutRoot = _path.relative_path(); - for( auto currentName : pathWitoutRoot ) + for( const auto & currentName : pathWitoutRoot ) { if( stdfs::is_dir_filename( currentName ) ) + { continue; + } INTERNAL_CHECK_ERROR( currentFolder ); auto subDirPtr = currentFolder->getSubFolder( currentName.string() ); currentFolder = subDirPtr; if( !currentFolder ) + { break; + } } return currentFolder; } @@ -136,11 +148,13 @@ MemoryFolder & MemoryFileSystem::ensureFolder( const Path & _path ) Path pathWitoutRoot = _path.relative_path(); MemoryFolder & root = ensureRoot( _path.root_directory() ); MemoryFolder * currentFolder = &root; - for( auto currentName : pathWitoutRoot ) + for( const auto & currentName : pathWitoutRoot ) { const std::string folderName = currentName.string(); if( folderName.empty() ) + { continue; + } INTERNAL_CHECK_ERROR( currentFolder ); auto subDirPtr = currentFolder->ensureSubFolder( currentName.string() ); @@ -156,7 +170,9 @@ MemoryFolder & MemoryFileSystem::ensureFolder( const Path & _path ) MemoryFileSystem::Path MemoryFileSystem::toAbsolutePath( const Path & _path ) const { if( !_path.is_absolute() ) + { return getCurrentPath() / _path; + } return _path; } diff --git a/src/fs/impl/memory/fs_memory_file_system.hpp b/src/fs/impl/memory/fs_memory_file_system.hpp index 421baaf..91f9ee3 100644 --- a/src/fs/impl/memory/fs_memory_file_system.hpp +++ b/src/fs/impl/memory/fs_memory_file_system.hpp @@ -16,13 +16,12 @@ class MemoryFolder; class MemoryFileSystem final : public FileSystem { public: - FilePtr openFile( const Path & _path ) const override; FilePtr createFile( const Path & _path ) override; bool isExistFile( const Path & _path ) const override; void forEachItem( - const Path & _ditPath, + const Path & _dirPath, ItemCallback _callback ) const override; @@ -30,7 +29,6 @@ class MemoryFileSystem final : public FileSystem Path toAbsolute( const Path & _path ) const override; private: - using FolderPtr = std::shared_ptr< MemoryFolder >; FolderPtr getRoot( const Path & _path ) const; @@ -42,7 +40,6 @@ class MemoryFileSystem final : public FileSystem Path toAbsolutePath( const Path & _path ) const; private: - using Roots = std::unordered_map< Path, FolderPtr >; Roots m_roots; }; diff --git a/src/fs/impl/memory/fs_memory_folder.cpp b/src/fs/impl/memory/fs_memory_folder.cpp index 7ad24c6..f48e24b 100644 --- a/src/fs/impl/memory/fs_memory_folder.cpp +++ b/src/fs/impl/memory/fs_memory_folder.cpp @@ -11,7 +11,6 @@ namespace fs::memory { MemoryFolder::MemoryFolder( std::string_view _name ) : m_name{ _name } { - } //------------------------------------------------------------------------------ @@ -19,7 +18,7 @@ MemoryFolder::MemoryFolder( std::string_view _name ) MemoryFolder::FolderPtr MemoryFolder::ensureSubFolder( std::string_view _name ) { std::string name{ _name }; - auto pair = m_subdirs.try_emplace( name, FolderPtr{ new MemoryFolder{ _name } } ); + auto pair = m_subdirs.try_emplace( name, std::make_shared< MemoryFolder > ( _name ) ); auto it = pair.first; FolderPtr & folderPtr = it->second; return folderPtr; @@ -31,7 +30,9 @@ MemoryFolder::FolderPtr MemoryFolder::getSubFolder( std::string_view _name ) con { const std::string name{ _name }; if( auto it = m_subdirs.find( name ); it != m_subdirs.end() ) + { return it->second; + } return nullptr; } @@ -41,7 +42,7 @@ MemoryFolder::FolderPtr MemoryFolder::getSubFolder( std::string_view _name ) con MemoryFolder::FilePtr MemoryFolder::ensureFile( std::string_view _name ) { std::string name{ _name }; - auto pair = m_files.try_emplace( name, FilePtr{ new MemoryFile{} } ); + auto pair = m_files.try_emplace( name, std::make_shared< MemoryFile >() ); auto it = pair.first; FilePtr & filePtr = it->second; return filePtr; @@ -53,20 +54,26 @@ MemoryFolder::FilePtr MemoryFolder::getFile( std::string_view _name ) const { const std::string name{ _name }; if( auto it = m_files.find( name ); it != m_files.end() ) + { return it->second; + } return nullptr; } //------------------------------------------------------------------------------ -void MemoryFolder::forEachItem( ItemCallback _callback ) +void MemoryFolder::forEachItem( const ItemCallback & _callback ) { - for( auto it : m_subdirs ) + for( const auto & it : m_subdirs ) + { _callback( it.first, ItemType::Folder ); + } - for( auto it : m_files ) + for( const auto & it : m_files ) + { _callback( it.first, ItemType::File ); + } } //------------------------------------------------------------------------------ diff --git a/src/fs/impl/memory/fs_memory_folder.hpp b/src/fs/impl/memory/fs_memory_folder.hpp index eae98d4..2eea681 100644 --- a/src/fs/impl/memory/fs_memory_folder.hpp +++ b/src/fs/impl/memory/fs_memory_folder.hpp @@ -2,10 +2,10 @@ #include "fs/api/enums/fs_item_type.hpp" +#include +#include #include #include -#include -#include //------------------------------------------------------------------------------ @@ -31,7 +31,7 @@ class MemoryFolder FilePtr ensureFile( std::string_view _name ); FilePtr getFile( std::string_view _name ) const; - void forEachItem( ItemCallback _callback ); + void forEachItem( const ItemCallback & _callback ); private: diff --git a/src/fs/impl/physical/fs_physical_file.cpp b/src/fs/impl/physical/fs_physical_file.cpp index cf4c369..ba69ae5 100644 --- a/src/fs/impl/physical/fs_physical_file.cpp +++ b/src/fs/impl/physical/fs_physical_file.cpp @@ -27,7 +27,7 @@ bool PhysicalFile::eof() const std::string PhysicalFile::getLine() const { std::string line; - std::getline( m_file, line ); + std::getline( m_file, line ); return line; } diff --git a/src/fs/impl/physical/fs_physical_file.hpp b/src/fs/impl/physical/fs_physical_file.hpp index cc1ead0..231cf58 100644 --- a/src/fs/impl/physical/fs_physical_file.hpp +++ b/src/fs/impl/physical/fs_physical_file.hpp @@ -12,9 +12,7 @@ namespace fs::physical { class PhysicalFile final : public File { - public: - explicit PhysicalFile( std::fstream && _file ); bool eof() const override; @@ -23,9 +21,7 @@ class PhysicalFile final : public File File & operator<<( std::string_view _str ) override; private: - mutable std::fstream m_file; - }; //------------------------------------------------------------------------------ diff --git a/src/fs/impl/physical/fs_physical_file_system.cpp b/src/fs/impl/physical/fs_physical_file_system.cpp index 1ad8143..5c8124d 100644 --- a/src/fs/impl/physical/fs_physical_file_system.cpp +++ b/src/fs/impl/physical/fs_physical_file_system.cpp @@ -1,14 +1,14 @@ #include "fs/impl/physical/fs_physical_file_system.hpp" -#include "fs/impl/physical/fs_physical_file.hpp" #include "fs/api/enums/fs_item_type.hpp" +#include "fs/impl/physical/fs_physical_file.hpp" -#include "fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp" #include "fs/impl/exceptions/fs_exception_cant_create_file.hpp" +#include "fs/impl/exceptions/fs_exception_cant_open_file_impl.hpp" #include "fs/impl/exceptions/fs_exception_checking_exist_file_fail.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -51,7 +51,9 @@ bool PhysicalFileSystem::isExistFile( const Path & _path ) const std::error_code errorCode; const bool result = stdfs::exists( _path, errorCode ); if( errorCode ) + { throw CheckingExistFileFailImpl( _path, errorCode ); + } return result; } @@ -90,7 +92,7 @@ void PhysicalFileSystem::forEachItem( ItemCallback _callback ) const { - for(auto& item : stdfs::directory_iterator( _ditPath ) ) + for(const auto & item : stdfs::directory_iterator( _ditPath ) ) { static_assert( static_cast< int >( ItemType::Count ) == 2 ); ItemType type = diff --git a/src/fs/impl/physical/fs_physical_file_system.hpp b/src/fs/impl/physical/fs_physical_file_system.hpp index 45a52da..ee0e485 100644 --- a/src/fs/impl/physical/fs_physical_file_system.hpp +++ b/src/fs/impl/physical/fs_physical_file_system.hpp @@ -11,7 +11,6 @@ namespace fs::physical { class PhysicalFileSystem final : public FileSystem { public: - FilePtr openFile( const Path & _path ) const override; FilePtr createFile( const Path & _path ) override; bool isExistFile( const Path & _path ) const override; @@ -25,7 +24,6 @@ class PhysicalFileSystem final : public FileSystem Path toAbsolute( const Path & _path ) const override; private: - FilePtr getFile( const Path & _path, bool _create ) const; }; diff --git a/src/json/api/json_object.hpp b/src/json/api/json_object.hpp index bb3362e..221c327 100644 --- a/src/json/api/json_object.hpp +++ b/src/json/api/json_object.hpp @@ -12,7 +12,6 @@ namespace json { class JsonObject { public: - using JsonValuePtr = stdfwd::unique_ptr< JsonValue >; virtual ~JsonObject() = default; diff --git a/src/json/ih/json_accessor.hpp b/src/json/ih/json_accessor.hpp index 06dfe0b..c20df4d 100644 --- a/src/json/ih/json_accessor.hpp +++ b/src/json/ih/json_accessor.hpp @@ -12,7 +12,6 @@ namespace json { class JsonAccessor { public: - using JsonObjectPtr = stdfwd::unique_ptr< JsonObject >; virtual ~JsonAccessor() = default; diff --git a/src/json/ih/json_accessor_impl.hpp b/src/json/ih/json_accessor_impl.hpp index dc7c9de..d1a7bc2 100644 --- a/src/json/ih/json_accessor_impl.hpp +++ b/src/json/ih/json_accessor_impl.hpp @@ -9,7 +9,6 @@ namespace json { class JsonAccesorImpl : public JsonAccessor { public: - JsonAccesorImpl(); ~JsonAccesorImpl() override; diff --git a/src/json/impl/json_array_impl.cpp b/src/json/impl/json_array_impl.cpp index 486adee..9278cbb 100644 --- a/src/json/impl/json_array_impl.cpp +++ b/src/json/impl/json_array_impl.cpp @@ -31,7 +31,7 @@ bool JsonArrayImpl::empty() const JsonArrayImpl::JsonValuePtr JsonArrayImpl::at( ArrayIndex _index ) const { - JsonImpl json = m_jsonImpl[ _index ]; + JsonImpl json = m_jsonImpl[_index]; return JsonValuePtr{ new JsonValueImpl{ std::move( json ) } }; } diff --git a/src/json/impl/json_array_impl.hpp b/src/json/impl/json_array_impl.hpp index 3403e3a..ea6054d 100644 --- a/src/json/impl/json_array_impl.hpp +++ b/src/json/impl/json_array_impl.hpp @@ -13,7 +13,6 @@ namespace json { class JsonArrayImpl final : public JsonArray { public: - using JsonImpl = nlohmann::json; JsonArrayImpl( JsonImpl && _jsonImpl ); @@ -23,7 +22,6 @@ class JsonArrayImpl final : public JsonArray JsonValuePtr at( ArrayIndex _index ) const override; private: - JsonImpl m_jsonImpl; }; diff --git a/src/json/impl/json_object_impl.cpp b/src/json/impl/json_object_impl.cpp index 3b83586..de12e5b 100644 --- a/src/json/impl/json_object_impl.cpp +++ b/src/json/impl/json_object_impl.cpp @@ -38,10 +38,8 @@ JsonObjectImpl::JsonValuePtr JsonObjectImpl::getAttributeValue( JsonImpl json = m_jsonImpl.at( _name.data() ); return JsonValuePtr{ new JsonValueImpl{ std::move( json ) } }; } - else - { - return nullptr; - } + + return nullptr; } //------------------------------------------------------------------------------ diff --git a/src/json/impl/json_object_impl.hpp b/src/json/impl/json_object_impl.hpp index 105c034..4d70bb3 100644 --- a/src/json/impl/json_object_impl.hpp +++ b/src/json/impl/json_object_impl.hpp @@ -12,9 +12,7 @@ namespace json { class JsonObjectImpl final : public JsonObject { - public: - using JsonObjectPtr = std::unique_ptr< JsonObject >; using JsonImpl = nlohmann::json; @@ -27,7 +25,6 @@ class JsonObjectImpl final : public JsonObject JsonValuePtr asValue() const override; private: - JsonImpl m_jsonImpl; }; diff --git a/src/json/impl/json_value_impl.cpp b/src/json/impl/json_value_impl.cpp index f88978b..843e630 100644 --- a/src/json/impl/json_value_impl.cpp +++ b/src/json/impl/json_value_impl.cpp @@ -1,7 +1,7 @@ #include "json/impl/json_value_impl.hpp" -#include "json/impl/json_object_impl.hpp" #include "json/impl/json_array_impl.hpp" +#include "json/impl/json_object_impl.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -45,7 +45,7 @@ bool JsonValueImpl::asBool() const JsonValueImpl::JsonObjectPtr JsonValueImpl::asObject() const { INTERNAL_CHECK_WARRING( m_jsonImpl.is_object() ); - JsonImpl t( std::move( m_jsonImpl )); + JsonImpl t( m_jsonImpl ); INTERNAL_CHECK_WARRING( t.is_object() ); return JsonObjectPtr{ new JsonObjectImpl{ std::move( t ) } }; @@ -56,7 +56,7 @@ JsonValueImpl::JsonObjectPtr JsonValueImpl::asObject() const JsonValueImpl::JsonArrayPtr JsonValueImpl::asArray() const { INTERNAL_CHECK_WARRING( m_jsonImpl.is_array() ); - JsonImpl t( std::move( m_jsonImpl ) ); + JsonImpl t( m_jsonImpl ); INTERNAL_CHECK_WARRING( t.is_array() ); return JsonArrayPtr{ new JsonArrayImpl{ std::move( t ) } }; diff --git a/src/json/impl/json_value_impl.hpp b/src/json/impl/json_value_impl.hpp index 39f486c..84c95f0 100644 --- a/src/json/impl/json_value_impl.hpp +++ b/src/json/impl/json_value_impl.hpp @@ -13,7 +13,6 @@ namespace json { class JsonValueImpl final : public JsonValue { public: - using JsonImpl = nlohmann::json; JsonValueImpl( JsonImpl && _jsonImpl ); @@ -26,9 +25,7 @@ class JsonValueImpl final : public JsonValue JsonArrayPtr asArray() const override; private: - JsonImpl m_jsonImpl; - }; //------------------------------------------------------------------------------ diff --git a/src/json/test/fixtures/json_test_fixture.cpp b/src/json/test/fixtures/json_test_fixture.cpp index 47a8a19..fc2ec0c 100644 --- a/src/json/test/fixtures/json_test_fixture.cpp +++ b/src/json/test/fixtures/json_test_fixture.cpp @@ -38,7 +38,9 @@ const JsonObject & JsonFixture::loadJson() JsonAccessor & JsonFixture::ensureJsonAccessor() { if( !m_accessor ) - m_accessor.reset( new JsonAccesorImpl ); + { + m_accessor = std::make_unique< JsonAccesorImpl >(); + } return *m_accessor; } diff --git a/src/json/test/fixtures/json_test_fixture.hpp b/src/json/test/fixtures/json_test_fixture.hpp index 99812d6..adbd2a2 100644 --- a/src/json/test/fixtures/json_test_fixture.hpp +++ b/src/json/test/fixtures/json_test_fixture.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -20,7 +20,6 @@ namespace json::test { class JsonFixture { public: - JsonFixture(); ~JsonFixture(); @@ -28,11 +27,9 @@ class JsonFixture const JsonObject & loadJson(); private: - JsonAccessor & ensureJsonAccessor(); private: - std::unique_ptr< JsonAccessor > m_accessor; std::unique_ptr< JsonObject > m_json; std::stringstream m_text; diff --git a/src/json/test/json_test_main.cpp b/src/json/test/json_test_main.cpp index d711b5e..8d1ae44 100644 --- a/src/json/test/json_test_main.cpp +++ b/src/json/test/json_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE json_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/json/test/suits/json_test_suits.cpp b/src/json/test/suits/json_test_suits.cpp index 03caa9f..d85460c 100644 --- a/src/json/test/suits/json_test_suits.cpp +++ b/src/json/test/suits/json_test_suits.cpp @@ -1,10 +1,10 @@ #include "json/test/fixtures/json_test_fixture.hpp" +#include "json/api/json_array.hpp" #include "json/api/json_object.hpp" #include "json/api/json_value.hpp" -#include "json/api/json_array.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -28,12 +28,12 @@ TEST PLAN: namespace json::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(JsonTests, JsonFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( JsonTests, JsonFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_simple_json) +TEST_CASE( t1_simple_json ) { // Init createJsonFile( @@ -52,83 +52,81 @@ BOOST_AUTO_TEST_CASE(t1_simple_json) { BOOST_TEST_PASSPOINT(); auto projectDirPtr = json.getAttributeValue( "project_dir" ); - BOOST_REQUIRE( projectDirPtr ); + TEST_REQUIRE( projectDirPtr ); const JsonValue & projectDir = *projectDirPtr; - BOOST_CHECK_EQUAL( projectDir.asString(), "./src" ); + TEST_CHECK_EQUAL( projectDir.asString(), "./src" ); } { - BOOST_TEST_PASSPOINT(); auto fileExtensionsPtr = json.getAttributeValue( "file_extensions" ); - BOOST_REQUIRE( fileExtensionsPtr ); + TEST_REQUIRE( fileExtensionsPtr ); const JsonValue & fileExtensionsValue = *fileExtensionsPtr; auto fileExtensionsArrayPtr = fileExtensionsValue.asArray(); - BOOST_REQUIRE( fileExtensionsArrayPtr ); + TEST_REQUIRE( fileExtensionsArrayPtr ); const JsonArray & fileExtensionsArray = *fileExtensionsArrayPtr; BOOST_REQUIRE_EQUAL( fileExtensionsArray.getSize(), 2 ); { auto cppExtensionsPtr = fileExtensionsArray.at( 0 ); - BOOST_REQUIRE( cppExtensionsPtr ); + TEST_REQUIRE( cppExtensionsPtr ); const JsonValue & cppExtension = *cppExtensionsPtr; - BOOST_CHECK_EQUAL( cppExtension.asString(), "*.cpp" ); + TEST_CHECK_EQUAL( cppExtension.asString(), "*.cpp" ); } { auto hppExtensionsPtr = fileExtensionsArray.at( 1 ); - BOOST_REQUIRE( hppExtensionsPtr ); + TEST_REQUIRE( hppExtensionsPtr ); const JsonValue & hppExtension = *hppExtensionsPtr; - BOOST_CHECK_EQUAL( hppExtension.asString(), "*.hpp" ); + TEST_CHECK_EQUAL( hppExtension.asString(), "*.hpp" ); } } { BOOST_TEST_PASSPOINT(); auto includeDirsPtr = json.getAttributeValue( "include_dirs" ); - BOOST_REQUIRE( includeDirsPtr ); + TEST_REQUIRE( includeDirsPtr ); const JsonValue & includeDirsValue = *includeDirsPtr; auto includeDirsArrayPtr = includeDirsValue.asArray(); - BOOST_REQUIRE( includeDirsArrayPtr ); + TEST_REQUIRE( includeDirsArrayPtr ); const JsonArray & includeDirsArray = *includeDirsArrayPtr; BOOST_REQUIRE_EQUAL( includeDirsArray.getSize(), 3 ); { auto dir1Ptr = includeDirsArray.at( 0 ); - BOOST_REQUIRE( dir1Ptr ); + TEST_REQUIRE( dir1Ptr ); const JsonValue & dir1 = *dir1Ptr; - BOOST_CHECK_EQUAL( dir1.asString(), "." ); + TEST_CHECK_EQUAL( dir1.asString(), "." ); } { auto dir2Ptr = includeDirsArray.at( 1 ); - BOOST_REQUIRE( dir2Ptr ); + TEST_REQUIRE( dir2Ptr ); const JsonValue & dir2 = *dir2Ptr; - BOOST_CHECK_EQUAL( dir2.asString(), "/usr/include/" ); + TEST_CHECK_EQUAL( dir2.asString(), "/usr/include/" ); } { auto dir3Ptr = includeDirsArray.at( 2 ); - BOOST_REQUIRE( dir3Ptr ); + TEST_REQUIRE( dir3Ptr ); const JsonValue & dir3 = *dir3Ptr; - BOOST_CHECK_EQUAL( dir3.asString(), "./3rd-part/cpp-std-fwd-master/" ); + TEST_CHECK_EQUAL( dir3.asString(), "./3rd-part/cpp-std-fwd-master/" ); } } { BOOST_TEST_PASSPOINT(); auto ignoreDirsPtr = json.getAttributeValue( "ignore_dirs" ); - BOOST_REQUIRE( ignoreDirsPtr ); + TEST_REQUIRE( ignoreDirsPtr ); const JsonValue & ignoreDirsValue = *ignoreDirsPtr; auto ignoreDirsArrayPtr = ignoreDirsValue.asArray(); - BOOST_REQUIRE( ignoreDirsArrayPtr ); + TEST_REQUIRE( ignoreDirsArrayPtr ); const JsonArray & ignoreDirsArray = *ignoreDirsArrayPtr; BOOST_REQUIRE_EQUAL( ignoreDirsArray.getSize(), 1 ); { auto dir1Ptr = ignoreDirsArray.at( 0 ); - BOOST_REQUIRE( dir1Ptr ); + TEST_REQUIRE( dir1Ptr ); const JsonValue & dir1 = *dir1Ptr; - BOOST_CHECK_EQUAL( dir1.asString(), "./3rd-part" ); + TEST_CHECK_EQUAL( dir1.asString(), "./3rd-part" ); } } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_bool) +TEST_CASE( t2_bool ) { // Init createJsonFile( R"({ "atr1":true, "atr2":false })" ); @@ -140,24 +138,23 @@ BOOST_AUTO_TEST_CASE(t2_bool) { BOOST_TEST_PASSPOINT(); auto atr1Ptr = json.getAttributeValue( "atr1" ); - BOOST_REQUIRE( atr1Ptr ); + TEST_REQUIRE( atr1Ptr ); const JsonValue & atr1 = *atr1Ptr; - BOOST_CHECK_EQUAL( atr1.asBool(), true ); + TEST_CHECK_EQUAL( atr1.asBool(), true ); } { BOOST_TEST_PASSPOINT(); auto atr2Ptr = json.getAttributeValue( "atr2" ); - BOOST_REQUIRE( atr2Ptr ); + TEST_REQUIRE( atr2Ptr ); const JsonValue & atr2 = *atr2Ptr; - BOOST_CHECK_EQUAL( atr2.asBool(), false ); + TEST_CHECK_EQUAL( atr2.asBool(), false ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_int) +TEST_CASE( t3_int ) { // Init createJsonFile( R"({ "val":42 })" ); @@ -167,14 +164,14 @@ BOOST_AUTO_TEST_CASE(t3_int) // Check auto atrPtr = json.getAttributeValue( "val" ); - BOOST_REQUIRE( atrPtr ); + TEST_REQUIRE( atrPtr ); const JsonValue & val = *atrPtr; - BOOST_CHECK_EQUAL( val.asInt(), 42 ); + TEST_CHECK_EQUAL( val.asInt(), 42 ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_string) +TEST_CASE( t4_string ) { // Init createJsonFile( R"({ "name": "str" })" ); @@ -184,14 +181,14 @@ BOOST_AUTO_TEST_CASE(t4_string) // Check auto atrPtr = json.getAttributeValue( "name" ); - BOOST_REQUIRE( atrPtr ); + TEST_REQUIRE( atrPtr ); const JsonValue & val = *atrPtr; - BOOST_CHECK_EQUAL( val.asString(), "str" ); + TEST_CHECK_EQUAL( val.asString(), "str" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_object) +TEST_CASE( t5_object ) { // Init createJsonFile( R"({ "object" : { "name" : "str" } })" ); @@ -201,20 +198,20 @@ BOOST_AUTO_TEST_CASE(t5_object) // Check auto atrPtr = json.getAttributeValue( "object" ); - BOOST_REQUIRE( atrPtr ); + TEST_REQUIRE( atrPtr ); auto objectPtr = atrPtr->asObject(); - BOOST_REQUIRE( objectPtr ); + TEST_REQUIRE( objectPtr ); - auto namePtr = objectPtr->getAttributeValue( "name" ); - BOOST_REQUIRE( namePtr ); + auto namePtr = objectPtr->getAttributeValue( "name" ); + TEST_REQUIRE( namePtr ); - BOOST_CHECK_EQUAL( namePtr->asString(), "str" ); + TEST_CHECK_EQUAL( namePtr->asString(), "str" ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_1_array_bool) +TEST_CASE( t6_1_array_bool ) { // Init createJsonFile( R"({ "array" : [true,false] })" ); @@ -224,29 +221,28 @@ BOOST_AUTO_TEST_CASE(t6_1_array_bool) // Check auto attributePtr = json.getAttributeValue( "array" ); - BOOST_REQUIRE( attributePtr ); + TEST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - BOOST_REQUIRE( arrayPtr ); + TEST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asBool(), true ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asBool(), true ); } { auto valPtr = array.at( 1 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asBool(), false ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asBool(), false ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_2_array_int) +TEST_CASE( t6_2_array_int ) { // Init createJsonFile( R"({ "array" : [42,43] })" ); @@ -256,29 +252,28 @@ BOOST_AUTO_TEST_CASE(t6_2_array_int) // Check auto attributePtr = json.getAttributeValue( "array" ); - BOOST_REQUIRE( attributePtr ); + TEST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - BOOST_REQUIRE( arrayPtr ); + TEST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asInt(), 42 ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asInt(), 42 ); } { auto valPtr = array.at( 1 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asInt(), 43 ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asInt(), 43 ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_3_array_string) +TEST_CASE( t6_3_array_string ) { // Init createJsonFile( R"({ "array" : ["str1","str2"] })" ); @@ -288,29 +283,28 @@ BOOST_AUTO_TEST_CASE(t6_3_array_string) // Check auto attributePtr = json.getAttributeValue( "array" ); - BOOST_REQUIRE( attributePtr ); + TEST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - BOOST_REQUIRE( arrayPtr ); + TEST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asString(), "str1" ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - BOOST_REQUIRE( valPtr ); - BOOST_CHECK_EQUAL( valPtr->asString(), "str2" ); + TEST_REQUIRE( valPtr ); + TEST_CHECK_EQUAL( valPtr->asString(), "str2" ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_4_array_object) +TEST_CASE( t6_4_array_object ) { // Init createJsonFile( R"({ "array" : [ { "name": "str1" }, { "name": "str2" }] })" ); @@ -320,39 +314,38 @@ BOOST_AUTO_TEST_CASE(t6_4_array_object) // Check auto attributePtr = json.getAttributeValue( "array" ); - BOOST_REQUIRE( attributePtr ); + TEST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - BOOST_REQUIRE( arrayPtr ); + TEST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - BOOST_REQUIRE( valPtr ); + TEST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - BOOST_REQUIRE( objectPtr ); + TEST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - BOOST_CHECK_EQUAL( namePtr->asString(), "str1" ); + TEST_CHECK_EQUAL( namePtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - BOOST_REQUIRE( valPtr ); + TEST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - BOOST_REQUIRE( objectPtr ); + TEST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - BOOST_CHECK_EQUAL( namePtr->asString(), "str2" ); + TEST_CHECK_EQUAL( namePtr->asString(), "str2" ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_4_array_root_of_object_with_objects) +TEST_CASE( t6_4_array_root_of_object_with_objects ) { // Init createJsonFile( @@ -371,39 +364,38 @@ BOOST_AUTO_TEST_CASE(t6_4_array_root_of_object_with_objects) // Check auto arrayValuePtr = json.asValue(); - BOOST_REQUIRE( arrayValuePtr ); + TEST_REQUIRE( arrayValuePtr ); auto arrayPtr = arrayValuePtr->asArray(); - BOOST_REQUIRE( arrayPtr ); + TEST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - BOOST_REQUIRE( valPtr ); + TEST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - BOOST_REQUIRE( objectPtr ); + TEST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - BOOST_CHECK_EQUAL( namePtr->asString(), "str1" ); + TEST_CHECK_EQUAL( namePtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - BOOST_REQUIRE( valPtr ); + TEST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - BOOST_REQUIRE( objectPtr ); + TEST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - BOOST_CHECK_EQUAL( namePtr->asString(), "str2" ); + TEST_CHECK_EQUAL( namePtr->asString(), "str2" ); } - } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_not_exist_attribute) +TEST_CASE( t7_not_exist_attribute ) { // Init createJsonFile( R"({ "name": "str" })" ); @@ -413,12 +405,12 @@ BOOST_AUTO_TEST_CASE(t7_not_exist_attribute) // Check auto atrPtr = json.getAttributeValue( "surname" ); - BOOST_REQUIRE( !atrPtr ); + TEST_REQUIRE( !atrPtr ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/main.cpp b/src/main.cpp index e792c5f..421d48c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,7 @@ //------------------------------------------------------------------------------ -int main(int _argc, char * _argv[]) +int main( int _argc, char * _argv[] ) { try { @@ -22,8 +22,6 @@ int main(int _argc, char * _argv[]) std::cout << "Something wrong happens" << std::endl; return EXIT_FAILURE; } - } //------------------------------------------------------------------------------ - diff --git a/src/model_includes/api/mi_analyzer.hpp b/src/model_includes/api/mi_analyzer.hpp index 5f019c3..153fa49 100644 --- a/src/model_includes/api/mi_analyzer.hpp +++ b/src/model_includes/api/mi_analyzer.hpp @@ -22,8 +22,7 @@ namespace model_includes { class Analyzer { public: - - using ModelPtr = stdfwd::unique_ptr< Model >; + using ModelPtr = stdfwd::unique_ptr< Model >; virtual ~Analyzer() = default; diff --git a/src/model_includes/api/mi_file.hpp b/src/model_includes/api/mi_file.hpp index cb5b525..68b1fdd 100644 --- a/src/model_includes/api/mi_file.hpp +++ b/src/model_includes/api/mi_file.hpp @@ -13,7 +13,6 @@ namespace model_includes { class File { public: - using IncludeIndex = std::size_t; using Path = stdfs::path; diff --git a/src/model_includes/api/mi_include.hpp b/src/model_includes/api/mi_include.hpp index 1fabd5a..1412260 100644 --- a/src/model_includes/api/mi_include.hpp +++ b/src/model_includes/api/mi_include.hpp @@ -13,7 +13,6 @@ namespace model_includes { class Include { public: - virtual ~Include() = default; virtual const IncludeLocation & getLocation() const = 0; diff --git a/src/model_includes/api/mi_include_location.hpp b/src/model_includes/api/mi_include_location.hpp index 56bbd59..06e08cf 100644 --- a/src/model_includes/api/mi_include_location.hpp +++ b/src/model_includes/api/mi_include_location.hpp @@ -11,7 +11,6 @@ namespace model_includes { class IncludeLocation { public: - virtual ~IncludeLocation() = default; using LineNumber = std::size_t; diff --git a/src/model_includes/ih/mi_accessor_impl.hpp b/src/model_includes/ih/mi_accessor_impl.hpp index fd025a3..cb8af32 100644 --- a/src/model_includes/ih/mi_accessor_impl.hpp +++ b/src/model_includes/ih/mi_accessor_impl.hpp @@ -11,7 +11,6 @@ namespace model_includes { class ModelIncludesAccessorImpl final : public ModelIncludesAccessor { public: - ModelIncludesAccessorImpl(); ~ModelIncludesAccessorImpl() override; @@ -23,8 +22,7 @@ class ModelIncludesAccessorImpl final : public ModelIncludesAccessor ModelPtr createEmptyModel() override; private: - - std::unique_ptr< Analyzer > m_analyzer; + std::unique_ptr< Analyzer > m_analyzer; }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_analyzer_context.cpp b/src/model_includes/impl/mi_analyzer_context.cpp index b27130c..e6fe78c 100644 --- a/src/model_includes/impl/mi_analyzer_context.cpp +++ b/src/model_includes/impl/mi_analyzer_context.cpp @@ -8,8 +8,8 @@ #include -#include #include +#include //------------------------------------------------------------------------------ @@ -26,7 +26,6 @@ AnalyzerContext::AnalyzerContext( , m_model{ _model } , needAnalyzeResolvedIncludes{ false } { - } //------------------------------------------------------------------------------ @@ -41,7 +40,6 @@ AnalyzerContext::AnalyzerContext( , m_model{ _model } , needAnalyzeResolvedIncludes{ false } { - } //------------------------------------------------------------------------------ @@ -79,12 +77,16 @@ bool AnalyzerContext::isCppFile( const Path & _path ) const const project::Project & project = getProject(); if( !project.hasCppFileExtensions() ) + { return true; + } const Path extension = _path.extension(); if( extension.empty() && project.getAnalyzeWithoutExtension() ) + { return true; + } const bool result = project.isExistsCppExtension( extension.string() ); return result; @@ -94,11 +96,15 @@ bool AnalyzerContext::isCppFile( const Path & _path ) const bool AnalyzerContext::isIgnoredFile( const Path & _path ) const { - if( getModel().findFile( _path ) ) + if( getModel().findFile( _path ) != nullptr ) + { return false; + } - if( m_ignoredFiles.count( _path ) ) + if( m_ignoredFiles.count( _path ) > 0 ) + { return true; + } if( getProject().isIgnoredFile( _path ) ) { @@ -144,7 +150,9 @@ bool AnalyzerContext::isFolderHasFile( const Path & _dir, const Path & _path ) const std::size_t pathSize = pathStr.size(); if( dirSize >= pathSize ) + { return true; + } const std::string pathSubStr = pathStr.substr( 0, dirSize ); const bool result = ( pathSubStr == dirStr ); @@ -167,7 +175,7 @@ const Model & AnalyzerContext::getModel() const //------------------------------------------------------------------------------ -void AnalyzerContext::setNeedAnalyzeResolvedIncludes( bool _enable) +void AnalyzerContext::setNeedAnalyzeResolvedIncludes( bool _enable ) { needAnalyzeResolvedIncludes = _enable; } @@ -185,7 +193,9 @@ void AnalyzerContext::addResolvedFile( const Path & _path ) { auto pair = m_resolvedFiles.insert( _path ); if( pair.second ) + { m_resolvedFilesStack.push( _path ); + } } //------------------------------------------------------------------------------ @@ -193,7 +203,9 @@ void AnalyzerContext::addResolvedFile( const Path & _path ) AnalyzerContext::PathOpt AnalyzerContext::popResolvedFile() { if( m_resolvedFilesStack.empty() ) + { return std::nullopt; + } Path result = m_resolvedFilesStack.top(); m_resolvedFilesStack.pop(); diff --git a/src/model_includes/impl/mi_analyzer_context.hpp b/src/model_includes/impl/mi_analyzer_context.hpp index 96ac518..c81ea1c 100644 --- a/src/model_includes/impl/mi_analyzer_context.hpp +++ b/src/model_includes/impl/mi_analyzer_context.hpp @@ -5,9 +5,9 @@ #include #include -#include -#include #include +#include +#include //------------------------------------------------------------------------------ @@ -76,7 +76,6 @@ class AnalyzerContext PathOpt getCurrentCMakeSourceFile() const; private: - const project::Project & m_project; const cmake_project::Project * m_cmakeProject; Model & m_model; @@ -89,7 +88,6 @@ class AnalyzerContext ResolvedFilesStack m_resolvedFilesStack; std::optional< Path > m_currentCMakeSourceFile; - }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_analyzer_impl.cpp b/src/model_includes/impl/mi_analyzer_impl.cpp index 9ead8a8..ad60cbb 100644 --- a/src/model_includes/impl/mi_analyzer_impl.cpp +++ b/src/model_includes/impl/mi_analyzer_impl.cpp @@ -1,22 +1,22 @@ #include "model_includes/impl/mi_analyzer_impl.hpp" -#include "model_includes/api/mi_model.hpp" -#include "model_includes/api/mi_file.hpp" #include "model_includes/api/enums/mi_file_type.hpp" -#include "model_includes/api/enums/mi_include_type.hpp" #include "model_includes/api/enums/mi_include_status.hpp" +#include "model_includes/api/enums/mi_include_type.hpp" +#include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_model.hpp" +#include "model_includes/impl/mi_analyzer_context.hpp" #include "model_includes/impl/mi_model_impl.hpp" -#include "model_includes/impl/mi_std_library.hpp" #include "model_includes/impl/mi_resolver.hpp" -#include "model_includes/impl/mi_analyzer_context.hpp" +#include "model_includes/impl/mi_std_library.hpp" -#include "parser/api/pr_parser.hpp" #include "parser/api/pr_include_file.hpp" +#include "parser/api/pr_parser.hpp" -#include "fs/api/fs_file_system.hpp" -#include "fs/api/fs_file.hpp" #include "fs/api/enums/fs_item_type.hpp" #include "fs/api/fs_exceptions.hpp" +#include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" #include "project/api/prj_project.hpp" @@ -24,11 +24,11 @@ #include "cmake_project/api/cprj_project.hpp" +#include #include +#include #include #include -#include -#include //------------------------------------------------------------------------------ @@ -74,7 +74,9 @@ AnalyzerImpl::ModelPtr AnalyzerImpl::analyze( [&]( const Path & _path ) { if( context.isFileInIgnoreDir( _path ) ) + { return true; + } context.setCurrentCMakeSourceFile( _path ); @@ -112,20 +114,22 @@ void AnalyzerImpl::analyzeFolder( ) const { if( _context.isIgnoredDir( _folderPath ) ) + { return; + } m_fs.forEachItem( _folderPath, [&]( const Path & _path, fs::ItemType _type ) { static_assert( static_cast< int >( fs::ItemType::Count ) == 2 ); - switch ( _type ) + switch( _type ) { - case fs::ItemType::Folder : + case fs::ItemType::Folder: analyzeFolder( _context, _path ); break; - case fs::ItemType::File : + case fs::ItemType::File: analyzeFile( _context, _path ); break; @@ -144,17 +148,23 @@ void AnalyzerImpl::analyzeFile( ) const { if( !_context.isCppFile( _path ) ) + { return; + } if( _context.isIgnoredFile( _path ) ) + { return; + } try { auto filePtr = m_fs.openFile( _path ); INTERNAL_CHECK_WARRING( filePtr ); if( !filePtr ) + { return; + } auto includesFiles = m_parser.parseFile( *filePtr ); analyzeIncludeFiles( _context, _path, includesFiles ); @@ -164,7 +174,6 @@ void AnalyzerImpl::analyzeFile( std::cout << _exception.what() << std::endl; return; } - } //------------------------------------------------------------------------------ @@ -193,18 +202,22 @@ void AnalyzerImpl::analyzeIncludeFile( ) const { if( _context.isIgnoreIncludeFile( _includeFile ) ) + { return; + } ResolvedPath pair = resolvePath( _context, _path, _includeFile ); const auto & includedFilePath = pair.first; if( _context.isIgnoredFile( includedFilePath ) ) + { return; + } FileType fileType = getFileType( includedFilePath ); Model & model = _context.takeModel(); - File & includedFile = model.ensureFile( includedFilePath, fileType ); + File & includedFile = model.ensureFile( includedFilePath, fileType ); const parser::IncludeFileLocation & location = _includeFile.getLocation(); Model::IncludeLocationInfo locationInfo{ @@ -213,8 +226,8 @@ void AnalyzerImpl::analyzeIncludeFile( location.getEnd() }; - const IncludeType type = getIncludeType( _includeFile ); - const IncludeStatus status = getIncludeStatus( includedFile, pair ); + const IncludeType type = getIncludeType( _includeFile ); + const IncludeStatus status = getIncludeStatus( includedFile, pair ); const auto & include = model.createInclude( locationInfo, _file, @@ -236,17 +249,19 @@ void AnalyzerImpl::postProcesNewInclude( using namespace model_includes; if( !_context.isNeedAnalyzeResolvedIncludes() ) + { return; + } static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); const IncludeStatus includeStatus = _include.getStatus(); switch( includeStatus ) { - case IncludeStatus::Unresolved : + case IncludeStatus::Unresolved: return; - case IncludeStatus::Resolved : + case IncludeStatus::Resolved: { const File & destinationFile = _include.getDestinationFile(); @@ -254,16 +269,16 @@ void AnalyzerImpl::postProcesNewInclude( const FileType type = destinationFile.getType(); switch( type ) { - case FileType::ProjectFile : + case FileType::ProjectFile: { _context.addResolvedFile( destinationFile.getPath() ); } break; - case FileType::StdLibraryFile : + case FileType::StdLibraryFile: return; - case FileType::Count : + case FileType::Count: { INTERNAL_CHECK_WARRING( false ); return; @@ -272,7 +287,7 @@ void AnalyzerImpl::postProcesNewInclude( } break; - case IncludeStatus::Count : + case IncludeStatus::Count: { INTERNAL_CHECK_WARRING( false ); return; @@ -294,7 +309,7 @@ IncludeType AnalyzerImpl::getIncludeType( ) const { static_assert( static_cast< int >( IncludeType::Count ) == 2 ); - return _includesFile.isSystem() ? IncludeType::System : IncludeType::User ; + return _includesFile.isSystem() ? IncludeType::System : IncludeType::User; } //------------------------------------------------------------------------------ @@ -306,7 +321,9 @@ IncludeStatus AnalyzerImpl::getIncludeStatus( { static_assert( static_cast< int >( FileType::Count ) == 2 ); if( _file.getType() == FileType::StdLibraryFile ) + { return IncludeStatus::Resolved; + } const bool isResolved = _pair.second; return isResolved ? IncludeStatus::Resolved : IncludeStatus::Unresolved; @@ -339,7 +356,7 @@ AnalyzerImpl::ResolvedPath AnalyzerImpl::resolvePath( isResolved = true; } - return ResolvedPath{ filePath,isResolved }; + return ResolvedPath{ filePath, isResolved }; } //------------------------------------------------------------------------------ @@ -347,7 +364,9 @@ AnalyzerImpl::ResolvedPath AnalyzerImpl::resolvePath( Resolver & AnalyzerImpl::ensureResolver() const { if( !m_resolver ) - m_resolver.reset( new Resolver{ m_fs } ); + { + m_resolver = std::make_unique< Resolver >( m_fs ); + } return *m_resolver; } diff --git a/src/model_includes/impl/mi_analyzer_impl.hpp b/src/model_includes/impl/mi_analyzer_impl.hpp index 673502f..2b55927 100644 --- a/src/model_includes/impl/mi_analyzer_impl.hpp +++ b/src/model_includes/impl/mi_analyzer_impl.hpp @@ -48,13 +48,12 @@ class AnalyzerImpl final : public Analyzer ) const override; private: - using Path = stdfs::path; using IncludeFiles = stdfwd::vector< parser::IncludeFile >; static ModelPtr initModel( const project::Project & _project ); - void analyzeFolder( AnalyzerContext & _context, const Path & _path ) const; + void analyzeFolder( AnalyzerContext & _context, const Path & _folderPath ) const; void analyzeFile( AnalyzerContext & _context, const Path & _path ) const; @@ -96,7 +95,6 @@ class AnalyzerImpl final : public Analyzer Resolver & ensureResolver() const; private: - const fs::FileSystem & m_fs; const parser::Parser & m_parser; mutable std::unique_ptr< Resolver > m_resolver; diff --git a/src/model_includes/impl/mi_file_impl.cpp b/src/model_includes/impl/mi_file_impl.cpp index 7aa6ca3..749d1a6 100644 --- a/src/model_includes/impl/mi_file_impl.cpp +++ b/src/model_includes/impl/mi_file_impl.cpp @@ -4,9 +4,9 @@ #include "exception/ih/exc_internal_error.hpp" -#include #include #include +#include #include //------------------------------------------------------------------------------ @@ -15,8 +15,8 @@ namespace model_includes { //------------------------------------------------------------------------------ -FileImpl::FileImpl( const Path & _path, FileType _type ) - : m_path{ _path } +FileImpl::FileImpl( Path _path, FileType _type ) + : m_path{ std::move( _path ) } , m_type{ _type } { } @@ -40,9 +40,13 @@ FileType FileImpl::getType() const void FileImpl::addInclude( const Include & _include ) { if( &_include.getSourceFile() == this ) + { m_includes.push_back( &_include ); + } else if( &_include.getDestinationFile() == this ) + { m_includedBy.push_back( &_include ); + } else INTERNAL_CHECK_WARRING( false ); } @@ -122,13 +126,15 @@ FileImpl::IncludeIndex FileImpl::getCountRecursive( const File * currentFilePtr = files.front(); files.pop_front(); INTERNAL_CHECK_WARRING( currentFilePtr ); - if( !currentFilePtr ) + if( currentFilePtr == nullptr ) + { continue; + } - const IncludeIndex count = (*currentFilePtr.*_getCount)(); + const IncludeIndex count = ( *currentFilePtr.*_getCount )(); for( IncludeIndex i = 0; i < count; ++i ) { - const Include & include = (*currentFilePtr.*_getInclude)( i ); + const Include & include = ( *currentFilePtr.*_getInclude )( i ); const File & file = ( include.*_getFile )(); if( auto pair = uniqFiles.insert( &file ); pair.second ) diff --git a/src/model_includes/impl/mi_file_impl.hpp b/src/model_includes/impl/mi_file_impl.hpp index 1b866ad..d6368de 100644 --- a/src/model_includes/impl/mi_file_impl.hpp +++ b/src/model_includes/impl/mi_file_impl.hpp @@ -1,7 +1,7 @@ #pragma once -#include "model_includes/api/mi_file.hpp" #include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_file.hpp" #include #include @@ -15,8 +15,7 @@ namespace model_includes { class FileImpl final : public File { public: - - FileImpl( const Path & _path, FileType _type ); + FileImpl( Path _path, FileType _type ); const Path & getPath() const override; FileType getType() const override; @@ -32,9 +31,8 @@ class FileImpl final : public File const Include & getIncludedBy( IncludeIndex _index ) const override; private: - using IncludesContainer = std::vector< const Include * >; - using IncludeCallback = std::function< void ( const Include & ) >; + using IncludeCallback = std::function< void( const Include & ) >; IncludeIndex getCountRecursive( IncludeIndex ( File::*_getCount )() const, @@ -43,7 +41,6 @@ class FileImpl final : public File ) const; private: - IncludesContainer m_includes; IncludesContainer m_includedBy; diff --git a/src/model_includes/impl/mi_include_impl.cpp b/src/model_includes/impl/mi_include_impl.cpp index f4e0b96..efabe21 100644 --- a/src/model_includes/impl/mi_include_impl.cpp +++ b/src/model_includes/impl/mi_include_impl.cpp @@ -23,7 +23,6 @@ IncludeImpl::IncludeImpl( , m_status{ _status } , m_type{ _type } { - } //------------------------------------------------------------------------------ @@ -69,4 +68,3 @@ IncludeType IncludeImpl::getType() const //------------------------------------------------------------------------------ } - diff --git a/src/model_includes/impl/mi_include_impl.hpp b/src/model_includes/impl/mi_include_impl.hpp index f0442b8..a510a1b 100644 --- a/src/model_includes/impl/mi_include_impl.hpp +++ b/src/model_includes/impl/mi_include_impl.hpp @@ -13,7 +13,6 @@ namespace model_includes { class IncludeImpl final : public Include { public: - using IncludeLocationPtr = std::unique_ptr< IncludeLocation >; IncludeImpl( @@ -35,7 +34,6 @@ class IncludeImpl final : public Include IncludeType getType() const override; private: - IncludeLocationPtr m_location; const File & m_sourceFile; diff --git a/src/model_includes/impl/mi_include_location_impl.cpp b/src/model_includes/impl/mi_include_location_impl.cpp index 03bb04d..a982dd4 100644 --- a/src/model_includes/impl/mi_include_location_impl.cpp +++ b/src/model_includes/impl/mi_include_location_impl.cpp @@ -15,7 +15,6 @@ IncludeLocationImpl::IncludeLocationImpl( , m_begin { _begin } , m_end { _end } { - } //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_include_location_impl.hpp b/src/model_includes/impl/mi_include_location_impl.hpp index 1b9c0e1..68b9845 100644 --- a/src/model_includes/impl/mi_include_location_impl.hpp +++ b/src/model_includes/impl/mi_include_location_impl.hpp @@ -11,7 +11,6 @@ namespace model_includes { class IncludeLocationImpl : public IncludeLocation { public: - IncludeLocationImpl( LineNumber _line, ColumNumber _begin, @@ -23,7 +22,6 @@ class IncludeLocationImpl : public IncludeLocation ColumNumber getFileNameEndPos() const override; private: - LineNumber m_line; ColumNumber m_begin; ColumNumber m_end; diff --git a/src/model_includes/impl/mi_model_impl.cpp b/src/model_includes/impl/mi_model_impl.cpp index 3552180..5a14010 100644 --- a/src/model_includes/impl/mi_model_impl.cpp +++ b/src/model_includes/impl/mi_model_impl.cpp @@ -6,8 +6,8 @@ #include "exception/ih/exc_internal_error.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -33,10 +33,12 @@ void ModelImpl::forEachFile( FileCallback _callback ) const { const File * file = pair.second.get(); INTERNAL_CHECK_WARRING( file ); - if( file ) + if( file != nullptr ) { if( !_callback( *file ) ) + { break; + } } } } @@ -72,7 +74,9 @@ File & ModelImpl::ensureFile( const Path & _filePath, FileType _fileType ) const File * ModelImpl::findFile( const Path & _filePath ) const { if( auto it = m_files.find( _filePath ); it != m_files.end() ) + { return it->second.get(); + } return nullptr; } @@ -85,10 +89,14 @@ void ModelImpl::forEachInclude( IncludeCallback _callback ) const { INTERNAL_CHECK_WARRING( includePtr ); if( !includePtr ) + { continue; + } if( !_callback( *includePtr ) ) + { break; + } } } diff --git a/src/model_includes/impl/mi_model_impl.hpp b/src/model_includes/impl/mi_model_impl.hpp index 115ec3d..9c037f4 100644 --- a/src/model_includes/impl/mi_model_impl.hpp +++ b/src/model_includes/impl/mi_model_impl.hpp @@ -18,7 +18,6 @@ namespace model_includes { class ModelImpl final : public Model { public: - ModelImpl(); ~ModelImpl() override; @@ -42,14 +41,12 @@ class ModelImpl final : public Model ) override; private: - using IncludeLocationPtr = std::unique_ptr< IncludeLocation >; IncludeLocationPtr createIncludeLocation( const IncludeLocationInfo & _location ) const; private: - using FilePtr = std::unique_ptr< File >; using Files = std::unordered_map< Path, FilePtr >; @@ -60,7 +57,6 @@ class ModelImpl final : public Model Includes m_includes; Path m_projectDir; - }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_resolver.cpp b/src/model_includes/impl/mi_resolver.cpp index 3606b31..bd6d335 100644 --- a/src/model_includes/impl/mi_resolver.cpp +++ b/src/model_includes/impl/mi_resolver.cpp @@ -1,20 +1,20 @@ #include "model_includes/impl/mi_resolver.hpp" -#include "model_includes/impl/mi_std_library.hpp" -#include "model_includes/impl/mi_resolver_context.hpp" #include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/impl/mi_resolver_context.hpp" +#include "model_includes/impl/mi_std_library.hpp" -#include "fs/api/fs_file_system.hpp" #include "fs/api/fs_exceptions.hpp" +#include "fs/api/fs_file_system.hpp" -#include "project/api/prj_project.hpp" #include "cmake_project/api/cprj_project.hpp" +#include "project/api/prj_project.hpp" #include "exception/ih/exc_internal_error.hpp" +#include #include #include -#include //------------------------------------------------------------------------------ @@ -42,12 +42,14 @@ Resolver::PathOpt Resolver::resolvePath( _cmakeProject, _startFile, _fileName, - _currentCMakeSourceFile + std::move( _currentCMakeSourceFile ) }; PathOpt pathOpt = checkInCurrentDir( context ); if( pathOpt ) + { return pathOpt; + } pathOpt = findInIncludeFolders( context ); @@ -61,7 +63,9 @@ FileType Resolver::resolveFileType( const Path & _file ) FileType result = FileType::ProjectFile; if( _file.has_parent_path() ) + { return result; + } const std::string name = _file.string(); const StdLibrary & library = getStdLibrary(); @@ -69,7 +73,6 @@ FileType Resolver::resolveFileType( const Path & _file ) result = isStdLib ? FileType::StdLibraryFile : FileType::ProjectFile; return result; - } //------------------------------------------------------------------------------ @@ -80,14 +83,17 @@ Resolver::PathOpt Resolver::checkInCurrentDir( { Path startDir = _context.getStartFile().parent_path(); if( startDir.is_relative() ) + { startDir = _context.getProject().getProjectDir() / startDir; + } const Path file = startDir / _context.getFileName(); if( isExistFile( file ) ) + { return PathOpt{ file }; + } return std::nullopt; - } //------------------------------------------------------------------------------ @@ -98,15 +104,18 @@ Resolver::PathOpt Resolver::findInIncludeFolders( { PathOpt pathOpt = findInIncludeFoldersInProject( _context ); if( pathOpt ) + { return pathOpt; + } - if( _context.getCMakeProject() ) + if( _context.getCMakeProject() != nullptr ) + { pathOpt = findInIncludeFoldersInCMakeProject( _context ); + } return pathOpt; } - //------------------------------------------------------------------------------ Resolver::PathOpt Resolver::findInIncludeFoldersInProject( @@ -116,15 +125,17 @@ Resolver::PathOpt Resolver::findInIncludeFoldersInProject( const std::string & fileName = _context.getFileName(); const project::Project & project = _context.getProject(); const project::Project::IncludeDirIndex count = project.getIncludeDirsCount(); - const auto projectDir = project.getProjectDir(); + const auto & projectDir = project.getProjectDir(); for( project::Project::IncludeDirIndex i = 0; i < count; ++i ) { - Path includeDir = project.getIncludeDir( i ); + const Path & includeDir = project.getIncludeDir( i ); PathOpt fileOpt = findFile( projectDir, includeDir, fileName ); if( fileOpt ) + { return fileOpt; + } } return std::nullopt; @@ -137,7 +148,7 @@ Resolver::PathOpt Resolver::findInIncludeFoldersInCMakeProject( ) const { const cmake_project::Project * projectOpt = _context.getCMakeProject(); - if( !projectOpt ) + if( projectOpt == nullptr ) { INTERNAL_CHECK_WARRING( false ); return std::nullopt; @@ -151,7 +162,9 @@ Resolver::PathOpt Resolver::findInIncludeFoldersInCMakeProject( PathOpt sourceFile = _context.getCurrentCMakeSourceFile(); if( !sourceFile ) + { sourceFile = startFile; + } PathOpt result; @@ -177,14 +190,18 @@ Resolver::PathOpt Resolver::findFile( { Path includeDir{ _includeDir }; if( includeDir.is_relative() ) + { includeDir = _projectDir / includeDir; + } Path file = includeDir / _fileName; file = stdfs::lexically_normal( file ); if( isExistFile( file ) ) + { return PathOpt{ file }; + } return std::nullopt; } diff --git a/src/model_includes/impl/mi_resolver.hpp b/src/model_includes/impl/mi_resolver.hpp index aeb74cb..2b84b7e 100644 --- a/src/model_includes/impl/mi_resolver.hpp +++ b/src/model_includes/impl/mi_resolver.hpp @@ -28,7 +28,6 @@ namespace model_includes { class Resolver { public: - using Path = stdfs::path; using PathOpt = std::optional< Path >; @@ -42,11 +41,10 @@ class Resolver PathOpt currentCMakeSourceFile ) const; - static FileType resolveFileType( const Path & _startFile ); + static FileType resolveFileType( const Path & _file ); private: - - PathOpt checkInCurrentDir( const ResolverContext & _context ) const; + PathOpt checkInCurrentDir( const ResolverContext & _context ) const; PathOpt findInIncludeFolders( const ResolverContext & _context ) const; PathOpt findInIncludeFoldersInProject( @@ -67,7 +65,6 @@ class Resolver static const StdLibrary & getStdLibrary(); private: - const fs::FileSystem & m_fs; }; diff --git a/src/model_includes/impl/mi_resolver_context.cpp b/src/model_includes/impl/mi_resolver_context.cpp index 868813e..b36b71b 100644 --- a/src/model_includes/impl/mi_resolver_context.cpp +++ b/src/model_includes/impl/mi_resolver_context.cpp @@ -9,17 +9,16 @@ namespace model_includes { ResolverContext::ResolverContext( const project::Project & _project, const cmake_project::Project * _cmakeProject, - const Path & _startFile, + Path _startFile, stdfwd::string_view _fileName, PathOpt _currentCMakeSourceFile ) : m_project{ _project } , m_cmakeProject{ _cmakeProject } - , m_startFile{ _startFile } + , m_startFile{ std::move( _startFile ) } , m_fileName{ _fileName } - , m_currentCMakeSourceFile{ _currentCMakeSourceFile } + , m_currentCMakeSourceFile{ std::move( _currentCMakeSourceFile ) } { - } //------------------------------------------------------------------------------ @@ -59,5 +58,4 @@ ResolverContext::PathOpt ResolverContext::getCurrentCMakeSourceFile() const //------------------------------------------------------------------------------ - } diff --git a/src/model_includes/impl/mi_resolver_context.hpp b/src/model_includes/impl/mi_resolver_context.hpp index d45b658..34ece13 100644 --- a/src/model_includes/impl/mi_resolver_context.hpp +++ b/src/model_includes/impl/mi_resolver_context.hpp @@ -2,9 +2,9 @@ #include +#include #include #include -#include //------------------------------------------------------------------------------ @@ -32,7 +32,7 @@ class ResolverContext ResolverContext( const project::Project & _project, const cmake_project::Project * _cmakeProject, - const Path & _startFile, + Path _startFile, stdfwd::string_view _fileName, PathOpt _currentCMakeSourceFile ); @@ -46,7 +46,6 @@ class ResolverContext PathOpt getCurrentCMakeSourceFile() const; private: - const project::Project & m_project; const cmake_project::Project * m_cmakeProject; diff --git a/src/model_includes/impl/mi_std_library.cpp b/src/model_includes/impl/mi_std_library.cpp index 1e4f668..803355e 100644 --- a/src/model_includes/impl/mi_std_library.cpp +++ b/src/model_includes/impl/mi_std_library.cpp @@ -24,7 +24,6 @@ const StdLibrary & StdLibrary::getInstance() } return *m_instance; - } //------------------------------------------------------------------------------ @@ -32,7 +31,7 @@ const StdLibrary & StdLibrary::getInstance() bool StdLibrary::isExists( std::string_view _name ) const { std::string str{ _name }; - return m_stdFiles.count( str ); + return m_stdFiles.count( str ) > 0; } //------------------------------------------------------------------------------ @@ -75,14 +74,14 @@ void StdLibrary::initCppLibraties() void StdLibrary::initConceptsLibrary() { - addHeaders({ "concepts" }); + addHeaders( { "concepts" } ); } //------------------------------------------------------------------------------ void StdLibrary::initCoroutinesLibrary() { - addHeaders({ "coroutine" }); + addHeaders( { "coroutine" } ); } //------------------------------------------------------------------------------ @@ -118,45 +117,45 @@ void StdLibrary::initUtilitiesLibrary() void StdLibrary::initDynamicMemoryLibrary() { - addHeaders({ + addHeaders( { "new", "memory", "scoped_allocator", "memory_resource", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initNumberLimitLibrary() { - addHeaders({ + addHeaders( { "climits", "cfloat", "cstdint", "cinttypes", "limits", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initErrorHandlingLibrary() { - addHeaders({ + addHeaders( { "exception", "stdexcept", "cassert", "system_error", "cerrno", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initStringLibraryLibrary() { - addHeaders({ + addHeaders( { "cctype", "cwctype", "cstring", @@ -166,14 +165,14 @@ void StdLibrary::initStringLibraryLibrary() "string_view", "charconv", "format", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initContainersLibrary() { - addHeaders({ + addHeaders( { "array", "vector", "deque", @@ -186,52 +185,52 @@ void StdLibrary::initContainersLibrary() "stack", "queue", "span", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initIteratorsLibrary() { - addHeaders({ "iterator" }); + addHeaders( { "iterator" } ); } //------------------------------------------------------------------------------ void StdLibrary::initRangesLibrary() { - addHeaders({ "ranges" }); + addHeaders( { "ranges" } ); } //------------------------------------------------------------------------------ void StdLibrary::initAlgorithmsLibrary() { - addHeaders({ "algorithm", "execution" }); + addHeaders( { "algorithm", "execution" } ); } //------------------------------------------------------------------------------ void StdLibrary::initNumericsLibrary() { - addHeaders({ + addHeaders( { "cmath", "complex", "valarray", "random", "numeric", - "ratio ", + "ratio", "cfenv", "bit", "numbers", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initIOLibrary() { - addHeaders({ + addHeaders( { "iosfwd", "ios", "istream", @@ -244,39 +243,39 @@ void StdLibrary::initIOLibrary() "iomanip", "streambuf", "cstdio", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initLocalizationLibrary() { - addHeaders({ + addHeaders( { "locale", "clocale", "codecvt", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initRegexLibrary() { - addHeaders({ "regex" }); + addHeaders( { "regex" } ); } //------------------------------------------------------------------------------ void StdLibrary::initAtomicLibrary() { - addHeaders({ "atomic" }); + addHeaders( { "atomic" } ); } //------------------------------------------------------------------------------ void StdLibrary::initThreadLibrary() { - addHeaders({ + addHeaders( { "thread", "stop_token", "mutex", @@ -286,14 +285,14 @@ void StdLibrary::initThreadLibrary() "semaphore", "latch", "barrier", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initFsLibrary() { - addHeaders({ "filesystem" }); + addHeaders( { "filesystem" } ); } //------------------------------------------------------------------------------ @@ -329,46 +328,42 @@ void StdLibrary::initCCompatibilityLibraries() void StdLibrary::initEmptyCHeaders() { - addHeaders({ + addHeaders( { "ccomplex", "complex.h", "ctgmath", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initMeaninglessCHeaders() { - addHeaders({ + addHeaders( { "ciso646", "iso646.h", "cstdalign", "cstdbool", "stdbool.h", - }); + } ); } //------------------------------------------------------------------------------ void StdLibrary::initUnsupportedCHeaders() { - addHeaders({ + addHeaders( { "stdatomic.h", "stdnoreturn.h", "threads.h", - }); - + } ); } //------------------------------------------------------------------------------ void StdLibrary::initCLibraries() { - addHeaders({ - "stdalign.h", - "tgmath.h" - }); + addHeaders( { "stdalign.h", "tgmath.h" } ); } //------------------------------------------------------------------------------ @@ -377,7 +372,7 @@ void StdLibrary::addHeaders( const Headers & _headers ) { for( const std::string & name : _headers ) { - if(auto pair = m_stdFiles.insert( name ); !pair.second) + if( auto pair = m_stdFiles.insert( name ); !pair.second ) { INTERNAL_CHECK_WARRING( false ); } diff --git a/src/model_includes/impl/mi_std_library.hpp b/src/model_includes/impl/mi_std_library.hpp index 024dbbd..aba8817 100644 --- a/src/model_includes/impl/mi_std_library.hpp +++ b/src/model_includes/impl/mi_std_library.hpp @@ -2,8 +2,8 @@ #include -#include #include +#include //------------------------------------------------------------------------------ @@ -14,13 +14,11 @@ namespace model_includes { class StdLibrary { public: - static const StdLibrary & getInstance(); bool isExists( std::string_view _name ) const; private: - StdLibrary(); void init(); @@ -55,9 +53,7 @@ class StdLibrary void addHeaders( const Headers & _headers ); private: - std::unordered_set< std::string > m_stdFiles; - }; //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp index 7839820..f2dfdd9 100644 --- a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp +++ b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.cpp @@ -2,32 +2,32 @@ #include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" -#include "model_includes/api/mi_model.hpp" #include "model_includes/api/enums/mi_file_type.hpp" -#include "model_includes/impl/mi_resolver.hpp" -#include "model_includes/impl/mi_analyzer_impl.hpp" +#include "model_includes/api/mi_model.hpp" #include "model_includes/ih/mi_accessor_impl.hpp" +#include "model_includes/impl/mi_analyzer_impl.hpp" +#include "model_includes/impl/mi_resolver.hpp" #include "parser/api/pr_parser.hpp" #include "parser/ih/pr_accessor_impl.hpp" -#include "fs/api/fs_file_system.hpp" #include "fs/api/fs_factory.hpp" #include "fs/api/fs_file.hpp" +#include "fs/api/fs_file_system.hpp" #include "fs/ih/fs_accessor_impl.hpp" #include "project/api/prj_project.hpp" #include "project/ih/prj_project_accesso_impl.hpp" -#include "cmake_project/api/cprj_project.hpp" #include "cmake_project/api/cprj_loader.hpp" +#include "cmake_project/api/cprj_project.hpp" #include "cmake_project/ih/cprj_accessor_impl.hpp" #include "exception/ih/exc_internal_error.hpp" -#include #include #include +#include //------------------------------------------------------------------------------ @@ -74,7 +74,7 @@ void ModelIncludesFixture::addFile( filePath = stdfs::lexically_normal( filePath ); auto filePtr = ensureFileSystem().createFile( filePath ); INTERNAL_CHECK_ERROR( filePtr ); - (*filePtr) << _text; + ( *filePtr ) << _text; } //------------------------------------------------------------------------------ @@ -160,7 +160,7 @@ ModelIncludesFixture::PathOpt ModelIncludesFixture::resolvePath( FileType ModelIncludesFixture::resolveFileType( stdfwd::string_view _file ) { - return ensureResolver().resolveFileType( _file ); + return Resolver::resolveFileType( _file ); } //------------------------------------------------------------------------------ @@ -171,7 +171,9 @@ BoostPredicate ModelIncludesFixture::checkFileType( ) { if( _currentFileType == _excpectedFile ) + { return true; + } std::stringstream stream; stream @@ -216,7 +218,9 @@ ModelWrapper ModelIncludesFixture::createModel() ModelIncludesAccessor & ModelIncludesFixture::ensureModelAccesddor() { if( !m_modelAccessor ) - m_modelAccessor.reset( new ModelIncludesAccessorImpl ); + { + m_modelAccessor = std::make_unique< ModelIncludesAccessorImpl >(); + } return *m_modelAccessor; } @@ -226,7 +230,9 @@ ModelIncludesAccessor & ModelIncludesFixture::ensureModelAccesddor() parser::ParserAccessor & ModelIncludesFixture::ensureParserAccessor() { if( !m_parserAccessorPtr ) - m_parserAccessorPtr.reset( new parser::ParserAccessorImpl ); + { + m_parserAccessorPtr = std::make_unique< parser::ParserAccessorImpl >(); + } return *m_parserAccessorPtr; } @@ -249,7 +255,9 @@ parser::Parser & ModelIncludesFixture::ensureParser() fs::FileSystemAccessor & ModelIncludesFixture::ensureFileAccessor() { if( !m_fsAccessorPtr ) - m_fsAccessorPtr.reset( new fs::FileSystemAccessorImpl ); + { + m_fsAccessorPtr = std::make_unique< fs::FileSystemAccessorImpl >(); + } return *m_fsAccessorPtr; } @@ -266,7 +274,9 @@ fs::FileSystem & ModelIncludesFixture::ensureFileSystem() Resolver & ModelIncludesFixture::ensureResolver() { if( !m_resolverPtr ) - m_resolverPtr.reset( new Resolver{ ensureFileSystem() } ); + { + m_resolverPtr = std::make_unique< Resolver >( ensureFileSystem() ); + } return *m_resolverPtr; } @@ -299,7 +309,9 @@ const ModelIncludesFixture::Path & ModelIncludesFixture::getProjectDir() project::ProjectAccessor & ModelIncludesFixture::ensureProjectAccessor() { if( !m_projectAccessor ) - m_projectAccessor.reset( new project::ProjectAccessorImpl ); + { + m_projectAccessor = std::make_unique< project::ProjectAccessorImpl >(); + } return *m_projectAccessor; } @@ -309,7 +321,9 @@ project::ProjectAccessor & ModelIncludesFixture::ensureProjectAccessor() project::Project & ModelIncludesFixture::ensureProject() { if( !m_project ) + { m_project = ensureProjectAccessor().createProject(); + } return *m_project; } @@ -319,7 +333,9 @@ project::Project & ModelIncludesFixture::ensureProject() cmake_project::Accessor & ModelIncludesFixture::ensureCmakeProjectAccessor() { if( !m_cmakeProjectAccessor ) - m_cmakeProjectAccessor.reset( new cmake_project::AccessorImpl ); + { + m_cmakeProjectAccessor = std::make_unique< cmake_project::AccessorImpl >(); + } return *m_cmakeProjectAccessor; } @@ -345,8 +361,10 @@ std::string ModelIncludesFixture::toString( FileType _fileType ) const static_assert( static_cast< int >( FileType::Count ) == 2 ); switch( _fileType ) { - case FileType::ProjectFile : return "ProjectFile"; - case FileType::StdLibraryFile : return "StdLibraryFile"; + case FileType::ProjectFile: + return "ProjectFile"; + case FileType::StdLibraryFile: + return "StdLibraryFile"; default: INTERNAL_CHECK_WARRING( false ); return ""; diff --git a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp index d420823..380442f 100644 --- a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp +++ b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp @@ -44,7 +44,6 @@ namespace model_includes::test { class ModelIncludesFixture { - public: using Path = stdfs::path; @@ -61,7 +60,7 @@ class ModelIncludesFixture void addFileToProject( std::string_view _file, std::string_view _text = "" ); void addFileToCmake( std::string_view _file ); - void addIncludePath( std::string_view _file ); + void addIncludePath( std::string_view _path ); void addIgnoredDir( std::string_view _dir ); void addFileFilter( std::string_view _filter ); @@ -79,7 +78,7 @@ class ModelIncludesFixture PathOpt resolvePath( const Path & _startFile, std::string_view _fileName, - const PathOpt & _currentCMakeSource + const PathOpt & _currentCMakeFile ); FileType resolveFileType( stdfwd::string_view _file ); @@ -95,7 +94,6 @@ class ModelIncludesFixture ModelWrapper createModel(); private: - const Path & getProjectDir(); ModelIncludesAccessor & ensureModelAccesddor(); @@ -118,7 +116,6 @@ class ModelIncludesFixture std::string toString( FileType _fileType ) const; private: - std::unique_ptr< ModelIncludesAccessor > m_modelAccessor; std::unique_ptr< fs::FileSystemAccessor > m_fsAccessorPtr; diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp index 6ee61aa..6490dac 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp @@ -24,7 +24,7 @@ FileWrapper::FileWrapper( const File * _file ) bool FileWrapper::isAvailable() const { - return m_file; + return m_file != nullptr; } //------------------------------------------------------------------------------ @@ -33,7 +33,9 @@ BoostPredicate FileWrapper::checkIncludesCount( int _exceptCount ) const { const File::IncludeIndex count = getFile().getIncludesCount(); if( count == static_cast< File::IncludeIndex >( _exceptCount ) ) + { return true; + } return dumpIncludes(); } @@ -44,7 +46,9 @@ BoostPredicate FileWrapper::checkIncludesCountRecursive( int _exceptCount ) cons { const File::IncludeIndex count = getFile().getIncludeFilesCountRecursive(); if( count == static_cast< File::IncludeIndex >( _exceptCount ) ) + { return true; + } return dumpIncludes(); } @@ -62,7 +66,9 @@ BoostPredicate FileWrapper::checkIncludedByCount( int _exceptCount ) const { const File::IncludeIndex count = getFile().getIncludedByCount(); if( count == static_cast< File::IncludeIndex >( _exceptCount ) ) + { return true; + } return dumpIncludedBy(); } @@ -73,7 +79,9 @@ BoostPredicate FileWrapper::checkIncludedByCountRecursive( int _exceptCount ) co { const File::IncludeIndex count = getFile().getIncludedByFilesCountRecursive(); if( count == static_cast< File::IncludeIndex >( _exceptCount ) ) + { return true; + } return dumpIncludedBy(); } @@ -90,8 +98,9 @@ IncludeWrapper FileWrapper::getIncludedBy( std::string_view _sourcePath ) const const Include & include = file.getIncludedBy( i ); const File & sourceFile = include.getSourceFile(); if( sourceFile.getPath() == sourcePath ) + { return include; - + } } return IncludeWrapper{}; } diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp index adb2b91..46c38b3 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp @@ -21,8 +21,7 @@ namespace model_includes::test { class FileWrapper { public: - - FileWrapper( const File * _file ); + FileWrapper( const File * _file ); bool isAvailable() const; @@ -35,8 +34,7 @@ class FileWrapper IncludeWrapper getIncludedBy( std::string_view _sourcePath ) const; private: - - using Path = stdfs::path; + using Path = stdfs::path; const File & getFile() const; @@ -45,7 +43,6 @@ class FileWrapper std::string dump( const Include & _include ) const; private: - const File * m_file; }; diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp index 571e62b..d1b2e0a 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp @@ -1,7 +1,7 @@ #include "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" -#include "model_includes/api/mi_include.hpp" #include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_include.hpp" #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" @@ -47,7 +47,7 @@ std::string IncludeWrapper::dump() const bool IncludeWrapper::isAvaliable() const { - return m_include; + return m_include != nullptr; } //------------------------------------------------------------------------------ @@ -70,7 +70,9 @@ BoostPredicate IncludeWrapper::checkType( IncludeType _exceptType ) const { const IncludeType type = getInclude().getType(); if( type == _exceptType ) + { return true; + } std::stringstream stream; stream @@ -89,7 +91,9 @@ BoostPredicate IncludeWrapper::checkStatus( IncludeStatus _exceptStatus ) const { const IncludeStatus status = getInclude().getStatus(); if( status == _exceptStatus ) + { return true; + } std::stringstream stream; stream @@ -109,19 +113,16 @@ BoostPredicate IncludeWrapper::checkFile( std::string_view _path ) const { - const Path filePath = _file.getPath(); + const Path & filePath = _file.getPath(); Path excpectedPath{ std::string{ _path } }; excpectedPath = toLexicallyNormal( excpectedPath ); - if( filePath == excpectedPath ) + if( filePath == excpectedPath ) + { return true; + } std::stringstream stream; - stream - << "current file: " - << filePath - << " but except :" - << excpectedPath - ; + stream << "current file: " << filePath << " but except :" << excpectedPath; return stream.str(); } @@ -138,11 +139,14 @@ const Include & IncludeWrapper::getInclude() const std::string IncludeWrapper::toString( IncludeType _type ) const { static_assert( static_cast< int >( IncludeType::Count ) == 2 ); - switch ( _type ) + switch( _type ) { - case IncludeType::User : return "user"; - case IncludeType::System : return "system"; - case IncludeType::Count : return ""; + case IncludeType::User: + return "user"; + case IncludeType::System: + return "system"; + case IncludeType::Count: + return ""; } INTERNAL_CHECK_WARRING( false ); @@ -156,9 +160,12 @@ std::string IncludeWrapper::toString( IncludeStatus _status ) const static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); switch( _status ) { - case IncludeStatus::Resolved : return "resolved"; - case IncludeStatus::Unresolved : return "unresolved"; - case IncludeStatus::Count : return ""; + case IncludeStatus::Resolved: + return "resolved"; + case IncludeStatus::Unresolved: + return "unresolved"; + case IncludeStatus::Count: + return ""; } INTERNAL_CHECK_WARRING( false ); diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp index 3d54f12..750ee51 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp @@ -23,21 +23,19 @@ namespace model_includes::test { class IncludeWrapper { public: - IncludeWrapper(); IncludeWrapper( const Include & _include ); std::string dump() const; bool isAvaliable() const; - BoostPredicate checkSource( std::string_view _path ) const; + BoostPredicate checkSource( std::string_view _path ) const; BoostPredicate checkDestination( std::string_view _path ) const; BoostPredicate checkType( IncludeType _exceptType ) const; BoostPredicate checkStatus( IncludeStatus _exceptStatus ) const; private: - using Path = stdfs::path; const Include & getInclude() const; @@ -50,7 +48,6 @@ class IncludeWrapper static Path toLexicallyNormal( const Path & _path ); private: - const Include * m_include; }; diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp index 2101d9a..c12e9d8 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp @@ -2,15 +2,15 @@ #include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" -#include "model_includes/api/mi_model.hpp" -#include "model_includes/api/mi_file.hpp" #include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_model.hpp" #include "exception/ih/exc_internal_error.hpp" #include -#include #include +#include //------------------------------------------------------------------------------ @@ -31,7 +31,7 @@ ModelWrapper::~ModelWrapper() = default; bool ModelWrapper::isAvailable() const { - return m_modelPtr.get(); + return m_modelPtr != nullptr; } //------------------------------------------------------------------------------ @@ -39,7 +39,9 @@ bool ModelWrapper::isAvailable() const BoostPredicate ModelWrapper::checkFilesCount( std::size_t _expectCount ) const { if( getModel().getFilesCount() == _expectCount ) + { return true; + } return dump(); } diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp index 927bc77..d700a88 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp @@ -23,7 +23,6 @@ namespace model_includes::test { class ModelWrapper { - public: using ModelPtr = stdfwd::unique_ptr< Model >; @@ -53,14 +52,12 @@ class ModelWrapper ); private: - const Model & getModel() const; Model & takeModel(); std::string dump() const; private: - ModelPtr m_modelPtr; }; diff --git a/src/model_includes/test/model_includes_test_main.cpp b/src/model_includes/test/model_includes_test_main.cpp index 6067164..beff5a8 100644 --- a/src/model_includes/test/model_includes_test_main.cpp +++ b/src/model_includes/test/model_includes_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE model_includes_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp index a64756f..6d0e600 100644 --- a/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp +++ b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp @@ -1,15 +1,14 @@ #include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" -#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" +#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" -#include "model_includes/api/mi_model.hpp" #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" +#include "model_includes/api/mi_model.hpp" -#include -#include +#include "test_tools/test_macros.hpp" #include @@ -34,12 +33,12 @@ TEST PLAN: namespace model_includes::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(AnalyzerforCmakeTests, ModelIncludesFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( AnalyzerforCmakeTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_1_only_one_cpp_file) +TEST_CASE( t1_1_only_one_cpp_file ) { // Init const std::string projectDir{ "/test_project/" }; @@ -55,21 +54,21 @@ BOOST_AUTO_TEST_CASE(t1_1_only_one_cpp_file) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 1 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 1 ) ); { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_CHECK( classACpp.checkIncludesCount( 0 ) ); + TEST_CHECK( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_2_cpp_file_with_header) +TEST_CASE( t1_2_cpp_file_with_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -95,43 +94,43 @@ BOOST_AUTO_TEST_CASE(t1_2_cpp_file_with_header) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_4_cpp_file_with_system_include) +TEST_CASE( t1_4_cpp_file_with_system_include ) { // Init const std::string projectDir{ "/test_project/" }; @@ -155,43 +154,43 @@ BOOST_AUTO_TEST_CASE(t1_4_cpp_file_with_system_include) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper systemHeader = model.findFile( systemHeaderName ); - BOOST_REQUIRE( systemHeader.isAvailable() ); + TEST_REQUIRE( systemHeader.isAvailable() ); { - BOOST_REQUIRE( systemHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( systemHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( systemHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( systemHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = systemHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( systemHeaderName ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::System ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( systemHeaderName ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::System ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( systemHeaderName ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::System ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( systemHeaderName ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::System ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_3_cpp_file_with_header_that_include_header) +TEST_CASE( t1_3_cpp_file_with_header_that_include_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -223,64 +222,64 @@ BOOST_AUTO_TEST_CASE(t1_3_cpp_file_with_header_that_include_header) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper classBaseHeader = model.findFile( classBaseHppPath ); - BOOST_REQUIRE( classBaseHeader.isAvailable() ); + TEST_REQUIRE( classBaseHeader.isAvailable() ); { - BOOST_REQUIRE( classBaseHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classBaseHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classBaseHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classBaseHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classBaseHeader.getIncludedBy( classAHppPath ); - BOOST_CHECK( includedByClassA.checkSource( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classBaseHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classBaseHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 1 ) ); IncludeWrapper includeToBaseClass = classAHeader.getInclude( 0 ); - BOOST_CHECK( includeToBaseClass.checkSource( classAHppPath ) ); - BOOST_CHECK( includeToBaseClass.checkDestination( classBaseHppPath ) ); - BOOST_CHECK( includeToBaseClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeToBaseClass.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeToBaseClass.checkSource( classAHppPath ) ); + TEST_CHECK( includeToBaseClass.checkDestination( classBaseHppPath ) ); + TEST_CHECK( includeToBaseClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeToBaseClass.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_several_files) +TEST_CASE( t2_1_several_files ) { // Init const std::string projectDir{ "/test_project/" }; @@ -303,29 +302,29 @@ BOOST_AUTO_TEST_CASE(t2_1_several_files) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classBCpp = model.findFile( classBCppPath ); - BOOST_REQUIRE( classBCpp.isAvailable() ); + TEST_REQUIRE( classBCpp.isAvailable() ); { - BOOST_REQUIRE( classBCpp.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classBCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classBCpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classBCpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_several_files_with_same_header) +TEST_CASE( t2_2_several_files_with_same_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -359,64 +358,64 @@ BOOST_AUTO_TEST_CASE(t2_2_several_files_with_same_header) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper classAFile = model.findFile( classACppPath ); - BOOST_REQUIRE( classAFile.isAvailable() ); + TEST_REQUIRE( classAFile.isAvailable() ); { - BOOST_REQUIRE( classAFile.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classAFile.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = classAFile.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classAFile.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classAFile.checkIncludedByCount( 0 ) ); } } { FileWrapper classBFile = model.findFile( classACppPath ); - BOOST_REQUIRE( classBFile.isAvailable() ); + TEST_REQUIRE( classBFile.isAvailable() ); { - BOOST_REQUIRE( classBFile.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classBFile.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = classBFile.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classBFile.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classBFile.checkIncludedByCount( 0 ) ); } } { FileWrapper headerFile = model.findFile( classHeaderPath ); - BOOST_REQUIRE( headerFile.isAvailable() ); + TEST_REQUIRE( headerFile.isAvailable() ); { - BOOST_REQUIRE( headerFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( headerFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( headerFile.checkIncludedByCount( 2 ) ); + TEST_REQUIRE( headerFile.checkIncludedByCount( 2 ) ); IncludeWrapper includedByClassA = headerFile.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classHeaderPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classHeaderPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassB = headerFile.getIncludedBy( classBCppPath ); - BOOST_CHECK( includedByClassB.checkSource( classBCppPath ) ); - BOOST_CHECK( includedByClassB.checkDestination( classHeaderPath ) ); - BOOST_CHECK( includedByClassB.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassB.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassB.checkSource( classBCppPath ) ); + TEST_CHECK( includedByClassB.checkDestination( classHeaderPath ) ); + TEST_CHECK( includedByClassB.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassB.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_ignore_files_ignore_destination) +TEST_CASE( t3_1_ignore_files_ignore_destination ) { // Init setProjectDir( "/test_project/" ); @@ -436,43 +435,43 @@ BOOST_AUTO_TEST_CASE(t3_1_ignore_files_ignore_destination) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - BOOST_REQUIRE( classAHpp.isAvailable() ); + TEST_REQUIRE( classAHpp.isAvailable() ); { - BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_ignore_files_ignore_source) +TEST_CASE( t3_2_ignore_files_ignore_source ) { // Init setProjectDir( "/test_project/" ); @@ -500,43 +499,43 @@ BOOST_AUTO_TEST_CASE(t3_2_ignore_files_ignore_source) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - BOOST_REQUIRE( classAHpp.isAvailable() ); + TEST_REQUIRE( classAHpp.isAvailable() ); { - BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp index ca3c12b..b355cbc 100644 --- a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp +++ b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp @@ -1,15 +1,14 @@ #include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" -#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" +#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" -#include "model_includes/api/mi_model.hpp" #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" +#include "model_includes/api/mi_model.hpp" -#include -#include +#include "test_tools/test_macros.hpp" #include @@ -47,12 +46,12 @@ TEST PLAN: namespace model_includes::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(AnalyzerTests, ModelIncludesFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( AnalyzerTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_1_file_in_current_directory) +TEST_CASE( t1_1_file_in_current_directory ) { // Init const std::string projectDir{ "/test_project/" }; @@ -63,11 +62,11 @@ BOOST_AUTO_TEST_CASE(t1_1_file_in_current_directory) const std::string classAHppPath{ projectDir + classAHppName }; const std::string classACppPath{ projectDir + classACppName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); addFileToProject( classAHppName, "class A{ A(); };" ); addFileToProject( @@ -80,64 +79,64 @@ BOOST_AUTO_TEST_CASE(t1_1_file_in_current_directory) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_2_file_in_include_directory) +TEST_CASE( t1_2_file_in_include_directory ) { // Init const std::string projectDir{ "/test_project/" }; @@ -150,12 +149,12 @@ BOOST_AUTO_TEST_CASE(t1_2_file_in_include_directory) const std::string classAHppPath{ includeDir + classAHppName }; const std::string classACppPath{ includeDir + classACppName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); addIncludePath( includeDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); addFile( classAHppPath, "class A{ A(); };" ); addFile( @@ -168,43 +167,43 @@ BOOST_AUTO_TEST_CASE(t1_2_file_in_include_directory) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_3_file_with_std_library_name_in_project) +TEST_CASE( t1_3_file_with_std_library_name_in_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -215,11 +214,11 @@ BOOST_AUTO_TEST_CASE(t1_3_file_with_std_library_name_in_project) const std::string classAHppPath{ projectDir + classLimitHppName }; const std::string classACppPath{ projectDir + classLimitCppName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include \"" + classLimitHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classLimitHppName + "\"" ); addFileToProject( classLimitHppName, "class A{ A(); };" ); addFileToProject( @@ -232,64 +231,64 @@ BOOST_AUTO_TEST_CASE(t1_3_file_with_std_library_name_in_project) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_4_include_in_local_folder) +TEST_CASE( t1_4_include_in_local_folder ) { // Init const std::string projectDir{ "/test_project/" }; @@ -316,42 +315,41 @@ BOOST_AUTO_TEST_CASE(t1_4_include_in_local_folder) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper file = model.findFile( classIncludeHppPath ); - BOOST_REQUIRE( file.isAvailable() ); + TEST_REQUIRE( file.isAvailable() ); { - BOOST_REQUIRE( file.checkIncludesCount( 0 ) ); + TEST_REQUIRE( file.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( file.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( file.checkIncludedByCount( 1 ) ); IncludeWrapper include = file.getIncludedBy( classIncludeCppPath ); - BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); - BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); - BOOST_CHECK( include.checkType( IncludeType::User ) ); - BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( include.checkSource( classIncludeCppPath ) ); + TEST_CHECK( include.checkDestination( classIncludeHppPath ) ); + TEST_CHECK( include.checkType( IncludeType::User ) ); + TEST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper file = model.findFile( classIncludeCppPath ); - BOOST_REQUIRE( file.isAvailable() ); + TEST_REQUIRE( file.isAvailable() ); { - BOOST_REQUIRE( file.checkIncludesCount( 1 ) ); + TEST_REQUIRE( file.checkIncludesCount( 1 ) ); IncludeWrapper include = file.getInclude( 0 ); - BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); - BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); - BOOST_CHECK( include.checkType( IncludeType::User ) ); - BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); - - BOOST_REQUIRE( file.checkIncludedByCount( 0 ) ); + TEST_CHECK( include.checkSource( classIncludeCppPath ) ); + TEST_CHECK( include.checkDestination( classIncludeHppPath ) ); + TEST_CHECK( include.checkType( IncludeType::User ) ); + TEST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + TEST_REQUIRE( file.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_include_type_user) +TEST_CASE( t2_1_include_type_user ) { // Init const std::string projectDir{ "/test_project/" }; @@ -360,53 +358,53 @@ BOOST_AUTO_TEST_CASE(t2_1_include_type_user) const std::string mainCppName{ "main.cpp" }; const std::string classAHppPath{ projectDir + classAHppName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); addFile( classAHppPath, "class A{ A(){} };" ); // Run ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_include_type_system) +TEST_CASE( t2_2_include_type_system ) { // Init const std::string projectDir{ "/test_project/" }; @@ -414,7 +412,7 @@ BOOST_AUTO_TEST_CASE(t2_2_include_type_system) const std::string systemName{ "iostream" }; const std::string mainCppName{ "main.cpp" }; - const std::string systemPath{ systemName }; + const std::string & systemPath{ systemName }; const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); @@ -424,43 +422,43 @@ BOOST_AUTO_TEST_CASE(t2_2_include_type_system) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToSystem = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); - BOOST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); - BOOST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); + TEST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); + TEST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper systemFile = model.findFile( systemPath ); - BOOST_REQUIRE( systemFile.isAvailable() ); + TEST_REQUIRE( systemFile.isAvailable() ); { - BOOST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = systemFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( systemPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( systemPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_3_include_type_mix) +TEST_CASE( t2_3_include_type_mix ) { // Init const std::string projectDir{ "/test_project/" }; @@ -469,7 +467,7 @@ BOOST_AUTO_TEST_CASE(t2_3_include_type_mix) const std::string userHeaderName{ "class_a.hpp" }; const std::string mainCppName{ "main.cpp" }; - const std::string systemPath{ systemName }; + const std::string & systemPath{ systemName }; const std::string userHeaderPath{ projectDir + userHeaderName }; const std::string mainCppPath{ projectDir + mainCppName }; @@ -483,64 +481,64 @@ BOOST_AUTO_TEST_CASE(t2_3_include_type_mix) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); IncludeWrapper includeMainToSystem = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); - BOOST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); - BOOST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); + TEST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); + TEST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 1 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper systemFile = model.findFile( systemPath ); - BOOST_REQUIRE( systemFile.isAvailable() ); + TEST_REQUIRE( systemFile.isAvailable() ); { - BOOST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = systemFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( systemPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( systemPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper userFile = model.findFile( userHeaderName ); - BOOST_REQUIRE( userFile.isAvailable() ); + TEST_REQUIRE( userFile.isAvailable() ); { - BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( userHeaderName ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( userHeaderName ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_include_status_resolved) +TEST_CASE( t3_1_include_status_resolved ) { // Init const std::string projectDir{ "/test_project/" }; @@ -559,42 +557,42 @@ BOOST_AUTO_TEST_CASE(t3_1_include_status_resolved) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( userHeaderPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( userHeaderPath ); - BOOST_REQUIRE( userFile.isAvailable() ); + TEST_REQUIRE( userFile.isAvailable() ); { - BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( userHeaderPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( userHeaderPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_include_status_unresolved) +TEST_CASE( t3_2_include_status_unresolved ) { // Init const std::string projectDir{ "/test_project/" }; @@ -611,43 +609,42 @@ BOOST_AUTO_TEST_CASE(t3_2_include_status_unresolved) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( userHeaderName ); - BOOST_REQUIRE( userFile.isAvailable() ); + TEST_REQUIRE( userFile.isAvailable() ); { - BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( userHeaderName ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( userHeaderName ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_include_status_mix) +TEST_CASE( t3_3_include_status_mix ) { // Init const std::string projectDir{ "/test_project/" }; @@ -656,7 +653,7 @@ BOOST_AUTO_TEST_CASE(t3_3_include_status_mix) const std::string classBHeaderName{ "class_b.hpp" }; const std::string mainCppName{ "main.cpp" }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; const std::string classAHeaderPath{ projectDir + classAHeaderName }; const std::string classBHeaderPath{ projectDir + classBHeaderName }; @@ -672,62 +669,62 @@ BOOST_AUTO_TEST_CASE(t3_3_include_status_mix) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 3 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHeaderPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHeaderPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includeMainToClassB = mainCpp.getInclude( 1 ); - BOOST_CHECK( includeMainToClassB.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassB.checkDestination( classBHeaderName ) ); - BOOST_CHECK( includeMainToClassB.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassB.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClassB.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassB.checkDestination( classBHeaderName ) ); + TEST_CHECK( includeMainToClassB.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassB.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHeaderPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHeaderPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHeaderPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classBHeader = model.findFile( classBHeaderName ); - BOOST_REQUIRE( classBHeader.isAvailable() ); + TEST_REQUIRE( classBHeader.isAvailable() ); { - BOOST_REQUIRE( classBHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classBHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classBHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classBHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classBHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classBHeaderName ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classBHeaderName ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_4_include_status_std_lib) +TEST_CASE( t3_4_include_status_std_lib ) { // Init const std::string projectDir{ "/test_project/" }; @@ -738,49 +735,48 @@ BOOST_AUTO_TEST_CASE(t3_4_include_status_std_lib) const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include <" + headerName +">" ); + addFileToProject( mainCppName, "#include <" + headerName + ">" ); // Run ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( headerName ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::System ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( headerName ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::System ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( headerName ); - BOOST_REQUIRE( userFile.isAvailable() ); + TEST_REQUIRE( userFile.isAvailable() ); { - BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( headerName ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( headerName ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_ignored_folders_regular_project) +TEST_CASE( t4_1_ignored_folders_regular_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -801,7 +797,7 @@ BOOST_AUTO_TEST_CASE(t4_1_ignored_folders_regular_project) setProjectDir( projectDir ); addIgnoredDir( ignoredDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); addFile( classAHppPath, "class A{ A(){} };" ); addFile( classIgnoreHppPath, "class I{ I(); };" ); addFile( classIgnoreCppPath, @@ -813,42 +809,42 @@ BOOST_AUTO_TEST_CASE(t4_1_ignored_folders_regular_project) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_2_ignored_folders_cmake_project) +TEST_CASE( t4_2_ignored_folders_cmake_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -869,7 +865,7 @@ BOOST_AUTO_TEST_CASE(t4_2_ignored_folders_cmake_project) setProjectDir( projectDir ); addIgnoredDir( ignoredDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName +"\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); addFile( classAHppPath, "class A{ A(){} };" ); addFile( classIgnoreHppPath, "class I{ I(); };" ); addFile( classIgnoreCppPath, @@ -884,42 +880,42 @@ BOOST_AUTO_TEST_CASE(t4_2_ignored_folders_cmake_project) ModelWrapper model = analyzeCmake(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_ignore_system_includes) +TEST_CASE( t5_ignore_system_includes ) { // Init const std::string projectDir{ "/test_project/" }; @@ -928,7 +924,6 @@ BOOST_AUTO_TEST_CASE(t5_ignore_system_includes) const std::string classA{ "classA.hpp" }; const std::string mainCppName{ "main.cpp" }; - const std::string systemPath{ systemName }; const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); @@ -945,28 +940,28 @@ BOOST_AUTO_TEST_CASE(t5_ignore_system_includes) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClass.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClass.checkDestination( classA ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClass.checkDestination( classA ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_1_ignore_files_ignore_destination) +TEST_CASE( t6_1_ignore_files_ignore_destination ) { // Init setProjectDir( "/test_project/" ); @@ -984,43 +979,43 @@ BOOST_AUTO_TEST_CASE(t6_1_ignore_files_ignore_destination) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - BOOST_REQUIRE( classAHpp.isAvailable() ); + TEST_REQUIRE( classAHpp.isAvailable() ); { - BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_2_ignore_files_ignore_source) +TEST_CASE( t6_2_ignore_files_ignore_source ) { // Init setProjectDir( "/test_project/" ); @@ -1045,43 +1040,43 @@ BOOST_AUTO_TEST_CASE(t6_2_ignore_files_ignore_source) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 2 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - BOOST_REQUIRE( classAHpp.isAvailable() ); + TEST_REQUIRE( classAHpp.isAvailable() ); { - BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_1_file_extensions_only_cpp_files) +TEST_CASE( t7_1_file_extensions_only_cpp_files ) { // Init const std::string projectDir{ "/test_project/" }; @@ -1095,12 +1090,12 @@ BOOST_AUTO_TEST_CASE(t7_1_file_extensions_only_cpp_files) const std::string classAHppPath{ projectDir + classAHppName }; const std::string classACppPath{ projectDir + classACppName }; const std::string cppHeaderPath{ projectDir + cppHeaderName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); - addFileToProject( cppHeaderName, "#include \"" + classAHppName + "\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); + addFileToProject( cppHeaderName, "#include \"" + classAHppName + "\"" ); addFileToProject( notCppHeaderName, "#include \"" + classAHppName + "\"" ); addFileToProject( classAHppName, "class A{ A(); };" ); @@ -1116,79 +1111,79 @@ BOOST_AUTO_TEST_CASE(t7_1_file_extensions_only_cpp_files) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 4 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 4 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper cppheaderFile = model.findFile( cppHeaderPath ); - BOOST_REQUIRE( cppheaderFile.isAvailable() ); + TEST_REQUIRE( cppheaderFile.isAvailable() ); { - BOOST_REQUIRE( cppheaderFile.checkIncludesCount( 1 ) ); + TEST_REQUIRE( cppheaderFile.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = cppheaderFile.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( cppHeaderPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( cppHeaderPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( cppheaderFile.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( cppheaderFile.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_2_file_extensions_analyze_without_extension) +TEST_CASE( t7_2_file_extensions_analyze_without_extension ) { // Init const std::string projectDir{ "/test_project/" }; @@ -1198,15 +1193,15 @@ BOOST_AUTO_TEST_CASE(t7_2_file_extensions_analyze_without_extension) const std::string headerName{ "header" }; const std::string mainCppName{ "main.cpp" }; - const std::string classAHppPath{ projectDir + classAHppName }; - const std::string classACppPath{ projectDir + classACppName }; - const std::string headerPath{ projectDir + headerName }; - const std::string mainCppPath{ projectDir + mainCppName }; + const std::string classAHppPath{ projectDir + classAHppName }; + const std::string classACppPath{ projectDir + classACppName }; + const std::string headerPath{ projectDir + headerName }; + const std::string mainCppPath{ projectDir + mainCppName }; setProjectDir( projectDir ); - addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); - addFileToProject( headerName, "#include \"" + classAHppName + "\"" ); + addFileToProject( mainCppName, "#include \"" + classAHppName + "\"" ); + addFileToProject( headerName, "#include \"" + classAHppName + "\"" ); addFileToProject( classAHppName, "class A{ A(); };" ); addFileToProject( @@ -1222,79 +1217,79 @@ BOOST_AUTO_TEST_CASE(t7_2_file_extensions_analyze_without_extension) ModelWrapper model = analyze(); // Check - BOOST_REQUIRE( model.isAvailable() ); - BOOST_REQUIRE( model.checkFilesCount( 4 ) ); + TEST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.checkFilesCount( 4 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - BOOST_REQUIRE( mainCpp.isAvailable() ); + TEST_REQUIRE( mainCpp.isAvailable() ); { - BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - BOOST_REQUIRE( classAHeader.isAvailable() ); + TEST_REQUIRE( classAHeader.isAvailable() ); { - BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - BOOST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); + TEST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); - BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); + TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); + TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); - BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); + TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - BOOST_REQUIRE( classACpp.isAvailable() ); + TEST_REQUIRE( classACpp.isAvailable() ); { - BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper headerFile = model.findFile( headerPath ); - BOOST_REQUIRE( headerFile.isAvailable() ); + TEST_REQUIRE( headerFile.isAvailable() ); { - BOOST_REQUIRE( headerFile.checkIncludesCount( 1 ) ); + TEST_REQUIRE( headerFile.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = headerFile.getInclude( 0 ); - BOOST_CHECK( includeClassAToHeader.checkSource( headerPath ) ); - BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + TEST_CHECK( includeClassAToHeader.checkSource( headerPath ) ); + TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - BOOST_REQUIRE( headerFile.checkIncludedByCount( 0 ) ); + TEST_REQUIRE( headerFile.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_model_includes_suits.cpp b/src/model_includes/test/suits/mi_test_model_includes_suits.cpp index 3f0f08e..cb293d8 100644 --- a/src/model_includes/test/suits/mi_test_model_includes_suits.cpp +++ b/src/model_includes/test/suits/mi_test_model_includes_suits.cpp @@ -1,9 +1,9 @@ #include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" -#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" +#include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -18,81 +18,79 @@ TEST PLAN: namespace model_includes::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(ModelIncludesTests, ModelIncludesFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ModelIncludesTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_1_file_includes_count_recursive) +TEST_CASE( t1_1_file_includes_count_recursive ) { // Init const std::string baseFile = "/test_project/base.hpp"; - const std::string classAFile = "/test_project/classA.hpp"; - const std::string classBFile = "/test_project/classB.hpp"; - - const std::string mainFile = "/test_project/main.cpp"; + const std::string classAFile = "/test_project/classA.hpp"; + const std::string classBFile = "/test_project/classB.hpp"; + const std::string mainFile = "/test_project/main.cpp"; // Run auto model = createModel(); - BOOST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.isAvailable() ); model.addInclude( classAFile, baseFile ); model.addInclude( classBFile, baseFile ); - model.addInclude( mainFile, classAFile ); - model.addInclude( mainFile, classBFile ); + model.addInclude( mainFile, classAFile ); + model.addInclude( mainFile, classBFile ); // Check auto file = model.findFile( mainFile ); - BOOST_REQUIRE( file.isAvailable() ); + TEST_REQUIRE( file.isAvailable() ); - BOOST_CHECK( file.checkIncludesCountRecursive( 3 ) ); + TEST_CHECK( file.checkIncludesCountRecursive( 3 ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_2_file_includes_by_count_recursive) +TEST_CASE( t1_2_file_includes_by_count_recursive ) { // Init const std::string baseFile = "/test_project/base.hpp"; - const std::string classAFile = "/test_project/classA.hpp"; - const std::string runA1File = "/test_project/runA1.hpp"; - - const std::string classBFile = "/test_project/classB.hpp"; - const std::string runB1File = "/test_project/runB1.hpp"; - const std::string runB2File = "/test_project/runB2.hpp"; + const std::string classAFile = "/test_project/classA.hpp"; + const std::string runA1File = "/test_project/runA1.hpp"; + const std::string classBFile = "/test_project/classB.hpp"; + const std::string runB1File = "/test_project/runB1.hpp"; + const std::string runB2File = "/test_project/runB2.hpp"; - const std::string mainFile = "/test_project/main.cpp"; + const std::string mainFile = "/test_project/main.cpp"; // Run auto model = createModel(); - BOOST_REQUIRE( model.isAvailable() ); + TEST_REQUIRE( model.isAvailable() ); model.addInclude( classAFile, baseFile ); - model.addInclude( runA1File, classAFile ); + model.addInclude( runA1File, classAFile ); model.addInclude( classBFile, baseFile ); - model.addInclude( runB1File, classBFile ); - model.addInclude( runB2File, classBFile ); + model.addInclude( runB1File, classBFile ); + model.addInclude( runB2File, classBFile ); - model.addInclude( mainFile, classAFile ); - model.addInclude( mainFile, classBFile ); + model.addInclude( mainFile, classAFile ); + model.addInclude( mainFile, classBFile ); // Check auto file = model.findFile( baseFile ); - BOOST_REQUIRE( file.isAvailable() ); + TEST_REQUIRE( file.isAvailable() ); - BOOST_CHECK( file.checkIncludedByCountRecursive( 6 ) ); + TEST_CHECK( file.checkIncludedByCountRecursive( 6 ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp b/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp index 5ef2421..7dd6251 100644 --- a/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp +++ b/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp @@ -2,7 +2,7 @@ #include "model_includes/api/enums/mi_file_type.hpp" -#include +#include "test_tools/test_macros.hpp" #include @@ -19,12 +19,12 @@ TEST PLAN: namespace model_includes::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(ResolverFileTypeTests, ModelIncludesFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ResolverFileTypeTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_project_file) +TEST_CASE( t1_project_file ) { // Init setProjectDir( "/test_project/" ); @@ -34,13 +34,12 @@ BOOST_AUTO_TEST_CASE(t1_project_file) const FileType fileType = resolveFileType( "/test_project/main.cpp" ); // Check - BOOST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); - + TEST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_std_library_file) +TEST_CASE( t2_std_library_file ) { // Init setProjectDir( "/test_project/" ); @@ -50,13 +49,12 @@ BOOST_AUTO_TEST_CASE(t2_std_library_file) const FileType fileType = resolveFileType( "iostream" ); // Check - BOOST_CHECK( checkFileType( fileType, FileType::StdLibraryFile ) ); - + TEST_CHECK( checkFileType( fileType, FileType::StdLibraryFile ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_project_file_with_std_library_name) +TEST_CASE( t3_project_file_with_std_library_name ) { // Init setProjectDir( "/test_project/" ); @@ -66,13 +64,12 @@ BOOST_AUTO_TEST_CASE(t3_project_file_with_std_library_name) const FileType fileType = resolveFileType( "/test_project/limit.h" ); // Check - BOOST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); - + TEST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp index 58d2cb2..de8b9ff 100644 --- a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp +++ b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp @@ -1,9 +1,9 @@ #include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" -#include #include +#include /*------------------------------------------------------------------------------ @@ -26,15 +26,15 @@ TEST PLAN: ------------------------------------------------------------------------------*/ -namespace model_includes::test { - +namespace model_includes::test +{ //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(ResolverPathTests, ModelIncludesFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ResolverPathTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_current_directory) +TEST_CASE( t1_current_directory ) { // Init setProjectDir( "/test_project/" ); @@ -45,15 +45,15 @@ BOOST_AUTO_TEST_CASE(t1_current_directory) PathOpt resolvedPath = resolvePath( "/test_project/main.cpp", "include.hpp" ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/include.hpp" }; - BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); + TEST_CHECK_EQUAL( *resolvedPath, exceptedPath ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_subdirectory) +TEST_CASE( t2_subdirectory ) { // Init setProjectDir( "/test_project/" ); @@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(t2_subdirectory) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/sub_dir/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -75,7 +75,7 @@ BOOST_AUTO_TEST_CASE(t2_subdirectory) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_in_include_dir) +TEST_CASE( t3_1_in_include_dir ) { // Init setProjectDir( "/test_project/" ); @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(t3_1_in_include_dir) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(t3_1_in_include_dir) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_in_include_subdir) +TEST_CASE( t3_2_in_include_subdir ) { // Init setProjectDir( "/test_project/" ); @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(t3_2_in_include_subdir) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/sub/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -123,7 +123,7 @@ BOOST_AUTO_TEST_CASE(t3_2_in_include_subdir) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_in_include_out_of_project) +TEST_CASE( t3_3_in_include_out_of_project ) { // Init setProjectDir( "/test_project/" ); @@ -139,7 +139,7 @@ BOOST_AUTO_TEST_CASE(t3_3_in_include_out_of_project) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -147,7 +147,7 @@ BOOST_AUTO_TEST_CASE(t3_3_in_include_out_of_project) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_not_found) +TEST_CASE( t4_not_found ) { // Init setProjectDir( "/test_project/" ); @@ -160,12 +160,12 @@ BOOST_AUTO_TEST_CASE(t4_not_found) ); // Check - BOOST_REQUIRE( !resolvedPath.has_value() ); + TEST_REQUIRE( !resolvedPath.has_value() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_cmake_project_one_file_in_include_dir) +TEST_CASE( t5_1_cmake_project_one_file_in_include_dir ) { // Init setProjectDir( "/test_project/" ); @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(t5_1_cmake_project_one_file_in_include_dir) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -189,7 +189,7 @@ BOOST_AUTO_TEST_CASE(t5_1_cmake_project_one_file_in_include_dir) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_cmake_project_two_files_in_different_include_dirs) +TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) { // Init setProjectDir( "/test_project/" ); @@ -209,20 +209,19 @@ BOOST_AUTO_TEST_CASE(t5_2_cmake_project_two_files_in_different_include_dirs) "include.hpp" ); - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib1/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); } { - // Check PathOpt resolvedPath = resolvePath( "/test_project/file2.cpp", "include.hpp" ); - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib2/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -231,7 +230,7 @@ BOOST_AUTO_TEST_CASE(t5_2_cmake_project_two_files_in_different_include_dirs) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_3_cmake_project_not_found) +TEST_CASE( t5_3_cmake_project_not_found ) { // Init setProjectDir( "/test_project/" ); @@ -247,12 +246,12 @@ BOOST_AUTO_TEST_CASE(t5_3_cmake_project_not_found) ); // Check - BOOST_REQUIRE( !resolvedPath.has_value() ); + TEST_REQUIRE( !resolvedPath.has_value() ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_4_cmake_project_mix_with_general_project) +TEST_CASE( t5_4_cmake_project_mix_with_general_project ) { // Init setProjectDir( "/test_project/" ); @@ -274,8 +273,8 @@ BOOST_AUTO_TEST_CASE(t5_4_cmake_project_mix_with_general_project) ); // Check - BOOST_REQUIRE( resolvedPath1.has_value() ); - BOOST_REQUIRE( resolvedPath2.has_value() ); + TEST_REQUIRE( resolvedPath1.has_value() ); + TEST_REQUIRE( resolvedPath2.has_value() ); const Path exceptedPath1{ "/test_project/lib1/include1.hpp" }; const Path exceptedPath2{ "/test_project/lib2/include2.hpp" }; @@ -286,7 +285,7 @@ BOOST_AUTO_TEST_CASE(t5_4_cmake_project_mix_with_general_project) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_5_cmake_header_include_file_from_cmake_include) +TEST_CASE( t5_5_cmake_header_include_file_from_cmake_include ) { // Init setProjectDir( "/test_project/" ); @@ -304,7 +303,7 @@ BOOST_AUTO_TEST_CASE(t5_5_cmake_header_include_file_from_cmake_include) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -312,7 +311,7 @@ BOOST_AUTO_TEST_CASE(t5_5_cmake_header_include_file_from_cmake_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_6_cmake_header_include_file_from_project_include) +TEST_CASE( t5_6_cmake_header_include_file_from_project_include ) { // Init setProjectDir( "/test_project/" ); @@ -332,7 +331,7 @@ BOOST_AUTO_TEST_CASE(t5_6_cmake_header_include_file_from_project_include) ); // Check - BOOST_REQUIRE( resolvedPath.has_value() ); + TEST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -340,7 +339,7 @@ BOOST_AUTO_TEST_CASE(t5_6_cmake_header_include_file_from_project_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/parser/api/pr_include_file.hpp b/src/parser/api/pr_include_file.hpp index a161761..221d611 100644 --- a/src/parser/api/pr_include_file.hpp +++ b/src/parser/api/pr_include_file.hpp @@ -13,7 +13,6 @@ namespace parser { class IncludeFile { public: - IncludeFile( const IncludeFileLocation & _location, std::string_view _name, @@ -23,14 +22,23 @@ class IncludeFile , m_name{ _name } , m_isSystem{ _isSystem } - {} - - const IncludeFileLocation & getLocation() const { return m_location; } - std::string_view getName() const { return m_name; } - bool isSystem() const { return m_isSystem; } + { + } + + const IncludeFileLocation & getLocation() const + { + return m_location; + } + std::string_view getName() const + { + return m_name; + } + bool isSystem() const + { + return m_isSystem; + } private: - const IncludeFileLocation m_location; const std::string m_name; const bool m_isSystem; diff --git a/src/parser/api/pr_include_file_location.hpp b/src/parser/api/pr_include_file_location.hpp index 200cd03..819f449 100644 --- a/src/parser/api/pr_include_file_location.hpp +++ b/src/parser/api/pr_include_file_location.hpp @@ -17,15 +17,22 @@ class IncludeFileLocation , m_begin{ _begin } , m_end{ _end } { - } - std::size_t getLineNumber() const { return m_line; } - std::size_t getBegin() const { return m_begin; } - std::size_t getEnd() const { return m_end; } + std::size_t getLineNumber() const + { + return m_line; + } + std::size_t getBegin() const + { + return m_begin; + } + std::size_t getEnd() const + { + return m_end; + } private: - const std::size_t m_line; const std::size_t m_begin; const std::size_t m_end; diff --git a/src/parser/api/pr_parser.hpp b/src/parser/api/pr_parser.hpp index f2e0aba..317c784 100644 --- a/src/parser/api/pr_parser.hpp +++ b/src/parser/api/pr_parser.hpp @@ -18,7 +18,6 @@ namespace parser { class Parser { public: - virtual ~Parser() = default; using IncludeFiles = stdfwd::vector< IncludeFile >; diff --git a/src/parser/ih/pr_accessor.hpp b/src/parser/ih/pr_accessor.hpp index 735fb35..e70275e 100644 --- a/src/parser/ih/pr_accessor.hpp +++ b/src/parser/ih/pr_accessor.hpp @@ -12,7 +12,6 @@ namespace parser { class ParserAccessor { public: - virtual ~ParserAccessor() = default; using ParserPtr = stdfwd::unique_ptr< Parser >; diff --git a/src/parser/ih/pr_accessor_impl.hpp b/src/parser/ih/pr_accessor_impl.hpp index 73d702c..3f0e73f 100644 --- a/src/parser/ih/pr_accessor_impl.hpp +++ b/src/parser/ih/pr_accessor_impl.hpp @@ -12,7 +12,6 @@ namespace parser { class ParserAccessorImpl final : public ParserAccessor { public: - ParserPtr createParser() override; }; diff --git a/src/parser/impl/pr_parser_context.cpp b/src/parser/impl/pr_parser_context.cpp index f44edef..9332d92 100644 --- a/src/parser/impl/pr_parser_context.cpp +++ b/src/parser/impl/pr_parser_context.cpp @@ -7,12 +7,11 @@ namespace parser { //------------------------------------------------------------------------------ ParserContext::ParserContext() - : m_lineNumber{1} + : m_lineNumber{ 1 } , m_isEnableMultilineComment{ false } , m_isEnableMultilineString{ false } , m_isEnableRawString{ false } { - } //------------------------------------------------------------------------------ diff --git a/src/parser/impl/pr_parser_context.hpp b/src/parser/impl/pr_parser_context.hpp index 55ed87b..69ce6fe 100644 --- a/src/parser/impl/pr_parser_context.hpp +++ b/src/parser/impl/pr_parser_context.hpp @@ -10,9 +10,7 @@ namespace parser { class ParserContext { - public: - ParserContext(); const std::string & getCurrentLine() const noexcept; @@ -31,14 +29,12 @@ class ParserContext void seEnableRawString( bool _enable ) noexcept; private: - std::string m_currentLine; std::size_t m_lineNumber; bool m_isEnableMultilineComment; bool m_isEnableMultilineString; bool m_isEnableRawString; - }; //------------------------------------------------------------------------------ diff --git a/src/parser/impl/pr_parser_impl.cpp b/src/parser/impl/pr_parser_impl.cpp index 2ed886c..6a98a96 100644 --- a/src/parser/impl/pr_parser_impl.cpp +++ b/src/parser/impl/pr_parser_impl.cpp @@ -5,11 +5,11 @@ #include "fs/api/fs_file.hpp" +#include +#include #include -#include #include -#include -#include +#include //------------------------------------------------------------------------------ @@ -41,39 +41,56 @@ Parser::IncludeFiles ParserImpl::parseFile( const fs::File & _file ) const ParserImpl::IncludeFileOpt ParserImpl::parseLine( ParserContext & _context ) { - constexpr size_t minimumSize = std::string_view{"/*"}.size() - 1; + constexpr size_t minimumSize = std::string_view{ "/*" }.size() - 1; IncludeFileOpt resutl; const std::string & line = _context.getCurrentLine(); const size_t size = line.size(); if( size <= minimumSize ) + { return resutl; + } - size_t startPos = getStartPos( _context ); + const size_t startPos = getStartPos( _context ); for( size_t i = startPos; i < size; ++i ) { const char currentChar = line[i]; switch( currentChar ) { - case '/' : - i = findComentEnd( _context, i); + case '/': + { + i = findComentEnd( _context, i ); break; + } case '"': + { i = findEndOfString( _context, i ); break; + } case 'R': + { i = findEndOfRawString( _context, i ); break; + } - case '#' : - if( auto indexOpt = findInclude( line, i ); indexOpt ) - return parseInclude( _context, *indexOpt ); - else // if found # and it's not include it doesn't need analyze + case '#': + { + if( auto indexOpt = findInclude( line, i ); indexOpt ) + { + return parseInclude( _context, *indexOpt ); + } + + // if found # and it's not include it doesn't need analyze return resutl; + + break; + } + default: + break; } } @@ -87,36 +104,94 @@ std::size_t ParserImpl::getStartPos( ParserContext & _context ) noexcept const std::size_t index = 0; if( _context.isEnableMultilineComment() ) + { return findComentEnd( _context, index ); + } if( _context.isEnableMultilineString() ) + { return findEndOfString( _context, index ); + } if( _context.isEnableRawString() ) + { return findEndOfRawString( _context, index ); + } return 0; } //------------------------------------------------------------------------------ +std::size_t ParserImpl::getStartPosInInclude( + const ParserContext & _conext, + std::size_t _index, + char _char +) +{ + const std::string & line = _conext.getCurrentLine(); + const std::size_t count = line.size(); + for( std::size_t i = _index; i < count; ++i ) + { + const char currentChar = line[i]; + if( currentChar == _char ) + { + return i; + } + + if( currentChar == '/' ) + { + const std::size_t nextPos = i + 1; + if( nextPos >= count ) + { + continue; + } + + const char nextChar = line[nextPos]; + if( nextChar == '/' ) + { + return std::string::npos; + } + + if( nextChar == '*' ) + { + const auto endPos = line.find( "*/", nextPos ); + if( endPos == std::string::npos ) + { + return std::string::npos; + } + i = endPos + 1; + } + } + } + return std::string::npos; +} + +//------------------------------------------------------------------------------ + std::size_t ParserImpl::findComentEnd( ParserContext & _context, std::size_t _index ) noexcept { const size_t nextIndex = _context.isEnableMultilineComment() ? 0 : _index + 1; const std::string & line = _context.getCurrentLine(); const size_t size = line.size(); if( nextIndex >= size ) + { return size; + } - const char nextChar = line[ nextIndex ]; + const char nextChar = line[nextIndex]; if( !_context.isEnableMultilineComment() ) { if( nextChar == '/' ) + { return size; + } if( nextChar != '*' ) + { return _index; + } assert( nextChar == '*' ); } @@ -136,15 +211,15 @@ std::size_t ParserImpl::findEndOfString( { const std::string & line = _context.getCurrentLine(); const size_t size = line.size(); - for( size_t i = _index + 1 ; i < size ; ++i ) + for( size_t i = _index + 1; i < size; ++i ) { const char currentChar = line[i]; - switch ( currentChar ) + switch( currentChar ) { case '\"': { _context.setMultilineString( false ); - return i; + return i; } case '\\': @@ -154,15 +229,18 @@ std::size_t ParserImpl::findEndOfString( _context.setMultilineString( true ); return size; } - else + + const size_t nextPost = i + 1; + assert( nextPost < size ); + if( nextPost < size && line[nextPost] == '\"' ) { - const size_t nextPost = i + 1; - assert( nextPost < size ); - if( nextPost < size && line[ nextPost ] == '\"' ) - i = nextPost; + i = nextPost; } - } + break; + } + default: + break; } } @@ -185,11 +263,9 @@ std::size_t ParserImpl::findEndOfRawString( { return _index; } - else - { - _index += 3; - _context.seEnableRawString( true ); - } + + _index += 3; + _context.seEnableRawString( true ); } const auto pos = line.find( ")\"", _index ); @@ -200,7 +276,6 @@ std::size_t ParserImpl::findEndOfRawString( } return line.size(); - } //------------------------------------------------------------------------------ @@ -219,11 +294,13 @@ std::optional< std::size_t > ParserImpl::findInclude( for( size_t i = _index + 1; i < size; ++i ) { - const char currentChar = _line[ i ]; + const char currentChar = _line[i]; if( currentChar == ' ' || currentChar == '\t' ) { if( isStartedCheckPhase ) + { return std::nullopt; + } } else { @@ -233,7 +310,9 @@ std::optional< std::size_t > ParserImpl::findInclude( { ++indexPhase; if( indexPhase >= includePhaseSize ) + { return i; + } } else { @@ -253,8 +332,8 @@ ParserImpl::IncludeFileOpt ParserImpl::parseInclude( ) { const std::string & line = _context.getCurrentLine(); - const size_t startPosSystem = line.find( '<', _index ); - const size_t startPosUser = line.find( '"', _index ); + const size_t startPosSystem = getStartPosInInclude( _context, _index, '<' ); + const size_t startPosUser = getStartPosInInclude( _context, _index, '"' ); if( startPosSystem == std::string::npos && startPosUser == std::string::npos ) { @@ -265,10 +344,9 @@ ParserImpl::IncludeFileOpt ParserImpl::parseInclude( const size_t startPos = std::min( startPosSystem, startPosUser ); const bool isSystem = - startPosSystem != std::string::npos - && startPosSystem == startPos - ; - const size_t startPosName = ( isSystem ? startPosSystem : startPosUser ) + 1; + startPosSystem != std::string::npos && startPosSystem == startPos; + const size_t startPosName = + ( isSystem ? startPosSystem : startPosUser ) + 1; const char endChar = isSystem ? '>' : '"'; @@ -286,7 +364,8 @@ ParserImpl::IncludeFileOpt ParserImpl::parseInclude( IncludeFileLocation location{ _context.getLineNumber(), - startPosName + 1, endPosName + 1 + startPosName + 1, + endPosName + 1 }; return IncludeFile{ location, name, isSystem }; } diff --git a/src/parser/impl/pr_parser_impl.hpp b/src/parser/impl/pr_parser_impl.hpp index d781e7c..2a74a45 100644 --- a/src/parser/impl/pr_parser_impl.hpp +++ b/src/parser/impl/pr_parser_impl.hpp @@ -12,13 +12,10 @@ class ParserContext; class ParserImpl final : public Parser { - public: - IncludeFiles parseFile( const fs::File & _file ) const override; private: - using IncludeFileOpt = std::optional< IncludeFile >; static IncludeFileOpt parseLine( ParserContext & _context ); @@ -28,6 +25,11 @@ class ParserImpl final : public Parser ); static std::size_t getStartPos( ParserContext & _context ) noexcept; + static std::size_t getStartPosInInclude( + const ParserContext & _conext, + std::size_t _index, + char _char + ); static std::size_t findComentEnd( ParserContext & _context, @@ -47,7 +49,6 @@ class ParserImpl final : public Parser std::size_t _index ); - }; //------------------------------------------------------------------------------ diff --git a/src/parser/test/fixtures/pr_test_file_wrapper.cpp b/src/parser/test/fixtures/pr_test_file_wrapper.cpp index bbe9abb..f5f788f 100644 --- a/src/parser/test/fixtures/pr_test_file_wrapper.cpp +++ b/src/parser/test/fixtures/pr_test_file_wrapper.cpp @@ -19,7 +19,7 @@ FileWrapper::~FileWrapper() = default; FileWrapper & FileWrapper::operator<<( std::string_view _str ) { INTERNAL_CHECK_ERROR( m_file ); - (*m_file) << _str << "\n"; + ( *m_file ) << _str << "\n"; return *this; } @@ -41,5 +41,3 @@ const fs::File & FileWrapper::getFile() const //------------------------------------------------------------------------------ } - - diff --git a/src/parser/test/fixtures/pr_test_file_wrapper.hpp b/src/parser/test/fixtures/pr_test_file_wrapper.hpp index 0c9134a..a9e13cd 100644 --- a/src/parser/test/fixtures/pr_test_file_wrapper.hpp +++ b/src/parser/test/fixtures/pr_test_file_wrapper.hpp @@ -1,7 +1,7 @@ #pragma once -#include #include +#include //------------------------------------------------------------------------------ @@ -18,7 +18,6 @@ namespace parser::test { class FileWrapper { public: - using FilePtr = std::shared_ptr< fs::File >; ~FileWrapper(); @@ -29,9 +28,7 @@ class FileWrapper const fs::File & getFile() const; private: - FilePtr m_file; - }; //------------------------------------------------------------------------------ diff --git a/src/parser/test/fixtures/pr_test_fixture.cpp b/src/parser/test/fixtures/pr_test_fixture.cpp index 7605fc3..68b5991 100644 --- a/src/parser/test/fixtures/pr_test_fixture.cpp +++ b/src/parser/test/fixtures/pr_test_fixture.cpp @@ -1,7 +1,7 @@ #include "parser/test/fixtures/pr_test_fixture.hpp" -#include "fs/impl/fs_factory_impl.hpp" #include "fs/api/fs_file_system.hpp" +#include "fs/impl/fs_factory_impl.hpp" #include "parser/api/pr_include_file.hpp" #include "parser/impl/pr_parser_impl.hpp" @@ -29,7 +29,7 @@ ParserFixture::~ParserFixture() = default; void ParserFixture::init() { - m_factory.reset( new fs::FactoryImpl ); + m_factory = std::make_unique< fs::FactoryImpl >(); INTERNAL_CHECK_ERROR( m_factory ); fs::FileSystem & fs = m_factory->getMemoryFileSystem(); diff --git a/src/parser/test/fixtures/pr_test_fixture.hpp b/src/parser/test/fixtures/pr_test_fixture.hpp index deed93d..7a30181 100644 --- a/src/parser/test/fixtures/pr_test_fixture.hpp +++ b/src/parser/test/fixtures/pr_test_fixture.hpp @@ -26,7 +26,6 @@ namespace parser::test { class ParserFixture { public: - using IncludeFiles = std::vector< IncludeFile >; ParserFixture(); @@ -39,16 +38,13 @@ class ParserFixture std::string getTempFileName() const; private: - void init(); private: - FileWrapper m_fileWrapper; std::unique_ptr< fs::Factory > m_factory; IncludeFiles m_files; - }; //------------------------------------------------------------------------------ diff --git a/src/parser/test/parser_test_main.cpp b/src/parser/test/parser_test_main.cpp index c4ff34c..7c3c0e2 100644 --- a/src/parser/test/parser_test_main.cpp +++ b/src/parser/test/parser_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE parser_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/parser/test/suits/pr_test_suits.cpp b/src/parser/test/suits/pr_test_suits.cpp index 55e59fa..c9cdcb4 100644 --- a/src/parser/test/suits/pr_test_suits.cpp +++ b/src/parser/test/suits/pr_test_suits.cpp @@ -1,9 +1,9 @@ -#include "parser/test/fixtures/pr_test_fixture.hpp" #include "parser/test/fixtures/pr_test_file_wrapper.hpp" +#include "parser/test/fixtures/pr_test_fixture.hpp" #include "parser/api/pr_include_file.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -25,23 +25,22 @@ TEST PLAN: 14. Raw string 15. Raw string with separator 16. Brackets in comments +17. File name in comments ------------------------------------------------------------------------------*/ namespace parser::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(ParserTests, ParserFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ParserTests, ParserFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_simple_system_include) +TEST_CASE( t1_simple_system_include ) { // Init - file()<< - "#include " - ; + file() << "#include "; // Run parse(); @@ -51,7 +50,7 @@ BOOST_AUTO_TEST_CASE(t1_simple_system_include) BOOST_REQUIRE_EQUAL( files.size(), 1 ); const auto & file = files.at( 0 ); - BOOST_CHECK_EQUAL( file.getName(), "iostream"); + BOOST_CHECK_EQUAL( file.getName(), "iostream" ); BOOST_CHECK_EQUAL( file.isSystem(), true ); const auto & location = file.getLocation(); @@ -62,12 +61,10 @@ BOOST_AUTO_TEST_CASE(t1_simple_system_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_simple_user_include) +TEST_CASE( t2_simple_user_include ) { // Init - file()<< - "#include \"user.hpp\"" - ; + file() << "#include \"user.hpp\""; // Run parse(); @@ -83,7 +80,7 @@ BOOST_AUTO_TEST_CASE(t2_simple_user_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_simple_user_and_system_include) +TEST_CASE( t3_simple_user_and_system_include ) { // Init file() @@ -109,12 +106,10 @@ BOOST_AUTO_TEST_CASE(t3_simple_user_and_system_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_include_without_space) +TEST_CASE( t4_include_without_space ) { // Init - file()<< - "#include" - ; + file() << "#include"; // Run parse(); @@ -130,7 +125,7 @@ BOOST_AUTO_TEST_CASE(t4_include_without_space) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_include_with_several_spaces) +TEST_CASE( t5_include_with_several_spaces ) { // Init file()<< @@ -151,12 +146,10 @@ BOOST_AUTO_TEST_CASE(t5_include_with_several_spaces) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_include_after_comment) +TEST_CASE( t6_include_after_comment ) { // Init - file()<< - " //#include " - ; + file() << " //#include "; // Run parse(); @@ -168,12 +161,10 @@ BOOST_AUTO_TEST_CASE(t6_include_after_comment) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_include_in_multiline_coment) +TEST_CASE( t7_include_in_multiline_coment ) { // Init - file()<< - "/* include */" - ; + file() << "/* include */"; // Run parse(); @@ -185,12 +176,10 @@ BOOST_AUTO_TEST_CASE(t7_include_in_multiline_coment) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_include_in_string) +TEST_CASE( t8_include_in_string ) { // Init - file()<< - "\" include \"" - ; + file() << "\" include \""; // Run parse(); @@ -202,10 +191,10 @@ BOOST_AUTO_TEST_CASE(t8_include_in_string) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t9_include_in_multiline_coment_with_several_lines) +TEST_CASE( t9_include_in_multiline_coment_with_several_lines ) { // Init - file()<< + file() << R"(/* text line #include "...". */ @@ -222,7 +211,7 @@ BOOST_AUTO_TEST_CASE(t9_include_in_multiline_coment_with_several_lines) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t10_include_after_multiline_coment_with_several_lines) +TEST_CASE( t10_include_after_multiline_coment_with_several_lines ) { // Init file()<< @@ -245,7 +234,7 @@ BOOST_AUTO_TEST_CASE(t10_include_after_multiline_coment_with_several_lines) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t11_include_include_in_multiline_string) +TEST_CASE( t11_include_include_in_multiline_string ) { // Init file()<< @@ -264,10 +253,10 @@ BOOST_AUTO_TEST_CASE(t11_include_include_in_multiline_string) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t12_first_line_new_line) +TEST_CASE( t12_first_line_new_line ) { // Init - file()<< + file() << R"( #include )" @@ -281,7 +270,7 @@ BOOST_AUTO_TEST_CASE(t12_first_line_new_line) BOOST_REQUIRE_EQUAL( files.size(), 1 ); const auto & file = files.at( 0 ); - BOOST_CHECK_EQUAL( file.getName(), "boost/test/unit_test.hpp"); + BOOST_CHECK_EQUAL( file.getName(), "boost/test/unit_test.hpp" ); BOOST_CHECK_EQUAL( file.isSystem(), true ); const auto & location = file.getLocation(); @@ -292,12 +281,10 @@ BOOST_AUTO_TEST_CASE(t12_first_line_new_line) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t13_string_with_quotation_marks) +TEST_CASE( t13_string_with_quotation_marks ) { // Init - file()<< - R"(\" \"#include ")" - ; + file() << R"(\" \"#include ")"; // Run parse(); @@ -307,10 +294,9 @@ BOOST_AUTO_TEST_CASE(t13_string_with_quotation_marks) BOOST_REQUIRE_EQUAL( files.size(), 0 ); } - //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t14_raw_string) +TEST_CASE( t14_raw_string ) { // Init file()<< @@ -330,7 +316,7 @@ BOOST_AUTO_TEST_CASE(t14_raw_string) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t15_raw_string_with_seperator) +TEST_CASE( t15_raw_string_with_seperator ) { // Init file()<< @@ -350,10 +336,10 @@ BOOST_AUTO_TEST_CASE(t15_raw_string_with_seperator) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t16_brackets_in_comments) +TEST_CASE( t16_brackets_in_comments ) { // Init - file()<< + file() << R"( #include "file.hpp" // <-> )" @@ -367,7 +353,7 @@ BOOST_AUTO_TEST_CASE(t16_brackets_in_comments) BOOST_REQUIRE_EQUAL( files.size(), 1 ); const auto & file = files.at( 0 ); - BOOST_CHECK_EQUAL( file.getName(), "file.hpp"); + BOOST_CHECK_EQUAL( file.getName(), "file.hpp" ); BOOST_CHECK_EQUAL( file.isSystem(), false ); const auto & location = file.getLocation(); @@ -378,7 +364,48 @@ BOOST_AUTO_TEST_CASE(t16_brackets_in_comments) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_CASE( t17_file_name_in_comments ) +{ + // Init + file() << + R"( + #include /**/ "filename1" + #include /*"text2"*/ + )" + ; + + // Run + parse(); + + // Check + const auto & files = getResults(); + BOOST_REQUIRE_EQUAL( files.size(), 2 ); + + { + const auto & file1 = files.at( 0 ); + BOOST_CHECK_EQUAL( file1.getName(), "filename1" ); + BOOST_CHECK_EQUAL( file1.isSystem(), false ); + + const auto & location1 = file1.getLocation(); + BOOST_CHECK_EQUAL( location1.getLineNumber(), 2 ); + BOOST_CHECK_EQUAL( location1.getBegin(), 25 ); + BOOST_CHECK_EQUAL( location1.getEnd(), 34 ); + } + { + const auto & file2 = files.at( 1 ); + BOOST_CHECK_EQUAL( file2.getName(), "filename2" ); + BOOST_CHECK_EQUAL( file2.isSystem(), true ); + + const auto & location2 = file2.getLocation(); + BOOST_CHECK_EQUAL( location2.getLineNumber(), 3 ); + BOOST_CHECK_EQUAL( location2.getBegin(), 25 ); + BOOST_CHECK_EQUAL( location2.getEnd(), 34 ); + } +} + +//------------------------------------------------------------------------------ + +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/project/api/prj_project.hpp b/src/project/api/prj_project.hpp index 527ce6d..8157149 100644 --- a/src/project/api/prj_project.hpp +++ b/src/project/api/prj_project.hpp @@ -24,7 +24,7 @@ class Project virtual ~Project() = default; virtual void setProjectDir( const Path & _path ) = 0; - virtual const Path & getProjectDir() const = 0; + virtual const Path & getProjectDir() const = 0; virtual IncludeDirIndex getIncludeDirsCount() const = 0; virtual const Path & getIncludeDir( IncludeDirIndex _index ) const = 0; diff --git a/src/project/ih/prj_project_accesso_impl.hpp b/src/project/ih/prj_project_accesso_impl.hpp index f06eeeb..ffbcbeb 100644 --- a/src/project/ih/prj_project_accesso_impl.hpp +++ b/src/project/ih/prj_project_accesso_impl.hpp @@ -11,7 +11,6 @@ namespace project { class ProjectAccessorImpl final : public ProjectAccessor { public: - ProjectAccessorImpl(); ~ProjectAccessorImpl() override; diff --git a/src/project/ih/prj_project_accessor.hpp b/src/project/ih/prj_project_accessor.hpp index a800c91..6083bf1 100644 --- a/src/project/ih/prj_project_accessor.hpp +++ b/src/project/ih/prj_project_accessor.hpp @@ -12,13 +12,11 @@ namespace project { class ProjectAccessor { public: - virtual ~ProjectAccessor() = default; using ProjectPtr = stdfwd::unique_ptr< Project >; virtual ProjectPtr createProject() = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/project/impl/exceptions/prj_base_exception_impl.hpp b/src/project/impl/exceptions/prj_base_exception_impl.hpp index 51c7161..815ef39 100644 --- a/src/project/impl/exceptions/prj_base_exception_impl.hpp +++ b/src/project/impl/exceptions/prj_base_exception_impl.hpp @@ -10,13 +10,12 @@ namespace project { //------------------------------------------------------------------------------ -template < class _BaseException > +template< class _BaseException > class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > { using BaseClass = ::exception::ExceptionImpl< _BaseException >; public: - explicit BaseExceptionImpl( std::string_view _code ) : BaseClass( resources::exceptions::ModuleName, _code ) { diff --git a/src/project/impl/exceptions/prj_exception_invalid_regex.cpp b/src/project/impl/exceptions/prj_exception_invalid_regex.cpp index eb801ba..c58fe11 100644 --- a/src/project/impl/exceptions/prj_exception_invalid_regex.cpp +++ b/src/project/impl/exceptions/prj_exception_invalid_regex.cpp @@ -9,14 +9,13 @@ namespace project { //------------------------------------------------------------------------------ InvalidRegexImpl::InvalidRegexImpl( - const std::string & _filter, + std::string _filter, const std::exception & _originException ) : BaseClass{ resources::exceptions::InvalidRegex::Code } - , m_filter{ _filter } + , m_filter{ std::move( _filter ) } , m_originMsg{ _originException.what() } { - } //------------------------------------------------------------------------------ diff --git a/src/project/impl/exceptions/prj_exception_invalid_regex.hpp b/src/project/impl/exceptions/prj_exception_invalid_regex.hpp index ab6fdb5..697244c 100644 --- a/src/project/impl/exceptions/prj_exception_invalid_regex.hpp +++ b/src/project/impl/exceptions/prj_exception_invalid_regex.hpp @@ -14,16 +14,14 @@ class InvalidRegexImpl : public BaseExceptionImpl< InvalidRegex > using BaseClass = BaseExceptionImpl< InvalidRegex >; public: - InvalidRegexImpl( - const std::string & _filter, + std::string _filter, const std::exception & _originException ); std::string getMessage() const noexcept override; private: - const std::string m_filter; const std::string m_originMsg; }; diff --git a/src/project/impl/prj_project_impl.cpp b/src/project/impl/prj_project_impl.cpp index 049e9f9..68fcb35 100644 --- a/src/project/impl/prj_project_impl.cpp +++ b/src/project/impl/prj_project_impl.cpp @@ -11,8 +11,8 @@ //------------------------------------------------------------------------------ -namespace project { - +namespace project +{ //------------------------------------------------------------------------------ ProjectImpl::ProjectImpl() @@ -61,7 +61,9 @@ void ProjectImpl::addIncludeDir( const Path & _path ) void ProjectImpl::addIncludeDirs( const DirPaths & _paths ) { for( const Path & path : _paths ) + { addIncludeDir( path ); + } } //------------------------------------------------------------------------------ @@ -76,20 +78,26 @@ bool ProjectImpl::hasIgnoreDirs() const bool ProjectImpl::isIgnoredDir( const Path & _path ) const { if( _path == getProjectDir() ) + { return false; + } Path path = convertToDirPath( _path ); const std::string dirName = path.parent_path().filename().string(); INTERNAL_CHECK_WARRING( !dirName.empty() ); if( dirName.empty() ) + { return false; + } // ignore hidden folders if( dirName.at( 0 ) == '.' ) + { return true; + } - const bool isFound = m_ignoredDirs.count( path ); + const bool isFound = m_ignoredDirs.count( path ) > 0; return isFound; } @@ -105,7 +113,9 @@ void ProjectImpl::addIgnoredDir( const Path & _path ) void ProjectImpl::addIgnoredDirs( const DirPaths & _paths ) { for( const Path & path : _paths ) + { addIgnoredDir( path ); + } } //------------------------------------------------------------------------------ @@ -115,7 +125,9 @@ void ProjectImpl::forEachIgnoreDir( PathCallback _callback ) const for( const Path & path : m_ignoredDirs ) { if( !_callback( path ) ) + { break; + } } } @@ -131,11 +143,11 @@ bool ProjectImpl::hasCppFileExtensions() const bool ProjectImpl::isExistsCppExtension( std::string_view _ext ) const { std::string ext{ _ext }; - bool result = m_extensions.count( ext ); + bool result = m_extensions.count( ext ) > 0; if( !result ) { ext = "*" + ext; - result = m_extensions.count( ext ); + result = m_extensions.count( ext ) > 0; } return result; @@ -154,7 +166,9 @@ void ProjectImpl::addCppFileExtension( std::string_view _ext ) void ProjectImpl::addCppFileExtensions( const Strings & _extensions ) { for( std::string_view ext : _extensions ) + { addCppFileExtension( ext ); + } } //------------------------------------------------------------------------------ @@ -164,7 +178,9 @@ void ProjectImpl::forEachFileExtension( FileExtensionCallback _callback ) const for( const std::string & ext : m_extensions ) { if( !_callback( ext ) ) + { break; + } } } @@ -210,13 +226,12 @@ void ProjectImpl::addFileFilter( std::string_view _filter ) std::string str{ _filter }; try { - m_fileFilters.push_back( tools::Regex{ str } ); + m_fileFilters.emplace_back( tools::Regex{ str } ); } - catch (const std::regex_error& _exception) + catch( const std::regex_error & _exception ) { throw InvalidRegexImpl{ str, _exception }; } - } //------------------------------------------------------------------------------ @@ -224,7 +239,9 @@ void ProjectImpl::addFileFilter( std::string_view _filter ) void ProjectImpl::addFileFilters( const Strings & _filters ) { for( const auto & filter : _filters ) + { addFileFilter( filter ); + } } //------------------------------------------------------------------------------ @@ -241,7 +258,9 @@ bool ProjectImpl::isIgnoredFile( const Path & _path ) const for( const tools::Regex & filter : m_fileFilters ) { if( isIgnoredFile( _path, filter ) ) + { return true; + } } return false; } @@ -251,7 +270,9 @@ bool ProjectImpl::isIgnoredFile( const Path & _path ) const void ProjectImpl::changeAllPathsToAbsolute() { for( Path & path : m_includeDirs ) + { changeToProjectPath( path ); + } std::vector< Path > newPath; newPath.reserve( m_ignoredDirs.size() ); @@ -285,7 +306,9 @@ ProjectImpl::Path ProjectImpl::convertToDirPath( const Path & _path ) const // folder path should finish with path separator path /= ""; if( filename == path.filename().string() ) - path /= Path::string_type { Path::preferred_separator }; + { + path /= Path::string_type{ Path::preferred_separator }; + } } return path; @@ -296,7 +319,9 @@ ProjectImpl::Path ProjectImpl::convertToDirPath( const Path & _path ) const void ProjectImpl::changeToAbsolute( const Path & _currentDir, Path & _path ) { if( !_path.is_absolute() ) + { _path = _currentDir / _path; + } changeToProjectPath( _path ); } @@ -311,11 +336,9 @@ bool ProjectImpl::isIgnoredFile( const Path & _path, const tools::Regex & _filte { return true; } - else - { - const std::string windowsStr = tools::toWindowsPath( originStr ); - return checkFilter( windowsStr, _filter ); - } + + const std::string windowsStr = tools::toWindowsPath( originStr ); + return checkFilter( windowsStr, _filter ); } //------------------------------------------------------------------------------ @@ -334,7 +357,9 @@ bool ProjectImpl::checkFilter( void ProjectImpl::changeToProjectPath( Path & _path ) { if( !_path.is_absolute() ) + { _path = getProjectDir() / _path; + } _path = convertToDirPath( _path ); } diff --git a/src/project/impl/prj_project_impl.hpp b/src/project/impl/prj_project_impl.hpp index 6a93834..7aaf9e3 100644 --- a/src/project/impl/prj_project_impl.hpp +++ b/src/project/impl/prj_project_impl.hpp @@ -2,13 +2,13 @@ #include "project/api/prj_project.hpp" -#include "tools/std_hash_fs_path.hpp" #include "tools/regex.hpp" +#include "tools/std_hash_fs_path.hpp" -#include #include -#include +#include #include +#include //------------------------------------------------------------------------------ @@ -19,7 +19,6 @@ namespace project { class ProjectImpl final : public Project { public: - explicit ProjectImpl(); void setProjectDir( const Path & _path ) override; @@ -59,7 +58,6 @@ class ProjectImpl final : public Project void changeAllPathsToAbsolute() override; private: - Path convertToDirPath( const Path & _path ) const; void changeToAbsolute( const Path & currentDir, Path & _path ); @@ -69,7 +67,6 @@ class ProjectImpl final : public Project static bool checkFilter( const std::string & _str, const tools::Regex & _filter ); private: - std::vector< Path > m_includeDirs; std::unordered_set< Path > m_ignoredDirs; std::unordered_set< std::string > m_extensions; diff --git a/src/project/test/fixture/prj_test_ficture.cpp b/src/project/test/fixture/prj_test_ficture.cpp index 30285ec..048cfe5 100644 --- a/src/project/test/fixture/prj_test_ficture.cpp +++ b/src/project/test/fixture/prj_test_ficture.cpp @@ -6,12 +6,12 @@ #include "exception/ih/exc_internal_error.hpp" +#include +#include +#include #include #include -#include #include -#include -#include //------------------------------------------------------------------------------ @@ -166,10 +166,12 @@ std::string ProjectFixture::toString( const Strings & _strings ) const std::string seperator = ","; std::string result; - for( const std::string str : _strings ) + for( const std::string & str : _strings ) { if( !result.empty() ) + { result += seperator; + } result += str; } @@ -195,7 +197,7 @@ ProjectAccessor & ProjectFixture::getProjectAccessor() { if( !m_accessor ) { - m_accessor.reset( new ProjectAccessorImpl ); + m_accessor = std::make_unique< ProjectAccessorImpl >(); } return *m_accessor; } diff --git a/src/project/test/fixture/prj_test_ficture.hpp b/src/project/test/fixture/prj_test_ficture.hpp index ddb3d2b..f37d8ab 100644 --- a/src/project/test/fixture/prj_test_ficture.hpp +++ b/src/project/test/fixture/prj_test_ficture.hpp @@ -58,11 +58,9 @@ class ProjectFixture static Paths toPaths( const Strings & _strings ); private: - ProjectAccessor & getProjectAccessor(); private: - std::unique_ptr< ProjectAccessor > m_accessor; std::unique_ptr< Project > m_project; }; diff --git a/src/project/test/prj_test_main.cpp b/src/project/test/prj_test_main.cpp index 13af5bd..6be8ed5 100644 --- a/src/project/test/prj_test_main.cpp +++ b/src/project/test/prj_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE project_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/project/test/suits/prj_test_suits.cpp b/src/project/test/suits/prj_test_suits.cpp index e99cea7..6ddfeb3 100644 --- a/src/project/test/suits/prj_test_suits.cpp +++ b/src/project/test/suits/prj_test_suits.cpp @@ -2,8 +2,7 @@ #include "project/api/prj_exceptions.hpp" -#include -#include +#include "test_tools/test_macros.hpp" #include @@ -34,30 +33,30 @@ TEST PLAN: ------------------------------------------------------------------------------*/ -namespace project::test { - +namespace project::test +{ //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(ProjectTests, ProjectFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( ProjectTests, ProjectFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_1_project_dir_absolute_path) +TEST_CASE( t1_1_project_dir_absolute_path ) { // Init const Path projectDirFullPath = "/home/user/project/"; setProjectDir( projectDirFullPath ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check BOOST_CHECK_EQUAL( getProjectDir(), projectDirFullPath ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_2_project_dir_relative_path) +TEST_CASE( t1_2_project_dir_relative_path ) { // Init const Path projectRelativePath = "project/"; @@ -65,29 +64,29 @@ BOOST_AUTO_TEST_CASE(t1_2_project_dir_relative_path) setProjectDir( projectRelativePath ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check BOOST_CHECK_EQUAL( getProjectDir(), projectAbsolutePath ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_1_include_dirs_absolute_paths) +TEST_CASE( t2_1_include_dirs_absolute_paths ) { // Init setProjectDir( "/home/user/project/" ); addIncludeDirs( { "/usr/lib1", "/usr/lib2" } ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check Paths currentPaths = getIncludeDirs(); - Paths exceptedPaths{ "/usr/lib1/","/usr/lib2/" }; + Paths exceptedPaths{ "/usr/lib1/", "/usr/lib2/" }; - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -99,20 +98,20 @@ BOOST_AUTO_TEST_CASE(t2_1_include_dirs_absolute_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_2_include_dirs_relative_paths) +TEST_CASE( t2_2_include_dirs_relative_paths ) { // Init setProjectDir( "/project/" ); addIncludeDirs( { "lib1", "lib2" } ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check Paths currentPaths = getIncludeDirs(); - Paths exceptedPaths{ "/project/lib1/","/project/lib2/" }; + Paths exceptedPaths{ "/project/lib1/", "/project/lib2/" }; - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -123,20 +122,20 @@ BOOST_AUTO_TEST_CASE(t2_2_include_dirs_relative_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_ignore_dirs_absolute_paths) +TEST_CASE( t3_1_ignore_dirs_absolute_paths ) { // Init setProjectDir( "/home/user/project/" ); addIgnoreDirs( { "/usr/ignore1", "/usr/ignore2" } ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check Paths currentPaths = getIgnoreDirs(); Paths exceptedPaths{ "/usr/ignore1/", "/usr/ignore2/" }; - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -147,20 +146,20 @@ BOOST_AUTO_TEST_CASE(t3_1_ignore_dirs_absolute_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_ignore_dirs_relative_paths) +TEST_CASE( t3_2_ignore_dirs_relative_paths ) { // Init setProjectDir( "/project/" ); addIgnoreDirs( { "ignore1", "ignore2" } ); - //Run + // Run changeAllPathsToAbsolute(); - //Check + // Check Paths currentPaths = getIgnoreDirs(); Paths exceptedPaths{ "/project/ignore1/", "/project/ignore2/" }; - BOOST_CHECK_EQUAL_COLLECTIONS( + TEST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -171,119 +170,118 @@ BOOST_AUTO_TEST_CASE(t3_2_ignore_dirs_relative_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_3_ignore_dirs_is_ignore) +TEST_CASE( t3_3_ignore_dirs_is_ignore ) { // Init setProjectDir( "/project/" ); addIgnoreDirs( { "ignore1", "/usr/ignore2" } ); - //Run + // Run changeAllPathsToAbsolute(); - //Check - BOOST_CHECK( isIgnoreDir( "/project/ignore1" ) ); - BOOST_CHECK( isIgnoreDir( "/usr/ignore2" ) ); + // Check + TEST_CHECK( isIgnoreDir( "/project/ignore1" ) ); + TEST_CHECK( isIgnoreDir( "/usr/ignore2" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_cpp_extension_is_cpp_extension) +TEST_CASE( t4_1_cpp_extension_is_cpp_extension ) { // Run addCppExtensions( { "*.cpp", "*.hpp" } ); - //Check - BOOST_CHECK( isExistsCppExtension( "*.cpp" ) ); - BOOST_CHECK( isExistsCppExtension( "*.hpp" ) ); - BOOST_CHECK( isExistsCppExtension( ".hpp" ) ); - BOOST_CHECK( !isExistsCppExtension( ".cxx" ) ); + // Check + TEST_CHECK( isExistsCppExtension( "*.cpp" ) ); + TEST_CHECK( isExistsCppExtension( "*.hpp" ) ); + TEST_CHECK( isExistsCppExtension( ".hpp" ) ); + TEST_CHECK( !isExistsCppExtension( ".cxx" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_ignore_files_empty) +TEST_CASE( t5_1_ignore_files_empty ) { // Init changeAllPathsToAbsolute(); // create project - //Check - BOOST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); + // Check + TEST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_ignore_files_library) +TEST_CASE( t5_2_ignore_files_library ) { // Init addFileFilter( "boost/.*" ); - //Check - BOOST_CHECK( isIgnoredFile( "boost/test/unit_test.hpp" ) ); - BOOST_CHECK( isIgnoredFile( "boost\\test\\unit_test.hpp" ) ); - BOOST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); + // Check + TEST_CHECK( isIgnoredFile( "boost/test/unit_test.hpp" ) ); + TEST_CHECK( isIgnoredFile( "boost\\test\\unit_test.hpp" ) ); + TEST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_3_ignore_file_name) +TEST_CASE( t5_3_ignore_file_name ) { // Init addFileFilter( "Q.*" ); - //Check - BOOST_CHECK( isIgnoredFile( "QWidget" ) ); - BOOST_CHECK( !isIgnoredFile( "/tmp/q_file.cpp" ) ); + // Check + TEST_CHECK( isIgnoredFile( "QWidget" ) ); + TEST_CHECK( !isIgnoredFile( "/tmp/q_file.cpp" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_4_ignore_sub_string) +TEST_CASE( t5_4_ignore_sub_string ) { // Init addFileFilter( "/ui.*.h" ); - //Check - BOOST_CHECK( isIgnoredFile( "/tmp/ui/file.h" ) ); - BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); + // Check + TEST_CHECK( isIgnoredFile( "/tmp/ui/file.h" ) ); + TEST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_5_ignore_only_begin_part) +TEST_CASE( t5_5_ignore_only_begin_part ) { // Init addFileFilter( "^ui.*.h" ); - //Check - BOOST_CHECK( !isIgnoredFile( "/tmp/ui/file.h" ) ); - BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); - BOOST_CHECK( isIgnoredFile( "ui/file.h" ) ); + // Check + TEST_CHECK( !isIgnoredFile( "/tmp/ui/file.h" ) ); + TEST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); + TEST_CHECK( isIgnoredFile( "ui/file.h" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_6_invalid_regex) +TEST_CASE( t5_6_invalid_regex ) { // Check - BOOST_CHECK_THROW( addFileFilter( "[" ), project::InvalidRegex ); - + TEST_CHECK_THROW( addFileFilter( "[" ), project::InvalidRegex ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_7_double_plus) +TEST_CASE( t5_7_double_plus ) { // Init addFileFilter( "lib\\+\\+v3/include/.*" ); - //Check - BOOST_CHECK( isIgnoredFile( "lib++v3/include/folder/file.h" ) ); + // Check + TEST_CHECK( isIgnoredFile( "lib++v3/include/folder/file.h" ) ); } //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/api/rp_factory.hpp b/src/reporter/api/rp_factory.hpp index 7deb0ae..bb69af5 100644 --- a/src/reporter/api/rp_factory.hpp +++ b/src/reporter/api/rp_factory.hpp @@ -14,7 +14,6 @@ namespace reporter { class Factory { public: - using ReporterPtr = stdfwd::unique_ptr< Reporter >; using SettingsPtr = stdfwd::unique_ptr< Settings >; diff --git a/src/reporter/api/rp_reporter.hpp b/src/reporter/api/rp_reporter.hpp index d06e2af..fcce9ff 100644 --- a/src/reporter/api/rp_reporter.hpp +++ b/src/reporter/api/rp_reporter.hpp @@ -21,7 +21,6 @@ namespace reporter { class Reporter { public: - virtual ~Reporter() = default; virtual ReporterKind getKind() const = 0; diff --git a/src/reporter/api/rp_settings.hpp b/src/reporter/api/rp_settings.hpp index e466df8..d9d0bee 100644 --- a/src/reporter/api/rp_settings.hpp +++ b/src/reporter/api/rp_settings.hpp @@ -11,7 +11,6 @@ namespace reporter { class Settings { public: - virtual ~Settings() = default; using CountType = std::size_t; diff --git a/src/reporter/exceptions/rp_base_exception_impl.hpp b/src/reporter/exceptions/rp_base_exception_impl.hpp index bb6473e..67085f7 100644 --- a/src/reporter/exceptions/rp_base_exception_impl.hpp +++ b/src/reporter/exceptions/rp_base_exception_impl.hpp @@ -14,15 +14,12 @@ template< class _BaseException > class BaseExceptionImpl : public ::exception::ExceptionImpl< _BaseException > { public: - using BaseClass = ::exception::ExceptionImpl< _BaseException >; explicit BaseExceptionImpl( std::string_view _code ) : BaseClass{ resources::exceptions::ModuleName, _code } { - } - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/exceptions/rp_incorrect_report_impl.cpp b/src/reporter/exceptions/rp_incorrect_report_impl.cpp index c488178..4b83ed9 100644 --- a/src/reporter/exceptions/rp_incorrect_report_impl.cpp +++ b/src/reporter/exceptions/rp_incorrect_report_impl.cpp @@ -24,7 +24,6 @@ IncorrectReportImpl::IncorrectReportImpl( std::string_view _name ) : BaseClass( resources::exceptions::IncorrectReport::Code ) , m_name( _name ) { - } //------------------------------------------------------------------------------ @@ -44,7 +43,8 @@ std::string IncorrectReportImpl::getMessage() const noexcept std::string IncorrectReportImpl::getPossiblesValues() { - static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + constexpr int ReporterKindCount = 5; + static_assert( static_cast< int >( ReporterKind::Count ) == ReporterKindCount ); static const std::string seperator = ", "; diff --git a/src/reporter/exceptions/rp_incorrect_report_impl.hpp b/src/reporter/exceptions/rp_incorrect_report_impl.hpp index 6250364..9010d41 100644 --- a/src/reporter/exceptions/rp_incorrect_report_impl.hpp +++ b/src/reporter/exceptions/rp_incorrect_report_impl.hpp @@ -1,7 +1,7 @@ #pragma once -#include "reporter/exceptions/rp_exceptions.hpp" #include "reporter/exceptions/rp_base_exception_impl.hpp" +#include "reporter/exceptions/rp_exceptions.hpp" //------------------------------------------------------------------------------ @@ -14,19 +14,15 @@ class IncorrectReportImpl : public BaseExceptionImpl< IncorrectReport > using BaseClass = BaseExceptionImpl< IncorrectReport >; public: - explicit IncorrectReportImpl( std::string_view _name ); std::string getMessage() const noexcept override; private: - static std::string getPossiblesValues(); private: - const std::string m_name; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/ih/rp_accessor.hpp b/src/reporter/ih/rp_accessor.hpp index e513cf6..5ffe401 100644 --- a/src/reporter/ih/rp_accessor.hpp +++ b/src/reporter/ih/rp_accessor.hpp @@ -10,11 +10,9 @@ namespace reporter { class ReporterAccessor { public: - virtual ~ReporterAccessor() = default; virtual Factory & getReporterFactory() = 0; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/ih/rp_accessor_impl.cpp b/src/reporter/ih/rp_accessor_impl.cpp index 4b614b7..dbff078 100644 --- a/src/reporter/ih/rp_accessor_impl.cpp +++ b/src/reporter/ih/rp_accessor_impl.cpp @@ -17,6 +17,10 @@ ReporterAccessorImpl::ReporterAccessorImpl() //------------------------------------------------------------------------------ +ReporterAccessorImpl::~ReporterAccessorImpl() = default; + +//------------------------------------------------------------------------------ + Factory & ReporterAccessorImpl::getReporterFactory() { INTERNAL_CHECK_ERROR( m_factory ); diff --git a/src/reporter/ih/rp_accessor_impl.hpp b/src/reporter/ih/rp_accessor_impl.hpp index 2998e80..ca690af 100644 --- a/src/reporter/ih/rp_accessor_impl.hpp +++ b/src/reporter/ih/rp_accessor_impl.hpp @@ -13,15 +13,13 @@ namespace reporter { class ReporterAccessorImpl final : public ReporterAccessor { public: - ReporterAccessorImpl(); + ~ReporterAccessorImpl() override; Factory & getReporterFactory() override; private: - std::unique_ptr< Factory > m_factory; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp index d2e1515..77c410f 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp @@ -6,19 +6,19 @@ #include "reporter/impl/tools/rp_sorted_includes_by_source_container.hpp" #include "reporter/resources/rp_different_type_report_resources.hpp" -#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/enums/mi_file_type.hpp" #include "model_includes/api/mi_file.hpp" #include "model_includes/api/mi_include.hpp" #include "model_includes/api/mi_include_location.hpp" -#include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_model.hpp" #include "exception/ih/exc_internal_error.hpp" #include #include -#include #include +#include //------------------------------------------------------------------------------ @@ -29,7 +29,6 @@ namespace reporter { DifferentTypeReporter::DifferentTypeReporter( SettingsPtr && _settingsPtr ) : BaseClass{ std::move( _settingsPtr ) } { - } //------------------------------------------------------------------------------ @@ -57,7 +56,9 @@ void DifferentTypeReporter::printFiles( ) const { if( _files.isEmpty() ) + { return; + } _stream << resources::different_type_report::Header; @@ -78,8 +79,9 @@ void DifferentTypeReporter::printFiles( }); if( isLimitFilesWithOriginSize( currentNumber, _originSize ) ) + { printFileLimitLine( _originSize, _stream ); - + } } //------------------------------------------------------------------------------ @@ -186,10 +188,14 @@ DifferentTypeReporter::Files DifferentTypeReporter::collectFiles( [&]( const model_includes::File & _file ) { if( isIgnoredFile( _file ) ) + { return true; + } if( isIncludedByDifferentType( _file ) ) + { result.insert( { _file, _file.getIncludedByCount() } ); + } return true; } @@ -216,8 +222,10 @@ DifferentTypeReporter::Details DifferentTypeReporter::collectDetails( bool DifferentTypeReporter::isIncludedByDifferentType( const File & _file ) { - if( _file.getIncludedByCount() < 2) + if( _file.getIncludedByCount() < 2 ) + { return false; + } const auto firstType = _file.getIncludedBy( 0 ).getType(); @@ -225,7 +233,9 @@ bool DifferentTypeReporter::isIncludedByDifferentType( const File & _file ) { const auto currentType = _file.getIncludedBy( i ).getType(); if( firstType != currentType ) + { return true; + } } return false; @@ -238,14 +248,18 @@ bool DifferentTypeReporter::isIgnoredFile( const File & _file ) const using namespace model_includes; if( getShowStdFiles() ) + { return false; + } const FileType type = _file.getType(); static_assert( static_cast< int >( FileType::Count ) == 2 ); switch( type ) { - case FileType::ProjectFile : return false; - case FileType::StdLibraryFile : return true; + case FileType::ProjectFile: + return false; + case FileType::StdLibraryFile: + return true; default: INTERNAL_CHECK_WARRING( false ); return false; diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp index 95e6e91..4f0e533 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp @@ -23,7 +23,6 @@ class DifferentTypeReporter final : public BaseReporterImpl using BaseClass = BaseReporterImpl; public: - explicit DifferentTypeReporter( SettingsPtr && _settingsPtr ); void report( @@ -74,7 +73,6 @@ class DifferentTypeReporter final : public BaseReporterImpl static bool isIncludedByDifferentType( const File & _file ); bool isIgnoredFile( const File & _file ) const; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp index 2473272..eda93a1 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp @@ -1,7 +1,7 @@ #include "reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp" -#include "model_includes/api/mi_include.hpp" #include "model_includes/api/enums/mi_include_type.hpp" +#include "model_includes/api/mi_include.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -35,12 +35,12 @@ void DifferentTypeReporterDetails::insertInclude( const Include & _include ) const auto type = _include.getType(); switch( type ) { - case IncludeType::User : + case IncludeType::User: m_userIncludes.insert( _include ); - break; - case IncludeType::System : + break; + case IncludeType::System: m_systemIncludes.insert( _include ); - break; + break; default: INTERNAL_CHECK_WARRING( false ); diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp index 0257a84..b6f8597 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter_details.hpp @@ -21,7 +21,6 @@ class DifferentTypeReporterDetails void insertInclude( const Include & _include ); private: - Includes m_userIncludes; Includes m_systemIncludes; }; diff --git a/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp b/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp index 25e2eb5..843e662 100644 --- a/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp +++ b/src/reporter/impl/dump_reporter/rp_dump_reporter.cpp @@ -3,12 +3,12 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/resources/rp_dump_resources.hpp" -#include "model_includes/api/mi_model.hpp" -#include "model_includes/api/mi_file.hpp" -#include "model_includes/api/mi_include.hpp" +#include "model_includes/api/enums/mi_file_type.hpp" #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" -#include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_include.hpp" +#include "model_includes/api/mi_model.hpp" #include "exception/ih/exc_internal_error.hpp" @@ -21,32 +21,9 @@ namespace reporter { //------------------------------------------------------------------------------ -bool DumpReporter::FileSorter::operator()( - const model_includes::File * _r, - const model_includes::File * _l -) const -{ - INTERNAL_CHECK_ERROR( _r ); - INTERNAL_CHECK_ERROR( _l ); - return operator()( *_r, *_l ); -} - -//------------------------------------------------------------------------------ - -bool DumpReporter::FileSorter::operator()( - const model_includes::File & _r, - const model_includes::File & _l -) const -{ - return stdfs::less( _r.getPath(), _l.getPath() ); -} - -//------------------------------------------------------------------------------ - DumpReporter::DumpReporter( SettingsPtr && _settingsPtr ) : BaseClass{ std::move( _settingsPtr ) } { - } //------------------------------------------------------------------------------ @@ -56,7 +33,7 @@ void DumpReporter::report( std::ostream & _stream ) { - SortedFilesContainer files; + Files files; collectFiles( _model, files ); dump( files, _model.getProjectDir(), _stream ); } @@ -72,12 +49,12 @@ ReporterKind DumpReporter::getKind() const void DumpReporter::collectFiles( const model_includes::Model & _model, - SortedFilesContainer & _files + Files & _files ) const { _model.forEachFile( [&]( const model_includes::File & _file ) { - _files.insert( &_file ); + _files.insert( _file ); return true; } ); @@ -86,7 +63,7 @@ void DumpReporter::collectFiles( //------------------------------------------------------------------------------ void DumpReporter::dump( - const SortedFilesContainer & _files, + const Files & _files, const Path & _dirPath, std::ostream & _stream ) const @@ -95,27 +72,24 @@ void DumpReporter::dump( int number = 1; - for( const File * filePtr : _files ) + _files.forEachFile( [&] ( const File & _file ) { - INTERNAL_CHECK_WARRING( filePtr ); - if( !filePtr ) - continue; - - const File & file = *filePtr; _stream << number << " : " - << toString( file, _dirPath ) + << toString( _file, _dirPath ) << " ( type: " - << toString( file.getType() ) + << toString( _file.getType() ) << " )\n" ; - dumpIncludes( file, _dirPath, _stream ); - dumpIncludedBy( file, _dirPath, _stream ); + dumpIncludes( _file, _dirPath, _stream ); + dumpIncludedBy( _file, _dirPath, _stream ); ++number; - } + + return true; + } ); } //------------------------------------------------------------------------------ @@ -129,11 +103,13 @@ void DumpReporter::dumpIncludes( using namespace model_includes; const File::IncludeIndex count = _file.getIncludesCount(); - if( !count ) + if( count == 0U ) + { return; + } indent( 1, _stream ) << "Includes:\n"; - for( File::IncludeIndex i = 0; i < count ; ++i ) + for( File::IncludeIndex i = 0; i < count; ++i ) { const Include & include = _file.getInclude( i ); @@ -158,8 +134,10 @@ void DumpReporter::dumpIncludedBy( using namespace model_includes; const File::IncludeIndex count = _file.getIncludedByCount(); - if( !count ) + if( count == 0U ) + { return; + } indent( 1, _stream ) << "Included by:\n"; for( File::IncludeIndex i = 0; i < count; ++i ) @@ -200,11 +178,12 @@ void DumpReporter::dumpFileFromInclude( //------------------------------------------------------------------------------ - std::ostream & DumpReporter::indent( int _count, std::ostream & _stream ) const { for( int i = 0; i < _count; ++i ) + { _stream << resources::dump_reporter::Indent; + } return _stream; } @@ -221,15 +200,17 @@ std::string DumpReporter::toString( //------------------------------------------------------------------------------ -std::string DumpReporter::toString( model_includes::FileType _fileType ) const +std::string DumpReporter::toString( model_includes::FileType _type ) const { using namespace model_includes; static_assert( static_cast< int >( FileType::Count ) == 2 ); - switch( _fileType ) + switch( _type ) { - case FileType::ProjectFile : return "project file"; - case FileType::StdLibraryFile : return "standard library file"; + case FileType::ProjectFile: + return "project file"; + case FileType::StdLibraryFile: + return "standard library file"; default: INTERNAL_CHECK_WARRING( false ); return ""; @@ -245,8 +226,10 @@ std::string DumpReporter::toString( model_includes::IncludeType _type ) const static_assert( static_cast< int >( IncludeType::Count ) == 2 ); switch( _type ) { - case IncludeType::User : return "user include"; - case IncludeType::System : return "system include"; + case IncludeType::User: + return "user include"; + case IncludeType::System: + return "system include"; default: INTERNAL_CHECK_WARRING( false ); return ""; @@ -255,15 +238,18 @@ std::string DumpReporter::toString( model_includes::IncludeType _type ) const //------------------------------------------------------------------------------ -std::string DumpReporter::toString( model_includes::IncludeStatus _status ) const +std::string +DumpReporter::toString( model_includes::IncludeStatus _status ) const { using namespace model_includes; - static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); + static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); switch( _status ) { - case IncludeStatus::Resolved : return "resolved"; - case IncludeStatus::Unresolved : return "unresolved"; + case IncludeStatus::Resolved: + return "resolved"; + case IncludeStatus::Unresolved: + return "unresolved"; default: INTERNAL_CHECK_WARRING( false ); return ""; diff --git a/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp b/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp index 9910949..da06a94 100644 --- a/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp +++ b/src/reporter/impl/dump_reporter/rp_dump_reporter.hpp @@ -1,9 +1,7 @@ #pragma once #include "reporter/impl/rp_base_reporter_impl.hpp" - -#include -#include +#include "reporter/impl/tools/rp_sorted_files_by_name_container.hpp" //------------------------------------------------------------------------------ @@ -27,8 +25,7 @@ class DumpReporter final : public BaseReporterImpl using BaseClass = BaseReporterImpl; public: - - explicit DumpReporter( SettingsPtr && _settingPtr ); + explicit DumpReporter( SettingsPtr && _settingsPtr ); void report( const model_includes::Model & _model, @@ -38,34 +35,14 @@ class DumpReporter final : public BaseReporterImpl ReporterKind getKind() const override; private: - using Path = stdfs::path; - struct FileSorter - { - bool operator()( - const model_includes::File * _r, - const model_includes::File * _l - ) const; - - bool operator()( - const model_includes::File & _r, - const model_includes::File & _l - ) const; - }; - - using SortedFilesContainer = std::set< - const model_includes::File *, - FileSorter - >; - - void collectFiles( - const model_includes::Model & _model, - SortedFilesContainer & _files - ) const; + using Files = SortedFilesByNameContainer; + + void collectFiles( const model_includes::Model & _model, Files & _files ) const; void dump( - const SortedFilesContainer & _files, + const Files & _files, const Path & _dirPath, std::ostream & _stream ) const; diff --git a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp index 30ba578..88098d3 100644 --- a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp @@ -1,24 +1,24 @@ #include "reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" -#include "reporter/impl/tools/rp_file_with_count.hpp" #include "reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp" -#include "reporter/resources/rp_most_impact_report_resources.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" #include "reporter/impl/tools/rp_file_with_count_container.hpp" #include "reporter/impl/tools/rp_file_with_count_sorter.hpp" +#include "reporter/resources/rp_most_impact_report_resources.hpp" -#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/enums/mi_file_type.hpp" #include "model_includes/api/mi_file.hpp" #include "model_includes/api/mi_include.hpp" #include "model_includes/api/mi_include_location.hpp" -#include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_model.hpp" #include "exception/ih/exc_internal_error.hpp" #include -#include #include +#include //------------------------------------------------------------------------------ @@ -27,11 +27,11 @@ namespace reporter { //------------------------------------------------------------------------------ bool MostImpcatReporter::DetailsSorter::operator()( - const MostImpactReporterDetail & _r, - const MostImpactReporterDetail & _l + const MostImpactReporterDetail & _l, + const MostImpactReporterDetail & _r ) const { - return FileWithCountSorter()( _r.getFileInfo(), _l.getFileInfo() ); + return FileWithCountSorter()( _l.getFileInfo(), _r.getFileInfo() ); } //------------------------------------------------------------------------------ @@ -39,7 +39,6 @@ bool MostImpcatReporter::DetailsSorter::operator()( MostImpcatReporter::MostImpcatReporter( SettingsPtr && _settingsPtr ) : BaseClass{ std::move( _settingsPtr ) } { - } //------------------------------------------------------------------------------ @@ -78,11 +77,15 @@ void MostImpcatReporter::collectFiles( [&]( const File & _file ) { if( !isCollectFile( _file ) ) + { return true; + } const File::IncludeIndex count = _file.getIncludedByFilesCountRecursive(); - if( count ) + if( count > 0) + { _files.insert( { _file, count } ); + } return true; } @@ -101,7 +104,9 @@ void MostImpcatReporter::printIncludesByFiles( using namespace model_includes; if( _files.isEmpty() ) + { return; + } _stream << resources::most_impact_report::Header; @@ -129,7 +134,9 @@ void MostImpcatReporter::printIncludesByFiles( } if( isLimitFilesWithOriginSize( currentNumber, _originSize ) ) + { printFileLimitLine( _originSize, _stream ); + } } //------------------------------------------------------------------------------ @@ -146,13 +153,15 @@ void MostImpcatReporter::printDetails( collectDetails( _includedByFile, details ); if( details.empty() ) + { return; + } _stream << resources::most_impact_report::HeaderForDetails; CountType currentNumber = 1; - for( const MostImpactReporterDetail & detail : details ) + for( const MostImpactReporterDetail & detail: details ) { if( isLimitDetails( currentNumber ) ) { @@ -186,7 +195,7 @@ void MostImpcatReporter::printDetail( const auto line = _detail.getIncludeLocation().getLineNumber(); - if( count ) + if( count > 0 ) { _stream << fmt::format( resources::most_impact_report::LineForDetailFmt, @@ -205,7 +214,6 @@ void MostImpcatReporter::printDetail( line ); } - } //------------------------------------------------------------------------------ @@ -240,8 +248,10 @@ bool MostImpcatReporter::isCollectFile( const model_includes::File & _file ) con static_assert( static_cast< int >( FileType::Count ) == 2 ); switch( type ) { - case FileType::ProjectFile : return true; - case FileType::StdLibraryFile : return getShowStdFiles(); + case FileType::ProjectFile: + return true; + case FileType::StdLibraryFile: + return getShowStdFiles(); default: INTERNAL_CHECK_WARRING( false ); return false; diff --git a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp index fad8188..bf31685 100644 --- a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp @@ -25,7 +25,6 @@ class MostImpcatReporter final : public BaseReporterImpl using BaseClass = BaseReporterImpl; public: - explicit MostImpcatReporter( SettingsPtr && _settingsPtr ); void report( @@ -36,7 +35,6 @@ class MostImpcatReporter final : public BaseReporterImpl ReporterKind getKind() const override; private: - class DetailsSorter { public: diff --git a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp index 573cbf3..fc4a5da 100644 --- a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter_detail.hpp @@ -18,7 +18,6 @@ namespace reporter { class MostImpactReporterDetail { public: - using CountType = FileWithCount::CountType; MostImpactReporterDetail( @@ -28,7 +27,6 @@ class MostImpactReporterDetail ); public: - const model_includes::File & getFile() const; FileWithCount::CountType getIncludedByCount() const; const model_includes::IncludeLocation & getIncludeLocation() const; @@ -36,7 +34,6 @@ class MostImpactReporterDetail const FileWithCount & getFileInfo() const; private: - const FileWithCount m_fileInfo; const model_includes::IncludeLocation & m_includeLocation; }; diff --git a/src/reporter/impl/rp_base_reporter_impl.cpp b/src/reporter/impl/rp_base_reporter_impl.cpp index b7b0933..272a2ae 100644 --- a/src/reporter/impl/rp_base_reporter_impl.cpp +++ b/src/reporter/impl/rp_base_reporter_impl.cpp @@ -6,8 +6,8 @@ #include "exception/ih/exc_internal_error.hpp" -#include #include +#include #include @@ -71,18 +71,22 @@ std::string BaseReporterImpl::getPathWithoutProject( ) { if( _dirPath.empty() ) + { return _filePath.string(); + } if( !isFromSameDirectory( _filePath, _dirPath ) ) + { return _filePath.string(); + } Path result = stdfs::lexically_relative( _filePath, _dirPath ); if( ( !result.empty() ) ) - return result.string(); - else { - return _filePath.string(); + return result.string(); } + + return _filePath.string(); } //------------------------------------------------------------------------------ @@ -94,7 +98,9 @@ bool BaseReporterImpl::isFromSameDirectory( { const Path root = _path1.root_path(); if( root != _path2.root_path() ) + { return false; + } Path commonPath = getCommonPath( _path1, _path2 ); const bool result = commonPath != root; @@ -122,7 +128,7 @@ BaseReporterImpl::Path BaseReporterImpl::getCommonPath( *itCurrentFirst == *itCurrentSecond ) { - resutl /= *itCurrentFirst; + resutl /= *itCurrentFirst; ++itCurrentFirst; ++itCurrentSecond; @@ -145,7 +151,7 @@ bool BaseReporterImpl::isLimitFilesWithOriginSize( CountType _originSize ) const { - return isLimitFiles( _currentNumber ) && _currentNumber - 1 != _originSize; + return isLimitFiles( _currentNumber ) && _currentNumber - 1 != _originSize; } //------------------------------------------------------------------------------ @@ -181,7 +187,7 @@ void BaseReporterImpl::printDetailsLimitLine( bool BaseReporterImpl::isLimit( CountType _currentNumber, CountType _limit ) { - return _limit && _currentNumber > _limit; + return ( _limit > 0 ) && ( _currentNumber > _limit ); } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_base_reporter_impl.hpp b/src/reporter/impl/rp_base_reporter_impl.hpp index e4cf56a..3d24d93 100644 --- a/src/reporter/impl/rp_base_reporter_impl.hpp +++ b/src/reporter/impl/rp_base_reporter_impl.hpp @@ -13,7 +13,6 @@ namespace reporter { class BaseReporterImpl : public Reporter { public: - using SettingsPtr = std::unique_ptr< Settings >; BaseReporterImpl( SettingsPtr && _settingsPtr ); @@ -23,7 +22,6 @@ class BaseReporterImpl : public Reporter void copySettings( const Settings & _settings ) override; protected: - using Path = stdfs::path; using CountType = size_t; @@ -57,13 +55,10 @@ class BaseReporterImpl : public Reporter ) const; private: - static bool isLimit( CountType _currentNumber, CountType _limit ); private: - SettingsPtr m_settings; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_factpory_impl.cpp b/src/reporter/impl/rp_factpory_impl.cpp index 3ecdd20..c409984 100644 --- a/src/reporter/impl/rp_factpory_impl.cpp +++ b/src/reporter/impl/rp_factpory_impl.cpp @@ -2,11 +2,11 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/impl/different_type_reporter/rp_different_type_reporter.hpp" #include "reporter/impl/dump_reporter/rp_dump_reporter.hpp" -#include "reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp" #include "reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp" #include "reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp" -#include "reporter/impl/different_type_reporter/rp_different_type_reporter.hpp" +#include "reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp" #include "reporter/impl/rp_settings_impl.hpp" @@ -22,7 +22,8 @@ namespace reporter { FactoryImpl::ReporterPtr FactoryImpl::createReporter( ReporterKind _kind ) { - static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + constexpr int ReporterKindCount = 5; + static_assert( static_cast< int >( ReporterKind::Count ) == ReporterKindCount ); switch( _kind ) { case ReporterKind::Unresolved : return createUnresolvedReporter(); @@ -32,7 +33,7 @@ FactoryImpl::ReporterPtr FactoryImpl::createReporter( ReporterKind _kind ) case ReporterKind::DifferentType : return createDifferentTypeReporter(); case ReporterKind::Count : { - INTERNAL_CHECK_WARRING(false); + INTERNAL_CHECK_WARRING( false ); return nullptr; } } diff --git a/src/reporter/impl/rp_factpory_impl.hpp b/src/reporter/impl/rp_factpory_impl.hpp index a372eec..79dc450 100644 --- a/src/reporter/impl/rp_factpory_impl.hpp +++ b/src/reporter/impl/rp_factpory_impl.hpp @@ -9,7 +9,6 @@ namespace reporter { class FactoryImpl final : public Factory { public: - ReporterPtr createReporter( ReporterKind _kind ) override; ReporterPtr createDumpReporter() override; @@ -19,7 +18,6 @@ class FactoryImpl final : public Factory ReporterPtr createDifferentTypeReporter() override; SettingsPtr createSettings() override; - }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_settings_impl.cpp b/src/reporter/impl/rp_settings_impl.cpp index 9536be8..d2c2a8d 100644 --- a/src/reporter/impl/rp_settings_impl.cpp +++ b/src/reporter/impl/rp_settings_impl.cpp @@ -11,7 +11,6 @@ SettingsImpl::SettingsImpl() , m_maxDetailsCount{ 0 } , m_showStdFiles{ true } { - } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_settings_impl.hpp b/src/reporter/impl/rp_settings_impl.hpp index 39ea726..11143a5 100644 --- a/src/reporter/impl/rp_settings_impl.hpp +++ b/src/reporter/impl/rp_settings_impl.hpp @@ -11,7 +11,6 @@ namespace reporter { class SettingsImpl final : public Settings { public: - SettingsImpl(); CountType getMaxFilesCount() const override; @@ -26,7 +25,6 @@ class SettingsImpl final : public Settings void copy( const Settings & _other ) override; private: - CountType m_maxFilesCount; CountType m_maxDetailsCount; bool m_showStdFiles; diff --git a/src/reporter/impl/tools/rp_file_sorter.cpp b/src/reporter/impl/tools/rp_file_sorter.cpp index c2249c9..dc6605f 100644 --- a/src/reporter/impl/tools/rp_file_sorter.cpp +++ b/src/reporter/impl/tools/rp_file_sorter.cpp @@ -17,7 +17,9 @@ bool FileSorter::operator()( const File * _l, const File * _r ) const INTERNAL_CHECK_WARRING( _l ); INTERNAL_CHECK_WARRING( _r ); if( _l == nullptr || _r == nullptr ) + { return false; + } return operator()( *_l, *_r ); } @@ -26,8 +28,8 @@ bool FileSorter::operator()( const File * _l, const File * _r ) const bool FileSorter::operator()( const File & _l, const File & _r ) const { - const auto lPath = _l.getPath(); - const auto rPath = _r.getPath(); + const auto & lPath = _l.getPath(); + const auto & rPath = _r.getPath(); return stdfs::less( lPath, rPath ); } diff --git a/src/reporter/impl/tools/rp_file_with_count.hpp b/src/reporter/impl/tools/rp_file_with_count.hpp index 0f5d57b..b9b7b17 100644 --- a/src/reporter/impl/tools/rp_file_with_count.hpp +++ b/src/reporter/impl/tools/rp_file_with_count.hpp @@ -16,18 +16,15 @@ namespace reporter { class FileWithCount { - public: - using CountType = std::size_t; - FileWithCount( const model_includes::File & _file, CountType _count ); + FileWithCount( const model_includes::File & _file, CountType _count ); const model_includes::File & getFile() const; CountType getCount() const; private: - const model_includes::File & m_file; const CountType m_count; }; diff --git a/src/reporter/impl/tools/rp_file_with_count_container.cpp b/src/reporter/impl/tools/rp_file_with_count_container.cpp index bc3b5e3..20d47b1 100644 --- a/src/reporter/impl/tools/rp_file_with_count_container.cpp +++ b/src/reporter/impl/tools/rp_file_with_count_container.cpp @@ -33,11 +33,13 @@ bool FileWithCountContainer::isEmpty() const void FileWithCountContainer::resizeByLimit( std::size_t _limit ) { - if( _limit && m_files.size() >= _limit ) + if( _limit > 0 && m_files.size() >= _limit ) { auto it = m_files.begin(); for( std::size_t i = 0; i < _limit; ++i ) + { ++it; + } m_files.erase( it, m_files.end() ); } @@ -45,28 +47,28 @@ void FileWithCountContainer::resizeByLimit( std::size_t _limit ) //------------------------------------------------------------------------------ -void FileWithCountContainer::forEachFile( FileCallback _callback ) const +void FileWithCountContainer::forEachFile( const FileCallback & _callback ) const { - for( const FileWithCount & fileInfo : m_files ) + for( const FileWithCount & fileInfo: m_files ) { const File & file = fileInfo.getFile(); if( !_callback( file ) ) + { break; + } } } //------------------------------------------------------------------------------ -FileWithCountContainer::Iterator -FileWithCountContainer::begin() const +FileWithCountContainer::Iterator FileWithCountContainer::begin() const { return m_files.begin(); } //------------------------------------------------------------------------------ -FileWithCountContainer::Iterator -FileWithCountContainer::end() const +FileWithCountContainer::Iterator FileWithCountContainer::end() const { return m_files.end(); } diff --git a/src/reporter/impl/tools/rp_file_with_count_container.hpp b/src/reporter/impl/tools/rp_file_with_count_container.hpp index 0673b80..4c3e1a4 100644 --- a/src/reporter/impl/tools/rp_file_with_count_container.hpp +++ b/src/reporter/impl/tools/rp_file_with_count_container.hpp @@ -3,8 +3,8 @@ #include "reporter/impl/tools/rp_file_with_count.hpp" #include "reporter/impl/tools/rp_file_with_count_sorter.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -33,13 +33,12 @@ class FileWithCountContainer void insert( const FileWithCount & _file ); void resizeByLimit( std::size_t _limit ); - void forEachFile( FileCallback _callback ) const; + void forEachFile( const FileCallback & _callback ) const; Iterator begin() const; Iterator end() const; private: - Files m_files; }; diff --git a/src/reporter/impl/tools/rp_file_with_count_sorter.cpp b/src/reporter/impl/tools/rp_file_with_count_sorter.cpp index 62c5f37..9409ad7 100644 --- a/src/reporter/impl/tools/rp_file_with_count_sorter.cpp +++ b/src/reporter/impl/tools/rp_file_with_count_sorter.cpp @@ -1,7 +1,7 @@ #include "reporter/impl/tools/rp_file_with_count_sorter.hpp" -#include "reporter/impl/tools/rp_file_with_count.hpp" #include "reporter/impl/tools/rp_file_sorter.hpp" +#include "reporter/impl/tools/rp_file_with_count.hpp" //------------------------------------------------------------------------------ @@ -19,10 +19,8 @@ bool FileWithCountSorter::operator()( // max is first return _l.getCount() > _r.getCount(); } - else - { - return FileSorter()( _l.getFile(), _r.getFile() ); - } + + return FileSorter()( _l.getFile(), _r.getFile() ); } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/tools/rp_file_with_count_sorter.hpp b/src/reporter/impl/tools/rp_file_with_count_sorter.hpp index 43a6423..9b2b43b 100644 --- a/src/reporter/impl/tools/rp_file_with_count_sorter.hpp +++ b/src/reporter/impl/tools/rp_file_with_count_sorter.hpp @@ -9,7 +9,7 @@ namespace reporter { struct FileWithCountSorter { - bool operator()( const FileWithCount & _l, const FileWithCount & _r ) const; + bool operator()( const FileWithCount & _l, const FileWithCount & _r ) const; }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp b/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp index a113bce..8499896 100644 --- a/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp +++ b/src/reporter/impl/tools/rp_includes_by_source_sorter.cpp @@ -21,7 +21,9 @@ bool IncludesBySourceSorter::operator()( INTERNAL_CHECK_WARRING( _r ); if( _l == nullptr || _r == nullptr ) + { return false; + } return operator()( *_l, *_r ); } diff --git a/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp b/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp index 434f84c..cd54095 100644 --- a/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp +++ b/src/reporter/impl/tools/rp_sorted_files_by_name_container.cpp @@ -32,18 +32,20 @@ bool SortedFilesByNameContainer::isEmpty() const //------------------------------------------------------------------------------ -void SortedFilesByNameContainer::forEachFile( FileCallback _callback ) const +void SortedFilesByNameContainer::forEachFile( const FileCallback & _callback ) const { for( const File * filePtr : m_files ) { - if( !filePtr ) + if( filePtr == nullptr ) { INTERNAL_CHECK_WARRING( false ); continue; } if( !_callback( *filePtr ) ) + { break; + } } } diff --git a/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp index 8d65f6d..5d0af3a 100644 --- a/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp +++ b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp @@ -20,7 +20,6 @@ namespace reporter { class SortedFilesByNameContainer { - public: using File = model_includes::File; @@ -31,12 +30,11 @@ class SortedFilesByNameContainer void insert( const File & _file ); bool isEmpty() const; - void forEachFile( FileCallback _callback ) const; + void forEachFile( const FileCallback & _callback ) const; std::size_t getSize() const; private: - using Path = stdfs::path; using FilesContainer = std::set< const File *, FileSorter >; diff --git a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp index 71e93b0..c7dd19c 100644 --- a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp +++ b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.cpp @@ -20,23 +20,29 @@ void SortedIncludesBySourceContainer::insert( const Include & _include ) //------------------------------------------------------------------------------ void SortedIncludesBySourceContainer::forEachInclude( - IncludeCallback _callback + const IncludeCallback & _callback ) const { for( const Include * include : m_includes ) { INTERNAL_CHECK_WARRING( include ); - if( !include ) + if( include == nullptr ) + { continue; + } if( !_callback( *include ) ) + { break; + } } } //------------------------------------------------------------------------------ -void SortedIncludesBySourceContainer::forEachSource( FileCallback _callback ) const +void SortedIncludesBySourceContainer::forEachSource( + const FileCallback & _callback +) const { forEachInclude( [&]( const Include & _include ) diff --git a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp index 9d6c251..686e2cf 100644 --- a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp +++ b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp @@ -21,7 +21,6 @@ namespace reporter { class SortedIncludesBySourceContainer { - public: using Include = model_includes::Include; @@ -32,13 +31,12 @@ class SortedIncludesBySourceContainer void insert( const Include & _include ); - void forEachInclude( IncludeCallback _callback ) const; - void forEachSource( FileCallback _callback ) const; + void forEachInclude( const IncludeCallback & _callback ) const; + void forEachSource( const FileCallback & _callback ) const; std::size_t getCount() const; private: - using Includes = std::set< const Include *, IncludesBySourceSorter >; Includes m_includes; diff --git a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp index 328e8d3..075fd3a 100644 --- a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp +++ b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.cpp @@ -1,11 +1,11 @@ #include "reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" -#include "reporter/resources/rp_unincluded_report_resources.hpp" #include "reporter/impl/tools/rp_sorted_files_by_name_container.hpp" +#include "reporter/resources/rp_unincluded_report_resources.hpp" -#include "model_includes/api/mi_model.hpp" #include "model_includes/api/mi_file.hpp" +#include "model_includes/api/mi_model.hpp" #include #include @@ -22,7 +22,6 @@ namespace reporter { UnincludedReporter::UnincludedReporter( SettingsPtr && _settingsPtr ) : BaseClass{ std::move( _settingsPtr ) } { - } //------------------------------------------------------------------------------ @@ -45,7 +44,7 @@ UnincludedReporter::FilesContainer UnincludedReporter::collectFiles( FilesContainer files; _model.forEachFile( [&]( const model_includes::File & _file ) { - if( isHeader( _file ) && !_file.getIncludedByCount() ) + if( isHeader( _file ) && _file.getIncludedByCount() == 0u ) { files.insert( _file ); } @@ -66,10 +65,12 @@ ReporterKind UnincludedReporter::getKind() const bool UnincludedReporter::isHeader( const model_includes::File & _file ) const { - const std::string extensionStr =_file.getPath().extension().string(); + const std::string extensionStr = _file.getPath().extension().string(); - if(extensionStr.empty()) + if( extensionStr.empty() ) + { return true; + } if( extensionStr.size() > 1 ) { @@ -88,7 +89,9 @@ void UnincludedReporter::printFiles( ) const { if( _files.isEmpty() ) + { return; + } _stream << resources::unincluded_report::Header; @@ -123,5 +126,4 @@ void UnincludedReporter::printFiles( //------------------------------------------------------------------------------ - } diff --git a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp index 907e517..9106350 100644 --- a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp +++ b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp @@ -19,12 +19,10 @@ namespace reporter { class UnincludedReporter final : public BaseReporterImpl { - using BaseClass = BaseReporterImpl; public: - - explicit UnincludedReporter( SettingsPtr && _settingPtr ); + explicit UnincludedReporter( SettingsPtr && _settingsPtr ); void report( const model_includes::Model & _model, @@ -34,7 +32,6 @@ class UnincludedReporter final : public BaseReporterImpl ReporterKind getKind() const override; private: - using Path = stdfs::path; using FilesContainer = SortedFilesByNameContainer; @@ -52,4 +49,3 @@ class UnincludedReporter final : public BaseReporterImpl //------------------------------------------------------------------------------ } - diff --git a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp index 5ec150e..0f4b23c 100644 --- a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp +++ b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp @@ -1,25 +1,25 @@ #include "reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp" #include "reporter/api/enums/rp_reporter_kind.hpp" -#include "reporter/resources/rp_unresolved_report_resources.hpp" -#include "reporter/resources/rp_report_resources.hpp" #include "reporter/impl/tools/rp_file_sorter.hpp" -#include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" -#include "reporter/impl/tools/rp_file_with_count_container.hpp" #include "reporter/impl/tools/rp_file_with_count.hpp" +#include "reporter/impl/tools/rp_file_with_count_container.hpp" +#include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" +#include "reporter/resources/rp_report_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" -#include "model_includes/api/mi_model.hpp" +#include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/mi_file.hpp" #include "model_includes/api/mi_include.hpp" #include "model_includes/api/mi_include_location.hpp" -#include "model_includes/api/enums/mi_include_status.hpp" +#include "model_includes/api/mi_model.hpp" #include "exception/ih/exc_internal_error.hpp" #include -#include #include +#include #include #include #include @@ -33,7 +33,6 @@ namespace reporter { UnresolvedReporter::UnresolvedReporter( SettingsPtr && _settingsPtr ) : BaseClass{ std::move( _settingsPtr ) } { - } //------------------------------------------------------------------------------ @@ -116,7 +115,9 @@ void UnresolvedReporter::report( using namespace model_includes; if( _unorderedIncludesByDestination.empty() ) + { return; + } _stream << resources::unresolved_report::Header; @@ -134,7 +135,7 @@ void UnresolvedReporter::report( reportDestinationFile( destinationFile, currentNumber, _projectDir, _stream ); - if( !_unorderedIncludesByDestination.count( &destinationFile ) ) + if( _unorderedIncludesByDestination.count( &destinationFile ) == 0U ) { INTERNAL_CHECK_WARRING( false ); continue; @@ -145,7 +146,6 @@ void UnresolvedReporter::report( reportSourceFiles( includes, _projectDir, _stream ); ++currentNumber; - } } @@ -189,8 +189,10 @@ void UnresolvedReporter::reportSourceFiles( } INTERNAL_CHECK_WARRING( includePtr ); - if( !includePtr ) + if( includePtr == nullptr ) + { continue; + } reportSourceFile( *includePtr, currentNumber, _projectDir, _stream ); ++currentNumber; @@ -239,8 +241,10 @@ bool UnresolvedReporter::isUnresolvedInclude( static_assert( static_cast< int >( IncludeStatus::Count ) == 2 ); switch( status ) { - case IncludeStatus::Resolved : return false; - case IncludeStatus::Unresolved : return true; + case IncludeStatus::Resolved: + return false; + case IncludeStatus::Unresolved: + return true; default: INTERNAL_CHECK_WARRING( false ); return false; diff --git a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp index 7820b60..111f4d5 100644 --- a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp +++ b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp @@ -22,7 +22,6 @@ class UnresolvedReporter final : public BaseReporterImpl using BaseClass = BaseReporterImpl; public: - explicit UnresolvedReporter( SettingsPtr && _settingsPtr ); void report( @@ -33,7 +32,6 @@ class UnresolvedReporter final : public BaseReporterImpl ReporterKind getKind() const override; private: - using UnorderedIncludes = stdfwd::vector< const model_includes::Include * >; using OrderedIncludes = stdfwd::set< const model_includes::Include *, diff --git a/src/reporter/resources/rp_unresolved_report_resources.cpp b/src/reporter/resources/rp_unresolved_report_resources.cpp index 42fc00f..d268eff 100644 --- a/src/reporter/resources/rp_unresolved_report_resources.cpp +++ b/src/reporter/resources/rp_unresolved_report_resources.cpp @@ -17,4 +17,3 @@ namespace reporter::resources::unresolved_report { //------------------------------------------------------------------------------ } - diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp index 84cc9f8..d8668bb 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp @@ -6,17 +6,17 @@ #include "reporter/api/rp_reporter.hpp" #include "reporter/api/rp_settings.hpp" -#include "model_includes/ih/mi_accessor_impl.hpp" -#include "model_includes/api/mi_model.hpp" #include "model_includes/api/enums/mi_file_type.hpp" +#include "model_includes/api/mi_model.hpp" +#include "model_includes/ih/mi_accessor_impl.hpp" #include "tools/path_string_tools.hpp" #include "exception/ih/exc_internal_error.hpp" -#include #include #include +#include //------------------------------------------------------------------------------ @@ -220,7 +220,9 @@ std::string ReporterFixture::runReporter( Reporter & _reporter ) ReporterAccessor & ReporterFixture::ensureReportAccessor() { if( !m_accessor ) - m_accessor.reset( new ReporterAccessorImpl ); + { + m_accessor = std::make_unique< ReporterAccessorImpl >(); + } return *m_accessor; } @@ -250,7 +252,9 @@ Settings & ReporterFixture::ensureSettings() model_includes::ModelIncludesAccessor & ReporterFixture::getModelAccessor() { if( !m_modelAccessor ) - m_modelAccessor.reset( new model_includes::ModelIncludesAccessorImpl ); + { + m_modelAccessor = std::make_unique< model_includes::ModelIncludesAccessorImpl >(); + } return *m_modelAccessor; } diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp index 51ce94b..cd471e5 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp @@ -1,11 +1,11 @@ #pragma once +#include "model_includes/api/enums/mi_file_type.hpp" #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" -#include "model_includes/api/enums/mi_file_type.hpp" -#include #include +#include //------------------------------------------------------------------------------ @@ -33,7 +33,6 @@ namespace reporter::test { class ReporterFixture { public: - ReporterFixture(); ~ReporterFixture(); @@ -88,12 +87,11 @@ class ReporterFixture model_includes::FileType _type = FileType::ProjectFile ); - model_includes::File & addFileToProject( std::string_view _file ); + model_includes::File & addFileToProject( std::string_view _file ); static std::string toPath( std::string_view _str ); private: - ReporterAccessor & ensureReportAccessor(); Factory & getFactory(); Settings & ensureSettings(); @@ -104,7 +102,6 @@ class ReporterFixture model_includes::Model & getModel(); private: - std::unique_ptr< ReporterAccessor > m_accessor; std::unique_ptr< Settings > m_settings; std::unique_ptr< model_includes::ModelIncludesAccessor > m_modelAccessor; diff --git a/src/reporter/test/reporter_test_main.cpp b/src/reporter/test/reporter_test_main.cpp index be8aff3..694cf27 100644 --- a/src/reporter/test/reporter_test_main.cpp +++ b/src/reporter/test/reporter_test_main.cpp @@ -1,9 +1,10 @@ #include "test_tools/boost_macroses.hpp" +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) #define BOOST_TEST_MODULE reporter_test #include -int main(int argc, char* argv[]) +int main( int argc, char * argv[] ) { - return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); + return boost::unit_test::unit_test_main( &init_unit_test, argc, argv ); } diff --git a/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp index b08f437..f62a22e 100644 --- a/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp +++ b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -23,12 +23,12 @@ TEST PLAN: namespace reporter::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(DifferentTypeReporterTests, ReporterFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( DifferentTypeReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty) +TEST_CASE( t1_empty ) { // Run const std::string result = runDifferentTypeReport(); @@ -39,7 +39,7 @@ BOOST_AUTO_TEST_CASE(t1_empty) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_one_include) +TEST_CASE( t2_one_include ) { // Init addInclude( "/test_project/main.cpp", "/test_project/header.hpp" ); @@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(t2_one_include) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_1_several_includes_with_user_type) +TEST_CASE( t3_1_several_includes_with_user_type ) { // Init addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); @@ -68,7 +68,7 @@ BOOST_AUTO_TEST_CASE(t3_1_several_includes_with_user_type) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_2_several_includes_with_system_type) +TEST_CASE( t3_2_several_includes_with_system_type ) { // Init addSystemInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); @@ -83,13 +83,13 @@ BOOST_AUTO_TEST_CASE(t3_2_several_includes_with_system_type) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_several_includes_system_and_user) +TEST_CASE( t4_1_several_includes_system_and_user ) { // Init setProjectDir( "/test_project/" ); - addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); - addSystemInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); + addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); // Run const std::string result = runDifferentTypeReport(); @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(t4_1_several_includes_system_and_user) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_2_several_includes_std) +TEST_CASE( t4_2_several_includes_std ) { // Init setProjectDir( "/test_project/" ); @@ -135,15 +135,15 @@ BOOST_AUTO_TEST_CASE(t4_2_several_includes_std) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_3_several_includes_hide_std) +TEST_CASE( t4_3_several_includes_hide_std ) { // Init setProjectDir( "/test_project/" ); addFile( "vector", model_includes::FileType::StdLibraryFile ); - addUserInclude( "/test_project/file1.cpp", "vector" ); - addSystemInclude( "/test_project/file2.cpp", "vector" ); + addUserInclude( "/test_project/file1.cpp", "vector" ); + addSystemInclude( "/test_project/file2.cpp", "vector" ); setShowStdFiles( false ); @@ -156,16 +156,16 @@ BOOST_AUTO_TEST_CASE(t4_3_several_includes_hide_std) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_limit_max_files) +TEST_CASE( t5_1_limit_max_files ) { // Init setProjectDir( "/test_project/" ); - addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); - addSystemInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); + addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); - addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); - addSystemInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); + addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); setMaxFilesCount( 1 ); @@ -187,21 +187,20 @@ BOOST_AUTO_TEST_CASE(t5_1_limit_max_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_limit_max_details) +TEST_CASE( t5_2_limit_max_details ) { // Init setProjectDir( "/test_project/" ); - addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); - addUserInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); - addSystemInclude( "/test_project/file3.cpp", "/test_project/header1.hpp" ); - addSystemInclude( "/test_project/file4.cpp", "/test_project/header1.hpp" ); - - addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); - addUserInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); - addSystemInclude( "/test_project/file3.cpp", "/test_project/header2.hpp" ); - addSystemInclude( "/test_project/file4.cpp", "/test_project/header2.hpp" ); + addUserInclude( "/test_project/file1.cpp", "/test_project/header1.hpp" ); + addUserInclude( "/test_project/file2.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file3.cpp", "/test_project/header1.hpp" ); + addSystemInclude( "/test_project/file4.cpp", "/test_project/header1.hpp" ); + addUserInclude( "/test_project/file1.cpp", "/test_project/header2.hpp" ); + addUserInclude( "/test_project/file2.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file3.cpp", "/test_project/header2.hpp" ); + addSystemInclude( "/test_project/file4.cpp", "/test_project/header2.hpp" ); setMaxDetailsCount( 1 ); @@ -231,7 +230,7 @@ BOOST_AUTO_TEST_CASE(t5_2_limit_max_details) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp b/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp index d21a4a9..b364f7f 100644 --- a/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -15,12 +15,12 @@ TEST PLAN: namespace reporter::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(DumpReporterTests, ReporterFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( DumpReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_includes) +TEST_CASE( t1_includes ) { // Init const std::string classA = toPath( "/test_project/class_a.hpp" ); @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(t1_includes) addInclude( main, classA, IncludeStatus::Resolved, IncludeType::User ); addInclude( main, classB, IncludeStatus::Resolved, IncludeType::User ); - + // Run std::string result = runDumpReporter(); @@ -50,7 +50,7 @@ BOOST_AUTO_TEST_CASE(t1_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_unresolved_includes) +TEST_CASE( t2_unresolved_includes ) { // Init const std::string classA = "class_a.hpp"; @@ -81,7 +81,7 @@ BOOST_AUTO_TEST_CASE(t2_unresolved_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_system_includes) +TEST_CASE( t3_system_includes ) { // Init const std::string main = toPath( "/test_project/main.cpp" ); @@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(t3_system_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_relative_paths) +TEST_CASE( t4_relative_paths ) { // Init const std::string classA = toPath( "/test_project/class_a.hpp" ); @@ -124,7 +124,8 @@ BOOST_AUTO_TEST_CASE(t4_relative_paths) std::string result = runDumpReporter(); // Check - BOOST_CHECK_EQUAL( result, + BOOST_CHECK_EQUAL( + result, "1 : class_a.hpp ( type: project file )\n" "\tIncluded by:\n" "\t\t1 : main.cpp ( type : user include status : resolved )\n" @@ -140,7 +141,7 @@ BOOST_AUTO_TEST_CASE(t4_relative_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp index 17d69b6..62a84bd 100644 --- a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp @@ -1,8 +1,8 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" -#include +#include /*------------------------------------------------------------------------------ @@ -29,12 +29,12 @@ TEST PLAN: namespace reporter::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(MostImpactReporterTests, ReporterFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( MostImpactReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty) +TEST_CASE( t1_empty ) { // Run std::string result = runMostImpactReporter(); @@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE(t1_empty) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_only_cpp_files) +TEST_CASE( t2_only_cpp_files ) { // Init const std::string classAFile = "/test_project/classA.hpp"; @@ -80,7 +80,7 @@ BOOST_AUTO_TEST_CASE(t2_only_cpp_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_files_with_same_count) +TEST_CASE( t3_files_with_same_count ) { // Init const std::string classAFile = "/test_project/classA.hpp"; @@ -118,28 +118,28 @@ BOOST_AUTO_TEST_CASE(t3_files_with_same_count) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_several_details) +TEST_CASE( t4_several_details ) { // Init const std::string classABaseFile = "/test_project/classABase.hpp"; - const std::string classAFile = "/test_project/classA.hpp"; - const std::string runA1file = "/test_project/runA1.cpp"; - const std::string runA2file = "/test_project/runA2.cpp"; + const std::string classAFile = "/test_project/classA.hpp"; + const std::string runA1file = "/test_project/runA1.cpp"; + const std::string runA2file = "/test_project/runA2.cpp"; const std::string classBBaseFile = "/test_project/classBBase.hpp"; - const std::string classBSubBaseFile = "/test_project/classBSubBase.hpp"; - const std::string classBFile = "/test_project/classB.hpp"; - const std::string runB1file = "/test_project/runB1.cpp"; - const std::string runB2file = "/test_project/runB2.cpp"; + const std::string classBSubBaseFile = "/test_project/classBSubBase.hpp"; + const std::string classBFile = "/test_project/classB.hpp"; + const std::string runB1file = "/test_project/runB1.cpp"; + const std::string runB2file = "/test_project/runB2.cpp"; addInclude( classAFile, classABaseFile ); - addInclude( runA1file, classAFile ); - addInclude( runA2file, classAFile ); + addInclude( runA1file, classAFile ); + addInclude( runA2file, classAFile ); addInclude( classBSubBaseFile, classBBaseFile ); - addInclude( classBFile, classBSubBaseFile ); - addInclude( runB1file, classBFile ); - addInclude( runB2file, classBFile ); + addInclude( classBFile, classBSubBaseFile ); + addInclude( runB1file, classBFile ); + addInclude( runB2file, classBFile ); // Run std::string result = runMostImpactReporter(); @@ -171,10 +171,10 @@ BOOST_AUTO_TEST_CASE(t4_several_details) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_1_limit_max_files) +TEST_CASE( t5_1_limit_max_files ) { // Init - const std::string sourceFileFmt = "/test_project/class{}.cpp"; + const std::string sourceFileFmt = "/test_project/class{}.cpp"; const std::string destinationFileFmt = "/test_project/class{}.hpp"; const int filesCount = 10; @@ -218,25 +218,25 @@ BOOST_AUTO_TEST_CASE(t5_1_limit_max_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_2_limit_max_details) +TEST_CASE( t5_2_limit_max_details ) { // Init const std::string classBaseFile = "/test_project/classBase.hpp"; - const std::string classAFile = "/test_project/classA.hpp"; - const std::string runA1file = "/test_project/runA1.cpp"; - const std::string runA2file = "/test_project/runA2.cpp"; + const std::string classAFile = "/test_project/classA.hpp"; + const std::string runA1file = "/test_project/runA1.cpp"; + const std::string runA2file = "/test_project/runA2.cpp"; - const std::string classBFile = "/test_project/classB.hpp"; - const std::string runB1file = "/test_project/runB1.cpp"; - const std::string runB2file = "/test_project/runB2.cpp"; + const std::string classBFile = "/test_project/classB.hpp"; + const std::string runB1file = "/test_project/runB1.cpp"; + const std::string runB2file = "/test_project/runB2.cpp"; addInclude( classAFile, classBaseFile ); - addInclude( runA1file, classAFile ); - addInclude( runA2file, classAFile ); + addInclude( runA1file, classAFile ); + addInclude( runA2file, classAFile ); addInclude( classBFile, classBaseFile ); - addInclude( runB1file, classBFile ); - addInclude( runB2file, classBFile ); + addInclude( runB1file, classBFile ); + addInclude( runB2file, classBFile ); setMaxDetailsCount( 1 ); @@ -264,10 +264,10 @@ BOOST_AUTO_TEST_CASE(t5_2_limit_max_details) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_3_limit_equal_to_files_number) +TEST_CASE( t5_3_limit_equal_to_files_number ) { // Init - const std::string sourceFileFmt = "/test_project/class{}.cpp"; + const std::string sourceFileFmt = "/test_project/class{}.cpp"; const std::string destinationFileFmt = "/test_project/class{}.hpp"; const int filesCount = 10; @@ -309,25 +309,25 @@ BOOST_AUTO_TEST_CASE(t5_3_limit_equal_to_files_number) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_4_limit_to_equal_details_number) +TEST_CASE( t5_4_limit_to_equal_details_number ) { // Init const std::string classBaseFile = "/test_project/classBase.hpp"; - const std::string classAFile = "/test_project/classA.hpp"; - const std::string runA1file = "/test_project/runA1.cpp"; - const std::string runA2file = "/test_project/runA2.cpp"; + const std::string classAFile = "/test_project/classA.hpp"; + const std::string runA1file = "/test_project/runA1.cpp"; + const std::string runA2file = "/test_project/runA2.cpp"; - const std::string classBFile = "/test_project/classB.hpp"; - const std::string runB1file = "/test_project/runB1.cpp"; - const std::string runB2file = "/test_project/runB2.cpp"; + const std::string classBFile = "/test_project/classB.hpp"; + const std::string runB1file = "/test_project/runB1.cpp"; + const std::string runB2file = "/test_project/runB2.cpp"; addInclude( classAFile, classBaseFile ); - addInclude( runA1file, classAFile ); - addInclude( runA2file, classAFile ); + addInclude( runA1file, classAFile ); + addInclude( runA2file, classAFile ); addInclude( classBFile, classBaseFile ); - addInclude( runB1file, classBFile ); - addInclude( runB2file, classBFile ); + addInclude( runB1file, classBFile ); + addInclude( runB2file, classBFile ); setMaxDetailsCount( 2 ); @@ -355,7 +355,7 @@ BOOST_AUTO_TEST_CASE(t5_4_limit_to_equal_details_number) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t6_relevant_pants) +TEST_CASE( t6_relevant_pants ) { // Init const std::string projectDir = "/test_project/"; @@ -399,10 +399,10 @@ BOOST_AUTO_TEST_CASE(t6_relevant_pants) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_1_std_file_dont_show) +TEST_CASE( t7_1_std_file_dont_show ) { // Init - const std::string stdFile = "vector"; + const std::string stdFile = "vector"; const std::string classAFile = "/test_project/classA.hpp"; const std::string classBFile = "/test_project/classB.hpp"; @@ -443,10 +443,10 @@ BOOST_AUTO_TEST_CASE(t7_1_std_file_dont_show) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t7_2_std_file_show) +TEST_CASE( t7_2_std_file_show ) { // Init - const std::string stdFile = "vector"; + const std::string stdFile = "vector"; const std::string classAFile = "/test_project/classA.hpp"; const std::string classBFile = "/test_project/classB.hpp"; @@ -491,7 +491,7 @@ BOOST_AUTO_TEST_CASE(t7_2_std_file_show) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_1_files_out_of_project_in_subdir) +TEST_CASE( t8_1_files_out_of_project_in_subdir ) { // Init const std::string projectDir = "/test_project/"; @@ -536,7 +536,7 @@ BOOST_AUTO_TEST_CASE(t8_1_files_out_of_project_in_subdir) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t8_2_files_out_of_project_in_other_dir) +TEST_CASE( t8_2_files_out_of_project_in_other_dir ) { // Init const std::string projectDir = "/test_project/"; @@ -581,7 +581,7 @@ BOOST_AUTO_TEST_CASE(t8_2_files_out_of_project_in_other_dir) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp index bea461c..956b433 100644 --- a/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -20,12 +20,12 @@ TEST PLAN: namespace reporter::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(UnincludedReporterTests, ReporterFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( UnincludedReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_empty) +TEST_CASE( t1_empty ) { // Init addInclude( "/test_project/main.cpp", "/test_project/classA.hpp" ); @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(t1_empty) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_one_header) +TEST_CASE( t2_one_header ) { // Init setProjectDir( "/tmp/" ); @@ -61,7 +61,7 @@ BOOST_AUTO_TEST_CASE(t2_one_header) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_several_headers) +TEST_CASE( t3_several_headers ) { // Init setProjectDir( "/tmp/" ); @@ -86,7 +86,7 @@ BOOST_AUTO_TEST_CASE(t3_several_headers) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_extension_hpp) +TEST_CASE( t4_1_extension_hpp ) { // Init setProjectDir( "/tmp/" ); @@ -107,7 +107,7 @@ BOOST_AUTO_TEST_CASE(t4_1_extension_hpp) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_2_extension_h) +TEST_CASE( t4_2_extension_h ) { // Init setProjectDir( "/tmp/" ); @@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(t4_2_extension_h) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_3_mix_extensions) +TEST_CASE( t4_3_mix_extensions ) { // Init setProjectDir( "/tmp/" ); @@ -151,7 +151,7 @@ BOOST_AUTO_TEST_CASE(t4_3_mix_extensions) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_4_empty_extension) +TEST_CASE( t4_4_empty_extension ) { // Init addFileToProject( "main.cpp" ); @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(t4_4_empty_extension) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_limit) +TEST_CASE( t5_limit ) { // Init setProjectDir( "/tmp/" ); @@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE(t5_limit) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp b/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp index 6aeb099..b007642 100644 --- a/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp +++ b/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include +#include "test_tools/test_macros.hpp" /*------------------------------------------------------------------------------ @@ -20,12 +20,12 @@ TEST PLAN: namespace reporter::test { //------------------------------------------------------------------------------ - -BOOST_FIXTURE_TEST_SUITE(UnresolvedReporterTests, ReporterFixture) +// clazy:excludeall=non-pod-global-static +TEST_GROUP_NAME( UnresolvedReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t1_model_not_have_unresolved_includes) +TEST_CASE( t1_model_not_have_unresolved_includes ) { // Init addInclude( "/test_project/main.cpp", "/test_project/classA.hpp" ); @@ -40,7 +40,7 @@ BOOST_AUTO_TEST_CASE(t1_model_not_have_unresolved_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t2_several_includes) +TEST_CASE( t2_several_includes ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(t2_several_includes) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t3_relative_paths) +TEST_CASE( t3_relative_paths ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(t3_relative_paths) const std::string classAFileName = "classA.hpp"; const std::string classAFile = projectDir + classAFileName; const std::string classBFileName = "classB.hpp"; - const std::string classBFile = projectDir + classBFileName;; + const std::string classBFile = projectDir + classBFileName; const std::string runA1fileName = "runA1.cpp"; const std::string runA1file = projectDir + runA1fileName; @@ -126,7 +126,7 @@ BOOST_AUTO_TEST_CASE(t3_relative_paths) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_1_limit_max_files) +TEST_CASE( t4_1_limit_max_files ) { // Init const int limit = 1; @@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE(t4_1_limit_max_files) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_2_limit_max_details) +TEST_CASE( t4_2_limit_max_details ) { // Init const int limit = 1; @@ -194,7 +194,7 @@ BOOST_AUTO_TEST_CASE(t4_2_limit_max_details) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_3_limit_equal_to_files_count) +TEST_CASE( t4_3_limit_equal_to_files_count ) { // Init const int limit = 2; @@ -234,7 +234,7 @@ BOOST_AUTO_TEST_CASE(t4_3_limit_equal_to_files_count) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t4_4_limit_equal_to_details_count) +TEST_CASE( t4_4_limit_equal_to_details_count ) { // Init const int limit = 2; @@ -264,7 +264,7 @@ BOOST_AUTO_TEST_CASE(t4_4_limit_equal_to_details_count) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_CASE(t5_ordering) +TEST_CASE( t5_ordering ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -315,7 +315,7 @@ BOOST_AUTO_TEST_CASE(t5_ordering) //------------------------------------------------------------------------------ -BOOST_AUTO_TEST_SUITE_END() +TEST_GROUP_END //------------------------------------------------------------------------------ diff --git a/src/reporter/tools/rp_reporter_kind_functins.cpp b/src/reporter/tools/rp_reporter_kind_functins.cpp index 4910293..3b0866d 100644 --- a/src/reporter/tools/rp_reporter_kind_functins.cpp +++ b/src/reporter/tools/rp_reporter_kind_functins.cpp @@ -2,18 +2,18 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" +#include "reporter/resources/rp_different_type_report_resources.hpp" +#include "reporter/resources/rp_dump_resources.hpp" #include "reporter/resources/rp_most_impact_report_resources.hpp" -#include "reporter/resources/rp_unresolved_report_resources.hpp" #include "reporter/resources/rp_unincluded_report_resources.hpp" -#include "reporter/resources/rp_dump_resources.hpp" -#include "reporter/resources/rp_different_type_report_resources.hpp" +#include "reporter/resources/rp_unresolved_report_resources.hpp" #include "reporter/exceptions/rp_incorrect_report_impl.hpp" #include "exception/ih/exc_internal_error.hpp" -#include #include +#include #include //------------------------------------------------------------------------------ @@ -26,7 +26,8 @@ ReporterKind toReporterKind( std::string_view _str ) { using namespace resources; - static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + constexpr int ReporterKindCount = 5; + static_assert( static_cast< int >( ReporterKind::Count ) == ReporterKindCount ); static std::unordered_map< std::string, reporter::ReporterKind > names{ { unresolved_report::Name, ReporterKind::Unresolved }, @@ -37,12 +38,12 @@ ReporterKind toReporterKind( std::string_view _str ) }; const std::string str{ _str }; - if( !names.count( str ) ) + if( names.count( str ) == 0U ) { throw IncorrectReportImpl( str ); } - return names[ str ]; + return names[str]; } //------------------------------------------------------------------------------ @@ -51,7 +52,8 @@ std::string reporterKindToString( ReporterKind _kind ) { using namespace resources; - static_assert( static_cast< int >( ReporterKind::Count ) == 5 ); + constexpr int ReporterKindCount = 5; + static_assert( static_cast< int >( ReporterKind::Count ) == ReporterKindCount ); switch( _kind ) { diff --git a/src/test_tools/boost_predicate_wrapper.cpp b/src/test_tools/boost_predicate_wrapper.cpp index 7bd900c..c7d6d09 100644 --- a/src/test_tools/boost_predicate_wrapper.cpp +++ b/src/test_tools/boost_predicate_wrapper.cpp @@ -6,8 +6,8 @@ namespace tools { //------------------------------------------------------------------------------ -BoostPredicateWrapper::BoostPredicateWrapper( bool ) - : m_message{ "" } +BoostPredicateWrapper::BoostPredicateWrapper( bool _result ) + : m_message{ _result ? "" : "error" } { } @@ -20,8 +20,8 @@ BoostPredicateWrapper::BoostPredicateWrapper( std::string_view _message ) //------------------------------------------------------------------------------ -BoostPredicateWrapper::BoostPredicateWrapper( const std::string & _message ) - : m_message{ _message } +BoostPredicateWrapper::BoostPredicateWrapper( std::string _message ) + : m_message{ std::move( _message ) } { } diff --git a/src/test_tools/boost_predicate_wrapper.hpp b/src/test_tools/boost_predicate_wrapper.hpp index 887ca23..68e513b 100644 --- a/src/test_tools/boost_predicate_wrapper.hpp +++ b/src/test_tools/boost_predicate_wrapper.hpp @@ -13,15 +13,13 @@ namespace tools { class BoostPredicateWrapper { public: - BoostPredicateWrapper( bool _result ); BoostPredicateWrapper( std::string_view _message ); - BoostPredicateWrapper( const std::string & _message ); + BoostPredicateWrapper( std::string _message ); operator ::boost::test_tools::assertion_result() const; private: - std::string m_message; }; diff --git a/src/test_tools/test_macros.hpp b/src/test_tools/test_macros.hpp new file mode 100644 index 0000000..d85c2eb --- /dev/null +++ b/src/test_tools/test_macros.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include + +#define TEST_GROUP_NAME( testGroup, testFixture ) \ + BOOST_FIXTURE_TEST_SUITE( testGroup, testFixture ) // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) + +#define TEST_GROUP_END \ + BOOST_AUTO_TEST_SUITE_END() // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) + +#define TEST_CASE( caseName ) \ + BOOST_AUTO_TEST_CASE( caseName ) // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) + +#define TEST_CHECK( conditional ) \ + BOOST_CHECK( conditional ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + +#define TEST_REQUIRE( conditional ) \ + BOOST_REQUIRE( conditional ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + +#define TEST_CHECK_EQUAL( L, R ) \ + BOOST_CHECK_EQUAL( L, R ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + +#define TEST_CHECK_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) \ + BOOST_CHECK_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + +#define TEST_REQUIRE_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) \ + BOOST_REQUIRE_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) + +#define TEST_CHECK_THROW( S, E ) \ + BOOST_CHECK_THROW( S, E ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) diff --git a/src/tools/path_string_tools.cpp b/src/tools/path_string_tools.cpp index 01d72ef..e893bb0 100644 --- a/src/tools/path_string_tools.cpp +++ b/src/tools/path_string_tools.cpp @@ -11,9 +11,9 @@ namespace tools { std::string toPath( const std::string & _originStr ) { #ifdef _WIN32 - return toWindowsPath( _originStr ); + return toWindowsPath( _originStr ); #else - return toUnixPath( _originStr ); + return toUnixPath( _originStr ); #endif } @@ -21,38 +21,30 @@ std::string toPath( const std::string & _originStr ) std::string toUnixPath( const std::string & _originStr ) { - return changeSeperatorInPath( _originStr, '\\', '/' ); + return changeSeperatorInPath( _originStr, '\\', '/' ); } - //------------------------------------------------------------------------------ std::string toWindowsPath( const std::string & _originStr ) { - return changeSeperatorInPath( _originStr, '/', '\\' ); + return changeSeperatorInPath( _originStr, '/', '\\' ); } //------------------------------------------------------------------------------ std::string changeSeperatorInPath( - const std::string & _originStr, - char _oldSeperator, - char _newSeperator -) + const std::string & _originStr, char _oldSeperator, char _newSeperator ) { - std::string result{ _originStr }; + std::string result{ _originStr }; - std::replace_if( - result.begin(), - result.end(), - [&]( char _c ){ return _c == _oldSeperator; }, - _newSeperator - ); + std::replace_if( + result.begin(), result.end(), + [&]( char _c ) { return _c == _oldSeperator; }, _newSeperator ); - return result; + return result; } - //------------------------------------------------------------------------------ } diff --git a/src/tools/path_string_tools.hpp b/src/tools/path_string_tools.hpp index 3748975..14f3945 100644 --- a/src/tools/path_string_tools.hpp +++ b/src/tools/path_string_tools.hpp @@ -14,9 +14,9 @@ std::string toUnixPath( const std::string & _originStr ); std::string toWindowsPath( const std::string & _originStr ); std::string changeSeperatorInPath( - const std::string & _originStr, - char _oldSeperator, - char _newSeperator + const std::string & _originStr, + char _oldSeperator, + char _newSeperator ); //------------------------------------------------------------------------------ diff --git a/src/tools/regex.cpp b/src/tools/regex.cpp index f13665d..20b151e 100644 --- a/src/tools/regex.cpp +++ b/src/tools/regex.cpp @@ -10,17 +10,11 @@ Regex::Regex( const std::string & _str ) : m_regex{ _str } , m_str{ _str } { - } //------------------------------------------------------------------------------ -Regex::Regex( const Regex & _other ) - : m_regex{ _other.m_regex } - , m_str{ _other.m_str } -{ - -} +Regex::Regex( const Regex & _other ) = default; //------------------------------------------------------------------------------ diff --git a/src/tools/regex.hpp b/src/tools/regex.hpp index d2ca623..e894020 100644 --- a/src/tools/regex.hpp +++ b/src/tools/regex.hpp @@ -11,7 +11,6 @@ namespace tools { class Regex { public: - explicit Regex( const std::string & _str ); Regex( const Regex & _other ); @@ -20,10 +19,8 @@ class Regex const std::string & toString() const; private: - const std::regex m_regex; const std::string m_str; - }; //------------------------------------------------------------------------------ From 0965fd777871c8b1b355d5ac945e229071022964 Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Sun, 11 Apr 2021 02:44:50 +0300 Subject: [PATCH 3/6] Added icon. Fixed .clang-tidy Fixed README --- .clang-tidy | 51 +------------------- README.md | 115 ++++++++++++++++++++++++-------------------- docs/icons/icon.svg | 16 ++++++ 3 files changed, 80 insertions(+), 102 deletions(-) create mode 100644 docs/icons/icon.svg diff --git a/.clang-tidy b/.clang-tidy index 77841e7..e5ac4a6 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,49 +1,2 @@ ---- -AccessModifierOffset: '-4' -AlignAfterOpenBracket: AlwaysBreak -AlignConsecutiveMacros: 'true' -AlignEscapedNewlines: Left -AlignTrailingComments: 'true' -AllowAllArgumentsOnNextLine: 'false' -AllowAllParametersOfDeclarationOnNextLine: 'true' -AllowShortBlocksOnASingleLine: 'false' -AllowShortCaseLabelsOnASingleLine: 'false' -AllowShortFunctionsOnASingleLine: None -AllowShortIfStatementsOnASingleLine: Never -AllowShortLoopsOnASingleLine: 'false' -AlwaysBreakAfterDefinitionReturnType: None -AlwaysBreakAfterReturnType: None -BinPackParameters: 'false' -BreakBeforeBraces: Allman -BreakConstructorInitializers: BeforeComma -BreakInheritanceList: BeforeComma -CompactNamespaces: 'false' -ExperimentalAutoDetectBinPacking: 'false' -FixNamespaceComments: 'false' -IndentCaseLabels: 'true' -IndentPPDirectives: BeforeHash -IndentWidth: '4' -KeepEmptyLinesAtTheStartOfBlocks: 'false' -Language: Cpp -MaxEmptyLinesToKeep: '1' -PointerAlignment: Middle -SortUsingDeclarations: 'true' -SpaceAfterCStyleCast: 'false' -SpaceAfterLogicalNot: 'false' -SpaceAfterTemplateKeyword: 'false' -SpaceBeforeAssignmentOperators: 'true' -SpaceBeforeCpp11BracedList: 'false' -SpaceBeforeInheritanceColon: 'true' -SpaceBeforeParens: Never -SpaceBeforeRangeBasedForLoopColon: 'false' -SpaceInEmptyParentheses: 'false' -SpacesInAngles: 'true' -SpacesInCStyleCastParentheses: 'true' -SpacesInContainerLiterals: 'true' -SpacesInParentheses: 'true' -SpacesInSquareBrackets: 'false' -Standard: Cpp11 -TabWidth: '4' -UseTab: Always - -... +Checks: '-*,abseil-*,android-*,boost-*,bugprone-*,cert-*,clang-*,cppcoreguidelines-avoid-*,cppcoreguidelines-c-copy-assignment-signature,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-macro-usage,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-no-malloc,cppcoreguidelines-non-private-member-variables-in-classes,cppcoreguidelines-pro-bounds-constant-array-index,cppcoreguidelines-pro-bounds-pointer-arithmetic,cppcoreguidelines-pro-type-*,cppcoreguidelines-slicing,cppcoreguidelines-special-member-functions,darwin-*,fuchsia-header-anon-namespaces,fuchsia-multiple-inheritance,fuchsia-restrict-system-includes,fuchsia-statically-constructed-objects,fuchsia-trailing-return,fuchsia-virtual-inheritance,google-build-explicit-make-pair,google-build-namespaces,google-default-arguments,google-explicit-constructor,google-global-names-in-headers,google-objc-*,google-readability-braces-around-statements,google-readability-casting,google-readability-function-size,google-readability-todo,google-runtime-*,hicpp-avoid-*,hicpp-braces-around-statements,hicpp-deprecated-headers,hicpp-exception-baseclass,hicpp-explicit-conversions,hicpp-function-size,hicpp-invalid-access-moved,hicpp-member-init,hicpp-move-const-arg,hicpp-multiway-paths-covered,hicpp-named-parameter,hicpp-new-delete-operators,hicpp-no-assembler,hicpp-no-malloc,hicpp-noexcept-move,hicpp-signed-bitwise,hicpp-special-member-functions,hicpp-static-assert,hicpp-undelegated-constructor,hicpp-uppercase-literal-suffix,hicpp-use-*,hicpp-vararg,linuxkernel-*,llvm-header-guard,llvm-twine-local,misc-*,modernize-avoid-*,modernize-concat-nested-namespaces,modernize-deprecated-*,modernize-loop-convert,modernize-make-*,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-*,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-*,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,mpi-*,objc-*,openmp-*,performance-*,portability-*,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-const-return-type,readability-container-size-empty,readability-delete-null-pointer,readability-deleted-default,readability-else-after-return,readability-function-size,readability-identifier-naming,readability-implicit-bool-conversion,readability-inconsistent-declaration-parameter-name,readability-isolate-declaration,readability-magic-numbers,readability-misleading-indentation,readability-misplaced-array-index,readability-named-parameter,readability-non-const-parameter,readability-qualified-auto,readability-redundant-*,readability-simplify-*,readability-static-*,readability-string-compare,readability-uniqueptr-delete-release,readability-uppercase-literal-suffix,zircon-*' +FormatStyle: 'file' diff --git a/README.md b/README.md index 31b19ce..a220353 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # CPPINCLUDE Tool for analyzing includes in C++. -One of the problem in C++ is that if header file was changed all files that -include the file will be recompiled and sometime it takes a lot of time. +One of the problems in C++ is that if a header file was changed all files that +include that file will be recompiled and sometime it takes a lot of time. ## Table of Contents @@ -69,9 +69,10 @@ public: ``` -If file *char_kind.hpp* is changed all files that include *base_char_factory.hpp* -and *base_char.hpp* will be recompile and it will take time. This tool helps to find -file in top of include hierarchy: +If file *char_kind.hpp* is changed all files that +include *base_char_factory.hpp* and *base_char.hpp* will be recompiled and +it will take time. This tool helps to find the file at the top of +the include hierarchy: ``` cppinclude @@ -123,8 +124,8 @@ Name|Short description ### configuration_file -The tool read setting from *.cppinclude.json* in work directory or -you can set file in argument *configuration_file*. +The tool reads settings from *.cppinclude.json* located in the work directory or +you can pass a configuration file in the argument *configuration_file*. For example: `cppinclude --configuration_file=project.json` @@ -138,7 +139,7 @@ Path to generated *compile_commands.json* file by CMake with argument `cmake .. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON` -You can set path in configuration file: +You can set the path for the compile_command.json file in the configuration file: ```json { @@ -146,7 +147,7 @@ You can set path in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --compile_commands=build/compile_commands.json` @@ -154,9 +155,9 @@ or in arguments: ### project_dir -Path to folder with sources. Often source files are located in *src* or -*sources* folder, not in root folder of project. -You can set in configuration file: +PPath to a folder that contains sources. Often source files are located +in *src* or *sources* folder, not in the root folder of project. +You can set it in configuration file with: ```json { @@ -164,7 +165,7 @@ You can set in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --project_dir=src` @@ -172,8 +173,8 @@ or in arguments: ### file_extensions -If you use file extensions for C++ that aren’t in default values. You can set in -configuration file: +If you use other file extensions than default values *file_extensions* +for C++ sources you can specify them in the configuration file with: ```json { @@ -181,7 +182,7 @@ configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --file_extensions=*.cc,*hh` @@ -189,8 +190,8 @@ or in arguments: ### analyze_without_extension -Analyze files in project directory without extension, default: false. -You can set in configuration file: +Analyze files without extension in the project directory, default: false. +You can set this option in the configuration file with: ```json { @@ -198,7 +199,7 @@ You can set in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --analyze_without_extension=true` @@ -206,8 +207,8 @@ or in arguments: ### include_dirs -Add folders where search included files. Default value is project folder. -You can set in configuration file: +Add paths to the header search directories. Default value is project folder. +You can set it in the configuration file with: ```json { @@ -215,7 +216,7 @@ You can set in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --include_dirs=lib1,lib2` @@ -223,9 +224,10 @@ or in arguments: ### ignore_dirs -Folders that will be ignored during analyzing project’s files. -It can be third-party libraries that are located in project directory -but don't need to analyze. You can set in configuration file: +Folders to be ignored during project analysis. +For example: third-party libraries that are located under the project directory +but should not be analyzed. +You can set it in the configuration file with: ```json { @@ -233,7 +235,7 @@ but don't need to analyze. You can set in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --ignore_dirs=./3rd-part,gtest` @@ -242,7 +244,7 @@ or in arguments: ### ignore_system_includes Ignore includes with *\<\>*, example *#include \* will be ignored. -You can set in configuration file: +You can set it in the configuration file with: ```json { @@ -250,7 +252,7 @@ You can set in configuration file: } ``` -or in arguments: +or, pass as an argument: `cppinclude --ignore_system_includes=true` @@ -268,7 +270,7 @@ or generated files (*.gen). You can set in configuration file } ``` -or in arguments: +or, pass as an argument: `cppinclude --ignore_files=boost/.*,.*\\.def` @@ -278,18 +280,20 @@ or in arguments: Name of report. Possible values: -* *unresolved* -- show included files that are not found in project folder; +* *unresolved* -- show included files that are not found within the project folder; * *most_impact* -- show files that most impact on other files; * *unincluded* -- show unincluded headers; * *different_type* -- show headers that are included in #include <...> and #include "..." . +As arguments: + ``` cppinclude --report=unresolved cppinclude --report=most_impact cppinclude --report=unresolved,most_impact ``` -Also you can set in configuration file: +As a configuration file setting: ```json { @@ -301,9 +305,10 @@ Also you can set in configuration file: #### unresolved -Show files that are found in includes but didn't found in file system. -One of the resean is missing includes files, for example: -There is file *main.cpp*, folder *include* that store file *header.hpp* : +Show headers that are included but not found in the given search paths. +One possible reason is missing include files, for example: +iven a *main.cpp* file and a *include* folder that stores +the *header.hpp* header: ``` tree @@ -314,7 +319,7 @@ tree ``` -If run *cppinclude* result will be: +When *cppinclude* is run, the result will be: ``` cppinclude --report=unresolved @@ -327,7 +332,8 @@ Unresolved files: ``` -But if add folder *include* to *include_dirs* resultat will be empty: +Adding the *include* folder to *include_dirs* will remove the +unresolved files entry: ``` cppinclude --report=unresolved --include_dirs=include @@ -337,7 +343,7 @@ cppinclude --report=unresolved --include_dirs=include #### most_impact -Show how many files will be recompiled with header will be changed. +Show how many files will be recompiled when a given header is changed. Example from [docs/examples/simple_example/](docs/examples/simple_example/) ``` @@ -359,14 +365,17 @@ Included by: ... ``` -It means if file char_kind.hpp will be changed 11 files are recompiled. +The above output means that a change in char_kind.hpp will force 11 +files to recompile. [Back to top](#cppinclude) #### unincluded -Show files that are found in file system but didn't found in includes. -It often happens after refactoring when file that include header was deleted. +Show headers that are found in the search directories but that were not +included in the source code. +It often happens after refactoring when headers when include directives +were removed from code and thefiles remained in place. Example from [docs/examples/simple_example_with_unincluded_headers/](docs/examples/simple_example_with_unincluded_headers/) ``` @@ -382,18 +391,19 @@ Unincluded headers: **Limitations:** -* Header with same names: +* Headers with same names: -If headers have same name but are located in different folders will be found -only first header and other will be unincluded. -For example: *lib1/header.hpp*, *lib2/header.hpp* and -*main.cpp* : +If headers have the same name but are located in different paths only one +occurrence will be counted. +only first header and other will be unincluded. +For example: *lib1/header.hpp*, *lib2/header.hpp* and *main.cpp* : ```c++ #include "header.hpp" ... ``` -Result will be: + +The result will be: ``` cppinclude --include_dirs=lib1,lib2 --report=unincluded @@ -406,23 +416,22 @@ Unincluded headers: ``` -* Empty result for CMake project: +* Empty result for CMake project: -If analyze CMake project ( generated file compile_commands.json ) -result will be empty. Because in current implementation *cppinclude* analyze -source files on file system or files from compile_commands.json +The current implementation ignores CMake project files. +Only source files are analyzed currently that are either specified +in compile_commands.json or that are found on the filesystem. * Header files are files that have extension started with *h* letter -***All limitations will be fixed in future releases *** - +***All limitations will be fixed in future releases*** [Back to top](#cppinclude) #### different_type Show headers that are included in different ways. -It helps to follow code style in project, +It helps to follow code styles in project, for example include third party libraries in <...> and project header in "...". Example from [docs/examples/simple_example_for_different_type_report/](docs/examples/simple_example_for_different_type_report/) diff --git a/docs/icons/icon.svg b/docs/icons/icon.svg new file mode 100644 index 0000000..3ee835d --- /dev/null +++ b/docs/icons/icon.svg @@ -0,0 +1,16 @@ + + + + cppinclude + + + From e5d6f76d9a897e31dd54713be6e96af28e8825b9 Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Wed, 5 May 2021 03:44:06 +0300 Subject: [PATCH 4/6] Public version 0.4.0 --- .clang-tidy | 57 +- .gitlab-ci.yml | 62 +- CHANGELOG.md | 6 + CMakeLists.txt | 4 +- README.md | 21 +- docs/examples/cppinclude/output_unix.txt | 96 +- docs/examples/cppinclude/output_win.txt | 96 +- docs/versions/VERSION_0.4.0.md | 77 + src/3rd-part/cpp-std-fwd/stdfwd.hpp | 1286 ----------------- src/3rd-part/std_fs/include/std_fs | 3 - src/3rd-part/stdfwd/include/stdfwd.hh | 43 + src/3rd-part/stdfwd/include/stdfwd/array | 23 + src/3rd-part/stdfwd/include/stdfwd/atomic | 57 + src/3rd-part/stdfwd/include/stdfwd/bitset | 24 + src/3rd-part/stdfwd/include/stdfwd/chrono | 69 + src/3rd-part/stdfwd/include/stdfwd/clocale | 22 + src/3rd-part/stdfwd/include/stdfwd/complex | 21 + .../stdfwd/include/stdfwd/condition_variable | 38 + src/3rd-part/stdfwd/include/stdfwd/deque | 24 + src/3rd-part/stdfwd/include/stdfwd/exception | 24 + src/3rd-part/stdfwd/include/stdfwd/filesystem | 96 ++ .../stdfwd/include/stdfwd/forward_list | 24 + src/3rd-part/stdfwd/include/stdfwd/functional | 84 ++ src/3rd-part/stdfwd/include/stdfwd/future | 54 + .../stdfwd/include/stdfwd/initializer_list | 21 + src/3rd-part/stdfwd/include/stdfwd/iterator | 104 ++ src/3rd-part/stdfwd/include/stdfwd/list | 28 + src/3rd-part/stdfwd/include/stdfwd/locale | 157 ++ src/3rd-part/stdfwd/include/stdfwd/map | 42 + src/3rd-part/stdfwd/include/stdfwd/memory | 81 ++ src/3rd-part/stdfwd/include/stdfwd/mutex | 45 + src/3rd-part/stdfwd/include/stdfwd/new | 29 + src/3rd-part/stdfwd/include/stdfwd/optional | 34 + src/3rd-part/stdfwd/include/stdfwd/ptrdiff_t | 25 + src/3rd-part/stdfwd/include/stdfwd/queue | 44 + src/3rd-part/stdfwd/include/stdfwd/random | 191 +++ src/3rd-part/stdfwd/include/stdfwd/ratio | 80 + src/3rd-part/stdfwd/include/stdfwd/regex | 84 ++ .../stdfwd/include/stdfwd/scoped_allocator | 35 + src/3rd-part/stdfwd/include/stdfwd/set | 39 + .../stdfwd/include/stdfwd/shared_mutex | 28 + src/3rd-part/stdfwd/include/stdfwd/size_t | 25 + src/3rd-part/stdfwd/include/stdfwd/stack | 28 + src/3rd-part/stdfwd/include/stdfwd/std_fs | 101 ++ src/3rd-part/stdfwd/include/stdfwd/stdexcept | 36 + .../stdfwd/include/stdfwd/stdfwd_details.hpp | 111 ++ src/3rd-part/stdfwd/include/stdfwd/string | 73 + .../stdfwd/include/stdfwd/string_view | 63 + .../stdfwd/include/stdfwd/system_error | 49 + src/3rd-part/stdfwd/include/stdfwd/thread | 20 + src/3rd-part/stdfwd/include/stdfwd/tuple | 21 + .../stdfwd/include/stdfwd/type_traits | 33 + src/3rd-part/stdfwd/include/stdfwd/typeindex | 20 + src/3rd-part/stdfwd/include/stdfwd/typeinfo | 32 + .../stdfwd/include/stdfwd/unordered_map | 53 + .../stdfwd/include/stdfwd/unordered_set | 43 + src/3rd-part/stdfwd/include/stdfwd/utility | 27 + src/3rd-part/stdfwd/include/stdfwd/valarray | 44 + src/3rd-part/stdfwd/include/stdfwd/vector | 24 + src/application/app_con.hpp | 3 +- .../resources/app_resources_arguments.cpp | 18 +- .../resources/app_resources_arguments.hpp | 18 +- .../app_resources_configuration_file.cpp | 1 + .../app_resources_configuration_file.hpp | 1 + .../resources/app_resources_version.cpp | 4 +- ...app_test_cmake_project_builder_fixture.hpp | 5 +- .../app_test_configuration_file_fixture.cpp | 8 + .../app_test_configuration_file_fixture.hpp | 6 +- .../test/fixtures/app_test_parser_fixture.hpp | 6 +- .../app_test_parser_wrapper_fixture.cpp | 16 +- .../app_test_parser_wrapper_fixture.hpp | 9 +- .../app_test_project_builder_fixture.cpp | 2 + .../app_test_project_builder_fixture.hpp | 7 +- ...pp_test_report_settings_loader_fixture.cpp | 16 +- ...pp_test_report_settings_loader_fixture.hpp | 6 +- .../suits/app_test_cmake_project_builder.cpp | 49 +- .../app_test_configuration_file_suits.cpp | 96 +- .../test/suits/app_test_parser_arguments.cpp | 73 +- ...pp_test_parser_arguments_wrapper_suits.cpp | 123 +- .../test/suits/app_test_project_builder.cpp | 34 +- .../suits/app_test_report_settings_loader.cpp | 91 +- .../tools/app_cmake_project_builder.hpp | 3 +- .../tools/app_configuration_file.cpp | 17 + .../tools/app_configuration_file.hpp | 5 +- .../tools/app_configuration_file_loader.cpp | 30 +- .../tools/app_configuration_file_loader.hpp | 3 +- src/application/tools/app_log.hpp | 4 +- src/application/tools/app_parser_arg.hpp | 5 +- .../tools/app_parser_arg_wrapper.cpp | 31 +- .../tools/app_parser_arg_wrapper.hpp | 8 +- src/application/tools/app_project_builder.hpp | 3 +- .../tools/app_report_settings_loader.cpp | 22 +- .../tools/app_report_settings_loader.hpp | 14 +- src/cmake_project/api/cprj_loader.hpp | 2 +- src/cmake_project/api/cprj_project.hpp | 4 +- src/cmake_project/ih/cprj_accessor.hpp | 2 +- .../impl/cprj_includes_parser.hpp | 4 +- .../impl/cprj_includes_parser_context.cpp | 4 +- .../impl/cprj_includes_parser_context.hpp | 11 +- src/cmake_project/impl/cprj_loader_impl.hpp | 2 + .../cprj_test_includes_parser_fixture.hpp | 5 +- .../fixtures/cprj_test_loader_fixture.hpp | 4 +- .../test/suits/cprj_test_includes_parser.cpp | 48 +- .../test/suits/cprj_test_loader.cpp | 27 +- src/compilation_db/api/cdb_command_object.hpp | 2 +- src/compilation_db/api/cdb_database.hpp | 3 +- src/compilation_db/api/cdb_loader.hpp | 2 +- src/compilation_db/ih/cdb_accessor.hpp | 2 +- src/compilation_db/impl/cdb_database_impl.cpp | 4 +- src/compilation_db/impl/cdb_loader_impl.cpp | 5 +- .../test/fixtures/cdb_test_fixture.hpp | 2 +- .../test/suits/cdb_test_suits.cpp | 11 +- src/exception/api/exc_exception.hpp | 2 +- src/fs/api/fs_file.hpp | 4 +- src/fs/api/fs_file_system.hpp | 4 +- src/json/api/json_array.hpp | 3 +- src/json/api/json_object.hpp | 3 +- src/json/api/json_value.hpp | 3 +- src/json/ih/json_accessor.hpp | 3 +- src/json/test/fixtures/json_test_fixture.hpp | 1 - src/json/test/suits/json_test_suits.cpp | 164 +-- src/model_includes/api/mi_analyzer.hpp | 2 +- src/model_includes/api/mi_file.hpp | 3 +- .../api/mi_include_location.hpp | 2 +- src/model_includes/api/mi_model.hpp | 3 +- src/model_includes/ih/mi_accessor.hpp | 2 +- .../impl/mi_analyzer_context.hpp | 7 +- src/model_includes/impl/mi_analyzer_impl.cpp | 16 +- src/model_includes/impl/mi_analyzer_impl.hpp | 3 + src/model_includes/impl/mi_file_impl.hpp | 2 + src/model_includes/impl/mi_resolver.hpp | 9 +- .../impl/mi_resolver_context.hpp | 2 +- src/model_includes/impl/mi_std_library.hpp | 2 - .../mi_test_model_includes_fixture.hpp | 5 +- .../wrappers/mi_test_file_wrapper.hpp | 2 +- .../wrappers/mi_test_include_wrapper.hpp | 2 +- .../wrappers/mi_test_model_wrapper.hpp | 3 +- .../mi_test_analyzer_for_cmake_suits.cpp | 285 ++-- .../test/suits/mi_test_analyzer_suits.cpp | 765 +++++----- .../suits/mi_test_model_includes_suits.cpp | 23 +- .../mi_test_resolver_file_type_suits.cpp | 20 +- .../suits/mi_test_resolver_path_suits.cpp | 61 +- src/parser/api/pr_include_file_location.hpp | 2 +- src/parser/api/pr_parser.hpp | 3 +- src/parser/ih/pr_accessor.hpp | 2 +- src/parser/impl/pr_parser_impl.hpp | 4 + .../test/fixtures/pr_test_file_wrapper.hpp | 2 +- src/parser/test/fixtures/pr_test_fixture.hpp | 1 + src/parser/test/suits/pr_test_suits.cpp | 59 +- src/project/api/prj_project.hpp | 6 +- src/project/ih/prj_project_accessor.hpp | 2 +- src/project/test/fixture/prj_test_ficture.hpp | 3 +- src/project/test/suits/prj_test_suits.cpp | 83 +- src/reporter/api/rp_factory.hpp | 2 +- src/reporter/api/rp_reporter.hpp | 2 +- src/reporter/api/rp_settings.hpp | 3 + .../rp_different_type_reporter.cpp | 21 +- .../rp_different_type_reporter.hpp | 2 + .../rp_most_impact_reporter.cpp | 16 +- .../rp_most_impact_reporter.hpp | 2 +- src/reporter/impl/rp_base_reporter_impl.cpp | 7 + src/reporter/impl/rp_base_reporter_impl.hpp | 3 + src/reporter/impl/rp_settings_impl.cpp | 18 +- src/reporter/impl/rp_settings_impl.hpp | 4 + .../tools/rp_file_with_count_container.hpp | 2 +- .../rp_sorted_files_by_name_container.hpp | 3 +- ...rp_sorted_includes_by_source_container.hpp | 2 +- .../rp_unincluded_reporter.hpp | 2 +- .../rp_unresolved_reporter.hpp | 4 + .../test/fixture/rp_test_reporter_fixture.cpp | 9 + .../test/fixture/rp_test_reporter_fixture.hpp | 4 +- .../rp_test_different_type_reporter_tests.cpp | 60 +- .../suits/rp_test_dump_reporter_suits.cpp | 15 +- .../rp_test_most_impact_reporter_suits.cpp | 72 +- .../rp_test_unincluded_reporter_suits.cpp | 23 +- .../rp_test_unresolved_reporter_tests.cpp | 23 +- .../tools/rp_reporter_kind_functins.hpp | 3 +- src/test_tools/test_macros.hpp | 30 - 178 files changed, 4383 insertions(+), 2584 deletions(-) create mode 100644 docs/versions/VERSION_0.4.0.md delete mode 100644 src/3rd-part/cpp-std-fwd/stdfwd.hpp create mode 100644 src/3rd-part/stdfwd/include/stdfwd.hh create mode 100644 src/3rd-part/stdfwd/include/stdfwd/array create mode 100644 src/3rd-part/stdfwd/include/stdfwd/atomic create mode 100644 src/3rd-part/stdfwd/include/stdfwd/bitset create mode 100644 src/3rd-part/stdfwd/include/stdfwd/chrono create mode 100644 src/3rd-part/stdfwd/include/stdfwd/clocale create mode 100644 src/3rd-part/stdfwd/include/stdfwd/complex create mode 100644 src/3rd-part/stdfwd/include/stdfwd/condition_variable create mode 100644 src/3rd-part/stdfwd/include/stdfwd/deque create mode 100644 src/3rd-part/stdfwd/include/stdfwd/exception create mode 100644 src/3rd-part/stdfwd/include/stdfwd/filesystem create mode 100644 src/3rd-part/stdfwd/include/stdfwd/forward_list create mode 100644 src/3rd-part/stdfwd/include/stdfwd/functional create mode 100644 src/3rd-part/stdfwd/include/stdfwd/future create mode 100644 src/3rd-part/stdfwd/include/stdfwd/initializer_list create mode 100644 src/3rd-part/stdfwd/include/stdfwd/iterator create mode 100644 src/3rd-part/stdfwd/include/stdfwd/list create mode 100644 src/3rd-part/stdfwd/include/stdfwd/locale create mode 100644 src/3rd-part/stdfwd/include/stdfwd/map create mode 100644 src/3rd-part/stdfwd/include/stdfwd/memory create mode 100644 src/3rd-part/stdfwd/include/stdfwd/mutex create mode 100644 src/3rd-part/stdfwd/include/stdfwd/new create mode 100644 src/3rd-part/stdfwd/include/stdfwd/optional create mode 100644 src/3rd-part/stdfwd/include/stdfwd/ptrdiff_t create mode 100644 src/3rd-part/stdfwd/include/stdfwd/queue create mode 100644 src/3rd-part/stdfwd/include/stdfwd/random create mode 100644 src/3rd-part/stdfwd/include/stdfwd/ratio create mode 100644 src/3rd-part/stdfwd/include/stdfwd/regex create mode 100644 src/3rd-part/stdfwd/include/stdfwd/scoped_allocator create mode 100644 src/3rd-part/stdfwd/include/stdfwd/set create mode 100644 src/3rd-part/stdfwd/include/stdfwd/shared_mutex create mode 100644 src/3rd-part/stdfwd/include/stdfwd/size_t create mode 100644 src/3rd-part/stdfwd/include/stdfwd/stack create mode 100644 src/3rd-part/stdfwd/include/stdfwd/std_fs create mode 100644 src/3rd-part/stdfwd/include/stdfwd/stdexcept create mode 100644 src/3rd-part/stdfwd/include/stdfwd/stdfwd_details.hpp create mode 100644 src/3rd-part/stdfwd/include/stdfwd/string create mode 100644 src/3rd-part/stdfwd/include/stdfwd/string_view create mode 100644 src/3rd-part/stdfwd/include/stdfwd/system_error create mode 100644 src/3rd-part/stdfwd/include/stdfwd/thread create mode 100644 src/3rd-part/stdfwd/include/stdfwd/tuple create mode 100644 src/3rd-part/stdfwd/include/stdfwd/type_traits create mode 100644 src/3rd-part/stdfwd/include/stdfwd/typeindex create mode 100644 src/3rd-part/stdfwd/include/stdfwd/typeinfo create mode 100644 src/3rd-part/stdfwd/include/stdfwd/unordered_map create mode 100644 src/3rd-part/stdfwd/include/stdfwd/unordered_set create mode 100644 src/3rd-part/stdfwd/include/stdfwd/utility create mode 100644 src/3rd-part/stdfwd/include/stdfwd/valarray create mode 100644 src/3rd-part/stdfwd/include/stdfwd/vector delete mode 100644 src/test_tools/test_macros.hpp diff --git a/.clang-tidy b/.clang-tidy index e5ac4a6..b2824d1 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,2 +1,57 @@ -Checks: '-*,abseil-*,android-*,boost-*,bugprone-*,cert-*,clang-*,cppcoreguidelines-avoid-*,cppcoreguidelines-c-copy-assignment-signature,cppcoreguidelines-interfaces-global-init,cppcoreguidelines-macro-usage,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-no-malloc,cppcoreguidelines-non-private-member-variables-in-classes,cppcoreguidelines-pro-bounds-constant-array-index,cppcoreguidelines-pro-bounds-pointer-arithmetic,cppcoreguidelines-pro-type-*,cppcoreguidelines-slicing,cppcoreguidelines-special-member-functions,darwin-*,fuchsia-header-anon-namespaces,fuchsia-multiple-inheritance,fuchsia-restrict-system-includes,fuchsia-statically-constructed-objects,fuchsia-trailing-return,fuchsia-virtual-inheritance,google-build-explicit-make-pair,google-build-namespaces,google-default-arguments,google-explicit-constructor,google-global-names-in-headers,google-objc-*,google-readability-braces-around-statements,google-readability-casting,google-readability-function-size,google-readability-todo,google-runtime-*,hicpp-avoid-*,hicpp-braces-around-statements,hicpp-deprecated-headers,hicpp-exception-baseclass,hicpp-explicit-conversions,hicpp-function-size,hicpp-invalid-access-moved,hicpp-member-init,hicpp-move-const-arg,hicpp-multiway-paths-covered,hicpp-named-parameter,hicpp-new-delete-operators,hicpp-no-assembler,hicpp-no-malloc,hicpp-noexcept-move,hicpp-signed-bitwise,hicpp-special-member-functions,hicpp-static-assert,hicpp-undelegated-constructor,hicpp-uppercase-literal-suffix,hicpp-use-*,hicpp-vararg,linuxkernel-*,llvm-header-guard,llvm-twine-local,misc-*,modernize-avoid-*,modernize-concat-nested-namespaces,modernize-deprecated-*,modernize-loop-convert,modernize-make-*,modernize-pass-by-value,modernize-raw-string-literal,modernize-redundant-void-arg,modernize-replace-*,modernize-return-braced-init-list,modernize-shrink-to-fit,modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-*,modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,mpi-*,objc-*,openmp-*,performance-*,portability-*,readability-avoid-const-params-in-decls,readability-braces-around-statements,readability-const-return-type,readability-container-size-empty,readability-delete-null-pointer,readability-deleted-default,readability-else-after-return,readability-function-size,readability-identifier-naming,readability-implicit-bool-conversion,readability-inconsistent-declaration-parameter-name,readability-isolate-declaration,readability-magic-numbers,readability-misleading-indentation,readability-misplaced-array-index,readability-named-parameter,readability-non-const-parameter,readability-qualified-auto,readability-redundant-*,readability-simplify-*,readability-static-*,readability-string-compare,readability-uniqueptr-delete-release,readability-uppercase-literal-suffix,zircon-*' +--- +Checks: "-*\, +abseil-*,\android-*,\ +boost-*,\ +bugprone-*, +cert-*,\ +clang-*,\ +cppcoreguidelines-avoid-*,cppcoreguidelines-c-copy-assignment-signature,cppcoreguidelines-interfaces-global-init,\ +cppcoreguidelines-macro-usage,cppcoreguidelines-narrowing-conversions,cppcoreguidelines-no-malloc,\ +cppcoreguidelines-non-private-member-variables-in-classes,cppcoreguidelines-pro-bounds-constant-array-index,\ +cppcoreguidelines-pro-bounds-pointer-arithmetic,cppcoreguidelines-pro-type-*,\ +cppcoreguidelines-slicing,cppcoreguidelines-special-member-functions,\ +darwin-*,\ +fuchsia-header-anon-namespaces,fuchsia-multiple-inheritance,fuchsia-restrict-system-includes,\ +fuchsia-statically-constructed-objects,fuchsia-trailing-return,\ +fuchsia-virtual-inheritance,\ +google-build-explicit-make-pair,google-build-namespaces,google-default-arguments,\ +google-explicit-constructor,google-global-names-in-headers,google-objc-*,\ +google-readability-braces-around-statements,google-readability-casting,\ +google-readability-function-size,google-readability-todo,google-runtime-*,\ +hicpp-avoid-*,hicpp-braces-around-statements,hicpp-deprecated-headers,\ +hicpp-exception-baseclass,hicpp-explicit-conversions,hicpp-function-size,\ +hicpp-invalid-access-moved,hicpp-member-init,hicpp-move-const-arg,\ +hicpp-multiway-paths-covered,hicpp-named-parameter,hicpp-new-delete-operators,\ +hicpp-no-assembler,hicpp-no-malloc,hicpp-noexcept-move,hicpp-signed-bitwise,\ +hicpp-special-member-functions,hicpp-static-assert,\ +hicpp-undelegated-constructor,hicpp-uppercase-literal-suffix,hicpp-use-*,hicpp-vararg,\ +linuxkernel-*,\ +llvm-header-guard,llvm-twine-local,\ +misc-*,\ +modernize-avoid-*,modernize-concat-nested-namespaces,modernize-deprecated-*,\ +modernize-loop-convert,modernize-make-*,modernize-pass-by-value,modernize-raw-string-literal,\ +modernize-redundant-void-arg,modernize-replace-*,\ +modernize-return-braced-init-list,modernize-shrink-to-fit,\ +modernize-unary-static-assert,modernize-use-auto,modernize-use-bool-literals,\ +modernize-use-default-member-init,modernize-use-emplace,modernize-use-equals-*,\ +modernize-use-nodiscard,modernize-use-noexcept,modernize-use-nullptr,modernize-use-override,\ +modernize-use-transparent-functors,modernize-use-uncaught-exceptions,modernize-use-using,\ +mpi-*,\ +objc-*,\ +openmp-*,\ +performance-*,\ +portability-*,\ +readability-avoid-const-params-in-decls,readability-braces-around-statements,\ +readability-const-return-type,readability-container-size-empty,readability-delete-null-pointer,\ +readability-deleted-default,readability-else-after-return,readability-function-size,\ +readability-identifier-naming,readability-implicit-bool-conversion,\ +readability-inconsistent-declaration-parameter-name,readability-isolate-declaration,\ +readability-magic-numbers,readability-misleading-indentation,readability-misplaced-array-index,\ +readability-named-parameter,readability-non-const-parameter,readability-qualified-auto,\ +readability-redundant-*,readability-simplify-*,readability-static-*,readability-string-compare,\ +readability-uniqueptr-delete-release,readability-uppercase-literal-suffix,\ +zircon-*" FormatStyle: 'file' +HeaderFilterRegex: 'boost/test' +AnalyzeTemporaryDtors: false +--- diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0124628..0d19ea6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,16 @@ +stages: + - build_major_compilers + - build_minor_compiler_gcc8 + - build_minor_compiler_gcc7 + - build_major_compiler_clang + - check_typos + - run_cppcheck + - build_minor_compiler_arm + build_gcc10: - stage: build + tags: + - vm_linux + stage: build_major_compilers image: ubuntu script: - apt-get update @@ -12,12 +23,14 @@ build_gcc10: - apt-get install libboost-test-dev -y - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release build_gcc8: - stage: build + tags: + - vm_linux + stage: build_minor_compiler_gcc8 image: ubuntu script: - apt-get update @@ -26,12 +39,15 @@ build_gcc8: - export CXX=g++-8 - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release + needs: [build_gcc10] build_gcc7: - stage: build + tags: + - vm_linux + stage: build_minor_compiler_gcc7 image: ubuntu script: - apt-get update @@ -40,12 +56,15 @@ build_gcc7: - export CXX=g++-7 - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release + needs: [build_gcc8] build_clang: - stage: build + tags: + - vm_linux + stage: build_major_compiler_clang image: ubuntu script: - apt-get update @@ -54,12 +73,13 @@ build_clang: - export CXX=/usr/bin/clang++ - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release + needs: [build_gcc7] build_windows: - stage: build + stage: build_major_compilers tags: - vm_win script: @@ -75,12 +95,12 @@ build_windows: #- vcpkg install boost-test:x64-windows #- vcpkg install boost-system:x64-windows - cmake .. -G "Visual Studio 16" -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON -DCMAKE_TOOLCHAIN_FILE=C:\vcpkg\scripts\buildsystems\vcpkg.cmake - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release build_vs2017: - stage: build + stage: build_major_compilers tags: - vm_win script: @@ -90,10 +110,10 @@ build_vs2017: - $env:PATH="C:\Program Files\CMake\bin;$env:PATH" - cd build - cmake -G "Visual Studio 15" .. -DCMAKE_BUILD_TYPE=Release - - cmake --build . --config Release + - cmake --build . --config Release -j4 build_macos: - stage: build + stage: build_major_compilers tags: - macmini script: @@ -103,12 +123,12 @@ build_macos: # brew install boost - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release + - cmake --build . --config Release -j4 # Run tests - ctest . -C Release build_arm_linux: - stage: build + stage: build_minor_compiler_arm tags: - arm-linux script: @@ -117,9 +137,12 @@ build_arm_linux: - cmake --build . --config Release -j4 # Run tests - ctest . -C Release + needs: [build_gcc10] check_typos: - stage: build + tags: + - vm_linux + stage: check_typos image: ubuntu script: - apt-get update @@ -130,9 +153,12 @@ check_typos: - apt-get install npm -y - npm install -g cspell - cspell "src/**/*" + needs: [build_clang] cppcheck: - stage: build + tags: + - vm_linux + stage: run_cppcheck image: ubuntu script: - apt-get update @@ -140,4 +166,6 @@ cppcheck: - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cppcheck --project=compile_commands.json --enable=all --suppressions-list=../.cppcheck-suppressions-list --error-exitcode=1 --quiet + needs: [check_typos] + diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e77188..180ab07 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [v0.4.0](docs/versions/VERSION_0.4.0.md) + +### Added (v0.4.0) + +* New argument *show_only_std_headers* + ## [v0.3.1](docs/versions/VERSION_0.3.1.md) ### Fixed (v0.3.1) diff --git a/CMakeLists.txt b/CMakeLists.txt index be4185f..d776652 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,8 +4,8 @@ project(cppinclude) include_directories(src/) include_directories(src/3rd-part/fmt/include/) -include_directories(src/3rd-part/cpp-std-fwd/) -include_directories(src/3rd-part/std_fs/include) +include_directories(src/3rd-part/stdfwd/include/) +include_directories(src/3rd-part/std_fs/include/) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) diff --git a/README.md b/README.md index a220353..5537b54 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ include that file will be recompiled and sometime it takes a lot of time. * [ignore_files](#ignore_files) * [report_limit](#report_limit) * [report_details_limit](#report_details_limit) + * [show_std_files](#show_std_files) + * [show_only_std_headers](#show_only_std_headers) * [Build](#build) * [Presentations](#presentations) * [Tips for optimization includes](#tips-for-optimization-includes) @@ -116,6 +118,7 @@ Name|Short description --[report_limit](#report_limit)=42|Maximum elements in report, 0 - unlimited (default: 10) --[report_details_limit](#report_details_limit)=42|Maximum details in report, 0 - unlimited (default: 10) --[show_std_files](#show_std_files)|Show standard library headers in output (default: false) +--[show_only_std_headers](#show_only_std_headers)|Show only standard library headers in output (default: false) --help|Show usage --verbose|Verbose mode --version|Show application version @@ -506,6 +509,22 @@ Also you can set in configuration file: [Back to top](#cppinclude) +### show_only_std_headers + +Show only standard library headers in output. + +`cppinclude --show_only_std_headers=true` + +Also you can set in configuration file: + +```json +{ + "show_only_std_headers" : true +} +``` + +[Back to top](#cppinclude) + ## Build Requirements: @@ -552,7 +571,7 @@ on Unix: ## Third-party libraries -* [cpp-std-fwd](https://github.com/Philip-Trettner/cpp-std-fwd) +* [stdfwd](https://github.com/olegpublicprofile/stdfwd) * [cxxopts](https://github.com/jarro2783/cxxopts) * [{fmt}](https://github.com/fmtlib/fmt) * [json for modern C++](https://github.com/nlohmann/json) diff --git a/docs/examples/cppinclude/output_unix.txt b/docs/examples/cppinclude/output_unix.txt index 041d078..9bcba01 100644 --- a/docs/examples/cppinclude/output_unix.txt +++ b/docs/examples/cppinclude/output_unix.txt @@ -30,7 +30,20 @@ Included by: 9 : "application/tools/app_configuration_file.cpp" line 5 10 : "application/tools/app_configuration_file_loader.cpp" line 9 ... 10 of 51 details -4 : "reporter/api/enums/rp_reporter_kind.hpp" impact on 19 file(s) +4 : "test_tools/test_macros.hpp" impact on 22 file(s) +Included by: + 1 : "application/test/suits/app_test_cmake_project_builder.cpp" line 7 + 2 : "application/test/suits/app_test_configuration_file_suits.cpp" line 3 + 3 : "application/test/suits/app_test_parser_arguments.cpp" line 3 + 4 : "application/test/suits/app_test_parser_arguments_wrapper_suits.cpp" line 9 + 5 : "application/test/suits/app_test_project_builder.cpp" line 5 + 6 : "application/test/suits/app_test_report_settings_loader.cpp" line 3 + 7 : "cmake_project/test/suits/cprj_test_includes_parser.cpp" line 3 + 8 : "cmake_project/test/suits/cprj_test_loader.cpp" line 3 + 9 : "compilation_db/test/suits/cdb_test_suits.cpp" line 6 + 10 : "json/test/suits/json_test_suits.cpp" line 7 + ... 10 of 22 details +5 : "reporter/api/enums/rp_reporter_kind.hpp" impact on 19 file(s) Included by: 1 : "application/exceptions/app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) 2 : "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) @@ -38,45 +51,45 @@ Included by: 4 : "application/test/fixtures/app_test_configuration_file_fixture.cpp" line 10 5 : "application/test/fixtures/app_test_parser_wrapper_fixture.cpp" line 6 6 : "application/test/suits/app_test_parser_arguments_wrapper_suits.cpp" line 6 - 7 : "application/tools/app_parser_arg_wrapper.cpp" line 5 + 7 : "application/tools/app_parser_arg_wrapper.cpp" line 6 8 : "reporter/exceptions/rp_incorrect_report_impl.cpp" line 10 9 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 3 10 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 3 ... 10 of 15 details -5 : "model_includes/api/enums/mi_file_type.hpp" impact on 18 file(s) +6 : "model_includes/api/enums/mi_file_type.hpp" impact on 18 file(s) Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) - 2 : "model_includes/impl/mi_file_impl.hpp" line 4, impact on 2 file(s) - 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 5 - 4 : "model_includes/impl/mi_resolver.cpp" line 5 - 5 : "model_includes/test/fixtures/mi_test_model_includes_fixture.cpp" line 6 - 6 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp" line 7 + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes/impl/mi_file_impl.hpp" line 3, impact on 2 file(s) + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 3 + 4 : "model_includes/impl/mi_resolver.cpp" line 3 + 5 : "model_includes/test/fixtures/mi_test_model_includes_fixture.cpp" line 5 + 6 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.cpp" line 5 7 : "model_includes/test/suits/mi_test_resolver_file_type_suits.cpp" line 3 - 8 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 13 - 9 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 11 - 10 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 14 + 8 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 9 + 9 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 6 + 10 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 10 ... 10 of 11 details -6 : "model_includes/api/enums/mi_include_status.hpp" impact on 17 file(s) +7 : "model_includes/api/enums/mi_include_status.hpp" impact on 17 file(s) Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) - 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 7 + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 4 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 6 - 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 8 - 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 8 - 7 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 9 - 8 : "reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp" line 15 -7 : "model_includes/api/enums/mi_include_type.hpp" impact on 17 file(s) + 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 7 + 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 7 + 7 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 7 + 8 : "reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp" line 11 +8 : "model_includes/api/enums/mi_include_type.hpp" impact on 17 file(s) Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) - 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 6 + 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 5 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 7 - 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 9 - 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 9 - 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 4 - 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 10 -8 : "test_tools/boost_predicate_wrapper.hpp" impact on 17 file(s) + 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 8 + 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 8 + 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 3 + 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 8 +9 : "test_tools/boost_predicate_wrapper.hpp" impact on 17 file(s) Included by: 1 : "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) 2 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) @@ -84,30 +97,17 @@ Included by: 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) 5 : "project/test/fixture/prj_test_ficture.hpp" line 3, impact on 2 file(s) 6 : "test_tools/boost_predicate_wrapper.cpp" line 1 -9 : "fs/api/fs_file_system.hpp" impact on 16 file(s) +10 : "fs/api/fs_file_system.hpp" impact on 16 file(s) Included by: 1 : "fs/impl/fs_factory_impl.hpp" line 4, impact on 3 file(s) 2 : "fs/impl/memory/fs_memory_file_system.hpp" line 3, impact on 2 file(s) 3 : "fs/impl/physical/fs_physical_file_system.hpp" line 3, impact on 2 file(s) - 4 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 13 - 5 : "application/test/fixtures/app_test_project_builder_fixture.cpp" line 15 - 6 : "application/tools/app_cmake_project_builder.cpp" line 19 - 7 : "application/tools/app_configuration_file_loader.cpp" line 11 + 4 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 15 + 5 : "application/test/fixtures/app_test_project_builder_fixture.cpp" line 16 + 6 : "application/tools/app_cmake_project_builder.cpp" line 20 + 7 : "application/tools/app_configuration_file_loader.cpp" line 12 8 : "application/tools/app_project_builder.cpp" line 9 - 9 : "model_includes/impl/mi_analyzer_impl.cpp" line 16 - 10 : "model_includes/impl/mi_resolver.cpp" line 7 - ... 10 of 12 details -10 : "model_includes/api/mi_include.hpp" impact on 16 file(s) -Included by: - 1 : "model_includes/impl/mi_model_impl.hpp" line 5, impact on 3 file(s) - 2 : "model_includes/impl/mi_include_impl.hpp" line 3, impact on 2 file(s) - 3 : "model_includes/impl/mi_file_impl.cpp" line 3 - 4 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.cpp" line 6 - 5 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 3 - 6 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 11 - 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 3 - 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 8 - 9 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 12 - 10 : "reporter/impl/tools/rp_includes_by_source_sorter.cpp" line 5 + 9 : "model_includes/impl/mi_analyzer_impl.cpp" line 19 + 10 : "model_includes/impl/mi_resolver.cpp" line 8 ... 10 of 12 details -... 10 of 163 files +... 10 of 164 files diff --git a/docs/examples/cppinclude/output_win.txt b/docs/examples/cppinclude/output_win.txt index 86acf9c..daa7d51 100644 --- a/docs/examples/cppinclude/output_win.txt +++ b/docs/examples/cppinclude/output_win.txt @@ -30,7 +30,20 @@ Included by: 9 : "application\tools\app_configuration_file.cpp" line 5 10 : "application\tools\app_configuration_file_loader.cpp" line 9 ... 10 of 51 details -4 : "reporter\api\enums\rp_reporter_kind.hpp" impact on 19 file(s) +4 : "test_tools\test_macros.hpp" impact on 22 file(s) +Included by: + 1 : "application\test\suits\app_test_cmake_project_builder.cpp" line 7 + 2 : "application\test\suits\app_test_configuration_file_suits.cpp" line 3 + 3 : "application\test\suits\app_test_parser_arguments.cpp" line 3 + 4 : "application\test\suits\app_test_parser_arguments_wrapper_suits.cpp" line 9 + 5 : "application\test\suits\app_test_project_builder.cpp" line 5 + 6 : "application\test\suits\app_test_report_settings_loader.cpp" line 3 + 7 : "cmake_project\test\suits\cprj_test_includes_parser.cpp" line 3 + 8 : "cmake_project\test\suits\cprj_test_loader.cpp" line 3 + 9 : "compilation_db\test\suits\cdb_test_suits.cpp" line 6 + 10 : "json\test\suits\json_test_suits.cpp" line 7 + ... 10 of 22 details +5 : "reporter\api\enums\rp_reporter_kind.hpp" impact on 19 file(s) Included by: 1 : "application\exceptions\app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) 2 : "application\test\fixtures\app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) @@ -38,45 +51,45 @@ Included by: 4 : "application\test\fixtures\app_test_configuration_file_fixture.cpp" line 10 5 : "application\test\fixtures\app_test_parser_wrapper_fixture.cpp" line 6 6 : "application\test\suits\app_test_parser_arguments_wrapper_suits.cpp" line 6 - 7 : "application\tools\app_parser_arg_wrapper.cpp" line 5 + 7 : "application\tools\app_parser_arg_wrapper.cpp" line 6 8 : "reporter\exceptions\rp_incorrect_report_impl.cpp" line 10 9 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 3 10 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 3 ... 10 of 15 details -5 : "model_includes\api\enums\mi_file_type.hpp" impact on 18 file(s) +6 : "model_includes\api\enums\mi_file_type.hpp" impact on 18 file(s) Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) - 2 : "model_includes\impl\mi_file_impl.hpp" line 4, impact on 2 file(s) - 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 5 - 4 : "model_includes\impl\mi_resolver.cpp" line 5 - 5 : "model_includes\test\fixtures\mi_test_model_includes_fixture.cpp" line 6 - 6 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.cpp" line 7 + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 2 : "model_includes\impl\mi_file_impl.hpp" line 3, impact on 2 file(s) + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 3 + 4 : "model_includes\impl\mi_resolver.cpp" line 3 + 5 : "model_includes\test\fixtures\mi_test_model_includes_fixture.cpp" line 5 + 6 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.cpp" line 5 7 : "model_includes\test\suits\mi_test_resolver_file_type_suits.cpp" line 3 - 8 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 13 - 9 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 11 - 10 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 14 + 8 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 9 + 9 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 6 + 10 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 10 ... 10 of 11 details -6 : "model_includes\api\enums\mi_include_status.hpp" impact on 17 file(s) +7 : "model_includes\api\enums\mi_include_status.hpp" impact on 17 file(s) Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) - 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 7 + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 4 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 6 - 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 8 - 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 8 - 7 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 9 - 8 : "reporter\impl\unresolved_reporter\rp_unresolved_reporter.cpp" line 15 -7 : "model_includes\api\enums\mi_include_type.hpp" impact on 17 file(s) + 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 7 + 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 7 + 7 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 7 + 8 : "reporter\impl\unresolved_reporter\rp_unresolved_reporter.cpp" line 11 +8 : "model_includes\api\enums\mi_include_type.hpp" impact on 17 file(s) Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) - 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 6 + 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 5 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 7 - 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 9 - 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 9 - 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 4 - 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 10 -8 : "test_tools\boost_predicate_wrapper.hpp" impact on 17 file(s) + 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 8 + 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 8 + 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 3 + 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 8 +9 : "test_tools\boost_predicate_wrapper.hpp" impact on 17 file(s) Included by: 1 : "model_includes\test\fixtures\mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) 2 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) @@ -84,30 +97,17 @@ Included by: 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) 5 : "project\test\fixture\prj_test_ficture.hpp" line 3, impact on 2 file(s) 6 : "test_tools\boost_predicate_wrapper.cpp" line 1 -9 : "fs\api\fs_file_system.hpp" impact on 16 file(s) +10 : "fs\api\fs_file_system.hpp" impact on 16 file(s) Included by: 1 : "fs\impl\fs_factory_impl.hpp" line 4, impact on 3 file(s) 2 : "fs\impl\memory\fs_memory_file_system.hpp" line 3, impact on 2 file(s) 3 : "fs\impl\physical\fs_physical_file_system.hpp" line 3, impact on 2 file(s) - 4 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 13 - 5 : "application\test\fixtures\app_test_project_builder_fixture.cpp" line 15 - 6 : "application\tools\app_cmake_project_builder.cpp" line 19 - 7 : "application\tools\app_configuration_file_loader.cpp" line 11 + 4 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 15 + 5 : "application\test\fixtures\app_test_project_builder_fixture.cpp" line 16 + 6 : "application\tools\app_cmake_project_builder.cpp" line 20 + 7 : "application\tools\app_configuration_file_loader.cpp" line 12 8 : "application\tools\app_project_builder.cpp" line 9 - 9 : "model_includes\impl\mi_analyzer_impl.cpp" line 16 - 10 : "model_includes\impl\mi_resolver.cpp" line 7 - ... 10 of 12 details -10 : "model_includes\api\mi_include.hpp" impact on 16 file(s) -Included by: - 1 : "model_includes\impl\mi_model_impl.hpp" line 5, impact on 3 file(s) - 2 : "model_includes\impl\mi_include_impl.hpp" line 3, impact on 2 file(s) - 3 : "model_includes\impl\mi_file_impl.cpp" line 3 - 4 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.cpp" line 6 - 5 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 3 - 6 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 11 - 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 3 - 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 8 - 9 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 12 - 10 : "reporter\impl\tools\rp_includes_by_source_sorter.cpp" line 5 + 9 : "model_includes\impl\mi_analyzer_impl.cpp" line 19 + 10 : "model_includes\impl\mi_resolver.cpp" line 8 ... 10 of 12 details -... 10 of 163 files +... 10 of 164 files diff --git a/docs/versions/VERSION_0.4.0.md b/docs/versions/VERSION_0.4.0.md new file mode 100644 index 0000000..3eda264 --- /dev/null +++ b/docs/versions/VERSION_0.4.0.md @@ -0,0 +1,77 @@ +# VERSION 0.4.0 + +## Added + +### New argument show_only_std_headers + +Show only standard library headers in output. Example [lua](docs/examples/lua) : + +**Before:** + +``` +cppinclude --report=most_impact --show_only_std_headers=false --ignore_system_includes=false --report_details_limit=3 + +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "luaconf.h" impact on 62 file(s) +Included by: + 1 : "lua.h" line 16, impact on 61 file(s) + 2 : "onelua.c" line 49 +2 : "lua.h" impact on 61 file(s) +Included by: + 1 : "llimits.h" line 15, impact on 40 file(s) + 2 : "lobject.h" line 16, impact on 34 file(s) + 3 : "lstate.h" line 10, impact on 26 file(s) + ... 3 of 44 details +3 : "llimits.h" impact on 40 file(s) +Included by: + 1 : "lobject.h" line 15, impact on 34 file(s) + 2 : "lmem.h" line 13, impact on 15 file(s) + 3 : "lopcodes.h" line 10, impact on 9 file(s) + ... 3 of 8 details +4 : "lprefix.h" impact on 35 file(s) +Included by: + 1 : "lapi.c" line 10, impact on 1 file(s) + 2 : "lauxlib.c" line 10, impact on 1 file(s) + 3 : "lbaselib.c" line 10, impact on 1 file(s) + ... 3 of 35 details +... + +``` + +**After:** + +``` +cppinclude --report=most_impact --show_only_std_headers=false --ignore_system_includes=false --report_details_limit=3 + +Start initialization project ... +Start analyze sources ... +Start report results ... +Most impact files: +1 : "assert.h" impact on 64 file(s) +Included by: + 1 : "luaconf.h" line 701, impact on 62 file(s) + 2 : "lutf8lib.c" line 13, impact on 1 file(s) + 3 : "ltests.h" line 24 + ... 3 of 4 details +2 : "stddef.h" impact on 64 file(s) +Included by: + 1 : "luaconf.h" line 12, impact on 62 file(s) + 2 : "lua.h" line 13, impact on 61 file(s) + 3 : "llimits.h" line 12, impact on 40 file(s) + ... 3 of 15 details +3 : "limits.h" impact on 63 file(s) +Included by: + 1 : "luaconf.h" line 11, impact on 62 file(s) + 2 : "llimits.h" line 11, impact on 40 file(s) + 3 : "lctype.h" line 34, impact on 5 file(s) + ... 3 of 16 details +4 : "stdint.h" impact on 63 file(s) +Included by: + 1 : "luaconf.h" line 660, impact on 62 file(s) +... + +``` + diff --git a/src/3rd-part/cpp-std-fwd/stdfwd.hpp b/src/3rd-part/cpp-std-fwd/stdfwd.hpp deleted file mode 100644 index df34403..0000000 --- a/src/3rd-part/cpp-std-fwd/stdfwd.hpp +++ /dev/null @@ -1,1286 +0,0 @@ -#pragma once - -// see https://stackoverflow.com/questions/31657499/how-to-detect-stdlib-libc-in-the-preprocessor -#include - -#include // for std::atomic typedefs - -#if defined(_LIBCPP_VERSION) -#define STDFWD_IS_LIBCPP -#elif defined(__GLIBCXX__) -#define STDFWD_IS_LIBSTDCPP -#elif defined(_MSC_VER) -#define STDFWD_IS_MSVC -#else -#error "Unknown stdlib" -#endif - -/* - * TODO: are these useful at all? - * - * - * - * - * - * - * - * - * TODO: - * - * slices? - * more types? - * iterators? - * raii types? - * what is useful here? - * depends heavily on ratio - */ - -#if defined(STDFWD_IS_LIBSTDCPP) - -#if _GLIBCXX_USE_CXX11_ABI - #define _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE inline _GLIBCXX_BEGIN_NAMESPACE_CXX11 -#else - #define _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE -#endif - -namespace std _GLIBCXX_VISIBILITY(default) -{ - inline namespace __cxx11 __attribute__((__abi_tag__("cxx11"))) {} - - // - template - class initializer_list; - - _GLIBCXX_BEGIN_NAMESPACE_VERSION - - // - template - struct pair; - - // - template - class tuple; - - // - class any; - - // - template - class optional; - struct nullopt_t; - - // - template - class variant; - struct monostate; - - // - template - class shared_ptr; - template - struct default_delete; - template - class unique_ptr; - template - class weak_ptr; - template - class allocator; - - // - template - struct complex; - - // - template - class valarray; - - // - class random_device; - - // - template - struct atomic; - struct atomic_flag; - - // - class mutex; - class timed_mutex; - class recursive_mutex; - class recursive_timed_mutex; - - // - class shared_mutex; - class shared_timed_mutex; - - // - class thread; - - // - template - class future; - template - class shared_future; - template - class packaged_task; - template - class promise; - - // - class condition_variable; - inline namespace _V2 - { - class condition_variable_any; - } - - // - template - struct char_traits; - _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE - template - class basic_string; - using string = basic_string, allocator>; - using wstring = basic_string, allocator>; - using u16string = basic_string, allocator>; - using u32string = basic_string, allocator>; - _GLIBCXX_END_NAMESPACE_CXX11 - - // - template - class basic_string_view; - using string_view = basic_string_view>; - using wstring_view = basic_string_view>; - using u16string_view = basic_string_view>; - using u32string_view = basic_string_view>; - - // - template - class function; - template - struct hash; - template - struct equal_to; - template - struct not_equal_to; - template - struct greater; - template - struct less; - template - struct greater_equal; - template - struct less_equal; - - // - not in container for some reason - template - class stack; - - // - not in container for some reason - template - class queue; - template - class priority_queue; - - _GLIBCXX_BEGIN_NAMESPACE_CONTAINER - - // - template - class vector; - - // - template - class deque; - - _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE - - // - template - class list; - - // - template - struct regex_traits; - template - class basic_regex; - using regex = basic_regex>; - template - class sub_match; - template - class match_results; - - _GLIBCXX_END_NAMESPACE_CXX11 - - // - template - class forward_list; - - // - template - class map; - template - class multimap; - - // - template - class set; - template - class multiset; - - // - template - class unordered_map; - template - class unordered_multimap; - - // - template - class unordered_set; - template - class unordered_multiset; - - _GLIBCXX_END_NAMESPACE_CONTAINER - - namespace filesystem - { - inline namespace __cxx11 __attribute__((__abi_tag__("cxx11"))) {} - _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE - - // - class path; - - _GLIBCXX_END_NAMESPACE_CXX11 - } - - namespace experimental - { - namespace filesystem - { - inline namespace v1 - { - inline namespace __cxx11 __attribute__((__abi_tag__("cxx11"))) {} - _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE - class path; - _GLIBCXX_END_NAMESPACE_CXX11 - } - } - } - - // - class ios_base; - template - class basic_ios; - template - class basic_streambuf; - template - class basic_istream; - template - class basic_ostream; - template - class basic_iostream; - - _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE - - template - class basic_stringbuf; - template - class basic_istringstream; - template - class basic_ostringstream; - template - class basic_stringstream; - - _GLIBCXX_END_NAMESPACE_CXX11 - - template - class basic_filebuf; - template - class basic_ifstream; - template - class basic_ofstream; - template - class basic_fstream; - template - class istreambuf_iterator; - template - class ostreambuf_iterator; - - using ios = basic_ios>; - using wios = basic_ios>; - - using streambuf = basic_streambuf>; - using istream = basic_istream>; - using ostream = basic_ostream>; - using iostream = basic_iostream>; - - using stringbuf = basic_stringbuf, allocator>; - using istringstream = basic_istringstream, allocator>; - using ostringstream = basic_ostringstream, allocator>; - using stringstream = basic_stringstream, allocator>; - - using filebuf = basic_filebuf>; - using ifstream = basic_ifstream>; - using ofstream = basic_ofstream>; - using fstream = basic_fstream>; - - using wstreambuf = basic_streambuf>; - using wistream = basic_istream>; - using wostream = basic_ostream>; - using wiostream = basic_iostream>; - - using wstringbuf = basic_stringbuf, allocator>; - using wistringstream = basic_istringstream, allocator>; - using wostringstream = basic_ostringstream, allocator>; - using wstringstream = basic_stringstream, allocator>; - - using wfilebuf = basic_filebuf>; - using wifstream = basic_ifstream>; - using wofstream = basic_ofstream>; - using wfstream = basic_fstream>; - - _GLIBCXX_END_NAMESPACE_VERSION - - _GLIBCXX_BEGIN_NAMESPACE_CONTAINER - - // - template - class bitset; - - // - template - struct array; - - _GLIBCXX_END_NAMESPACE_CONTAINER -} // namespace std_GLIBCXX_VISIBILITY(default) - -#elif defined(STDFWD_IS_MSVC) - -_STD_BEGIN - -using size_t = decltype(sizeof(0)); - -// -template -class initializer_list; - -// -template -struct pair; - -// -template -class tuple; - -// -class any; - -// -template -class optional; -struct nullopt_t; - -// -template -class variant; -struct monostate; - -// -template -class shared_ptr; -template -struct default_delete; -template -class unique_ptr; -template -class weak_ptr; -template -class allocator; - -// -template -class complex; - -// -template -class valarray; - -// -class random_device; - -// -template -struct atomic; -struct atomic_flag; - -// -class mutex; -class timed_mutex; -class recursive_mutex; -class recursive_timed_mutex; - -// -class shared_mutex; -class shared_timed_mutex; - -// -class thread; - -// -template -class future; -template -class shared_future; -template -class packaged_task; -template -class promise; - -// -class condition_variable; -class condition_variable_any; - -// -template -struct char_traits; -template -class basic_string; -using string = basic_string, allocator>; -using wstring = basic_string, allocator>; -using u16string = basic_string, allocator>; -using u32string = basic_string, allocator>; - -// -template -class basic_string_view; -using string_view = basic_string_view>; -using wstring_view = basic_string_view>; -using u16string_view = basic_string_view>; -using u32string_view = basic_string_view>; - -// -template -class function; -template -struct hash; -template -struct equal_to; -template -struct not_equal_to; -template -struct greater; -template -struct less; -template -struct greater_equal; -template -struct less_equal; - -// - not in container for some reason -template -class stack; - -// - not in container for some reason -template -class queue; -template -class priority_queue; - -// -template -class vector; - -// -template -class deque; - -// -template -class list; - -// -template -class regex_traits; -template -class basic_regex; -using regex = basic_regex>; -template -class sub_match; -template -class match_results; - -// -template -class forward_list; - -// -template -class map; -template -class multimap; - -// -template -class set; -template -class multiset; - -// -template -class unordered_map; -template -class unordered_multimap; - -// -template -class unordered_set; -template -class unordered_multiset; - -#if __has_include() -namespace filesystem -{ -// -class path; -} - -#elif __has_include() -namespace experimental -{ - namespace filesystem - { - // - class path; - } -} -#endif - -// -class ios_base; -template -class basic_ios; -template -class basic_streambuf; -template -class basic_istream; -template -class basic_ostream; -template -class basic_iostream; - -template -class basic_stringbuf; -template -class basic_istringstream; -template -class basic_ostringstream; -template -class basic_stringstream; - -template -class basic_filebuf; -template -class basic_ifstream; -template -class basic_ofstream; -template -class basic_fstream; -template -class istreambuf_iterator; -template -class ostreambuf_iterator; - -using ios = basic_ios>; -using wios = basic_ios>; - -using streambuf = basic_streambuf>; -using istream = basic_istream>; -using ostream = basic_ostream>; -using iostream = basic_iostream>; - -using stringbuf = basic_stringbuf, allocator>; -using istringstream = basic_istringstream, allocator>; -using ostringstream = basic_ostringstream, allocator>; -using stringstream = basic_stringstream, allocator>; - -using filebuf = basic_filebuf>; -using ifstream = basic_ifstream>; -using ofstream = basic_ofstream>; -using fstream = basic_fstream>; - -using wstreambuf = basic_streambuf>; -using wistream = basic_istream>; -using wostream = basic_ostream>; -using wiostream = basic_iostream>; - -using wstringbuf = basic_stringbuf, allocator>; -using wistringstream = basic_istringstream, allocator>; -using wostringstream = basic_ostringstream, allocator>; -using wstringstream = basic_stringstream, allocator>; - -using wfilebuf = basic_filebuf>; -using wifstream = basic_ifstream>; -using wofstream = basic_ofstream>; -using wfstream = basic_fstream>; - -// -template -class bitset; - -// -template -class array; -_STD_END - -#elif defined(STDFWD_IS_LIBCPP) - -namespace std { - - // -template -class _LIBCPP_TEMPLATE_VIS initializer_list; - -} - -_LIBCPP_BEGIN_NAMESPACE_STD - -typedef __PTRDIFF_TYPE__ ptrdiff_t; -typedef __SIZE_TYPE__ size_t; - -// -template -struct pair; - -// -template -class tuple; - -// -class any; - -// -template -class optional; -struct nullopt_t; - -// -template -class variant; -struct monostate; - -// -template -class shared_ptr; -template -struct default_delete; -template -class unique_ptr; -template -class weak_ptr; -template -class allocator; - -// -template -struct complex; - -// -template -class valarray; - -// -class random_device; - -// -template -struct atomic; -struct atomic_flag; - -// -class mutex; -class timed_mutex; -class recursive_mutex; -class recursive_timed_mutex; - -// -class shared_mutex; -class shared_timed_mutex; - -// -class thread; - -// -template -class future; -template -class shared_future; -template -class packaged_task; -template -class promise; - -// -class condition_variable; -inline namespace _V2 -{ -class condition_variable_any; -} - -// -template -struct char_traits; -template -class _LIBCPP_TEMPLATE_VIS basic_string; - -using string = basic_string, allocator>; -using wstring = basic_string, allocator>; -using u16string = basic_string, allocator>; -using u32string = basic_string, allocator>; - -// -template -class basic_string_view; -using string_view = basic_string_view>; -using wstring_view = basic_string_view>; -using u16string_view = basic_string_view>; -using u32string_view = basic_string_view>; - -// -template -class function; -template -struct hash; -template -struct equal_to; -template -struct not_equal_to; -template -struct greater; -template -struct less; -template -struct greater_equal; -template -struct less_equal; - -// - not in container for some reason -template -class stack; - -// - not in container for some reason -template -class queue; -template -class priority_queue; - -// -template -class vector; - -// -template -class deque; - -// -template -class list; - -// -template -struct regex_traits; -template -class basic_regex; -using regex = basic_regex>; -template -class sub_match; -template -class match_results; - -// -template -class forward_list; - -// -template -class map; -template -class multimap; - -// -template -class set; -template -class multiset; - -// -template -class unordered_map; -template -class unordered_multimap; - -// -template -class unordered_set; -template -class unordered_multiset; - -namespace experimental -{ - namespace filesystem - { - class path; - } -} - -// -class ios_base; -template -class basic_ios; -template -class basic_streambuf; -template -class basic_istream; -template -class basic_ostream; -template -class basic_iostream; - -template -class basic_stringbuf; -template -class basic_istringstream; -template -class basic_ostringstream; -template -class basic_stringstream; - -template -class basic_filebuf; -template -class basic_ifstream; -template -class basic_ofstream; -template -class basic_fstream; -template -class istreambuf_iterator; -template -class ostreambuf_iterator; - -using ios = basic_ios>; -using wios = basic_ios>; - -using streambuf = basic_streambuf>; -using istream = basic_istream>; -using ostream = basic_ostream>; -using iostream = basic_iostream>; - -using stringbuf = basic_stringbuf, allocator>; -using istringstream = basic_istringstream, allocator>; -using ostringstream = basic_ostringstream, allocator>; -using stringstream = basic_stringstream, allocator>; - -using filebuf = basic_filebuf>; -using ifstream = basic_ifstream>; -using ofstream = basic_ofstream>; -using fstream = basic_fstream>; - -using wstreambuf = basic_streambuf>; -using wistream = basic_istream>; -using wostream = basic_ostream>; -using wiostream = basic_iostream>; - -using wstringbuf = basic_stringbuf, allocator>; -using wistringstream = basic_istringstream, allocator>; -using wostringstream = basic_ostringstream, allocator>; -using wstringstream = basic_stringstream, allocator>; - -using wfilebuf = basic_filebuf>; -using wifstream = basic_ifstream>; -using wofstream = basic_ofstream>; -using wfstream = basic_fstream>; - - -template -class _LIBCPP_TEMPLATE_VIS bitset; - -template -struct _LIBCPP_TEMPLATE_VIS array; - -_LIBCPP_END_NAMESPACE_STD - -_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM - -// -class path; - -_LIBCPP_END_NAMESPACE_FILESYSTEM - -#else -#error "not implemented" - -#endif - -// shared typedefs -namespace std -{ -// -using atomic_bool = atomic; -using atomic_char = atomic; -using atomic_schar = atomic; -using atomic_uchar = atomic; -using atomic_short = atomic; -using atomic_ushort = atomic; -using atomic_int = atomic; -using atomic_uint = atomic; -using atomic_long = atomic; -using atomic_ulong = atomic; -using atomic_llong = atomic; -using atomic_ullong = atomic; -using atomic_char16_t = atomic; -using atomic_char32_t = atomic; -using atomic_wchar_t = atomic; - -using atomic_int8_t = atomic; -using atomic_uint8_t = atomic; -using atomic_int16_t = atomic; -using atomic_uint16_t = atomic; -using atomic_int32_t = atomic; -using atomic_uint32_t = atomic; -using atomic_int64_t = atomic; -using atomic_uint64_t = atomic; - -using atomic_int_least8_t = atomic; -using atomic_uint_least8_t = atomic; -using atomic_int_least16_t = atomic; -using atomic_uint_least16_t = atomic; -using atomic_int_least32_t = atomic; -using atomic_uint_least32_t = atomic; -using atomic_int_least64_t = atomic; -using atomic_uint_least64_t = atomic; - -using atomic_int_fast8_t = atomic; -using atomic_uint_fast8_t = atomic; -using atomic_int_fast16_t = atomic; -using atomic_uint_fast16_t = atomic; -using atomic_int_fast32_t = atomic; -using atomic_uint_fast32_t = atomic; -using atomic_int_fast64_t = atomic; -using atomic_uint_fast64_t = atomic; - -using atomic_intptr_t = atomic; -using atomic_uintptr_t = atomic; -using atomic_size_t = atomic; -using atomic_ptrdiff_t = atomic; -using atomic_intmax_t = atomic; -using atomic_uintmax_t = atomic; -} - -// dedicated forward declaration namespace -// (provides proper default template arguments) -namespace stdfwd -{ -// -//using std::initializer_list; - -// -using std::pair; - -// -using std::tuple; - -// -using std::any; - -// -using std::nullopt_t; -using std::optional; - -// -using std::monostate; -using std::variant; - -// -using std::complex; - -// -using std::valarray; - -// -using std::random_device; - -// -using std::atomic; -using std::atomic_flag; - -// named typedefs -using std::atomic_bool; -using std::atomic_char; -using std::atomic_char16_t; -using std::atomic_char32_t; -using std::atomic_int; -using std::atomic_llong; -using std::atomic_long; -using std::atomic_schar; -using std::atomic_short; -using std::atomic_uchar; -using std::atomic_uint; -using std::atomic_ullong; -using std::atomic_ulong; -using std::atomic_ushort; -using std::atomic_wchar_t; - -using std::atomic_int16_t; -using std::atomic_int32_t; -using std::atomic_int64_t; -using std::atomic_int8_t; -using std::atomic_uint16_t; -using std::atomic_uint32_t; -using std::atomic_uint64_t; -using std::atomic_uint8_t; - -using std::atomic_int_least16_t; -using std::atomic_int_least32_t; -using std::atomic_int_least64_t; -using std::atomic_int_least8_t; -using std::atomic_uint_least16_t; -using std::atomic_uint_least32_t; -using std::atomic_uint_least64_t; -using std::atomic_uint_least8_t; - -using std::atomic_int_fast16_t; -using std::atomic_int_fast32_t; -using std::atomic_int_fast64_t; -using std::atomic_int_fast8_t; -using std::atomic_uint_fast16_t; -using std::atomic_uint_fast32_t; -using std::atomic_uint_fast64_t; -using std::atomic_uint_fast8_t; - -using std::atomic_intmax_t; -using std::atomic_intptr_t; -using std::atomic_ptrdiff_t; -using std::atomic_size_t; -using std::atomic_uintmax_t; -using std::atomic_uintptr_t; - -// -using std::mutex; -using std::recursive_mutex; -using std::recursive_timed_mutex; -using std::timed_mutex; - -// -using std::shared_mutex; -using std::shared_timed_mutex; - -// -using std::thread; - -// -using std::future; -using std::packaged_task; -using std::promise; -using std::shared_future; - -// -using std::condition_variable; -using std::condition_variable_any; - -// -template > -using basic_string_view = std::basic_string_view<_CharT, _Traits>; -using std::string_view; -using std::u16string_view; -using std::u32string_view; -using std::wstring_view; - -// -using std::allocator; -using std::shared_ptr; -using std::weak_ptr; -template > -using unique_ptr = std::unique_ptr<_Tp, _Dp>; - -// -using std::function; -using std::hash; -template -using equal_to = std::equal_to<_Tp>; -template -using not_equal_to = std::not_equal_to<_Tp>; -template -using greater = std::greater<_Tp>; -template -using less = std::less<_Tp>; -template -using greater_equal = std::greater_equal<_Tp>; -template -using less_equal = std::less_equal<_Tp>; - -// -template , typename Allocator = std::allocator> -using basic_string = std::basic_string; -using std::string; -using std::u16string; -using std::u32string; -using std::wstring; - -// -template > -using vector = std::vector<_Tp, _Alloc>; - -// -template > -using deque = std::deque<_Tp, _Alloc>; - -// -template > -using list = std::list<_Tp, _Alloc>; - -// -using std::regex_traits; -template > -using basic_regex = std::basic_regex<_Ch_type, _Rx_traits>; -using std::regex; -using std::sub_match; -template >> -using match_results = std::match_results<_Bi_iter, _Alloc>; - -// -template > -using forward_list = std::forward_list<_Tp, _Alloc>; - -// -template , typename _Alloc = std::allocator>> -using map = std::map<_Key, _Tp, _Compare, _Alloc>; -template , typename _Alloc = std::allocator>> -using multimap = std::multimap<_Key, _Tp, _Compare, _Alloc>; - -// -template , typename _Alloc = std::allocator<_Key>> -using set = std::set<_Key, _Compare, _Alloc>; -template , typename _Alloc = std::allocator<_Key>> -using multiset = std::multiset<_Key, _Compare, _Alloc>; - -// -template , typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator>> -using unordered_map = std::unordered_map<_Key, _Tp, _Hash, _Pred, _Alloc>; -template , typename _Pred = std::equal_to<_Key>, typename _Alloc = std::allocator>> -using unordered_multimap = std::unordered_multimap<_Key, _Tp, _Hash, _Pred, _Alloc>; - -// -template , typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value>> -using unordered_set = std::unordered_set<_Value, _Hash, _Pred, _Alloc>; -template , typename _Pred = std::equal_to<_Value>, typename _Alloc = std::allocator<_Value>> -using unordered_multiset = std::unordered_multiset<_Value, _Hash, _Pred, _Alloc>; - -// -template > -using stack = std::stack<_Tp, _Sequence>; - -// -template > -using queue = std::queue<_Tp, _Sequence>; -template , typename _Compare = less> -using priority_queue = std::priority_queue<_Tp, _Sequence, _Compare>; - -// -using std::bitset; - -// -using std::array; - -// -using std::char_traits; -template > -using basic_ios = std::basic_ios; -template > -using basic_streambuf = std::basic_streambuf; -template > -using basic_istream = std::basic_istream; -template > -using basic_ostream = std::basic_ostream; -template > -using basic_iostream = std::basic_iostream; -template , class Allocator = allocator> -using basic_stringbuf = std::basic_stringbuf; - -template , class Allocator = allocator> -using basic_istringstream = std::basic_istringstream; -template , class Allocator = allocator> -using basic_ostringstream = std::basic_ostringstream; -template , class Allocator = allocator> -using basic_stringstream = std::basic_stringstream; - -template > -using basic_filebuf = std::basic_filebuf; -template > -using basic_ifstream = std::basic_ifstream; -template > -using basic_ofstream = std::basic_ofstream; -template > -using basic_fstream = std::basic_fstream; - -template > -using istreambuf_iterator = std::istreambuf_iterator; -template > -using ostreambuf_iterator = std::ostreambuf_iterator; - -using ios = basic_ios; -using wios = basic_ios; - -using streambuf = basic_streambuf; -using istream = basic_istream; -using ostream = basic_ostream; -using iostream = basic_iostream; - -using stringbuf = basic_stringbuf; -using istringstream = basic_istringstream; -using ostringstream = basic_ostringstream; -using stringstream = basic_stringstream; - -using filebuf = basic_filebuf; -using ifstream = basic_ifstream; -using ofstream = basic_ofstream; -using fstream = basic_fstream; - -using wstreambuf = basic_streambuf; -using wistream = basic_istream; -using wostream = basic_ostream; -using wiostream = basic_iostream; - -using wstringbuf = basic_stringbuf; -using wistringstream = basic_istringstream; -using wostringstream = basic_ostringstream; -using wstringstream = basic_stringstream; - -using wfilebuf = basic_filebuf; -using wifstream = basic_ifstream; -using wofstream = basic_ofstream; -using wfstream = basic_fstream; - -namespace filesystem -{ -// -#ifdef _VSTD_FS -using _VSTD_FS::path; -#else -using std::filesystem::path; -#endif -} - -} - -namespace stdfs -{ - #if __has_include() - #ifdef _VSTD_FS - using path = _VSTD_FS::path; - #else - using std::filesystem::path; - #endif - #elif __has_include() - using path = std::experimental::filesystem::path; - #else - #error Compiler does not have or - #endif -} - diff --git a/src/3rd-part/std_fs/include/std_fs b/src/3rd-part/std_fs/include/std_fs index 914aba5..94d3a43 100644 --- a/src/3rd-part/std_fs/include/std_fs +++ b/src/3rd-part/std_fs/include/std_fs @@ -44,9 +44,6 @@ namespace fs_real = std::filesystem; namespace fs_real = std::experimental::filesystem; #endif -#if __cpp_lib_filesystem >= 201606 -#endif - using path = fs_real::path; using directory_iterator = fs_real::directory_iterator; #ifndef _MSC_VER diff --git a/src/3rd-part/stdfwd/include/stdfwd.hh b/src/3rd-part/stdfwd/include/stdfwd.hh new file mode 100644 index 0000000..98fbe3c --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd.hh @@ -0,0 +1,43 @@ +#include "stdfwd/array" +#include "stdfwd/atomic" +#include "stdfwd/bitset" +#include "stdfwd/chrono" +#include "stdfwd/clocale" +#include "stdfwd/complex" +#include "stdfwd/condition_variable" +#include "stdfwd/deque" +#include "stdfwd/exception" +#include "stdfwd/filesystem" +#include "stdfwd/forward_list" +#include "stdfwd/functional" +#include "stdfwd/future" +#include "stdfwd/initializer_list" +#include "stdfwd/iterator" +#include "stdfwd/list" +#include "stdfwd/locale" +#include "stdfwd/map" +#include "stdfwd/memory" +#include "stdfwd/mutex" +#include "stdfwd/new" +#include "stdfwd/queue" +#include "stdfwd/random" +#include "stdfwd/ratio" +#include "stdfwd/regex" +#include "stdfwd/scoped_allocator" +#include "stdfwd/set" +#include "stdfwd/size_t" +#include "stdfwd/stack" +#include "stdfwd/stdexcept" +#include "stdfwd/string" +#include "stdfwd/system_error" +#include "stdfwd/thread" +#include "stdfwd/tuple" +#include "stdfwd/type_traits" +#include "stdfwd/typeindex" +#include "stdfwd/typeinfo" +#include "stdfwd/unordered_map" +#include "stdfwd/unordered_set" +#include "stdfwd/utility" +#include "stdfwd/valarray" +#include "stdfwd/vector" + diff --git a/src/3rd-part/stdfwd/include/stdfwd/array b/src/3rd-part/stdfwd/include/stdfwd/array new file mode 100644 index 0000000..34b633f --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/array @@ -0,0 +1,23 @@ +#pragma once + +#include "stdfwd_details.hpp" + +#include "size_t" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T, std::size_t N> + struct array; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::array; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/atomic b/src/3rd-part/stdfwd/include/stdfwd/atomic new file mode 100644 index 0000000..afbea7a --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/atomic @@ -0,0 +1,57 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > struct atomic; + + using atomic_bool = atomic; + using atomic_char = atomic; + using atomic_schar = atomic; + using atomic_uchar = atomic; + using atomic_short = atomic; + using atomic_ushort = atomic; + using atomic_int = atomic; + using atomic_uint = atomic; + using atomic_long = atomic; + using atomic_ulong = atomic; + using atomic_llong = atomic; + using atomic_ullong = atomic; + using atomic_char16_t = atomic; + using atomic_char32_t = atomic; + using atomic_wchar_t = atomic; + + class atomic_flag; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd { + + template< class T > + using atomic = std::atomic< T >; + + using std::atomic_bool; + using std::atomic_char; + using std::atomic_schar; + using std::atomic_uchar; + using std::atomic_short; + using std::atomic_ushort; + using std::atomic_int; + using std::atomic_uint; + using std::atomic_long; + using std::atomic_ulong; + using std::atomic_llong; + using std::atomic_ullong; + using std::atomic_char16_t; + using std::atomic_char32_t; + using std::atomic_wchar_t; + + using std::atomic_flag; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/bitset b/src/3rd-part/stdfwd/include/stdfwd/bitset new file mode 100644 index 0000000..3844eca --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/bitset @@ -0,0 +1,24 @@ +#pragma once + +#include "stdfwd_details.hpp" + +#include "size_t" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< std::size_t N > + class bitset; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::bitset; +} + +//------------------------------------------------------------------------------ + diff --git a/src/3rd-part/stdfwd/include/stdfwd/chrono b/src/3rd-part/stdfwd/include/stdfwd/chrono new file mode 100644 index 0000000..0e9ecbc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/chrono @@ -0,0 +1,69 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_LIBSTDCPP + #define STDFWD_BEGIN_CHRONO_CLOCKS inline namespace _V2 { + #define STDFWD_END_CHRONO_CLOCKS } +#else + #define STDFWD_BEGIN_CHRONO_CLOCKS + #define STDFWD_END_CHRONO_CLOCKS +#endif + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + +namespace chrono +{ + template class duration; + template class time_point; + template struct treat_as_floating_point; + template struct duration_values; + + STDFWD_BEGIN_CHRONO_CLOCKS + + class system_clock; + class steady_clock; + + #if defined(STDFWD_IS_LIBSTDCPP) + using high_resolution_clock = system_clock; + #elif defined(STDFWD_IS_LIBCPP) + using high_resolution_clock = steady_clock; + #elif defined(STDFWD_IS_MSVC) + using high_resolution_clock = steady_clock; + #else + class high_resolution_clock; + #endif + + STDFWD_END_CHRONO_CLOCKS + +} +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd { +namespace chrono { + + template + using treat_as_floating_point = std::chrono::treat_as_floating_point< Rep >; + + template + using duration = std::chrono::duration< Rep, Period >; + + template + using time_point = std::chrono::time_point< Clock, Duration >; + + template + using duration_values = std::chrono::duration_values< Rep >; + + using std::chrono::system_clock; + using std::chrono::steady_clock; + using std::chrono::high_resolution_clock; +} +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/clocale b/src/3rd-part/stdfwd/include/stdfwd/clocale new file mode 100644 index 0000000..fec0011 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/clocale @@ -0,0 +1,22 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +struct lconv; + +STDFWD_STD_BEGIN + + using ::lconv; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::lconv; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/complex b/src/3rd-part/stdfwd/include/stdfwd/complex new file mode 100644 index 0000000..782c936 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/complex @@ -0,0 +1,21 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template class complex; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template + using complex = std::complex; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/condition_variable b/src/3rd-part/stdfwd/include/stdfwd/condition_variable new file mode 100644 index 0000000..8069bbc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/condition_variable @@ -0,0 +1,38 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_LIBSTDCPP + #define STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_BEGIN inline namespace _V2 { + #define STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_END } +#else + #define STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_BEGIN + #define STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_END +#endif + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class condition_variable; + + STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_BEGIN + class condition_variable_any; + STDFWD_CONDITION_VARIABLE_ANY_NANESPACE_END + + enum class cv_status; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::condition_variable; + using std::condition_variable_any; + using std::cv_status; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/deque b/src/3rd-part/stdfwd/include/stdfwd/deque new file mode 100644 index 0000000..39f2a27 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/deque @@ -0,0 +1,24 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + template< class T, class Allocator > + class deque; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using deque = std::deque< T, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/exception b/src/3rd-part/stdfwd/include/stdfwd/exception new file mode 100644 index 0000000..a70cbbd --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/exception @@ -0,0 +1,24 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_PURE_BEGIN + + class exception; + class bad_exception; + class nested_exception; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::exception; + using std::bad_exception; + using std::nested_exception; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/filesystem b/src/3rd-part/stdfwd/include/stdfwd/filesystem new file mode 100644 index 0000000..9d43f1b --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/filesystem @@ -0,0 +1,96 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_LIBCPP + #define STDFWD_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + #define STDFWD_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_FILESYSTEM +#else + #define STDFWD_BEGIN_NAMESPACE_FILESYSTEM \ + STDFWD_STD_BEGIN \ + namespace filesystem { \ + + + #define STDFWD_END_NAMESPACE_FILESYSTEM } STDFWD_STD_END +#endif + +//------------------------------------------------------------------------------ + +STDFWD_BEGIN_NAMESPACE_FILESYSTEM + +STDFWD_CPP11_INLINE_BEGIN + + class path; + class filesystem_error; + class directory_entry; + class directory_iterator; + class recursive_directory_iterator; + +STDFWD_CPP11_END + + class file_status; + struct space_info; + + #ifdef STDFWD_IS_MSVC + enum class file_type; + #else + enum class file_type : signed char; + #endif + + #ifdef STDFWD_IS_MSVC + enum class perms; + #else + enum class perms : unsigned; + #endif + + #if defined(STDFWD_IS_LIBCPP) + enum class perm_options : unsigned char; + #elif defined(STDFWD_IS_MSVC) + enum class perm_options; + #else + enum class perm_options : unsigned; + #endif + + #ifdef STDFWD_IS_MSVC + enum class copy_options; + #else + enum class copy_options : unsigned short; + #endif + + #ifdef STDFWD_IS_MSVC + enum class directory_options; + #else + enum class directory_options : unsigned char; + #endif + +STDFWD_END_NAMESPACE_FILESYSTEM + + +//------------------------------------------------------------------------------ + +namespace stdfwd { +namespace filesystem { + +#ifdef STDFWD_IS_CPP17 + + using std::filesystem::path; + using std::filesystem::filesystem_error; + using std::filesystem::directory_entry; + using std::filesystem::directory_iterator; + using std::filesystem::recursive_directory_iterator; + using std::filesystem::file_status; + + using std::filesystem::space_info; + + using std::filesystem::file_type; + using std::filesystem::perms; + using std::filesystem::perm_options; + using std::filesystem::copy_options; + using std::filesystem::directory_options; + +#endif +}} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/forward_list b/src/3rd-part/stdfwd/include/stdfwd/forward_list new file mode 100644 index 0000000..12102cc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/forward_list @@ -0,0 +1,24 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + template< class T, class Allocator > + class forward_list; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using forward_list = std::forward_list< T, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/functional b/src/3rd-part/stdfwd/include/stdfwd/functional new file mode 100644 index 0000000..3b46f86 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/functional @@ -0,0 +1,84 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class function; + template< class T > class reference_wrapper; + + template< class T > struct equal_to; + template< class T > struct not_equal_to; + template< class T > struct greater; + template< class T > struct less; + template< class T > struct greater_equal; + template< class T > struct less_equal; + + template< class T > struct plus; + template< class T > struct minus; + template< class T > struct multiplies; + template< class T > struct divides; + template< class T > struct modulus; + template< class T > struct negate; + + template< class T > struct logical_and; + template< class T > struct logical_or; + template< class T > struct logical_not; + + template< class T > struct bit_and; + template< class T > struct bit_or; + template< class T > struct bit_xor; + template< class T > struct bit_not; + + template< class T > struct is_bind_expression; + template< class T > struct is_placeholder; + + class bad_function_call; + + template< class T > struct hash; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::function; + + using std::reference_wrapper; + + using std::equal_to; + using std::not_equal_to; + using std::greater; + using std::less; + using std::greater_equal; + using std::less_equal; + + using std::plus; + using std::minus; + using std::multiplies; + using std::divides; + using std::modulus; + using std::negate; + + using std::logical_and; + using std::logical_or; + using std::logical_not; + + using std::bit_and; + using std::bit_or; + using std::bit_xor; + using std::bit_not; + + using std::is_bind_expression; + using std::is_placeholder; + + using std::bad_function_call; + + using std::function; + + using std::hash; + +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/future b/src/3rd-part/stdfwd/include/stdfwd/future new file mode 100644 index 0000000..bbf4af2 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/future @@ -0,0 +1,54 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class R > class promise; + + template< class R > class packaged_task; + template< class R, class ...Args > + class packaged_task; + + template< class T > class future; + + template< class T > class shared_future; + + enum class launch; + + enum class future_status; + + class future_error; + + enum class future_errc; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class R > + using promise = std::promise< R >; + + template< class R > + using packaged_task = std::packaged_task< R >; + + template< class T > + using future = std::future< T >; + + template< class T > + using shared_future = std::shared_future< T >; + + using std::launch; + + using std::future_status; + + using std::future_error; + + using std::future_errc; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/initializer_list b/src/3rd-part/stdfwd/include/stdfwd/initializer_list new file mode 100644 index 0000000..b2cd117 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/initializer_list @@ -0,0 +1,21 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_PURE_BEGIN + + template< class T > class STDFWD_TEMPLATE_VISIBILITY initializer_list; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T > + using initializer_list = std::initializer_list< T >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/iterator b/src/3rd-part/stdfwd/include/stdfwd/iterator new file mode 100644 index 0000000..d9b60cb --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/iterator @@ -0,0 +1,104 @@ +#pragma once + +#include "stdfwd_details.hpp" + +#include "ptrdiff_t" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + #ifdef STDFWD_IS_MSVC + template< class CharT > struct char_traits; + #else + template< class CharT > class char_traits; + #endif + + template< class Iter > struct iterator_traits; + + template + struct iterator; + + template< class Iter > class reverse_iterator; + template< class Iter > class move_iterator; + + template< class Container > class back_insert_iterator; + template< class Container > class front_insert_iterator; + template< class Container > class insert_iterator; + + template< class T, class CharT, class Traits, class Distance> + class istream_iterator; + + template< class T, class CharT, class Traits > + class ostream_iterator; + + template< class CharT, class Traits > class istreambuf_iterator; + template< class CharT, class Traits > class ostreambuf_iterator; + + struct input_iterator_tag; + struct output_iterator_tag; + struct forward_iterator_tag; + struct bidirectional_iterator_tag; + struct random_access_iterator_tag; + struct contiguous_iterator_tag; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class Iter > + using iterator_traits = std::iterator_traits< Iter >; + + template< + class Category, + class T, + class Distance = std::ptrdiff_t, + class Pointer = T*, + class Reference = T& + > + using iterator = std::iterator< Category, T, Distance, Pointer, Reference >; + + template< class T, + class CharT = char, + class Traits = std::char_traits, + class Distance = std::ptrdiff_t + > + using istream_iterator = std::istream_iterator< T, CharT, Traits, Distance>; + + template< class T, + class CharT = char, + class Traits = std::char_traits> + using ostream_iterator = std::ostream_iterator< T, CharT, Traits >; + + template< class CharT, class Traits = std::char_traits > + using istreambuf_iterator = std::istreambuf_iterator< CharT, Traits >; + + template< class CharT, class Traits = std::char_traits > + using ostreambuf_iterator = std::ostreambuf_iterator< CharT, Traits >; + + template< class Iter > + using reverse_iterator = std::reverse_iterator< Iter >; + + template< class Iter > + using move_iterator = std::move_iterator< Iter >; + + template< class Container > + using back_insert_iterator = std::back_insert_iterator< Container >; + + template< class Container > + using front_insert_iterator = std::front_insert_iterator< Container >; + + template< class Container > + using insert_iterator = std::insert_iterator< Container >; + + using std::input_iterator_tag; + using std::output_iterator_tag; + using std::forward_iterator_tag; + using std::bidirectional_iterator_tag; + using std::random_access_iterator_tag; + using std::contiguous_iterator_tag; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/list b/src/3rd-part/stdfwd/include/stdfwd/list new file mode 100644 index 0000000..b5fa109 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/list @@ -0,0 +1,28 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + STDFWD_CPP11_INLINE_BEGIN + + template< class T, class Allocator > + class list; + + STDFWD_CPP11_END + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using list = std::list< T, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/locale b/src/3rd-part/stdfwd/include/stdfwd/locale new file mode 100644 index 0000000..1914424 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/locale @@ -0,0 +1,157 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + #ifdef STDFWD_IS_MSVC + template< class CharT > struct char_traits; + #else + template< class CharT > class char_traits; + #endif + + template< class T > class allocator; + + template< class CharT, class Traits > class istreambuf_iterator; + template< class CharT, class Traits > class ostreambuf_iterator; + + STDFWD_CPP11_BEGIN + template< class Codecvt, class Elem, class Wide_alloc, class Byte_alloc > + class wstring_convert; + STDFWD_CPP11_END + + template< class Codecvt, class Elem, class Tr > + class wbuffer_convert; + + class locale; + class ctype_base; + template< class charT > class ctype; + + class codecvt_base; + template< class internT, class externT, class stateT > class codecvt; + template< class internT, class externT, class stateT > class codecvt_byname; + + template< class charT, class InputIterator > class num_get; + template< class charT, class OutputIterator > class num_put; + + STDFWD_CPP11_BEGIN + template< class charT > class numpunct; + template< class charT > class numpunct_byname; + + template< class charT > class collate; + template< class charT > class collate_byname; + STDFWD_CPP11_END + + class time_base; + STDFWD_CPP11_BEGIN + template< class charT, class InputIterator > class time_get; + template< class charT, class InputIterator > class time_get_byname; + STDFWD_CPP11_END + template< class charT, class OutputIterator > class time_put; + template< class charT, class OutputIterator > class time_put_byname; + + class money_base; + STDFWD_CPP11_BEGIN + template< class charT, class InputIterator > class money_get; + template< class charT, class OutputIterator > class money_put; + template< class charT, bool Intl > class moneypunct; + template< class charT, bool Intl > class moneypunct_byname; + STDFWD_CPP11_END + + class messages_base; + STDFWD_CPP11_BEGIN + template< class charT > class messages; + template< class charT > class messages_byname; + STDFWD_CPP11_END + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class CharT, class Traits = std::char_traits > + using istreambuf_iterator = std::istreambuf_iterator< CharT, Traits >; + + template< class CharT, class Traits = std::char_traits > + using ostreambuf_iterator = std::ostreambuf_iterator< CharT, Traits >; + + template< class Codecvt, + class Elem = wchar_t, + class Wide_alloc = std::allocator, + class Byte_alloc = std::allocator + > using wstring_convert = std::wstring_convert< + Codecvt, + Elem, + Wide_alloc, + Byte_alloc + >; + + template > + using wbuffer_convert = std::wbuffer_convert< Codecvt, Elem, Tr >; + + using std::locale; + using std::ctype_base; + + template< class charT > + using ctype = std::ctype< charT >; + + using std::codecvt_base; + template< class internT, class externT, class stateT > + using codecvt = std::codecvt< internT, externT, stateT >; + template< class internT, class externT, class stateT > + using codecvt_byname = std::codecvt_byname< internT, externT, stateT >; + + template < + class charT, + class InputIterator = istreambuf_iterator + > using num_get = std::num_get< charT, InputIterator >; + + template < + class charT, + class OutputIterator = ostreambuf_iterator + > using num_put = std::num_put< charT, OutputIterator >; + + template< class charT > + using numpunct = std::numpunct< charT >; + template< class charT > + using numpunct_byname = std::numpunct_byname< charT >; + + template< class charT > + using collate = std::collate< charT >; + template< class charT > + using collate_byname = std::collate_byname< charT >; + + using std::time_base; + template< class charT, class InputIterator = istreambuf_iterator< charT> > + using time_get = std::time_get< charT, InputIterator >; + template > + using time_get_byname = std::time_get_byname< charT, InputIterator >; + template< class charT, class OutputIterator = ostreambuf_iterator > + using time_put = std::time_put< charT, OutputIterator >; + template< class charT, class OutputIterator = ostreambuf_iterator > + using time_put_byname = std::time_put_byname< charT, OutputIterator >; + + using std::money_base; + template< class charT, class InputIterator = istreambuf_iterator > + using money_get = std::money_get< charT, InputIterator >; + template< class charT, class OutputIterator = ostreambuf_iterator > + using money_put = std::money_put< charT, OutputIterator >; + template< class charT, bool Intl = false > + using moneypunct = std::moneypunct< charT, Intl >; + template< class charT, bool Intl = false > + using moneypunct_byname = std::moneypunct_byname< charT, Intl >; + + using std::messages_base; + template< class charT > + using messages = std::messages< charT >; + template< class charT > + using messages_byname = std::messages_byname< charT >; + +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/map b/src/3rd-part/stdfwd/include/stdfwd/map new file mode 100644 index 0000000..746cd6b --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/map @@ -0,0 +1,42 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + template< class T > struct less; + template< class T1, class T2 > struct pair; + + template< class Key, class T, class Compare, class Allocator > + class map; + + template< class Key, class T, class Compare, class Allocator > + class multimap; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< + class Key, + class T, + class Compare = std::less< Key >, + class Allocator = std::allocator > + > + using map = std::map< Key, T, Compare, Allocator >; + + template< + class Key, + class T, + class Compare = std::less< Key >, + class Allocator = std::allocator > + > + using multimap = std::multimap< Key, T, Compare, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/memory b/src/3rd-part/stdfwd/include/stdfwd/memory new file mode 100644 index 0000000..84216bc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/memory @@ -0,0 +1,81 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + template< class Ptr > struct pointer_traits; + + #ifdef STDFWD_IS_LIBCPP + struct pointer_safety; + #else + enum class pointer_safety; + #endif + + template< class Alloc > struct allocator_traits; + + struct allocator_arg_t; + + template< class T, class Alloc > struct uses_allocator; + + template< class OutputIt, class T > + class raw_storage_iterator; + + template< class T, class Deleter > class unique_ptr; + + template< class T > class shared_ptr; + template< class T > class weak_ptr; + template< class T > class auto_ptr; + + template< class T > class enable_shared_from_this; + + class bad_weak_ptr; + template< class T > struct default_delete; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class Ptr > + using pointer_traits = std::pointer_traits< Ptr >; + + using std::pointer_safety; + + template< class T > + using allocator = std::allocator< T >; + + template< class Alloc > + using allocator_traits = std::allocator_traits< Alloc >; + + using std::allocator_arg_t; + + template< class T, class Alloc > + using uses_allocator = std::uses_allocator< T, Alloc >; + + template< class T, class Deleter = std::default_delete > + using unique_ptr = std::unique_ptr< T, Deleter >; + + template< class T > + using shared_ptr = std::shared_ptr< T >; + + template< class T > + using weak_ptr = std::weak_ptr< T >; + + template< class T > + using enable_shared_from_this = std::enable_shared_from_this< T >; + + using std::bad_weak_ptr; + + template< class T > + using default_delete = std::default_delete< T >; + +} + +//------------------------------------------------------------------------------ + diff --git a/src/3rd-part/stdfwd/include/stdfwd/mutex b/src/3rd-part/stdfwd/include/stdfwd/mutex new file mode 100644 index 0000000..3d65bcc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/mutex @@ -0,0 +1,45 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class mutex; + class timed_mutex; + class recursive_mutex; + class recursive_timed_mutex; + + template< class Mutex > class lock_guard; + template< class Mutex > class unique_lock; + + struct defer_lock_t; + struct try_to_lock_t; + struct adopt_lock_t; + + class once_flag; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::mutex; + using std::timed_mutex; + using std::recursive_mutex; + using std::recursive_timed_mutex; + + template< class Mutex > + using lock_guard = std::lock_guard< Mutex >; + template< class Mutex > + using unique_lock = std::unique_lock< Mutex >; + + using std::defer_lock_t; + using std::try_to_lock_t; + using std::adopt_lock_t; + using std::once_flag; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/new b/src/3rd-part/stdfwd/include/stdfwd/new new file mode 100644 index 0000000..9789757 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/new @@ -0,0 +1,29 @@ +#pragma once + +#include "stdfwd_details.hpp" + +#include "size_t" + +//------------------------------------------------------------------------------ + +STDFWD_STD_PURE_BEGIN + + class bad_alloc; + class bad_array_new_length; + + struct nothrow_t; + enum class align_val_t : std::size_t; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::bad_alloc; + using std::bad_array_new_length; + using std::nothrow_t; + using std::align_val_t; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/optional b/src/3rd-part/stdfwd/include/stdfwd/optional new file mode 100644 index 0000000..bd4987d --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/optional @@ -0,0 +1,34 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > + class optional; + struct nullopt_t; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +STDFWD_STD_PURE_BEGIN + + class bad_optional_access; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T > + using optional = std::optional< T >; + + using std::nullopt_t; + using std::bad_optional_access; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/ptrdiff_t b/src/3rd-part/stdfwd/include/stdfwd/ptrdiff_t new file mode 100644 index 0000000..d06bfa7 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/ptrdiff_t @@ -0,0 +1,25 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + #if defined(STDFWD_IS_MSVC) + + #ifdef _WIN64 + typedef __int64 ptrdiff_t; + #else + typedef int ptrdiff_t; + #endif + + #elif defined(STDFWD_IS_LIBCPP) + + typedef __PTRDIFF_TYPE__ ptrdiff_t; + + #endif + +STDFWD_STD_END + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/queue b/src/3rd-part/stdfwd/include/stdfwd/queue new file mode 100644 index 0000000..1237fe7 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/queue @@ -0,0 +1,44 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + template< class T > struct less; + + template< class T, class Allocator > class deque; + template< class T, class Allocator > class vector; + + template< class T, class Container > + class queue; + + template< class T, class Container, class Compare > + class priority_queue; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using deque = std::deque< T, Allocator >; + + template< class T, class Container = deque< T > > + using queue = std::queue< T, Container >; + + template< class T, class Allocator = std::allocator< T > > + using vector = std::vector< T, Allocator >; + + template< + class T, + class Container = vector< T >, + class Compare = std::less< typename Container::value_type > + > + using priority_queue = std::priority_queue< T, Container, Compare >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/random b/src/3rd-part/stdfwd/include/stdfwd/random new file mode 100644 index 0000000..362cee4 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/random @@ -0,0 +1,191 @@ +#pragma once + +#include "stdfwd_details.hpp" + +#include "size_t" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template + class linear_congruential_engine; + + template class mersenne_twister_engine; + + template + class subtract_with_carry_engine; + + template + class discard_block_engine; + + template + class independent_bits_engine; + + template + class shuffle_order_engine; + + + #if defined (STDFWD_IS_LIBSTDCPP) + #if __WORDSIZE == 64 + typedef unsigned long int uint_fast32_t; + typedef unsigned long int uint_fast64_t; + #else + typedef unsigned int uint_fast32_t; + __extension__ + typedef unsigned long long int uint_fast64_t; + #endif + #else + typedef unsigned int uint32_t; + typedef unsigned long long uint64_t; + + typedef uint32_t uint_fast32_t; + typedef uint64_t uint_fast64_t; + #endif + + + typedef linear_congruential_engine< + uint_fast32_t, + 16807UL, + 0UL, + 2147483647UL + > minstd_rand0; + + typedef linear_congruential_engine< + uint_fast32_t, + 48271UL, + 0UL, + 2147483647UL + > minstd_rand; + + typedef mersenne_twister_engine< + uint_fast32_t, + 32, 624, 397, 31, + 0x9908b0dfUL, 11, + 0xffffffffUL, 7, + 0x9d2c5680UL, 15, + 0xefc60000UL, 18, 1812433253UL + > mt19937; + + typedef mersenne_twister_engine< + uint_fast64_t, + 64, 312, 156, 31, + 0xb5026f5aa96619e9ULL, 29, + 0x5555555555555555ULL, 17, + 0x71d67fffeda60000ULL, 37, + 0xfff7eee000000000ULL, 43, + 6364136223846793005ULL + > mt19937_64; + + typedef subtract_with_carry_engine + ranlux24_base; + typedef subtract_with_carry_engine + ranlux48_base; + + typedef discard_block_engine ranlux24; + typedef discard_block_engine ranlux48; + typedef shuffle_order_engine knuth_b; + #if defined(STDFWD_IS_LIBSTDCPP) + typedef minstd_rand0 default_random_engine; + #elif defined(STDFWD_IS_LIBCPP) + typedef minstd_rand default_random_engine; + #elif defined(STDFWD_IS_MSVC) + typedef mt19937 default_random_engine; + #endif + + class random_device; + class seed_seq; + class bernoulli_distribution; + + template class uniform_int_distribution; + template class binomial_distribution; + template class geometric_distribution; + template class discrete_distribution; + template class negative_binomial_distribution; + template class poisson_distribution; + + template class uniform_real_distribution; + template class exponential_distribution; + template class gamma_distribution; + template class weibull_distribution; + template class extreme_value_distribution; + template class normal_distribution; + template class lognormal_distribution; + template class chi_squared_distribution; + template class cauchy_distribution; + template class fisher_f_distribution; + template class student_t_distribution; + template class piecewise_constant_distribution; + template class piecewise_linear_distribution; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template + using linear_congruential_engine = std::linear_congruential_engine< + UIntType,a,c,m + >; + + template + using mersenne_twister_engine = std::mersenne_twister_engine< + UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f + >; + + template + using subtract_with_carry_engine = std::subtract_with_carry_engine< + UIntType, w, s, r + >; + + template + using discard_block_engine = std::discard_block_engine< Engine, p, r >; + + template + using shuffle_order_engine = std::shuffle_order_engine< Engine, k >; + + using std::minstd_rand0; + using std::minstd_rand; + using std::mt19937; + using std::mt19937_64; + using std::ranlux24_base; + using std::ranlux48_base; + using std::ranlux24; + using std::ranlux48; + using std::knuth_b; + + using std::random_device; + using std::seed_seq; + using std::bernoulli_distribution; + + using uniform_int_distribution = std::uniform_int_distribution< int >; + using binomial_distribution = std::binomial_distribution< int >; + using geometric_distribution = std::geometric_distribution< int >; + using discrete_distribution = std::discrete_distribution< int >; + using negative_binomial_distribution = std::negative_binomial_distribution< int >; + using poisson_distribution = std::poisson_distribution< int >; + + using uniform_real_distribution = std::uniform_real_distribution< double >; + using exponential_distribution = std::exponential_distribution< double >; + using gamma_distribution = std::gamma_distribution< double >; + using weibull_distribution = std::weibull_distribution< double >; + using extreme_value_distribution = std::extreme_value_distribution< double >; + using normal_distribution = std::normal_distribution< double >; + using lognormal_distribution = std::lognormal_distribution< double >; + using chi_squared_distribution = std::chi_squared_distribution< double >; + using cauchy_distribution = std::cauchy_distribution< double >; + using fisher_f_distribution = std::fisher_f_distribution< double >; + using student_t_distribution = std::student_t_distribution< double >; + using piecewise_constant_distribution = std::piecewise_constant_distribution< double >; + using piecewise_linear_distribution = std::piecewise_linear_distribution< double >; + +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/ratio b/src/3rd-part/stdfwd/include/stdfwd/ratio new file mode 100644 index 0000000..986c788 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/ratio @@ -0,0 +1,80 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN +#if defined (STDFWD_IS_LIBSTDCPP) + #if __WORDSIZE == 64 + typedef long int __intmax_t; + #else + __extension__ typedef long long int __intmax_t; + #endif + typedef __intmax_t intmax_t; +#elif defined (STDFWD_IS_LIBCPP) + typedef __INTMAX_TYPE__ intmax_t; +#elif defined (STDFWD_IS_MSVC) + typedef long long int intmax_t; +#endif + + template struct ratio; + + template struct ratio_equal; + template struct ratio_not_equal; + template struct ratio_less; + template struct ratio_less_equal; + template struct ratio_greater; + template struct ratio_greater_equal; + + typedef ratio<1, 1000000000000000000> atto; + typedef ratio<1, 1000000000000000> femto; + typedef ratio<1, 1000000000000> pico; + typedef ratio<1, 1000000000> nano; + typedef ratio<1, 1000000> micro; + typedef ratio<1, 1000> milli; + typedef ratio<1, 100> centi; + typedef ratio<1, 10> deci; + typedef ratio< 10, 1> deca; + typedef ratio< 100, 1> hecto; + typedef ratio< 1000, 1> kilo; + typedef ratio< 1000000, 1> mega; + typedef ratio< 1000000000, 1> giga; + typedef ratio< 1000000000000, 1> tera; + typedef ratio< 1000000000000000, 1> peta; + typedef ratio< 1000000000000000000, 1> exa; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template using ratio = std::ratio< N, D >; + + template using ratio_equal = std::ratio_equal< R1, R2 >; + template using ratio_not_equal = std::ratio_not_equal< R1, R2 >; + template using ratio_less = std::ratio_less< R1, R2 >; + template using ratio_less_equal = std::ratio_less_equal< R1, R2 >; + template using ratio_greater = std::ratio_greater< R1, R2 >; + template using ratio_greater_equal = std::ratio_greater_equal< R1, R2 >; + + using std::atto; + using std::femto; + using std::pico; + using std::nano; + using std::micro; + using std::milli; + using std::centi; + using std::deci; + using std::deca; + using std::hecto; + using std::kilo; + using std::mega; + using std::giga; + using std::tera; + using std::peta; + using std::exa; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/regex b/src/3rd-part/stdfwd/include/stdfwd/regex new file mode 100644 index 0000000..71faeae --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/regex @@ -0,0 +1,84 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + template< class Iter > struct iterator_traits; + + class regex_error; + + STDFWD_CPP11_BEGIN + + template struct regex_traits; + template class basic_regex; + + template class sub_match; + + template + class match_results; + + template + class regex_iterator; + + template + class regex_token_iterator; + + STDFWD_CPP11_END + + using csub_match = sub_match; + using wcsub_match = sub_match; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T > + using allocator = std::allocator< T >; + + template< class Iter > + using iterator_traits = std::iterator_traits< Iter >; + + using std::regex_error; + + template + using regex_traits = std::regex_traits< CharT >; + + template > + using basic_regex = std::basic_regex< CharT, Traits >; + + template + using sub_match = std::sub_match< BiIt >; + + template>> + using match_results = std::match_results< BiIt, Allocator >; + + template< + class BiIt, + class CharT = typename iterator_traits::value_type, + class Traits = regex_traits + > + using regex_iterator = std::regex_iterator< BiIt, CharT, Traits >; + + template< + class BiIt, + class CharT = typename iterator_traits::value_type, + class Traits = regex_traits + > + using regex_token_iterator = std::regex_token_iterator< BiIt, CharT, Traits >; + + using std::csub_match; + using std::wcsub_match; + + using regex = basic_regex; + using wregex = basic_regex; + + using cmatch = match_results; + using wcmatch = match_results; + +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/scoped_allocator b/src/3rd-part/stdfwd/include/stdfwd/scoped_allocator new file mode 100644 index 0000000..b579c71 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/scoped_allocator @@ -0,0 +1,35 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + #ifdef STDFWD_IS_LIBCPP + template + class scoped_allocator_adaptor; + #else + template + class scoped_allocator_adaptor; + #endif + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + #ifdef STDFWD_IS_LIBCPP + template + using scoped_allocator_adaptor = std::scoped_allocator_adaptor< Alloc ... >; + #else + template + using scoped_allocator_adaptor = std::scoped_allocator_adaptor< + OuterAlloc, + InnerAlloc ... + >; + #endif +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/set b/src/3rd-part/stdfwd/include/stdfwd/set new file mode 100644 index 0000000..a61171b --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/set @@ -0,0 +1,39 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + template< class T > struct less; + + template< class Key, class Compare, class Allocator > + class set; + + template< class Key, class Compare, class Allocator > + class multiset; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< + class Key, + class Compare = std::less< Key >, + class Allocator = std::allocator< Key > + > + using set = std::set< Key, Compare, Allocator >; + + template< + class Key, + class Compare = std::less< Key >, + class Allocator = std::allocator< Key > + > + using multiset = std::multiset< Key, Compare, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/shared_mutex b/src/3rd-part/stdfwd/include/stdfwd/shared_mutex new file mode 100644 index 0000000..98625cc --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/shared_mutex @@ -0,0 +1,28 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class shared_mutex; + class shared_timed_mutex; + template class shared_lock; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + + using std::shared_mutex; + using std::shared_timed_mutex; + + template + using shared_lock = std::shared_lock< Mutex >; + +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/size_t b/src/3rd-part/stdfwd/include/stdfwd/size_t new file mode 100644 index 0000000..1d553ef --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/size_t @@ -0,0 +1,25 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + #if defined(STDFWD_IS_MSVC) + + #ifdef _WIN64 + typedef unsigned __int64 size_t; + #else + typedef unsigned int size_t; + #endif + + #elif defined(STDFWD_IS_LIBCPP) + + typedef __SIZE_TYPE__ size_t; + + #endif + +STDFWD_STD_END + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/stack b/src/3rd-part/stdfwd/include/stdfwd/stack new file mode 100644 index 0000000..9a2ae3e --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/stack @@ -0,0 +1,28 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + template< class T, class Allocator > class deque; + + template< class T, class Container > + class stack; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using deque = std::deque< T, Allocator >; + + template< class T, class Container = deque< T > > + using stack = std::stack< T, Container >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/std_fs b/src/3rd-part/stdfwd/include/stdfwd/std_fs new file mode 100644 index 0000000..010d7c2 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/std_fs @@ -0,0 +1,101 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_LIBCPP + #define STDFWD_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM + #define STDFWD_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_FILESYSTEM +#else +#define STDFWD_BEGIN_NAMESPACE_FILESYSTEM \ + STDFWD_STD_BEGIN \ + namespace filesystem { \ + + + #define STDFWD_END_NAMESPACE_FILESYSTEM } STDFWD_STD_END +#endif + +//------------------------------------------------------------------------------ + +STDFWD_BEGIN_NAMESPACE_FILESYSTEM + + STDFWD_CPP11_INLINE_BEGIN + class path; + STDFWD_CPP11_END + +STDFWD_END_NAMESPACE_FILESYSTEM + +//------------------------------------------------------------------------------ + +STDFWD_BEGIN_NAMESPACE_FILESYSTEM + +#if defined(STDFWD_IS_LIBSTDCPP) + + namespace experimental + { + namespace filesystem + { + inline namespace v1 + { + inline namespace __cxx11 __attribute__((__abi_tag__("cxx11"))) {} + _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE + class path; + _GLIBCXX_END_NAMESPACE_CXX11 + } + } + } + +#elif defined(STDFWD_IS_MSVC) + + #if __has_include() + namespace filesystem + { + class path; + } + + #elif __has_include() + namespace experimental + { + namespace filesystem + { + // + class path; + } + } + #endif + +#elif defined(STDFWD_IS_LIBCPP) + + namespace experimental + { + namespace filesystem + { + class path; + } + } + +#endif + +STDFWD_END_NAMESPACE_FILESYSTEM + + +//------------------------------------------------------------------------------ + +namespace stdfs { + + #if __has_include() + #ifdef _VSTD_FS + using path = _VSTD_FS::path; + #else + using std::filesystem::path; + #endif + #elif __has_include() + using path = std::experimental::filesystem::path; + #else + #error Compiler does not have or + #endif + +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/stdexcept b/src/3rd-part/stdfwd/include/stdfwd/stdexcept new file mode 100644 index 0000000..3501da1 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/stdexcept @@ -0,0 +1,36 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_PURE_BEGIN + + class logic_error; + class domain_error; + class invalid_argument; + class length_error; + class out_of_range; + class runtime_error; + class range_error; + class overflow_error; + class underflow_error; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::logic_error; + using std::domain_error; + using std::invalid_argument; + using std::length_error; + using std::out_of_range; + using std::runtime_error; + using std::range_error; + using std::overflow_error; + using std::underflow_error; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/stdfwd_details.hpp b/src/3rd-part/stdfwd/include/stdfwd/stdfwd_details.hpp new file mode 100644 index 0000000..60a66ac --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/stdfwd_details.hpp @@ -0,0 +1,111 @@ +#pragma once + +// see https://stackoverflow.com/questions/31657499/how-to-detect-stdlib-libc-in-the-preprocessor +#include + +//------------------------------------------------------------------------------ + +#if defined(_LIBCPP_VERSION) +#define STDFWD_IS_LIBCPP +#elif defined(__GLIBCXX__) +#define STDFWD_IS_LIBSTDCPP +#elif defined(_MSC_VER) +#define STDFWD_IS_MSVC +#else +#error "Unknown stdlib" +#endif + +//------------------------------------------------------------------------------ + +#if defined(STDFWD_IS_LIBSTDCPP) + +#if _GLIBCXX_USE_CXX11_ABI + #define _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE inline _GLIBCXX_BEGIN_NAMESPACE_CXX11 +#else + #define _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE +#endif + +#define STDFWD_STD_BEGIN \ +namespace std _GLIBCXX_VISIBILITY(default) \ +{ \ + _GLIBCXX_BEGIN_NAMESPACE_VERSION \ + +#define STDFWD_STD_PURE_BEGIN STDFWD_STD_BEGIN + +#define STDFWD_STD_END } // namespace std_GLIBCXX_VISIBILITY(default) +#define STDFWD_STD_PURE_END STDFWD_STD_END + +#elif defined(STDFWD_IS_MSVC) + +#define STDFWD_STD_BEGIN _STD_BEGIN +#define STDFWD_STD_PURE_BEGIN STDFWD_STD_BEGIN + +#define STDFWD_STD_END _STD_END +#define STDFWD_STD_PURE_END STDFWD_STD_END + +#elif defined(STDFWD_IS_LIBCPP) + +#define STDFWD_STD_BEGIN _LIBCPP_BEGIN_NAMESPACE_STD +#define STDFWD_STD_PURE_BEGIN namespace std { + +#define STDFWD_STD_END _LIBCPP_END_NAMESPACE_STD +#define STDFWD_STD_PURE_END } + +#else + +#error "not implemented" + +#endif + +//------------------------------------------------------------------------------ + +#ifdef _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE + #define STDFWD_CPP11_INLINE_BEGIN _GLIBCXX_BEGIN_NAMESPACE_CXX11_INLINE +#else + #define STDFWD_CPP11_INLINE_BEGIN +#endif + +#ifdef _GLIBCXX_BEGIN_NAMESPACE_CXX11 + #define STDFWD_CPP11_BEGIN _GLIBCXX_BEGIN_NAMESPACE_CXX11 +#else + #define STDFWD_CPP11_BEGIN +#endif + +#ifdef _GLIBCXX_END_NAMESPACE_CXX11 + #define STDFWD_CPP11_END _GLIBCXX_END_NAMESPACE_CXX11 +#else + #define STDFWD_CPP11_END +#endif + +//------------------------------------------------------------------------------ + +#if ( defined(STDFWD_IS_MSVC) && defined (_LIBCPP_TEMPLATE_VIS) ) + #define STDFWD_TEMPLATE_VISIBILITY _LIBCPP_TEMPLATE_VIS +#else + #define STDFWD_TEMPLATE_VISIBILITY +#endif + +//------------------------------------------------------------------------------ + +// Visual Studio has bug https://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11 +#if defined(_MSVC_LANG) + #define STDFWD_CPP_VERSION _MSVC_LANG +#elif defined(__cplusplus) + #define STDFWD_CPP_VERSION __cplusplus +#endif + +#if STDFWD_CPP_VERSION >= 201103L + #define STDFWD_IS_CPP11 +#endif + +#if STDFWD_CPP_VERSION >= 201402L + #define STDFWD_IS_CPP14 +#endif + +#if STDFWD_CPP_VERSION >= 201703L + #define STDFWD_IS_CPP17 +#endif + +#if STDFWD_CPP_VERSION >= 202002L + #define STDFWD_IS_CPP20 +#endif diff --git a/src/3rd-part/stdfwd/include/stdfwd/string b/src/3rd-part/stdfwd/include/stdfwd/string new file mode 100644 index 0000000..87cb8fa --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/string @@ -0,0 +1,73 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_CPP20 + #define STDFWD_IS_U8STRING +#endif + +#ifdef STDFWD_IS_CPP11 + #define STDFWD_IS_U16STRING + #define STDFWD_IS_U32STRING +#endif + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + template< class Char > + struct char_traits; + + STDFWD_CPP11_INLINE_BEGIN + + template< class Char, class Traits, class Allocator > + class STDFWD_TEMPLATE_VISIBILITY basic_string; + + using string = basic_string, allocator>; + using wstring = basic_string, allocator>; + + #ifdef STDFWD_IS_U8STRING + using u8string = basic_string, allocator>; + #endif + + #ifdef STDFWD_IS_U16STRING + using u16string = basic_string, allocator>; + #endif + + #ifdef STDFWD_IS_U32STRING + using u32string = basic_string, allocator>; + #endif + + STDFWD_CPP11_END + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< + class Char, + class Traits = std::char_traits, + class Allocator = std::allocator + > using basic_string = std::basic_string; + + using std::string; + using std::wstring; + + #ifdef STDFWD_IS_U8STRING + using std::u8string; + #endif + + #ifdef STDFWD_IS_U16STRING + using std::u16string; + #endif + + #ifdef STDFWD_IS_U32STRING + using std::u32string; + #endif +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/string_view b/src/3rd-part/stdfwd/include/stdfwd/string_view new file mode 100644 index 0000000..4c61223 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/string_view @@ -0,0 +1,63 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_CPP20 + #define STDFWD_IS_U8STRING +#endif + +#ifdef STDFWD_IS_CPP11 + #define STDFWD_IS_U16STRING + #define STDFWD_IS_U32STRING +#endif + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class Char > + struct char_traits; + + template< class CharT, class Traits > + class basic_string_view; + + using string_view = basic_string_view>; + using wstring_view = basic_string_view>; + #ifdef STDFWD_IS_U8STRING + using u8string_view = basic_string_view>; + #endif + + #ifdef STDFWD_IS_U16STRING + using u16string_view = basic_string_view>; + #endif + + #ifdef STDFWD_IS_U32STRING + using u32string_view = basic_string_view>; + #endif + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class CharT, class Traits = std::char_traits< CharT > > + using basic_string_view = std::basic_string_view< CharT, Traits >; + + using std::string_view; + using std::wstring_view; + + #ifdef STDFWD_IS_U8STRING + using std::u8string_view; + #endif + + #ifdef STDFWD_IS_U16STRING + using std::u16string_view; + #endif + + #ifdef STDFWD_IS_U32STRING + using std::u32string_view; + #endif +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/system_error b/src/3rd-part/stdfwd/include/stdfwd/system_error new file mode 100644 index 0000000..1273ba4 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/system_error @@ -0,0 +1,49 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_LIBSTDCPP + #define STDFWD_ERROR_CATEGORY_NAMESPACE_BEGIN inline namespace _V2 { + #define STDFWD_ERROR_CATEGORY_NAMESPACE_END } +#else + #define STDFWD_ERROR_CATEGORY_NAMESPACE_BEGIN + #define STDFWD_ERROR_CATEGORY_NAMESPACE_END +#endif + +//------------------------------------------------------------------------------ + + +STDFWD_STD_BEGIN + + STDFWD_ERROR_CATEGORY_NAMESPACE_BEGIN + class error_category; + STDFWD_ERROR_CATEGORY_NAMESPACE_END + class error_code; + class error_condition; + class system_error; + + template struct is_error_code_enum; + template struct is_error_condition_enum; + + enum class errc; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::error_category; + using std::error_code; + using std::error_condition; + using std::system_error; + + template + using is_error_code_enum = std::is_error_code_enum< T >; + template + using is_error_condition_enum = std::is_error_condition_enum< T >; + + using std::errc; +} diff --git a/src/3rd-part/stdfwd/include/stdfwd/thread b/src/3rd-part/stdfwd/include/stdfwd/thread new file mode 100644 index 0000000..e9e6d6a --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/thread @@ -0,0 +1,20 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class thread; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::thread; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/tuple b/src/3rd-part/stdfwd/include/stdfwd/tuple new file mode 100644 index 0000000..813c965 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/tuple @@ -0,0 +1,21 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class... Types > class tuple; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class... Types > + using tuple = std::tuple< Types ... >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/type_traits b/src/3rd-part/stdfwd/include/stdfwd/type_traits new file mode 100644 index 0000000..ef61ac6 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/type_traits @@ -0,0 +1,33 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T, T v > struct integral_constant; + + using true_type = integral_constant< bool, true >; + using false_type = integral_constant< bool, false >; + + template< bool B > + using bool_constant = integral_constant< bool, B >; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, T v > + using integral_constant = std::integral_constant< T, v >; + + using std::true_type; + using std::false_type; + + template< bool B > + using bool_constant = std::bool_constant< B >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/typeindex b/src/3rd-part/stdfwd/include/stdfwd/typeindex new file mode 100644 index 0000000..1e3e0c9 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/typeindex @@ -0,0 +1,20 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class type_index; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + class type_index; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/typeinfo b/src/3rd-part/stdfwd/include/stdfwd/typeinfo new file mode 100644 index 0000000..7149e94 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/typeinfo @@ -0,0 +1,32 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +#ifdef STDFWD_IS_MSVC +class type_info; +#endif + +STDFWD_STD_PURE_BEGIN + + #ifdef STDFWD_IS_MSVC + using ::type_info; + #else + class type_info; + #endif + class bad_cast; + class bad_typeid; + +STDFWD_STD_PURE_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::type_info; + using std::bad_cast; + using std::bad_typeid; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/unordered_map b/src/3rd-part/stdfwd/include/stdfwd/unordered_map new file mode 100644 index 0000000..ec38ac2 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/unordered_map @@ -0,0 +1,53 @@ +#pragma once + +#include "stdfwd_details.hpp" + + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > struct hash; + template< class T > struct equal_to; + template< class T > class allocator; + template< class T1, class T2> struct pair; + + template< class Key, class T, class Hash, class KeyEqual, class Allocator > + class unordered_map; + + template< class Key, class T, class Hash, class KeyEqual, class Allocator > + class unordered_multimap; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< + class Key, + class T, + class Hash = std::hash< Key >, + class KeyEqual = std::equal_to< Key >, + class Allocator = std::allocator< std::pair< const Key, T > > + > + using unordered_map = std::unordered_map< Key, T, Hash, KeyEqual, Allocator >; + + template< + class Key, + class T, + class Hash = std::hash< Key >, + class KeyEqual = std::equal_to< Key >, + class Allocator = std::allocator< std::pair< const Key, T > > + > + using unordered_multimap = std::unordered_multimap< + Key, + T, + Hash, + KeyEqual, + Allocator + >; + +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/unordered_set b/src/3rd-part/stdfwd/include/stdfwd/unordered_set new file mode 100644 index 0000000..169a289 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/unordered_set @@ -0,0 +1,43 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > struct hash; + template< class T > struct equal_to; + template< class T > class allocator; + + template< class Key, class Hash, class KeyEqual, class Allocator > + class unordered_set; + + template< class Key, class Hash, class KeyEqual, class Allocator > + class unordered_multiset; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + + template< + class Key, + class Hash = std::hash, + class KeyEqual = std::equal_to, + class Allocator = std::allocator + > + using unordered_set = std::unordered_set< Key, Hash, KeyEqual, Allocator >; + + template< + class Key, + class Hash = std::hash, + class KeyEqual = std::equal_to, + class Allocator = std::allocator + > + using unordered_multiset = std::unordered_multiset< Key, Hash, KeyEqual, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/utility b/src/3rd-part/stdfwd/include/stdfwd/utility new file mode 100644 index 0000000..ad203f0 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/utility @@ -0,0 +1,27 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T1, class T2 > struct pair; + + template< class Tp, Tp... Idx > + struct integer_sequence; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::pair; + + using std::integer_sequence; + +} + +//------------------------------------------------------------------------------ + diff --git a/src/3rd-part/stdfwd/include/stdfwd/valarray b/src/3rd-part/stdfwd/include/stdfwd/valarray new file mode 100644 index 0000000..5df4efe --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/valarray @@ -0,0 +1,44 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + class slice; + class gslice; + + template class valarray; + template class slice_array; + template class gslice_array; + template class mask_array; + template class indirect_array; + + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + using std::slice; + using std::gslice; + + template + using valarray = std::valarray; + + template + using slice_array = std::slice_array; + + template + using gslice_array = std::gslice_array; + + template + using mask_array = std::mask_array; + + template + using indirect_array = std::indirect_array; +} + +//------------------------------------------------------------------------------ diff --git a/src/3rd-part/stdfwd/include/stdfwd/vector b/src/3rd-part/stdfwd/include/stdfwd/vector new file mode 100644 index 0000000..6ffff50 --- /dev/null +++ b/src/3rd-part/stdfwd/include/stdfwd/vector @@ -0,0 +1,24 @@ +#pragma once + +#include "stdfwd_details.hpp" + +//------------------------------------------------------------------------------ + +STDFWD_STD_BEGIN + + template< class T > class allocator; + + template< class T, class Allocator > + class vector; + +STDFWD_STD_END + +//------------------------------------------------------------------------------ + +namespace stdfwd +{ + template< class T, class Allocator = std::allocator< T > > + using vector = std::vector< T, Allocator >; +} + +//------------------------------------------------------------------------------ diff --git a/src/application/app_con.hpp b/src/application/app_con.hpp index 7aedd61..e4e3e0f 100644 --- a/src/application/app_con.hpp +++ b/src/application/app_con.hpp @@ -2,7 +2,8 @@ #include "application/tools/app_plugin_ptr.hpp" -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_arguments.cpp b/src/application/resources/app_resources_arguments.cpp index 8780c38..b1c8c89 100644 --- a/src/application/resources/app_resources_arguments.cpp +++ b/src/application/resources/app_resources_arguments.cpp @@ -31,7 +31,7 @@ namespace fileExtensions { const char * const FullName = configuration_file::FileExtensions; const char * const Description = "Extensions C++ files"; // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) - const char * const DefaultValue[] = { "*.cpp", "*.hpp", "*.c", "*.h", "*.cxx", "*.hxx", nullptr }; + const char * const DefaultValues[] = { "*.cpp", "*.hpp", "*.c", "*.h", "*.cxx", "*.hxx", nullptr }; } //------------------------------------------------------------------------------ @@ -52,7 +52,7 @@ namespace includeDirs { const char * const FullName = configuration_file::IncludeDirs; const char * const Description = "Include directories"; // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) - const char * const DefaultValue[] = { ".", nullptr }; + const char * const DefaultValues[] = { ".", nullptr }; } //------------------------------------------------------------------------------ @@ -63,7 +63,7 @@ namespace ignoreDirs { const char * const FullName = configuration_file::IgnoreDirs; const char * const Description = "Directories that will be ignored"; // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) - const char * const DefaultValue[] = { nullptr }; + const char * const DefaultValues[] = { nullptr }; } //------------------------------------------------------------------------------ @@ -84,7 +84,7 @@ namespace ignoreFiles { const char * const FullName = configuration_file::IgnoreFiles; const char * const Description = "Files will be ignored by regexp"; // NOLINTNEXTLINE(hicpp-avoid-c-arrays, modernize-avoid-c-arrays, cppcoreguidelines-avoid-c-arrays) - const char * const DefaultValue[] = { nullptr }; + const char * const DefaultValues[] = { nullptr }; } //------------------------------------------------------------------------------ @@ -191,4 +191,14 @@ namespace show_std_files { //------------------------------------------------------------------------------ +namespace show_only_std_headers { + + // NOLINTNEXTLINE(cppcoreguidelines-interfaces-global-init) + const char * const FullName = configuration_file::ShowOnlyStdHeaders; + const char * const Description = "Show only standard library headers in output (default: false)"; + const bool DefaultValue = false; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/application/resources/app_resources_arguments.hpp b/src/application/resources/app_resources_arguments.hpp index 85e752c..fee9ccc 100644 --- a/src/application/resources/app_resources_arguments.hpp +++ b/src/application/resources/app_resources_arguments.hpp @@ -19,7 +19,7 @@ namespace fileExtensions { extern const char * const FullName; extern const char * const Description; - extern const char * const DefaultValue[]; + extern const char * const DefaultValues[]; } //------------------------------------------------------------------------------ @@ -37,7 +37,7 @@ namespace includeDirs { extern const char * const FullName; extern const char * const Description; - extern const char * const DefaultValue[]; + extern const char * const DefaultValues[]; } //------------------------------------------------------------------------------ @@ -46,7 +46,7 @@ namespace ignoreDirs { extern const char * const FullName; extern const char * const Description; - extern const char * const DefaultValue[]; + extern const char * const DefaultValues[]; } //------------------------------------------------------------------------------ @@ -64,7 +64,7 @@ namespace ignoreFiles { extern const char * const FullName; extern const char * const Description; - extern const char * const DefaultValue[]; + extern const char * const DefaultValues[]; } //------------------------------------------------------------------------------ @@ -147,4 +147,14 @@ namespace show_std_files { } //------------------------------------------------------------------------------ + +namespace show_only_std_headers { + + extern const char * const FullName; + extern const char * const Description; + extern const bool DefaultValue; +} + +//------------------------------------------------------------------------------ + } diff --git a/src/application/resources/app_resources_configuration_file.cpp b/src/application/resources/app_resources_configuration_file.cpp index ee17045..aebfdbd 100644 --- a/src/application/resources/app_resources_configuration_file.cpp +++ b/src/application/resources/app_resources_configuration_file.cpp @@ -22,6 +22,7 @@ namespace application::resources::configuration_file { const char * const ReportLimit = "report_limit"; const char * const ReportDetailsLimit = "report_details_limit"; const char * const ShowStdFiles = "show_std_files"; + const char * const ShowOnlyStdHeaders = "show_only_std_headers"; //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_configuration_file.hpp b/src/application/resources/app_resources_configuration_file.hpp index 96d140b..68037fa 100644 --- a/src/application/resources/app_resources_configuration_file.hpp +++ b/src/application/resources/app_resources_configuration_file.hpp @@ -22,6 +22,7 @@ namespace application::resources::configuration_file { extern const char * const ReportLimit; extern const char * const ReportDetailsLimit; extern const char * const ShowStdFiles; + extern const char * const ShowOnlyStdHeaders; //------------------------------------------------------------------------------ diff --git a/src/application/resources/app_resources_version.cpp b/src/application/resources/app_resources_version.cpp index 7d13aec..b6e03e5 100644 --- a/src/application/resources/app_resources_version.cpp +++ b/src/application/resources/app_resources_version.cpp @@ -7,8 +7,8 @@ namespace application::resources::version { //------------------------------------------------------------------------------ const int Major = 0; - const int Minor = 3; - const int Path = 1; + const int Minor = 4; + const int Path = 0; const char * const VersionFormat = "{}.{}.{}\n"; diff --git a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp index 27aa858..ad3967a 100644 --- a/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp +++ b/src/application/test/fixtures/app_test_cmake_project_builder_fixture.hpp @@ -1,6 +1,9 @@ #pragma once -#include +#include +#include +#include +#include #include diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp index 2475cad..3baa25f 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.cpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.cpp @@ -131,6 +131,14 @@ ConfigurationfileFixture::getShowStdFile() const //------------------------------------------------------------------------------ +ConfigurationfileFixture::BoolOpt +ConfigurationfileFixture::getShowOnlyStdHeaders() const +{ + return getConfigurationFile().getShowOnlyStdFiles(); +} + +//------------------------------------------------------------------------------ + ConfigurationfileFixture::StringOpt ConfigurationfileFixture::toStirng( const StringsOpt & _arrayOpt ) { diff --git a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp index df4bb9b..393a832 100644 --- a/src/application/test/fixtures/app_test_configuration_file_fixture.hpp +++ b/src/application/test/fixtures/app_test_configuration_file_fixture.hpp @@ -3,7 +3,10 @@ #include "application/tools/app_plugin_ptr.hpp" #include -#include +#include +#include +#include +#include //------------------------------------------------------------------------------ @@ -65,6 +68,7 @@ class ConfigurationfileFixture IntOpt getReportLimit() const; IntOpt getReportDetailsLimit() const; BoolOpt getShowStdFile() const; + BoolOpt getShowOnlyStdHeaders() const; static StringOpt toStirng( const StringsOpt & _arrayOpt ); static StringOpt toStirng( const PathsArrayOpt & _arrayOpt ); diff --git a/src/application/test/fixtures/app_test_parser_fixture.hpp b/src/application/test/fixtures/app_test_parser_fixture.hpp index d0fc18e..d5b8114 100644 --- a/src/application/test/fixtures/app_test_parser_fixture.hpp +++ b/src/application/test/fixtures/app_test_parser_fixture.hpp @@ -1,7 +1,11 @@ #pragma once +#include +#include +#include +#include + #include -#include //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp index 6f75734..6c777dc 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.cpp @@ -286,7 +286,21 @@ ParserWrapperFixture::BoolOpt ParserWrapperFixture::getShowStdFile() const bool ParserWrapperFixture::getDefaultShowStdFile() const { - return getParser().getDefaultShowStdfile(); + return getParser().getDefaultShowStdFile(); +} + +//------------------------------------------------------------------------------ + +ParserWrapperFixture::BoolOpt ParserWrapperFixture::getShowOnlyStdHeaders() const +{ + return getParser().getShowOnlyStdHeaders(); +} + +//------------------------------------------------------------------------------ + +bool ParserWrapperFixture::getDefaultShowOnlyStdHeaders() const +{ + return getParser().getDefaultShowOnlyStdHeaders(); } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp index 2f0fe9b..7e5a39a 100644 --- a/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp +++ b/src/application/test/fixtures/app_test_parser_wrapper_fixture.hpp @@ -1,7 +1,11 @@ #pragma once +#include +#include +#include +#include + #include -#include //------------------------------------------------------------------------------ @@ -77,6 +81,9 @@ class ParserWrapperFixture BoolOpt getShowStdFile() const; bool getDefaultShowStdFile() const; + BoolOpt getShowOnlyStdHeaders() const; + bool getDefaultShowOnlyStdHeaders() const; + bool isHelp() const; bool isVerbose() const; bool isVersion() const; diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.cpp b/src/application/test/fixtures/app_test_project_builder_fixture.cpp index e336d20..ba6d9c2 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.cpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.cpp @@ -207,6 +207,8 @@ ProjectBuilderFixture::Strings ProjectBuilderFixture::toStrings( { const std::string str{ *it }; result.push_back( str ); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) + ++it; } return result; } diff --git a/src/application/test/fixtures/app_test_project_builder_fixture.hpp b/src/application/test/fixtures/app_test_project_builder_fixture.hpp index 86b32ea..776ad7c 100644 --- a/src/application/test/fixtures/app_test_project_builder_fixture.hpp +++ b/src/application/test/fixtures/app_test_project_builder_fixture.hpp @@ -2,8 +2,13 @@ #include "application/tools/app_plugin_ptr.hpp" +#include +#include +#include +#include +#include + #include -#include //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp index f10661e..032700c 100644 --- a/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.cpp @@ -106,7 +106,21 @@ bool ReportSettingsLoaderFixture::getShowStdFiles() const bool ReportSettingsLoaderFixture::getDefaultShowStdFiles() const { - return getArguments().getDefaultShowStdfile(); + return getArguments().getDefaultShowStdFile(); +} + +//------------------------------------------------------------------------------ + +bool ReportSettingsLoaderFixture::getShowOnlyStdHeaders() const +{ + return getSettings().getShowOnlyStdHeaders(); +} + +//------------------------------------------------------------------------------ + +bool ReportSettingsLoaderFixture::getDefaultShowOnlyStdHeaders() const +{ + return getArguments().getDefaultShowOnlyStdHeaders(); } //------------------------------------------------------------------------------ diff --git a/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp index b125799..f2ddf70 100644 --- a/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp +++ b/src/application/test/fixtures/app_test_report_settings_loader_fixture.hpp @@ -2,10 +2,11 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" -#include +#include #include #include +#include //------------------------------------------------------------------------------ @@ -53,6 +54,9 @@ class ReportSettingsLoaderFixture bool getShowStdFiles() const; bool getDefaultShowStdFiles() const; + bool getShowOnlyStdHeaders() const; + bool getDefaultShowOnlyStdHeaders() const; + std::string getReports() const; std::string getDefaultReports() const; diff --git a/src/application/test/suits/app_test_cmake_project_builder.cpp b/src/application/test/suits/app_test_cmake_project_builder.cpp index d2b6675..02af156 100644 --- a/src/application/test/suits/app_test_cmake_project_builder.cpp +++ b/src/application/test/suits/app_test_cmake_project_builder.cpp @@ -4,9 +4,7 @@ #include "application/resources/app_resources_arguments.hpp" -#include "test_tools/test_macros.hpp" - -#include "test_tools/test_macros.hpp" +#include #include #include @@ -28,23 +26,22 @@ namespace application::test { //------------------------------------------------------------------------------ -// clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( CMakeProjectBuildersTets, CMakeProjectBuilderFixture ) +BOOST_FIXTURE_TEST_SUITE( CMakeProjectBuildersTets, CMakeProjectBuilderFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_file_not_exist ) +BOOST_AUTO_TEST_CASE( t1_file_not_exist ) { // Run buildProject(); // Check - TEST_CHECK( !isInitializedProject() ); + BOOST_CHECK( !isInitializedProject() ); } //------------------------------------------------------------------------------ -TEST_CASE( t2_default_compilation_file_exist ) +BOOST_AUTO_TEST_CASE( t2_default_compilation_file_exist ) { // Init addCMakeFile( @@ -67,7 +64,7 @@ TEST_CASE( t2_default_compilation_file_exist ) buildProject(); // Check - TEST_REQUIRE( isInitializedProject() ); + BOOST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -75,7 +72,7 @@ TEST_CASE( t2_default_compilation_file_exist ) "/tmp/project/file2.cpp" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -85,7 +82,7 @@ TEST_CASE( t2_default_compilation_file_exist ) //------------------------------------------------------------------------------ -TEST_CASE( t3_compilation_file_from_arguments ) +BOOST_AUTO_TEST_CASE( t3_compilation_file_from_arguments ) { // Init std::string compilationFile = "build/compile_commands.json"; @@ -111,7 +108,7 @@ TEST_CASE( t3_compilation_file_from_arguments ) buildProject(); // Check - TEST_REQUIRE( isInitializedProject() ); + BOOST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -119,7 +116,7 @@ TEST_CASE( t3_compilation_file_from_arguments ) "/tmp/project/file2.cpp" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -129,7 +126,7 @@ TEST_CASE( t3_compilation_file_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t4_compilation_file_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t4_compilation_file_from_configuration_file ) { // Init std::string compilationFile = "build/compile_commands.json"; @@ -155,7 +152,7 @@ TEST_CASE( t4_compilation_file_from_configuration_file ) buildProject(); // Check - TEST_REQUIRE( isInitializedProject() ); + BOOST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -163,7 +160,7 @@ TEST_CASE( t4_compilation_file_from_configuration_file ) "/tmp/project/file2.cpp" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -173,7 +170,7 @@ TEST_CASE( t4_compilation_file_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t5_1_include_files_several_includes ) +BOOST_AUTO_TEST_CASE( t5_1_include_files_several_includes ) { // Init addCMakeFile( @@ -191,12 +188,12 @@ TEST_CASE( t5_1_include_files_several_includes ) buildProject(); // Check - TEST_REQUIRE( isInitializedProject() ); + BOOST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "/tmp/project/file1.cpp" } ); - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -206,7 +203,7 @@ TEST_CASE( t5_1_include_files_several_includes ) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib1/" , "./lib2/" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -216,7 +213,7 @@ TEST_CASE( t5_1_include_files_several_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_include_files_different_includes_in_different_files ) +BOOST_AUTO_TEST_CASE( t5_2_include_files_different_includes_in_different_files ) { // Init addCMakeFile( @@ -239,7 +236,7 @@ TEST_CASE( t5_2_include_files_different_includes_in_different_files ) buildProject(); // Check - TEST_REQUIRE( isInitializedProject() ); + BOOST_REQUIRE( isInitializedProject() ); const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { @@ -247,7 +244,7 @@ TEST_CASE( t5_2_include_files_different_includes_in_different_files ) "/tmp/project/file2.cpp" } ); - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -258,7 +255,7 @@ TEST_CASE( t5_2_include_files_different_includes_in_different_files ) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file1.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib1/" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -269,7 +266,7 @@ TEST_CASE( t5_2_include_files_different_includes_in_different_files ) const auto resultIncludesFile = getResultIncludes( "/tmp/project/file2.cpp" ); const auto exceptedIncludes = toExceptedFiles( { "./lib2/" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludesFile.begin(), resultIncludesFile.end(), exceptedIncludes.begin(), @@ -280,7 +277,7 @@ TEST_CASE( t5_2_include_files_different_includes_in_different_files ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_configuration_file_suits.cpp b/src/application/test/suits/app_test_configuration_file_suits.cpp index 7372c6b..f02e284 100644 --- a/src/application/test/suits/app_test_configuration_file_suits.cpp +++ b/src/application/test/suits/app_test_configuration_file_suits.cpp @@ -1,6 +1,6 @@ #include "application/test/fixtures/app_test_configuration_file_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include #include @@ -25,6 +25,7 @@ TEST PLAN 11. Report details limit 12. Show std files 13. Compile commands +14. Show only std files -------------------------------------------------------------------------------*/ @@ -33,39 +34,40 @@ namespace application::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ConfigurationfileTests, ConfigurationfileFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ConfigurationfileTests, ConfigurationfileFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty ) +BOOST_AUTO_TEST_CASE( t1_empty ) { // Run loadFromJson( "{}" ); // Check - TEST_CHECK( !getProjectDir().has_value() ); - TEST_CHECK( !getFileExtensions().has_value() ); - TEST_CHECK( !getAnalyzeWithoutExtension().has_value() ); - TEST_CHECK( !getIncludeDirs().has_value() ); - TEST_CHECK( !getIgnoreDirs().has_value() ); - TEST_CHECK( !getIgnoreSystemIncludes().has_value() ); + BOOST_CHECK( !getProjectDir().has_value() ); + BOOST_CHECK( !getFileExtensions().has_value() ); + BOOST_CHECK( !getAnalyzeWithoutExtension().has_value() ); + BOOST_CHECK( !getIncludeDirs().has_value() ); + BOOST_CHECK( !getIgnoreDirs().has_value() ); + BOOST_CHECK( !getIgnoreSystemIncludes().has_value() ); } //------------------------------------------------------------------------------ -TEST_CASE( t2_project_dir ) +BOOST_AUTO_TEST_CASE( t2_project_dir ) { // Run loadFromJson( R"({"project_dir":"/tmp/project"})" ); // Check - TEST_REQUIRE( getProjectDir().has_value() ); + BOOST_REQUIRE( getProjectDir().has_value() ); BOOST_CHECK_EQUAL( getProjectDir()->string(), "/tmp/project" ); } //------------------------------------------------------------------------------ -TEST_CASE( t3_file_extenstions ) +BOOST_AUTO_TEST_CASE( t3_file_extenstions ) { // Run loadFromJson( R"({ "file_extensions" : [ "*.cpp", "*.hpp" ] })" ); @@ -73,13 +75,13 @@ TEST_CASE( t3_file_extenstions ) // Check auto valueOpt = getFileExtensions(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "*.cpp,*.hpp" ); } //------------------------------------------------------------------------------ -TEST_CASE( t4_include_dir ) +BOOST_AUTO_TEST_CASE( t4_include_dir ) { // Run loadFromJson( R"({ "include_dirs" : [ "include1", "include2" ] })" ); @@ -87,13 +89,13 @@ TEST_CASE( t4_include_dir ) // Check auto valueOpt = getIncludeDirs(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "include1,include2" ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_ignore_dir ) +BOOST_AUTO_TEST_CASE( t5_ignore_dir ) { // Run loadFromJson( R"({ "ignore_dirs" : [ "ignore1", "ignore2" ] })" ); @@ -101,13 +103,13 @@ TEST_CASE( t5_ignore_dir ) // Check auto valueOpt = getIgnoreDirs(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "ignore1,ignore2" ); } //------------------------------------------------------------------------------ -TEST_CASE( t6_ignore_system_includes ) +BOOST_AUTO_TEST_CASE( t6_ignore_system_includes ) { // Run loadFromJson( R"({ "ignore_system_includes" : true })" ); @@ -115,13 +117,13 @@ TEST_CASE( t6_ignore_system_includes ) // Check auto valueOpt = getIgnoreSystemIncludes(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -TEST_CASE( t7_ignore_files ) +BOOST_AUTO_TEST_CASE( t7_ignore_files ) { // Run loadFromJson( R"({ "ignore_files" : [ "lib1_*", "lib2_*" ] })" ); @@ -129,13 +131,13 @@ TEST_CASE( t7_ignore_files ) // Check auto valueOpt = getIgnoreFiles(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "lib1_*,lib2_*" ); } //------------------------------------------------------------------------------ -TEST_CASE( t8_analyze_without_extension ) +BOOST_AUTO_TEST_CASE( t8_analyze_without_extension ) { // Run loadFromJson( R"({ "analyze_without_extension" : true })" ); @@ -143,13 +145,13 @@ TEST_CASE( t8_analyze_without_extension ) // Check auto valueOpt = getAnalyzeWithoutExtension(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_1_report_unresolved ) +BOOST_AUTO_TEST_CASE( t9_1_report_unresolved ) { // Run loadFromJson( R"({ "report" : [ "unresolved" ] })" ); @@ -157,13 +159,13 @@ TEST_CASE( t9_1_report_unresolved ) // Check auto valueOpt = getReports(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "unresolved" ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_2_report_most_impact ) +BOOST_AUTO_TEST_CASE( t9_2_report_most_impact ) { // Run loadFromJson( R"({ "report" : [ "most_impact" ] })" ); @@ -171,13 +173,13 @@ TEST_CASE( t9_2_report_most_impact ) // Check auto valueOpt = getReports(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "most_impact" ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_3_report_dump ) +BOOST_AUTO_TEST_CASE( t9_3_report_dump ) { // Run loadFromJson( R"({ "report" : [ "dump" ] })" ); @@ -185,13 +187,13 @@ TEST_CASE( t9_3_report_dump ) // Check auto valueOpt = getReports(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "dump" ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_4_several_reports ) +BOOST_AUTO_TEST_CASE( t9_4_several_reports ) { // Run loadFromJson( R"({ "report" : [ "unresolved" , "most_impact", "dump" ] })" ); @@ -199,13 +201,13 @@ TEST_CASE( t9_4_several_reports ) // Check auto valueOpt = getReports(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, "unresolved,most_impact,dump" ); } //------------------------------------------------------------------------------ -TEST_CASE( t10_report_limit ) +BOOST_AUTO_TEST_CASE( t10_report_limit ) { // Run loadFromJson( R"({ "report_limit" : 10 })" ); @@ -213,13 +215,13 @@ TEST_CASE( t10_report_limit ) // Check auto valueOpt = getReportLimit(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, 10 ); } //------------------------------------------------------------------------------ -TEST_CASE( t11_report_details_limit ) +BOOST_AUTO_TEST_CASE( t11_report_details_limit ) { // Run loadFromJson( R"({ "report_details_limit" : 10 })" ); @@ -227,13 +229,13 @@ TEST_CASE( t11_report_details_limit ) // Check auto valueOpt = getReportDetailsLimit(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, 10 ); } //------------------------------------------------------------------------------ -TEST_CASE( t12_show_std_files ) +BOOST_AUTO_TEST_CASE( t12_show_std_files ) { // Run loadFromJson( R"({ "show_std_files" : true })" ); @@ -241,13 +243,13 @@ TEST_CASE( t12_show_std_files ) // Check auto valueOpt = getShowStdFile(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -TEST_CASE( t13_compile_commands ) +BOOST_AUTO_TEST_CASE( t13_compile_commands ) { // Run loadFromJson( R"({ "compile_commands" : "compile_commands.json" })" ); @@ -255,13 +257,27 @@ TEST_CASE( t13_compile_commands ) // Check auto valueOpt = getCompileCommands(); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( *valueOpt, stdfs::path{ "compile_commands.json" } ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_CASE( t14_show_only_std_headers ) +{ + // Run + loadFromJson( R"({ "show_only_std_headers" : true })" ); + + // Check + auto valueOpt = getShowOnlyStdHeaders(); + + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_parser_arguments.cpp b/src/application/test/suits/app_test_parser_arguments.cpp index 4c4e60c..6409630 100644 --- a/src/application/test/suits/app_test_parser_arguments.cpp +++ b/src/application/test/suits/app_test_parser_arguments.cpp @@ -1,6 +1,6 @@ #include "application/test/fixtures/app_test_parser_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include #include @@ -35,11 +35,12 @@ namespace application::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ParserArgumentsTets, ParserArgumentsFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ParserArgumentsTets, ParserArgumentsFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_argument_with_value ) +BOOST_AUTO_TEST_CASE( t1_argument_with_value ) { // Init const std::string argumentName = "dir"; @@ -56,13 +57,13 @@ TEST_CASE( t1_argument_with_value ) // Check auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); - TEST_CHECK_EQUAL( argumentValue, *valueOpt ); + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t2_argument_with_only_default_value ) +BOOST_AUTO_TEST_CASE( t2_argument_with_only_default_value ) { // Init const std::string argumentName = "dir"; @@ -76,12 +77,12 @@ TEST_CASE( t2_argument_with_only_default_value ) // Check auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( !valueOpt.has_value() ); + BOOST_REQUIRE( !valueOpt.has_value() ); } //------------------------------------------------------------------------------ -TEST_CASE( t3_argument_with_value_and_default_value ) +BOOST_AUTO_TEST_CASE( t3_argument_with_value_and_default_value ) { // Init const std::string argumentName = "dir"; @@ -98,13 +99,13 @@ TEST_CASE( t3_argument_with_value_and_default_value ) // Check auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t4_unrecognized_argument ) +BOOST_AUTO_TEST_CASE( t4_unrecognized_argument ) { // Init const std::string argumentName = "dir"; @@ -114,12 +115,12 @@ TEST_CASE( t4_unrecognized_argument ) const std::string argument = "--" + argumentName + "=" + argumentValue; // Run - TEST_CHECK_THROW( parseArguments( { argument } ), std::logic_error ); + BOOST_CHECK_THROW( parseArguments( { argument } ), std::logic_error ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_help ) +BOOST_AUTO_TEST_CASE( t5_help ) { // Init const std::string argumentName = "dir"; @@ -144,7 +145,7 @@ TEST_CASE( t5_help ) //------------------------------------------------------------------------------ -TEST_CASE( t6_value_with_quotation_mark ) +BOOST_AUTO_TEST_CASE( t6_value_with_quotation_mark ) { // Init const std::string argumentName = "dir"; @@ -165,13 +166,13 @@ TEST_CASE( t6_value_with_quotation_mark ) // Check auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t7_value_with_apostrophe ) +BOOST_AUTO_TEST_CASE( t7_value_with_apostrophe ) { // Init const std::string argumentName = "dir"; @@ -190,13 +191,13 @@ TEST_CASE( t7_value_with_apostrophe ) // Check auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t8_several_arguments ) +BOOST_AUTO_TEST_CASE( t8_several_arguments ) { // Init const std::string argumentNewName = "new"; @@ -222,18 +223,18 @@ TEST_CASE( t8_several_arguments ) // Check auto valueNewOpt = getArgumentStringValue( argumentNewName ); - TEST_REQUIRE( valueNewOpt.has_value() ); + BOOST_REQUIRE( valueNewOpt.has_value() ); BOOST_CHECK_EQUAL( argumentNewValue, *valueNewOpt ); auto valueOldOpt = getArgumentStringValue( argumentOldName ); - TEST_REQUIRE( valueOldOpt.has_value() ); + BOOST_REQUIRE( valueOldOpt.has_value() ); BOOST_CHECK_EQUAL( argumentOldValue, *valueOldOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_check_exist_argument ) +BOOST_AUTO_TEST_CASE( t9_check_exist_argument ) { // Init const std::string argumentName = "help"; @@ -246,12 +247,12 @@ TEST_CASE( t9_check_exist_argument ) parseArguments( { argument } ); // Check - TEST_CHECK( isExistArgument( argumentName ) ); + BOOST_CHECK( isExistArgument( argumentName ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t10_1_array_simple ) +BOOST_AUTO_TEST_CASE( t10_1_array_simple ) { // Init const std::string argumentName = "array"; @@ -270,13 +271,13 @@ TEST_CASE( t10_1_array_simple ) auto valueOpt = getArgumentStringsValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t10_2_array_with_default_value ) +BOOST_AUTO_TEST_CASE( t10_2_array_with_default_value ) { // Init const std::string argumentName = "array"; @@ -294,12 +295,12 @@ TEST_CASE( t10_2_array_with_default_value ) auto valueOpt = getArgumentStringValue( argumentName ); - TEST_REQUIRE( !valueOpt.has_value() ); + BOOST_REQUIRE( !valueOpt.has_value() ); } //------------------------------------------------------------------------------ -TEST_CASE( t10_3_array_with_quotes ) +BOOST_AUTO_TEST_CASE( t10_3_array_with_quotes ) { // Init const std::string argumentName = "array"; @@ -318,13 +319,13 @@ TEST_CASE( t10_3_array_with_quotes ) auto valueOpt = getArgumentStringsValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( "a,b,c", *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t11_int ) +BOOST_AUTO_TEST_CASE( t11_int ) { // Init const std::string argumentName = "number"; @@ -343,13 +344,13 @@ TEST_CASE( t11_int ) // Check auto valueOpt = getArgumentIntValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t12_bool ) +BOOST_AUTO_TEST_CASE( t12_bool ) { // Init const std::string argumentName = "skip"; @@ -368,13 +369,13 @@ TEST_CASE( t12_bool ) // Check auto valueOpt = getArgumentBoolValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValue, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t13_path ) +BOOST_AUTO_TEST_CASE( t13_path ) { // Init const std::string argumentName = "number"; @@ -393,13 +394,13 @@ TEST_CASE( t13_path ) // Check auto valueOpt = getArgumentPathValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValueStr, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_CASE( t14_paths ) +BOOST_AUTO_TEST_CASE( t14_paths ) { // Init const std::string argumentName = "number"; @@ -418,13 +419,13 @@ TEST_CASE( t14_paths ) // Check auto valueOpt = getArgumentPathsValue( argumentName ); - TEST_REQUIRE( valueOpt.has_value() ); + BOOST_REQUIRE( valueOpt.has_value() ); BOOST_CHECK_EQUAL( argumentValueStr, *valueOpt ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp index a79bbf5..ff9e714 100644 --- a/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp +++ b/src/application/test/suits/app_test_parser_arguments_wrapper_suits.cpp @@ -6,7 +6,7 @@ #include "reporter/api/enums/rp_reporter_kind.hpp" #include "reporter/exceptions/rp_exceptions.hpp" -#include "test_tools/test_macros.hpp" +#include #include #include @@ -60,6 +60,9 @@ TEST PLAN 16. Compile commands 16.1 From arguments 16.2 Default +17. Show only std headers + 17.1 From arguments + 17.2 Default -------------------------------------------------------------------------------*/ @@ -68,11 +71,12 @@ namespace application::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ParserWrapperTets, ParserWrapperFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ParserWrapperTets, ParserWrapperFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_1_project_dir_from_argument ) +BOOST_AUTO_TEST_CASE( t1_1_project_dir_from_argument ) { // Run parse( "--project_dir=test_value" ); @@ -83,7 +87,7 @@ TEST_CASE( t1_1_project_dir_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t1_2_project_dir_default ) +BOOST_AUTO_TEST_CASE( t1_2_project_dir_default ) { // Run parse( "" ); @@ -96,7 +100,7 @@ TEST_CASE( t1_2_project_dir_default ) //------------------------------------------------------------------------------ -TEST_CASE( t1_3_project_dir_from_argument_without_full_name ) +BOOST_AUTO_TEST_CASE( t1_3_project_dir_from_argument_without_full_name ) { // Init parse( "project_dir" ); @@ -107,7 +111,7 @@ TEST_CASE( t1_3_project_dir_from_argument_without_full_name ) //------------------------------------------------------------------------------ -TEST_CASE( t2_1_file_extensions_from_argument ) +BOOST_AUTO_TEST_CASE( t2_1_file_extensions_from_argument ) { // Run parse( "--file_extensions=*.cpp,*.hpp" ); @@ -121,21 +125,21 @@ TEST_CASE( t2_1_file_extensions_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t2_2_file_extensions_default ) +BOOST_AUTO_TEST_CASE( t2_2_file_extensions_default ) { // Run parse( "" ); // Check BOOST_CHECK_EQUAL( - toString( resources::arguments::fileExtensions::DefaultValue ), + toString( resources::arguments::fileExtensions::DefaultValues ), toString( getDefaultFileExtensions() ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t3_1_include_dirs_from_argument ) +BOOST_AUTO_TEST_CASE( t3_1_include_dirs_from_argument ) { // Run parse( "--include_dirs=/include/dir1,/include/dir2" ); @@ -149,21 +153,21 @@ TEST_CASE( t3_1_include_dirs_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t3_2_include_dirs_default ) +BOOST_AUTO_TEST_CASE( t3_2_include_dirs_default ) { // Run parse( "" ); // Check BOOST_CHECK_EQUAL( - toString( resources::arguments::includeDirs::DefaultValue ), + toString( resources::arguments::includeDirs::DefaultValues ), toString( getDefaultIncludeDirs() ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t4_1_ignore_dirs_from_argument ) +BOOST_AUTO_TEST_CASE( t4_1_ignore_dirs_from_argument ) { // Run parse( "--ignore_dirs=/include/dir1,/include/dir2" ); @@ -177,21 +181,21 @@ TEST_CASE( t4_1_ignore_dirs_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t4_2_ignore_dirs_default ) +BOOST_AUTO_TEST_CASE( t4_2_ignore_dirs_default ) { // Run parse( "" ); // Check BOOST_CHECK_EQUAL( - toString( resources::arguments::ignoreDirs::DefaultValue ), + toString( resources::arguments::ignoreDirs::DefaultValues ), toString( getDefaultIgnoreDirs() ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_1_configuration_file_from_arguments ) +BOOST_AUTO_TEST_CASE( t5_1_configuration_file_from_arguments ) { // Run parse( "--configuration_file=./file" ); @@ -202,7 +206,7 @@ TEST_CASE( t5_1_configuration_file_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_configuration_file_default ) +BOOST_AUTO_TEST_CASE( t5_2_configuration_file_default ) { // Run parse( "" ); @@ -216,29 +220,29 @@ TEST_CASE( t5_2_configuration_file_default ) //------------------------------------------------------------------------------ -TEST_CASE( t6_1_help_from_arguments ) +BOOST_AUTO_TEST_CASE( t6_1_help_from_arguments ) { // Run parse( "--help" ); // Check - TEST_CHECK( isHelp() ); + BOOST_CHECK( isHelp() ); } //------------------------------------------------------------------------------ -TEST_CASE( t7_verbose ) +BOOST_AUTO_TEST_CASE( t7_verbose ) { // Run parse( "--verbose" ); // Check - TEST_CHECK( isVerbose() ); + BOOST_CHECK( isVerbose() ); } //------------------------------------------------------------------------------ -TEST_CASE( t8_1_report_from_argument ) +BOOST_AUTO_TEST_CASE( t8_1_report_from_argument ) { // Run parse( "--report=unresolved" ); @@ -249,7 +253,7 @@ TEST_CASE( t8_1_report_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t8_2_report_default ) +BOOST_AUTO_TEST_CASE( t8_2_report_default ) { // Run parse( "" ); @@ -263,17 +267,17 @@ TEST_CASE( t8_2_report_default ) //------------------------------------------------------------------------------ -TEST_CASE( t8_3_report_incorrect_name ) +BOOST_AUTO_TEST_CASE( t8_3_report_incorrect_name ) { // Check parse( "--report=incorrect_name" ); - TEST_CHECK_THROW( getReporterKinds(), reporter::IncorrectReport ); + BOOST_CHECK_THROW( getReporterKinds(), reporter::IncorrectReport ); } //------------------------------------------------------------------------------ -TEST_CASE( t9_1_report_limit_from_argument ) +BOOST_AUTO_TEST_CASE( t9_1_report_limit_from_argument ) { // Run parse( "--report_limit=42" ); @@ -284,7 +288,7 @@ TEST_CASE( t9_1_report_limit_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t9_2_report_limit_default ) +BOOST_AUTO_TEST_CASE( t9_2_report_limit_default ) { // Run parse( "" ); @@ -298,20 +302,20 @@ TEST_CASE( t9_2_report_limit_default ) //------------------------------------------------------------------------------ -TEST_CASE( t10_1_ignore_system_includes_from_arguments ) +BOOST_AUTO_TEST_CASE( t10_1_ignore_system_includes_from_arguments ) { // Run parse( "--ignore_system_includes=true" ); // Check auto valueOpt = getIgnoreSystemIncludes(); - TEST_REQUIRE( valueOpt.has_value() ); - TEST_CHECK_EQUAL( *valueOpt, true ); + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -TEST_CASE( t10_2_ignore_system_includes_default ) +BOOST_AUTO_TEST_CASE( t10_2_ignore_system_includes_default ) { // Run parse( "" ); @@ -325,7 +329,7 @@ TEST_CASE( t10_2_ignore_system_includes_default ) //------------------------------------------------------------------------------ -TEST_CASE( t11_1_ignore_files_from_argument ) +BOOST_AUTO_TEST_CASE( t11_1_ignore_files_from_argument ) { // Run parse( "--ignore_files=lib1_*,lib2_*" ); @@ -337,7 +341,7 @@ TEST_CASE( t11_1_ignore_files_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t11_2_ignore_files_default ) +BOOST_AUTO_TEST_CASE( t11_2_ignore_files_default ) { // Run parse( "" ); @@ -345,25 +349,25 @@ TEST_CASE( t11_2_ignore_files_default ) // Check BOOST_CHECK_EQUAL( getDefaultIgnoreFiles(), - toString( resources::arguments::ignoreFiles::DefaultValue ) + toString( resources::arguments::ignoreFiles::DefaultValues ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t12_version ) +BOOST_AUTO_TEST_CASE( t12_version ) { // Run parse( "--version" ); // Check - TEST_CHECK( isVersion() ); + BOOST_CHECK( isVersion() ); } //------------------------------------------------------------------------------ -TEST_CASE( t13_1_report_details_limit_from_argument ) +BOOST_AUTO_TEST_CASE( t13_1_report_details_limit_from_argument ) { // Run parse( "--report_details_limit=42" ); @@ -374,7 +378,7 @@ TEST_CASE( t13_1_report_details_limit_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t13_2_report_details_limit_default ) +BOOST_AUTO_TEST_CASE( t13_2_report_details_limit_default ) { // Run parse( "" ); @@ -388,7 +392,7 @@ TEST_CASE( t13_2_report_details_limit_default ) //------------------------------------------------------------------------------ -TEST_CASE( t14_1_analyze_without_extension_from_argument ) +BOOST_AUTO_TEST_CASE( t14_1_analyze_without_extension_from_argument ) { // Run parse( "--analyze_without_extension=true" ); @@ -399,7 +403,7 @@ TEST_CASE( t14_1_analyze_without_extension_from_argument ) //------------------------------------------------------------------------------ -TEST_CASE( t14_2_analyze_without_extension_default ) +BOOST_AUTO_TEST_CASE( t14_2_analyze_without_extension_default ) { // Run parse( "" ); @@ -413,20 +417,20 @@ TEST_CASE( t14_2_analyze_without_extension_default ) //------------------------------------------------------------------------------ -TEST_CASE( t15_1_show_std_files_from_argument ) +BOOST_AUTO_TEST_CASE( t15_1_show_std_files_from_argument ) { // Run parse( "--show_std_files=true" ); // Check auto valueOpt = getShowStdFile(); - TEST_REQUIRE( valueOpt.has_value() ); - TEST_CHECK_EQUAL( *valueOpt, true ); + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, true ); } //------------------------------------------------------------------------------ -TEST_CASE( t15_1_show_std_files_default ) +BOOST_AUTO_TEST_CASE( t15_2_show_std_files_default ) { // Run parse( "" ); @@ -440,7 +444,7 @@ TEST_CASE( t15_1_show_std_files_default ) //------------------------------------------------------------------------------ -TEST_CASE( t16_1_compile_commands_from_arguments ) +BOOST_AUTO_TEST_CASE( t16_1_compile_commands_from_arguments ) { // Run parse( "--compile_commands=build/compile_commands.json" ); @@ -451,7 +455,7 @@ TEST_CASE( t16_1_compile_commands_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t16_2_compile_commands_default ) +BOOST_AUTO_TEST_CASE( t16_2_compile_commands_default ) { // Run parse( "" ); @@ -465,7 +469,34 @@ TEST_CASE( t16_2_compile_commands_default ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_CASE( t17_1_show_only_std_headers_from_argument ) +{ + // Run + parse( "--show_only_std_headers=true" ); + + // Check + auto valueOpt = getShowOnlyStdHeaders(); + BOOST_REQUIRE( valueOpt.has_value() ); + BOOST_CHECK_EQUAL( *valueOpt, true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE( t17_2_show_only_std_headers_default ) +{ + // Run + parse( "" ); + + // Check + BOOST_CHECK_EQUAL( + getDefaultShowOnlyStdHeaders(), + resources::arguments::show_only_std_headers::DefaultValue + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_project_builder.cpp b/src/application/test/suits/app_test_project_builder.cpp index d611fcf..7f5ca87 100644 --- a/src/application/test/suits/app_test_project_builder.cpp +++ b/src/application/test/suits/app_test_project_builder.cpp @@ -2,7 +2,7 @@ #include "application/resources/app_resources_arguments.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -34,11 +34,13 @@ namespace application::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ProjectBuildersTets, ProjectBuilderFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ProjectBuildersTets, ProjectBuilderFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty_arguments_and_configuration_file ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t1_empty_arguments_and_configuration_file ) { // Run parserArguments( {} ); @@ -53,7 +55,7 @@ TEST_CASE( t1_empty_arguments_and_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_only_arguments ) +BOOST_AUTO_TEST_CASE( t2_only_arguments ) { // Init using namespace resources::arguments; @@ -108,7 +110,7 @@ TEST_CASE( t2_only_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t3_only_configuration_file ) +BOOST_AUTO_TEST_CASE( t3_only_configuration_file ) { // Init createDefaultConfigurationFile( @@ -144,7 +146,7 @@ TEST_CASE( t3_only_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t5_1_ignore_system_includes_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t5_1_ignore_system_includes_from_configuration_file ) { // Init createDefaultConfigurationFile( @@ -163,7 +165,7 @@ TEST_CASE( t5_1_ignore_system_includes_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_ignore_system_includes_from_arguments ) +BOOST_AUTO_TEST_CASE( t5_2_ignore_system_includes_from_arguments ) { // Run parserArguments( { "--ignore_system_includes=true" } ); @@ -175,7 +177,7 @@ TEST_CASE( t5_2_ignore_system_includes_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t5_3_ignore_system_includes_default ) +BOOST_AUTO_TEST_CASE( t5_3_ignore_system_includes_default ) { // Run parserArguments( {} ); @@ -190,7 +192,7 @@ TEST_CASE( t5_3_ignore_system_includes_default ) //------------------------------------------------------------------------------ -TEST_CASE( t6_1_ignore_files_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t6_1_ignore_files_from_configuration_file ) { // Init createDefaultConfigurationFile( @@ -208,7 +210,7 @@ TEST_CASE( t6_1_ignore_files_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t6_2_ignore_files_from_arguments ) +BOOST_AUTO_TEST_CASE( t6_2_ignore_files_from_arguments ) { // Run parserArguments( { "--ignore_files=boost.*" } ); @@ -220,21 +222,21 @@ TEST_CASE( t6_2_ignore_files_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t6_3_ignore_files_default ) +BOOST_AUTO_TEST_CASE( t6_3_ignore_files_default ) { // Run parserArguments( {} ); buildProject(); //Check - auto defaultValues = toStrings( resources::arguments::ignoreFiles::DefaultValue ); + auto defaultValues = toStrings( resources::arguments::ignoreFiles::DefaultValues ); BOOST_REQUIRE_EQUAL( getFileFiltersCount(), defaultValues.size() ); } //------------------------------------------------------------------------------ -TEST_CASE( t7_1_analyze_without_extension_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t7_1_analyze_without_extension_from_configuration_file ) { // Init createDefaultConfigurationFile( @@ -253,7 +255,7 @@ TEST_CASE( t7_1_analyze_without_extension_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t7_2_analyze_without_extension_from_arguments ) +BOOST_AUTO_TEST_CASE( t7_2_analyze_without_extension_from_arguments ) { // Run parserArguments( { "--analyze_without_extension=true" } ); @@ -265,7 +267,7 @@ TEST_CASE( t7_2_analyze_without_extension_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t7_3_analyze_without_extension_default ) +BOOST_AUTO_TEST_CASE( t7_3_analyze_without_extension_default ) { // Run parserArguments( {} ); @@ -279,7 +281,7 @@ TEST_CASE( t7_3_analyze_without_extension_default ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/test/suits/app_test_report_settings_loader.cpp b/src/application/test/suits/app_test_report_settings_loader.cpp index 4401e69..20bc053 100644 --- a/src/application/test/suits/app_test_report_settings_loader.cpp +++ b/src/application/test/suits/app_test_report_settings_loader.cpp @@ -1,6 +1,6 @@ #include "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -16,10 +16,15 @@ TEST PLAN: 2.2.1 from arguments 2.2.2 from configuration file 2.2.3 mix - 3.3 show std files + 2.3 show std files 2.3.1 from arguments 2.3.2 from configuration file 2.3.3 mix + 2.4 show only std headers + 2.4.1 from arguments + 2.4.2 from configuration file + 2.4.3 mix + 2.4.4 ignore show std files 3. Load report kinds 3.1 From arguments 3.2 From configuration file @@ -31,11 +36,12 @@ namespace application::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ReportSettingsLoaderTests, ReportSettingsLoaderFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ReportSettingsLoaderTests, ReportSettingsLoaderFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty_arguments_and_configuration_file ) +BOOST_AUTO_TEST_CASE( t1_empty_arguments_and_configuration_file ) { // Run parserArguments( "" ); @@ -51,7 +57,7 @@ TEST_CASE( t1_empty_arguments_and_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_1_1_load_max_files_from_arguments ) +BOOST_AUTO_TEST_CASE( t2_1_1_load_max_files_from_arguments ) { // Run parserArguments( "--report_limit=42" ); @@ -63,7 +69,7 @@ TEST_CASE( t2_1_1_load_max_files_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t2_1_2_load_max_files_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t2_1_2_load_max_files_from_configuration_file ) { // Run createConfigurationFile( R"({ "report_limit" : 42 })" ); @@ -75,7 +81,7 @@ TEST_CASE( t2_1_2_load_max_files_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_1_3_load_max_files_from_mix ) +BOOST_AUTO_TEST_CASE( t2_1_3_load_max_files_from_mix ) { // Run createConfigurationFile( R"({ "report_limit" : 1 })" ); @@ -88,7 +94,7 @@ TEST_CASE( t2_1_3_load_max_files_from_mix ) //------------------------------------------------------------------------------ -TEST_CASE( t2_2_1_load_max_details_from_arguments ) +BOOST_AUTO_TEST_CASE( t2_2_1_load_max_details_from_arguments ) { // Run parserArguments( "--report_details_limit=42" ); @@ -100,7 +106,7 @@ TEST_CASE( t2_2_1_load_max_details_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t2_2_2_load_max_details_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t2_2_2_load_max_details_from_configuration_file ) { // Run createConfigurationFile( R"({ "report_details_limit" : 42 })" ); @@ -112,7 +118,7 @@ TEST_CASE( t2_2_2_load_max_details_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_2_2_load_max_details_from_mix ) +BOOST_AUTO_TEST_CASE( t2_2_2_load_max_details_from_mix ) { // Run createConfigurationFile( R"({ "report_details_limit" : 1 })" ); @@ -125,7 +131,7 @@ TEST_CASE( t2_2_2_load_max_details_from_mix ) //------------------------------------------------------------------------------ -TEST_CASE( t2_3_1_load_show_std_files_from_arguments ) +BOOST_AUTO_TEST_CASE( t2_3_1_load_show_std_files_from_arguments ) { // Run parserArguments( "--show_std_files=true" ); @@ -137,7 +143,7 @@ TEST_CASE( t2_3_1_load_show_std_files_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t2_3_2_load_show_std_files_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t2_3_2_load_show_std_files_from_configuration_file ) { // Run createConfigurationFile( R"({ "show_std_files" : true })" ); @@ -149,7 +155,7 @@ TEST_CASE( t2_3_2_load_show_std_files_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_3_3_load_show_std_files_from_mix ) +BOOST_AUTO_TEST_CASE( t2_3_3_load_show_std_files_from_mix ) { // Run createConfigurationFile( R"({ "show_std_files" : true })" ); @@ -162,7 +168,7 @@ TEST_CASE( t2_3_3_load_show_std_files_from_mix ) //------------------------------------------------------------------------------ -TEST_CASE( t3_3_1_load_reports_from_arguments ) +BOOST_AUTO_TEST_CASE( t3_3_1_load_reports_from_arguments ) { // Run parserArguments( "--report=most_impact,unresolved" ); @@ -174,7 +180,7 @@ TEST_CASE( t3_3_1_load_reports_from_arguments ) //------------------------------------------------------------------------------ -TEST_CASE( t3_3_2_load_reports_from_configuration_file ) +BOOST_AUTO_TEST_CASE( t3_3_2_load_reports_from_configuration_file ) { // Run createConfigurationFile( R"({ "report" : [ "most_impact","unresolved" ] })" ); @@ -186,7 +192,7 @@ TEST_CASE( t3_3_2_load_reports_from_configuration_file ) //------------------------------------------------------------------------------ -TEST_CASE( t3_3_3_load_reports_from_mix ) +BOOST_AUTO_TEST_CASE( t3_3_3_load_reports_from_mix ) { // Run createConfigurationFile( R"({ "report" : [ "most_impact" ] })" ); @@ -199,7 +205,58 @@ TEST_CASE( t3_3_3_load_reports_from_mix ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_CASE( t_2_4_1_load_show_only_std_headers_from_arguments ) +{ + // Run + parserArguments( "--show_only_std_headers=true" ); + load(); + + // Check + BOOST_CHECK_EQUAL( getShowOnlyStdHeaders(), true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE( t2_4_2_load_show_only_std_headers_from_configuration_file ) +{ + // Run + createConfigurationFile( R"({ "show_only_std_headers" : true })" ); + load(); + + // Check + BOOST_CHECK_EQUAL( getShowOnlyStdHeaders(), true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE( t2_4_3_load_show_only_std_headers_from_mix ) +{ + // Run + createConfigurationFile( R"({ "show_only_std_headers" : true })" ); + parserArguments( "--show_only_std_headers=false" ); + load(); + + // Check + BOOST_CHECK_EQUAL( getShowOnlyStdHeaders(), false ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_CASE( t2_4_4_load_show_only_std_headers_ignore_show_std_files ) +{ + // Run + parserArguments( "--show_only_std_headers=true" ); + parserArguments( "--show_std_files=false" ); + load(); + + // Check + BOOST_CHECK_EQUAL( getShowOnlyStdHeaders(), true ); + BOOST_CHECK_EQUAL( getShowStdFiles(), true ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_cmake_project_builder.hpp b/src/application/tools/app_cmake_project_builder.hpp index e02d178..c70f719 100644 --- a/src/application/tools/app_cmake_project_builder.hpp +++ b/src/application/tools/app_cmake_project_builder.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file.cpp b/src/application/tools/app_configuration_file.cpp index b08d83a..3b6dc4d 100644 --- a/src/application/tools/app_configuration_file.cpp +++ b/src/application/tools/app_configuration_file.cpp @@ -33,6 +33,7 @@ void ConfigurationFile::loadFromJson( const json::JsonObject & _json ) loadReportLimit( _json ); loadReportDetailsLimit( _json ); loadShowStdFiles( _json ); + loadShowOnlyStdHeaders( _json ); } //------------------------------------------------------------------------------ @@ -128,6 +129,13 @@ ConfigurationFile::BoolOpt ConfigurationFile::getShowStdFiles() const //------------------------------------------------------------------------------ +ConfigurationFile::BoolOpt ConfigurationFile::getShowOnlyStdFiles() const +{ + return m_showOnlyStdHeaders; +} + +//------------------------------------------------------------------------------ + void ConfigurationFile::loadProjectDir( const json::JsonObject & _json ) { using namespace resources; @@ -261,6 +269,15 @@ void ConfigurationFile::loadShowStdFiles( const json::JsonObject & _json ) //------------------------------------------------------------------------------ +void ConfigurationFile::loadShowOnlyStdHeaders( const json::JsonObject & _json ) +{ + using namespace resources; + + loadBoolOpt( _json, configuration_file::ShowOnlyStdHeaders, m_showOnlyStdHeaders ); +} + +//------------------------------------------------------------------------------ + void ConfigurationFile::loadStringValue( const json::JsonObject & _json, std::string_view _name, diff --git a/src/application/tools/app_configuration_file.hpp b/src/application/tools/app_configuration_file.hpp index 0540b38..31fb26d 100644 --- a/src/application/tools/app_configuration_file.hpp +++ b/src/application/tools/app_configuration_file.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -61,6 +61,7 @@ class ConfigurationFile IntOpt getReportLimit() const; IntOpt getReportDetailsLimit() const; BoolOpt getShowStdFiles() const; + BoolOpt getShowOnlyStdFiles() const; private: void loadProjectDir( const json::JsonObject & _json ); @@ -78,6 +79,7 @@ class ConfigurationFile void loadReportLimit( const json::JsonObject & _json ); void loadReportDetailsLimit( const json::JsonObject & _json ); void loadShowStdFiles( const json::JsonObject & _json ); + void loadShowOnlyStdHeaders( const json::JsonObject & _json ); void loadStringValue( const json::JsonObject & _json, @@ -132,6 +134,7 @@ class ConfigurationFile IntOpt m_reportLimit; IntOpt m_reportDetailsLimit; BoolOpt m_showStdFiles; + BoolOpt m_showOnlyStdHeaders; }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file_loader.cpp b/src/application/tools/app_configuration_file_loader.cpp index c876ace..92e891a 100644 --- a/src/application/tools/app_configuration_file_loader.cpp +++ b/src/application/tools/app_configuration_file_loader.cpp @@ -42,12 +42,7 @@ ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( configurationPathOpt = _arguments.getDefaultConfigurationFile(); } - INTERNAL_CHECK_WARRING( configurationPathOpt ); - if( !configurationPathOpt ) - { - return nullptr; - } - + INTERNAL_CHECK_ERROR( configurationPathOpt ); if( !m_fs.isExistFile( *configurationPathOpt ) ) { return nullptr; @@ -55,12 +50,12 @@ ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( auto filePtr = m_fs.openFile( *configurationPathOpt ); INTERNAL_CHECK_WARRING( filePtr ) - if( !filePtr ) + if( filePtr ) { - return nullptr; + return load( *filePtr ); } - return load( *filePtr ); + return nullptr; } //------------------------------------------------------------------------------ @@ -71,20 +66,15 @@ ConfigurationFileLoader::ConfigurationFilePtr ConfigurationFileLoader::load( { auto jsonObjectPtr = m_jsonAccessor.createJson( _file.toInputStream() ); INTERNAL_CHECK_WARRING( jsonObjectPtr ) - if( !jsonObjectPtr ) + if( jsonObjectPtr ) { - return nullptr; - } - - ConfigurationFilePtr resultPtr{ new ConfigurationFile }; - INTERNAL_CHECK_WARRING( resultPtr ) - if( !resultPtr ) - { - return nullptr; + ConfigurationFilePtr resultPtr{ new ConfigurationFile }; + INTERNAL_CHECK_ERROR( resultPtr ) + resultPtr->loadFromJson( *jsonObjectPtr ); + return resultPtr; } - resultPtr->loadFromJson( *jsonObjectPtr ); - return resultPtr; + return nullptr; } //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_configuration_file_loader.hpp b/src/application/tools/app_configuration_file_loader.hpp index 8c99a65..cfd2933 100644 --- a/src/application/tools/app_configuration_file_loader.hpp +++ b/src/application/tools/app_configuration_file_loader.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_log.hpp b/src/application/tools/app_log.hpp index 3d329e1..6545f93 100644 --- a/src/application/tools/app_log.hpp +++ b/src/application/tools/app_log.hpp @@ -1,7 +1,9 @@ #pragma once +#include + #include -#include +#include //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_parser_arg.hpp b/src/application/tools/app_parser_arg.hpp index 08533fe..dd58610 100644 --- a/src/application/tools/app_parser_arg.hpp +++ b/src/application/tools/app_parser_arg.hpp @@ -1,8 +1,11 @@ #pragma once +#include +#include +#include + #include #include -#include //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_parser_arg_wrapper.cpp b/src/application/tools/app_parser_arg_wrapper.cpp index 2778c14..205544d 100644 --- a/src/application/tools/app_parser_arg_wrapper.cpp +++ b/src/application/tools/app_parser_arg_wrapper.cpp @@ -29,7 +29,7 @@ ParserArgWrapper::ParserArgWrapper() , m_fileExtensionsArg{ resources::arguments::fileExtensions::FullName, resources::arguments::fileExtensions::Description, - toStrings( resources::arguments::fileExtensions::DefaultValue ) + toStrings( resources::arguments::fileExtensions::DefaultValues ) } , m_analyzeWithoutextension{ resources::arguments::analyze_without_extension::FullName, @@ -39,12 +39,12 @@ ParserArgWrapper::ParserArgWrapper() , m_includeDirsArg{ resources::arguments::includeDirs::FullName, resources::arguments::includeDirs::Description, - toPaths( resources::arguments::includeDirs::DefaultValue ) + toPaths( resources::arguments::includeDirs::DefaultValues ) } , m_ignoreDirsArg{ resources::arguments::ignoreDirs::FullName, resources::arguments::ignoreDirs::Description, - toPaths( resources::arguments::ignoreDirs::DefaultValue ) + toPaths( resources::arguments::ignoreDirs::DefaultValues ) } , m_ignoreSystemIncludes{ resources::arguments::ignoreSystemIncludes::FullName, @@ -54,7 +54,7 @@ ParserArgWrapper::ParserArgWrapper() , m_ignoreFilesArg{ resources::arguments::ignoreFiles::FullName, resources::arguments::ignoreFiles::Description, - toStrings( resources::arguments::ignoreFiles::DefaultValue ) + toStrings( resources::arguments::ignoreFiles::DefaultValues ) } , m_configurationFileArg{ resources::arguments::configurationFile::FullName, @@ -98,6 +98,11 @@ ParserArgWrapper::ParserArgWrapper() resources::arguments::show_std_files::Description, resources::arguments::show_std_files::DefaultValue } + , m_showOnlyStdHeadersArg{ + resources::arguments::show_only_std_headers::FullName, + resources::arguments::show_only_std_headers::Description, + resources::arguments::show_only_std_headers::DefaultValue + } { } @@ -135,6 +140,7 @@ void ParserArgWrapper::parse( int _argc, char * _argv[] ) setArgumentValue( m_reportLimitArg, &ParserArgWrapper::getInt ); setArgumentValue( m_reportDetailsLimitArg, &ParserArgWrapper::getInt ); setArgumentValue( m_showStdFilesArg, &ParserArgWrapper::getBool ); + setArgumentValue( m_showOnlyStdHeadersArg, &ParserArgWrapper::getBool ); } //------------------------------------------------------------------------------ @@ -175,6 +181,7 @@ void ParserArgWrapper::init() addArgument< int >( m_reportLimitArg ); addArgument< int >( m_reportDetailsLimitArg ); addArgument< bool >( m_showStdFilesArg ); + addArgument< bool >( m_showOnlyStdHeadersArg ); addArgument( m_helpArg ); addArgument( m_verboseArg ); @@ -336,13 +343,27 @@ ParserArgWrapper::BoolOpt ParserArgWrapper::getShowStdFile() const //------------------------------------------------------------------------------ -bool ParserArgWrapper::getDefaultShowStdfile() const +bool ParserArgWrapper::getDefaultShowStdFile() const { return getDefaultValue< bool >( m_showStdFilesArg ); } //------------------------------------------------------------------------------ +ParserArgWrapper::BoolOpt ParserArgWrapper::getShowOnlyStdHeaders() const +{ + return m_showOnlyStdHeadersArg.getValue< bool >(); +} + +//------------------------------------------------------------------------------ + +bool ParserArgWrapper::getDefaultShowOnlyStdHeaders() const +{ + return getDefaultValue< bool >( m_showOnlyStdHeadersArg ); +} + +//------------------------------------------------------------------------------ + ParserArgWrapper::PathOpt ParserArgWrapper::getConfigurationFile() const { return m_configurationFileArg.getValue< Path >(); diff --git a/src/application/tools/app_parser_arg_wrapper.hpp b/src/application/tools/app_parser_arg_wrapper.hpp index ca598a1..f8864e0 100644 --- a/src/application/tools/app_parser_arg_wrapper.hpp +++ b/src/application/tools/app_parser_arg_wrapper.hpp @@ -3,8 +3,6 @@ #include "application/tools/app_argument.hpp" #include "application/tools/app_parser_arg.hpp" -#include - //------------------------------------------------------------------------------ namespace reporter { @@ -79,7 +77,10 @@ class ParserArgWrapper int getDefaultReportDetailsLimit() const; BoolOpt getShowStdFile() const; - bool getDefaultShowStdfile() const; + bool getDefaultShowStdFile() const; + + BoolOpt getShowOnlyStdHeaders() const; + bool getDefaultShowOnlyStdHeaders() const; bool isHelp() const; void showHelp( std::ostream & _stream ) const; @@ -140,6 +141,7 @@ class ParserArgWrapper Argument m_reportLimitArg; Argument m_reportDetailsLimitArg; Argument m_showStdFilesArg; + Argument m_showOnlyStdHeadersArg; }; //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_project_builder.hpp b/src/application/tools/app_project_builder.hpp index c5748bd..bfc4d19 100644 --- a/src/application/tools/app_project_builder.hpp +++ b/src/application/tools/app_project_builder.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/application/tools/app_report_settings_loader.cpp b/src/application/tools/app_report_settings_loader.cpp index e0d5903..a01dcf2 100644 --- a/src/application/tools/app_report_settings_loader.cpp +++ b/src/application/tools/app_report_settings_loader.cpp @@ -43,10 +43,14 @@ ReportSettingsLoader::SettingsPtr ReportSettingsLoader::load( const auto maxFiles = loadMaxFilesCount( _arguments, _configurationFile ); const auto maxDetails = loadMaxDetailsCount( _arguments, _configurationFile ); const bool showStdFiles = loadShowStdFiles( _arguments, _configurationFile ); + const bool showOnlyStdFiles = loadShowOnlyStdHeaders( _arguments, _configurationFile ); settings.setMaxFilesCount( maxFiles ); settings.setMaxDetailsCount( maxDetails ); settings.setShowStdFiles( showStdFiles ); + settings.setShowOnlyStdHeaders( showOnlyStdFiles ); + if( showOnlyStdFiles ) + settings.setShowStdFiles( true ); return settingsPtr; } @@ -123,7 +127,7 @@ bool ReportSettingsLoader::loadShowStdFiles( return getValue( _arguments, &ParserArgWrapper::getShowStdFile, - &ParserArgWrapper::getDefaultShowStdfile, + &ParserArgWrapper::getDefaultShowStdFile, _configurationFile, &ConfigurationFile::getShowStdFiles ); @@ -131,6 +135,22 @@ bool ReportSettingsLoader::loadShowStdFiles( //------------------------------------------------------------------------------ +bool ReportSettingsLoader::loadShowOnlyStdHeaders( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile +) +{ + return getValue( + _arguments, + &ParserArgWrapper::getShowOnlyStdHeaders, + &ParserArgWrapper::getDefaultShowOnlyStdHeaders, + _configurationFile, + &ConfigurationFile::getShowOnlyStdFiles + ); +} + +//------------------------------------------------------------------------------ + template< typename _ValueType > _ValueType ReportSettingsLoader::getValue( const ParserArgWrapper & _arguments, diff --git a/src/application/tools/app_report_settings_loader.hpp b/src/application/tools/app_report_settings_loader.hpp index 3c29dac..aa6eba2 100644 --- a/src/application/tools/app_report_settings_loader.hpp +++ b/src/application/tools/app_report_settings_loader.hpp @@ -1,6 +1,9 @@ #pragma once -#include +#include +#include +#include +#include //------------------------------------------------------------------------------ @@ -21,8 +24,8 @@ namespace application { class ReportSettingsLoader { public: - using SettingsPtr = stdfwd::unique_ptr< reporter::Settings >; - using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; + using SettingsPtr = stdfwd::unique_ptr< reporter::Settings >; + using ReporterKinds = stdfwd::vector< reporter::ReporterKind >; using CountType = std::size_t; @@ -56,6 +59,11 @@ class ReportSettingsLoader const ConfigurationFile * _configurationFile ); + static bool loadShowOnlyStdHeaders( + const ParserArgWrapper & _arguments, + const ConfigurationFile * _configurationFile + ); + template< typename _ValueType > static _ValueType getValue( const ParserArgWrapper & _arguments, diff --git a/src/cmake_project/api/cprj_loader.hpp b/src/cmake_project/api/cprj_loader.hpp index 76c1bf8..50dca9a 100644 --- a/src/cmake_project/api/cprj_loader.hpp +++ b/src/cmake_project/api/cprj_loader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/api/cprj_project.hpp b/src/cmake_project/api/cprj_project.hpp index 0e21ebb..34037ac 100644 --- a/src/cmake_project/api/cprj_project.hpp +++ b/src/cmake_project/api/cprj_project.hpp @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/ih/cprj_accessor.hpp b/src/cmake_project/ih/cprj_accessor.hpp index a7322c6..7edcdbf 100644 --- a/src/cmake_project/ih/cprj_accessor.hpp +++ b/src/cmake_project/ih/cprj_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_includes_parser.hpp b/src/cmake_project/impl/cprj_includes_parser.hpp index 5dfd66f..e299fdd 100644 --- a/src/cmake_project/impl/cprj_includes_parser.hpp +++ b/src/cmake_project/impl/cprj_includes_parser.hpp @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_includes_parser_context.cpp b/src/cmake_project/impl/cprj_includes_parser_context.cpp index f135074..f451564 100644 --- a/src/cmake_project/impl/cprj_includes_parser_context.cpp +++ b/src/cmake_project/impl/cprj_includes_parser_context.cpp @@ -9,8 +9,8 @@ namespace cmake_project { //------------------------------------------------------------------------------ IncludeParserContext::IncludeParserContext( std::string_view _command ) - : m_size{ _command.size() } - , m_command{ _command } + : m_command{ _command } + , m_size{ _command.size() } { } diff --git a/src/cmake_project/impl/cprj_includes_parser_context.hpp b/src/cmake_project/impl/cprj_includes_parser_context.hpp index 63929db..70ccdd4 100644 --- a/src/cmake_project/impl/cprj_includes_parser_context.hpp +++ b/src/cmake_project/impl/cprj_includes_parser_context.hpp @@ -1,10 +1,10 @@ #pragma once +#include #include -#include +#include #include -#include //------------------------------------------------------------------------------ @@ -17,7 +17,7 @@ class IncludeParserContext public: using Path = stdfs::path; - using Includes = stdfwd::vector< Path >; + using Includes = std::vector< Path >; using IndexType = std::size_t; IncludeParserContext( std::string_view _command ); @@ -30,10 +30,11 @@ class IncludeParserContext void addInclude( const Path & _path ); private: + std::vector< Path > m_includes; + + std::string m_command; IndexType m_size; - std::string m_command; - Includes m_includes; }; //------------------------------------------------------------------------------ diff --git a/src/cmake_project/impl/cprj_loader_impl.hpp b/src/cmake_project/impl/cprj_loader_impl.hpp index e21f71a..cb01ebc 100644 --- a/src/cmake_project/impl/cprj_loader_impl.hpp +++ b/src/cmake_project/impl/cprj_loader_impl.hpp @@ -2,6 +2,8 @@ #include "cmake_project/api/cprj_loader.hpp" +#include + #include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp index cc2e7d1..a1ad269 100644 --- a/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp +++ b/src/cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp @@ -1,7 +1,10 @@ #pragma once +#include +#include +#include + #include -#include //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp index dda0a2d..145968c 100644 --- a/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp +++ b/src/cmake_project/test/fixtures/cprj_test_loader_fixture.hpp @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include #include diff --git a/src/cmake_project/test/suits/cprj_test_includes_parser.cpp b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp index 8e2434a..1919f45 100644 --- a/src/cmake_project/test/suits/cprj_test_includes_parser.cpp +++ b/src/cmake_project/test/suits/cprj_test_includes_parser.cpp @@ -1,6 +1,6 @@ #include "cmake_project/test/fixtures/cprj_test_includes_parser_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -22,18 +22,20 @@ namespace cmake_project::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( IncldesParserTests, IncldesParserFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( IncldesParserTests, IncldesParserFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_without_include_paramter ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t1_without_include_paramter ) { // Run auto actualResult = parseString( "/usr/bin/c++ -o file2.cpp.o -c file2.cpp" ); Strings exceptedResult{}; // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -44,14 +46,15 @@ TEST_CASE( t1_without_include_paramter ) //------------------------------------------------------------------------------ -TEST_CASE( t2_paramter_in_name ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t2_paramter_in_name ) { // Run auto actualResult = parseString( "/bin/c++ -o f-I.cpp.o -c f-I.cpp" ); Strings exceptedResult{}; // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -62,14 +65,15 @@ TEST_CASE( t2_paramter_in_name ) //------------------------------------------------------------------------------ -TEST_CASE( t3_one_paramter ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t3_one_paramter ) { // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./include -c f.cpp" ); Strings exceptedResult = toPathStrings( {"./include"} ); // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -79,14 +83,15 @@ TEST_CASE( t3_one_paramter ) //------------------------------------------------------------------------------ -TEST_CASE( t4_several_parameters ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t4_several_parameters ) { // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -I./lib1 -I./lib2 -c f.cpp" ); Strings exceptedResult = toPathStrings( { "./lib1", "./lib2" } ); // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -96,14 +101,15 @@ TEST_CASE( t4_several_parameters ) //------------------------------------------------------------------------------ -TEST_CASE( t5_paramter_in_end_of_string ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t5_paramter_in_end_of_string ) { // Run auto actualResult = parseString( "/bin/c++ -o f.cpp.o -c f.cpp -I./include" ); Strings exceptedResult = toPathStrings( {"./include"} ); // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -113,14 +119,15 @@ TEST_CASE( t5_paramter_in_end_of_string ) //------------------------------------------------------------------------------ -TEST_CASE( t6_file_with_space ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t6_file_with_space ) { // Run auto actualResult = parseString( R"(/bin/c++ -o f.cpp.o -c \"space in file\".cpp)" ); Strings exceptedResult; // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -130,7 +137,8 @@ TEST_CASE( t6_file_with_space ) //------------------------------------------------------------------------------ -TEST_CASE( t7_include_with_space ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t7_include_with_space ) { // Run auto actualResult = parseString( @@ -138,7 +146,7 @@ TEST_CASE( t7_include_with_space ) Strings exceptedResult = toPathStrings( { "./include with space" } ); // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -148,7 +156,8 @@ TEST_CASE( t7_include_with_space ) //------------------------------------------------------------------------------ -TEST_CASE( t8_double_spaces ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_CASE( t8_double_spaces ) { // Run auto actualResult = @@ -156,7 +165,7 @@ TEST_CASE( t8_double_spaces ) Strings exceptedResult = toPathStrings( { "./include" } ); // Check - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( actualResult.begin(), actualResult.end(), exceptedResult.begin(), @@ -166,7 +175,8 @@ TEST_CASE( t8_double_spaces ) //------------------------------------------------------------------------------ -TEST_GROUP_END +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/cmake_project/test/suits/cprj_test_loader.cpp b/src/cmake_project/test/suits/cprj_test_loader.cpp index d12bfd5..a40ad35 100644 --- a/src/cmake_project/test/suits/cprj_test_loader.cpp +++ b/src/cmake_project/test/suits/cprj_test_loader.cpp @@ -1,6 +1,6 @@ #include "cmake_project/test/fixtures/cprj_test_loader_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -17,11 +17,12 @@ namespace cmake_project::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( CMakeProjectLoaderTests, LoaderFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( CMakeProjectLoaderTests, LoaderFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_one_file ) +BOOST_AUTO_TEST_CASE( t1_one_file ) { // Init addDefaultComandForFile( "file.cpp" ); @@ -33,7 +34,7 @@ TEST_CASE( t1_one_file ) const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "file.cpp" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -43,7 +44,7 @@ TEST_CASE( t1_one_file ) //------------------------------------------------------------------------------ -TEST_CASE( t2_several_files ) +BOOST_AUTO_TEST_CASE( t2_several_files ) { // Init addDefaultComandForFile( "file1.cpp" ); @@ -56,7 +57,7 @@ TEST_CASE( t2_several_files ) const auto resultFiles = getResultsFiles(); const auto exceptedFiles = toExceptedFiles( { "file1.cpp", "file2.cpp" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -66,7 +67,7 @@ TEST_CASE( t2_several_files ) //------------------------------------------------------------------------------ -TEST_CASE( t3_includes ) +BOOST_AUTO_TEST_CASE( t3_includes ) { // Init addComandWithIncludes( "file1.cpp", { "./lib1" } ); @@ -86,7 +87,7 @@ TEST_CASE( t3_includes ) "file4.cpp" } ); - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( resultFiles.begin(), resultFiles.end(), exceptedFiles.begin(), @@ -97,7 +98,7 @@ TEST_CASE( t3_includes ) const auto resultIncludes = getResultsIncludes( "file1.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib1" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -108,7 +109,7 @@ TEST_CASE( t3_includes ) const auto resultIncludes = getResultsIncludes( "file2.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib2", "./lib3" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -119,7 +120,7 @@ TEST_CASE( t3_includes ) const auto resultIncludes = getResultsIncludes( "file3.cpp" ); const auto exceptedIncludes = toExceptedIncludes( {} ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -130,7 +131,7 @@ TEST_CASE( t3_includes ) const auto resultIncludes = getResultsIncludes( "file4.cpp" ); const auto exceptedIncludes = toExceptedIncludes( { "./lib4" } ); - TEST_CHECK_EQUAL_COLLECTIONS( + BOOST_CHECK_EQUAL_COLLECTIONS( resultIncludes.begin(), resultIncludes.end(), exceptedIncludes.begin(), @@ -141,7 +142,7 @@ TEST_CASE( t3_includes ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/compilation_db/api/cdb_command_object.hpp b/src/compilation_db/api/cdb_command_object.hpp index a174873..4166c0e 100644 --- a/src/compilation_db/api/cdb_command_object.hpp +++ b/src/compilation_db/api/cdb_command_object.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/compilation_db/api/cdb_database.hpp b/src/compilation_db/api/cdb_database.hpp index dace055..c055777 100644 --- a/src/compilation_db/api/cdb_database.hpp +++ b/src/compilation_db/api/cdb_database.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/compilation_db/api/cdb_loader.hpp b/src/compilation_db/api/cdb_loader.hpp index 91b9c40..0a7d679 100644 --- a/src/compilation_db/api/cdb_loader.hpp +++ b/src/compilation_db/api/cdb_loader.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/compilation_db/ih/cdb_accessor.hpp b/src/compilation_db/ih/cdb_accessor.hpp index 783c751..e0ae774 100644 --- a/src/compilation_db/ih/cdb_accessor.hpp +++ b/src/compilation_db/ih/cdb_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/compilation_db/impl/cdb_database_impl.cpp b/src/compilation_db/impl/cdb_database_impl.cpp index f6c11d7..62f9445 100644 --- a/src/compilation_db/impl/cdb_database_impl.cpp +++ b/src/compilation_db/impl/cdb_database_impl.cpp @@ -39,8 +39,8 @@ void DatabaseImpl::addCommand( std::string_view _file ) { - m_objects.emplace_back( - new CommandObjectImpl{ _directory, _command, _file } + m_objects.push_back( + std::make_unique< CommandObjectImpl >( _directory, _command, _file ) ); } diff --git a/src/compilation_db/impl/cdb_loader_impl.cpp b/src/compilation_db/impl/cdb_loader_impl.cpp index a54fa74..cf2acb2 100644 --- a/src/compilation_db/impl/cdb_loader_impl.cpp +++ b/src/compilation_db/impl/cdb_loader_impl.cpp @@ -42,7 +42,10 @@ LoaderImpl::DatabasePtr LoaderImpl::load( const json::JsonObject & _json ) { auto itemPtr = array.at( i ); INTERNAL_CHECK_WARRING( itemPtr ); - loadItem( *itemPtr, *result ); + if( itemPtr ) + { + loadItem( *itemPtr, *result ); + } } return result; diff --git a/src/compilation_db/test/fixtures/cdb_test_fixture.hpp b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp index 69dd4d2..d510e9d 100644 --- a/src/compilation_db/test/fixtures/cdb_test_fixture.hpp +++ b/src/compilation_db/test/fixtures/cdb_test_fixture.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/src/compilation_db/test/suits/cdb_test_suits.cpp b/src/compilation_db/test/suits/cdb_test_suits.cpp index 54ffef7..a894e4b 100644 --- a/src/compilation_db/test/suits/cdb_test_suits.cpp +++ b/src/compilation_db/test/suits/cdb_test_suits.cpp @@ -3,7 +3,7 @@ #include "compilation_db/api/cdb_command_object.hpp" #include "compilation_db/api/cdb_database.hpp" -#include "test_tools/test_macros.hpp" +#include #include /*------------------------------------------------------------------------------ @@ -19,11 +19,12 @@ namespace compilation_db::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( CompilationDbTests, CompilationDbFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( CompilationDbTests, CompilationDbFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_one_compilation_object ) +BOOST_AUTO_TEST_CASE( t1_one_compilation_object ) { // Run const Database & db = parseJson( @@ -51,7 +52,7 @@ TEST_CASE( t1_one_compilation_object ) //------------------------------------------------------------------------------ -TEST_CASE( t2_several_compilation_objects ) +BOOST_AUTO_TEST_CASE( t2_several_compilation_objects ) { // Run const Database & db = parseJson( @@ -107,7 +108,7 @@ TEST_CASE( t2_several_compilation_objects ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/exception/api/exc_exception.hpp b/src/exception/api/exc_exception.hpp index c91b3b8..1c9cbf4 100644 --- a/src/exception/api/exc_exception.hpp +++ b/src/exception/api/exc_exception.hpp @@ -1,7 +1,7 @@ #pragma once #include -#include +#include //------------------------------------------------------------------------------ diff --git a/src/fs/api/fs_file.hpp b/src/fs/api/fs_file.hpp index f807a11..dd8bd4d 100644 --- a/src/fs/api/fs_file.hpp +++ b/src/fs/api/fs_file.hpp @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/fs/api/fs_file_system.hpp b/src/fs/api/fs_file_system.hpp index ee161e9..cedad40 100644 --- a/src/fs/api/fs_file_system.hpp +++ b/src/fs/api/fs_file_system.hpp @@ -1,6 +1,8 @@ #pragma once -#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/json/api/json_array.hpp b/src/json/api/json_array.hpp index e2c8832..75fc282 100644 --- a/src/json/api/json_array.hpp +++ b/src/json/api/json_array.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/json/api/json_object.hpp b/src/json/api/json_object.hpp index 221c327..a07b2dc 100644 --- a/src/json/api/json_object.hpp +++ b/src/json/api/json_object.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/json/api/json_value.hpp b/src/json/api/json_value.hpp index 8ba3635..c7b51c1 100644 --- a/src/json/api/json_value.hpp +++ b/src/json/api/json_value.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/json/ih/json_accessor.hpp b/src/json/ih/json_accessor.hpp index c20df4d..1b0b1f0 100644 --- a/src/json/ih/json_accessor.hpp +++ b/src/json/ih/json_accessor.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/json/test/fixtures/json_test_fixture.hpp b/src/json/test/fixtures/json_test_fixture.hpp index adbd2a2..6a20847 100644 --- a/src/json/test/fixtures/json_test_fixture.hpp +++ b/src/json/test/fixtures/json_test_fixture.hpp @@ -2,7 +2,6 @@ #include #include -#include //------------------------------------------------------------------------------ diff --git a/src/json/test/suits/json_test_suits.cpp b/src/json/test/suits/json_test_suits.cpp index d85460c..81480ad 100644 --- a/src/json/test/suits/json_test_suits.cpp +++ b/src/json/test/suits/json_test_suits.cpp @@ -4,7 +4,7 @@ #include "json/api/json_object.hpp" #include "json/api/json_value.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -28,12 +28,12 @@ TEST PLAN: namespace json::test { //------------------------------------------------------------------------------ -// clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( JsonTests, JsonFixture ) + +BOOST_FIXTURE_TEST_SUITE( JsonTests, JsonFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_simple_json ) +BOOST_AUTO_TEST_CASE( t1_simple_json ) { // Init createJsonFile( @@ -52,81 +52,81 @@ TEST_CASE( t1_simple_json ) { BOOST_TEST_PASSPOINT(); auto projectDirPtr = json.getAttributeValue( "project_dir" ); - TEST_REQUIRE( projectDirPtr ); + BOOST_REQUIRE( projectDirPtr ); const JsonValue & projectDir = *projectDirPtr; - TEST_CHECK_EQUAL( projectDir.asString(), "./src" ); + BOOST_CHECK_EQUAL( projectDir.asString(), "./src" ); } { BOOST_TEST_PASSPOINT(); auto fileExtensionsPtr = json.getAttributeValue( "file_extensions" ); - TEST_REQUIRE( fileExtensionsPtr ); + BOOST_REQUIRE( fileExtensionsPtr ); const JsonValue & fileExtensionsValue = *fileExtensionsPtr; auto fileExtensionsArrayPtr = fileExtensionsValue.asArray(); - TEST_REQUIRE( fileExtensionsArrayPtr ); + BOOST_REQUIRE( fileExtensionsArrayPtr ); const JsonArray & fileExtensionsArray = *fileExtensionsArrayPtr; BOOST_REQUIRE_EQUAL( fileExtensionsArray.getSize(), 2 ); { auto cppExtensionsPtr = fileExtensionsArray.at( 0 ); - TEST_REQUIRE( cppExtensionsPtr ); + BOOST_REQUIRE( cppExtensionsPtr ); const JsonValue & cppExtension = *cppExtensionsPtr; - TEST_CHECK_EQUAL( cppExtension.asString(), "*.cpp" ); + BOOST_CHECK_EQUAL( cppExtension.asString(), "*.cpp" ); } { auto hppExtensionsPtr = fileExtensionsArray.at( 1 ); - TEST_REQUIRE( hppExtensionsPtr ); + BOOST_REQUIRE( hppExtensionsPtr ); const JsonValue & hppExtension = *hppExtensionsPtr; - TEST_CHECK_EQUAL( hppExtension.asString(), "*.hpp" ); + BOOST_CHECK_EQUAL( hppExtension.asString(), "*.hpp" ); } } { BOOST_TEST_PASSPOINT(); auto includeDirsPtr = json.getAttributeValue( "include_dirs" ); - TEST_REQUIRE( includeDirsPtr ); + BOOST_REQUIRE( includeDirsPtr ); const JsonValue & includeDirsValue = *includeDirsPtr; auto includeDirsArrayPtr = includeDirsValue.asArray(); - TEST_REQUIRE( includeDirsArrayPtr ); + BOOST_REQUIRE( includeDirsArrayPtr ); const JsonArray & includeDirsArray = *includeDirsArrayPtr; BOOST_REQUIRE_EQUAL( includeDirsArray.getSize(), 3 ); { auto dir1Ptr = includeDirsArray.at( 0 ); - TEST_REQUIRE( dir1Ptr ); + BOOST_REQUIRE( dir1Ptr ); const JsonValue & dir1 = *dir1Ptr; - TEST_CHECK_EQUAL( dir1.asString(), "." ); + BOOST_CHECK_EQUAL( dir1.asString(), "." ); } { auto dir2Ptr = includeDirsArray.at( 1 ); - TEST_REQUIRE( dir2Ptr ); + BOOST_REQUIRE( dir2Ptr ); const JsonValue & dir2 = *dir2Ptr; - TEST_CHECK_EQUAL( dir2.asString(), "/usr/include/" ); + BOOST_CHECK_EQUAL( dir2.asString(), "/usr/include/" ); } { auto dir3Ptr = includeDirsArray.at( 2 ); - TEST_REQUIRE( dir3Ptr ); + BOOST_REQUIRE( dir3Ptr ); const JsonValue & dir3 = *dir3Ptr; - TEST_CHECK_EQUAL( dir3.asString(), "./3rd-part/cpp-std-fwd-master/" ); + BOOST_CHECK_EQUAL( dir3.asString(), "./3rd-part/cpp-std-fwd-master/" ); } } { BOOST_TEST_PASSPOINT(); auto ignoreDirsPtr = json.getAttributeValue( "ignore_dirs" ); - TEST_REQUIRE( ignoreDirsPtr ); + BOOST_REQUIRE( ignoreDirsPtr ); const JsonValue & ignoreDirsValue = *ignoreDirsPtr; auto ignoreDirsArrayPtr = ignoreDirsValue.asArray(); - TEST_REQUIRE( ignoreDirsArrayPtr ); + BOOST_REQUIRE( ignoreDirsArrayPtr ); const JsonArray & ignoreDirsArray = *ignoreDirsArrayPtr; BOOST_REQUIRE_EQUAL( ignoreDirsArray.getSize(), 1 ); { auto dir1Ptr = ignoreDirsArray.at( 0 ); - TEST_REQUIRE( dir1Ptr ); + BOOST_REQUIRE( dir1Ptr ); const JsonValue & dir1 = *dir1Ptr; - TEST_CHECK_EQUAL( dir1.asString(), "./3rd-part" ); + BOOST_CHECK_EQUAL( dir1.asString(), "./3rd-part" ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_bool ) +BOOST_AUTO_TEST_CASE( t2_bool ) { // Init createJsonFile( R"({ "atr1":true, "atr2":false })" ); @@ -138,23 +138,23 @@ TEST_CASE( t2_bool ) { BOOST_TEST_PASSPOINT(); auto atr1Ptr = json.getAttributeValue( "atr1" ); - TEST_REQUIRE( atr1Ptr ); + BOOST_REQUIRE( atr1Ptr ); const JsonValue & atr1 = *atr1Ptr; - TEST_CHECK_EQUAL( atr1.asBool(), true ); + BOOST_CHECK_EQUAL( atr1.asBool(), true ); } { BOOST_TEST_PASSPOINT(); auto atr2Ptr = json.getAttributeValue( "atr2" ); - TEST_REQUIRE( atr2Ptr ); + BOOST_REQUIRE( atr2Ptr ); const JsonValue & atr2 = *atr2Ptr; - TEST_CHECK_EQUAL( atr2.asBool(), false ); + BOOST_CHECK_EQUAL( atr2.asBool(), false ); } } //------------------------------------------------------------------------------ -TEST_CASE( t3_int ) +BOOST_AUTO_TEST_CASE( t3_int ) { // Init createJsonFile( R"({ "val":42 })" ); @@ -164,14 +164,14 @@ TEST_CASE( t3_int ) // Check auto atrPtr = json.getAttributeValue( "val" ); - TEST_REQUIRE( atrPtr ); + BOOST_REQUIRE( atrPtr ); const JsonValue & val = *atrPtr; - TEST_CHECK_EQUAL( val.asInt(), 42 ); + BOOST_CHECK_EQUAL( val.asInt(), 42 ); } //------------------------------------------------------------------------------ -TEST_CASE( t4_string ) +BOOST_AUTO_TEST_CASE( t4_string ) { // Init createJsonFile( R"({ "name": "str" })" ); @@ -181,14 +181,14 @@ TEST_CASE( t4_string ) // Check auto atrPtr = json.getAttributeValue( "name" ); - TEST_REQUIRE( atrPtr ); + BOOST_REQUIRE( atrPtr ); const JsonValue & val = *atrPtr; - TEST_CHECK_EQUAL( val.asString(), "str" ); + BOOST_CHECK_EQUAL( val.asString(), "str" ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_object ) +BOOST_AUTO_TEST_CASE( t5_object ) { // Init createJsonFile( R"({ "object" : { "name" : "str" } })" ); @@ -198,20 +198,20 @@ TEST_CASE( t5_object ) // Check auto atrPtr = json.getAttributeValue( "object" ); - TEST_REQUIRE( atrPtr ); + BOOST_REQUIRE( atrPtr ); auto objectPtr = atrPtr->asObject(); - TEST_REQUIRE( objectPtr ); + BOOST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - TEST_REQUIRE( namePtr ); + BOOST_REQUIRE( namePtr ); - TEST_CHECK_EQUAL( namePtr->asString(), "str" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str" ); } //------------------------------------------------------------------------------ -TEST_CASE( t6_1_array_bool ) +BOOST_AUTO_TEST_CASE( t6_1_array_bool ) { // Init createJsonFile( R"({ "array" : [true,false] })" ); @@ -221,28 +221,28 @@ TEST_CASE( t6_1_array_bool ) // Check auto attributePtr = json.getAttributeValue( "array" ); - TEST_REQUIRE( attributePtr ); + BOOST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - TEST_REQUIRE( arrayPtr ); + BOOST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asBool(), true ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asBool(), true ); } { auto valPtr = array.at( 1 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asBool(), false ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asBool(), false ); } } //------------------------------------------------------------------------------ -TEST_CASE( t6_2_array_int ) +BOOST_AUTO_TEST_CASE( t6_2_array_int ) { // Init createJsonFile( R"({ "array" : [42,43] })" ); @@ -252,28 +252,28 @@ TEST_CASE( t6_2_array_int ) // Check auto attributePtr = json.getAttributeValue( "array" ); - TEST_REQUIRE( attributePtr ); + BOOST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - TEST_REQUIRE( arrayPtr ); + BOOST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asInt(), 42 ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asInt(), 42 ); } { auto valPtr = array.at( 1 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asInt(), 43 ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asInt(), 43 ); } } //------------------------------------------------------------------------------ -TEST_CASE( t6_3_array_string ) +BOOST_AUTO_TEST_CASE( t6_3_array_string ) { // Init createJsonFile( R"({ "array" : ["str1","str2"] })" ); @@ -283,28 +283,28 @@ TEST_CASE( t6_3_array_string ) // Check auto attributePtr = json.getAttributeValue( "array" ); - TEST_REQUIRE( attributePtr ); + BOOST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - TEST_REQUIRE( arrayPtr ); + BOOST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asString(), "str1" ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - TEST_REQUIRE( valPtr ); - TEST_CHECK_EQUAL( valPtr->asString(), "str2" ); + BOOST_REQUIRE( valPtr ); + BOOST_CHECK_EQUAL( valPtr->asString(), "str2" ); } } //------------------------------------------------------------------------------ -TEST_CASE( t6_4_array_object ) +BOOST_AUTO_TEST_CASE( t6_4_array_object ) { // Init createJsonFile( R"({ "array" : [ { "name": "str1" }, { "name": "str2" }] })" ); @@ -314,38 +314,38 @@ TEST_CASE( t6_4_array_object ) // Check auto attributePtr = json.getAttributeValue( "array" ); - TEST_REQUIRE( attributePtr ); + BOOST_REQUIRE( attributePtr ); auto arrayPtr = attributePtr->asArray(); - TEST_REQUIRE( arrayPtr ); + BOOST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - TEST_REQUIRE( valPtr ); + BOOST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - TEST_REQUIRE( objectPtr ); + BOOST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - TEST_CHECK_EQUAL( namePtr->asString(), "str1" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - TEST_REQUIRE( valPtr ); + BOOST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - TEST_REQUIRE( objectPtr ); + BOOST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - TEST_CHECK_EQUAL( namePtr->asString(), "str2" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str2" ); } } //------------------------------------------------------------------------------ -TEST_CASE( t6_4_array_root_of_object_with_objects ) +BOOST_AUTO_TEST_CASE( t6_4_array_root_of_object_with_objects ) { // Init createJsonFile( @@ -364,38 +364,38 @@ TEST_CASE( t6_4_array_root_of_object_with_objects ) // Check auto arrayValuePtr = json.asValue(); - TEST_REQUIRE( arrayValuePtr ); + BOOST_REQUIRE( arrayValuePtr ); auto arrayPtr = arrayValuePtr->asArray(); - TEST_REQUIRE( arrayPtr ); + BOOST_REQUIRE( arrayPtr ); const JsonArray & array = *arrayPtr; BOOST_REQUIRE_EQUAL( array.getSize(), 2 ); { auto valPtr = array.at( 0 ); - TEST_REQUIRE( valPtr ); + BOOST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - TEST_REQUIRE( objectPtr ); + BOOST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - TEST_CHECK_EQUAL( namePtr->asString(), "str1" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str1" ); } { auto valPtr = array.at( 1 ); - TEST_REQUIRE( valPtr ); + BOOST_REQUIRE( valPtr ); auto objectPtr = valPtr->asObject(); - TEST_REQUIRE( objectPtr ); + BOOST_REQUIRE( objectPtr ); auto namePtr = objectPtr->getAttributeValue( "name" ); - TEST_CHECK_EQUAL( namePtr->asString(), "str2" ); + BOOST_CHECK_EQUAL( namePtr->asString(), "str2" ); } } //------------------------------------------------------------------------------ -TEST_CASE( t7_not_exist_attribute ) +BOOST_AUTO_TEST_CASE( t7_not_exist_attribute ) { // Init createJsonFile( R"({ "name": "str" })" ); @@ -405,12 +405,12 @@ TEST_CASE( t7_not_exist_attribute ) // Check auto atrPtr = json.getAttributeValue( "surname" ); - TEST_REQUIRE( !atrPtr ); + BOOST_REQUIRE( !atrPtr ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/model_includes/api/mi_analyzer.hpp b/src/model_includes/api/mi_analyzer.hpp index 153fa49..c8b7bb1 100644 --- a/src/model_includes/api/mi_analyzer.hpp +++ b/src/model_includes/api/mi_analyzer.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/api/mi_file.hpp b/src/model_includes/api/mi_file.hpp index 68b1fdd..965f96e 100644 --- a/src/model_includes/api/mi_file.hpp +++ b/src/model_includes/api/mi_file.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/api/mi_include_location.hpp b/src/model_includes/api/mi_include_location.hpp index 06e08cf..c0ea61a 100644 --- a/src/model_includes/api/mi_include_location.hpp +++ b/src/model_includes/api/mi_include_location.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/api/mi_model.hpp b/src/model_includes/api/mi_model.hpp index 5a9d3e5..a859aa1 100644 --- a/src/model_includes/api/mi_model.hpp +++ b/src/model_includes/api/mi_model.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/ih/mi_accessor.hpp b/src/model_includes/ih/mi_accessor.hpp index 8a0b1d9..83df420 100644 --- a/src/model_includes/ih/mi_accessor.hpp +++ b/src/model_includes/ih/mi_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_analyzer_context.hpp b/src/model_includes/impl/mi_analyzer_context.hpp index c81ea1c..dd831fa 100644 --- a/src/model_includes/impl/mi_analyzer_context.hpp +++ b/src/model_includes/impl/mi_analyzer_context.hpp @@ -3,7 +3,6 @@ #include "tools/std_hash_fs_path.hpp" #include -#include #include #include @@ -34,9 +33,9 @@ class AnalyzerContext { public: - using Path = stdfs::path; - using PathOpt = std::optional< Path >; - using IgnoredFiles = std::unordered_set< Path >; + using Path = stdfs::path; + using PathOpt = std::optional< Path >; + using IgnoredFiles = std::unordered_set< Path >; using ResolvedFiles = std::unordered_set< Path >; using ResolvedFilesStack = std::stack< Path >; diff --git a/src/model_includes/impl/mi_analyzer_impl.cpp b/src/model_includes/impl/mi_analyzer_impl.cpp index ad60cbb..bdfa9a6 100644 --- a/src/model_includes/impl/mi_analyzer_impl.cpp +++ b/src/model_includes/impl/mi_analyzer_impl.cpp @@ -73,18 +73,16 @@ AnalyzerImpl::ModelPtr AnalyzerImpl::analyze( _cmakeProject.forEachFilePath( [&]( const Path & _path ) { - if( context.isFileInIgnoreDir( _path ) ) + if( !context.isFileInIgnoreDir( _path ) ) { - return true; - } - - context.setCurrentCMakeSourceFile( _path ); + context.setCurrentCMakeSourceFile( _path ); - analyzeFile( context, _path ); + analyzeFile( context, _path ); - while( auto pathOpt = context.popResolvedFile() ) - { - analyzeFile( context, *pathOpt ); + while( auto pathOpt = context.popResolvedFile() ) + { + analyzeFile( context, *pathOpt ); + } } return true; diff --git a/src/model_includes/impl/mi_analyzer_impl.hpp b/src/model_includes/impl/mi_analyzer_impl.hpp index 2b55927..7e09139 100644 --- a/src/model_includes/impl/mi_analyzer_impl.hpp +++ b/src/model_includes/impl/mi_analyzer_impl.hpp @@ -2,6 +2,9 @@ #include "model_includes/api/mi_analyzer.hpp" +#include +#include + #include //------------------------------------------------------------------------------ diff --git a/src/model_includes/impl/mi_file_impl.hpp b/src/model_includes/impl/mi_file_impl.hpp index d6368de..ac47f5b 100644 --- a/src/model_includes/impl/mi_file_impl.hpp +++ b/src/model_includes/impl/mi_file_impl.hpp @@ -3,6 +3,8 @@ #include "model_includes/api/enums/mi_file_type.hpp" #include "model_includes/api/mi_file.hpp" +#include + #include #include diff --git a/src/model_includes/impl/mi_resolver.hpp b/src/model_includes/impl/mi_resolver.hpp index 2b84b7e..e4216c7 100644 --- a/src/model_includes/impl/mi_resolver.hpp +++ b/src/model_includes/impl/mi_resolver.hpp @@ -1,6 +1,9 @@ #pragma once -#include +#include +#include +#include +#include //------------------------------------------------------------------------------ @@ -28,8 +31,8 @@ namespace model_includes { class Resolver { public: - using Path = stdfs::path; - using PathOpt = std::optional< Path >; + using Path = stdfs::path; + using PathOpt = std::optional< Path >; explicit Resolver( const fs::FileSystem & _fs ); diff --git a/src/model_includes/impl/mi_resolver_context.hpp b/src/model_includes/impl/mi_resolver_context.hpp index 34ece13..6e5e7d4 100644 --- a/src/model_includes/impl/mi_resolver_context.hpp +++ b/src/model_includes/impl/mi_resolver_context.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include diff --git a/src/model_includes/impl/mi_std_library.hpp b/src/model_includes/impl/mi_std_library.hpp index aba8817..f788afc 100644 --- a/src/model_includes/impl/mi_std_library.hpp +++ b/src/model_includes/impl/mi_std_library.hpp @@ -1,7 +1,5 @@ #pragma once -#include - #include #include diff --git a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp index 380442f..6916301 100644 --- a/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp +++ b/src/model_includes/test/fixtures/mi_test_model_includes_fixture.hpp @@ -2,7 +2,10 @@ #include "test_tools/boost_predicate_wrapper.hpp" -#include +#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp index 46c38b3..2a73dfd 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp @@ -2,7 +2,7 @@ #include "test_tools/boost_predicate_wrapper.hpp" -#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp index 750ee51..adc1707 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp @@ -2,7 +2,7 @@ #include "test_tools/boost_predicate_wrapper.hpp" -#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp index d700a88..558c3d3 100644 --- a/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp +++ b/src/model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp @@ -5,7 +5,8 @@ #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp index 6d0e600..024ba7f 100644 --- a/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp +++ b/src/model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp @@ -8,7 +8,7 @@ #include "model_includes/api/enums/mi_include_type.hpp" #include "model_includes/api/mi_model.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -34,11 +34,12 @@ namespace model_includes::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( AnalyzerforCmakeTests, ModelIncludesFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( AnalyzerforCmakeTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_1_only_one_cpp_file ) +BOOST_AUTO_TEST_CASE( t1_1_only_one_cpp_file ) { // Init const std::string projectDir{ "/test_project/" }; @@ -54,21 +55,21 @@ TEST_CASE( t1_1_only_one_cpp_file ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 1 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 1 ) ); { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_CHECK( classACpp.checkIncludesCount( 0 ) ); - TEST_CHECK( classACpp.checkIncludedByCount( 0 ) ); + BOOST_CHECK( classACpp.checkIncludesCount( 0 ) ); + BOOST_CHECK( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_2_cpp_file_with_header ) +BOOST_AUTO_TEST_CASE( t1_2_cpp_file_with_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -94,43 +95,43 @@ TEST_CASE( t1_2_cpp_file_with_header ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_4_cpp_file_with_system_include ) +BOOST_AUTO_TEST_CASE( t1_4_cpp_file_with_system_include ) { // Init const std::string projectDir{ "/test_project/" }; @@ -154,43 +155,43 @@ TEST_CASE( t1_4_cpp_file_with_system_include ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper systemHeader = model.findFile( systemHeaderName ); - TEST_REQUIRE( systemHeader.isAvailable() ); + BOOST_REQUIRE( systemHeader.isAvailable() ); { - TEST_REQUIRE( systemHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( systemHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( systemHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( systemHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = systemHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( systemHeaderName ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::System ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( systemHeaderName ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::System ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( systemHeaderName ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::System ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( systemHeaderName ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::System ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_3_cpp_file_with_header_that_include_header ) +BOOST_AUTO_TEST_CASE( t1_3_cpp_file_with_header_that_include_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -222,64 +223,64 @@ TEST_CASE( t1_3_cpp_file_with_header_that_include_header ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper classBaseHeader = model.findFile( classBaseHppPath ); - TEST_REQUIRE( classBaseHeader.isAvailable() ); + BOOST_REQUIRE( classBaseHeader.isAvailable() ); { - TEST_REQUIRE( classBaseHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classBaseHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classBaseHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classBaseHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classBaseHeader.getIncludedBy( classAHppPath ); - TEST_CHECK( includedByClassA.checkSource( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classBaseHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classBaseHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 1 ) ); IncludeWrapper includeToBaseClass = classAHeader.getInclude( 0 ); - TEST_CHECK( includeToBaseClass.checkSource( classAHppPath ) ); - TEST_CHECK( includeToBaseClass.checkDestination( classBaseHppPath ) ); - TEST_CHECK( includeToBaseClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeToBaseClass.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeToBaseClass.checkSource( classAHppPath ) ); + BOOST_CHECK( includeToBaseClass.checkDestination( classBaseHppPath ) ); + BOOST_CHECK( includeToBaseClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeToBaseClass.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_1_several_files ) +BOOST_AUTO_TEST_CASE( t2_1_several_files ) { // Init const std::string projectDir{ "/test_project/" }; @@ -302,29 +303,29 @@ TEST_CASE( t2_1_several_files ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classBCpp = model.findFile( classBCppPath ); - TEST_REQUIRE( classBCpp.isAvailable() ); + BOOST_REQUIRE( classBCpp.isAvailable() ); { - TEST_REQUIRE( classBCpp.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classBCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classBCpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classBCpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_2_several_files_with_same_header ) +BOOST_AUTO_TEST_CASE( t2_2_several_files_with_same_header ) { // Init const std::string projectDir{ "/test_project/" }; @@ -358,64 +359,64 @@ TEST_CASE( t2_2_several_files_with_same_header ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper classAFile = model.findFile( classACppPath ); - TEST_REQUIRE( classAFile.isAvailable() ); + BOOST_REQUIRE( classAFile.isAvailable() ); { - TEST_REQUIRE( classAFile.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classAFile.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = classAFile.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classAFile.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classAFile.checkIncludedByCount( 0 ) ); } } { FileWrapper classBFile = model.findFile( classACppPath ); - TEST_REQUIRE( classBFile.isAvailable() ); + BOOST_REQUIRE( classBFile.isAvailable() ); { - TEST_REQUIRE( classBFile.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classBFile.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = classBFile.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classBFile.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classBFile.checkIncludedByCount( 0 ) ); } } { FileWrapper headerFile = model.findFile( classHeaderPath ); - TEST_REQUIRE( headerFile.isAvailable() ); + BOOST_REQUIRE( headerFile.isAvailable() ); { - TEST_REQUIRE( headerFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( headerFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( headerFile.checkIncludedByCount( 2 ) ); + BOOST_REQUIRE( headerFile.checkIncludedByCount( 2 ) ); IncludeWrapper includedByClassA = headerFile.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classHeaderPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassB = headerFile.getIncludedBy( classBCppPath ); - TEST_CHECK( includedByClassB.checkSource( classBCppPath ) ); - TEST_CHECK( includedByClassB.checkDestination( classHeaderPath ) ); - TEST_CHECK( includedByClassB.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassB.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassB.checkSource( classBCppPath ) ); + BOOST_CHECK( includedByClassB.checkDestination( classHeaderPath ) ); + BOOST_CHECK( includedByClassB.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassB.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_1_ignore_files_ignore_destination ) +BOOST_AUTO_TEST_CASE( t3_1_ignore_files_ignore_destination ) { // Init setProjectDir( "/test_project/" ); @@ -435,43 +436,43 @@ TEST_CASE( t3_1_ignore_files_ignore_destination ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - TEST_REQUIRE( classAHpp.isAvailable() ); + BOOST_REQUIRE( classAHpp.isAvailable() ); { - TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_2_ignore_files_ignore_source ) +BOOST_AUTO_TEST_CASE( t3_2_ignore_files_ignore_source ) { // Init setProjectDir( "/test_project/" ); @@ -499,43 +500,43 @@ TEST_CASE( t3_2_ignore_files_ignore_source ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - TEST_REQUIRE( classAHpp.isAvailable() ); + BOOST_REQUIRE( classAHpp.isAvailable() ); { - TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp index b355cbc..2729dbf 100644 --- a/src/model_includes/test/suits/mi_test_analyzer_suits.cpp +++ b/src/model_includes/test/suits/mi_test_analyzer_suits.cpp @@ -8,7 +8,7 @@ #include "model_includes/api/enums/mi_include_type.hpp" #include "model_includes/api/mi_model.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -47,11 +47,12 @@ namespace model_includes::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( AnalyzerTests, ModelIncludesFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( AnalyzerTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_1_file_in_current_directory ) +BOOST_AUTO_TEST_CASE( t1_1_file_in_current_directory ) { // Init const std::string projectDir{ "/test_project/" }; @@ -79,64 +80,64 @@ TEST_CASE( t1_1_file_in_current_directory ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_2_file_in_include_directory ) +BOOST_AUTO_TEST_CASE( t1_2_file_in_include_directory ) { // Init const std::string projectDir{ "/test_project/" }; @@ -167,43 +168,43 @@ TEST_CASE( t1_2_file_in_include_directory ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_3_file_with_std_library_name_in_project ) +BOOST_AUTO_TEST_CASE( t1_3_file_with_std_library_name_in_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -231,64 +232,64 @@ TEST_CASE( t1_3_file_with_std_library_name_in_project ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 2 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t1_4_include_in_local_folder ) +BOOST_AUTO_TEST_CASE( t1_4_include_in_local_folder ) { // Init const std::string projectDir{ "/test_project/" }; @@ -315,41 +316,41 @@ TEST_CASE( t1_4_include_in_local_folder ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper file = model.findFile( classIncludeHppPath ); - TEST_REQUIRE( file.isAvailable() ); + BOOST_REQUIRE( file.isAvailable() ); { - TEST_REQUIRE( file.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( file.checkIncludesCount( 0 ) ); - TEST_REQUIRE( file.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( file.checkIncludedByCount( 1 ) ); IncludeWrapper include = file.getIncludedBy( classIncludeCppPath ); - TEST_CHECK( include.checkSource( classIncludeCppPath ) ); - TEST_CHECK( include.checkDestination( classIncludeHppPath ) ); - TEST_CHECK( include.checkType( IncludeType::User ) ); - TEST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); + BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); + BOOST_CHECK( include.checkType( IncludeType::User ) ); + BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper file = model.findFile( classIncludeCppPath ); - TEST_REQUIRE( file.isAvailable() ); + BOOST_REQUIRE( file.isAvailable() ); { - TEST_REQUIRE( file.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( file.checkIncludesCount( 1 ) ); IncludeWrapper include = file.getInclude( 0 ); - TEST_CHECK( include.checkSource( classIncludeCppPath ) ); - TEST_CHECK( include.checkDestination( classIncludeHppPath ) ); - TEST_CHECK( include.checkType( IncludeType::User ) ); - TEST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( include.checkSource( classIncludeCppPath ) ); + BOOST_CHECK( include.checkDestination( classIncludeHppPath ) ); + BOOST_CHECK( include.checkType( IncludeType::User ) ); + BOOST_CHECK( include.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( file.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( file.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_1_include_type_user ) +BOOST_AUTO_TEST_CASE( t2_1_include_type_user ) { // Init const std::string projectDir{ "/test_project/" }; @@ -368,43 +369,43 @@ TEST_CASE( t2_1_include_type_user ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_2_include_type_system ) +BOOST_AUTO_TEST_CASE( t2_2_include_type_system ) { // Init const std::string projectDir{ "/test_project/" }; @@ -422,43 +423,43 @@ TEST_CASE( t2_2_include_type_system ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToSystem = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); - TEST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); - TEST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); + BOOST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); + BOOST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper systemFile = model.findFile( systemPath ); - TEST_REQUIRE( systemFile.isAvailable() ); + BOOST_REQUIRE( systemFile.isAvailable() ); { - TEST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = systemFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( systemPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( systemPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t2_3_include_type_mix ) +BOOST_AUTO_TEST_CASE( t2_3_include_type_mix ) { // Init const std::string projectDir{ "/test_project/" }; @@ -481,64 +482,64 @@ TEST_CASE( t2_3_include_type_mix ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); IncludeWrapper includeMainToSystem = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); - TEST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); - TEST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToSystem.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToSystem.checkDestination( systemPath ) ); + BOOST_CHECK( includeMainToSystem.checkType( IncludeType::System ) ); + BOOST_CHECK( includeMainToSystem.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 1 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper systemFile = model.findFile( systemPath ); - TEST_REQUIRE( systemFile.isAvailable() ); + BOOST_REQUIRE( systemFile.isAvailable() ); { - TEST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( systemFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( systemFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = systemFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( systemPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( systemPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper userFile = model.findFile( userHeaderName ); - TEST_REQUIRE( userFile.isAvailable() ); + BOOST_REQUIRE( userFile.isAvailable() ); { - TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( userHeaderName ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( userHeaderName ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_1_include_status_resolved ) +BOOST_AUTO_TEST_CASE( t3_1_include_status_resolved ) { // Init const std::string projectDir{ "/test_project/" }; @@ -557,42 +558,42 @@ TEST_CASE( t3_1_include_status_resolved ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( userHeaderPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( userHeaderPath ); - TEST_REQUIRE( userFile.isAvailable() ); + BOOST_REQUIRE( userFile.isAvailable() ); { - TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( userHeaderPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( userHeaderPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_2_include_status_unresolved ) +BOOST_AUTO_TEST_CASE( t3_2_include_status_unresolved ) { // Init const std::string projectDir{ "/test_project/" }; @@ -609,42 +610,42 @@ TEST_CASE( t3_2_include_status_unresolved ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( userHeaderName ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( userHeaderName ); - TEST_REQUIRE( userFile.isAvailable() ); + BOOST_REQUIRE( userFile.isAvailable() ); { - TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( userHeaderName ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( userHeaderName ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_3_include_status_mix ) +BOOST_AUTO_TEST_CASE( t3_3_include_status_mix ) { // Init const std::string projectDir{ "/test_project/" }; @@ -669,62 +670,62 @@ TEST_CASE( t3_3_include_status_mix ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 3 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 3 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 2 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHeaderPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHeaderPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includeMainToClassB = mainCpp.getInclude( 1 ); - TEST_CHECK( includeMainToClassB.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassB.checkDestination( classBHeaderName ) ); - TEST_CHECK( includeMainToClassB.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassB.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClassB.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassB.checkDestination( classBHeaderName ) ); + BOOST_CHECK( includeMainToClassB.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassB.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHeaderPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHeaderPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHeaderPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classBHeader = model.findFile( classBHeaderName ); - TEST_REQUIRE( classBHeader.isAvailable() ); + BOOST_REQUIRE( classBHeader.isAvailable() ); { - TEST_REQUIRE( classBHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classBHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classBHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classBHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classBHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classBHeaderName ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classBHeaderName ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Unresolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t3_4_include_status_std_lib ) +BOOST_AUTO_TEST_CASE( t3_4_include_status_std_lib ) { // Init const std::string projectDir{ "/test_project/" }; @@ -741,42 +742,42 @@ TEST_CASE( t3_4_include_status_std_lib ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( headerName ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::System ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( headerName ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::System ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper userFile = model.findFile( headerName ); - TEST_REQUIRE( userFile.isAvailable() ); + BOOST_REQUIRE( userFile.isAvailable() ); { - TEST_REQUIRE( userFile.checkIncludesCount( 0 ) ); - TEST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( userFile.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( userFile.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = userFile.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( headerName ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::System ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( headerName ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::System ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t4_1_ignored_folders_regular_project ) +BOOST_AUTO_TEST_CASE( t4_1_ignored_folders_regular_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -809,42 +810,42 @@ TEST_CASE( t4_1_ignored_folders_regular_project ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t4_2_ignored_folders_cmake_project ) +BOOST_AUTO_TEST_CASE( t4_2_ignored_folders_cmake_project ) { // Init const std::string projectDir{ "/test_project/" }; @@ -880,42 +881,42 @@ TEST_CASE( t4_2_ignored_folders_cmake_project ) ModelWrapper model = analyzeCmake(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 1 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t5_ignore_system_includes ) +BOOST_AUTO_TEST_CASE( t5_ignore_system_includes ) { // Init const std::string projectDir{ "/test_project/" }; @@ -940,28 +941,28 @@ TEST_CASE( t5_ignore_system_includes ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClass.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClass.checkDestination( classA ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClass.checkDestination( classA ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t6_1_ignore_files_ignore_destination ) +BOOST_AUTO_TEST_CASE( t6_1_ignore_files_ignore_destination ) { // Init setProjectDir( "/test_project/" ); @@ -979,43 +980,43 @@ TEST_CASE( t6_1_ignore_files_ignore_destination ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - TEST_REQUIRE( classAHpp.isAvailable() ); + BOOST_REQUIRE( classAHpp.isAvailable() ); { - TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t6_2_ignore_files_ignore_source ) +BOOST_AUTO_TEST_CASE( t6_2_ignore_files_ignore_source ) { // Init setProjectDir( "/test_project/" ); @@ -1040,43 +1041,43 @@ TEST_CASE( t6_2_ignore_files_ignore_source ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 2 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 2 ) ); { FileWrapper mainCpp = model.findFile( "/test_project/main.cpp" ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClass = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHpp = model.findFile( "lib/classA.hpp" ); - TEST_REQUIRE( classAHpp.isAvailable() ); + BOOST_REQUIRE( classAHpp.isAvailable() ); { - TEST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); + BOOST_REQUIRE( classAHpp.checkIncludedByCount( 1 ) ); IncludeWrapper includeMainToClass = classAHpp.getIncludedBy( "/test_project/main.cpp" ); - TEST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); - TEST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); - TEST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); + BOOST_CHECK( includeMainToClass.checkSource( "/test_project/main.cpp" ) ); + BOOST_CHECK( includeMainToClass.checkDestination( "lib/classA.hpp" ) ); + BOOST_CHECK( includeMainToClass.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClass.checkStatus( IncludeStatus::Unresolved ) ); - TEST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHpp.checkIncludesCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t7_1_file_extensions_only_cpp_files ) +BOOST_AUTO_TEST_CASE( t7_1_file_extensions_only_cpp_files ) { // Init const std::string projectDir{ "/test_project/" }; @@ -1111,79 +1112,79 @@ TEST_CASE( t7_1_file_extensions_only_cpp_files ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 4 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 4 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper cppheaderFile = model.findFile( cppHeaderPath ); - TEST_REQUIRE( cppheaderFile.isAvailable() ); + BOOST_REQUIRE( cppheaderFile.isAvailable() ); { - TEST_REQUIRE( cppheaderFile.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( cppheaderFile.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = cppheaderFile.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( cppHeaderPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( cppHeaderPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( cppheaderFile.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( cppheaderFile.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_CASE( t7_2_file_extensions_analyze_without_extension ) +BOOST_AUTO_TEST_CASE( t7_2_file_extensions_analyze_without_extension ) { // Init const std::string projectDir{ "/test_project/" }; @@ -1217,79 +1218,79 @@ TEST_CASE( t7_2_file_extensions_analyze_without_extension ) ModelWrapper model = analyze(); // Check - TEST_REQUIRE( model.isAvailable() ); - TEST_REQUIRE( model.checkFilesCount( 4 ) ); + BOOST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.checkFilesCount( 4 ) ); { FileWrapper mainCpp = model.findFile( mainCppPath ); - TEST_REQUIRE( mainCpp.isAvailable() ); + BOOST_REQUIRE( mainCpp.isAvailable() ); { - TEST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( mainCpp.checkIncludesCount( 1 ) ); IncludeWrapper includeMainToClassA = mainCpp.getInclude( 0 ); - TEST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); - TEST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeMainToClassA.checkSource( mainCppPath ) ); + BOOST_CHECK( includeMainToClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeMainToClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includeMainToClassA.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( mainCpp.checkIncludedByCount( 0 ) ); } } { FileWrapper classAHeader = model.findFile( classAHppPath ); - TEST_REQUIRE( classAHeader.isAvailable() ); + BOOST_REQUIRE( classAHeader.isAvailable() ); { - TEST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); + BOOST_REQUIRE( classAHeader.checkIncludesCount( 0 ) ); - TEST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); + BOOST_REQUIRE( classAHeader.checkIncludedByCount( 3 ) ); IncludeWrapper includedByMain = classAHeader.getIncludedBy( mainCppPath ); - TEST_CHECK( includedByMain.checkSource( mainCppPath ) ); - TEST_CHECK( includedByMain.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByMain.checkType( IncludeType::User ) ); - TEST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByMain.checkSource( mainCppPath ) ); + BOOST_CHECK( includedByMain.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByMain.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByMain.checkStatus( IncludeStatus::Resolved ) ); IncludeWrapper includedByClassA = classAHeader.getIncludedBy( classACppPath ); - TEST_CHECK( includedByClassA.checkSource( classACppPath ) ); - TEST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); - TEST_CHECK( includedByClassA.checkType( IncludeType::User ) ); - TEST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includedByClassA.checkSource( classACppPath ) ); + BOOST_CHECK( includedByClassA.checkDestination( classAHppPath ) ); + BOOST_CHECK( includedByClassA.checkType( IncludeType::User ) ); + BOOST_CHECK( includedByClassA.checkStatus( IncludeStatus::Resolved ) ); } } { FileWrapper classACpp = model.findFile( classACppPath ); - TEST_REQUIRE( classACpp.isAvailable() ); + BOOST_REQUIRE( classACpp.isAvailable() ); { - TEST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( classACpp.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = classACpp.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( classACppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( classACpp.checkIncludedByCount( 0 ) ); } } { FileWrapper headerFile = model.findFile( headerPath ); - TEST_REQUIRE( headerFile.isAvailable() ); + BOOST_REQUIRE( headerFile.isAvailable() ); { - TEST_REQUIRE( headerFile.checkIncludesCount( 1 ) ); + BOOST_REQUIRE( headerFile.checkIncludesCount( 1 ) ); IncludeWrapper includeClassAToHeader = headerFile.getInclude( 0 ); - TEST_CHECK( includeClassAToHeader.checkSource( headerPath ) ); - TEST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); - TEST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); - TEST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); + BOOST_CHECK( includeClassAToHeader.checkSource( headerPath ) ); + BOOST_CHECK( includeClassAToHeader.checkDestination( classAHppPath ) ); + BOOST_CHECK( includeClassAToHeader.checkType( IncludeType::User ) ); + BOOST_CHECK( includeClassAToHeader.checkStatus( IncludeStatus::Resolved ) ); - TEST_REQUIRE( headerFile.checkIncludedByCount( 0 ) ); + BOOST_REQUIRE( headerFile.checkIncludedByCount( 0 ) ); } } } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_model_includes_suits.cpp b/src/model_includes/test/suits/mi_test_model_includes_suits.cpp index cb293d8..5b3cb8d 100644 --- a/src/model_includes/test/suits/mi_test_model_includes_suits.cpp +++ b/src/model_includes/test/suits/mi_test_model_includes_suits.cpp @@ -3,7 +3,7 @@ #include "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" #include "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -19,11 +19,12 @@ namespace model_includes::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ModelIncludesTests, ModelIncludesFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ModelIncludesTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_1_file_includes_count_recursive ) +BOOST_AUTO_TEST_CASE( t1_1_file_includes_count_recursive ) { // Init const std::string baseFile = "/test_project/base.hpp"; @@ -34,7 +35,7 @@ TEST_CASE( t1_1_file_includes_count_recursive ) // Run auto model = createModel(); - TEST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.isAvailable() ); model.addInclude( classAFile, baseFile ); model.addInclude( classBFile, baseFile ); @@ -45,14 +46,14 @@ TEST_CASE( t1_1_file_includes_count_recursive ) // Check auto file = model.findFile( mainFile ); - TEST_REQUIRE( file.isAvailable() ); + BOOST_REQUIRE( file.isAvailable() ); - TEST_CHECK( file.checkIncludesCountRecursive( 3 ) ); + BOOST_CHECK( file.checkIncludesCountRecursive( 3 ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t1_2_file_includes_by_count_recursive ) +BOOST_AUTO_TEST_CASE( t1_2_file_includes_by_count_recursive ) { // Init const std::string baseFile = "/test_project/base.hpp"; @@ -68,7 +69,7 @@ TEST_CASE( t1_2_file_includes_by_count_recursive ) // Run auto model = createModel(); - TEST_REQUIRE( model.isAvailable() ); + BOOST_REQUIRE( model.isAvailable() ); model.addInclude( classAFile, baseFile ); model.addInclude( runA1File, classAFile ); @@ -83,14 +84,14 @@ TEST_CASE( t1_2_file_includes_by_count_recursive ) // Check auto file = model.findFile( baseFile ); - TEST_REQUIRE( file.isAvailable() ); + BOOST_REQUIRE( file.isAvailable() ); - TEST_CHECK( file.checkIncludedByCountRecursive( 6 ) ); + BOOST_CHECK( file.checkIncludedByCountRecursive( 6 ) ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp b/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp index 7dd6251..79c409d 100644 --- a/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp +++ b/src/model_includes/test/suits/mi_test_resolver_file_type_suits.cpp @@ -2,7 +2,7 @@ #include "model_includes/api/enums/mi_file_type.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -19,12 +19,12 @@ TEST PLAN: namespace model_includes::test { //------------------------------------------------------------------------------ -// clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ResolverFileTypeTests, ModelIncludesFixture ) + +BOOST_FIXTURE_TEST_SUITE( ResolverFileTypeTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_project_file ) +BOOST_AUTO_TEST_CASE( t1_project_file ) { // Init setProjectDir( "/test_project/" ); @@ -34,12 +34,12 @@ TEST_CASE( t1_project_file ) const FileType fileType = resolveFileType( "/test_project/main.cpp" ); // Check - TEST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); + BOOST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t2_std_library_file ) +BOOST_AUTO_TEST_CASE( t2_std_library_file ) { // Init setProjectDir( "/test_project/" ); @@ -49,12 +49,12 @@ TEST_CASE( t2_std_library_file ) const FileType fileType = resolveFileType( "iostream" ); // Check - TEST_CHECK( checkFileType( fileType, FileType::StdLibraryFile ) ); + BOOST_CHECK( checkFileType( fileType, FileType::StdLibraryFile ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t3_project_file_with_std_library_name ) +BOOST_AUTO_TEST_CASE( t3_project_file_with_std_library_name ) { // Init setProjectDir( "/test_project/" ); @@ -64,12 +64,12 @@ TEST_CASE( t3_project_file_with_std_library_name ) const FileType fileType = resolveFileType( "/test_project/limit.h" ); // Check - TEST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); + BOOST_CHECK( checkFileType( fileType, FileType::ProjectFile ) ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp index de8b9ff..85b05bb 100644 --- a/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp +++ b/src/model_includes/test/suits/mi_test_resolver_path_suits.cpp @@ -1,6 +1,6 @@ #include "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include #include @@ -30,11 +30,12 @@ namespace model_includes::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ResolverPathTests, ModelIncludesFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ResolverPathTests, ModelIncludesFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_current_directory ) +BOOST_AUTO_TEST_CASE( t1_current_directory ) { // Init setProjectDir( "/test_project/" ); @@ -45,15 +46,15 @@ TEST_CASE( t1_current_directory ) PathOpt resolvedPath = resolvePath( "/test_project/main.cpp", "include.hpp" ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/include.hpp" }; - TEST_CHECK_EQUAL( *resolvedPath, exceptedPath ); + BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); } //------------------------------------------------------------------------------ -TEST_CASE( t2_subdirectory ) +BOOST_AUTO_TEST_CASE( t2_subdirectory ) { // Init setProjectDir( "/test_project/" ); @@ -67,7 +68,7 @@ TEST_CASE( t2_subdirectory ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/sub_dir/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -75,7 +76,7 @@ TEST_CASE( t2_subdirectory ) //------------------------------------------------------------------------------ -TEST_CASE( t3_1_in_include_dir ) +BOOST_AUTO_TEST_CASE( t3_1_in_include_dir ) { // Init setProjectDir( "/test_project/" ); @@ -91,7 +92,7 @@ TEST_CASE( t3_1_in_include_dir ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -99,7 +100,7 @@ TEST_CASE( t3_1_in_include_dir ) //------------------------------------------------------------------------------ -TEST_CASE( t3_2_in_include_subdir ) +BOOST_AUTO_TEST_CASE( t3_2_in_include_subdir ) { // Init setProjectDir( "/test_project/" ); @@ -115,7 +116,7 @@ TEST_CASE( t3_2_in_include_subdir ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/sub/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -123,7 +124,7 @@ TEST_CASE( t3_2_in_include_subdir ) //------------------------------------------------------------------------------ -TEST_CASE( t3_3_in_include_out_of_project ) +BOOST_AUTO_TEST_CASE( t3_3_in_include_out_of_project ) { // Init setProjectDir( "/test_project/" ); @@ -139,7 +140,7 @@ TEST_CASE( t3_3_in_include_out_of_project ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -147,7 +148,7 @@ TEST_CASE( t3_3_in_include_out_of_project ) //------------------------------------------------------------------------------ -TEST_CASE( t4_not_found ) +BOOST_AUTO_TEST_CASE( t4_not_found ) { // Init setProjectDir( "/test_project/" ); @@ -160,12 +161,12 @@ TEST_CASE( t4_not_found ) ); // Check - TEST_REQUIRE( !resolvedPath.has_value() ); + BOOST_REQUIRE( !resolvedPath.has_value() ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_1_cmake_project_one_file_in_include_dir ) +BOOST_AUTO_TEST_CASE( t5_1_cmake_project_one_file_in_include_dir ) { // Init setProjectDir( "/test_project/" ); @@ -181,7 +182,7 @@ TEST_CASE( t5_1_cmake_project_one_file_in_include_dir ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -189,7 +190,7 @@ TEST_CASE( t5_1_cmake_project_one_file_in_include_dir ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) +BOOST_AUTO_TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) { // Init setProjectDir( "/test_project/" ); @@ -209,7 +210,7 @@ TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) "include.hpp" ); - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib1/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -221,7 +222,7 @@ TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) "include.hpp" ); - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib2/include.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -230,7 +231,7 @@ TEST_CASE( t5_2_cmake_project_two_files_in_different_include_dirs ) //------------------------------------------------------------------------------ -TEST_CASE( t5_3_cmake_project_not_found ) +BOOST_AUTO_TEST_CASE( t5_3_cmake_project_not_found ) { // Init setProjectDir( "/test_project/" ); @@ -246,12 +247,12 @@ TEST_CASE( t5_3_cmake_project_not_found ) ); // Check - TEST_REQUIRE( !resolvedPath.has_value() ); + BOOST_REQUIRE( !resolvedPath.has_value() ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_4_cmake_project_mix_with_general_project ) +BOOST_AUTO_TEST_CASE( t5_4_cmake_project_mix_with_general_project ) { // Init setProjectDir( "/test_project/" ); @@ -273,8 +274,8 @@ TEST_CASE( t5_4_cmake_project_mix_with_general_project ) ); // Check - TEST_REQUIRE( resolvedPath1.has_value() ); - TEST_REQUIRE( resolvedPath2.has_value() ); + BOOST_REQUIRE( resolvedPath1.has_value() ); + BOOST_REQUIRE( resolvedPath2.has_value() ); const Path exceptedPath1{ "/test_project/lib1/include1.hpp" }; const Path exceptedPath2{ "/test_project/lib2/include2.hpp" }; @@ -285,7 +286,7 @@ TEST_CASE( t5_4_cmake_project_mix_with_general_project ) //------------------------------------------------------------------------------ -TEST_CASE( t5_5_cmake_header_include_file_from_cmake_include ) +BOOST_AUTO_TEST_CASE( t5_5_cmake_header_include_file_from_cmake_include ) { // Init setProjectDir( "/test_project/" ); @@ -303,7 +304,7 @@ TEST_CASE( t5_5_cmake_header_include_file_from_cmake_include ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -311,7 +312,7 @@ TEST_CASE( t5_5_cmake_header_include_file_from_cmake_include ) //------------------------------------------------------------------------------ -TEST_CASE( t5_6_cmake_header_include_file_from_project_include ) +BOOST_AUTO_TEST_CASE( t5_6_cmake_header_include_file_from_project_include ) { // Init setProjectDir( "/test_project/" ); @@ -331,7 +332,7 @@ TEST_CASE( t5_6_cmake_header_include_file_from_project_include ) ); // Check - TEST_REQUIRE( resolvedPath.has_value() ); + BOOST_REQUIRE( resolvedPath.has_value() ); const Path exceptedPath{ "/test_project/lib/base_class.hpp" }; BOOST_CHECK_EQUAL( *resolvedPath, exceptedPath ); @@ -339,7 +340,7 @@ TEST_CASE( t5_6_cmake_header_include_file_from_project_include ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/parser/api/pr_include_file_location.hpp b/src/parser/api/pr_include_file_location.hpp index 819f449..677dcd5 100644 --- a/src/parser/api/pr_include_file_location.hpp +++ b/src/parser/api/pr_include_file_location.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/parser/api/pr_parser.hpp b/src/parser/api/pr_parser.hpp index 317c784..80eb955 100644 --- a/src/parser/api/pr_parser.hpp +++ b/src/parser/api/pr_parser.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/parser/ih/pr_accessor.hpp b/src/parser/ih/pr_accessor.hpp index e70275e..c207ba2 100644 --- a/src/parser/ih/pr_accessor.hpp +++ b/src/parser/ih/pr_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/parser/impl/pr_parser_impl.hpp b/src/parser/impl/pr_parser_impl.hpp index 2a74a45..dcd3d5a 100644 --- a/src/parser/impl/pr_parser_impl.hpp +++ b/src/parser/impl/pr_parser_impl.hpp @@ -2,6 +2,10 @@ #include "parser/api/pr_parser.hpp" +#include +#include +#include + //------------------------------------------------------------------------------ namespace parser { diff --git a/src/parser/test/fixtures/pr_test_file_wrapper.hpp b/src/parser/test/fixtures/pr_test_file_wrapper.hpp index a9e13cd..0ea80d0 100644 --- a/src/parser/test/fixtures/pr_test_file_wrapper.hpp +++ b/src/parser/test/fixtures/pr_test_file_wrapper.hpp @@ -1,7 +1,7 @@ #pragma once +#include #include -#include //------------------------------------------------------------------------------ diff --git a/src/parser/test/fixtures/pr_test_fixture.hpp b/src/parser/test/fixtures/pr_test_fixture.hpp index 7a30181..b925e2a 100644 --- a/src/parser/test/fixtures/pr_test_fixture.hpp +++ b/src/parser/test/fixtures/pr_test_fixture.hpp @@ -3,6 +3,7 @@ #include "parser/test/fixtures/pr_test_file_wrapper.hpp" #include +#include //------------------------------------------------------------------------------ diff --git a/src/parser/test/suits/pr_test_suits.cpp b/src/parser/test/suits/pr_test_suits.cpp index c9cdcb4..58f7e54 100644 --- a/src/parser/test/suits/pr_test_suits.cpp +++ b/src/parser/test/suits/pr_test_suits.cpp @@ -3,7 +3,7 @@ #include "parser/api/pr_include_file.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -33,11 +33,13 @@ namespace parser::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ParserTests, ParserFixture ) + +BOOST_FIXTURE_TEST_SUITE( ParserTests, ParserFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_simple_system_include ) + +BOOST_AUTO_TEST_CASE( t1_simple_system_include ) { // Init file() << "#include "; @@ -61,7 +63,8 @@ TEST_CASE( t1_simple_system_include ) //------------------------------------------------------------------------------ -TEST_CASE( t2_simple_user_include ) + +BOOST_AUTO_TEST_CASE( t2_simple_user_include ) { // Init file() << "#include \"user.hpp\""; @@ -80,7 +83,8 @@ TEST_CASE( t2_simple_user_include ) //------------------------------------------------------------------------------ -TEST_CASE( t3_simple_user_and_system_include ) + +BOOST_AUTO_TEST_CASE( t3_simple_user_and_system_include ) { // Init file() @@ -106,7 +110,8 @@ TEST_CASE( t3_simple_user_and_system_include ) //------------------------------------------------------------------------------ -TEST_CASE( t4_include_without_space ) + +BOOST_AUTO_TEST_CASE( t4_include_without_space ) { // Init file() << "#include"; @@ -125,7 +130,8 @@ TEST_CASE( t4_include_without_space ) //------------------------------------------------------------------------------ -TEST_CASE( t5_include_with_several_spaces ) + +BOOST_AUTO_TEST_CASE( t5_include_with_several_spaces ) { // Init file()<< @@ -146,7 +152,8 @@ TEST_CASE( t5_include_with_several_spaces ) //------------------------------------------------------------------------------ -TEST_CASE( t6_include_after_comment ) + +BOOST_AUTO_TEST_CASE( t6_include_after_comment ) { // Init file() << " //#include "; @@ -161,7 +168,8 @@ TEST_CASE( t6_include_after_comment ) //------------------------------------------------------------------------------ -TEST_CASE( t7_include_in_multiline_coment ) + +BOOST_AUTO_TEST_CASE( t7_include_in_multiline_coment ) { // Init file() << "/* include */"; @@ -176,7 +184,8 @@ TEST_CASE( t7_include_in_multiline_coment ) //------------------------------------------------------------------------------ -TEST_CASE( t8_include_in_string ) + +BOOST_AUTO_TEST_CASE( t8_include_in_string ) { // Init file() << "\" include \""; @@ -191,7 +200,8 @@ TEST_CASE( t8_include_in_string ) //------------------------------------------------------------------------------ -TEST_CASE( t9_include_in_multiline_coment_with_several_lines ) + +BOOST_AUTO_TEST_CASE( t9_include_in_multiline_coment_with_several_lines ) { // Init file() << @@ -211,7 +221,8 @@ TEST_CASE( t9_include_in_multiline_coment_with_several_lines ) //------------------------------------------------------------------------------ -TEST_CASE( t10_include_after_multiline_coment_with_several_lines ) + +BOOST_AUTO_TEST_CASE( t10_include_after_multiline_coment_with_several_lines ) { // Init file()<< @@ -234,7 +245,8 @@ TEST_CASE( t10_include_after_multiline_coment_with_several_lines ) //------------------------------------------------------------------------------ -TEST_CASE( t11_include_include_in_multiline_string ) + +BOOST_AUTO_TEST_CASE( t11_include_include_in_multiline_string ) { // Init file()<< @@ -253,7 +265,8 @@ TEST_CASE( t11_include_include_in_multiline_string ) //------------------------------------------------------------------------------ -TEST_CASE( t12_first_line_new_line ) + +BOOST_AUTO_TEST_CASE( t12_first_line_new_line ) { // Init file() << @@ -281,7 +294,8 @@ TEST_CASE( t12_first_line_new_line ) //------------------------------------------------------------------------------ -TEST_CASE( t13_string_with_quotation_marks ) + +BOOST_AUTO_TEST_CASE( t13_string_with_quotation_marks ) { // Init file() << R"(\" \"#include ")"; @@ -296,7 +310,8 @@ TEST_CASE( t13_string_with_quotation_marks ) //------------------------------------------------------------------------------ -TEST_CASE( t14_raw_string ) + +BOOST_AUTO_TEST_CASE( t14_raw_string ) { // Init file()<< @@ -316,7 +331,8 @@ TEST_CASE( t14_raw_string ) //------------------------------------------------------------------------------ -TEST_CASE( t15_raw_string_with_seperator ) + +BOOST_AUTO_TEST_CASE( t15_raw_string_with_seperator ) { // Init file()<< @@ -336,7 +352,8 @@ TEST_CASE( t15_raw_string_with_seperator ) //------------------------------------------------------------------------------ -TEST_CASE( t16_brackets_in_comments ) + +BOOST_AUTO_TEST_CASE( t16_brackets_in_comments ) { // Init file() << @@ -364,7 +381,8 @@ TEST_CASE( t16_brackets_in_comments ) //------------------------------------------------------------------------------ -TEST_CASE( t17_file_name_in_comments ) + +BOOST_AUTO_TEST_CASE( t17_file_name_in_comments ) { // Init file() << @@ -405,7 +423,8 @@ TEST_CASE( t17_file_name_in_comments ) //------------------------------------------------------------------------------ -TEST_GROUP_END + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/project/api/prj_project.hpp b/src/project/api/prj_project.hpp index 8157149..092a7fe 100644 --- a/src/project/api/prj_project.hpp +++ b/src/project/api/prj_project.hpp @@ -1,6 +1,10 @@ #pragma once -#include +#include +#include +#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/project/ih/prj_project_accessor.hpp b/src/project/ih/prj_project_accessor.hpp index 6083bf1..1ad6374 100644 --- a/src/project/ih/prj_project_accessor.hpp +++ b/src/project/ih/prj_project_accessor.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/project/test/fixture/prj_test_ficture.hpp b/src/project/test/fixture/prj_test_ficture.hpp index f37d8ab..ad019b5 100644 --- a/src/project/test/fixture/prj_test_ficture.hpp +++ b/src/project/test/fixture/prj_test_ficture.hpp @@ -2,7 +2,8 @@ #include "test_tools/boost_predicate_wrapper.hpp" -#include +#include +#include #include diff --git a/src/project/test/suits/prj_test_suits.cpp b/src/project/test/suits/prj_test_suits.cpp index 6ddfeb3..4339ed5 100644 --- a/src/project/test/suits/prj_test_suits.cpp +++ b/src/project/test/suits/prj_test_suits.cpp @@ -2,7 +2,7 @@ #include "project/api/prj_exceptions.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -37,11 +37,12 @@ namespace project::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( ProjectTests, ProjectFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( ProjectTests, ProjectFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_1_project_dir_absolute_path ) +BOOST_AUTO_TEST_CASE( t1_1_project_dir_absolute_path ) { // Init const Path projectDirFullPath = "/home/user/project/"; @@ -56,7 +57,7 @@ TEST_CASE( t1_1_project_dir_absolute_path ) //------------------------------------------------------------------------------ -TEST_CASE( t1_2_project_dir_relative_path ) +BOOST_AUTO_TEST_CASE( t1_2_project_dir_relative_path ) { // Init const Path projectRelativePath = "project/"; @@ -73,7 +74,7 @@ TEST_CASE( t1_2_project_dir_relative_path ) //------------------------------------------------------------------------------ -TEST_CASE( t2_1_include_dirs_absolute_paths ) +BOOST_AUTO_TEST_CASE( t2_1_include_dirs_absolute_paths ) { // Init setProjectDir( "/home/user/project/" ); @@ -86,7 +87,7 @@ TEST_CASE( t2_1_include_dirs_absolute_paths ) Paths currentPaths = getIncludeDirs(); Paths exceptedPaths{ "/usr/lib1/", "/usr/lib2/" }; - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -98,7 +99,7 @@ TEST_CASE( t2_1_include_dirs_absolute_paths ) //------------------------------------------------------------------------------ -TEST_CASE( t2_2_include_dirs_relative_paths ) +BOOST_AUTO_TEST_CASE( t2_2_include_dirs_relative_paths ) { // Init setProjectDir( "/project/" ); @@ -111,7 +112,7 @@ TEST_CASE( t2_2_include_dirs_relative_paths ) Paths currentPaths = getIncludeDirs(); Paths exceptedPaths{ "/project/lib1/", "/project/lib2/" }; - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -122,7 +123,7 @@ TEST_CASE( t2_2_include_dirs_relative_paths ) //------------------------------------------------------------------------------ -TEST_CASE( t3_1_ignore_dirs_absolute_paths ) +BOOST_AUTO_TEST_CASE( t3_1_ignore_dirs_absolute_paths ) { // Init setProjectDir( "/home/user/project/" ); @@ -135,7 +136,7 @@ TEST_CASE( t3_1_ignore_dirs_absolute_paths ) Paths currentPaths = getIgnoreDirs(); Paths exceptedPaths{ "/usr/ignore1/", "/usr/ignore2/" }; - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -146,7 +147,7 @@ TEST_CASE( t3_1_ignore_dirs_absolute_paths ) //------------------------------------------------------------------------------ -TEST_CASE( t3_2_ignore_dirs_relative_paths ) +BOOST_AUTO_TEST_CASE( t3_2_ignore_dirs_relative_paths ) { // Init setProjectDir( "/project/" ); @@ -159,7 +160,7 @@ TEST_CASE( t3_2_ignore_dirs_relative_paths ) Paths currentPaths = getIgnoreDirs(); Paths exceptedPaths{ "/project/ignore1/", "/project/ignore2/" }; - TEST_REQUIRE_EQUAL_COLLECTIONS( + BOOST_REQUIRE_EQUAL_COLLECTIONS( currentPaths.begin(), currentPaths.end(), @@ -170,7 +171,7 @@ TEST_CASE( t3_2_ignore_dirs_relative_paths ) //------------------------------------------------------------------------------ -TEST_CASE( t3_3_ignore_dirs_is_ignore ) +BOOST_AUTO_TEST_CASE( t3_3_ignore_dirs_is_ignore ) { // Init @@ -181,107 +182,107 @@ TEST_CASE( t3_3_ignore_dirs_is_ignore ) changeAllPathsToAbsolute(); // Check - TEST_CHECK( isIgnoreDir( "/project/ignore1" ) ); - TEST_CHECK( isIgnoreDir( "/usr/ignore2" ) ); + BOOST_CHECK( isIgnoreDir( "/project/ignore1" ) ); + BOOST_CHECK( isIgnoreDir( "/usr/ignore2" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t4_1_cpp_extension_is_cpp_extension ) +BOOST_AUTO_TEST_CASE( t4_1_cpp_extension_is_cpp_extension ) { // Run addCppExtensions( { "*.cpp", "*.hpp" } ); // Check - TEST_CHECK( isExistsCppExtension( "*.cpp" ) ); - TEST_CHECK( isExistsCppExtension( "*.hpp" ) ); - TEST_CHECK( isExistsCppExtension( ".hpp" ) ); - TEST_CHECK( !isExistsCppExtension( ".cxx" ) ); + BOOST_CHECK( isExistsCppExtension( "*.cpp" ) ); + BOOST_CHECK( isExistsCppExtension( "*.hpp" ) ); + BOOST_CHECK( isExistsCppExtension( ".hpp" ) ); + BOOST_CHECK( !isExistsCppExtension( ".cxx" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_1_ignore_files_empty ) +BOOST_AUTO_TEST_CASE( t5_1_ignore_files_empty ) { // Init changeAllPathsToAbsolute(); // create project // Check - TEST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_2_ignore_files_library ) +BOOST_AUTO_TEST_CASE( t5_2_ignore_files_library ) { // Init addFileFilter( "boost/.*" ); // Check - TEST_CHECK( isIgnoredFile( "boost/test/unit_test.hpp" ) ); - TEST_CHECK( isIgnoredFile( "boost\\test\\unit_test.hpp" ) ); - TEST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); + BOOST_CHECK( isIgnoredFile( "boost/test/unit_test.hpp" ) ); + BOOST_CHECK( isIgnoredFile( "boost\\test\\unit_test.hpp" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/file.cpp" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_3_ignore_file_name ) +BOOST_AUTO_TEST_CASE( t5_3_ignore_file_name ) { // Init addFileFilter( "Q.*" ); // Check - TEST_CHECK( isIgnoredFile( "QWidget" ) ); - TEST_CHECK( !isIgnoredFile( "/tmp/q_file.cpp" ) ); + BOOST_CHECK( isIgnoredFile( "QWidget" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/q_file.cpp" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_4_ignore_sub_string ) +BOOST_AUTO_TEST_CASE( t5_4_ignore_sub_string ) { // Init addFileFilter( "/ui.*.h" ); // Check - TEST_CHECK( isIgnoredFile( "/tmp/ui/file.h" ) ); - TEST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); + BOOST_CHECK( isIgnoredFile( "/tmp/ui/file.h" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_5_ignore_only_begin_part ) +BOOST_AUTO_TEST_CASE( t5_5_ignore_only_begin_part ) { // Init addFileFilter( "^ui.*.h" ); // Check - TEST_CHECK( !isIgnoredFile( "/tmp/ui/file.h" ) ); - TEST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); - TEST_CHECK( isIgnoredFile( "ui/file.h" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/ui/file.h" ) ); + BOOST_CHECK( !isIgnoredFile( "/tmp/gui/file.h" ) ); + BOOST_CHECK( isIgnoredFile( "ui/file.h" ) ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_6_invalid_regex ) +BOOST_AUTO_TEST_CASE( t5_6_invalid_regex ) { // Check - TEST_CHECK_THROW( addFileFilter( "[" ), project::InvalidRegex ); + BOOST_CHECK_THROW( addFileFilter( "[" ), project::InvalidRegex ); } //------------------------------------------------------------------------------ -TEST_CASE( t5_7_double_plus ) +BOOST_AUTO_TEST_CASE( t5_7_double_plus ) { // Init addFileFilter( "lib\\+\\+v3/include/.*" ); // Check - TEST_CHECK( isIgnoredFile( "lib++v3/include/folder/file.h" ) ); + BOOST_CHECK( isIgnoredFile( "lib++v3/include/folder/file.h" ) ); } //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/api/rp_factory.hpp b/src/reporter/api/rp_factory.hpp index bb69af5..730c599 100644 --- a/src/reporter/api/rp_factory.hpp +++ b/src/reporter/api/rp_factory.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include //------------------------------------------------------------------------------ diff --git a/src/reporter/api/rp_reporter.hpp b/src/reporter/api/rp_reporter.hpp index fcce9ff..91ea625 100644 --- a/src/reporter/api/rp_reporter.hpp +++ b/src/reporter/api/rp_reporter.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include #include diff --git a/src/reporter/api/rp_settings.hpp b/src/reporter/api/rp_settings.hpp index d9d0bee..38e8f6a 100644 --- a/src/reporter/api/rp_settings.hpp +++ b/src/reporter/api/rp_settings.hpp @@ -24,6 +24,9 @@ class Settings virtual bool getShowStdFiles() const = 0; virtual void setShowStdFiles( bool _enable ) = 0; + virtual bool getShowOnlyStdHeaders() const = 0; + virtual void setShowOnlyStdHeaders( bool _enable ) = 0; + virtual void copy( const Settings & _other ) = 0; }; diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp index 77c410f..7f91334 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.cpp @@ -187,14 +187,12 @@ DifferentTypeReporter::Files DifferentTypeReporter::collectFiles( _model.forEachFile( [&]( const model_includes::File & _file ) { - if( isIgnoredFile( _file ) ) + if( !isIgnoredFile( _file ) ) { - return true; - } - - if( isIncludedByDifferentType( _file ) ) - { - result.insert( { _file, _file.getIncludedByCount() } ); + if( isIncludedByDifferentType( _file ) ) + { + result.insert( { _file, _file.getIncludedByCount() } ); + } } return true; @@ -247,19 +245,14 @@ bool DifferentTypeReporter::isIgnoredFile( const File & _file ) const { using namespace model_includes; - if( getShowStdFiles() ) - { - return false; - } - const FileType type = _file.getType(); static_assert( static_cast< int >( FileType::Count ) == 2 ); switch( type ) { case FileType::ProjectFile: - return false; + return getShowOnlyStdHeaders(); case FileType::StdLibraryFile: - return true; + return !getShowStdFiles(); default: INTERNAL_CHECK_WARRING( false ); return false; diff --git a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp index 4f0e533..e2bf6dd 100644 --- a/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp +++ b/src/reporter/impl/different_type_reporter/rp_different_type_reporter.hpp @@ -2,6 +2,8 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" +#include + //------------------------------------------------------------------------------ namespace model_includes { diff --git a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp index 88098d3..18dd977 100644 --- a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp @@ -76,15 +76,13 @@ void MostImpcatReporter::collectFiles( _model.forEachFile( [&]( const File & _file ) { - if( !isCollectFile( _file ) ) + if( isCollectFile( _file ) ) { - return true; - } - - const File::IncludeIndex count = _file.getIncludedByFilesCountRecursive(); - if( count > 0) - { - _files.insert( { _file, count } ); + const File::IncludeIndex count = _file.getIncludedByFilesCountRecursive(); + if( count > 0) + { + _files.insert( { _file, count } ); + } } return true; @@ -249,7 +247,7 @@ bool MostImpcatReporter::isCollectFile( const model_includes::File & _file ) con switch( type ) { case FileType::ProjectFile: - return true; + return !getShowOnlyStdHeaders(); case FileType::StdLibraryFile: return getShowStdFiles(); default: diff --git a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp index bf31685..c8be2d1 100644 --- a/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp +++ b/src/reporter/impl/most_impact_reporter/rp_most_impact_reporter.hpp @@ -2,7 +2,7 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" -#include +#include //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_base_reporter_impl.cpp b/src/reporter/impl/rp_base_reporter_impl.cpp index 272a2ae..82b60b0 100644 --- a/src/reporter/impl/rp_base_reporter_impl.cpp +++ b/src/reporter/impl/rp_base_reporter_impl.cpp @@ -65,6 +65,13 @@ bool BaseReporterImpl::getShowStdFiles() const //------------------------------------------------------------------------------ +bool BaseReporterImpl::getShowOnlyStdHeaders() const +{ + return getSettings().getShowOnlyStdHeaders(); +} + +//------------------------------------------------------------------------------ + std::string BaseReporterImpl::getPathWithoutProject( const Path & _filePath, const Path & _dirPath diff --git a/src/reporter/impl/rp_base_reporter_impl.hpp b/src/reporter/impl/rp_base_reporter_impl.hpp index 3d24d93..919dbff 100644 --- a/src/reporter/impl/rp_base_reporter_impl.hpp +++ b/src/reporter/impl/rp_base_reporter_impl.hpp @@ -2,6 +2,8 @@ #include "reporter/api/rp_reporter.hpp" +#include + #include //------------------------------------------------------------------------------ @@ -28,6 +30,7 @@ class BaseReporterImpl : public Reporter CountType getMaxFilesCount() const; CountType getMaxDetailsCount() const; bool getShowStdFiles() const; + bool getShowOnlyStdHeaders() const; static std::string getPathWithoutProject( const Path & _filePath, diff --git a/src/reporter/impl/rp_settings_impl.cpp b/src/reporter/impl/rp_settings_impl.cpp index d2c2a8d..ac5b9fd 100644 --- a/src/reporter/impl/rp_settings_impl.cpp +++ b/src/reporter/impl/rp_settings_impl.cpp @@ -9,7 +9,8 @@ namespace reporter { SettingsImpl::SettingsImpl() : m_maxFilesCount{ 0 } , m_maxDetailsCount{ 0 } - , m_showStdFiles{ true } + , m_showStdFiles{ false } + , m_showOnlyStdHeaders{ false } { } @@ -57,11 +58,26 @@ void SettingsImpl::setShowStdFiles( bool _enable ) //------------------------------------------------------------------------------ +bool SettingsImpl::getShowOnlyStdHeaders() const +{ + return m_showOnlyStdHeaders; +} + +//------------------------------------------------------------------------------ + +void SettingsImpl::setShowOnlyStdHeaders( bool _enable ) +{ + m_showOnlyStdHeaders = _enable; +} + +//------------------------------------------------------------------------------ + void SettingsImpl::copy( const Settings & _other ) { setMaxFilesCount( _other.getMaxFilesCount() ); setMaxDetailsCount( _other.getMaxDetailsCount() ); setShowStdFiles( _other.getShowStdFiles() ); + setShowOnlyStdHeaders( _other.getShowOnlyStdHeaders() ); } //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/rp_settings_impl.hpp b/src/reporter/impl/rp_settings_impl.hpp index 11143a5..4f9a798 100644 --- a/src/reporter/impl/rp_settings_impl.hpp +++ b/src/reporter/impl/rp_settings_impl.hpp @@ -22,12 +22,16 @@ class SettingsImpl final : public Settings bool getShowStdFiles() const override; void setShowStdFiles( bool _enable ) override; + bool getShowOnlyStdHeaders() const override; + void setShowOnlyStdHeaders( bool _enable ) override; + void copy( const Settings & _other ) override; private: CountType m_maxFilesCount; CountType m_maxDetailsCount; bool m_showStdFiles; + bool m_showOnlyStdHeaders; }; //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/tools/rp_file_with_count_container.hpp b/src/reporter/impl/tools/rp_file_with_count_container.hpp index 4c3e1a4..999aad3 100644 --- a/src/reporter/impl/tools/rp_file_with_count_container.hpp +++ b/src/reporter/impl/tools/rp_file_with_count_container.hpp @@ -3,8 +3,8 @@ #include "reporter/impl/tools/rp_file_with_count.hpp" #include "reporter/impl/tools/rp_file_with_count_sorter.hpp" +#include #include -#include //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp index 5d0af3a..292743c 100644 --- a/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp +++ b/src/reporter/impl/tools/rp_sorted_files_by_name_container.hpp @@ -2,7 +2,8 @@ #include "reporter/impl/tools/rp_file_sorter.hpp" -#include +#include +#include #include diff --git a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp index 686e2cf..10f2d6c 100644 --- a/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp +++ b/src/reporter/impl/tools/rp_sorted_includes_by_source_container.hpp @@ -2,7 +2,7 @@ #include "reporter/impl/tools/rp_includes_by_source_sorter.hpp" -#include +#include #include diff --git a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp index 9106350..396accf 100644 --- a/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp +++ b/src/reporter/impl/unincluded_reporter/rp_unincluded_reporter.hpp @@ -2,7 +2,7 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" -#include +#include //------------------------------------------------------------------------------ diff --git a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp index 111f4d5..bc44d9c 100644 --- a/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp +++ b/src/reporter/impl/unresolved_reporter/rp_unresolved_reporter.hpp @@ -2,6 +2,10 @@ #include "reporter/impl/rp_base_reporter_impl.hpp" +#include +#include +#include + //------------------------------------------------------------------------------ namespace model_includes { diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp index d8668bb..0cd188e 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.cpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.cpp @@ -131,6 +131,15 @@ void ReporterFixture::setShowStdFiles( bool _enable ) //------------------------------------------------------------------------------ +void ReporterFixture::setShowOnlyStdHeaders( bool _enable ) +{ + ensureSettings().setShowOnlyStdHeaders( _enable ); + if( _enable ) + setShowStdFiles( true ); +} + +//------------------------------------------------------------------------------ + std::string ReporterFixture::runDumpReporter() { auto reporterPtr = getFactory().createDumpReporter(); diff --git a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp index cd471e5..2ff15a5 100644 --- a/src/reporter/test/fixture/rp_test_reporter_fixture.hpp +++ b/src/reporter/test/fixture/rp_test_reporter_fixture.hpp @@ -4,8 +4,9 @@ #include "model_includes/api/enums/mi_include_status.hpp" #include "model_includes/api/enums/mi_include_type.hpp" +#include +#include #include -#include //------------------------------------------------------------------------------ @@ -72,6 +73,7 @@ class ReporterFixture void setMaxFilesCount( int _count ); void setMaxDetailsCount( int _count ); void setShowStdFiles( bool _enable ); + void setShowOnlyStdHeaders( bool _enable ); void setProjectDir( std::string_view _dir ); Path getProjectDir(); diff --git a/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp index f62a22e..649c20f 100644 --- a/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp +++ b/src/reporter/test/suits/rp_test_different_type_reporter_tests.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -17,6 +17,7 @@ TEST PLAN: 5. Limits 5.1 max files 5.2 max details +6. Show only std headers ------------------------------------------------------------------------------*/ @@ -24,11 +25,12 @@ namespace reporter::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( DifferentTypeReporterTests, ReporterFixture ) + +BOOST_FIXTURE_TEST_SUITE( DifferentTypeReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty ) +BOOST_AUTO_TEST_CASE( t1_empty ) { // Run const std::string result = runDifferentTypeReport(); @@ -39,7 +41,7 @@ TEST_CASE( t1_empty ) //------------------------------------------------------------------------------ -TEST_CASE( t2_one_include ) +BOOST_AUTO_TEST_CASE( t2_one_include ) { // Init addInclude( "/test_project/main.cpp", "/test_project/header.hpp" ); @@ -53,7 +55,7 @@ TEST_CASE( t2_one_include ) //------------------------------------------------------------------------------ -TEST_CASE( t3_1_several_includes_with_user_type ) +BOOST_AUTO_TEST_CASE( t3_1_several_includes_with_user_type ) { // Init addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); @@ -68,7 +70,7 @@ TEST_CASE( t3_1_several_includes_with_user_type ) //------------------------------------------------------------------------------ -TEST_CASE( t3_2_several_includes_with_system_type ) +BOOST_AUTO_TEST_CASE( t3_2_several_includes_with_system_type ) { // Init addSystemInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); @@ -83,7 +85,7 @@ TEST_CASE( t3_2_several_includes_with_system_type ) //------------------------------------------------------------------------------ -TEST_CASE( t4_1_several_includes_system_and_user ) +BOOST_AUTO_TEST_CASE( t4_1_several_includes_system_and_user ) { // Init setProjectDir( "/test_project/" ); @@ -108,7 +110,7 @@ TEST_CASE( t4_1_several_includes_system_and_user ) //------------------------------------------------------------------------------ -TEST_CASE( t4_2_several_includes_std ) +BOOST_AUTO_TEST_CASE( t4_2_several_includes_std ) { // Init setProjectDir( "/test_project/" ); @@ -119,6 +121,7 @@ TEST_CASE( t4_2_several_includes_std ) addSystemInclude( "/test_project/file2.cpp", "vector" ); // Run + setShowStdFiles( true ); const std::string result = runDifferentTypeReport(); // Check @@ -135,7 +138,7 @@ TEST_CASE( t4_2_several_includes_std ) //------------------------------------------------------------------------------ -TEST_CASE( t4_3_several_includes_hide_std ) +BOOST_AUTO_TEST_CASE( t4_3_several_includes_hide_std ) { // Init setProjectDir( "/test_project/" ); @@ -156,7 +159,7 @@ TEST_CASE( t4_3_several_includes_hide_std ) //------------------------------------------------------------------------------ -TEST_CASE( t5_1_limit_max_files ) +BOOST_AUTO_TEST_CASE( t5_1_limit_max_files ) { // Init setProjectDir( "/test_project/" ); @@ -187,7 +190,7 @@ TEST_CASE( t5_1_limit_max_files ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_limit_max_details ) +BOOST_AUTO_TEST_CASE( t5_2_limit_max_details ) { // Init setProjectDir( "/test_project/" ); @@ -230,7 +233,40 @@ TEST_CASE( t5_2_limit_max_details ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_CASE( t6_show_only_std_headers ) +{ + // Init + setProjectDir( "/test_project/" ); + + addFile( "vector", model_includes::FileType::StdLibraryFile ); + addFile( "/test_project/header.hpp", model_includes::FileType::ProjectFile ); + + addUserInclude( "/test_project/file1.cpp", "vector" ); + addSystemInclude( "/test_project/file2.cpp", "vector" ); + + addUserInclude( "/test_project/file1.cpp", "/test_project/header.hpp" ); + addSystemInclude( "/test_project/file2.cpp", "/test_project/header.hpp" ); + + setShowOnlyStdHeaders( true ); + + // Run + const std::string result = runDifferentTypeReport(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Files that are included by different ways:\n" + "1. vector\n" + "With double quotation marks ( #include \"...\" ) in files:\n" + "\t1. file1.cpp line 1\n" + "With angle brackets ( #include <...> ) in files:\n" + "\t1. file2.cpp line 1\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp b/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp index b364f7f..8434c31 100644 --- a/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_dump_reporter_suits.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -16,11 +16,12 @@ namespace reporter::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( DumpReporterTests, ReporterFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( DumpReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_includes ) +BOOST_AUTO_TEST_CASE( t1_includes ) { // Init const std::string classA = toPath( "/test_project/class_a.hpp" ); @@ -50,7 +51,7 @@ TEST_CASE( t1_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t2_unresolved_includes ) +BOOST_AUTO_TEST_CASE( t2_unresolved_includes ) { // Init const std::string classA = "class_a.hpp"; @@ -81,7 +82,7 @@ TEST_CASE( t2_unresolved_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t3_system_includes ) +BOOST_AUTO_TEST_CASE( t3_system_includes ) { // Init const std::string main = toPath( "/test_project/main.cpp" ); @@ -108,7 +109,7 @@ TEST_CASE( t3_system_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t4_relative_paths ) +BOOST_AUTO_TEST_CASE( t4_relative_paths ) { // Init const std::string classA = toPath( "/test_project/class_a.hpp" ); @@ -141,7 +142,7 @@ TEST_CASE( t4_relative_paths ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp index 62a84bd..074b417 100644 --- a/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_most_impact_reporter_suits.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include #include @@ -23,18 +23,19 @@ TEST PLAN: 8. Files out of project 8.1 in sub directory 8.2 in other directory +9. Show only std headers ------------------------------------------------------------------------------*/ namespace reporter::test { //------------------------------------------------------------------------------ -// clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( MostImpactReporterTests, ReporterFixture ) + +BOOST_FIXTURE_TEST_SUITE( MostImpactReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty ) +BOOST_AUTO_TEST_CASE( t1_empty ) { // Run std::string result = runMostImpactReporter(); @@ -45,7 +46,7 @@ TEST_CASE( t1_empty ) //------------------------------------------------------------------------------ -TEST_CASE( t2_only_cpp_files ) +BOOST_AUTO_TEST_CASE( t2_only_cpp_files ) { // Init const std::string classAFile = "/test_project/classA.hpp"; @@ -80,7 +81,7 @@ TEST_CASE( t2_only_cpp_files ) //------------------------------------------------------------------------------ -TEST_CASE( t3_files_with_same_count ) +BOOST_AUTO_TEST_CASE( t3_files_with_same_count ) { // Init const std::string classAFile = "/test_project/classA.hpp"; @@ -118,7 +119,7 @@ TEST_CASE( t3_files_with_same_count ) //------------------------------------------------------------------------------ -TEST_CASE( t4_several_details ) +BOOST_AUTO_TEST_CASE( t4_several_details ) { // Init const std::string classABaseFile = "/test_project/classABase.hpp"; @@ -171,7 +172,7 @@ TEST_CASE( t4_several_details ) //------------------------------------------------------------------------------ -TEST_CASE( t5_1_limit_max_files ) +BOOST_AUTO_TEST_CASE( t5_1_limit_max_files ) { // Init const std::string sourceFileFmt = "/test_project/class{}.cpp"; @@ -218,7 +219,7 @@ TEST_CASE( t5_1_limit_max_files ) //------------------------------------------------------------------------------ -TEST_CASE( t5_2_limit_max_details ) +BOOST_AUTO_TEST_CASE( t5_2_limit_max_details ) { // Init const std::string classBaseFile = "/test_project/classBase.hpp"; @@ -264,7 +265,7 @@ TEST_CASE( t5_2_limit_max_details ) //------------------------------------------------------------------------------ -TEST_CASE( t5_3_limit_equal_to_files_number ) +BOOST_AUTO_TEST_CASE( t5_3_limit_equal_to_files_number ) { // Init const std::string sourceFileFmt = "/test_project/class{}.cpp"; @@ -309,7 +310,7 @@ TEST_CASE( t5_3_limit_equal_to_files_number ) //------------------------------------------------------------------------------ -TEST_CASE( t5_4_limit_to_equal_details_number ) +BOOST_AUTO_TEST_CASE( t5_4_limit_to_equal_details_number ) { // Init const std::string classBaseFile = "/test_project/classBase.hpp"; @@ -355,7 +356,7 @@ TEST_CASE( t5_4_limit_to_equal_details_number ) //------------------------------------------------------------------------------ -TEST_CASE( t6_relevant_pants ) +BOOST_AUTO_TEST_CASE( t6_relevant_pants ) { // Init const std::string projectDir = "/test_project/"; @@ -399,7 +400,7 @@ TEST_CASE( t6_relevant_pants ) //------------------------------------------------------------------------------ -TEST_CASE( t7_1_std_file_dont_show ) +BOOST_AUTO_TEST_CASE( t7_1_std_file_dont_show ) { // Init const std::string stdFile = "vector"; @@ -443,7 +444,7 @@ TEST_CASE( t7_1_std_file_dont_show ) //------------------------------------------------------------------------------ -TEST_CASE( t7_2_std_file_show ) +BOOST_AUTO_TEST_CASE( t7_2_std_file_show ) { // Init const std::string stdFile = "vector"; @@ -491,7 +492,7 @@ TEST_CASE( t7_2_std_file_show ) //------------------------------------------------------------------------------ -TEST_CASE( t8_1_files_out_of_project_in_subdir ) +BOOST_AUTO_TEST_CASE( t8_1_files_out_of_project_in_subdir ) { // Init const std::string projectDir = "/test_project/"; @@ -536,7 +537,7 @@ TEST_CASE( t8_1_files_out_of_project_in_subdir ) //------------------------------------------------------------------------------ -TEST_CASE( t8_2_files_out_of_project_in_other_dir ) +BOOST_AUTO_TEST_CASE( t8_2_files_out_of_project_in_other_dir ) { // Init const std::string projectDir = "/test_project/"; @@ -581,7 +582,44 @@ TEST_CASE( t8_2_files_out_of_project_in_other_dir ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_CASE( t9_show_only_std_files ) +{ + // Init + const std::string stdFile = "vector"; + + const std::string classAFile = "/test_project/classA.hpp"; + const std::string classBFile = "/test_project/classB.hpp"; + + const std::string runA1file = "/test_project/runA1.cpp"; + const std::string runB1file = "/test_project/runB1.cpp"; + + addFile( stdFile, FileType::StdLibraryFile ); + + addInclude( classAFile, stdFile, IncludeType::System ); + addInclude( classBFile, stdFile, IncludeType::System ); + + addInclude( runA1file, classAFile ); + addInclude( runB1file, classBFile ); + + setShowOnlyStdHeaders( true ); + + // Run + std::string result = runMostImpactReporter(); + + // Check + BOOST_CHECK_EQUAL( + result, + "Most impact files:\n" + "1 : \"" + toPath( stdFile ) + "\" impact on 4 file(s)\n" + "Included by:\n" + "\t1 : \"" + toPath( classAFile ) + "\" line 1, impact on 1 file(s)\n" + "\t2 : \"" + toPath( classBFile ) + "\" line 1, impact on 1 file(s)\n" + ); +} + +//------------------------------------------------------------------------------ + +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp index 956b433..75c0ac2 100644 --- a/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp +++ b/src/reporter/test/suits/rp_test_unincluded_reporter_suits.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -21,11 +21,12 @@ namespace reporter::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( UnincludedReporterTests, ReporterFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( UnincludedReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_empty ) +BOOST_AUTO_TEST_CASE( t1_empty ) { // Init addInclude( "/test_project/main.cpp", "/test_project/classA.hpp" ); @@ -40,7 +41,7 @@ TEST_CASE( t1_empty ) //------------------------------------------------------------------------------ -TEST_CASE( t2_one_header ) +BOOST_AUTO_TEST_CASE( t2_one_header ) { // Init setProjectDir( "/tmp/" ); @@ -61,7 +62,7 @@ TEST_CASE( t2_one_header ) //------------------------------------------------------------------------------ -TEST_CASE( t3_several_headers ) +BOOST_AUTO_TEST_CASE( t3_several_headers ) { // Init setProjectDir( "/tmp/" ); @@ -86,7 +87,7 @@ TEST_CASE( t3_several_headers ) //------------------------------------------------------------------------------ -TEST_CASE( t4_1_extension_hpp ) +BOOST_AUTO_TEST_CASE( t4_1_extension_hpp ) { // Init setProjectDir( "/tmp/" ); @@ -107,7 +108,7 @@ TEST_CASE( t4_1_extension_hpp ) //------------------------------------------------------------------------------ -TEST_CASE( t4_2_extension_h ) +BOOST_AUTO_TEST_CASE( t4_2_extension_h ) { // Init setProjectDir( "/tmp/" ); @@ -128,7 +129,7 @@ TEST_CASE( t4_2_extension_h ) //------------------------------------------------------------------------------ -TEST_CASE( t4_3_mix_extensions ) +BOOST_AUTO_TEST_CASE( t4_3_mix_extensions ) { // Init setProjectDir( "/tmp/" ); @@ -151,7 +152,7 @@ TEST_CASE( t4_3_mix_extensions ) //------------------------------------------------------------------------------ -TEST_CASE( t4_4_empty_extension ) +BOOST_AUTO_TEST_CASE( t4_4_empty_extension ) { // Init addFileToProject( "main.cpp" ); @@ -170,7 +171,7 @@ TEST_CASE( t4_4_empty_extension ) //------------------------------------------------------------------------------ -TEST_CASE( t5_limit ) +BOOST_AUTO_TEST_CASE( t5_limit ) { // Init setProjectDir( "/tmp/" ); @@ -197,7 +198,7 @@ TEST_CASE( t5_limit ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp b/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp index b007642..51df9e0 100644 --- a/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp +++ b/src/reporter/test/suits/rp_test_unresolved_reporter_tests.cpp @@ -1,6 +1,6 @@ #include "reporter/test/fixture/rp_test_reporter_fixture.hpp" -#include "test_tools/test_macros.hpp" +#include /*------------------------------------------------------------------------------ @@ -21,11 +21,12 @@ namespace reporter::test { //------------------------------------------------------------------------------ // clazy:excludeall=non-pod-global-static -TEST_GROUP_NAME( UnresolvedReporterTests, ReporterFixture ) +// NOLINTNEXTLINE(fuchsia-statically-constructed-objects,cert-err58-cpp) +BOOST_FIXTURE_TEST_SUITE( UnresolvedReporterTests, ReporterFixture ) //------------------------------------------------------------------------------ -TEST_CASE( t1_model_not_have_unresolved_includes ) +BOOST_AUTO_TEST_CASE( t1_model_not_have_unresolved_includes ) { // Init addInclude( "/test_project/main.cpp", "/test_project/classA.hpp" ); @@ -40,7 +41,7 @@ TEST_CASE( t1_model_not_have_unresolved_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t2_several_includes ) +BOOST_AUTO_TEST_CASE( t2_several_includes ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -78,7 +79,7 @@ TEST_CASE( t2_several_includes ) //------------------------------------------------------------------------------ -TEST_CASE( t3_relative_paths ) +BOOST_AUTO_TEST_CASE( t3_relative_paths ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -126,7 +127,7 @@ TEST_CASE( t3_relative_paths ) //------------------------------------------------------------------------------ -TEST_CASE( t4_1_limit_max_files ) +BOOST_AUTO_TEST_CASE( t4_1_limit_max_files ) { // Init const int limit = 1; @@ -164,7 +165,7 @@ TEST_CASE( t4_1_limit_max_files ) //------------------------------------------------------------------------------ -TEST_CASE( t4_2_limit_max_details ) +BOOST_AUTO_TEST_CASE( t4_2_limit_max_details ) { // Init const int limit = 1; @@ -194,7 +195,7 @@ TEST_CASE( t4_2_limit_max_details ) //------------------------------------------------------------------------------ -TEST_CASE( t4_3_limit_equal_to_files_count ) +BOOST_AUTO_TEST_CASE( t4_3_limit_equal_to_files_count ) { // Init const int limit = 2; @@ -234,7 +235,7 @@ TEST_CASE( t4_3_limit_equal_to_files_count ) //------------------------------------------------------------------------------ -TEST_CASE( t4_4_limit_equal_to_details_count ) +BOOST_AUTO_TEST_CASE( t4_4_limit_equal_to_details_count ) { // Init const int limit = 2; @@ -264,7 +265,7 @@ TEST_CASE( t4_4_limit_equal_to_details_count ) //------------------------------------------------------------------------------ -TEST_CASE( t5_ordering ) +BOOST_AUTO_TEST_CASE( t5_ordering ) { // Init const auto unresolvedStatus = IncludeStatus::Unresolved; @@ -315,7 +316,7 @@ TEST_CASE( t5_ordering ) //------------------------------------------------------------------------------ -TEST_GROUP_END +BOOST_AUTO_TEST_SUITE_END() //------------------------------------------------------------------------------ diff --git a/src/reporter/tools/rp_reporter_kind_functins.hpp b/src/reporter/tools/rp_reporter_kind_functins.hpp index 9807ca7..cfaf7af 100644 --- a/src/reporter/tools/rp_reporter_kind_functins.hpp +++ b/src/reporter/tools/rp_reporter_kind_functins.hpp @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include //------------------------------------------------------------------------------ diff --git a/src/test_tools/test_macros.hpp b/src/test_tools/test_macros.hpp deleted file mode 100644 index d85c2eb..0000000 --- a/src/test_tools/test_macros.hpp +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include - -#define TEST_GROUP_NAME( testGroup, testFixture ) \ - BOOST_FIXTURE_TEST_SUITE( testGroup, testFixture ) // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) - -#define TEST_GROUP_END \ - BOOST_AUTO_TEST_SUITE_END() // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) - -#define TEST_CASE( caseName ) \ - BOOST_AUTO_TEST_CASE( caseName ) // NOLINT(fuchsia-statically-constructed-objects,cert-err58-cpp) - -#define TEST_CHECK( conditional ) \ - BOOST_CHECK( conditional ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - -#define TEST_REQUIRE( conditional ) \ - BOOST_REQUIRE( conditional ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - -#define TEST_CHECK_EQUAL( L, R ) \ - BOOST_CHECK_EQUAL( L, R ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - -#define TEST_CHECK_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) \ - BOOST_CHECK_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - -#define TEST_REQUIRE_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) \ - BOOST_REQUIRE_EQUAL_COLLECTIONS( beginLeft, endLeft, beginRight, endRight ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) - -#define TEST_CHECK_THROW( S, E ) \ - BOOST_CHECK_THROW( S, E ) // NOLINT(cppcoreguidelines-pro-type-vararg,hicpp-vararg) From 7a4a7b1220324572566023f0d3ad2e3bcc2589cb Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Mon, 10 May 2021 00:03:29 +0300 Subject: [PATCH 5/6] * Added Dockerfile * Added docker image to README.md * Added target install ( make install for linux) --- .gitlab-ci.yml | 50 +++++++++++++++-- CMakeLists.txt | 9 +++- Dockerfile | 23 ++++++++ README.md | 32 +++++++++++ docs/versions/VERSION_0.4.0.md | 54 +++++++++---------- src/application/app_con.cpp | 2 +- .../resources/app_resources_version.cpp | 4 +- .../resources/app_resources_version.hpp | 2 +- src/cmake/InstallConfig.cmake | 13 +++++ 9 files changed, 152 insertions(+), 37 deletions(-) create mode 100644 Dockerfile create mode 100644 src/cmake/InstallConfig.cmake diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0d19ea6..d059f18 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,8 @@ stages: - check_typos - run_cppcheck - build_minor_compiler_arm + - install_deb_file + - install_rpm_file build_gcc10: tags: @@ -23,7 +25,7 @@ build_gcc10: - apt-get install libboost-test-dev -y - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release -j4 + - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release @@ -39,7 +41,7 @@ build_gcc8: - export CXX=g++-8 - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release -j4 + - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release needs: [build_gcc10] @@ -56,7 +58,7 @@ build_gcc7: - export CXX=g++-7 - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release -j4 + - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release needs: [build_gcc8] @@ -73,7 +75,7 @@ build_clang: - export CXX=/usr/bin/clang++ - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release -j4 + - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release needs: [build_gcc7] @@ -134,7 +136,7 @@ build_arm_linux: script: - cd build - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON - - cmake --build . --config Release -j4 + - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release needs: [build_gcc10] @@ -167,5 +169,43 @@ cppcheck: - cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCPPINCLUDE_BUILD_WITH_TESTS=ON - cppcheck --project=compile_commands.json --enable=all --suppressions-list=../.cppcheck-suppressions-list --error-exitcode=1 --quiet needs: [check_typos] + +generate_deb_file: + tags: + - vm_linux + stage: install_deb_file + image: ubuntu + script: + - apt-get update + - apt-get install -y gcc-10 g++-10 cmake file + - export CC=gcc-10 + - export CXX=g++-10 + - cd build + - cmake .. -DCMAKE_BUILD_TYPE=Release + - cmake --build . --config Release -j$(nproc) + # Generate deb file + - cpack -G DEB + - dpkg -i *.deb + - cd .. + - cppinclude --version + needs: [cppcheck] + +generate_rpm_file: + tags: + - vm_linux + stage: install_rpm_file + image: centos + script: + - yum group install "Development Tools" -y + - yum install cmake3 -y + - cd build + - cmake3 .. -DCMAKE_BUILD_TYPE=Release + - cmake3 --build . --config Release + # Generate rpm file + - cpack -G RPM + - rpm -i *.rpm + - cd .. + - cppinclude --version + needs: [build_gcc10] diff --git a/CMakeLists.txt b/CMakeLists.txt index d776652..d59ba0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,10 @@ cmake_minimum_required(VERSION 3.10) -project(cppinclude) +project(cppinclude + VERSION 0.4.0 + DESCRIPTION "Tool for analyzing includes in C++" + LANGUAGES CXX +) include_directories(src/) include_directories(src/3rd-part/fmt/include/) @@ -66,3 +70,6 @@ if(MSVC) set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/INCREMENTAL:NO") endif() +include(InstallConfig) +include(CPack) + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2ab50e0 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,23 @@ +FROM ubuntu + +RUN apt-get update + +ENV DEBIAN_FRONTEND noninteractive +RUN ln -fs /usr/share/zoneinfo/America/New_York /etc/localtime +RUN apt-get install -y gcc-10 g++-10 cmake + +ADD ./ /cppinclude + +WORKDIR /cppinclude/ +RUN rm -rf ./build || true + +ENV CC gcc-10 +ENV CXX g++-10 +RUN mkdir -p build && cd build && \ +cmake .. -DCMAKE_BUILD_TYPE=Release && \ +cmake --build . --config Release -j$(nproc) && \ +make install && \ +cd .. && \ +rm -rf ./build + +WORKDIR / diff --git a/README.md b/README.md index 5537b54..3dab53f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ include that file will be recompiled and sometime it takes a lot of time. * [show_std_files](#show_std_files) * [show_only_std_headers](#show_only_std_headers) * [Build](#build) +* [Docker image](#docker-image) * [Presentations](#presentations) * [Tips for optimization includes](#tips-for-optimization-includes) * [Third-party libraries](#third-party-libraries) @@ -552,6 +553,37 @@ on Unix: [Back to top](#cppinclude) +## Docker image + +Pull image: + +```sh +docker pull cppinclude/cppinclude +``` + +Or build docker image from source: + +```sh +docker build -t cppinclude/cppinclude . +``` + +Test image: + +```sh +docker run -it cppinclude/cppinclude bash +cppinclude --version +``` + +Analyze your sources in docker image: + +```sh +docker run -v /tmp/project_src:/src/project_src -it cppinclude/cppinclude +cd /src/project_src +cppinclude +``` + +[Back to top](#cppinclude) + ## Presentations * 2020, Lightning Talk on CppCon 2020, cppinclude - Tool for analyzing includes in C++ diff --git a/docs/versions/VERSION_0.4.0.md b/docs/versions/VERSION_0.4.0.md index 3eda264..7462463 100644 --- a/docs/versions/VERSION_0.4.0.md +++ b/docs/versions/VERSION_0.4.0.md @@ -17,26 +17,26 @@ Start report results ... Most impact files: 1 : "luaconf.h" impact on 62 file(s) Included by: - 1 : "lua.h" line 16, impact on 61 file(s) - 2 : "onelua.c" line 49 + 1 : "lua.h" line 16, impact on 61 file(s) + 2 : "onelua.c" line 49 2 : "lua.h" impact on 61 file(s) Included by: - 1 : "llimits.h" line 15, impact on 40 file(s) - 2 : "lobject.h" line 16, impact on 34 file(s) - 3 : "lstate.h" line 10, impact on 26 file(s) - ... 3 of 44 details + 1 : "llimits.h" line 15, impact on 40 file(s) + 2 : "lobject.h" line 16, impact on 34 file(s) + 3 : "lstate.h" line 10, impact on 26 file(s) + ... 3 of 44 details 3 : "llimits.h" impact on 40 file(s) Included by: - 1 : "lobject.h" line 15, impact on 34 file(s) - 2 : "lmem.h" line 13, impact on 15 file(s) - 3 : "lopcodes.h" line 10, impact on 9 file(s) - ... 3 of 8 details + 1 : "lobject.h" line 15, impact on 34 file(s) + 2 : "lmem.h" line 13, impact on 15 file(s) + 3 : "lopcodes.h" line 10, impact on 9 file(s) + ... 3 of 8 details 4 : "lprefix.h" impact on 35 file(s) Included by: - 1 : "lapi.c" line 10, impact on 1 file(s) - 2 : "lauxlib.c" line 10, impact on 1 file(s) - 3 : "lbaselib.c" line 10, impact on 1 file(s) - ... 3 of 35 details + 1 : "lapi.c" line 10, impact on 1 file(s) + 2 : "lauxlib.c" line 10, impact on 1 file(s) + 3 : "lbaselib.c" line 10, impact on 1 file(s) + ... 3 of 35 details ... ``` @@ -52,25 +52,25 @@ Start report results ... Most impact files: 1 : "assert.h" impact on 64 file(s) Included by: - 1 : "luaconf.h" line 701, impact on 62 file(s) - 2 : "lutf8lib.c" line 13, impact on 1 file(s) - 3 : "ltests.h" line 24 - ... 3 of 4 details + 1 : "luaconf.h" line 701, impact on 62 file(s) + 2 : "lutf8lib.c" line 13, impact on 1 file(s) + 3 : "ltests.h" line 24 + ... 3 of 4 details 2 : "stddef.h" impact on 64 file(s) Included by: - 1 : "luaconf.h" line 12, impact on 62 file(s) - 2 : "lua.h" line 13, impact on 61 file(s) - 3 : "llimits.h" line 12, impact on 40 file(s) - ... 3 of 15 details + 1 : "luaconf.h" line 12, impact on 62 file(s) + 2 : "lua.h" line 13, impact on 61 file(s) + 3 : "llimits.h" line 12, impact on 40 file(s) + ... 3 of 15 details 3 : "limits.h" impact on 63 file(s) Included by: - 1 : "luaconf.h" line 11, impact on 62 file(s) - 2 : "llimits.h" line 11, impact on 40 file(s) - 3 : "lctype.h" line 34, impact on 5 file(s) - ... 3 of 16 details + 1 : "luaconf.h" line 11, impact on 62 file(s) + 2 : "llimits.h" line 11, impact on 40 file(s) + 3 : "lctype.h" line 34, impact on 5 file(s) + ... 3 of 16 details 4 : "stdint.h" impact on 63 file(s) Included by: - 1 : "luaconf.h" line 660, impact on 62 file(s) + 1 : "luaconf.h" line 660, impact on 62 file(s) ... ``` diff --git a/src/application/app_con.cpp b/src/application/app_con.cpp index 3c73386..0b3d600 100644 --- a/src/application/app_con.cpp +++ b/src/application/app_con.cpp @@ -413,7 +413,7 @@ void ConcoleApplication::showVersion() version::VersionFormat, version::Major, version::Minor, - version::Path + version::Patch ); } diff --git a/src/application/resources/app_resources_version.cpp b/src/application/resources/app_resources_version.cpp index b6e03e5..314638e 100644 --- a/src/application/resources/app_resources_version.cpp +++ b/src/application/resources/app_resources_version.cpp @@ -7,8 +7,8 @@ namespace application::resources::version { //------------------------------------------------------------------------------ const int Major = 0; - const int Minor = 4; - const int Path = 0; + const int Minor = 4; + const int Patch = 0; const char * const VersionFormat = "{}.{}.{}\n"; diff --git a/src/application/resources/app_resources_version.hpp b/src/application/resources/app_resources_version.hpp index a157c24..33eb288 100644 --- a/src/application/resources/app_resources_version.hpp +++ b/src/application/resources/app_resources_version.hpp @@ -8,7 +8,7 @@ namespace application::resources::version { extern const int Major; extern const int Minor; - extern const int Path; + extern const int Patch; extern const char * const VersionFormat; diff --git a/src/cmake/InstallConfig.cmake b/src/cmake/InstallConfig.cmake new file mode 100644 index 0000000..714fa3a --- /dev/null +++ b/src/cmake/InstallConfig.cmake @@ -0,0 +1,13 @@ +set(CPACK_PACKAGE_CONTACT "cppinclude@yandex.com") +set(CPACK_PACKAGE_DESCRIPTION "") +set(CPACK_PACKAGE_VENDOR "cppinclude") + +set(CPACK_DEBIAN_PACKAGE_NAME "${PROJECT_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}-${CMAKE_PROJECT_VERSION}") +set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT} ) +set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + +if(NOT DEFINED CMAKE_INSTALL_PREFIX AND NOT WIN32) + set(CMAKE_INSTALL_PREFIX "/usr/bin/") +endif() + +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) From dc126c6057d2fe30569e6e86f66d2c8eebb50212 Mon Sep 17 00:00:00 2001 From: Cpp Include Date: Tue, 10 Aug 2021 21:32:51 +0300 Subject: [PATCH 6/6] Public version 0.5.0 --- .gitlab-ci.yml | 90 +- CHANGELOG.md | 14 +- CMakeLists.txt | 4 +- LICENSE | 21 + README.md | 123 +- check_code_style.sh | 2 +- docs/examples/chromium/.cppinclude.json | 370 +- docs/examples/chromium/output_unix.txt | 210 +- docs/examples/chromium/output_win.txt | 210 +- docs/examples/clementine/output_unix.txt | 154 +- docs/examples/clementine/output_win.txt | 154 +- docs/examples/cmake/output_unix.txt | 130 +- docs/examples/cppinclude/output_unix.txt | 111 +- docs/examples/cppinclude/output_win.txt | 111 +- docs/examples/gcc/output_unix.txt | 184 +- docs/examples/gcc/output_win.txt | 184 +- docs/examples/llvm-project/output_unix.txt | 218 +- docs/examples/llvm-project/output_win.txt | 218 +- docs/examples/lua/output_unix.txt | 630 +- docs/examples/lua/output_win.txt | 630 +- .../notepad-plus-plus/output_unix.txt | 88 +- .../examples/notepad-plus-plus/output_win.txt | 88 +- docs/examples/simple_example/output_unix.txt | 26 +- docs/examples/simple_example/output_win.txt | 26 +- .../simple_example_cmake/output_unix.txt | 26 +- .../simple_example_cmake/output_win.txt | 26 +- .../output_unix.txt | 22 +- .../output_win.txt | 22 +- .../output_unix.txt | 30 +- .../output_win.txt | 30 +- .../output_unix.txt | 26 +- .../output_win.txt | 26 +- .../output_unix.txt | 26 +- .../output_win.txt | 26 +- docs/examples/vlc/output_unix.txt | 96 +- docs/examples/vlc/output_win.txt | 96 +- docs/versions/VERSION_0.5.0.md | 101 + src/3rd-part/.clang-format | 5 + src/3rd-part/cxxopts/include/cxxopts.hpp | 6 +- src/3rd-part/fmt/CMakeLists.txt | 148 +- src/3rd-part/fmt/include/fmt/chrono.h | 250 +- src/3rd-part/fmt/include/fmt/color.h | 131 +- src/3rd-part/fmt/include/fmt/compile.h | 330 +- src/3rd-part/fmt/include/fmt/core.h | 1531 ++-- src/3rd-part/fmt/include/fmt/format-inl.h | 2256 ++++-- src/3rd-part/fmt/include/fmt/format.h | 3293 +++++---- src/3rd-part/fmt/include/fmt/locale.h | 63 +- src/3rd-part/fmt/include/fmt/os.h | 480 ++ src/3rd-part/fmt/include/fmt/ostream.h | 76 +- src/3rd-part/fmt/include/fmt/posix.h | 323 +- src/3rd-part/fmt/include/fmt/printf.h | 200 +- src/3rd-part/fmt/include/fmt/ranges.h | 117 +- src/3rd-part/fmt/src/format.cc | 195 +- src/3rd-part/fmt/src/{posix.cc => os.cc} | 227 +- .../fmt/support/cmake/JoinPaths.cmake | 26 + src/3rd-part/fmt/support/cmake/cxx14.cmake | 11 - src/3rd-part/fmt/support/cmake/fmt.pc.in | 6 +- src/3rd-part/re2/CMakeLists.txt | 163 + src/3rd-part/re2/re2/bitmap256.h | 117 + src/3rd-part/re2/re2/bitstate.cc | 385 + src/3rd-part/re2/re2/compile.cc | 1261 ++++ src/3rd-part/re2/re2/dfa.cc | 2118 ++++++ src/3rd-part/re2/re2/filtered_re2.cc | 137 + src/3rd-part/re2/re2/filtered_re2.h | 114 + src/3rd-part/re2/re2/mimics_pcre.cc | 199 + src/3rd-part/re2/re2/nfa.cc | 715 ++ src/3rd-part/re2/re2/onepass.cc | 623 ++ src/3rd-part/re2/re2/parse.cc | 2466 +++++++ src/3rd-part/re2/re2/perl_groups.cc | 119 + src/3rd-part/re2/re2/pod_array.h | 55 + src/3rd-part/re2/re2/prefilter.cc | 711 ++ src/3rd-part/re2/re2/prefilter.h | 108 + src/3rd-part/re2/re2/prefilter_tree.cc | 409 ++ src/3rd-part/re2/re2/prefilter_tree.h | 139 + src/3rd-part/re2/re2/prog.cc | 1166 +++ src/3rd-part/re2/re2/prog.h | 455 ++ src/3rd-part/re2/re2/re2.cc | 1331 ++++ src/3rd-part/re2/re2/re2.h | 1014 +++ src/3rd-part/re2/re2/regexp.cc | 987 +++ src/3rd-part/re2/re2/regexp.h | 665 ++ src/3rd-part/re2/re2/set.cc | 176 + src/3rd-part/re2/re2/set.h | 85 + src/3rd-part/re2/re2/simplify.cc | 665 ++ src/3rd-part/re2/re2/sparse_array.h | 392 ++ src/3rd-part/re2/re2/sparse_set.h | 264 + src/3rd-part/re2/re2/stringpiece.cc | 65 + src/3rd-part/re2/re2/stringpiece.h | 210 + src/3rd-part/re2/re2/tostring.cc | 351 + src/3rd-part/re2/re2/unicode_casefold.cc | 582 ++ src/3rd-part/re2/re2/unicode_casefold.h | 78 + src/3rd-part/re2/re2/unicode_groups.cc | 6269 +++++++++++++++++ src/3rd-part/re2/re2/unicode_groups.h | 67 + src/3rd-part/re2/re2/walker-inl.h | 248 + src/3rd-part/re2/util/benchmark.cc | 131 + src/3rd-part/re2/util/benchmark.h | 156 + src/3rd-part/re2/util/flags.h | 26 + src/3rd-part/re2/util/fuzz.cc | 21 + src/3rd-part/re2/util/logging.h | 109 + src/3rd-part/re2/util/malloc_counter.h | 19 + src/3rd-part/re2/util/mix.h | 41 + src/3rd-part/re2/util/mutex.h | 148 + src/3rd-part/re2/util/pcre.cc | 1025 +++ src/3rd-part/re2/util/pcre.h | 681 ++ src/3rd-part/re2/util/rune.cc | 260 + src/3rd-part/re2/util/strutil.cc | 149 + src/3rd-part/re2/util/strutil.h | 21 + src/3rd-part/re2/util/test.cc | 34 + src/3rd-part/re2/util/test.h | 50 + src/3rd-part/re2/util/utf.h | 44 + src/3rd-part/re2/util/util.h | 42 + src/application/app_con.cpp | 146 +- src/application/app_con.hpp | 132 +- .../app_base_exception_with_message_impl.hpp | 10 +- .../exceptions/app_cant_create_analyzer.cpp | 7 +- .../exceptions/app_cant_create_model_impl.cpp | 7 +- .../exceptions/app_cant_create_model_impl.hpp | 4 +- .../app_cant_create_project_impl.cpp | 7 +- .../app_cant_create_project_impl.hpp | 4 +- .../app_cant_create_report_impl.cpp | 4 +- .../app_cant_load_reporter_settings.cpp | 7 +- .../app_cant_load_reporter_settings.hpp | 4 +- src/application/exceptions/app_exceptions.hpp | 27 +- ...app_incorrect_thousands_separator_impl.cpp | 21 + ...app_incorrect_thousands_separator_impl.hpp | 24 + .../resources/app_resources_arguments.cpp | 265 +- .../resources/app_resources_arguments.hpp | 186 +- .../app_resources_configuration_file.cpp | 33 +- .../app_resources_configuration_file.hpp | 33 +- .../resources/app_resources_exceptions.cpp | 53 +- .../resources/app_resources_exceptions.hpp | 52 +- .../resources/app_resources_messages.cpp | 10 +- .../resources/app_resources_messages.hpp | 10 +- .../resources/app_resources_version.cpp | 12 +- .../resources/app_resources_version.hpp | 12 +- ...app_test_cmake_project_builder_fixture.cpp | 56 +- ...app_test_cmake_project_builder_fixture.hpp | 39 +- .../app_test_configuration_file_fixture.cpp | 30 +- .../app_test_configuration_file_fixture.hpp | 49 +- .../test/fixtures/app_test_parser_fixture.cpp | 60 +- .../test/fixtures/app_test_parser_fixture.hpp | 61 +- .../app_test_parser_wrapper_fixture.cpp | 131 +- .../app_test_parser_wrapper_fixture.hpp | 36 +- .../app_test_project_builder_fixture.cpp | 52 +- .../app_test_project_builder_fixture.hpp | 49 +- ...pp_test_report_settings_loader_fixture.cpp | 53 +- ...pp_test_report_settings_loader_fixture.hpp | 35 +- .../suits/app_test_cmake_project_builder.cpp | 113 +- .../app_test_configuration_file_suits.cpp | 37 +- .../test/suits/app_test_parser_arguments.cpp | 24 +- ...pp_test_parser_arguments_wrapper_suits.cpp | 144 +- .../test/suits/app_test_project_builder.cpp | 84 +- .../suits/app_test_report_settings_loader.cpp | 164 +- src/application/tools/app_argument.cpp | 15 +- src/application/tools/app_argument.hpp | 7 +- .../tools/app_cmake_project_builder.cpp | 36 +- .../tools/app_cmake_project_builder.hpp | 59 +- .../tools/app_configuration_file.cpp | 111 +- .../tools/app_configuration_file.hpp | 66 +- .../tools/app_configuration_file_loader.cpp | 22 +- .../tools/app_configuration_file_loader.hpp | 38 +- src/application/tools/app_log.cpp | 12 +- src/application/tools/app_log.hpp | 4 +- src/application/tools/app_parser_arg.cpp | 73 +- src/application/tools/app_parser_arg.hpp | 63 +- .../tools/app_parser_arg_wrapper.cpp | 176 +- .../tools/app_parser_arg_wrapper.hpp | 62 +- src/application/tools/app_plugin_ptr.hpp | 4 +- src/application/tools/app_project_builder.cpp | 25 +- src/application/tools/app_project_builder.hpp | 47 +- .../tools/app_report_settings_loader.cpp | 118 +- .../tools/app_report_settings_loader.hpp | 62 +- src/cmake_project/api/cprj_loader.hpp | 10 +- src/cmake_project/api/cprj_project.hpp | 22 +- src/cmake_project/ih/cprj_accessor.hpp | 5 +- src/cmake_project/ih/cprj_accessor_impl.cpp | 4 +- src/cmake_project/ih/cprj_accessor_impl.hpp | 4 +- .../impl/cprj_includes_parser.cpp | 35 +- .../impl/cprj_includes_parser.hpp | 46 +- .../impl/cprj_includes_parser_context.cpp | 8 +- .../impl/cprj_includes_parser_context.hpp | 20 +- src/cmake_project/impl/cprj_loader_impl.cpp | 14 +- src/cmake_project/impl/cprj_loader_impl.hpp | 17 +- src/cmake_project/impl/cprj_project_impl.cpp | 12 +- src/cmake_project/impl/cprj_project_impl.hpp | 17 +- .../cprj_test_includes_parser_fixture.cpp | 23 +- .../cprj_test_includes_parser_fixture.hpp | 18 +- .../fixtures/cprj_test_loader_fixture.cpp | 40 +- .../fixtures/cprj_test_loader_fixture.hpp | 33 +- .../test/suits/cprj_test_includes_parser.cpp | 81 +- .../test/suits/cprj_test_loader.cpp | 64 +- src/compilation_db/api/cdb_command_object.hpp | 4 +- src/compilation_db/api/cdb_database.hpp | 9 +- src/compilation_db/api/cdb_loader.hpp | 10 +- src/compilation_db/ih/cdb_accessor.hpp | 5 +- src/compilation_db/ih/cdb_accessor_impl.cpp | 4 +- src/compilation_db/ih/cdb_accessor_impl.hpp | 4 +- .../impl/cdb_command_object_impl.cpp | 13 +- .../impl/cdb_command_object_impl.hpp | 7 +- src/compilation_db/impl/cdb_database_impl.cpp | 10 +- src/compilation_db/impl/cdb_database_impl.hpp | 7 +- src/compilation_db/impl/cdb_loader_impl.cpp | 4 +- src/compilation_db/impl/cdb_loader_impl.hpp | 9 +- .../resources/cdb_resources.cpp | 10 +- .../resources/cdb_resources.hpp | 10 +- .../test/fixtures/cdb_test_fixture.cpp | 9 +- .../test/fixtures/cdb_test_fixture.hpp | 20 +- .../test/suits/cdb_test_suits.cpp | 26 +- src/exception/api/exc_exception.hpp | 4 +- src/exception/ih/exc_exception_impl.hpp | 20 +- .../ih/exc_exception_with_message_impl.hpp | 11 +- src/exception/ih/exc_internal_error.hpp | 26 +- src/fs/api/enums/fs_item_type.hpp | 4 +- src/fs/api/fs_exceptions.hpp | 20 +- src/fs/api/fs_factory.hpp | 4 +- src/fs/api/fs_file.hpp | 6 +- src/fs/api/fs_file_system.hpp | 20 +- src/fs/ih/fs_accessor.hpp | 4 +- src/fs/ih/fs_accessor_impl.cpp | 6 +- src/fs/ih/fs_accessor_impl.hpp | 4 +- .../exceptions/fs_base_exception_impl.hpp | 6 +- .../fs_exception_cant_create_file.cpp | 8 +- .../fs_exception_cant_create_file.hpp | 4 +- .../fs_exception_cant_open_file_impl.cpp | 8 +- .../fs_exception_cant_open_file_impl.hpp | 4 +- .../fs_exception_checking_exist_file_fail.cpp | 22 +- .../fs_exception_checking_exist_file_fail.hpp | 7 +- src/fs/impl/fs_factory_impl.cpp | 4 +- src/fs/impl/fs_factory_impl.hpp | 4 +- src/fs/impl/memory/fs_memory_file.cpp | 4 +- src/fs/impl/memory/fs_memory_file.hpp | 4 +- src/fs/impl/memory/fs_memory_file_system.cpp | 35 +- src/fs/impl/memory/fs_memory_file_system.hpp | 10 +- src/fs/impl/memory/fs_memory_folder.cpp | 16 +- src/fs/impl/memory/fs_memory_folder.hpp | 16 +- src/fs/impl/physical/fs_physical_file.cpp | 6 +- src/fs/impl/physical/fs_physical_file.hpp | 4 +- .../impl/physical/fs_physical_file_system.cpp | 33 +- .../impl/physical/fs_physical_file_system.hpp | 10 +- src/fs/resources/fs_resources_exceptions.cpp | 18 +- src/fs/resources/fs_resources_exceptions.hpp | 18 +- src/json/api/json_array.hpp | 12 +- src/json/api/json_object.hpp | 5 +- src/json/api/json_value.hpp | 12 +- src/json/ih/json_accessor.hpp | 7 +- src/json/ih/json_accessor_impl.cpp | 9 +- src/json/ih/json_accessor_impl.hpp | 4 +- src/json/impl/json_array_impl.cpp | 6 +- src/json/impl/json_array_impl.hpp | 4 +- src/json/impl/json_object_impl.cpp | 16 +- src/json/impl/json_object_impl.hpp | 4 +- src/json/impl/json_value_impl.cpp | 6 +- src/json/impl/json_value_impl.hpp | 4 +- src/json/test/fixtures/json_test_fixture.cpp | 4 +- src/json/test/fixtures/json_test_fixture.hpp | 11 +- src/json/test/suits/json_test_suits.cpp | 21 +- src/model_includes/api/enums/mi_file_type.hpp | 4 +- .../api/enums/mi_include_status.hpp | 4 +- .../api/enums/mi_include_type.hpp | 4 +- src/model_includes/api/mi_analyzer.hpp | 18 +- src/model_includes/api/mi_file.hpp | 9 +- src/model_includes/api/mi_include.hpp | 11 +- .../api/mi_include_location.hpp | 8 +- src/model_includes/api/mi_model.hpp | 25 +- src/model_includes/ih/mi_accessor.hpp | 26 +- src/model_includes/ih/mi_accessor_impl.cpp | 14 +- src/model_includes/ih/mi_accessor_impl.hpp | 8 +- .../impl/mi_analyzer_context.cpp | 35 +- .../impl/mi_analyzer_context.hpp | 39 +- src/model_includes/impl/mi_analyzer_impl.cpp | 107 +- src/model_includes/impl/mi_analyzer_impl.hpp | 67 +- src/model_includes/impl/mi_file_impl.cpp | 23 +- src/model_includes/impl/mi_file_impl.hpp | 7 +- src/model_includes/impl/mi_include_impl.cpp | 17 +- src/model_includes/impl/mi_include_impl.hpp | 7 +- .../impl/mi_include_location_impl.cpp | 18 +- .../impl/mi_include_location_impl.hpp | 9 +- src/model_includes/impl/mi_model_impl.cpp | 37 +- src/model_includes/impl/mi_model_impl.hpp | 12 +- src/model_includes/impl/mi_resolver.cpp | 53 +- src/model_includes/impl/mi_resolver.hpp | 45 +- .../impl/mi_resolver_context.cpp | 17 +- .../impl/mi_resolver_context.hpp | 22 +- src/model_includes/impl/mi_std_library.cpp | 63 +- src/model_includes/impl/mi_std_library.hpp | 4 +- .../mi_test_model_includes_fixture.cpp | 52 +- .../mi_test_model_includes_fixture.hpp | 89 +- .../wrappers/mi_test_file_wrapper.cpp | 17 +- .../wrappers/mi_test_file_wrapper.hpp | 12 +- .../wrappers/mi_test_include_wrapper.cpp | 42 +- .../wrappers/mi_test_include_wrapper.hpp | 18 +- .../wrappers/mi_test_model_wrapper.cpp | 34 +- .../wrappers/mi_test_model_wrapper.hpp | 22 +- .../mi_test_analyzer_for_cmake_suits.cpp | 189 +- .../test/suits/mi_test_analyzer_suits.cpp | 512 +- .../suits/mi_test_model_includes_suits.cpp | 4 +- .../mi_test_resolver_file_type_suits.cpp | 5 +- .../suits/mi_test_resolver_path_suits.cpp | 81 +- src/parser/api/pr_include_file.hpp | 17 +- src/parser/api/pr_include_file_location.hpp | 14 +- src/parser/api/pr_parser.hpp | 10 +- src/parser/ih/pr_accessor.hpp | 5 +- src/parser/ih/pr_accessor_impl.cpp | 4 +- src/parser/ih/pr_accessor_impl.hpp | 5 +- src/parser/impl/pr_parser_context.cpp | 12 +- src/parser/impl/pr_parser_context.hpp | 4 +- src/parser/impl/pr_parser_impl.cpp | 49 +- src/parser/impl/pr_parser_impl.hpp | 44 +- .../test/fixtures/pr_test_file_wrapper.cpp | 4 +- .../test/fixtures/pr_test_file_wrapper.hpp | 11 +- src/parser/test/fixtures/pr_test_fixture.cpp | 4 +- src/parser/test/fixtures/pr_test_fixture.hpp | 18 +- src/parser/test/suits/pr_test_suits.cpp | 82 +- src/project/api/prj_exceptions.hpp | 12 +- src/project/api/prj_project.hpp | 28 +- src/project/ih/prj_project_accesso_impl.cpp | 4 +- src/project/ih/prj_project_accesso_impl.hpp | 4 +- src/project/ih/prj_project_accessor.hpp | 5 +- .../exceptions/prj_base_exception_impl.hpp | 6 +- .../prj_exception_invalid_regex.cpp | 17 +- .../prj_exception_invalid_regex.hpp | 10 +- src/project/impl/prj_project_impl.cpp | 69 +- src/project/impl/prj_project_impl.hpp | 17 +- .../resources/prj_resources_exceptions.cpp | 10 +- .../resources/prj_resources_exceptions.hpp | 10 +- src/project/test/fixture/prj_test_ficture.cpp | 23 +- src/project/test/fixture/prj_test_ficture.hpp | 20 +- src/project/test/suits/prj_test_suits.cpp | 29 +- src/reporter/api/enums/rp_reporter_kind.hpp | 4 +- src/reporter/api/rp_factory.hpp | 9 +- src/reporter/api/rp_reporter.hpp | 18 +- src/reporter/api/rp_settings.hpp | 10 +- .../exceptions/rp_base_exception_impl.hpp | 6 +- src/reporter/exceptions/rp_exceptions.hpp | 12 +- .../exceptions/rp_incorrect_report_impl.cpp | 42 +- .../exceptions/rp_incorrect_report_impl.hpp | 4 +- src/reporter/ih/rp_accessor.hpp | 5 +- src/reporter/ih/rp_accessor_impl.cpp | 6 +- src/reporter/ih/rp_accessor_impl.hpp | 4 +- .../rp_different_type_reporter.cpp | 125 +- .../rp_different_type_reporter.hpp | 45 +- .../rp_different_type_reporter_details.cpp | 4 +- .../rp_different_type_reporter_details.hpp | 9 +- .../impl/dump_reporter/rp_dump_reporter.cpp | 83 +- .../impl/dump_reporter/rp_dump_reporter.hpp | 42 +- .../rp_most_impact_reporter.cpp | 94 +- .../rp_most_impact_reporter.hpp | 48 +- .../rp_most_impact_reporter_detail.cpp | 11 +- .../rp_most_impact_reporter_detail.hpp | 14 +- src/reporter/impl/rp_base_reporter_impl.cpp | 75 +- src/reporter/impl/rp_base_reporter_impl.hpp | 28 +- src/reporter/impl/rp_factpory_impl.cpp | 24 +- src/reporter/impl/rp_factpory_impl.hpp | 4 +- src/reporter/impl/rp_settings_impl.cpp | 44 +- src/reporter/impl/rp_settings_impl.hpp | 12 +- src/reporter/impl/tools/rp_file_sorter.cpp | 4 +- src/reporter/impl/tools/rp_file_sorter.hpp | 9 +- .../impl/tools/rp_file_with_count.cpp | 12 +- .../impl/tools/rp_file_with_count.hpp | 9 +- .../tools/rp_file_with_count_container.cpp | 4 +- .../tools/rp_file_with_count_container.hpp | 20 +- .../impl/tools/rp_file_with_count_sorter.cpp | 8 +- .../impl/tools/rp_file_with_count_sorter.hpp | 5 +- .../tools/rp_includes_by_source_sorter.cpp | 12 +- .../tools/rp_includes_by_source_sorter.hpp | 9 +- .../rp_sorted_files_by_name_container.cpp | 9 +- .../rp_sorted_files_by_name_container.hpp | 16 +- ...rp_sorted_includes_by_source_container.cpp | 21 +- ...rp_sorted_includes_by_source_container.hpp | 20 +- .../rp_unincluded_reporter.cpp | 67 +- .../rp_unincluded_reporter.hpp | 17 +- .../rp_unresolved_reporter.cpp | 97 +- .../rp_unresolved_reporter.hpp | 53 +- .../rp_different_type_report_resources.cpp | 22 +- .../rp_different_type_report_resources.hpp | 16 +- src/reporter/resources/rp_dump_resources.cpp | 8 +- src/reporter/resources/rp_dump_resources.hpp | 8 +- .../rp_most_impact_report_resources.cpp | 17 +- .../rp_most_impact_report_resources.hpp | 16 +- .../resources/rp_report_resources.cpp | 8 +- .../resources/rp_report_resources.hpp | 8 +- .../resources/rp_resources_exceptions.cpp | 15 +- .../resources/rp_resources_exceptions.hpp | 14 +- .../rp_unincluded_report_resources.cpp | 10 +- .../rp_unincluded_report_resources.hpp | 10 +- .../rp_unresolved_report_resources.cpp | 17 +- .../rp_unresolved_report_resources.hpp | 15 +- .../test/fixture/rp_test_reporter_fixture.cpp | 67 +- .../test/fixture/rp_test_reporter_fixture.hpp | 54 +- .../rp_test_different_type_reporter_tests.cpp | 194 +- .../suits/rp_test_dump_reporter_suits.cpp | 109 +- .../rp_test_most_impact_reporter_suits.cpp | 485 +- .../rp_test_unincluded_reporter_suits.cpp | 104 +- .../rp_test_unresolved_reporter_tests.cpp | 210 +- .../tools/rp_reporter_kind_functins.cpp | 37 +- .../tools/rp_reporter_kind_functins.hpp | 6 +- src/test_tools/boost_predicate_wrapper.cpp | 10 +- src/test_tools/boost_predicate_wrapper.hpp | 4 +- src/tools/CMakeLists.txt | 4 +- src/tools/is_vector.hpp | 13 +- src/tools/numeric_punct_settings.cpp | 38 + src/tools/numeric_punct_settings.hpp | 28 + src/tools/path_string_tools.cpp | 14 +- src/tools/path_string_tools.hpp | 11 +- src/tools/regex.cpp | 74 +- src/tools/regex.hpp | 16 +- src/tools/regex_exception.cpp | 30 + src/tools/regex_exception.hpp | 29 + src/tools/std_hash_fs_path.hpp | 12 +- 408 files changed, 41804 insertions(+), 9945 deletions(-) create mode 100644 LICENSE create mode 100644 docs/versions/VERSION_0.5.0.md create mode 100644 src/3rd-part/.clang-format create mode 100644 src/3rd-part/fmt/include/fmt/os.h rename src/3rd-part/fmt/src/{posix.cc => os.cc} (55%) create mode 100644 src/3rd-part/fmt/support/cmake/JoinPaths.cmake create mode 100644 src/3rd-part/re2/CMakeLists.txt create mode 100644 src/3rd-part/re2/re2/bitmap256.h create mode 100644 src/3rd-part/re2/re2/bitstate.cc create mode 100644 src/3rd-part/re2/re2/compile.cc create mode 100644 src/3rd-part/re2/re2/dfa.cc create mode 100644 src/3rd-part/re2/re2/filtered_re2.cc create mode 100644 src/3rd-part/re2/re2/filtered_re2.h create mode 100644 src/3rd-part/re2/re2/mimics_pcre.cc create mode 100644 src/3rd-part/re2/re2/nfa.cc create mode 100644 src/3rd-part/re2/re2/onepass.cc create mode 100644 src/3rd-part/re2/re2/parse.cc create mode 100644 src/3rd-part/re2/re2/perl_groups.cc create mode 100644 src/3rd-part/re2/re2/pod_array.h create mode 100644 src/3rd-part/re2/re2/prefilter.cc create mode 100644 src/3rd-part/re2/re2/prefilter.h create mode 100644 src/3rd-part/re2/re2/prefilter_tree.cc create mode 100644 src/3rd-part/re2/re2/prefilter_tree.h create mode 100644 src/3rd-part/re2/re2/prog.cc create mode 100644 src/3rd-part/re2/re2/prog.h create mode 100644 src/3rd-part/re2/re2/re2.cc create mode 100644 src/3rd-part/re2/re2/re2.h create mode 100644 src/3rd-part/re2/re2/regexp.cc create mode 100644 src/3rd-part/re2/re2/regexp.h create mode 100644 src/3rd-part/re2/re2/set.cc create mode 100644 src/3rd-part/re2/re2/set.h create mode 100644 src/3rd-part/re2/re2/simplify.cc create mode 100644 src/3rd-part/re2/re2/sparse_array.h create mode 100644 src/3rd-part/re2/re2/sparse_set.h create mode 100644 src/3rd-part/re2/re2/stringpiece.cc create mode 100644 src/3rd-part/re2/re2/stringpiece.h create mode 100644 src/3rd-part/re2/re2/tostring.cc create mode 100644 src/3rd-part/re2/re2/unicode_casefold.cc create mode 100644 src/3rd-part/re2/re2/unicode_casefold.h create mode 100644 src/3rd-part/re2/re2/unicode_groups.cc create mode 100644 src/3rd-part/re2/re2/unicode_groups.h create mode 100644 src/3rd-part/re2/re2/walker-inl.h create mode 100644 src/3rd-part/re2/util/benchmark.cc create mode 100644 src/3rd-part/re2/util/benchmark.h create mode 100644 src/3rd-part/re2/util/flags.h create mode 100644 src/3rd-part/re2/util/fuzz.cc create mode 100644 src/3rd-part/re2/util/logging.h create mode 100644 src/3rd-part/re2/util/malloc_counter.h create mode 100644 src/3rd-part/re2/util/mix.h create mode 100644 src/3rd-part/re2/util/mutex.h create mode 100644 src/3rd-part/re2/util/pcre.cc create mode 100644 src/3rd-part/re2/util/pcre.h create mode 100644 src/3rd-part/re2/util/rune.cc create mode 100644 src/3rd-part/re2/util/strutil.cc create mode 100644 src/3rd-part/re2/util/strutil.h create mode 100644 src/3rd-part/re2/util/test.cc create mode 100644 src/3rd-part/re2/util/test.h create mode 100644 src/3rd-part/re2/util/utf.h create mode 100644 src/3rd-part/re2/util/util.h create mode 100644 src/application/exceptions/app_incorrect_thousands_separator_impl.cpp create mode 100644 src/application/exceptions/app_incorrect_thousands_separator_impl.hpp create mode 100644 src/tools/numeric_punct_settings.cpp create mode 100644 src/tools/numeric_punct_settings.hpp create mode 100644 src/tools/regex_exception.cpp create mode 100644 src/tools/regex_exception.hpp diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d059f18..d36eca5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,7 @@ stages: - build_major_compilers + - build_minor_compiler_gcc10 + - build_minor_compiler_gcc9 - build_minor_compiler_gcc8 - build_minor_compiler_gcc7 - build_major_compiler_clang @@ -9,10 +11,34 @@ stages: - install_deb_file - install_rpm_file -build_gcc10: +build_gcc: + only: + refs: + - master tags: - vm_linux stage: build_major_compilers + image: gcc + script: + - apt-get update + - apt-get install cmake -y + # Build without boost + - ./build.sh + # Build with boost + - apt-get install libboost-test-dev -y + - cd build + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake --build . --config Release -j$(nproc) + # Run tests + - ctest . -C Release + +build_gcc10: + only: + refs: + - master + tags: + - vm_linux + stage: build_minor_compiler_gcc10 image: ubuntu script: - apt-get update @@ -28,8 +54,32 @@ build_gcc10: - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release + needs: [build_gcc] + +build_gcc9: + only: + refs: + - master + tags: + - vm_linux + stage: build_minor_compiler_gcc9 + image: ubuntu + script: + - apt-get update + - apt-get install cmake gcc-9 g++-9 libboost-test-dev -y + - export CC=gcc-9 + - export CXX=g++-9 + - cd build + - cmake .. -DCMAKE_BUILD_TYPE=Release -DCPPINCLUDE_BUILD_WITH_TESTS=ON + - cmake --build . --config Release -j$(nproc) + # Run tests + - ctest . -C Release + needs: [build_gcc10] build_gcc8: + only: + refs: + - master tags: - vm_linux stage: build_minor_compiler_gcc8 @@ -44,9 +94,12 @@ build_gcc8: - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release - needs: [build_gcc10] + needs: [build_gcc9] build_gcc7: + only: + refs: + - master tags: - vm_linux stage: build_minor_compiler_gcc7 @@ -64,6 +117,9 @@ build_gcc7: needs: [build_gcc8] build_clang: + only: + refs: + - master tags: - vm_linux stage: build_major_compiler_clang @@ -81,6 +137,9 @@ build_clang: needs: [build_gcc7] build_windows: + only: + refs: + - master stage: build_major_compilers tags: - vm_win @@ -102,6 +161,9 @@ build_windows: - ctest . -C Release build_vs2017: + only: + refs: + - master stage: build_major_compilers tags: - vm_win @@ -115,6 +177,9 @@ build_vs2017: - cmake --build . --config Release -j4 build_macos: + only: + refs: + - master stage: build_major_compilers tags: - macmini @@ -130,6 +195,9 @@ build_macos: - ctest . -C Release build_arm_linux: + only: + refs: + - master stage: build_minor_compiler_arm tags: - arm-linux @@ -139,9 +207,12 @@ build_arm_linux: - cmake --build . --config Release -j$(nproc) # Run tests - ctest . -C Release - needs: [build_gcc10] + needs: [build_gcc] check_typos: + only: + refs: + - master tags: - vm_linux stage: check_typos @@ -158,6 +229,9 @@ check_typos: needs: [build_clang] cppcheck: + only: + refs: + - master tags: - vm_linux stage: run_cppcheck @@ -171,6 +245,9 @@ cppcheck: needs: [check_typos] generate_deb_file: + only: + refs: + - master tags: - vm_linux stage: install_deb_file @@ -191,13 +268,16 @@ generate_deb_file: needs: [cppcheck] generate_rpm_file: + only: + refs: + - master tags: - vm_linux stage: install_rpm_file image: centos script: - yum group install "Development Tools" -y - - yum install cmake3 -y + - yum install cmake3 libarchive -y - cd build - cmake3 .. -DCMAKE_BUILD_TYPE=Release - cmake3 --build . --config Release @@ -206,6 +286,6 @@ generate_rpm_file: - rpm -i *.rpm - cd .. - cppinclude --version - needs: [build_gcc10] + needs: [build_gcc] diff --git a/CHANGELOG.md b/CHANGELOG.md index 180ab07..7faa384 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,22 @@ # Changelog +## [v0.5.0](docs/versions/VERSION_0.5.0.md) + +### Improved (v0.5.0) + +* Perfomance with regex + +### Added (v0.5.0) + +* New argument *show_details* +* New argument *thousands_separator* +* New argument *verbose_ignore* + ## [v0.4.0](docs/versions/VERSION_0.4.0.md) ### Added (v0.4.0) -* New argument *show_only_std_headers* +* New argument *show_only_std_headers* ## [v0.3.1](docs/versions/VERSION_0.3.1.md) diff --git a/CMakeLists.txt b/CMakeLists.txt index d59ba0a..d11e6af 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.10) project(cppinclude - VERSION 0.4.0 + VERSION 0.5.0 DESCRIPTION "Tool for analyzing includes in C++" LANGUAGES CXX ) @@ -10,6 +10,7 @@ include_directories(src/) include_directories(src/3rd-part/fmt/include/) include_directories(src/3rd-part/stdfwd/include/) include_directories(src/3rd-part/std_fs/include/) +include_directories(src/3rd-part/std_fs/re2/re2) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -60,6 +61,7 @@ add_subdirectory(src/tools) add_subdirectory(src/project) add_subdirectory(src/application) add_subdirectory(src/3rd-part/fmt) +add_subdirectory(src/3rd-part/re2) add_subdirectory(src/json) add_subdirectory(src/compilation_db) add_subdirectory(src/cmake_project) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a631c3f --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 cppinclude + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 3dab53f..2293744 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,9 @@ include that file will be recompiled and sometime it takes a lot of time. * [report_details_limit](#report_details_limit) * [show_std_files](#show_std_files) * [show_only_std_headers](#show_only_std_headers) + * [show_details](#show_details) + * [thousands_separator](#thousands_separator) + * [verbose_ignore](#verbose_ignore) * [Build](#build) * [Docker image](#docker-image) * [Presentations](#presentations) @@ -81,18 +84,18 @@ the include hierarchy: cppinclude ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files ... ``` @@ -120,9 +123,12 @@ Name|Short description --[report_details_limit](#report_details_limit)=42|Maximum details in report, 0 - unlimited (default: 10) --[show_std_files](#show_std_files)|Show standard library headers in output (default: false) --[show_only_std_headers](#show_only_std_headers)|Show only standard library headers in output (default: false) +--[show_details](#show_details)|Show details in output (default: true) +--[thousands_separator](#thousands_separator)=separator|Set thousands separator, for example ',' (default: ' ') --help|Show usage --verbose|Verbose mode --version|Show application version +--[verbose_ignore](#verbose_ignore)|Show ignored files [Back to top](#cppinclude) @@ -354,18 +360,18 @@ Example from [docs/examples/simple_example/](docs/examples/simple_example/) cppinclude --report=most_impact ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files ... ``` @@ -524,6 +530,86 @@ Also you can set in configuration file: } ``` +### show_details + +Show or hide details + +`cppinclude --show_details=false` + +Also you can set in configuration file: + +```json +{ + "show_details" : false +} +``` + +Example [lua](docs/examples/lua) : + +``` +cppinclude --show_details=false + +... +Most impact files: +1 : "luaconf.h" impact on 62 files +2 : "lua.h" impact on 61 files +3 : "llimits.h" impact on 40 files +... + +``` + +Don't show where files are included + +[Back to top](#cppinclude) + +### thousands_separator + +You can change default thousands separator (space) to your separator + +For example: + +`cppinclude --thousands_separator=,` + +Also you can set in configuration file: + +```json +{ + "thousands_separator" : "," +} +``` + +Result: + +``` +... +Most impact files: +1 : "supper_header.h" impact on 123,456 files +2 : "config.h" impact on 12,345 files +3 : "limits.h" impact on 1,234 files +... + +``` + +**Note:** you can use only one character + +Don't show where files are included + +[Back to top](#cppinclude) + +### verbose_ignore + +Show ignored files and folders. For example: + +``` +cppinclude --verbose_ignore + +Path "sys/types.h" was ignored by "sys/.*.h" +Path "mach/mach_init.h" was ignored by "mach/.*.h" +Folder ".../3rdparty" was ignored +... + +``` + [Back to top](#cppinclude) ## Build @@ -608,6 +694,7 @@ cppinclude * [{fmt}](https://github.com/fmtlib/fmt) * [json for modern C++](https://github.com/nlohmann/json) * [Boost.Test](https://www.boost.org/) +* [RE2](https://github.com/google/re2) [Back to top](#cppinclude) diff --git a/check_code_style.sh b/check_code_style.sh index 36ebfa8..8d2484c 100755 --- a/check_code_style.sh +++ b/check_code_style.sh @@ -4,7 +4,7 @@ echo "Prepare sources..." [[ -d $tempDir ]] && rm -r $tempDir mkdir -p $tempDir && echo "Created new folder $tempDir" -cp .clang-tidy $tempDir && echo "Copied .clang-tidy" +cp .clang-format $tempDir && echo "Copied .clang-format" cp -r ./src $tempDir && echo "Copied src folder" echo "Run clang-format..." diff --git a/docs/examples/chromium/.cppinclude.json b/docs/examples/chromium/.cppinclude.json index 5ef6d86..561e158 100644 --- a/docs/examples/chromium/.cppinclude.json +++ b/docs/examples/chromium/.cppinclude.json @@ -39,232 +39,232 @@ "ignore_files" : [ - "v8/.*", + "third_party/.*", "media/.*", - "chrome/common/.*", + ".*/mojom/.*", + "ui/accessibility/.*", + "components/policy/.*", + "components/autofill_assistant/browser/.*", "chrome/credential_provider/gaiacp/.*", - "chrome/browser/devtools/protocol/forward.h", - "chrome/app/vector_icons/vector_icons.h", + "v8/.*", + + "chrome/browser/devtools/protocol/forward\\.h", + "chrome/app/vector_icons/vector_icons\\.h", "chrome/browser/devtools/protocol/.*", "chrome/browser/browser_switcher/bho/.*", - "chrome/elevation_service/elevation_service_idl.h", - - "headless/lib/browser/protocol/protocol.h", + "chrome/elevation_service/elevation_service_idl\\.h", + + "headless/lib/browser/protocol/protocol\\.h", "headless/public/devtools/domains/.*", - + "chromeos/services/device_sync/proto/.*", "chromeos/assistant/internal/.*", - - "components/autofill_assistant/browser/.*", + "components/policy/proto/.*", "components/sync/protocol/.*", "components/ui_devtools/.*", - "components/url_pattern_index/flat/url_pattern_index_generated.h", - "components/contextual_search/core/browser/contextual_search_preference.h", - "components/cronet/version.h", - "components/policy/.*", - "components/subresource_filter/core/common/flat/indexed_ruleset_generated.h", - + "components/url_pattern_index/flat/url_pattern_index_generated\\.h", + "components/contextual_search/core/browser/contextual_search_preference\\.h", + "components/cronet/version\\.h", + "components/subresource_filter/core/common/flat/indexed_ruleset_generated\\.h", + "content/browser/devtools/protocol/.*", - + "extensions/buildflags/.*", "extensions/common/api/.*", "extensions/browser/api/declarative_net_request/flat/.*", - + "native_client/src/include/.*", "native_client/src/trusted/service_runtime/.*", - + "ppapi/buildflags/.*", - "ppapi/c/test_cgen/stdint.h", - "ppapi/c/test_cgen_range/dev_channel_interface.h", - "ui/accessibility/.*", - "ui/ozone/platform_list.h", + "ppapi/c/test_cgen/stdint\\.h", + "ppapi/c/test_cgen_range/dev_channel_interface\\.h", + "ui/ozone/platform_list\\.h", "device/vr/public/mojom/.*", "printing/buildflags/.*", "libassistant/shared/public/.*", "clang/.*\\.h", "llvm/Support/.*", - "llvm/Pass.h", - "llvm/Transforms/IPO/PassManagerBuilder.h", - "llvm/Analysis/CallGraph.h", + "llvm/Pass\\.h", + "llvm/Transforms/IPO/PassManagerBuilder\\.h", + "llvm/Analysis/CallGraph\\.h", "llvm/ADT/.*", "fuchsia/fidl/chromium/cast/cpp/.*", "native_client/src/untrusted/.*", - "services/metrics/public/cpp/ukm_builders.h", - "services/metrics/public/cpp/ukm_decode.h", - "chrome/updater/app/server/win/updater_idl.h", - "components/ui_devtools/Protocol.h", - "headless/public/devtools/domains/page.h", - "base/fuchsia/testfidl/cpp/fidl.h", + "services/metrics/public/cpp/ukm_builders\\.h", + "services/metrics/public/cpp/ukm_decode\\.h", + "chrome/updater/app/server/win/updater_idl\\.h", + "components/ui_devtools/Protocol\\.h", + "headless/public/devtools/domains/page\\.h", + "base/fuchsia/testfidl/cpp/fidl\\.h", "remoting/host/win/.*", - ".*allowed/good.h", + ".*allowed/good\\.h", "library_loaders/.*", "buildtools/checkdeps/testdata/.*", - "ash/resources/vector_icons/vector_icons.h", - "chrome/updater/updater_version.h", + "ash/resources/vector_icons/vector_icons\\.h", + "chrome/updater/updater_version\\.h", "chromecast/common/extensions_api/.*", - "chromecast/ui/vector_icons.h", - "third_party/.*", + "chromecast/ui/vector_icons\\.h", "include/config/Sk.*", "include/core/Sk.*", - "ios/chrome/browser/web/external_app_launcher.h", + "ios/chrome/browser/web/external_app_launcher\\.h", "libassistant/shared/internal_api/.*", - "nacl/nacl_exception.h", - "native_client/tests/inbrowser_test_runner/test_runner.h", - "node_modules/piex/src/piex.h", - - "google_update/google_update_idl.h", - "gpu/config/gpu_driver_bug_workaround_autogen.h", - + "nacl/nacl_exception\\.h", + "native_client/tests/inbrowser_test_runner/test_runner\\.h", + "node_modules/piex/src/piex\\.h", + + "google_update/google_update_idl\\.h", + "gpu/config/gpu_driver_bug_workaround_autogen\\.h", + "headless/lib/browser/protocol/.*", - - "mojo/public/cpp/bindings/pending_reciever.h", - ".*/config.h", - ".*\\.mojom.h", - ".*\\.mojom-forward.h", - ".*\\.mojom-shared.h", - ".*\\.mojom-test-utils.h", - ".*\\.mojom-blink.h", - ".*\\.test-mojom.h", - ".*/mojom/.*", - ".*\\.pb.h", - ".*buildflags.h", - + "mojo/public/cpp/bindings/pending_reciever\\.h", + + ".*/config\\.h", + ".*\\.mojom\\.h", + ".*\\.mojom-forward\\.h", + ".*\\.mojom-shared\\.h", + ".*\\.mojom-test-utils\\.h", + ".*\\.mojom-blink\\.h", + ".*\\.test-mojom\\.h", + ".*\\.pb\\.h", + ".*buildflags\\.h", + "ui/gfx/x/.*", "llvm/IR/.*", - - "Availability.h", - "archive.h", - "atltypes.h", - "irt.h", - "json_reader.cpp", - "stddef.h", - - "whatever/whocares/ok.h", - - "generated_resources.h", - "strings.h", - "vector_icons.h", - "browser_resources.h", - "theme_resources.h", - "ui_resources.h", - "ui_chromeos_resources.h", - "ui_chromeos_strings.h", - "chromeos_strings.h", - "components_resources.h", - "components_chromium_strings.h", - "chrome_unscaled_resources.h", - "components_scaled_resources.h", - "extensions_strings.h", - "extensions_browser_resources.h", - "webui_resources.h", - "views_examples_resources.h", - "dev_ui_browser_resources.h", - "dev_ui_components_resources.h", - "version_info_values.h", - "locale_settings.h", - "dwmapi.h", - - "^chrome/browser/chromeos/login/test/wizard_in_process_browser_test.h", - "^chrome/browser/chromeos/net/wake_on_wifi_connection_observer.h", - "^chrome/browser/metrics/variations/ui_string_overrider_factory.h", - "^chrome/browser/search/local_ntp_js_integrity.h", - "^chrome/browser/metrics/expired_histograms_array.h", - "^chromecast/bindings/grit/resources.h", - "^chrome/chrome_cleaner/constants/chrome_cleanup_tool_branding.h", - "^chrome/chrome_cleaner/constants/software_reporter_tool_branding.h", - "^chrome/grit/.*.h", - "^chrome/test/chromedriver/chrome/js.h", - "^chrome/test/base/perf/.*.h", - "^chrome/test/chromedriver/chrome/user_data_dir.h", - "^chrome/renderer/app_categorizer.h", - "^chrome/services/soda/internal/soda_client.h", - - "^chromecast/android/cast_shell_jni_registration.h", - "^chromecast/app/grit/chromecast_settings.h", - "^chromecast/internal/shell/browser/cast_content_browser_internal_manifest_overlay.h", - "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay.h", - - "^android_webview/test/android_webview_unittests_jni/.*.h", - "^android_webview/test/webview_instrumentation_test_native_jni/.*.h", - "^ash/public/cpp/assistant/assistant_image_downloader.h", - "^base/containers/any_internal.h", - "^chromeos/ime/input_methods.h", + + "Availability\\.h", + "archive\\.h", + "atltypes\\.h", + "irt\\.h", + "json_reader\\.cpp", + "stddef\\.h", + + "whatever/whocares/ok\\.h", + + "generated_resources\\.h", + "strings\\.h", + "vector_icons\\.h", + "browser_resources\\.h", + "theme_resources\\.h", + "ui_resources\\.h", + "ui_chromeos_resources\\.h", + "ui_chromeos_strings\\.h", + "chromeos_strings\\.h", + "components_resources\\.h", + "components_chromium_strings\\.h", + "chrome_unscaled_resources\\.h", + "components_scaled_resources\\.h", + "extensions_strings\\.h", + "extensions_browser_resources\\.h", + "webui_resources\\.h", + "views_examples_resources\\.h", + "dev_ui_browser_resources\\.h", + "dev_ui_components_resources\\.h", + "version_info_values\\.h", + "locale_settings\\.h", + "dwmapi\\.h", + + "^chrome/browser/chromeos/login/test/wizard_in_process_browser_test\\.h", + "^chrome/browser/chromeos/net/wake_on_wifi_connection_observer\\.h", + "^chrome/browser/metrics/variations/ui_string_overrider_factory\\.h", + "^chrome/browser/search/local_ntp_js_integrity\\.h", + "^chrome/browser/metrics/expired_histograms_array\\.h", + "^chromecast/bindings/grit/resources\\.h", + "^chrome/chrome_cleaner/constants/chrome_cleanup_tool_branding\\.h", + "^chrome/chrome_cleaner/constants/software_reporter_tool_branding\\.h", + "^chrome/grit/.*\\.h", + "^chrome/test/chromedriver/chrome/js\\.h", + "^chrome/test/base/perf/.*\\.h", + "^chrome/test/chromedriver/chrome/user_data_dir\\.h", + "^chrome/renderer/app_categorizer\\.h", + "^chrome/services/soda/internal/soda_client\\.h", + + "^chromecast/android/cast_shell_jni_registration\\.h", + "^chromecast/app/grit/chromecast_settings\\.h", + "^chromecast/internal/shell/browser/cast_content_browser_internal_manifest_overlay\\.h", + "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay\\.h", + + "^android_webview/test/android_webview_unittests_jni/.*\\.h", + "^android_webview/test/webview_instrumentation_test_native_jni/.*\\.h", + "^ash/public/cpp/assistant/assistant_image_downloader\\.h", + "^base/containers/any_internal\\.h", + "^chromeos/ime/input_methods\\.h", "^components/certificate_transparency/data/log_list-inc.cc", - "^components/exo/wayland/fuzzer/.*.h", - "^components/metrics/structured/structured_events.h", - "^components/schema_org/.*.h", - "^components/search_engines/prepopulated_engines.h", - "^components/schema_org/schema_org_property_configurations.h", - "^components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator_helper.h", - "^components/variations/field_trial_config/fieldtrial_testing_config.h", - "^native_client/src/public/chrome_main.h", - "^net/http/transport_security_state_static_unittest_default.h", - "^native_client/src/public/.*.h", - "^tools/json_schema_compiler/test/.*.h", + "^components/exo/wayland/fuzzer/.*\\.h", + "^components/metrics/structured/structured_events\\.h", + "^components/schema_org/.*\\.h", + "^components/search_engines/prepopulated_engines\\.h", + "^components/schema_org/schema_org_property_configurations\\.h", + "^components/language/content/browser/ulp_language_code_locator/ulp_language_code_locator_helper\\.h", + "^components/variations/field_trial_config/fieldtrial_testing_config\\.h", + "^native_client/src/public/chrome_main\\.h", + "^net/http/transport_security_state_static_unittest_default\\.h", + "^native_client/src/public/.*\\.h", + "^tools/json_schema_compiler/test/.*\\.h", "^base/android/jni_generator/", - "jni_headers/.*.h", - "jni_registration.h", + "jni_headers/.*\\.h", + "jni_registration\\.h", "chrome_jni", - - "nacl_check.h", - "_strings.h", - "_resources.h", - "_resources_map.h", - "version.h", - "_gen.h", + + "nacl_check\\.h", + "_strings\\.h", + "_resources\\.h", + "_resources_map\\.h", + "version\\.h", + "_gen\\.h", "_gen.inc", - "generated_.*.h", - "_autogen.h", - "^windows.h", - "^archive_entry.h", - "jni_*.h", + "generated_.*\\.h", + "_autogen\\.h", + "^windows\\.h", + "^archive_entry\\.h", + "jni_*\\.h", ".inc$", - "-inc.cc$", - - "^testing/gtest/gtest.h", - - "^chrome/services/soda/internal/soda_client.h", - "^chromecast/bindings/grit/resources.h", - "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay.h", - "^chromeos/printing/uri_components.h", - "^components/feed/core/feed_image_manager.h", - "^components/offline_pages/core/downloads/download_notifying_observer.h", - "^components/site_isolation/internal/google_chrome_isolated_origins.h", - "^content/common/mac_helpers.h", - "^content/public/renderer/media_stream_video_sink.h", - "^dummy_classes.h", - "^extensions/shell/common/api/identity.h", - "^extensions/shell/common/api/shell_api_features.h", - "^google_apis/internal/google_chrome_api_keys.h", - "^google_apis/internal/metrics_signing_key.h", - "^headless/embedded_resource_pak.h", - "^json/reader.h", - "^json/writer.h", - "^libunwind.h", - "^link.h", - "^mojo/public/cpp/bindings/tests/extra_cpp_template_unittest.test-mojom-extra_cpp_template_unittest.h", - "^nacl_app/flock.h", - "^native_client/src/trusted/desc/nacl_desc_quota.h", - "^native_client/src/trusted/desc/nacl_desc_quota_interface.h", - "^net/http/transport_security_state_static.h", - "^net/http/transport_security_state_static_unittest1.h", - "^net/http/transport_security_state_static_unittest2.h", - "^net/http/transport_security_state_static_unittest3.h", - "^net/spdy/platform/impl/spdy_unsafe_arena_impl.h", - "^net/traffic_annotation/network_traffic.h", - "^ppapi/c/trusted/ppb_instance_trusted.h", - "test_thunk/simple.h", - "^ppapi/thunk/ppb_display_color_profile_api.h", - "^ppapi/thunk/simple_api.h", - "^sandbox/linux/bpf_dsl/golden/golden_files.h", - "^skia/ext/skia_commit_hash.h", - "^test_output.h", - "^ui/chromeos/colors/cros_colors.h", - "^xdg-shell-server-protocol.h", - "^xdg-shell-unstable-v6-server-protocol.h", - "^zlib.h" + "-inc\\.cc$", + + "^testing/gtest/gtest\\.h", + + "^chrome/services/soda/internal/soda_client\\.h", + "^chromecast/bindings/grit/resources\\.h", + "^chromecast/internal/shell/browser/cast_content_packaged_services_internal_manifest_overlay\\.h", + "^chromeos/printing/uri_components\\.h", + "^components/feed/core/feed_image_manager\\.h", + "^components/offline_pages/core/downloads/download_notifying_observer\\.h", + "^components/site_isolation/internal/google_chrome_isolated_origins\\.h", + "^content/common/mac_helpers\\.h", + "^content/public/renderer/media_stream_video_sink\\.h", + "^dummy_classes\\.h", + "^extensions/shell/common/api/identity\\.h", + "^extensions/shell/common/api/shell_api_features\\.h", + "^google_apis/internal/google_chrome_api_keys\\.h", + "^google_apis/internal/metrics_signing_key\\.h", + "^headless/embedded_resource_pak\\.h", + "^json/reader\\.h", + "^json/writer\\.h", + "^libunwind\\.h", + "^link\\.h", + "^mojo/public/cpp/bindings/tests/extra_cpp_template_unittest.test-mojom-extra_cpp_template_unittest\\.h", + "^nacl_app/flock\\.h", + "^native_client/src/trusted/desc/nacl_desc_quota\\.h", + "^native_client/src/trusted/desc/nacl_desc_quota_interface\\.h", + "^net/http/transport_security_state_static\\.h", + "^net/http/transport_security_state_static_unittest1\\.h", + "^net/http/transport_security_state_static_unittest2\\.h", + "^net/http/transport_security_state_static_unittest3\\.h", + "^net/spdy/platform/impl/spdy_unsafe_arena_impl\\.h", + "^net/traffic_annotation/network_traffic\\.h", + "^ppapi/c/trusted/ppb_instance_trusted\\.h", + "test_thunk/simple\\.h", + "^ppapi/thunk/ppb_display_color_profile_api\\.h", + "^ppapi/thunk/simple_api\\.h", + "^sandbox/linux/bpf_dsl/golden/golden_files\\.h", + "^skia/ext/skia_commit_hash\\.h", + "^test_output\\.h", + "^ui/chromeos/colors/cros_colors\\.h", + "^xdg-shell-server-protocol\\.h", + "^xdg-shell-unstable-v6-server-protocol\\.h", + "^zlib\\.h" ] } diff --git a/docs/examples/chromium/output_unix.txt b/docs/examples/chromium/output_unix.txt index bebc2ab..909dfc2 100644 --- a/docs/examples/chromium/output_unix.txt +++ b/docs/examples/chromium/output_unix.txt @@ -2,61 +2,61 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "build/build_config.h" impact on 53601 file(s) +1 : "build/build_config.h" impact on 53 619 files Included by: - 1 : "base/compiler_specific.h" line 8, impact on 52630 file(s) - 2 : "base/immediate_crash.h" line 8, impact on 52115 file(s) - 3 : "base/template_util.h" line 15, impact on 51449 file(s) - 4 : "base/strings/string16.h" line 37, impact on 50734 file(s) - 5 : "base/numerics/safe_math_shared_impl.h" line 19, impact on 47161 file(s) - 6 : "base/time/time.h" line 66, impact on 46267 file(s) - 7 : "base/threading/platform_thread.h" line 17, impact on 43621 file(s) - 8 : "base/thread_annotations.h" line 36, impact on 43570 file(s) - 9 : "base/synchronization/lock_impl.h" line 12, impact on 43565 file(s) - 10 : "base/synchronization/lock.h" line 14, impact on 43561 file(s) - ... 10 of 5797 details -2 : "base/base_export.h" impact on 52947 file(s) + 1 : "base/compiler_specific.h" line 8, impact on 52 647 files + 2 : "base/immediate_crash.h" line 8, impact on 52 132 files + 3 : "base/template_util.h" line 15, impact on 51 466 files + 4 : "base/strings/string16.h" line 37, impact on 50 752 files + 5 : "base/numerics/safe_math_shared_impl.h" line 19, impact on 47 176 files + 6 : "base/time/time.h" line 66, impact on 46 282 files + 7 : "base/threading/platform_thread.h" line 17, impact on 43 636 files + 8 : "base/thread_annotations.h" line 36, impact on 43 585 files + 9 : "base/synchronization/lock_impl.h" line 12, impact on 43 580 files + 10 : "base/synchronization/lock.h" line 14, impact on 43 576 files + ... 10 of 5 797 details +2 : "base/base_export.h" impact on 52 965 files Included by: - 1 : "base/check.h" line 10, impact on 52108 file(s) - 2 : "base/strings/string16.h" line 36, impact on 50734 file(s) - 3 : "base/strings/string_piece.h" line 32, impact on 49683 file(s) - 4 : "base/time/time.h" line 60, impact on 46267 file(s) - 5 : "base/threading/platform_thread.h" line 14, impact on 43621 file(s) - 6 : "base/synchronization/lock_impl.h" line 8, impact on 43565 file(s) - 7 : "base/synchronization/lock.h" line 8, impact on 43561 file(s) - 8 : "base/atomicops.h" line 39, impact on 43505 file(s) - 9 : "base/sequence_checker_impl.h" line 10, impact on 42643 file(s) - 10 : "base/threading/thread_collision_warner.h" line 11, impact on 42420 file(s) + 1 : "base/check.h" line 10, impact on 52 125 files + 2 : "base/strings/string16.h" line 36, impact on 50 752 files + 3 : "base/strings/string_piece.h" line 32, impact on 49 700 files + 4 : "base/time/time.h" line 60, impact on 46 282 files + 5 : "base/threading/platform_thread.h" line 14, impact on 43 636 files + 6 : "base/synchronization/lock_impl.h" line 8, impact on 43 580 files + 7 : "base/synchronization/lock.h" line 8, impact on 43 576 files + 8 : "base/atomicops.h" line 39, impact on 43 520 files + 9 : "base/sequence_checker_impl.h" line 10, impact on 42 658 files + 10 : "base/threading/thread_collision_warner.h" line 11, impact on 42 435 files ... 10 of 424 details -3 : "base/compiler_specific.h" impact on 52630 file(s) +3 : "base/compiler_specific.h" impact on 52 647 files Included by: - 1 : "base/check.h" line 11, impact on 52108 file(s) - 2 : "base/strings/char_traits.h" line 10, impact on 49686 file(s) - 3 : "base/time/time.h" line 62, impact on 46267 file(s) - 4 : "base/sequence_checker_impl.h" line 11, impact on 42643 file(s) - 5 : "base/sequence_checker.h" line 9, impact on 42641 file(s) - 6 : "base/memory/scoped_refptr.h" line 15, impact on 42570 file(s) - 7 : "base/threading/thread_collision_warner.h" line 12, impact on 42420 file(s) - 8 : "base/memory/ref_counted.h" line 15, impact on 42417 file(s) - 9 : "base/mac/scoped_typeref.h" line 9, impact on 33370 file(s) - 10 : "base/bind.h" line 14, impact on 32901 file(s) - ... 10 of 2103 details -4 : "base/dcheck_is_on.h" impact on 52187 file(s) + 1 : "base/check.h" line 11, impact on 52 125 files + 2 : "base/strings/char_traits.h" line 10, impact on 49 703 files + 3 : "base/time/time.h" line 62, impact on 46 282 files + 4 : "base/sequence_checker_impl.h" line 11, impact on 42 658 files + 5 : "base/sequence_checker.h" line 9, impact on 42 656 files + 6 : "base/memory/scoped_refptr.h" line 15, impact on 42 585 files + 7 : "base/threading/thread_collision_warner.h" line 12, impact on 42 435 files + 8 : "base/memory/ref_counted.h" line 15, impact on 42 432 files + 9 : "base/mac/scoped_typeref.h" line 9, impact on 33 385 files + 10 : "base/bind.h" line 14, impact on 32 916 files + ... 10 of 2 103 details +4 : "base/dcheck_is_on.h" impact on 52 204 files Included by: - 1 : "base/check.h" line 12, impact on 52108 file(s) - 2 : "base/win/scoped_handle.h" line 13, impact on 29646 file(s) - 3 : "base/logging.h" line 18, impact on 24516 file(s) - 4 : "components/performance_manager/public/graph/graph.h" line 12, impact on 204 file(s) - 5 : "remoting/base/protobuf_http_request_base.h" line 12, impact on 15 file(s) + 1 : "base/check.h" line 12, impact on 52 125 files + 2 : "base/win/scoped_handle.h" line 13, impact on 29 653 files + 3 : "base/logging.h" line 18, impact on 24 524 files + 4 : "components/performance_manager/public/graph/graph.h" line 12, impact on 204 files + 5 : "remoting/base/protobuf_http_request_base.h" line 12, impact on 15 files 6 : "chrome/app/chrome_main_delegate.cc" line 14 7 : "chrome/chrome_cleaner/executables/chrome_cleaner_main.cc" line 16 8 : "chrome/chrome_cleaner/executables/chrome_reporter_main.cc" line 17 9 : "components/performance_manager/graph/graph.cc" line 7 10 : "content/browser/tracing/tracing_controller_impl.cc" line 16 -5 : "base/immediate_crash.h" impact on 52115 file(s) +5 : "base/immediate_crash.h" impact on 52 132 files Included by: - 1 : "base/check.h" line 13, impact on 52108 file(s) - 2 : "base/allocator/malloc_zone_functions_mac.h" line 12, impact on 5 file(s) + 1 : "base/check.h" line 13, impact on 52 125 files + 2 : "base/allocator/malloc_zone_functions_mac.h" line 12, impact on 5 files 3 : "base/immediate_crash_unittest.cc" line 5 4 : "base/test/immediate_crash_test_helper.cc" line 5 5 : "base/win/atl_throw.cc" line 11 @@ -64,72 +64,72 @@ Included by: 7 : "components/services/storage/test_api/test_api.cc" line 8 8 : "net/dns/host_resolver.cc" line 11 9 : "services/test/echo/echo_service.cc" line 7 -6 : "base/check.h" impact on 52108 file(s) +6 : "base/check.h" impact on 52 125 files Included by: - 1 : "base/check_op.h" line 11, impact on 50824 file(s) - 2 : "base/optional.h" line 12, impact on 49824 file(s) - 3 : "base/stl_util.h" line 26, impact on 44553 file(s) - 4 : "base/sequence_checker.h" line 8, impact on 42641 file(s) - 5 : "base/memory/scoped_refptr.h" line 14, impact on 42570 file(s) - 6 : "base/notreached.h" line 8, impact on 40938 file(s) - 7 : "base/memory/weak_ptr.h" line 76, impact on 37545 file(s) - 8 : "base/mac/scoped_typeref.h" line 8, impact on 33370 file(s) - 9 : "base/bind_internal.h" line 18, impact on 32901 file(s) - 10 : "base/task_runner.h" line 13, impact on 30221 file(s) - ... 10 of 1523 details -7 : "base/macros.h" impact on 51890 file(s) + 1 : "base/check_op.h" line 11, impact on 50 841 files + 2 : "base/optional.h" line 12, impact on 49 841 files + 3 : "base/stl_util.h" line 26, impact on 44 570 files + 4 : "base/sequence_checker.h" line 8, impact on 42 656 files + 5 : "base/memory/scoped_refptr.h" line 14, impact on 42 585 files + 6 : "base/notreached.h" line 8, impact on 40 953 files + 7 : "base/memory/weak_ptr.h" line 76, impact on 37 560 files + 8 : "base/mac/scoped_typeref.h" line 8, impact on 33 385 files + 9 : "base/bind_internal.h" line 18, impact on 32 916 files + 10 : "base/task_runner.h" line 13, impact on 30 231 files + ... 10 of 1 524 details +7 : "base/macros.h" impact on 51 908 files Included by: - 1 : "base/threading/platform_thread.h" line 15, impact on 43621 file(s) - 2 : "base/synchronization/lock_impl.h" line 10, impact on 43565 file(s) - 3 : "base/synchronization/lock.h" line 10, impact on 43561 file(s) - 4 : "base/atomicops_internals_x86_msvc.h" line 16, impact on 43506 file(s) - 5 : "base/sequence_checker_impl.h" line 12, impact on 42643 file(s) - 6 : "base/memory/scoped_refptr.h" line 16, impact on 42570 file(s) - 7 : "base/threading/thread_collision_warner.h" line 13, impact on 42420 file(s) - 8 : "base/memory/ref_counted.h" line 17, impact on 42417 file(s) - 9 : "base/containers/span.h" line 19, impact on 41006 file(s) - 10 : "base/callback_internal.h" line 13, impact on 38416 file(s) - ... 10 of 15272 details -8 : "base/template_util.h" impact on 51449 file(s) + 1 : "base/threading/platform_thread.h" line 15, impact on 43 636 files + 2 : "base/synchronization/lock_impl.h" line 10, impact on 43 580 files + 3 : "base/synchronization/lock.h" line 10, impact on 43 576 files + 4 : "base/atomicops_internals_x86_msvc.h" line 16, impact on 43 521 files + 5 : "base/sequence_checker_impl.h" line 12, impact on 42 658 files + 6 : "base/memory/scoped_refptr.h" line 16, impact on 42 585 files + 7 : "base/threading/thread_collision_warner.h" line 13, impact on 42 435 files + 8 : "base/memory/ref_counted.h" line 17, impact on 42 432 files + 9 : "base/containers/span.h" line 19, impact on 41 023 files + 10 : "base/callback_internal.h" line 13, impact on 38 431 files + ... 10 of 15 276 details +8 : "base/template_util.h" impact on 51 466 files Included by: - 1 : "base/check_op.h" line 12, impact on 50824 file(s) - 2 : "base/optional.h" line 13, impact on 49824 file(s) - 3 : "base/stl_util.h" line 28, impact on 44553 file(s) - 4 : "base/containers/span.h" line 21, impact on 41006 file(s) - 5 : "base/memory/raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32902 file(s) - 6 : "base/bind.h" line 15, impact on 32901 file(s) - 7 : "base/bind_internal.h" line 23, impact on 32901 file(s) - 8 : "base/containers/flat_tree.h" line 15, impact on 31143 file(s) - 9 : "base/containers/flat_map.h" line 14, impact on 29812 file(s) - 10 : "base/containers/circular_deque.h" line 18, impact on 26264 file(s) + 1 : "base/check_op.h" line 12, impact on 50 841 files + 2 : "base/optional.h" line 13, impact on 49 841 files + 3 : "base/stl_util.h" line 28, impact on 44 570 files + 4 : "base/containers/span.h" line 21, impact on 41 023 files + 5 : "base/memory/raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32 917 files + 6 : "base/bind.h" line 15, impact on 32 916 files + 7 : "base/bind_internal.h" line 23, impact on 32 916 files + 8 : "base/containers/flat_tree.h" line 15, impact on 31 158 files + 9 : "base/containers/flat_map.h" line 14, impact on 29 827 files + 10 : "base/containers/circular_deque.h" line 18, impact on 26 269 files ... 10 of 23 details -9 : "base/check_op.h" impact on 50824 file(s) +9 : "base/check_op.h" impact on 50 841 files Included by: - 1 : "base/strings/string_piece.h" line 33, impact on 49683 file(s) - 2 : "base/time/time.h" line 61, impact on 46267 file(s) - 3 : "base/thread_annotations.h" line 35, impact on 43570 file(s) - 4 : "base/synchronization/lock_impl.h" line 9, impact on 43565 file(s) - 5 : "base/synchronization/lock.h" line 9, impact on 43561 file(s) - 6 : "base/memory/ref_counted.h" line 14, impact on 42417 file(s) - 7 : "base/containers/checked_iterators.h" line 12, impact on 41010 file(s) - 8 : "base/containers/span.h" line 17, impact on 41006 file(s) - 9 : "base/win/scoped_handle.h" line 11, impact on 29646 file(s) - 10 : "base/observer_list_internal.h" line 9, impact on 27997 file(s) - ... 10 of 1609 details -10 : "base/strings/string16.h" impact on 50734 file(s) + 1 : "base/strings/string_piece.h" line 33, impact on 49 700 files + 2 : "base/time/time.h" line 61, impact on 46 282 files + 3 : "base/thread_annotations.h" line 35, impact on 43 585 files + 4 : "base/synchronization/lock_impl.h" line 9, impact on 43 580 files + 5 : "base/synchronization/lock.h" line 9, impact on 43 576 files + 6 : "base/memory/ref_counted.h" line 14, impact on 42 432 files + 7 : "base/containers/checked_iterators.h" line 12, impact on 41 027 files + 8 : "base/containers/span.h" line 17, impact on 41 023 files + 9 : "base/win/scoped_handle.h" line 11, impact on 29 653 files + 10 : "base/observer_list_internal.h" line 9, impact on 28 003 files + ... 10 of 1 609 details +10 : "base/strings/string16.h" impact on 50 752 files Included by: - 1 : "base/strings/string_piece_forward.h" line 12, impact on 50009 file(s) - 2 : "base/strings/string_piece.h" line 35, impact on 49683 file(s) - 3 : "base/hash/hash.h" line 17, impact on 37370 file(s) - 4 : "base/files/file_path.h" line 115, impact on 31747 file(s) - 5 : "base/values.h" line 40, impact on 27647 file(s) - 6 : "url/url_canon.h" line 13, impact on 24380 file(s) - 7 : "url/gurl.h" line 16, impact on 23762 file(s) - 8 : "base/strings/string_util.h" line 24, impact on 23068 file(s) - 9 : "base/strings/string_util_win.h" line 19, impact on 23068 file(s) - 10 : "base/pickle.h" line 19, impact on 18703 file(s) - ... 10 of 2099 details -... 10 of 26036 files + 1 : "base/strings/string_piece_forward.h" line 12, impact on 50 026 files + 2 : "base/strings/string_piece.h" line 35, impact on 49 700 files + 3 : "base/hash/hash.h" line 17, impact on 37 381 files + 4 : "base/files/file_path.h" line 115, impact on 31 761 files + 5 : "base/values.h" line 40, impact on 27 662 files + 6 : "url/url_canon.h" line 13, impact on 24 386 files + 7 : "url/gurl.h" line 16, impact on 23 768 files + 8 : "base/strings/string_util.h" line 24, impact on 23 075 files + 9 : "base/strings/string_util_win.h" line 19, impact on 23 075 files + 10 : "base/pickle.h" line 19, impact on 18 709 files + ... 10 of 2 099 details +... 10 of 26 043 files Unincluded headers: 1 : "ash/accelerators/accelerator_ids.h" 2 : "ash/assistant/model/assistant_screen_context_model_observer.h" @@ -141,4 +141,4 @@ Unincluded headers: 8 : "base/mac/objc_release_properties.h" 9 : "base/mac/scoped_aedesc.h" 10 : "base/mac/scoped_objc_class_swizzler.h" -... 10 of 2691 files +... 10 of 2 691 files diff --git a/docs/examples/chromium/output_win.txt b/docs/examples/chromium/output_win.txt index 98e2579..7eaa764 100644 --- a/docs/examples/chromium/output_win.txt +++ b/docs/examples/chromium/output_win.txt @@ -2,61 +2,61 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "build\build_config.h" impact on 53601 file(s) +1 : "build\build_config.h" impact on 53 619 files Included by: - 1 : "base\compiler_specific.h" line 8, impact on 52630 file(s) - 2 : "base\immediate_crash.h" line 8, impact on 52115 file(s) - 3 : "base\template_util.h" line 15, impact on 51449 file(s) - 4 : "base\strings\string16.h" line 37, impact on 50734 file(s) - 5 : "base\numerics\safe_math_shared_impl.h" line 19, impact on 47161 file(s) - 6 : "base\time\time.h" line 66, impact on 46267 file(s) - 7 : "base\threading\platform_thread.h" line 17, impact on 43621 file(s) - 8 : "base\thread_annotations.h" line 36, impact on 43570 file(s) - 9 : "base\synchronization\lock_impl.h" line 12, impact on 43565 file(s) - 10 : "base\synchronization\lock.h" line 14, impact on 43561 file(s) - ... 10 of 5797 details -2 : "base\base_export.h" impact on 52947 file(s) + 1 : "base\compiler_specific.h" line 8, impact on 52 647 files + 2 : "base\immediate_crash.h" line 8, impact on 52 132 files + 3 : "base\template_util.h" line 15, impact on 51 466 files + 4 : "base\strings\string16.h" line 37, impact on 50 752 files + 5 : "base\numerics\safe_math_shared_impl.h" line 19, impact on 47 176 files + 6 : "base\time\time.h" line 66, impact on 46 282 files + 7 : "base\threading\platform_thread.h" line 17, impact on 43 636 files + 8 : "base\thread_annotations.h" line 36, impact on 43 585 files + 9 : "base\synchronization\lock_impl.h" line 12, impact on 43 580 files + 10 : "base\synchronization\lock.h" line 14, impact on 43 576 files + ... 10 of 5 797 details +2 : "base\base_export.h" impact on 52 965 files Included by: - 1 : "base\check.h" line 10, impact on 52108 file(s) - 2 : "base\strings\string16.h" line 36, impact on 50734 file(s) - 3 : "base\strings\string_piece.h" line 32, impact on 49683 file(s) - 4 : "base\time\time.h" line 60, impact on 46267 file(s) - 5 : "base\threading\platform_thread.h" line 14, impact on 43621 file(s) - 6 : "base\synchronization\lock_impl.h" line 8, impact on 43565 file(s) - 7 : "base\synchronization\lock.h" line 8, impact on 43561 file(s) - 8 : "base\atomicops.h" line 39, impact on 43505 file(s) - 9 : "base\sequence_checker_impl.h" line 10, impact on 42643 file(s) - 10 : "base\threading\thread_collision_warner.h" line 11, impact on 42420 file(s) + 1 : "base\check.h" line 10, impact on 52 125 files + 2 : "base\strings\string16.h" line 36, impact on 50 752 files + 3 : "base\strings\string_piece.h" line 32, impact on 49 700 files + 4 : "base\time\time.h" line 60, impact on 46 282 files + 5 : "base\threading\platform_thread.h" line 14, impact on 43 636 files + 6 : "base\synchronization\lock_impl.h" line 8, impact on 43 580 files + 7 : "base\synchronization\lock.h" line 8, impact on 43 576 files + 8 : "base\atomicops.h" line 39, impact on 43 520 files + 9 : "base\sequence_checker_impl.h" line 10, impact on 42 658 files + 10 : "base\threading\thread_collision_warner.h" line 11, impact on 42 435 files ... 10 of 424 details -3 : "base\compiler_specific.h" impact on 52630 file(s) +3 : "base\compiler_specific.h" impact on 52 647 files Included by: - 1 : "base\check.h" line 11, impact on 52108 file(s) - 2 : "base\strings\char_traits.h" line 10, impact on 49686 file(s) - 3 : "base\time\time.h" line 62, impact on 46267 file(s) - 4 : "base\sequence_checker_impl.h" line 11, impact on 42643 file(s) - 5 : "base\sequence_checker.h" line 9, impact on 42641 file(s) - 6 : "base\memory\scoped_refptr.h" line 15, impact on 42570 file(s) - 7 : "base\threading\thread_collision_warner.h" line 12, impact on 42420 file(s) - 8 : "base\memory\ref_counted.h" line 15, impact on 42417 file(s) - 9 : "base\mac\scoped_typeref.h" line 9, impact on 33370 file(s) - 10 : "base\bind.h" line 14, impact on 32901 file(s) - ... 10 of 2103 details -4 : "base\dcheck_is_on.h" impact on 52187 file(s) + 1 : "base\check.h" line 11, impact on 52 125 files + 2 : "base\strings\char_traits.h" line 10, impact on 49 703 files + 3 : "base\time\time.h" line 62, impact on 46 282 files + 4 : "base\sequence_checker_impl.h" line 11, impact on 42 658 files + 5 : "base\sequence_checker.h" line 9, impact on 42 656 files + 6 : "base\memory\scoped_refptr.h" line 15, impact on 42 585 files + 7 : "base\threading\thread_collision_warner.h" line 12, impact on 42 435 files + 8 : "base\memory\ref_counted.h" line 15, impact on 42 432 files + 9 : "base\mac\scoped_typeref.h" line 9, impact on 33 385 files + 10 : "base\bind.h" line 14, impact on 32 916 files + ... 10 of 2 103 details +4 : "base\dcheck_is_on.h" impact on 52 204 files Included by: - 1 : "base\check.h" line 12, impact on 52108 file(s) - 2 : "base\win\scoped_handle.h" line 13, impact on 29646 file(s) - 3 : "base\logging.h" line 18, impact on 24516 file(s) - 4 : "components\performance_manager\public\graph\graph.h" line 12, impact on 204 file(s) - 5 : "remoting\base\protobuf_http_request_base.h" line 12, impact on 15 file(s) + 1 : "base\check.h" line 12, impact on 52 125 files + 2 : "base\win\scoped_handle.h" line 13, impact on 29 653 files + 3 : "base\logging.h" line 18, impact on 24 524 files + 4 : "components\performance_manager\public\graph\graph.h" line 12, impact on 204 files + 5 : "remoting\base\protobuf_http_request_base.h" line 12, impact on 15 files 6 : "chrome\app\chrome_main_delegate.cc" line 14 7 : "chrome\chrome_cleaner\executables\chrome_cleaner_main.cc" line 16 8 : "chrome\chrome_cleaner\executables\chrome_reporter_main.cc" line 17 9 : "components\performance_manager\graph\graph.cc" line 7 10 : "content\browser\tracing\tracing_controller_impl.cc" line 16 -5 : "base\immediate_crash.h" impact on 52115 file(s) +5 : "base\immediate_crash.h" impact on 52 132 files Included by: - 1 : "base\check.h" line 13, impact on 52108 file(s) - 2 : "base\allocator\malloc_zone_functions_mac.h" line 12, impact on 5 file(s) + 1 : "base\check.h" line 13, impact on 52 125 files + 2 : "base\allocator\malloc_zone_functions_mac.h" line 12, impact on 5 files 3 : "base\immediate_crash_unittest.cc" line 5 4 : "base\test\immediate_crash_test_helper.cc" line 5 5 : "base\win\atl_throw.cc" line 11 @@ -64,72 +64,72 @@ Included by: 7 : "components\services\storage\test_api\test_api.cc" line 8 8 : "net\dns\host_resolver.cc" line 11 9 : "services\test\echo\echo_service.cc" line 7 -6 : "base\check.h" impact on 52108 file(s) +6 : "base\check.h" impact on 52 125 files Included by: - 1 : "base\check_op.h" line 11, impact on 50824 file(s) - 2 : "base\optional.h" line 12, impact on 49824 file(s) - 3 : "base\stl_util.h" line 26, impact on 44553 file(s) - 4 : "base\sequence_checker.h" line 8, impact on 42641 file(s) - 5 : "base\memory\scoped_refptr.h" line 14, impact on 42570 file(s) - 6 : "base\notreached.h" line 8, impact on 40938 file(s) - 7 : "base\memory\weak_ptr.h" line 76, impact on 37545 file(s) - 8 : "base\mac\scoped_typeref.h" line 8, impact on 33370 file(s) - 9 : "base\bind_internal.h" line 18, impact on 32901 file(s) - 10 : "base\task_runner.h" line 13, impact on 30221 file(s) - ... 10 of 1523 details -7 : "base\macros.h" impact on 51890 file(s) + 1 : "base\check_op.h" line 11, impact on 50 841 files + 2 : "base\optional.h" line 12, impact on 49 841 files + 3 : "base\stl_util.h" line 26, impact on 44 570 files + 4 : "base\sequence_checker.h" line 8, impact on 42 656 files + 5 : "base\memory\scoped_refptr.h" line 14, impact on 42 585 files + 6 : "base\notreached.h" line 8, impact on 40 953 files + 7 : "base\memory\weak_ptr.h" line 76, impact on 37 560 files + 8 : "base\mac\scoped_typeref.h" line 8, impact on 33 385 files + 9 : "base\bind_internal.h" line 18, impact on 32 916 files + 10 : "base\task_runner.h" line 13, impact on 30 231 files + ... 10 of 1 524 details +7 : "base\macros.h" impact on 51 908 files Included by: - 1 : "base\threading\platform_thread.h" line 15, impact on 43621 file(s) - 2 : "base\synchronization\lock_impl.h" line 10, impact on 43565 file(s) - 3 : "base\synchronization\lock.h" line 10, impact on 43561 file(s) - 4 : "base\atomicops_internals_x86_msvc.h" line 16, impact on 43506 file(s) - 5 : "base\sequence_checker_impl.h" line 12, impact on 42643 file(s) - 6 : "base\memory\scoped_refptr.h" line 16, impact on 42570 file(s) - 7 : "base\threading\thread_collision_warner.h" line 13, impact on 42420 file(s) - 8 : "base\memory\ref_counted.h" line 17, impact on 42417 file(s) - 9 : "base\containers\span.h" line 19, impact on 41006 file(s) - 10 : "base\callback_internal.h" line 13, impact on 38416 file(s) - ... 10 of 15272 details -8 : "base\template_util.h" impact on 51449 file(s) + 1 : "base\threading\platform_thread.h" line 15, impact on 43 636 files + 2 : "base\synchronization\lock_impl.h" line 10, impact on 43 580 files + 3 : "base\synchronization\lock.h" line 10, impact on 43 576 files + 4 : "base\atomicops_internals_x86_msvc.h" line 16, impact on 43 521 files + 5 : "base\sequence_checker_impl.h" line 12, impact on 42 658 files + 6 : "base\memory\scoped_refptr.h" line 16, impact on 42 585 files + 7 : "base\threading\thread_collision_warner.h" line 13, impact on 42 435 files + 8 : "base\memory\ref_counted.h" line 17, impact on 42 432 files + 9 : "base\containers\span.h" line 19, impact on 41 023 files + 10 : "base\callback_internal.h" line 13, impact on 38 431 files + ... 10 of 15 276 details +8 : "base\template_util.h" impact on 51 466 files Included by: - 1 : "base\check_op.h" line 12, impact on 50824 file(s) - 2 : "base\optional.h" line 13, impact on 49824 file(s) - 3 : "base\stl_util.h" line 28, impact on 44553 file(s) - 4 : "base\containers\span.h" line 21, impact on 41006 file(s) - 5 : "base\memory\raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32902 file(s) - 6 : "base\bind.h" line 15, impact on 32901 file(s) - 7 : "base\bind_internal.h" line 23, impact on 32901 file(s) - 8 : "base\containers\flat_tree.h" line 15, impact on 31143 file(s) - 9 : "base\containers\flat_map.h" line 14, impact on 29812 file(s) - 10 : "base\containers\circular_deque.h" line 18, impact on 26264 file(s) + 1 : "base\check_op.h" line 12, impact on 50 841 files + 2 : "base\optional.h" line 13, impact on 49 841 files + 3 : "base\stl_util.h" line 28, impact on 44 570 files + 4 : "base\containers\span.h" line 21, impact on 41 023 files + 5 : "base\memory\raw_scoped_refptr_mismatch_checker.h" line 10, impact on 32 917 files + 6 : "base\bind.h" line 15, impact on 32 916 files + 7 : "base\bind_internal.h" line 23, impact on 32 916 files + 8 : "base\containers\flat_tree.h" line 15, impact on 31 158 files + 9 : "base\containers\flat_map.h" line 14, impact on 29 827 files + 10 : "base\containers\circular_deque.h" line 18, impact on 26 269 files ... 10 of 23 details -9 : "base\check_op.h" impact on 50824 file(s) +9 : "base\check_op.h" impact on 50 841 files Included by: - 1 : "base\strings\string_piece.h" line 33, impact on 49683 file(s) - 2 : "base\time\time.h" line 61, impact on 46267 file(s) - 3 : "base\thread_annotations.h" line 35, impact on 43570 file(s) - 4 : "base\synchronization\lock_impl.h" line 9, impact on 43565 file(s) - 5 : "base\synchronization\lock.h" line 9, impact on 43561 file(s) - 6 : "base\memory\ref_counted.h" line 14, impact on 42417 file(s) - 7 : "base\containers\checked_iterators.h" line 12, impact on 41010 file(s) - 8 : "base\containers\span.h" line 17, impact on 41006 file(s) - 9 : "base\win\scoped_handle.h" line 11, impact on 29646 file(s) - 10 : "base\observer_list_internal.h" line 9, impact on 27997 file(s) - ... 10 of 1609 details -10 : "base\strings\string16.h" impact on 50734 file(s) + 1 : "base\strings\string_piece.h" line 33, impact on 49 700 files + 2 : "base\time\time.h" line 61, impact on 46 282 files + 3 : "base\thread_annotations.h" line 35, impact on 43 585 files + 4 : "base\synchronization\lock_impl.h" line 9, impact on 43 580 files + 5 : "base\synchronization\lock.h" line 9, impact on 43 576 files + 6 : "base\memory\ref_counted.h" line 14, impact on 42 432 files + 7 : "base\containers\checked_iterators.h" line 12, impact on 41 027 files + 8 : "base\containers\span.h" line 17, impact on 41 023 files + 9 : "base\win\scoped_handle.h" line 11, impact on 29 653 files + 10 : "base\observer_list_internal.h" line 9, impact on 28 003 files + ... 10 of 1 609 details +10 : "base\strings\string16.h" impact on 50 752 files Included by: - 1 : "base\strings\string_piece_forward.h" line 12, impact on 50009 file(s) - 2 : "base\strings\string_piece.h" line 35, impact on 49683 file(s) - 3 : "base\hash\hash.h" line 17, impact on 37370 file(s) - 4 : "base\files\file_path.h" line 115, impact on 31747 file(s) - 5 : "base\values.h" line 40, impact on 27647 file(s) - 6 : "url\url_canon.h" line 13, impact on 24380 file(s) - 7 : "url\gurl.h" line 16, impact on 23762 file(s) - 8 : "base\strings\string_util.h" line 24, impact on 23068 file(s) - 9 : "base\strings\string_util_win.h" line 19, impact on 23068 file(s) - 10 : "base\pickle.h" line 19, impact on 18703 file(s) - ... 10 of 2099 details -... 10 of 26036 files + 1 : "base\strings\string_piece_forward.h" line 12, impact on 50 026 files + 2 : "base\strings\string_piece.h" line 35, impact on 49 700 files + 3 : "base\hash\hash.h" line 17, impact on 37 381 files + 4 : "base\files\file_path.h" line 115, impact on 31 761 files + 5 : "base\values.h" line 40, impact on 27 662 files + 6 : "url\url_canon.h" line 13, impact on 24 386 files + 7 : "url\gurl.h" line 16, impact on 23 768 files + 8 : "base\strings\string_util.h" line 24, impact on 23 075 files + 9 : "base\strings\string_util_win.h" line 19, impact on 23 075 files + 10 : "base\pickle.h" line 19, impact on 18 709 files + ... 10 of 2 099 details +... 10 of 26 043 files Unincluded headers: 1 : "ash\accelerators\accelerator_ids.h" 2 : "ash\assistant\model\assistant_screen_context_model_observer.h" @@ -141,4 +141,4 @@ Unincluded headers: 8 : "base\mac\objc_release_properties.h" 9 : "base\mac\scoped_aedesc.h" 10 : "base\mac\scoped_objc_class_swizzler.h" -... 10 of 2691 files +... 10 of 2 691 files diff --git a/docs/examples/clementine/output_unix.txt b/docs/examples/clementine/output_unix.txt index a93a7a5..21d101f 100644 --- a/docs/examples/clementine/output_unix.txt +++ b/docs/examples/clementine/output_unix.txt @@ -2,99 +2,99 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "src/playlist/playlistsequence.h" impact on 185 file(s) +1 : "src/playlist/playlistsequence.h" impact on 185 files Included by: - 1 : "src/playlist/playlist.h" line 25, impact on 129 file(s) - 2 : "src/widgets/osd.h" line 30, impact on 76 file(s) + 1 : "src/playlist/playlist.h" line 25, impact on 129 files + 2 : "src/widgets/osd.h" line 30, impact on 76 files 3 : "src/networkremote/incomingdataparser.cpp" line 27 4 : "src/playlist/playlistsequence.cpp" line 18 5 : "src/ui/mainwindow.cpp" line 88 6 : "tests/mpris1_test.cpp" line 24 -2 : "src/playlist/playlistitem.h" impact on 179 file(s) +2 : "src/playlist/playlistitem.h" impact on 179 files Included by: - 1 : "src/playlist/playlist.h" line 24, impact on 129 file(s) - 2 : "src/smartplaylists/generator.h" line 21, impact on 31 file(s) - 3 : "src/ui/mainwindow.h" line 33, impact on 13 file(s) - 4 : "src/library/libraryplaylistitem.h" line 22, impact on 12 file(s) - 5 : "src/ui/edittagdialog.h" line 28, impact on 12 file(s) - 6 : "src/playlist/playlistbackend.h" line 26, impact on 11 file(s) - 7 : "src/songinfo/songinfobase.h" line 26, impact on 11 file(s) - 8 : "src/playlist/songplaylistitem.h" line 21, impact on 7 file(s) - 9 : "src/playlist/playlistitemmimedata.h" line 21, impact on 2 file(s) - 10 : "src/playlist/playlistundocommands.h" line 24, impact on 2 file(s) + 1 : "src/playlist/playlist.h" line 24, impact on 129 files + 2 : "src/smartplaylists/generator.h" line 21, impact on 31 files + 3 : "src/ui/mainwindow.h" line 33, impact on 13 files + 4 : "src/library/libraryplaylistitem.h" line 22, impact on 12 files + 5 : "src/ui/edittagdialog.h" line 28, impact on 12 files + 6 : "src/playlist/playlistbackend.h" line 26, impact on 11 files + 7 : "src/songinfo/songinfobase.h" line 26, impact on 11 files + 8 : "src/playlist/songplaylistitem.h" line 21, impact on 7 files + 9 : "src/playlist/playlistitemmimedata.h" line 21, impact on 2 files + 10 : "src/playlist/playlistundocommands.h" line 24, impact on 2 files ... 10 of 14 details -3 : "src/smartplaylists/generator_fwd.h" impact on 166 file(s) +3 : "src/smartplaylists/generator_fwd.h" impact on 166 files Included by: - 1 : "src/playlist/playlist.h" line 28, impact on 129 file(s) - 2 : "src/playlist/playlistmanager.h" line 29, impact on 73 file(s) - 3 : "src/library/librarymodel.h" line 34, impact on 58 file(s) - 4 : "src/smartplaylists/generator.h" line 88, impact on 31 file(s) - 5 : "src/playlist/playlistbackend.h" line 27, impact on 11 file(s) - 6 : "src/songinfo/songinfobase.h" line 27, impact on 11 file(s) - 7 : "src/smartplaylists/generatormimedata.h" line 23, impact on 4 file(s) - 8 : "src/smartplaylists/wizardplugin.h" line 23, impact on 4 file(s) - 9 : "src/smartplaylists/generatorinserter.h" line 21, impact on 2 file(s) - 10 : "src/smartplaylists/wizard.h" line 21, impact on 2 file(s) + 1 : "src/playlist/playlist.h" line 28, impact on 129 files + 2 : "src/playlist/playlistmanager.h" line 29, impact on 73 files + 3 : "src/library/librarymodel.h" line 34, impact on 58 files + 4 : "src/smartplaylists/generator.h" line 88, impact on 31 files + 5 : "src/playlist/playlistbackend.h" line 27, impact on 11 files + 6 : "src/songinfo/songinfobase.h" line 27, impact on 11 files + 7 : "src/smartplaylists/generatormimedata.h" line 23, impact on 4 files + 8 : "src/smartplaylists/wizardplugin.h" line 23, impact on 4 files + 9 : "src/smartplaylists/generatorinserter.h" line 21, impact on 2 files + 10 : "src/smartplaylists/wizard.h" line 21, impact on 2 files ... 10 of 12 details -4 : "src/engines/engine_fwd.h" impact on 140 file(s) +4 : "src/engines/engine_fwd.h" impact on 140 files Included by: - 1 : "src/widgets/osd.h" line 28, impact on 76 file(s) - 2 : "src/library/librarymodel.h" line 32, impact on 58 file(s) - 3 : "src/engines/enginebase.h" line 34, impact on 29 file(s) - 4 : "src/ui/mainwindow.h" line 31, impact on 13 file(s) - 5 : "src/analyzers/analyzerbase.h" line 36, impact on 9 file(s) - 6 : "src/networkremote/outgoingdatacreator.h" line 16, impact on 3 file(s) - 7 : "src/engines/gstenginepipeline.h" line 33, impact on 2 file(s) - 8 : "src/analyzers/analyzercontainer.h" line 30, impact on 1 file(s) -5 : "src/playlist/playlist.h" impact on 129 file(s) + 1 : "src/widgets/osd.h" line 28, impact on 76 files + 2 : "src/library/librarymodel.h" line 32, impact on 58 files + 3 : "src/engines/enginebase.h" line 34, impact on 29 files + 4 : "src/ui/mainwindow.h" line 31, impact on 13 files + 5 : "src/analyzers/analyzerbase.h" line 36, impact on 9 files + 6 : "src/networkremote/outgoingdatacreator.h" line 16, impact on 3 files + 7 : "src/engines/gstenginepipeline.h" line 33, impact on 2 files + 8 : "src/analyzers/analyzercontainer.h" line 30, impact on 1 file +5 : "src/playlist/playlist.h" impact on 129 files Included by: - 1 : "src/playlist/playlistmanager.h" line 28, impact on 73 file(s) - 2 : "src/playlistparsers/parserbase.h" line 25, impact on 27 file(s) - 3 : "src/playlist/playlistview.h" line 27, impact on 10 file(s) - 4 : "src/playlistparsers/playlistparser.h" line 25, impact on 8 file(s) - 5 : "src/playlist/playlistdelegates.h" line 21, impact on 6 file(s) - 6 : "src/playlist/queue.h" line 21, impact on 6 file(s) - 7 : "src/networkremote/outgoingdatacreator.h" line 18, impact on 3 file(s) - 8 : "src/playlist/playlistfilter.h" line 24, impact on 2 file(s) - 9 : "src/playlist/playlistsaveoptionsdialog.h" line 23, impact on 2 file(s) - 10 : "src/smartplaylists/generatorinserter.h" line 26, impact on 2 file(s) + 1 : "src/playlist/playlistmanager.h" line 28, impact on 73 files + 2 : "src/playlistparsers/parserbase.h" line 25, impact on 27 files + 3 : "src/playlist/playlistview.h" line 27, impact on 10 files + 4 : "src/playlistparsers/playlistparser.h" line 25, impact on 8 files + 5 : "src/playlist/playlistdelegates.h" line 21, impact on 6 files + 6 : "src/playlist/queue.h" line 21, impact on 6 files + 7 : "src/networkremote/outgoingdatacreator.h" line 18, impact on 3 files + 8 : "src/playlist/playlistfilter.h" line 24, impact on 2 files + 9 : "src/playlist/playlistsaveoptionsdialog.h" line 23, impact on 2 files + 10 : "src/smartplaylists/generatorinserter.h" line 26, impact on 2 files ... 10 of 33 details -6 : "src/ui/iconloader.h" impact on 128 file(s) +6 : "src/ui/iconloader.h" impact on 128 files Included by: - 1 : "src/widgets/lineedit.h" line 25, impact on 14 file(s) - 2 : "src/internet/box/boxurlhandler.h" line 23, impact on 2 file(s) - 3 : "src/internet/dropbox/dropboxurlhandler.h" line 23, impact on 2 file(s) - 4 : "src/internet/googledrive/googledriveurlhandler.h" line 23, impact on 2 file(s) - 5 : "src/internet/magnatune/magnatuneurlhandler.h" line 24, impact on 2 file(s) - 6 : "src/internet/seafile/seafileurlhandler.h" line 23, impact on 2 file(s) - 7 : "src/internet/skydrive/skydriveurlhandler.h" line 23, impact on 2 file(s) - 8 : "src/internet/subsonic/subsonicurlhandler.h" line 24, impact on 2 file(s) + 1 : "src/widgets/lineedit.h" line 25, impact on 14 files + 2 : "src/internet/box/boxurlhandler.h" line 23, impact on 2 files + 3 : "src/internet/dropbox/dropboxurlhandler.h" line 23, impact on 2 files + 4 : "src/internet/googledrive/googledriveurlhandler.h" line 23, impact on 2 files + 5 : "src/internet/magnatune/magnatuneurlhandler.h" line 24, impact on 2 files + 6 : "src/internet/seafile/seafileurlhandler.h" line 23, impact on 2 files + 7 : "src/internet/skydrive/skydriveurlhandler.h" line 23, impact on 2 files + 8 : "src/internet/subsonic/subsonicurlhandler.h" line 24, impact on 2 files 9 : "src/covers/currentartloader.cpp" line 29 10 : "src/devices/deviceinfo.cpp" line 31 ... 10 of 114 details -7 : "src/covers/albumcoverloaderoptions.h" impact on 112 file(s) +7 : "src/covers/albumcoverloaderoptions.h" impact on 112 files Included by: - 1 : "src/library/librarymodel.h" line 31, impact on 58 file(s) - 2 : "src/globalsearch/globalsearch.h" line 25, impact on 21 file(s) - 3 : "src/covers/albumcoverloader.h" line 24, impact on 15 file(s) - 4 : "src/ui/edittagdialog.h" line 26, impact on 12 file(s) - 5 : "src/internet/podcasts/podcastdiscoverymodel.h" line 23, impact on 10 file(s) - 6 : "src/ui/albumcovermanager.h" line 28, impact on 7 file(s) - 7 : "src/covers/currentartloader.h" line 28, impact on 6 file(s) - 8 : "src/ui/albumcoversearcher.h" line 26, impact on 3 file(s) - 9 : "src/ui/standarditemiconloader.h" line 21, impact on 3 file(s) - 10 : "src/internet/podcasts/podcastinfowidget.h" line 24, impact on 1 file(s) + 1 : "src/library/librarymodel.h" line 31, impact on 58 files + 2 : "src/globalsearch/globalsearch.h" line 25, impact on 21 files + 3 : "src/covers/albumcoverloader.h" line 24, impact on 15 files + 4 : "src/ui/edittagdialog.h" line 26, impact on 12 files + 5 : "src/internet/podcasts/podcastdiscoverymodel.h" line 23, impact on 10 files + 6 : "src/ui/albumcovermanager.h" line 28, impact on 7 files + 7 : "src/covers/currentartloader.h" line 28, impact on 6 files + 8 : "src/ui/albumcoversearcher.h" line 26, impact on 3 files + 9 : "src/ui/standarditemiconloader.h" line 21, impact on 3 files + 10 : "src/internet/podcasts/podcastinfowidget.h" line 24, impact on 1 file ... 10 of 12 details -8 : "src/library/directory.h" impact on 92 file(s) +8 : "src/library/directory.h" impact on 92 files Included by: - 1 : "src/library/librarywatcher.h" line 21, impact on 60 file(s) - 2 : "src/library/librarybackend.h" line 26, impact on 59 file(s) - 3 : "src/library/librarydirectorymodel.h" line 26, impact on 9 file(s) - 4 : "tests/metatypes_env.h" line 28, impact on 1 file(s) -9 : "src/library/libraryquery.h" impact on 90 file(s) + 1 : "src/library/librarywatcher.h" line 21, impact on 60 files + 2 : "src/library/librarybackend.h" line 26, impact on 59 files + 3 : "src/library/librarydirectorymodel.h" line 26, impact on 9 files + 4 : "tests/metatypes_env.h" line 28, impact on 1 file +9 : "src/library/libraryquery.h" impact on 90 files Included by: - 1 : "src/library/librarybackend.h" line 27, impact on 59 file(s) - 2 : "src/library/librarymodel.h" line 26, impact on 58 file(s) + 1 : "src/library/librarybackend.h" line 27, impact on 59 files + 2 : "src/library/librarymodel.h" line 26, impact on 58 files 3 : "src/globalsearch/librarysearchprovider.cpp" line 22 4 : "src/library/librarybackend.cpp" line 19 5 : "src/library/libraryfilterwidget.cpp" line 20 @@ -102,11 +102,11 @@ Included by: 7 : "src/library/sqlrow.cpp" line 18 8 : "src/playlistparsers/parserbase.cpp" line 21 9 : "src/ui/albumcovermanager.cpp" line 31 -10 : "src/widgets/osd.h" impact on 76 file(s) +10 : "src/widgets/osd.h" impact on 76 files Included by: - 1 : "src/ui/settingspage.h" line 23, impact on 52 file(s) - 2 : "src/ui/settingsdialog.h" line 25, impact on 34 file(s) - 3 : "src/wiimotedev/shortcuts.h" line 27, impact on 3 file(s) + 1 : "src/ui/settingspage.h" line 23, impact on 52 files + 2 : "src/ui/settingsdialog.h" line 25, impact on 34 files + 3 : "src/wiimotedev/shortcuts.h" line 27, impact on 3 files 4 : "src/main.cpp" line 67 5 : "src/ui/mainwindow.cpp" line 122 6 : "src/widgets/osd.cpp" line 22 diff --git a/docs/examples/clementine/output_win.txt b/docs/examples/clementine/output_win.txt index 7b4b3cb..58c1813 100644 --- a/docs/examples/clementine/output_win.txt +++ b/docs/examples/clementine/output_win.txt @@ -2,99 +2,99 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "src\playlist\playlistsequence.h" impact on 185 file(s) +1 : "src\playlist\playlistsequence.h" impact on 185 files Included by: - 1 : "src\playlist\playlist.h" line 25, impact on 129 file(s) - 2 : "src\widgets\osd.h" line 30, impact on 76 file(s) + 1 : "src\playlist\playlist.h" line 25, impact on 129 files + 2 : "src\widgets\osd.h" line 30, impact on 76 files 3 : "src\networkremote\incomingdataparser.cpp" line 27 4 : "src\playlist\playlistsequence.cpp" line 18 5 : "src\ui\mainwindow.cpp" line 88 6 : "tests\mpris1_test.cpp" line 24 -2 : "src\playlist\playlistitem.h" impact on 179 file(s) +2 : "src\playlist\playlistitem.h" impact on 179 files Included by: - 1 : "src\playlist\playlist.h" line 24, impact on 129 file(s) - 2 : "src\smartplaylists\generator.h" line 21, impact on 31 file(s) - 3 : "src\ui\mainwindow.h" line 33, impact on 13 file(s) - 4 : "src\library\libraryplaylistitem.h" line 22, impact on 12 file(s) - 5 : "src\ui\edittagdialog.h" line 28, impact on 12 file(s) - 6 : "src\playlist\playlistbackend.h" line 26, impact on 11 file(s) - 7 : "src\songinfo\songinfobase.h" line 26, impact on 11 file(s) - 8 : "src\playlist\songplaylistitem.h" line 21, impact on 7 file(s) - 9 : "src\playlist\playlistitemmimedata.h" line 21, impact on 2 file(s) - 10 : "src\playlist\playlistundocommands.h" line 24, impact on 2 file(s) + 1 : "src\playlist\playlist.h" line 24, impact on 129 files + 2 : "src\smartplaylists\generator.h" line 21, impact on 31 files + 3 : "src\ui\mainwindow.h" line 33, impact on 13 files + 4 : "src\library\libraryplaylistitem.h" line 22, impact on 12 files + 5 : "src\ui\edittagdialog.h" line 28, impact on 12 files + 6 : "src\playlist\playlistbackend.h" line 26, impact on 11 files + 7 : "src\songinfo\songinfobase.h" line 26, impact on 11 files + 8 : "src\playlist\songplaylistitem.h" line 21, impact on 7 files + 9 : "src\playlist\playlistitemmimedata.h" line 21, impact on 2 files + 10 : "src\playlist\playlistundocommands.h" line 24, impact on 2 files ... 10 of 14 details -3 : "src\smartplaylists\generator_fwd.h" impact on 166 file(s) +3 : "src\smartplaylists\generator_fwd.h" impact on 166 files Included by: - 1 : "src\playlist\playlist.h" line 28, impact on 129 file(s) - 2 : "src\playlist\playlistmanager.h" line 29, impact on 73 file(s) - 3 : "src\library\librarymodel.h" line 34, impact on 58 file(s) - 4 : "src\smartplaylists\generator.h" line 88, impact on 31 file(s) - 5 : "src\playlist\playlistbackend.h" line 27, impact on 11 file(s) - 6 : "src\songinfo\songinfobase.h" line 27, impact on 11 file(s) - 7 : "src\smartplaylists\generatormimedata.h" line 23, impact on 4 file(s) - 8 : "src\smartplaylists\wizardplugin.h" line 23, impact on 4 file(s) - 9 : "src\smartplaylists\generatorinserter.h" line 21, impact on 2 file(s) - 10 : "src\smartplaylists\wizard.h" line 21, impact on 2 file(s) + 1 : "src\playlist\playlist.h" line 28, impact on 129 files + 2 : "src\playlist\playlistmanager.h" line 29, impact on 73 files + 3 : "src\library\librarymodel.h" line 34, impact on 58 files + 4 : "src\smartplaylists\generator.h" line 88, impact on 31 files + 5 : "src\playlist\playlistbackend.h" line 27, impact on 11 files + 6 : "src\songinfo\songinfobase.h" line 27, impact on 11 files + 7 : "src\smartplaylists\generatormimedata.h" line 23, impact on 4 files + 8 : "src\smartplaylists\wizardplugin.h" line 23, impact on 4 files + 9 : "src\smartplaylists\generatorinserter.h" line 21, impact on 2 files + 10 : "src\smartplaylists\wizard.h" line 21, impact on 2 files ... 10 of 12 details -4 : "src\engines\engine_fwd.h" impact on 140 file(s) +4 : "src\engines\engine_fwd.h" impact on 140 files Included by: - 1 : "src\widgets\osd.h" line 28, impact on 76 file(s) - 2 : "src\library\librarymodel.h" line 32, impact on 58 file(s) - 3 : "src\engines\enginebase.h" line 34, impact on 29 file(s) - 4 : "src\ui\mainwindow.h" line 31, impact on 13 file(s) - 5 : "src\analyzers\analyzerbase.h" line 36, impact on 9 file(s) - 6 : "src\networkremote\outgoingdatacreator.h" line 16, impact on 3 file(s) - 7 : "src\engines\gstenginepipeline.h" line 33, impact on 2 file(s) - 8 : "src\analyzers\analyzercontainer.h" line 30, impact on 1 file(s) -5 : "src\playlist\playlist.h" impact on 129 file(s) + 1 : "src\widgets\osd.h" line 28, impact on 76 files + 2 : "src\library\librarymodel.h" line 32, impact on 58 files + 3 : "src\engines\enginebase.h" line 34, impact on 29 files + 4 : "src\ui\mainwindow.h" line 31, impact on 13 files + 5 : "src\analyzers\analyzerbase.h" line 36, impact on 9 files + 6 : "src\networkremote\outgoingdatacreator.h" line 16, impact on 3 files + 7 : "src\engines\gstenginepipeline.h" line 33, impact on 2 files + 8 : "src\analyzers\analyzercontainer.h" line 30, impact on 1 file +5 : "src\playlist\playlist.h" impact on 129 files Included by: - 1 : "src\playlist\playlistmanager.h" line 28, impact on 73 file(s) - 2 : "src\playlistparsers\parserbase.h" line 25, impact on 27 file(s) - 3 : "src\playlist\playlistview.h" line 27, impact on 10 file(s) - 4 : "src\playlistparsers\playlistparser.h" line 25, impact on 8 file(s) - 5 : "src\playlist\playlistdelegates.h" line 21, impact on 6 file(s) - 6 : "src\playlist\queue.h" line 21, impact on 6 file(s) - 7 : "src\networkremote\outgoingdatacreator.h" line 18, impact on 3 file(s) - 8 : "src\playlist\playlistfilter.h" line 24, impact on 2 file(s) - 9 : "src\playlist\playlistsaveoptionsdialog.h" line 23, impact on 2 file(s) - 10 : "src\smartplaylists\generatorinserter.h" line 26, impact on 2 file(s) + 1 : "src\playlist\playlistmanager.h" line 28, impact on 73 files + 2 : "src\playlistparsers\parserbase.h" line 25, impact on 27 files + 3 : "src\playlist\playlistview.h" line 27, impact on 10 files + 4 : "src\playlistparsers\playlistparser.h" line 25, impact on 8 files + 5 : "src\playlist\playlistdelegates.h" line 21, impact on 6 files + 6 : "src\playlist\queue.h" line 21, impact on 6 files + 7 : "src\networkremote\outgoingdatacreator.h" line 18, impact on 3 files + 8 : "src\playlist\playlistfilter.h" line 24, impact on 2 files + 9 : "src\playlist\playlistsaveoptionsdialog.h" line 23, impact on 2 files + 10 : "src\smartplaylists\generatorinserter.h" line 26, impact on 2 files ... 10 of 33 details -6 : "src\ui\iconloader.h" impact on 128 file(s) +6 : "src\ui\iconloader.h" impact on 128 files Included by: - 1 : "src\widgets\lineedit.h" line 25, impact on 14 file(s) - 2 : "src\internet\box\boxurlhandler.h" line 23, impact on 2 file(s) - 3 : "src\internet\dropbox\dropboxurlhandler.h" line 23, impact on 2 file(s) - 4 : "src\internet\googledrive\googledriveurlhandler.h" line 23, impact on 2 file(s) - 5 : "src\internet\magnatune\magnatuneurlhandler.h" line 24, impact on 2 file(s) - 6 : "src\internet\seafile\seafileurlhandler.h" line 23, impact on 2 file(s) - 7 : "src\internet\skydrive\skydriveurlhandler.h" line 23, impact on 2 file(s) - 8 : "src\internet\subsonic\subsonicurlhandler.h" line 24, impact on 2 file(s) + 1 : "src\widgets\lineedit.h" line 25, impact on 14 files + 2 : "src\internet\box\boxurlhandler.h" line 23, impact on 2 files + 3 : "src\internet\dropbox\dropboxurlhandler.h" line 23, impact on 2 files + 4 : "src\internet\googledrive\googledriveurlhandler.h" line 23, impact on 2 files + 5 : "src\internet\magnatune\magnatuneurlhandler.h" line 24, impact on 2 files + 6 : "src\internet\seafile\seafileurlhandler.h" line 23, impact on 2 files + 7 : "src\internet\skydrive\skydriveurlhandler.h" line 23, impact on 2 files + 8 : "src\internet\subsonic\subsonicurlhandler.h" line 24, impact on 2 files 9 : "src\covers\currentartloader.cpp" line 29 10 : "src\devices\deviceinfo.cpp" line 31 ... 10 of 114 details -7 : "src\covers\albumcoverloaderoptions.h" impact on 112 file(s) +7 : "src\covers\albumcoverloaderoptions.h" impact on 112 files Included by: - 1 : "src\library\librarymodel.h" line 31, impact on 58 file(s) - 2 : "src\globalsearch\globalsearch.h" line 25, impact on 21 file(s) - 3 : "src\covers\albumcoverloader.h" line 24, impact on 15 file(s) - 4 : "src\ui\edittagdialog.h" line 26, impact on 12 file(s) - 5 : "src\internet\podcasts\podcastdiscoverymodel.h" line 23, impact on 10 file(s) - 6 : "src\ui\albumcovermanager.h" line 28, impact on 7 file(s) - 7 : "src\covers\currentartloader.h" line 28, impact on 6 file(s) - 8 : "src\ui\albumcoversearcher.h" line 26, impact on 3 file(s) - 9 : "src\ui\standarditemiconloader.h" line 21, impact on 3 file(s) - 10 : "src\internet\podcasts\podcastinfowidget.h" line 24, impact on 1 file(s) + 1 : "src\library\librarymodel.h" line 31, impact on 58 files + 2 : "src\globalsearch\globalsearch.h" line 25, impact on 21 files + 3 : "src\covers\albumcoverloader.h" line 24, impact on 15 files + 4 : "src\ui\edittagdialog.h" line 26, impact on 12 files + 5 : "src\internet\podcasts\podcastdiscoverymodel.h" line 23, impact on 10 files + 6 : "src\ui\albumcovermanager.h" line 28, impact on 7 files + 7 : "src\covers\currentartloader.h" line 28, impact on 6 files + 8 : "src\ui\albumcoversearcher.h" line 26, impact on 3 files + 9 : "src\ui\standarditemiconloader.h" line 21, impact on 3 files + 10 : "src\internet\podcasts\podcastinfowidget.h" line 24, impact on 1 file ... 10 of 12 details -8 : "src\library\directory.h" impact on 92 file(s) +8 : "src\library\directory.h" impact on 92 files Included by: - 1 : "src\library\librarywatcher.h" line 21, impact on 60 file(s) - 2 : "src\library\librarybackend.h" line 26, impact on 59 file(s) - 3 : "src\library\librarydirectorymodel.h" line 26, impact on 9 file(s) - 4 : "tests\metatypes_env.h" line 28, impact on 1 file(s) -9 : "src\library\libraryquery.h" impact on 90 file(s) + 1 : "src\library\librarywatcher.h" line 21, impact on 60 files + 2 : "src\library\librarybackend.h" line 26, impact on 59 files + 3 : "src\library\librarydirectorymodel.h" line 26, impact on 9 files + 4 : "tests\metatypes_env.h" line 28, impact on 1 file +9 : "src\library\libraryquery.h" impact on 90 files Included by: - 1 : "src\library\librarybackend.h" line 27, impact on 59 file(s) - 2 : "src\library\librarymodel.h" line 26, impact on 58 file(s) + 1 : "src\library\librarybackend.h" line 27, impact on 59 files + 2 : "src\library\librarymodel.h" line 26, impact on 58 files 3 : "src\globalsearch\librarysearchprovider.cpp" line 22 4 : "src\library\librarybackend.cpp" line 19 5 : "src\library\libraryfilterwidget.cpp" line 20 @@ -102,11 +102,11 @@ Included by: 7 : "src\library\sqlrow.cpp" line 18 8 : "src\playlistparsers\parserbase.cpp" line 21 9 : "src\ui\albumcovermanager.cpp" line 31 -10 : "src\widgets\osd.h" impact on 76 file(s) +10 : "src\widgets\osd.h" impact on 76 files Included by: - 1 : "src\ui\settingspage.h" line 23, impact on 52 file(s) - 2 : "src\ui\settingsdialog.h" line 25, impact on 34 file(s) - 3 : "src\wiimotedev\shortcuts.h" line 27, impact on 3 file(s) + 1 : "src\ui\settingspage.h" line 23, impact on 52 files + 2 : "src\ui\settingsdialog.h" line 25, impact on 34 files + 3 : "src\wiimotedev\shortcuts.h" line 27, impact on 3 files 4 : "src\main.cpp" line 67 5 : "src\ui\mainwindow.cpp" line 122 6 : "src\widgets\osd.cpp" line 22 diff --git a/docs/examples/cmake/output_unix.txt b/docs/examples/cmake/output_unix.txt index 8576d36..ac65c20 100644 --- a/docs/examples/cmake/output_unix.txt +++ b/docs/examples/cmake/output_unix.txt @@ -2,52 +2,52 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "build/Source/cmsys/Configure.hxx" impact on 832 file(s) +1 : "build/Source/cmsys/Configure.hxx" impact on 832 files Included by: - 1 : "build/Source/cmConfigure.h" line 5, impact on 831 file(s) -2 : "build/Source/cmConfigure.h" impact on 831 file(s) + 1 : "build/Source/cmConfigure.h" line 5, impact on 831 files +2 : "build/Source/cmConfigure.h" impact on 831 files Included by: - 1 : "CMake/Source/cmProcessOutput.h" line 5, impact on 447 file(s) - 2 : "CMake/Source/cmCryptoHash.h" line 5, impact on 436 file(s) - 3 : "CMake/Source/cmSystemTools.h" line 5, impact on 432 file(s) - 4 : "CMake/Source/cmLinkedTree.h" line 5, impact on 370 file(s) - 5 : "CMake/Source/cmStateTypes.h" line 6, impact on 367 file(s) - 6 : "CMake/Source/cmPolicies.h" line 5, impact on 332 file(s) - 7 : "CMake/Source/cmStateSnapshot.h" line 6, impact on 329 file(s) - 8 : "CMake/Source/cmListFileCache.h" line 5, impact on 326 file(s) - 9 : "CMake/Source/cmRange.h" line 5, impact on 321 file(s) - 10 : "CMake/Source/cmStringAlgorithms.h" line 5, impact on 317 file(s) + 1 : "CMake/Source/cmProcessOutput.h" line 5, impact on 447 files + 2 : "CMake/Source/cmCryptoHash.h" line 5, impact on 436 files + 3 : "CMake/Source/cmSystemTools.h" line 5, impact on 432 files + 4 : "CMake/Source/cmLinkedTree.h" line 5, impact on 370 files + 5 : "CMake/Source/cmStateTypes.h" line 6, impact on 367 files + 6 : "CMake/Source/cmPolicies.h" line 5, impact on 332 files + 7 : "CMake/Source/cmStateSnapshot.h" line 6, impact on 329 files + 8 : "CMake/Source/cmListFileCache.h" line 5, impact on 326 files + 9 : "CMake/Source/cmRange.h" line 5, impact on 321 files + 10 : "CMake/Source/cmStringAlgorithms.h" line 5, impact on 317 files ... 10 of 393 details -3 : "CMake/Source/cmProcessOutput.h" impact on 447 file(s) +3 : "CMake/Source/cmProcessOutput.h" impact on 447 files Included by: - 1 : "CMake/Source/cmSystemTools.h" line 19, impact on 432 file(s) - 2 : "CMake/Source/cmCTest.h" line 18, impact on 65 file(s) - 3 : "CMake/Source/cmProcessTools.h" line 11, impact on 19 file(s) - 4 : "CMake/Source/CTest/cmCTestVC.h" line 10, impact on 17 file(s) - 5 : "CMake/Source/CTest/cmProcess.h" line 18, impact on 4 file(s) - 6 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 19, impact on 3 file(s) + 1 : "CMake/Source/cmSystemTools.h" line 19, impact on 432 files + 2 : "CMake/Source/cmCTest.h" line 18, impact on 65 files + 3 : "CMake/Source/cmProcessTools.h" line 11, impact on 19 files + 4 : "CMake/Source/CTest/cmCTestVC.h" line 10, impact on 17 files + 5 : "CMake/Source/CTest/cmProcess.h" line 18, impact on 4 files + 6 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 19, impact on 3 files 7 : "CMake/Source/CTest/cmCTestBuildHandler.cxx" line 22 8 : "CMake/Source/CTest/cmCTestGIT.cxx" line 17 9 : "CMake/Source/CTest/cmCTestLaunch.cxx" line 15 10 : "CMake/Source/cmCTest.cxx" line 56 ... 10 of 18 details -4 : "CMake/Source/cmDuration.h" impact on 437 file(s) +4 : "CMake/Source/cmDuration.h" impact on 437 files Included by: - 1 : "CMake/Source/cmSystemTools.h" line 18, impact on 432 file(s) - 2 : "CMake/Source/cmGlobalGenerator.h" line 22, impact on 115 file(s) - 3 : "CMake/Source/cmCTest.h" line 17, impact on 65 file(s) - 4 : "CMake/Source/CTest/cmCTestTestHandler.h" line 23, impact on 17 file(s) - 5 : "CMake/Source/CTest/cmCTestScriptHandler.h" line 13, impact on 7 file(s) - 6 : "CMake/Source/CTest/cmProcess.h" line 17, impact on 4 file(s) - 7 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 18, impact on 3 file(s) - 8 : "CMake/Source/CTest/cmCTestRunTest.h" line 18, impact on 3 file(s) - 9 : "CMake/Source/CTest/cmCTestBuildAndTestHandler.h" line 14, impact on 2 file(s) + 1 : "CMake/Source/cmSystemTools.h" line 18, impact on 432 files + 2 : "CMake/Source/cmGlobalGenerator.h" line 22, impact on 115 files + 3 : "CMake/Source/cmCTest.h" line 17, impact on 65 files + 4 : "CMake/Source/CTest/cmCTestTestHandler.h" line 23, impact on 17 files + 5 : "CMake/Source/CTest/cmCTestScriptHandler.h" line 13, impact on 7 files + 6 : "CMake/Source/CTest/cmProcess.h" line 17, impact on 4 files + 7 : "CMake/Source/CTest/cmCTestBuildHandler.h" line 18, impact on 3 files + 8 : "CMake/Source/CTest/cmCTestRunTest.h" line 18, impact on 3 files + 9 : "CMake/Source/CTest/cmCTestBuildAndTestHandler.h" line 14, impact on 2 files 10 : "CMake/Source/CPack/IFW/cmCPackIFWGenerator.cxx" line 15 ... 10 of 30 details -5 : "CMake/Source/cmCryptoHash.h" impact on 436 file(s) +5 : "CMake/Source/cmCryptoHash.h" impact on 436 files Included by: - 1 : "CMake/Source/cmSystemTools.h" line 17, impact on 432 file(s) - 2 : "CMake/Source/cmcmd.h" line 11, impact on 2 file(s) + 1 : "CMake/Source/cmSystemTools.h" line 17, impact on 432 files + 2 : "CMake/Source/cmcmd.h" line 11, impact on 2 files 3 : "CMake/Source/CPack/cmCPackDebGenerator.cxx" line 19 4 : "CMake/Source/CPack/cmCPackGenerator.cxx" line 16 5 : "CMake/Source/CTest/cmCTestLaunchReporter.cxx" line 9 @@ -57,14 +57,14 @@ Included by: 9 : "CMake/Source/cmFileAPICodemodel.cxx" line 22 10 : "CMake/Source/cmFileCommand.cxx" line 32 ... 10 of 19 details -6 : "build/Source/cmsys/SystemTools.hxx" impact on 435 file(s) +6 : "build/Source/cmsys/SystemTools.hxx" impact on 435 files Included by: - 1 : "CMake/Source/cmSystemTools.h" line 15, impact on 432 file(s) - 2 : "CMake/Source/cmUtils.hxx" line 5, impact on 2 file(s) + 1 : "CMake/Source/cmSystemTools.h" line 15, impact on 432 files + 2 : "CMake/Source/cmUtils.hxx" line 5, impact on 2 files 3 : "CMake/Source/cmFileMonitor.cxx" line 12 -7 : "build/Source/cmsys/Process.h" impact on 434 file(s) +7 : "build/Source/cmsys/Process.h" impact on 434 files Included by: - 1 : "CMake/Source/cmSystemTools.h" line 14, impact on 432 file(s) + 1 : "CMake/Source/cmSystemTools.h" line 14, impact on 432 files 2 : "CMake/Source/CTest/cmCTestBuildAndTestHandler.cxx" line 10 3 : "CMake/Source/CTest/cmCTestBuildHandler.cxx" line 14 4 : "CMake/Source/CTest/cmCTestCoverageHandler.cxx" line 19 @@ -75,38 +75,38 @@ Included by: 9 : "CMake/Source/CTest/cmCTestVC.cxx" line 10 10 : "CMake/Source/CTest/cmProcess.cxx" line 12 ... 10 of 15 details -8 : "CMake/Source/cmSystemTools.h" impact on 432 file(s) +8 : "CMake/Source/cmSystemTools.h" impact on 432 files Included by: - 1 : "CMake/Source/cmListFileCache.h" line 17, impact on 326 file(s) - 2 : "CMake/Source/cmGlobalGenerator.h" line 26, impact on 115 file(s) - 3 : "CMake/Source/cmLinkItem.h" line 15, impact on 70 file(s) - 4 : "CMake/Source/CTest/cmCTestGenericHandler.h" line 14, impact on 53 file(s) - 5 : "CMake/Source/CPack/cmCPackGenerator.h" line 15, impact on 33 file(s) - 6 : "CMake/Source/cmTargetPropertyComputer.h" line 13, impact on 3 file(s) - 7 : "CMake/Source/cmFileLockUnix.cxx" line 10, impact on 1 file(s) - 8 : "CMake/Source/cmFileLockWin32.cxx" line 6, impact on 1 file(s) + 1 : "CMake/Source/cmListFileCache.h" line 17, impact on 326 files + 2 : "CMake/Source/cmGlobalGenerator.h" line 26, impact on 115 files + 3 : "CMake/Source/cmLinkItem.h" line 15, impact on 70 files + 4 : "CMake/Source/CTest/cmCTestGenericHandler.h" line 14, impact on 53 files + 5 : "CMake/Source/CPack/cmCPackGenerator.h" line 15, impact on 33 files + 6 : "CMake/Source/cmTargetPropertyComputer.h" line 13, impact on 3 files + 7 : "CMake/Source/cmFileLockUnix.cxx" line 10, impact on 1 file + 8 : "CMake/Source/cmFileLockWin32.cxx" line 6, impact on 1 file 9 : "CMake/Source/CPack/IFW/cmCPackIFWCommon.cxx" line 14 10 : "CMake/Source/CPack/IFW/cmCPackIFWGenerator.cxx" line 18 ... 10 of 250 details -9 : "CMake/Source/cmLinkedTree.h" impact on 370 file(s) +9 : "CMake/Source/cmLinkedTree.h" impact on 370 files Included by: - 1 : "CMake/Source/cmStateTypes.h" line 8, impact on 367 file(s) - 2 : "CMake/Source/cmStateSnapshot.h" line 13, impact on 329 file(s) - 3 : "CMake/Source/cmDefinitions.h" line 14, impact on 123 file(s) - 4 : "CMake/Source/cmStatePrivate.h" line 12, impact on 121 file(s) - 5 : "CMake/Source/cmState.h" line 15, impact on 105 file(s) - 6 : "CMake/Source/cmStateDirectory.h" line 12, impact on 34 file(s) -10 : "CMake/Source/cmStateTypes.h" impact on 367 file(s) + 1 : "CMake/Source/cmStateTypes.h" line 8, impact on 367 files + 2 : "CMake/Source/cmStateSnapshot.h" line 13, impact on 329 files + 3 : "CMake/Source/cmDefinitions.h" line 14, impact on 123 files + 4 : "CMake/Source/cmStatePrivate.h" line 12, impact on 121 files + 5 : "CMake/Source/cmState.h" line 15, impact on 105 files + 6 : "CMake/Source/cmStateDirectory.h" line 12, impact on 34 files +10 : "CMake/Source/cmStateTypes.h" impact on 367 files Included by: - 1 : "CMake/Source/cmStateSnapshot.h" line 15, impact on 329 file(s) - 2 : "CMake/Source/cmTarget.h" line 18, impact on 235 file(s) - 3 : "CMake/Source/cmMakefile.h" line 32, impact on 201 file(s) - 4 : "CMake/Source/cmStatePrivate.h" line 17, impact on 121 file(s) - 5 : "CMake/Source/cmState.h" line 22, impact on 105 file(s) - 6 : "CMake/Source/cmake.h" line 27, impact on 75 file(s) - 7 : "CMake/Source/cmGeneratorTarget.h" line 21, impact on 66 file(s) - 8 : "CMake/Source/cmBinUtilsLinker.h" line 8, impact on 18 file(s) - 9 : "CMake/Source/CursesDialog/cmCursesWidget.h" line 10, impact on 17 file(s) - 10 : "CMake/Source/cmExportFileGenerator.h" line 14, impact on 16 file(s) + 1 : "CMake/Source/cmStateSnapshot.h" line 15, impact on 329 files + 2 : "CMake/Source/cmTarget.h" line 18, impact on 235 files + 3 : "CMake/Source/cmMakefile.h" line 32, impact on 201 files + 4 : "CMake/Source/cmStatePrivate.h" line 17, impact on 121 files + 5 : "CMake/Source/cmState.h" line 22, impact on 105 files + 6 : "CMake/Source/cmake.h" line 27, impact on 75 files + 7 : "CMake/Source/cmGeneratorTarget.h" line 21, impact on 66 files + 8 : "CMake/Source/cmBinUtilsLinker.h" line 8, impact on 18 files + 9 : "CMake/Source/CursesDialog/cmCursesWidget.h" line 10, impact on 17 files + 10 : "CMake/Source/cmExportFileGenerator.h" line 14, impact on 16 files ... 10 of 104 details ... 10 of 892 files diff --git a/docs/examples/cppinclude/output_unix.txt b/docs/examples/cppinclude/output_unix.txt index 9bcba01..245cad1 100644 --- a/docs/examples/cppinclude/output_unix.txt +++ b/docs/examples/cppinclude/output_unix.txt @@ -2,22 +2,22 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "exception/api/exc_exception.hpp" impact on 86 file(s) +1 : "exception/api/exc_exception.hpp" impact on 89 files Included by: - 1 : "exception/ih/exc_exception_impl.hpp" line 3, impact on 79 file(s) - 2 : "application/exceptions/app_exceptions.hpp" line 3, impact on 12 file(s) - 3 : "fs/api/fs_exceptions.hpp" line 3, impact on 9 file(s) - 4 : "project/api/prj_exceptions.hpp" line 3, impact on 4 file(s) - 5 : "reporter/exceptions/rp_exceptions.hpp" line 3, impact on 4 file(s) -2 : "exception/ih/exc_exception_impl.hpp" impact on 79 file(s) + 1 : "exception/ih/exc_exception_impl.hpp" line 3, impact on 81 files + 2 : "application/exceptions/app_exceptions.hpp" line 3, impact on 16 files + 3 : "fs/api/fs_exceptions.hpp" line 3, impact on 9 files + 4 : "project/api/prj_exceptions.hpp" line 3, impact on 4 files + 5 : "reporter/exceptions/rp_exceptions.hpp" line 3, impact on 4 files +2 : "exception/ih/exc_exception_impl.hpp" impact on 81 files Included by: - 1 : "exception/ih/exc_internal_error.hpp" line 3, impact on 51 file(s) - 2 : "exception/ih/exc_exception_with_message_impl.hpp" line 3, impact on 10 file(s) - 3 : "fs/impl/exceptions/fs_base_exception_impl.hpp" line 5, impact on 7 file(s) - 4 : "application/exceptions/app_base_exception_impl.hpp" line 3, impact on 3 file(s) - 5 : "project/impl/exceptions/prj_base_exception_impl.hpp" line 5, impact on 3 file(s) - 6 : "reporter/exceptions/rp_base_exception_impl.hpp" line 3, impact on 3 file(s) -3 : "exception/ih/exc_internal_error.hpp" impact on 51 file(s) + 1 : "exception/ih/exc_internal_error.hpp" line 3, impact on 51 files + 2 : "exception/ih/exc_exception_with_message_impl.hpp" line 3, impact on 13 files + 3 : "fs/impl/exceptions/fs_base_exception_impl.hpp" line 5, impact on 7 files + 4 : "application/exceptions/app_base_exception_impl.hpp" line 3, impact on 3 files + 5 : "project/impl/exceptions/prj_base_exception_impl.hpp" line 5, impact on 3 files + 6 : "reporter/exceptions/rp_base_exception_impl.hpp" line 3, impact on 3 files +3 : "exception/ih/exc_internal_error.hpp" impact on 51 files Included by: 1 : "application/exceptions/app_cant_create_report_impl.cpp" line 8 2 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 18 @@ -30,23 +30,10 @@ Included by: 9 : "application/tools/app_configuration_file.cpp" line 5 10 : "application/tools/app_configuration_file_loader.cpp" line 9 ... 10 of 51 details -4 : "test_tools/test_macros.hpp" impact on 22 file(s) +4 : "reporter/api/enums/rp_reporter_kind.hpp" impact on 19 files Included by: - 1 : "application/test/suits/app_test_cmake_project_builder.cpp" line 7 - 2 : "application/test/suits/app_test_configuration_file_suits.cpp" line 3 - 3 : "application/test/suits/app_test_parser_arguments.cpp" line 3 - 4 : "application/test/suits/app_test_parser_arguments_wrapper_suits.cpp" line 9 - 5 : "application/test/suits/app_test_project_builder.cpp" line 5 - 6 : "application/test/suits/app_test_report_settings_loader.cpp" line 3 - 7 : "cmake_project/test/suits/cprj_test_includes_parser.cpp" line 3 - 8 : "cmake_project/test/suits/cprj_test_loader.cpp" line 3 - 9 : "compilation_db/test/suits/cdb_test_suits.cpp" line 6 - 10 : "json/test/suits/json_test_suits.cpp" line 7 - ... 10 of 22 details -5 : "reporter/api/enums/rp_reporter_kind.hpp" impact on 19 file(s) -Included by: - 1 : "application/exceptions/app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) - 2 : "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) + 1 : "application/exceptions/app_cant_create_report_impl.hpp" line 6, impact on 2 files + 2 : "application/test/fixtures/app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 files 3 : "application/resources/app_resources_arguments.cpp" line 10 4 : "application/test/fixtures/app_test_configuration_file_fixture.cpp" line 10 5 : "application/test/fixtures/app_test_parser_wrapper_fixture.cpp" line 6 @@ -56,10 +43,10 @@ Included by: 9 : "reporter/impl/different_type_reporter/rp_different_type_reporter.cpp" line 3 10 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 3 ... 10 of 15 details -6 : "model_includes/api/enums/mi_file_type.hpp" impact on 18 file(s) +5 : "model_includes/api/enums/mi_file_type.hpp" impact on 18 files Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) - 2 : "model_includes/impl/mi_file_impl.hpp" line 3, impact on 2 file(s) + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 3, impact on 6 files + 2 : "model_includes/impl/mi_file_impl.hpp" line 3, impact on 2 files 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 3 4 : "model_includes/impl/mi_resolver.cpp" line 3 5 : "model_includes/test/fixtures/mi_test_model_includes_fixture.cpp" line 5 @@ -69,45 +56,53 @@ Included by: 9 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 6 10 : "reporter/impl/most_impact_reporter/rp_most_impact_reporter.cpp" line 10 ... 10 of 11 details -7 : "model_includes/api/enums/mi_include_status.hpp" impact on 17 file(s) +6 : "application/resources/app_resources_exceptions.hpp" impact on 17 files +Included by: + 1 : "application/exceptions/app_base_exception_with_message_impl.hpp" line 3, impact on 12 files + 2 : "application/exceptions/app_base_exception_impl.hpp" line 5, impact on 3 files + 3 : "application/exceptions/app_cant_create_analyzer.cpp" line 3 + 4 : "application/exceptions/app_cant_create_model_impl.cpp" line 2 + 5 : "application/exceptions/app_cant_create_project_impl.cpp" line 3 + 6 : "application/exceptions/app_cant_create_report_impl.cpp" line 4 + 7 : "application/exceptions/app_cant_load_reporter_settings.cpp" line 3 + 8 : "application/exceptions/app_incorrect_thousands_separator_impl.cpp" line 3 + 9 : "application/resources/app_resources_exceptions.cpp" line 1 +7 : "model_includes/api/enums/mi_include_status.hpp" impact on 17 files Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) - 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 4, impact on 6 files + 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 5, impact on 5 files 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 4 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 6 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 7 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 7 7 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 7 8 : "reporter/impl/unresolved_reporter/rp_unresolved_reporter.cpp" line 11 -8 : "model_includes/api/enums/mi_include_type.hpp" impact on 17 file(s) +8 : "model_includes/api/enums/mi_include_type.hpp" impact on 17 files Included by: - 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) - 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) + 1 : "reporter/test/fixture/rp_test_reporter_fixture.hpp" line 5, impact on 6 files + 2 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 6, impact on 5 files 3 : "model_includes/impl/mi_analyzer_impl.cpp" line 5 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.cpp" line 7 5 : "model_includes/test/suits/mi_test_analyzer_for_cmake_suits.cpp" line 8 6 : "model_includes/test/suits/mi_test_analyzer_suits.cpp" line 8 7 : "reporter/impl/different_type_reporter/rp_different_type_reporter_details.cpp" line 3 8 : "reporter/impl/dump_reporter/rp_dump_reporter.cpp" line 8 -9 : "test_tools/boost_predicate_wrapper.hpp" impact on 17 file(s) +9 : "test_tools/boost_predicate_wrapper.hpp" impact on 17 files Included by: - 1 : "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) - 2 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) - 3 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 3, impact on 5 file(s) - 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) - 5 : "project/test/fixture/prj_test_ficture.hpp" line 3, impact on 2 file(s) + 1 : "model_includes/test/fixtures/mi_test_model_includes_fixture.hpp" line 3, impact on 6 files + 2 : "model_includes/test/fixtures/wrappers/mi_test_file_wrapper.hpp" line 3, impact on 5 files + 3 : "model_includes/test/fixtures/wrappers/mi_test_model_wrapper.hpp" line 3, impact on 5 files + 4 : "model_includes/test/fixtures/wrappers/mi_test_include_wrapper.hpp" line 3, impact on 4 files + 5 : "project/test/fixture/prj_test_ficture.hpp" line 3, impact on 2 files 6 : "test_tools/boost_predicate_wrapper.cpp" line 1 -10 : "fs/api/fs_file_system.hpp" impact on 16 file(s) +10 : "application/exceptions/app_exceptions.hpp" impact on 16 files Included by: - 1 : "fs/impl/fs_factory_impl.hpp" line 4, impact on 3 file(s) - 2 : "fs/impl/memory/fs_memory_file_system.hpp" line 3, impact on 2 file(s) - 3 : "fs/impl/physical/fs_physical_file_system.hpp" line 3, impact on 2 file(s) - 4 : "application/test/fixtures/app_test_cmake_project_builder_fixture.cpp" line 15 - 5 : "application/test/fixtures/app_test_project_builder_fixture.cpp" line 16 - 6 : "application/tools/app_cmake_project_builder.cpp" line 20 - 7 : "application/tools/app_configuration_file_loader.cpp" line 12 - 8 : "application/tools/app_project_builder.cpp" line 9 - 9 : "model_includes/impl/mi_analyzer_impl.cpp" line 19 - 10 : "model_includes/impl/mi_resolver.cpp" line 8 - ... 10 of 12 details -... 10 of 164 files + 1 : "application/exceptions/app_cant_create_analyzer.hpp" line 4, impact on 2 files + 2 : "application/exceptions/app_cant_create_model_impl.hpp" line 4, impact on 2 files + 3 : "application/exceptions/app_cant_create_project_impl.hpp" line 4, impact on 2 files + 4 : "application/exceptions/app_cant_create_report_impl.hpp" line 4, impact on 2 files + 5 : "application/exceptions/app_cant_load_reporter_settings.hpp" line 4, impact on 2 files + 6 : "application/exceptions/app_incorrect_thousands_separator_impl.hpp" line 4, impact on 2 files + 7 : "application/test/suits/app_test_parser_arguments_wrapper_suits.cpp" line 3 + 8 : "application/test/suits/app_test_report_settings_loader.cpp" line 3 +... 10 of 166 files diff --git a/docs/examples/cppinclude/output_win.txt b/docs/examples/cppinclude/output_win.txt index daa7d51..0fd1a73 100644 --- a/docs/examples/cppinclude/output_win.txt +++ b/docs/examples/cppinclude/output_win.txt @@ -2,22 +2,22 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "exception\api\exc_exception.hpp" impact on 86 file(s) +1 : "exception\api\exc_exception.hpp" impact on 89 files Included by: - 1 : "exception\ih\exc_exception_impl.hpp" line 3, impact on 79 file(s) - 2 : "application\exceptions\app_exceptions.hpp" line 3, impact on 12 file(s) - 3 : "fs\api\fs_exceptions.hpp" line 3, impact on 9 file(s) - 4 : "project\api\prj_exceptions.hpp" line 3, impact on 4 file(s) - 5 : "reporter\exceptions\rp_exceptions.hpp" line 3, impact on 4 file(s) -2 : "exception\ih\exc_exception_impl.hpp" impact on 79 file(s) + 1 : "exception\ih\exc_exception_impl.hpp" line 3, impact on 81 files + 2 : "application\exceptions\app_exceptions.hpp" line 3, impact on 16 files + 3 : "fs\api\fs_exceptions.hpp" line 3, impact on 9 files + 4 : "project\api\prj_exceptions.hpp" line 3, impact on 4 files + 5 : "reporter\exceptions\rp_exceptions.hpp" line 3, impact on 4 files +2 : "exception\ih\exc_exception_impl.hpp" impact on 81 files Included by: - 1 : "exception\ih\exc_internal_error.hpp" line 3, impact on 51 file(s) - 2 : "exception\ih\exc_exception_with_message_impl.hpp" line 3, impact on 10 file(s) - 3 : "fs\impl\exceptions\fs_base_exception_impl.hpp" line 5, impact on 7 file(s) - 4 : "application\exceptions\app_base_exception_impl.hpp" line 3, impact on 3 file(s) - 5 : "project\impl\exceptions\prj_base_exception_impl.hpp" line 5, impact on 3 file(s) - 6 : "reporter\exceptions\rp_base_exception_impl.hpp" line 3, impact on 3 file(s) -3 : "exception\ih\exc_internal_error.hpp" impact on 51 file(s) + 1 : "exception\ih\exc_internal_error.hpp" line 3, impact on 51 files + 2 : "exception\ih\exc_exception_with_message_impl.hpp" line 3, impact on 13 files + 3 : "fs\impl\exceptions\fs_base_exception_impl.hpp" line 5, impact on 7 files + 4 : "application\exceptions\app_base_exception_impl.hpp" line 3, impact on 3 files + 5 : "project\impl\exceptions\prj_base_exception_impl.hpp" line 5, impact on 3 files + 6 : "reporter\exceptions\rp_base_exception_impl.hpp" line 3, impact on 3 files +3 : "exception\ih\exc_internal_error.hpp" impact on 51 files Included by: 1 : "application\exceptions\app_cant_create_report_impl.cpp" line 8 2 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 18 @@ -30,23 +30,10 @@ Included by: 9 : "application\tools\app_configuration_file.cpp" line 5 10 : "application\tools\app_configuration_file_loader.cpp" line 9 ... 10 of 51 details -4 : "test_tools\test_macros.hpp" impact on 22 file(s) +4 : "reporter\api\enums\rp_reporter_kind.hpp" impact on 19 files Included by: - 1 : "application\test\suits\app_test_cmake_project_builder.cpp" line 7 - 2 : "application\test\suits\app_test_configuration_file_suits.cpp" line 3 - 3 : "application\test\suits\app_test_parser_arguments.cpp" line 3 - 4 : "application\test\suits\app_test_parser_arguments_wrapper_suits.cpp" line 9 - 5 : "application\test\suits\app_test_project_builder.cpp" line 5 - 6 : "application\test\suits\app_test_report_settings_loader.cpp" line 3 - 7 : "cmake_project\test\suits\cprj_test_includes_parser.cpp" line 3 - 8 : "cmake_project\test\suits\cprj_test_loader.cpp" line 3 - 9 : "compilation_db\test\suits\cdb_test_suits.cpp" line 6 - 10 : "json\test\suits\json_test_suits.cpp" line 7 - ... 10 of 22 details -5 : "reporter\api\enums\rp_reporter_kind.hpp" impact on 19 file(s) -Included by: - 1 : "application\exceptions\app_cant_create_report_impl.hpp" line 6, impact on 2 file(s) - 2 : "application\test\fixtures\app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 file(s) + 1 : "application\exceptions\app_cant_create_report_impl.hpp" line 6, impact on 2 files + 2 : "application\test\fixtures\app_test_report_settings_loader_fixture.hpp" line 3, impact on 2 files 3 : "application\resources\app_resources_arguments.cpp" line 10 4 : "application\test\fixtures\app_test_configuration_file_fixture.cpp" line 10 5 : "application\test\fixtures\app_test_parser_wrapper_fixture.cpp" line 6 @@ -56,10 +43,10 @@ Included by: 9 : "reporter\impl\different_type_reporter\rp_different_type_reporter.cpp" line 3 10 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 3 ... 10 of 15 details -6 : "model_includes\api\enums\mi_file_type.hpp" impact on 18 file(s) +5 : "model_includes\api\enums\mi_file_type.hpp" impact on 18 files Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 3, impact on 6 file(s) - 2 : "model_includes\impl\mi_file_impl.hpp" line 3, impact on 2 file(s) + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 3, impact on 6 files + 2 : "model_includes\impl\mi_file_impl.hpp" line 3, impact on 2 files 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 3 4 : "model_includes\impl\mi_resolver.cpp" line 3 5 : "model_includes\test\fixtures\mi_test_model_includes_fixture.cpp" line 5 @@ -69,45 +56,53 @@ Included by: 9 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 6 10 : "reporter\impl\most_impact_reporter\rp_most_impact_reporter.cpp" line 10 ... 10 of 11 details -7 : "model_includes\api\enums\mi_include_status.hpp" impact on 17 file(s) +6 : "application\resources\app_resources_exceptions.hpp" impact on 17 files +Included by: + 1 : "application\exceptions\app_base_exception_with_message_impl.hpp" line 3, impact on 12 files + 2 : "application\exceptions\app_base_exception_impl.hpp" line 5, impact on 3 files + 3 : "application\exceptions\app_cant_create_analyzer.cpp" line 3 + 4 : "application\exceptions\app_cant_create_model_impl.cpp" line 2 + 5 : "application\exceptions\app_cant_create_project_impl.cpp" line 3 + 6 : "application\exceptions\app_cant_create_report_impl.cpp" line 4 + 7 : "application\exceptions\app_cant_load_reporter_settings.cpp" line 3 + 8 : "application\exceptions\app_incorrect_thousands_separator_impl.cpp" line 3 + 9 : "application\resources\app_resources_exceptions.cpp" line 1 +7 : "model_includes\api\enums\mi_include_status.hpp" impact on 17 files Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 4, impact on 6 file(s) - 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 5, impact on 5 file(s) + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 4, impact on 6 files + 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 5, impact on 5 files 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 4 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 6 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 7 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 7 7 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 7 8 : "reporter\impl\unresolved_reporter\rp_unresolved_reporter.cpp" line 11 -8 : "model_includes\api\enums\mi_include_type.hpp" impact on 17 file(s) +8 : "model_includes\api\enums\mi_include_type.hpp" impact on 17 files Included by: - 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 5, impact on 6 file(s) - 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 6, impact on 5 file(s) + 1 : "reporter\test\fixture\rp_test_reporter_fixture.hpp" line 5, impact on 6 files + 2 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 6, impact on 5 files 3 : "model_includes\impl\mi_analyzer_impl.cpp" line 5 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.cpp" line 7 5 : "model_includes\test\suits\mi_test_analyzer_for_cmake_suits.cpp" line 8 6 : "model_includes\test\suits\mi_test_analyzer_suits.cpp" line 8 7 : "reporter\impl\different_type_reporter\rp_different_type_reporter_details.cpp" line 3 8 : "reporter\impl\dump_reporter\rp_dump_reporter.cpp" line 8 -9 : "test_tools\boost_predicate_wrapper.hpp" impact on 17 file(s) +9 : "test_tools\boost_predicate_wrapper.hpp" impact on 17 files Included by: - 1 : "model_includes\test\fixtures\mi_test_model_includes_fixture.hpp" line 3, impact on 6 file(s) - 2 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.hpp" line 3, impact on 5 file(s) - 3 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 3, impact on 5 file(s) - 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.hpp" line 3, impact on 4 file(s) - 5 : "project\test\fixture\prj_test_ficture.hpp" line 3, impact on 2 file(s) + 1 : "model_includes\test\fixtures\mi_test_model_includes_fixture.hpp" line 3, impact on 6 files + 2 : "model_includes\test\fixtures\wrappers\mi_test_file_wrapper.hpp" line 3, impact on 5 files + 3 : "model_includes\test\fixtures\wrappers\mi_test_model_wrapper.hpp" line 3, impact on 5 files + 4 : "model_includes\test\fixtures\wrappers\mi_test_include_wrapper.hpp" line 3, impact on 4 files + 5 : "project\test\fixture\prj_test_ficture.hpp" line 3, impact on 2 files 6 : "test_tools\boost_predicate_wrapper.cpp" line 1 -10 : "fs\api\fs_file_system.hpp" impact on 16 file(s) +10 : "application\exceptions\app_exceptions.hpp" impact on 16 files Included by: - 1 : "fs\impl\fs_factory_impl.hpp" line 4, impact on 3 file(s) - 2 : "fs\impl\memory\fs_memory_file_system.hpp" line 3, impact on 2 file(s) - 3 : "fs\impl\physical\fs_physical_file_system.hpp" line 3, impact on 2 file(s) - 4 : "application\test\fixtures\app_test_cmake_project_builder_fixture.cpp" line 15 - 5 : "application\test\fixtures\app_test_project_builder_fixture.cpp" line 16 - 6 : "application\tools\app_cmake_project_builder.cpp" line 20 - 7 : "application\tools\app_configuration_file_loader.cpp" line 12 - 8 : "application\tools\app_project_builder.cpp" line 9 - 9 : "model_includes\impl\mi_analyzer_impl.cpp" line 19 - 10 : "model_includes\impl\mi_resolver.cpp" line 8 - ... 10 of 12 details -... 10 of 164 files + 1 : "application\exceptions\app_cant_create_analyzer.hpp" line 4, impact on 2 files + 2 : "application\exceptions\app_cant_create_model_impl.hpp" line 4, impact on 2 files + 3 : "application\exceptions\app_cant_create_project_impl.hpp" line 4, impact on 2 files + 4 : "application\exceptions\app_cant_create_report_impl.hpp" line 4, impact on 2 files + 5 : "application\exceptions\app_cant_load_reporter_settings.hpp" line 4, impact on 2 files + 6 : "application\exceptions\app_incorrect_thousands_separator_impl.hpp" line 4, impact on 2 files + 7 : "application\test\suits\app_test_parser_arguments_wrapper_suits.cpp" line 3 + 8 : "application\test\suits\app_test_report_settings_loader.cpp" line 3 +... 10 of 166 files diff --git a/docs/examples/gcc/output_unix.txt b/docs/examples/gcc/output_unix.txt index 00ff9eb..2f9959f 100644 --- a/docs/examples/gcc/output_unix.txt +++ b/docs/examples/gcc/output_unix.txt @@ -2,117 +2,117 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "libstdc++-v3/include/c_compatibility/stdio.h" impact on 10322 file(s) +1 : "libstdc++-v3/include/c_compatibility/stdio.h" impact on 10 322 files Included by: - 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 49, impact on 4716 file(s) - 2 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 1, impact on 1799 file(s) - 3 : "include/libiberty.h" line 49, impact on 1152 file(s) - 4 : "gcc/wide-int-print.h" line 23, impact on 1118 file(s) - 5 : "gcc/system.h" line 46, impact on 1060 file(s) - 6 : "libgfortran/libgfortran.h" line 42, impact on 591 file(s) - 7 : "libffi/testsuite/libffi.call/ffitest.h" line 2, impact on 145 file(s) - 8 : "gcc/jit/libgccjit.h" line 23, impact on 139 file(s) - 9 : "gcc/testsuite/gcc.dg/compat/compat-common.h" line 8, impact on 117 file(s) - 10 : "gcc/testsuite/jit.dg/harness.h" line 16, impact on 117 file(s) - ... 10 of 1198 details -2 : "fixincludes/tests/base/unistd.h" impact on 6319 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 49, impact on 4 716 files + 2 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 1, impact on 1 799 files + 3 : "include/libiberty.h" line 49, impact on 1 152 files + 4 : "gcc/wide-int-print.h" line 23, impact on 1 118 files + 5 : "gcc/system.h" line 46, impact on 1 060 files + 6 : "libgfortran/libgfortran.h" line 42, impact on 591 files + 7 : "libffi/testsuite/libffi.call/ffitest.h" line 2, impact on 145 files + 8 : "gcc/jit/libgccjit.h" line 23, impact on 139 files + 9 : "gcc/testsuite/gcc.dg/compat/compat-common.h" line 8, impact on 117 files + 10 : "gcc/testsuite/jit.dg/harness.h" line 16, impact on 117 files + ... 10 of 1 198 details +2 : "fixincludes/tests/base/unistd.h" impact on 6 319 files Included by: - 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 73, impact on 4716 file(s) - 2 : "gcc/system.h" line 294, impact on 1060 file(s) - 3 : "libstdc++-v3/testsuite/util/testsuite_fs.h" line 38, impact on 140 file(s) - 4 : "gcc/testsuite/jit.dg/harness.h" line 17, impact on 117 file(s) - 5 : "gcc/tsystem.h" line 102, impact on 75 file(s) - 6 : "libstdc++-v3/include/ext/stdio_sync_filebuf.h" line 35, impact on 18 file(s) - 7 : "libcpp/system.h" line 222, impact on 14 file(s) - 8 : "include/simple-object.h" line 27, impact on 11 file(s) - 9 : "liboffloadmic/runtime/coi/coi_server.h" line 44, impact on 10 file(s) - 10 : "gcc/testsuite/gcc.dg/guality/guality.h" line 25, impact on 8 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" line 73, impact on 4 716 files + 2 : "gcc/system.h" line 294, impact on 1 060 files + 3 : "libstdc++-v3/testsuite/util/testsuite_fs.h" line 38, impact on 140 files + 4 : "gcc/testsuite/jit.dg/harness.h" line 17, impact on 117 files + 5 : "gcc/tsystem.h" line 102, impact on 75 files + 6 : "libstdc++-v3/include/ext/stdio_sync_filebuf.h" line 35, impact on 18 files + 7 : "libcpp/system.h" line 222, impact on 14 files + 8 : "include/simple-object.h" line 27, impact on 11 files + 9 : "liboffloadmic/runtime/coi/coi_server.h" line 44, impact on 10 files + 10 : "gcc/testsuite/gcc.dg/guality/guality.h" line 25, impact on 8 files ... 10 of 294 details -3 : "gcc/ginclude/stdint-gcc.h" impact on 5209 file(s) +3 : "gcc/ginclude/stdint-gcc.h" impact on 5 209 files Included by: - 1 : "gcc/config/vxworks/stdint.h" line 26, impact on 5208 file(s) -4 : "gcc/config/vxworks/stdint.h" impact on 5208 file(s) + 1 : "gcc/config/vxworks/stdint.h" line 26, impact on 5 208 files +4 : "gcc/config/vxworks/stdint.h" impact on 5 208 files Included by: - 1 : "gcc/config/arm/arm_mve.h" line 31, impact on 2485 file(s) - 2 : "gcc/system.h" line 524, impact on 1060 file(s) - 3 : "libgcc/gstdint.h" line 6, impact on 659 file(s) - 4 : "gcc/config/arm/arm_fp16.h" line 34, impact on 286 file(s) - 5 : "gcc/config/arm/arm_neon.h" line 43, impact on 282 file(s) - 6 : "include/plugin-api.h" line 30, impact on 235 file(s) - 7 : "include/splay-tree.h" line 40, impact on 162 file(s) - 8 : "libffi/testsuite/libffi.call/ffitest.h" line 9, impact on 145 file(s) - 9 : "liboffloadmic/include/coi/common/COITypes_common.h" line 51, impact on 41 file(s) - 10 : "libbacktrace/backtrace.h" line 43, impact on 34 file(s) + 1 : "gcc/config/arm/arm_mve.h" line 31, impact on 2 485 files + 2 : "gcc/system.h" line 524, impact on 1 060 files + 3 : "libgcc/gstdint.h" line 6, impact on 659 files + 4 : "gcc/config/arm/arm_fp16.h" line 34, impact on 286 files + 5 : "gcc/config/arm/arm_neon.h" line 43, impact on 282 files + 6 : "include/plugin-api.h" line 30, impact on 235 files + 7 : "include/splay-tree.h" line 40, impact on 162 files + 8 : "libffi/testsuite/libffi.call/ffitest.h" line 9, impact on 145 files + 9 : "liboffloadmic/include/coi/common/COITypes_common.h" line 51, impact on 41 files + 10 : "libbacktrace/backtrace.h" line 43, impact on 34 files ... 10 of 363 details -5 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" impact on 4716 file(s) +5 : "libstdc++-v3/testsuite/util/testsuite_hooks.h" impact on 4 716 files Included by: - 1 : "libstdc++-v3/testsuite/util/testsuite_allocator.h" line 32, impact on 332 file(s) - 2 : "libstdc++-v3/testsuite/util/testsuite_iterators.h" line 30, impact on 326 file(s) - 3 : "libstdc++-v3/testsuite/util/testsuite_tr1.h" line 26, impact on 225 file(s) - 4 : "libstdc++-v3/testsuite/util/testsuite_api.h" line 23, impact on 138 file(s) - 5 : "libstdc++-v3/testsuite/util/debug/checks.h" line 27, impact on 111 file(s) - 6 : "libstdc++-v3/testsuite/util/testsuite_rvalref.h" line 25, impact on 71 file(s) - 7 : "libstdc++-v3/testsuite/util/replacement_memory_operators.h" line 23, impact on 32 file(s) - 8 : "libstdc++-v3/testsuite/util/debug/unordered_checks.h" line 19, impact on 16 file(s) - 9 : "libstdc++-v3/testsuite/util/testsuite_random.h" line 29, impact on 12 file(s) - 10 : "libstdc++-v3/testsuite/util/testsuite_new_operators.h" line 26, impact on 3 file(s) - ... 10 of 4083 details -6 : "gcc/config/i386/mmintrin.h" impact on 4383 file(s) + 1 : "libstdc++-v3/testsuite/util/testsuite_allocator.h" line 32, impact on 332 files + 2 : "libstdc++-v3/testsuite/util/testsuite_iterators.h" line 30, impact on 326 files + 3 : "libstdc++-v3/testsuite/util/testsuite_tr1.h" line 26, impact on 225 files + 4 : "libstdc++-v3/testsuite/util/testsuite_api.h" line 23, impact on 138 files + 5 : "libstdc++-v3/testsuite/util/debug/checks.h" line 27, impact on 111 files + 6 : "libstdc++-v3/testsuite/util/testsuite_rvalref.h" line 25, impact on 71 files + 7 : "libstdc++-v3/testsuite/util/replacement_memory_operators.h" line 23, impact on 32 files + 8 : "libstdc++-v3/testsuite/util/debug/unordered_checks.h" line 19, impact on 16 files + 9 : "libstdc++-v3/testsuite/util/testsuite_random.h" line 29, impact on 12 files + 10 : "libstdc++-v3/testsuite/util/testsuite_new_operators.h" line 26, impact on 3 files + ... 10 of 4 083 details +6 : "gcc/config/i386/mmintrin.h" impact on 4 383 files Included by: - 1 : "gcc/config/i386/xmmintrin.h" line 31, impact on 4373 file(s) - 2 : "gcc/config/i386/immintrin.h" line 27, impact on 3236 file(s) - 3 : "gcc/config/i386/mm3dnow.h" line 30, impact on 367 file(s) -7 : "gcc/config/rs6000/mm_malloc.h" impact on 4381 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 31, impact on 4 373 files + 2 : "gcc/config/i386/immintrin.h" line 27, impact on 3 236 files + 3 : "gcc/config/i386/mm3dnow.h" line 30, impact on 367 files +7 : "gcc/config/rs6000/mm_malloc.h" impact on 4 381 files Included by: - 1 : "gcc/config/i386/xmmintrin.h" line 34, impact on 4373 file(s) - 2 : "gcc/config/rs6000/xmmintrin.h" line 82, impact on 5 file(s) - 3 : "gcc/testsuite/gcc.target/i386/sse-23.c" line 5, impact on 2 file(s) - 4 : "gcc/testsuite/gcc.target/i386/sse-13.c" line 5, impact on 1 file(s) - 5 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 6, impact on 1 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 34, impact on 4 373 files + 2 : "gcc/config/rs6000/xmmintrin.h" line 82, impact on 5 files + 3 : "gcc/testsuite/gcc.target/i386/sse-23.c" line 5, impact on 2 files + 4 : "gcc/testsuite/gcc.target/i386/sse-13.c" line 5, impact on 1 file + 5 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 6, impact on 1 file 6 : "gcc/testsuite/gcc.target/i386/avx-1.c" line 5 7 : "gcc/testsuite/gcc.target/i386/avx-2.c" line 5 8 : "gcc/testsuite/gcc.target/i386/sse-14.c" line 5 9 : "liboffloadmic/runtime/offload_common.cpp" line 32 -8 : "gcc/config/i386/emmintrin.h" impact on 4373 file(s) +8 : "gcc/config/i386/emmintrin.h" impact on 4 373 files Included by: - 1 : "gcc/config/i386/xmmintrin.h" line 1316, impact on 4373 file(s) - 2 : "gcc/config/i386/pmmintrin.h" line 31, impact on 3491 file(s) - 3 : "gcc/config/i386/wmmintrin.h" line 31, impact on 3251 file(s) - 4 : "gcc/config/i386/immintrin.h" line 31, impact on 3236 file(s) - 5 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 5, impact on 1799 file(s) - 6 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 9, impact on 7 file(s) - 7 : "gcc/testsuite/g++.dg/asan/asan_test.cc" line 686, impact on 1 file(s) - 8 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 141, impact on 1 file(s) - 9 : "gcc/testsuite/gcc.target/i386/sse2-addpd-1.c" line 15, impact on 1 file(s) - 10 : "gcc/testsuite/gcc.target/i386/sse2-addsd-1.c" line 15, impact on 1 file(s) + 1 : "gcc/config/i386/xmmintrin.h" line 1 316, impact on 4 373 files + 2 : "gcc/config/i386/pmmintrin.h" line 31, impact on 3 491 files + 3 : "gcc/config/i386/wmmintrin.h" line 31, impact on 3 251 files + 4 : "gcc/config/i386/immintrin.h" line 31, impact on 3 236 files + 5 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 5, impact on 1 799 files + 6 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 9, impact on 7 files + 7 : "gcc/testsuite/g++.dg/asan/asan_test.cc" line 686, impact on 1 file + 8 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 141, impact on 1 file + 9 : "gcc/testsuite/gcc.target/i386/sse2-addpd-1.c" line 15, impact on 1 file + 10 : "gcc/testsuite/gcc.target/i386/sse2-addsd-1.c" line 15, impact on 1 file ... 10 of 350 details -9 : "gcc/config/i386/xmmintrin.h" impact on 4373 file(s) +9 : "gcc/config/i386/xmmintrin.h" impact on 4 373 files Included by: - 1 : "gcc/config/i386/emmintrin.h" line 31, impact on 4373 file(s) - 2 : "gcc/config/i386/immintrin.h" line 29, impact on 3236 file(s) - 3 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 2, impact on 1799 file(s) - 4 : "gcc/testsuite/gcc.target/x86_64/abi/defines.h" line 5, impact on 19 file(s) - 5 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 6, impact on 7 file(s) - 6 : "gcc/testsuite/gcc.dg/compat/union-m128-1.h" line 1, impact on 2 file(s) - 7 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 127, impact on 1 file(s) - 8 : "gcc/testsuite/gcc.target/i386/sse-addps-1.c" line 15, impact on 1 file(s) - 9 : "gcc/testsuite/gcc.target/i386/sse-addss-1.c" line 15, impact on 1 file(s) - 10 : "gcc/testsuite/gcc.target/i386/sse-andnps-1.c" line 15, impact on 1 file(s) + 1 : "gcc/config/i386/emmintrin.h" line 31, impact on 4 373 files + 2 : "gcc/config/i386/immintrin.h" line 29, impact on 3 236 files + 3 : "gcc/testsuite/gcc.target/i386/m128-check.h" line 2, impact on 1 799 files + 4 : "gcc/testsuite/gcc.target/x86_64/abi/defines.h" line 5, impact on 19 files + 5 : "gcc/testsuite/gcc.target/powerpc/m128-check.h" line 6, impact on 7 files + 6 : "gcc/testsuite/gcc.dg/compat/union-m128-1.h" line 1, impact on 2 files + 7 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 127, impact on 1 file + 8 : "gcc/testsuite/gcc.target/i386/sse-addps-1.c" line 15, impact on 1 file + 9 : "gcc/testsuite/gcc.target/i386/sse-addss-1.c" line 15, impact on 1 file + 10 : "gcc/testsuite/gcc.target/i386/sse-andnps-1.c" line 15, impact on 1 file ... 10 of 169 details -10 : "gcc/config/i386/pmmintrin.h" impact on 3491 file(s) +10 : "gcc/config/i386/pmmintrin.h" impact on 3 491 files Included by: - 1 : "gcc/config/i386/tmmintrin.h" line 31, impact on 3451 file(s) - 2 : "gcc/config/i386/immintrin.h" line 33, impact on 3236 file(s) - 3 : "gcc/config/i386/ammintrin.h" line 31, impact on 364 file(s) - 4 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 157, impact on 1 file(s) - 5 : "gcc/testsuite/gcc.target/i386/sse3-addsubpd.c" line 15, impact on 1 file(s) - 6 : "gcc/testsuite/gcc.target/i386/sse3-addsubps.c" line 15, impact on 1 file(s) - 7 : "gcc/testsuite/gcc.target/i386/sse3-haddpd.c" line 14, impact on 1 file(s) - 8 : "gcc/testsuite/gcc.target/i386/sse3-haddps.c" line 15, impact on 1 file(s) - 9 : "gcc/testsuite/gcc.target/i386/sse3-hsubpd.c" line 14, impact on 1 file(s) - 10 : "gcc/testsuite/gcc.target/i386/sse3-hsubps.c" line 14, impact on 1 file(s) + 1 : "gcc/config/i386/tmmintrin.h" line 31, impact on 3 451 files + 2 : "gcc/config/i386/immintrin.h" line 33, impact on 3 236 files + 3 : "gcc/config/i386/ammintrin.h" line 31, impact on 364 files + 4 : "gcc/testsuite/gcc.target/i386/sse-22.c" line 157, impact on 1 file + 5 : "gcc/testsuite/gcc.target/i386/sse3-addsubpd.c" line 15, impact on 1 file + 6 : "gcc/testsuite/gcc.target/i386/sse3-addsubps.c" line 15, impact on 1 file + 7 : "gcc/testsuite/gcc.target/i386/sse3-haddpd.c" line 14, impact on 1 file + 8 : "gcc/testsuite/gcc.target/i386/sse3-haddps.c" line 15, impact on 1 file + 9 : "gcc/testsuite/gcc.target/i386/sse3-hsubpd.c" line 14, impact on 1 file + 10 : "gcc/testsuite/gcc.target/i386/sse3-hsubps.c" line 14, impact on 1 file ... 10 of 26 details -... 10 of 3748 files +... 10 of 3 748 files Unincluded headers: 1 : "fixincludes/system.h" 2 : "fixincludes/tests/base/AvailabilityInternal.h" diff --git a/docs/examples/gcc/output_win.txt b/docs/examples/gcc/output_win.txt index a70836a..1f07ce9 100644 --- a/docs/examples/gcc/output_win.txt +++ b/docs/examples/gcc/output_win.txt @@ -2,117 +2,117 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "libstdc++-v3\include\c_compatibility\stdio.h" impact on 10322 file(s) +1 : "libstdc++-v3\include\c_compatibility\stdio.h" impact on 10 322 files Included by: - 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 49, impact on 4716 file(s) - 2 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 1, impact on 1799 file(s) - 3 : "include\libiberty.h" line 49, impact on 1152 file(s) - 4 : "gcc\wide-int-print.h" line 23, impact on 1118 file(s) - 5 : "gcc\system.h" line 46, impact on 1060 file(s) - 6 : "libgfortran\libgfortran.h" line 42, impact on 591 file(s) - 7 : "libffi\testsuite\libffi.call\ffitest.h" line 2, impact on 145 file(s) - 8 : "gcc\jit\libgccjit.h" line 23, impact on 139 file(s) - 9 : "gcc\testsuite\gcc.dg\compat\compat-common.h" line 8, impact on 117 file(s) - 10 : "gcc\testsuite\jit.dg\harness.h" line 16, impact on 117 file(s) - ... 10 of 1198 details -2 : "fixincludes\tests\base\unistd.h" impact on 6319 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 49, impact on 4 716 files + 2 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 1, impact on 1 799 files + 3 : "include\libiberty.h" line 49, impact on 1 152 files + 4 : "gcc\wide-int-print.h" line 23, impact on 1 118 files + 5 : "gcc\system.h" line 46, impact on 1 060 files + 6 : "libgfortran\libgfortran.h" line 42, impact on 591 files + 7 : "libffi\testsuite\libffi.call\ffitest.h" line 2, impact on 145 files + 8 : "gcc\jit\libgccjit.h" line 23, impact on 139 files + 9 : "gcc\testsuite\gcc.dg\compat\compat-common.h" line 8, impact on 117 files + 10 : "gcc\testsuite\jit.dg\harness.h" line 16, impact on 117 files + ... 10 of 1 198 details +2 : "fixincludes\tests\base\unistd.h" impact on 6 319 files Included by: - 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 73, impact on 4716 file(s) - 2 : "gcc\system.h" line 294, impact on 1060 file(s) - 3 : "libstdc++-v3\testsuite\util\testsuite_fs.h" line 38, impact on 140 file(s) - 4 : "gcc\testsuite\jit.dg\harness.h" line 17, impact on 117 file(s) - 5 : "gcc\tsystem.h" line 102, impact on 75 file(s) - 6 : "libstdc++-v3\include\ext\stdio_sync_filebuf.h" line 35, impact on 18 file(s) - 7 : "libcpp\system.h" line 222, impact on 14 file(s) - 8 : "include\simple-object.h" line 27, impact on 11 file(s) - 9 : "liboffloadmic\runtime\coi\coi_server.h" line 44, impact on 10 file(s) - 10 : "gcc\testsuite\gcc.dg\guality\guality.h" line 25, impact on 8 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" line 73, impact on 4 716 files + 2 : "gcc\system.h" line 294, impact on 1 060 files + 3 : "libstdc++-v3\testsuite\util\testsuite_fs.h" line 38, impact on 140 files + 4 : "gcc\testsuite\jit.dg\harness.h" line 17, impact on 117 files + 5 : "gcc\tsystem.h" line 102, impact on 75 files + 6 : "libstdc++-v3\include\ext\stdio_sync_filebuf.h" line 35, impact on 18 files + 7 : "libcpp\system.h" line 222, impact on 14 files + 8 : "include\simple-object.h" line 27, impact on 11 files + 9 : "liboffloadmic\runtime\coi\coi_server.h" line 44, impact on 10 files + 10 : "gcc\testsuite\gcc.dg\guality\guality.h" line 25, impact on 8 files ... 10 of 294 details -3 : "gcc\ginclude\stdint-gcc.h" impact on 5209 file(s) +3 : "gcc\ginclude\stdint-gcc.h" impact on 5 209 files Included by: - 1 : "gcc\config\vxworks\stdint.h" line 26, impact on 5208 file(s) -4 : "gcc\config\vxworks\stdint.h" impact on 5208 file(s) + 1 : "gcc\config\vxworks\stdint.h" line 26, impact on 5 208 files +4 : "gcc\config\vxworks\stdint.h" impact on 5 208 files Included by: - 1 : "gcc\config\arm\arm_mve.h" line 31, impact on 2485 file(s) - 2 : "gcc\system.h" line 524, impact on 1060 file(s) - 3 : "libgcc\gstdint.h" line 6, impact on 659 file(s) - 4 : "gcc\config\arm\arm_fp16.h" line 34, impact on 286 file(s) - 5 : "gcc\config\arm\arm_neon.h" line 43, impact on 282 file(s) - 6 : "include\plugin-api.h" line 30, impact on 235 file(s) - 7 : "include\splay-tree.h" line 40, impact on 162 file(s) - 8 : "libffi\testsuite\libffi.call\ffitest.h" line 9, impact on 145 file(s) - 9 : "liboffloadmic\include\coi\common\COITypes_common.h" line 51, impact on 41 file(s) - 10 : "libbacktrace\backtrace.h" line 43, impact on 34 file(s) + 1 : "gcc\config\arm\arm_mve.h" line 31, impact on 2 485 files + 2 : "gcc\system.h" line 524, impact on 1 060 files + 3 : "libgcc\gstdint.h" line 6, impact on 659 files + 4 : "gcc\config\arm\arm_fp16.h" line 34, impact on 286 files + 5 : "gcc\config\arm\arm_neon.h" line 43, impact on 282 files + 6 : "include\plugin-api.h" line 30, impact on 235 files + 7 : "include\splay-tree.h" line 40, impact on 162 files + 8 : "libffi\testsuite\libffi.call\ffitest.h" line 9, impact on 145 files + 9 : "liboffloadmic\include\coi\common\COITypes_common.h" line 51, impact on 41 files + 10 : "libbacktrace\backtrace.h" line 43, impact on 34 files ... 10 of 363 details -5 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" impact on 4716 file(s) +5 : "libstdc++-v3\testsuite\util\testsuite_hooks.h" impact on 4 716 files Included by: - 1 : "libstdc++-v3\testsuite\util\testsuite_allocator.h" line 32, impact on 332 file(s) - 2 : "libstdc++-v3\testsuite\util\testsuite_iterators.h" line 30, impact on 326 file(s) - 3 : "libstdc++-v3\testsuite\util\testsuite_tr1.h" line 26, impact on 225 file(s) - 4 : "libstdc++-v3\testsuite\util\testsuite_api.h" line 23, impact on 138 file(s) - 5 : "libstdc++-v3\testsuite\util\debug\checks.h" line 27, impact on 111 file(s) - 6 : "libstdc++-v3\testsuite\util\testsuite_rvalref.h" line 25, impact on 71 file(s) - 7 : "libstdc++-v3\testsuite\util\replacement_memory_operators.h" line 23, impact on 32 file(s) - 8 : "libstdc++-v3\testsuite\util\debug\unordered_checks.h" line 19, impact on 16 file(s) - 9 : "libstdc++-v3\testsuite\util\testsuite_random.h" line 29, impact on 12 file(s) - 10 : "libstdc++-v3\testsuite\util\testsuite_new_operators.h" line 26, impact on 3 file(s) - ... 10 of 4083 details -6 : "gcc\config\i386\mmintrin.h" impact on 4383 file(s) + 1 : "libstdc++-v3\testsuite\util\testsuite_allocator.h" line 32, impact on 332 files + 2 : "libstdc++-v3\testsuite\util\testsuite_iterators.h" line 30, impact on 326 files + 3 : "libstdc++-v3\testsuite\util\testsuite_tr1.h" line 26, impact on 225 files + 4 : "libstdc++-v3\testsuite\util\testsuite_api.h" line 23, impact on 138 files + 5 : "libstdc++-v3\testsuite\util\debug\checks.h" line 27, impact on 111 files + 6 : "libstdc++-v3\testsuite\util\testsuite_rvalref.h" line 25, impact on 71 files + 7 : "libstdc++-v3\testsuite\util\replacement_memory_operators.h" line 23, impact on 32 files + 8 : "libstdc++-v3\testsuite\util\debug\unordered_checks.h" line 19, impact on 16 files + 9 : "libstdc++-v3\testsuite\util\testsuite_random.h" line 29, impact on 12 files + 10 : "libstdc++-v3\testsuite\util\testsuite_new_operators.h" line 26, impact on 3 files + ... 10 of 4 083 details +6 : "gcc\config\i386\mmintrin.h" impact on 4 383 files Included by: - 1 : "gcc\config\i386\xmmintrin.h" line 31, impact on 4373 file(s) - 2 : "gcc\config\i386\immintrin.h" line 27, impact on 3236 file(s) - 3 : "gcc\config\i386\mm3dnow.h" line 30, impact on 367 file(s) -7 : "gcc\config\rs6000\mm_malloc.h" impact on 4381 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 31, impact on 4 373 files + 2 : "gcc\config\i386\immintrin.h" line 27, impact on 3 236 files + 3 : "gcc\config\i386\mm3dnow.h" line 30, impact on 367 files +7 : "gcc\config\rs6000\mm_malloc.h" impact on 4 381 files Included by: - 1 : "gcc\config\i386\xmmintrin.h" line 34, impact on 4373 file(s) - 2 : "gcc\config\rs6000\xmmintrin.h" line 82, impact on 5 file(s) - 3 : "gcc\testsuite\gcc.target\i386\sse-23.c" line 5, impact on 2 file(s) - 4 : "gcc\testsuite\gcc.target\i386\sse-13.c" line 5, impact on 1 file(s) - 5 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 6, impact on 1 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 34, impact on 4 373 files + 2 : "gcc\config\rs6000\xmmintrin.h" line 82, impact on 5 files + 3 : "gcc\testsuite\gcc.target\i386\sse-23.c" line 5, impact on 2 files + 4 : "gcc\testsuite\gcc.target\i386\sse-13.c" line 5, impact on 1 file + 5 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 6, impact on 1 file 6 : "gcc\testsuite\gcc.target\i386\avx-1.c" line 5 7 : "gcc\testsuite\gcc.target\i386\avx-2.c" line 5 8 : "gcc\testsuite\gcc.target\i386\sse-14.c" line 5 9 : "liboffloadmic\runtime\offload_common.cpp" line 32 -8 : "gcc\config\i386\emmintrin.h" impact on 4373 file(s) +8 : "gcc\config\i386\emmintrin.h" impact on 4 373 files Included by: - 1 : "gcc\config\i386\xmmintrin.h" line 1316, impact on 4373 file(s) - 2 : "gcc\config\i386\pmmintrin.h" line 31, impact on 3491 file(s) - 3 : "gcc\config\i386\wmmintrin.h" line 31, impact on 3251 file(s) - 4 : "gcc\config\i386\immintrin.h" line 31, impact on 3236 file(s) - 5 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 5, impact on 1799 file(s) - 6 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 9, impact on 7 file(s) - 7 : "gcc\testsuite\g++.dg\asan\asan_test.cc" line 686, impact on 1 file(s) - 8 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 141, impact on 1 file(s) - 9 : "gcc\testsuite\gcc.target\i386\sse2-addpd-1.c" line 15, impact on 1 file(s) - 10 : "gcc\testsuite\gcc.target\i386\sse2-addsd-1.c" line 15, impact on 1 file(s) + 1 : "gcc\config\i386\xmmintrin.h" line 1 316, impact on 4 373 files + 2 : "gcc\config\i386\pmmintrin.h" line 31, impact on 3 491 files + 3 : "gcc\config\i386\wmmintrin.h" line 31, impact on 3 251 files + 4 : "gcc\config\i386\immintrin.h" line 31, impact on 3 236 files + 5 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 5, impact on 1 799 files + 6 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 9, impact on 7 files + 7 : "gcc\testsuite\g++.dg\asan\asan_test.cc" line 686, impact on 1 file + 8 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 141, impact on 1 file + 9 : "gcc\testsuite\gcc.target\i386\sse2-addpd-1.c" line 15, impact on 1 file + 10 : "gcc\testsuite\gcc.target\i386\sse2-addsd-1.c" line 15, impact on 1 file ... 10 of 350 details -9 : "gcc\config\i386\xmmintrin.h" impact on 4373 file(s) +9 : "gcc\config\i386\xmmintrin.h" impact on 4 373 files Included by: - 1 : "gcc\config\i386\emmintrin.h" line 31, impact on 4373 file(s) - 2 : "gcc\config\i386\immintrin.h" line 29, impact on 3236 file(s) - 3 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 2, impact on 1799 file(s) - 4 : "gcc\testsuite\gcc.target\x86_64\abi\defines.h" line 5, impact on 19 file(s) - 5 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 6, impact on 7 file(s) - 6 : "gcc\testsuite\gcc.dg\compat\union-m128-1.h" line 1, impact on 2 file(s) - 7 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 127, impact on 1 file(s) - 8 : "gcc\testsuite\gcc.target\i386\sse-addps-1.c" line 15, impact on 1 file(s) - 9 : "gcc\testsuite\gcc.target\i386\sse-addss-1.c" line 15, impact on 1 file(s) - 10 : "gcc\testsuite\gcc.target\i386\sse-andnps-1.c" line 15, impact on 1 file(s) + 1 : "gcc\config\i386\emmintrin.h" line 31, impact on 4 373 files + 2 : "gcc\config\i386\immintrin.h" line 29, impact on 3 236 files + 3 : "gcc\testsuite\gcc.target\i386\m128-check.h" line 2, impact on 1 799 files + 4 : "gcc\testsuite\gcc.target\x86_64\abi\defines.h" line 5, impact on 19 files + 5 : "gcc\testsuite\gcc.target\powerpc\m128-check.h" line 6, impact on 7 files + 6 : "gcc\testsuite\gcc.dg\compat\union-m128-1.h" line 1, impact on 2 files + 7 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 127, impact on 1 file + 8 : "gcc\testsuite\gcc.target\i386\sse-addps-1.c" line 15, impact on 1 file + 9 : "gcc\testsuite\gcc.target\i386\sse-addss-1.c" line 15, impact on 1 file + 10 : "gcc\testsuite\gcc.target\i386\sse-andnps-1.c" line 15, impact on 1 file ... 10 of 169 details -10 : "gcc\config\i386\pmmintrin.h" impact on 3491 file(s) +10 : "gcc\config\i386\pmmintrin.h" impact on 3 491 files Included by: - 1 : "gcc\config\i386\tmmintrin.h" line 31, impact on 3451 file(s) - 2 : "gcc\config\i386\immintrin.h" line 33, impact on 3236 file(s) - 3 : "gcc\config\i386\ammintrin.h" line 31, impact on 364 file(s) - 4 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 157, impact on 1 file(s) - 5 : "gcc\testsuite\gcc.target\i386\sse3-addsubpd.c" line 15, impact on 1 file(s) - 6 : "gcc\testsuite\gcc.target\i386\sse3-addsubps.c" line 15, impact on 1 file(s) - 7 : "gcc\testsuite\gcc.target\i386\sse3-haddpd.c" line 14, impact on 1 file(s) - 8 : "gcc\testsuite\gcc.target\i386\sse3-haddps.c" line 15, impact on 1 file(s) - 9 : "gcc\testsuite\gcc.target\i386\sse3-hsubpd.c" line 14, impact on 1 file(s) - 10 : "gcc\testsuite\gcc.target\i386\sse3-hsubps.c" line 14, impact on 1 file(s) + 1 : "gcc\config\i386\tmmintrin.h" line 31, impact on 3 451 files + 2 : "gcc\config\i386\immintrin.h" line 33, impact on 3 236 files + 3 : "gcc\config\i386\ammintrin.h" line 31, impact on 364 files + 4 : "gcc\testsuite\gcc.target\i386\sse-22.c" line 157, impact on 1 file + 5 : "gcc\testsuite\gcc.target\i386\sse3-addsubpd.c" line 15, impact on 1 file + 6 : "gcc\testsuite\gcc.target\i386\sse3-addsubps.c" line 15, impact on 1 file + 7 : "gcc\testsuite\gcc.target\i386\sse3-haddpd.c" line 14, impact on 1 file + 8 : "gcc\testsuite\gcc.target\i386\sse3-haddps.c" line 15, impact on 1 file + 9 : "gcc\testsuite\gcc.target\i386\sse3-hsubpd.c" line 14, impact on 1 file + 10 : "gcc\testsuite\gcc.target\i386\sse3-hsubps.c" line 14, impact on 1 file ... 10 of 26 details -... 10 of 3748 files +... 10 of 3 748 files Unincluded headers: 1 : "fixincludes\system.h" 2 : "fixincludes\tests\base\AvailabilityInternal.h" diff --git a/docs/examples/llvm-project/output_unix.txt b/docs/examples/llvm-project/output_unix.txt index 6e15e1a..a10b3dc 100644 --- a/docs/examples/llvm-project/output_unix.txt +++ b/docs/examples/llvm-project/output_unix.txt @@ -2,51 +2,51 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "libcxx/include/__config" impact on 18982 file(s) +1 : "libcxx/include/__config" impact on 18 982 files Included by: - 1 : "libcxx/include/math.h" line 294, impact on 17505 file(s) - 2 : "libcxx/include/stdlib.h" line 91, impact on 17505 file(s) - 3 : "libcxx/include/stdint.h" line 106, impact on 11752 file(s) - 4 : "libcxx/include/stddef.h" line 39, impact on 11042 file(s) - 5 : "libcxx/include/inttypes.h" line 238, impact on 9937 file(s) - 6 : "libcxx/include/setjmp.h" line 28, impact on 7910 file(s) - 7 : "libcxx/test/support/test_macros.h" line 18, impact on 5744 file(s) - 8 : "libcxx/include/stdio.h" line 101, impact on 3356 file(s) - 9 : "libcxx/include/string.h" line 54, impact on 1882 file(s) - 10 : "libcxx/include/limits.h" line 40, impact on 1068 file(s) + 1 : "libcxx/include/math.h" line 294, impact on 17 505 files + 2 : "libcxx/include/stdlib.h" line 91, impact on 17 505 files + 3 : "libcxx/include/stdint.h" line 106, impact on 11 752 files + 4 : "libcxx/include/stddef.h" line 39, impact on 11 042 files + 5 : "libcxx/include/inttypes.h" line 238, impact on 9 937 files + 6 : "libcxx/include/setjmp.h" line 28, impact on 7 910 files + 7 : "libcxx/test/support/test_macros.h" line 18, impact on 5 744 files + 8 : "libcxx/include/stdio.h" line 101, impact on 3 356 files + 9 : "libcxx/include/string.h" line 54, impact on 1 882 files + 10 : "libcxx/include/limits.h" line 40, impact on 1 068 files ... 10 of 48 details -2 : "libcxx/include/type_traits" impact on 17768 file(s) +2 : "libcxx/include/type_traits" impact on 17 768 files Included by: - 1 : "libcxx/include/math.h" line 311, impact on 17505 file(s) - 2 : "llvm/include/llvm/Support/type_traits.h" line 17, impact on 9534 file(s) - 3 : "llvm/include/llvm/ADT/iterator.h" line 16, impact on 9419 file(s) - 4 : "llvm/include/llvm/ADT/STLExtras.h" line 35, impact on 9405 file(s) - 5 : "llvm/include/llvm/Support/SwapByteOrder.h" line 20, impact on 9323 file(s) - 6 : "llvm/include/llvm/ADT/StringRef.h" line 21, impact on 9312 file(s) - 7 : "llvm/include/llvm/Support/MathExtras.h" line 23, impact on 9305 file(s) - 8 : "llvm/include/llvm/ADT/SmallVector.h" line 32, impact on 9242 file(s) - 9 : "llvm/include/llvm/ADT/ArrayRef.h" line 24, impact on 8875 file(s) - 10 : "llvm/include/llvm/Support/PointerLikeTypeTraits.h" line 19, impact on 8498 file(s) - ... 10 of 1372 details -3 : "libcxx/include/limits" impact on 17677 file(s) + 1 : "libcxx/include/math.h" line 311, impact on 17 505 files + 2 : "llvm/include/llvm/Support/type_traits.h" line 17, impact on 9 534 files + 3 : "llvm/include/llvm/ADT/iterator.h" line 16, impact on 9 419 files + 4 : "llvm/include/llvm/ADT/STLExtras.h" line 35, impact on 9 405 files + 5 : "llvm/include/llvm/Support/SwapByteOrder.h" line 20, impact on 9 323 files + 6 : "llvm/include/llvm/ADT/StringRef.h" line 21, impact on 9 312 files + 7 : "llvm/include/llvm/Support/MathExtras.h" line 23, impact on 9 305 files + 8 : "llvm/include/llvm/ADT/SmallVector.h" line 32, impact on 9 242 files + 9 : "llvm/include/llvm/ADT/ArrayRef.h" line 24, impact on 8 875 files + 10 : "llvm/include/llvm/Support/PointerLikeTypeTraits.h" line 19, impact on 8 498 files + ... 10 of 1 372 details +3 : "libcxx/include/limits" impact on 17 677 files Included by: - 1 : "libcxx/include/math.h" line 312, impact on 17505 file(s) - 2 : "llvm/include/llvm/ADT/STLExtras.h" line 32, impact on 9405 file(s) - 3 : "llvm/include/llvm/ADT/StringRef.h" line 19, impact on 9312 file(s) - 4 : "llvm/include/llvm/Support/MathExtras.h" line 22, impact on 9305 file(s) - 5 : "llvm/include/llvm/Support/Alignment.h" line 28, impact on 8063 file(s) - 6 : "llvm/include/llvm/ADT/PointerIntPair.h" line 21, impact on 6760 file(s) - 7 : "clang/include/clang/Basic/Diagnostic.h" line 31, impact on 2055 file(s) - 8 : "llvm/include/llvm/ADT/SmallBitVector.h" line 24, impact on 1103 file(s) - 9 : "llvm/include/llvm/ADT/SparseSet.h" line 28, impact on 746 file(s) - 10 : "clang/include/clang/ASTMatchers/ASTMatchers.h" line 89, impact on 695 file(s) + 1 : "libcxx/include/math.h" line 312, impact on 17 505 files + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 32, impact on 9 405 files + 3 : "llvm/include/llvm/ADT/StringRef.h" line 19, impact on 9 312 files + 4 : "llvm/include/llvm/Support/MathExtras.h" line 22, impact on 9 305 files + 5 : "llvm/include/llvm/Support/Alignment.h" line 28, impact on 8 063 files + 6 : "llvm/include/llvm/ADT/PointerIntPair.h" line 21, impact on 6 760 files + 7 : "clang/include/clang/Basic/Diagnostic.h" line 31, impact on 2 055 files + 8 : "llvm/include/llvm/ADT/SmallBitVector.h" line 24, impact on 1 103 files + 9 : "llvm/include/llvm/ADT/SparseSet.h" line 28, impact on 746 files + 10 : "clang/include/clang/ASTMatchers/ASTMatchers.h" line 89, impact on 695 files ... 10 of 379 details -4 : "libcxx/include/math.h" impact on 17505 file(s) +4 : "libcxx/include/math.h" impact on 17 505 files Included by: - 1 : "libcxx/include/stdlib.h" line 100, impact on 17505 file(s) - 2 : "llvm/include/llvm-c/DataTypes.h" line 30, impact on 9481 file(s) - 3 : "compiler-rt/lib/builtins/int_math.h" line 27, impact on 66 file(s) - 4 : "openmp/runtime/src/kmp_stats.h" line 30, impact on 18 file(s) + 1 : "libcxx/include/stdlib.h" line 100, impact on 17 505 files + 2 : "llvm/include/llvm-c/DataTypes.h" line 30, impact on 9 481 files + 3 : "compiler-rt/lib/builtins/int_math.h" line 27, impact on 66 files + 4 : "openmp/runtime/src/kmp_stats.h" line 30, impact on 18 files 5 : "compiler-rt/lib/msan/tests/msan_test.cpp" line 41 6 : "compiler-rt/test/asan/TestCases/frexp_interceptor.cpp" line 5 7 : "compiler-rt/test/builtins/Unit/adddf3vfp_test.c" line 18 @@ -54,85 +54,85 @@ Included by: 9 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmpeq_test.c" line 19 10 : "compiler-rt/test/builtins/Unit/arm/aeabi_cdcmple_test.c" line 21 ... 10 of 127 details -5 : "libcxx/include/stdlib.h" impact on 17505 file(s) +5 : "libcxx/include/stdlib.h" impact on 17 505 files Included by: - 1 : "libcxx/include/math.h" line 301, impact on 17505 file(s) - 2 : "llvm/include/llvm-c/DataTypes.h" line 63, impact on 9481 file(s) - 3 : "llvm/include/llvm/Support/SwapByteOrder.h" line 22, impact on 9323 file(s) - 4 : "clang/lib/Headers/mm_malloc.h" line 13, impact on 7943 file(s) - 5 : "libcxx/test/support/test_macros.h" line 301, impact on 5744 file(s) - 6 : "polly/lib/External/isl/include/isl/arg.h" line 14, impact on 316 file(s) - 7 : "polly/lib/External/isl/include/isl/ctx.h" line 14, impact on 315 file(s) - 8 : "compiler-rt/test/tsan/test.h" line 2, impact on 169 file(s) - 9 : "llgo/third_party/gofrontend/libffi/testsuite/libffi.call/ffitest.h" line 1, impact on 144 file(s) - 10 : "libcxx/test/support/platform_support.h" line 55, impact on 137 file(s) - ... 10 of 1003 details -6 : "libcxx/include/cassert" impact on 14768 file(s) + 1 : "libcxx/include/math.h" line 301, impact on 17 505 files + 2 : "llvm/include/llvm-c/DataTypes.h" line 63, impact on 9 481 files + 3 : "llvm/include/llvm/Support/SwapByteOrder.h" line 22, impact on 9 323 files + 4 : "clang/lib/Headers/mm_malloc.h" line 13, impact on 7 943 files + 5 : "libcxx/test/support/test_macros.h" line 301, impact on 5 744 files + 6 : "polly/lib/External/isl/include/isl/arg.h" line 14, impact on 316 files + 7 : "polly/lib/External/isl/include/isl/ctx.h" line 14, impact on 315 files + 8 : "compiler-rt/test/tsan/test.h" line 2, impact on 169 files + 9 : "llgo/third_party/gofrontend/libffi/testsuite/libffi.call/ffitest.h" line 1, impact on 144 files + 10 : "libcxx/test/support/platform_support.h" line 55, impact on 137 files + ... 10 of 1 003 details +6 : "libcxx/include/cassert" impact on 14 768 files Included by: - 1 : "llvm/include/llvm/ADT/Optional.h" line 21, impact on 9448 file(s) - 2 : "llvm/include/llvm/ADT/STLExtras.h" line 25, impact on 9405 file(s) - 3 : "llvm/include/llvm/ADT/StringRef.h" line 16, impact on 9312 file(s) - 4 : "llvm/include/llvm/Support/MathExtras.h" line 19, impact on 9305 file(s) - 5 : "llvm/include/llvm/ADT/SmallVector.h" line 24, impact on 9242 file(s) - 6 : "llvm/include/llvm/ADT/Hashing.h" line 52, impact on 8901 file(s) - 7 : "llvm/include/llvm/ADT/ArrayRef.h" line 19, impact on 8875 file(s) - 8 : "llvm/include/llvm/ADT/Twine.h" line 15, impact on 8386 file(s) - 9 : "llvm/include/llvm/Support/raw_ostream.h" line 18, impact on 8269 file(s) - 10 : "llvm/include/llvm/Support/Alignment.h" line 27, impact on 8063 file(s) - ... 10 of 6042 details -7 : "libcxx/include/cstddef" impact on 11856 file(s) + 1 : "llvm/include/llvm/ADT/Optional.h" line 21, impact on 9 448 files + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 25, impact on 9 405 files + 3 : "llvm/include/llvm/ADT/StringRef.h" line 16, impact on 9 312 files + 4 : "llvm/include/llvm/Support/MathExtras.h" line 19, impact on 9 305 files + 5 : "llvm/include/llvm/ADT/SmallVector.h" line 24, impact on 9 242 files + 6 : "llvm/include/llvm/ADT/Hashing.h" line 52, impact on 8 901 files + 7 : "llvm/include/llvm/ADT/ArrayRef.h" line 19, impact on 8 875 files + 8 : "llvm/include/llvm/ADT/Twine.h" line 15, impact on 8 386 files + 9 : "llvm/include/llvm/Support/raw_ostream.h" line 18, impact on 8 269 files + 10 : "llvm/include/llvm/Support/Alignment.h" line 27, impact on 8 063 files + ... 10 of 6 042 details +7 : "libcxx/include/cstddef" impact on 11 856 files Included by: - 1 : "llvm/include/llvm-c/DataTypes.h" line 59, impact on 9481 file(s) - 2 : "llvm/include/llvm/ADT/iterator.h" line 14, impact on 9419 file(s) - 3 : "llvm/include/llvm/ADT/STLExtras.h" line 26, impact on 9405 file(s) - 4 : "llvm/include/llvm/Support/SwapByteOrder.h" line 19, impact on 9323 file(s) - 5 : "llvm/include/llvm/ADT/StringRef.h" line 17, impact on 9312 file(s) - 6 : "llvm/include/llvm/Support/AlignOf.h" line 17, impact on 9249 file(s) - 7 : "llvm/include/llvm/ADT/SmallVector.h" line 25, impact on 9242 file(s) - 8 : "llvm/include/llvm/ADT/ArrayRef.h" line 20, impact on 8875 file(s) - 9 : "llvm/include/llvm/Support/raw_ostream.h" line 19, impact on 8269 file(s) - 10 : "llvm/include/llvm/ADT/SmallString.h" line 18, impact on 8032 file(s) + 1 : "llvm/include/llvm-c/DataTypes.h" line 59, impact on 9 481 files + 2 : "llvm/include/llvm/ADT/iterator.h" line 14, impact on 9 419 files + 3 : "llvm/include/llvm/ADT/STLExtras.h" line 26, impact on 9 405 files + 4 : "llvm/include/llvm/Support/SwapByteOrder.h" line 19, impact on 9 323 files + 5 : "llvm/include/llvm/ADT/StringRef.h" line 17, impact on 9 312 files + 6 : "llvm/include/llvm/Support/AlignOf.h" line 17, impact on 9 249 files + 7 : "llvm/include/llvm/ADT/SmallVector.h" line 25, impact on 9 242 files + 8 : "llvm/include/llvm/ADT/ArrayRef.h" line 20, impact on 8 875 files + 9 : "llvm/include/llvm/Support/raw_ostream.h" line 19, impact on 8 269 files + 10 : "llvm/include/llvm/ADT/SmallString.h" line 18, impact on 8 032 files ... 10 of 890 details -8 : "libcxx/include/stdint.h" impact on 11752 file(s) +8 : "libcxx/include/stdint.h" impact on 11 752 files Included by: - 1 : "compiler-rt/include/sanitizer/common_interface_defs.h" line 16, impact on 10001 file(s) - 2 : "libcxx/include/inttypes.h" line 255, impact on 9937 file(s) - 3 : "llvm/include/llvm-c/DataTypes.h" line 34, impact on 9481 file(s) - 4 : "lldb/include/lldb/lldb-types.h" line 15, impact on 1722 file(s) - 5 : "llvm/include/llvm/IR/FPEnv.h" line 20, impact on 1196 file(s) - 6 : "lldb/include/lldb/Utility/Status.h" line 18, impact on 1129 file(s) - 7 : "lldb/include/lldb/Utility/FileSpec.h" line 23, impact on 1128 file(s) - 8 : "lldb/include/lldb/Utility/Stream.h" line 21, impact on 983 file(s) - 9 : "lldb/include/lldb/Core/Address.h" line 18, impact on 845 file(s) - 10 : "lldb/include/lldb/Utility/Endian.h" line 14, impact on 751 file(s) + 1 : "compiler-rt/include/sanitizer/common_interface_defs.h" line 16, impact on 10 001 files + 2 : "libcxx/include/inttypes.h" line 255, impact on 9 937 files + 3 : "llvm/include/llvm-c/DataTypes.h" line 34, impact on 9 481 files + 4 : "lldb/include/lldb/lldb-types.h" line 15, impact on 1 722 files + 5 : "llvm/include/llvm/IR/FPEnv.h" line 20, impact on 1 196 files + 6 : "lldb/include/lldb/Utility/Status.h" line 18, impact on 1 129 files + 7 : "lldb/include/lldb/Utility/FileSpec.h" line 23, impact on 1 128 files + 8 : "lldb/include/lldb/Utility/Stream.h" line 21, impact on 983 files + 9 : "lldb/include/lldb/Core/Address.h" line 18, impact on 845 files + 10 : "lldb/include/lldb/Utility/Endian.h" line 14, impact on 751 files ... 10 of 430 details -9 : "libcxx/include/memory" impact on 11478 file(s) +9 : "libcxx/include/memory" impact on 11 478 files Included by: - 1 : "llvm/include/llvm/ADT/Optional.h" line 22, impact on 9448 file(s) - 2 : "llvm/include/llvm/ADT/STLExtras.h" line 33, impact on 9405 file(s) - 3 : "llvm/include/llvm/ADT/SmallVector.h" line 30, impact on 9242 file(s) - 4 : "llvm/include/llvm/ADT/ArrayRef.h" line 23, impact on 8875 file(s) - 5 : "llvm/include/llvm/Support/Casting.h" line 20, impact on 7366 file(s) - 6 : "llvm/include/llvm/Support/Error.h" line 34, impact on 6869 file(s) - 7 : "llvm/include/llvm/Support/FileSystem.h" line 41, impact on 5728 file(s) - 8 : "llvm/include/llvm/ADT/APFloat.h" line 22, impact on 5376 file(s) - 9 : "llvm/include/llvm/Support/MemoryBuffer.h" line 25, impact on 5178 file(s) - 10 : "llvm/include/llvm/Support/SourceMgr.h" line 28, impact on 4601 file(s) - ... 10 of 1310 details -10 : "libcxx/include/cstdlib" impact on 11439 file(s) + 1 : "llvm/include/llvm/ADT/Optional.h" line 22, impact on 9 448 files + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 33, impact on 9 405 files + 3 : "llvm/include/llvm/ADT/SmallVector.h" line 30, impact on 9 242 files + 4 : "llvm/include/llvm/ADT/ArrayRef.h" line 23, impact on 8 875 files + 5 : "llvm/include/llvm/Support/Casting.h" line 20, impact on 7 366 files + 6 : "llvm/include/llvm/Support/Error.h" line 34, impact on 6 869 files + 7 : "llvm/include/llvm/Support/FileSystem.h" line 41, impact on 5 728 files + 8 : "llvm/include/llvm/ADT/APFloat.h" line 22, impact on 5 376 files + 9 : "llvm/include/llvm/Support/MemoryBuffer.h" line 25, impact on 5 178 files + 10 : "llvm/include/llvm/Support/SourceMgr.h" line 28, impact on 4 601 files + ... 10 of 1 310 details +10 : "libcxx/include/cstdlib" impact on 11 439 files Included by: - 1 : "llvm/include/llvm-c/DataTypes.h" line 60, impact on 9481 file(s) - 2 : "llvm/include/llvm/ADT/STLExtras.h" line 28, impact on 9405 file(s) - 3 : "llvm/include/llvm/Support/MemAlloc.h" line 21, impact on 9243 file(s) - 4 : "llvm/include/llvm/ADT/SmallVector.h" line 26, impact on 9242 file(s) - 5 : "llvm/include/llvm/Support/Allocator.h" line 34, impact on 8025 file(s) - 6 : "llvm/include/llvm/ADT/StringMap.h" line 25, impact on 7738 file(s) - 7 : "llvm/include/llvm/ADT/StringExtras.h" line 23, impact on 6930 file(s) - 8 : "llvm/include/llvm/Support/Error.h" line 32, impact on 6869 file(s) - 9 : "llvm/include/llvm/ADT/SmallPtrSet.h" line 23, impact on 5164 file(s) - 10 : "llvm/include/llvm/ADT/BitVector.h" line 23, impact on 4074 file(s) + 1 : "llvm/include/llvm-c/DataTypes.h" line 60, impact on 9 481 files + 2 : "llvm/include/llvm/ADT/STLExtras.h" line 28, impact on 9 405 files + 3 : "llvm/include/llvm/Support/MemAlloc.h" line 21, impact on 9 243 files + 4 : "llvm/include/llvm/ADT/SmallVector.h" line 26, impact on 9 242 files + 5 : "llvm/include/llvm/Support/Allocator.h" line 34, impact on 8 025 files + 6 : "llvm/include/llvm/ADT/StringMap.h" line 25, impact on 7 738 files + 7 : "llvm/include/llvm/ADT/StringExtras.h" line 23, impact on 6 930 files + 8 : "llvm/include/llvm/Support/Error.h" line 32, impact on 6 869 files + 9 : "llvm/include/llvm/ADT/SmallPtrSet.h" line 23, impact on 5 164 files + 10 : "llvm/include/llvm/ADT/BitVector.h" line 23, impact on 4 074 files ... 10 of 570 details -... 10 of 5969 files +... 10 of 5 969 files Unincluded headers: 1 : "clang/include/clang/Analysis/AnalysisDiagnostic.h" 2 : "clang/include/clang/Analysis/FlowSensitive/DataflowValues.h" diff --git a/docs/examples/llvm-project/output_win.txt b/docs/examples/llvm-project/output_win.txt index 4c0ac8c..8fae933 100644 --- a/docs/examples/llvm-project/output_win.txt +++ b/docs/examples/llvm-project/output_win.txt @@ -2,51 +2,51 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "libcxx\include\__config" impact on 18982 file(s) +1 : "libcxx\include\__config" impact on 18 982 files Included by: - 1 : "libcxx\include\math.h" line 294, impact on 17505 file(s) - 2 : "libcxx\include\stdlib.h" line 91, impact on 17505 file(s) - 3 : "libcxx\include\stdint.h" line 106, impact on 11752 file(s) - 4 : "libcxx\include\stddef.h" line 39, impact on 11042 file(s) - 5 : "libcxx\include\inttypes.h" line 238, impact on 9937 file(s) - 6 : "libcxx\include\setjmp.h" line 28, impact on 7910 file(s) - 7 : "libcxx\test\support\test_macros.h" line 18, impact on 5744 file(s) - 8 : "libcxx\include\stdio.h" line 101, impact on 3356 file(s) - 9 : "libcxx\include\string.h" line 54, impact on 1882 file(s) - 10 : "libcxx\include\limits.h" line 40, impact on 1068 file(s) + 1 : "libcxx\include\math.h" line 294, impact on 17 505 files + 2 : "libcxx\include\stdlib.h" line 91, impact on 17 505 files + 3 : "libcxx\include\stdint.h" line 106, impact on 11 752 files + 4 : "libcxx\include\stddef.h" line 39, impact on 11 042 files + 5 : "libcxx\include\inttypes.h" line 238, impact on 9 937 files + 6 : "libcxx\include\setjmp.h" line 28, impact on 7 910 files + 7 : "libcxx\test\support\test_macros.h" line 18, impact on 5 744 files + 8 : "libcxx\include\stdio.h" line 101, impact on 3 356 files + 9 : "libcxx\include\string.h" line 54, impact on 1 882 files + 10 : "libcxx\include\limits.h" line 40, impact on 1 068 files ... 10 of 48 details -2 : "libcxx\include\type_traits" impact on 17768 file(s) +2 : "libcxx\include\type_traits" impact on 17 768 files Included by: - 1 : "libcxx\include\math.h" line 311, impact on 17505 file(s) - 2 : "llvm\include\llvm\Support\type_traits.h" line 17, impact on 9534 file(s) - 3 : "llvm\include\llvm\ADT\iterator.h" line 16, impact on 9419 file(s) - 4 : "llvm\include\llvm\ADT\STLExtras.h" line 35, impact on 9405 file(s) - 5 : "llvm\include\llvm\Support\SwapByteOrder.h" line 20, impact on 9323 file(s) - 6 : "llvm\include\llvm\ADT\StringRef.h" line 21, impact on 9312 file(s) - 7 : "llvm\include\llvm\Support\MathExtras.h" line 23, impact on 9305 file(s) - 8 : "llvm\include\llvm\ADT\SmallVector.h" line 32, impact on 9242 file(s) - 9 : "llvm\include\llvm\ADT\ArrayRef.h" line 24, impact on 8875 file(s) - 10 : "llvm\include\llvm\Support\PointerLikeTypeTraits.h" line 19, impact on 8498 file(s) - ... 10 of 1372 details -3 : "libcxx\include\limits" impact on 17677 file(s) + 1 : "libcxx\include\math.h" line 311, impact on 17 505 files + 2 : "llvm\include\llvm\Support\type_traits.h" line 17, impact on 9 534 files + 3 : "llvm\include\llvm\ADT\iterator.h" line 16, impact on 9 419 files + 4 : "llvm\include\llvm\ADT\STLExtras.h" line 35, impact on 9 405 files + 5 : "llvm\include\llvm\Support\SwapByteOrder.h" line 20, impact on 9 323 files + 6 : "llvm\include\llvm\ADT\StringRef.h" line 21, impact on 9 312 files + 7 : "llvm\include\llvm\Support\MathExtras.h" line 23, impact on 9 305 files + 8 : "llvm\include\llvm\ADT\SmallVector.h" line 32, impact on 9 242 files + 9 : "llvm\include\llvm\ADT\ArrayRef.h" line 24, impact on 8 875 files + 10 : "llvm\include\llvm\Support\PointerLikeTypeTraits.h" line 19, impact on 8 498 files + ... 10 of 1 372 details +3 : "libcxx\include\limits" impact on 17 677 files Included by: - 1 : "libcxx\include\math.h" line 312, impact on 17505 file(s) - 2 : "llvm\include\llvm\ADT\STLExtras.h" line 32, impact on 9405 file(s) - 3 : "llvm\include\llvm\ADT\StringRef.h" line 19, impact on 9312 file(s) - 4 : "llvm\include\llvm\Support\MathExtras.h" line 22, impact on 9305 file(s) - 5 : "llvm\include\llvm\Support\Alignment.h" line 28, impact on 8063 file(s) - 6 : "llvm\include\llvm\ADT\PointerIntPair.h" line 21, impact on 6760 file(s) - 7 : "clang\include\clang\Basic\Diagnostic.h" line 31, impact on 2055 file(s) - 8 : "llvm\include\llvm\ADT\SmallBitVector.h" line 24, impact on 1103 file(s) - 9 : "llvm\include\llvm\ADT\SparseSet.h" line 28, impact on 746 file(s) - 10 : "clang\include\clang\ASTMatchers\ASTMatchers.h" line 89, impact on 695 file(s) + 1 : "libcxx\include\math.h" line 312, impact on 17 505 files + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 32, impact on 9 405 files + 3 : "llvm\include\llvm\ADT\StringRef.h" line 19, impact on 9 312 files + 4 : "llvm\include\llvm\Support\MathExtras.h" line 22, impact on 9 305 files + 5 : "llvm\include\llvm\Support\Alignment.h" line 28, impact on 8 063 files + 6 : "llvm\include\llvm\ADT\PointerIntPair.h" line 21, impact on 6 760 files + 7 : "clang\include\clang\Basic\Diagnostic.h" line 31, impact on 2 055 files + 8 : "llvm\include\llvm\ADT\SmallBitVector.h" line 24, impact on 1 103 files + 9 : "llvm\include\llvm\ADT\SparseSet.h" line 28, impact on 746 files + 10 : "clang\include\clang\ASTMatchers\ASTMatchers.h" line 89, impact on 695 files ... 10 of 379 details -4 : "libcxx\include\math.h" impact on 17505 file(s) +4 : "libcxx\include\math.h" impact on 17 505 files Included by: - 1 : "libcxx\include\stdlib.h" line 100, impact on 17505 file(s) - 2 : "llvm\include\llvm-c\DataTypes.h" line 30, impact on 9481 file(s) - 3 : "compiler-rt\lib\builtins\int_math.h" line 27, impact on 66 file(s) - 4 : "openmp\runtime\src\kmp_stats.h" line 30, impact on 18 file(s) + 1 : "libcxx\include\stdlib.h" line 100, impact on 17 505 files + 2 : "llvm\include\llvm-c\DataTypes.h" line 30, impact on 9 481 files + 3 : "compiler-rt\lib\builtins\int_math.h" line 27, impact on 66 files + 4 : "openmp\runtime\src\kmp_stats.h" line 30, impact on 18 files 5 : "compiler-rt\lib\msan\tests\msan_test.cpp" line 41 6 : "compiler-rt\test\asan\TestCases\frexp_interceptor.cpp" line 5 7 : "compiler-rt\test\builtins\Unit\adddf3vfp_test.c" line 18 @@ -54,85 +54,85 @@ Included by: 9 : "compiler-rt\test\builtins\Unit\arm\aeabi_cdcmpeq_test.c" line 19 10 : "compiler-rt\test\builtins\Unit\arm\aeabi_cdcmple_test.c" line 21 ... 10 of 127 details -5 : "libcxx\include\stdlib.h" impact on 17505 file(s) +5 : "libcxx\include\stdlib.h" impact on 17 505 files Included by: - 1 : "libcxx\include\math.h" line 301, impact on 17505 file(s) - 2 : "llvm\include\llvm-c\DataTypes.h" line 63, impact on 9481 file(s) - 3 : "llvm\include\llvm\Support\SwapByteOrder.h" line 22, impact on 9323 file(s) - 4 : "clang\lib\Headers\mm_malloc.h" line 13, impact on 7943 file(s) - 5 : "libcxx\test\support\test_macros.h" line 301, impact on 5744 file(s) - 6 : "polly\lib\External\isl\include\isl\arg.h" line 14, impact on 316 file(s) - 7 : "polly\lib\External\isl\include\isl\ctx.h" line 14, impact on 315 file(s) - 8 : "compiler-rt\test\tsan\test.h" line 2, impact on 169 file(s) - 9 : "llgo\third_party\gofrontend\libffi\testsuite\libffi.call\ffitest.h" line 1, impact on 144 file(s) - 10 : "libcxx\test\support\platform_support.h" line 55, impact on 137 file(s) - ... 10 of 1003 details -6 : "libcxx\include\cassert" impact on 14768 file(s) + 1 : "libcxx\include\math.h" line 301, impact on 17 505 files + 2 : "llvm\include\llvm-c\DataTypes.h" line 63, impact on 9 481 files + 3 : "llvm\include\llvm\Support\SwapByteOrder.h" line 22, impact on 9 323 files + 4 : "clang\lib\Headers\mm_malloc.h" line 13, impact on 7 943 files + 5 : "libcxx\test\support\test_macros.h" line 301, impact on 5 744 files + 6 : "polly\lib\External\isl\include\isl\arg.h" line 14, impact on 316 files + 7 : "polly\lib\External\isl\include\isl\ctx.h" line 14, impact on 315 files + 8 : "compiler-rt\test\tsan\test.h" line 2, impact on 169 files + 9 : "llgo\third_party\gofrontend\libffi\testsuite\libffi.call\ffitest.h" line 1, impact on 144 files + 10 : "libcxx\test\support\platform_support.h" line 55, impact on 137 files + ... 10 of 1 003 details +6 : "libcxx\include\cassert" impact on 14 768 files Included by: - 1 : "llvm\include\llvm\ADT\Optional.h" line 21, impact on 9448 file(s) - 2 : "llvm\include\llvm\ADT\STLExtras.h" line 25, impact on 9405 file(s) - 3 : "llvm\include\llvm\ADT\StringRef.h" line 16, impact on 9312 file(s) - 4 : "llvm\include\llvm\Support\MathExtras.h" line 19, impact on 9305 file(s) - 5 : "llvm\include\llvm\ADT\SmallVector.h" line 24, impact on 9242 file(s) - 6 : "llvm\include\llvm\ADT\Hashing.h" line 52, impact on 8901 file(s) - 7 : "llvm\include\llvm\ADT\ArrayRef.h" line 19, impact on 8875 file(s) - 8 : "llvm\include\llvm\ADT\Twine.h" line 15, impact on 8386 file(s) - 9 : "llvm\include\llvm\Support\raw_ostream.h" line 18, impact on 8269 file(s) - 10 : "llvm\include\llvm\Support\Alignment.h" line 27, impact on 8063 file(s) - ... 10 of 6042 details -7 : "libcxx\include\cstddef" impact on 11856 file(s) + 1 : "llvm\include\llvm\ADT\Optional.h" line 21, impact on 9 448 files + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 25, impact on 9 405 files + 3 : "llvm\include\llvm\ADT\StringRef.h" line 16, impact on 9 312 files + 4 : "llvm\include\llvm\Support\MathExtras.h" line 19, impact on 9 305 files + 5 : "llvm\include\llvm\ADT\SmallVector.h" line 24, impact on 9 242 files + 6 : "llvm\include\llvm\ADT\Hashing.h" line 52, impact on 8 901 files + 7 : "llvm\include\llvm\ADT\ArrayRef.h" line 19, impact on 8 875 files + 8 : "llvm\include\llvm\ADT\Twine.h" line 15, impact on 8 386 files + 9 : "llvm\include\llvm\Support\raw_ostream.h" line 18, impact on 8 269 files + 10 : "llvm\include\llvm\Support\Alignment.h" line 27, impact on 8 063 files + ... 10 of 6 042 details +7 : "libcxx\include\cstddef" impact on 11 856 files Included by: - 1 : "llvm\include\llvm-c\DataTypes.h" line 59, impact on 9481 file(s) - 2 : "llvm\include\llvm\ADT\iterator.h" line 14, impact on 9419 file(s) - 3 : "llvm\include\llvm\ADT\STLExtras.h" line 26, impact on 9405 file(s) - 4 : "llvm\include\llvm\Support\SwapByteOrder.h" line 19, impact on 9323 file(s) - 5 : "llvm\include\llvm\ADT\StringRef.h" line 17, impact on 9312 file(s) - 6 : "llvm\include\llvm\Support\AlignOf.h" line 17, impact on 9249 file(s) - 7 : "llvm\include\llvm\ADT\SmallVector.h" line 25, impact on 9242 file(s) - 8 : "llvm\include\llvm\ADT\ArrayRef.h" line 20, impact on 8875 file(s) - 9 : "llvm\include\llvm\Support\raw_ostream.h" line 19, impact on 8269 file(s) - 10 : "llvm\include\llvm\ADT\SmallString.h" line 18, impact on 8032 file(s) + 1 : "llvm\include\llvm-c\DataTypes.h" line 59, impact on 9 481 files + 2 : "llvm\include\llvm\ADT\iterator.h" line 14, impact on 9 419 files + 3 : "llvm\include\llvm\ADT\STLExtras.h" line 26, impact on 9 405 files + 4 : "llvm\include\llvm\Support\SwapByteOrder.h" line 19, impact on 9 323 files + 5 : "llvm\include\llvm\ADT\StringRef.h" line 17, impact on 9 312 files + 6 : "llvm\include\llvm\Support\AlignOf.h" line 17, impact on 9 249 files + 7 : "llvm\include\llvm\ADT\SmallVector.h" line 25, impact on 9 242 files + 8 : "llvm\include\llvm\ADT\ArrayRef.h" line 20, impact on 8 875 files + 9 : "llvm\include\llvm\Support\raw_ostream.h" line 19, impact on 8 269 files + 10 : "llvm\include\llvm\ADT\SmallString.h" line 18, impact on 8 032 files ... 10 of 890 details -8 : "libcxx\include\stdint.h" impact on 11752 file(s) +8 : "libcxx\include\stdint.h" impact on 11 752 files Included by: - 1 : "compiler-rt\include\sanitizer\common_interface_defs.h" line 16, impact on 10001 file(s) - 2 : "libcxx\include\inttypes.h" line 255, impact on 9937 file(s) - 3 : "llvm\include\llvm-c\DataTypes.h" line 34, impact on 9481 file(s) - 4 : "lldb\include\lldb\lldb-types.h" line 15, impact on 1722 file(s) - 5 : "llvm\include\llvm\IR\FPEnv.h" line 20, impact on 1196 file(s) - 6 : "lldb\include\lldb\Utility\Status.h" line 18, impact on 1129 file(s) - 7 : "lldb\include\lldb\Utility\FileSpec.h" line 23, impact on 1128 file(s) - 8 : "lldb\include\lldb\Utility\Stream.h" line 21, impact on 983 file(s) - 9 : "lldb\include\lldb\Core\Address.h" line 18, impact on 845 file(s) - 10 : "lldb\include\lldb\Utility\Endian.h" line 14, impact on 751 file(s) + 1 : "compiler-rt\include\sanitizer\common_interface_defs.h" line 16, impact on 10 001 files + 2 : "libcxx\include\inttypes.h" line 255, impact on 9 937 files + 3 : "llvm\include\llvm-c\DataTypes.h" line 34, impact on 9 481 files + 4 : "lldb\include\lldb\lldb-types.h" line 15, impact on 1 722 files + 5 : "llvm\include\llvm\IR\FPEnv.h" line 20, impact on 1 196 files + 6 : "lldb\include\lldb\Utility\Status.h" line 18, impact on 1 129 files + 7 : "lldb\include\lldb\Utility\FileSpec.h" line 23, impact on 1 128 files + 8 : "lldb\include\lldb\Utility\Stream.h" line 21, impact on 983 files + 9 : "lldb\include\lldb\Core\Address.h" line 18, impact on 845 files + 10 : "lldb\include\lldb\Utility\Endian.h" line 14, impact on 751 files ... 10 of 430 details -9 : "libcxx\include\memory" impact on 11478 file(s) +9 : "libcxx\include\memory" impact on 11 478 files Included by: - 1 : "llvm\include\llvm\ADT\Optional.h" line 22, impact on 9448 file(s) - 2 : "llvm\include\llvm\ADT\STLExtras.h" line 33, impact on 9405 file(s) - 3 : "llvm\include\llvm\ADT\SmallVector.h" line 30, impact on 9242 file(s) - 4 : "llvm\include\llvm\ADT\ArrayRef.h" line 23, impact on 8875 file(s) - 5 : "llvm\include\llvm\Support\Casting.h" line 20, impact on 7366 file(s) - 6 : "llvm\include\llvm\Support\Error.h" line 34, impact on 6869 file(s) - 7 : "llvm\include\llvm\Support\FileSystem.h" line 41, impact on 5728 file(s) - 8 : "llvm\include\llvm\ADT\APFloat.h" line 22, impact on 5376 file(s) - 9 : "llvm\include\llvm\Support\MemoryBuffer.h" line 25, impact on 5178 file(s) - 10 : "llvm\include\llvm\Support\SourceMgr.h" line 28, impact on 4601 file(s) - ... 10 of 1310 details -10 : "libcxx\include\cstdlib" impact on 11439 file(s) + 1 : "llvm\include\llvm\ADT\Optional.h" line 22, impact on 9 448 files + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 33, impact on 9 405 files + 3 : "llvm\include\llvm\ADT\SmallVector.h" line 30, impact on 9 242 files + 4 : "llvm\include\llvm\ADT\ArrayRef.h" line 23, impact on 8 875 files + 5 : "llvm\include\llvm\Support\Casting.h" line 20, impact on 7 366 files + 6 : "llvm\include\llvm\Support\Error.h" line 34, impact on 6 869 files + 7 : "llvm\include\llvm\Support\FileSystem.h" line 41, impact on 5 728 files + 8 : "llvm\include\llvm\ADT\APFloat.h" line 22, impact on 5 376 files + 9 : "llvm\include\llvm\Support\MemoryBuffer.h" line 25, impact on 5 178 files + 10 : "llvm\include\llvm\Support\SourceMgr.h" line 28, impact on 4 601 files + ... 10 of 1 310 details +10 : "libcxx\include\cstdlib" impact on 11 439 files Included by: - 1 : "llvm\include\llvm-c\DataTypes.h" line 60, impact on 9481 file(s) - 2 : "llvm\include\llvm\ADT\STLExtras.h" line 28, impact on 9405 file(s) - 3 : "llvm\include\llvm\Support\MemAlloc.h" line 21, impact on 9243 file(s) - 4 : "llvm\include\llvm\ADT\SmallVector.h" line 26, impact on 9242 file(s) - 5 : "llvm\include\llvm\Support\Allocator.h" line 34, impact on 8025 file(s) - 6 : "llvm\include\llvm\ADT\StringMap.h" line 25, impact on 7738 file(s) - 7 : "llvm\include\llvm\ADT\StringExtras.h" line 23, impact on 6930 file(s) - 8 : "llvm\include\llvm\Support\Error.h" line 32, impact on 6869 file(s) - 9 : "llvm\include\llvm\ADT\SmallPtrSet.h" line 23, impact on 5164 file(s) - 10 : "llvm\include\llvm\ADT\BitVector.h" line 23, impact on 4074 file(s) + 1 : "llvm\include\llvm-c\DataTypes.h" line 60, impact on 9 481 files + 2 : "llvm\include\llvm\ADT\STLExtras.h" line 28, impact on 9 405 files + 3 : "llvm\include\llvm\Support\MemAlloc.h" line 21, impact on 9 243 files + 4 : "llvm\include\llvm\ADT\SmallVector.h" line 26, impact on 9 242 files + 5 : "llvm\include\llvm\Support\Allocator.h" line 34, impact on 8 025 files + 6 : "llvm\include\llvm\ADT\StringMap.h" line 25, impact on 7 738 files + 7 : "llvm\include\llvm\ADT\StringExtras.h" line 23, impact on 6 930 files + 8 : "llvm\include\llvm\Support\Error.h" line 32, impact on 6 869 files + 9 : "llvm\include\llvm\ADT\SmallPtrSet.h" line 23, impact on 5 164 files + 10 : "llvm\include\llvm\ADT\BitVector.h" line 23, impact on 4 074 files ... 10 of 570 details -... 10 of 5975 files +... 10 of 5 975 files Unincluded headers: 1 : "clang\include\clang\Analysis\AnalysisDiagnostic.h" 2 : "clang\include\clang\Analysis\FlowSensitive\DataflowValues.h" diff --git a/docs/examples/lua/output_unix.txt b/docs/examples/lua/output_unix.txt index 151bc8f..61d8760 100644 --- a/docs/examples/lua/output_unix.txt +++ b/docs/examples/lua/output_unix.txt @@ -2,374 +2,374 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "luaconf.h" impact on 62 file(s) +1 : "luaconf.h" impact on 62 files Included by: - 1 : "lua.h" line 16, impact on 61 file(s) + 1 : "lua.h" line 16, impact on 61 files 2 : "onelua.c" line 49 -2 : "lua.h" impact on 61 file(s) +2 : "lua.h" impact on 61 files Included by: - 1 : "llimits.h" line 15, impact on 40 file(s) - 2 : "lobject.h" line 16, impact on 34 file(s) - 3 : "lstate.h" line 10, impact on 26 file(s) - 4 : "lauxlib.h" line 15, impact on 18 file(s) - 5 : "lmem.h" line 14, impact on 15 file(s) - 6 : "lualib.h" line 11, impact on 14 file(s) - 7 : "lctype.h" line 10, impact on 5 file(s) - 8 : "lapi.c" line 17, impact on 1 file(s) - 9 : "lauxlib.c" line 25, impact on 1 file(s) - 10 : "lbaselib.c" line 18, impact on 1 file(s) - 11 : "lcode.c" line 17, impact on 1 file(s) - 12 : "lcorolib.c" line 15, impact on 1 file(s) - 13 : "ldblib.c" line 17, impact on 1 file(s) - 14 : "ldebug.c" line 17, impact on 1 file(s) - 15 : "ldo.c" line 17, impact on 1 file(s) - 16 : "ldump.c" line 15, impact on 1 file(s) - 17 : "lfunc.c" line 15, impact on 1 file(s) - 18 : "lgc.c" line 16, impact on 1 file(s) - 19 : "linit.c" line 32, impact on 1 file(s) - 20 : "liolib.c" line 20, impact on 1 file(s) - 21 : "llex.c" line 16, impact on 1 file(s) - 22 : "lmathlib.c" line 19, impact on 1 file(s) - 23 : "lmem.c" line 15, impact on 1 file(s) - 24 : "loadlib.c" line 21, impact on 1 file(s) - 25 : "lobject.c" line 20, impact on 1 file(s) - 26 : "loslib.c" line 19, impact on 1 file(s) - 27 : "lparser.c" line 16, impact on 1 file(s) - 28 : "lstate.c" line 16, impact on 1 file(s) - 29 : "lstring.c" line 15, impact on 1 file(s) - 30 : "lstrlib.c" line 23, impact on 1 file(s) + 1 : "llimits.h" line 15, impact on 40 files + 2 : "lobject.h" line 16, impact on 34 files + 3 : "lstate.h" line 10, impact on 26 files + 4 : "lauxlib.h" line 15, impact on 18 files + 5 : "lmem.h" line 14, impact on 15 files + 6 : "lualib.h" line 11, impact on 14 files + 7 : "lctype.h" line 10, impact on 5 files + 8 : "lapi.c" line 17, impact on 1 file + 9 : "lauxlib.c" line 25, impact on 1 file + 10 : "lbaselib.c" line 18, impact on 1 file + 11 : "lcode.c" line 17, impact on 1 file + 12 : "lcorolib.c" line 15, impact on 1 file + 13 : "ldblib.c" line 17, impact on 1 file + 14 : "ldebug.c" line 17, impact on 1 file + 15 : "ldo.c" line 17, impact on 1 file + 16 : "ldump.c" line 15, impact on 1 file + 17 : "lfunc.c" line 15, impact on 1 file + 18 : "lgc.c" line 16, impact on 1 file + 19 : "linit.c" line 32, impact on 1 file + 20 : "liolib.c" line 20, impact on 1 file + 21 : "llex.c" line 16, impact on 1 file + 22 : "lmathlib.c" line 19, impact on 1 file + 23 : "lmem.c" line 15, impact on 1 file + 24 : "loadlib.c" line 21, impact on 1 file + 25 : "lobject.c" line 20, impact on 1 file + 26 : "loslib.c" line 19, impact on 1 file + 27 : "lparser.c" line 16, impact on 1 file + 28 : "lstate.c" line 16, impact on 1 file + 29 : "lstring.c" line 15, impact on 1 file + 30 : "lstrlib.c" line 23, impact on 1 file ... 30 of 44 details -3 : "llimits.h" impact on 40 file(s) +3 : "llimits.h" impact on 40 files Included by: - 1 : "lobject.h" line 15, impact on 34 file(s) - 2 : "lmem.h" line 13, impact on 15 file(s) - 3 : "lopcodes.h" line 10, impact on 9 file(s) - 4 : "lparser.h" line 10, impact on 8 file(s) - 5 : "lapi.h" line 11, impact on 6 file(s) - 6 : "lctype.h" line 36, impact on 5 file(s) - 7 : "lundump.h" line 10, impact on 5 file(s) - 8 : "lzio.c" line 17, impact on 1 file(s) -4 : "lprefix.h" impact on 35 file(s) + 1 : "lobject.h" line 15, impact on 34 files + 2 : "lmem.h" line 13, impact on 15 files + 3 : "lopcodes.h" line 10, impact on 9 files + 4 : "lparser.h" line 10, impact on 8 files + 5 : "lapi.h" line 11, impact on 6 files + 6 : "lctype.h" line 36, impact on 5 files + 7 : "lundump.h" line 10, impact on 5 files + 8 : "lzio.c" line 17, impact on 1 file +4 : "lprefix.h" impact on 35 files Included by: - 1 : "lapi.c" line 10, impact on 1 file(s) - 2 : "lauxlib.c" line 10, impact on 1 file(s) - 3 : "lbaselib.c" line 10, impact on 1 file(s) - 4 : "lcode.c" line 10, impact on 1 file(s) - 5 : "lcorolib.c" line 10, impact on 1 file(s) - 6 : "lctype.c" line 10, impact on 1 file(s) - 7 : "ldblib.c" line 10, impact on 1 file(s) - 8 : "ldebug.c" line 10, impact on 1 file(s) - 9 : "ldo.c" line 10, impact on 1 file(s) - 10 : "ldump.c" line 10, impact on 1 file(s) - 11 : "lfunc.c" line 10, impact on 1 file(s) - 12 : "lgc.c" line 10, impact on 1 file(s) - 13 : "linit.c" line 27, impact on 1 file(s) - 14 : "liolib.c" line 10, impact on 1 file(s) - 15 : "llex.c" line 10, impact on 1 file(s) - 16 : "lmathlib.c" line 10, impact on 1 file(s) - 17 : "lmem.c" line 10, impact on 1 file(s) - 18 : "loadlib.c" line 14, impact on 1 file(s) - 19 : "lobject.c" line 10, impact on 1 file(s) - 20 : "lopcodes.c" line 10, impact on 1 file(s) - 21 : "loslib.c" line 10, impact on 1 file(s) - 22 : "lparser.c" line 10, impact on 1 file(s) - 23 : "lstate.c" line 10, impact on 1 file(s) - 24 : "lstring.c" line 10, impact on 1 file(s) - 25 : "lstrlib.c" line 10, impact on 1 file(s) - 26 : "ltable.c" line 10, impact on 1 file(s) - 27 : "ltablib.c" line 10, impact on 1 file(s) - 28 : "ltm.c" line 10, impact on 1 file(s) - 29 : "lua.c" line 9, impact on 1 file(s) - 30 : "lundump.c" line 10, impact on 1 file(s) + 1 : "lapi.c" line 10, impact on 1 file + 2 : "lauxlib.c" line 10, impact on 1 file + 3 : "lbaselib.c" line 10, impact on 1 file + 4 : "lcode.c" line 10, impact on 1 file + 5 : "lcorolib.c" line 10, impact on 1 file + 6 : "lctype.c" line 10, impact on 1 file + 7 : "ldblib.c" line 10, impact on 1 file + 8 : "ldebug.c" line 10, impact on 1 file + 9 : "ldo.c" line 10, impact on 1 file + 10 : "ldump.c" line 10, impact on 1 file + 11 : "lfunc.c" line 10, impact on 1 file + 12 : "lgc.c" line 10, impact on 1 file + 13 : "linit.c" line 27, impact on 1 file + 14 : "liolib.c" line 10, impact on 1 file + 15 : "llex.c" line 10, impact on 1 file + 16 : "lmathlib.c" line 10, impact on 1 file + 17 : "lmem.c" line 10, impact on 1 file + 18 : "loadlib.c" line 14, impact on 1 file + 19 : "lobject.c" line 10, impact on 1 file + 20 : "lopcodes.c" line 10, impact on 1 file + 21 : "loslib.c" line 10, impact on 1 file + 22 : "lparser.c" line 10, impact on 1 file + 23 : "lstate.c" line 10, impact on 1 file + 24 : "lstring.c" line 10, impact on 1 file + 25 : "lstrlib.c" line 10, impact on 1 file + 26 : "ltable.c" line 10, impact on 1 file + 27 : "ltablib.c" line 10, impact on 1 file + 28 : "ltm.c" line 10, impact on 1 file + 29 : "lua.c" line 9, impact on 1 file + 30 : "lundump.c" line 10, impact on 1 file ... 30 of 35 details -5 : "lobject.h" impact on 34 file(s) +5 : "lobject.h" impact on 34 files Included by: - 1 : "ltm.h" line 11, impact on 27 file(s) - 2 : "lstate.h" line 12, impact on 26 file(s) - 3 : "ldo.h" line 11, impact on 19 file(s) - 4 : "lgc.h" line 11, impact on 19 file(s) - 5 : "lstring.h" line 11, impact on 16 file(s) - 6 : "ltable.h" line 10, impact on 13 file(s) - 7 : "lfunc.h" line 11, impact on 11 file(s) - 8 : "lvm.h" line 12, impact on 9 file(s) - 9 : "llex.h" line 10, impact on 8 file(s) - 10 : "lparser.h" line 11, impact on 8 file(s) - 11 : "lcode.h" line 11, impact on 5 file(s) - 12 : "lundump.h" line 11, impact on 5 file(s) - 13 : "lapi.c" line 25, impact on 1 file(s) - 14 : "lcode.c" line 25, impact on 1 file(s) - 15 : "ldebug.c" line 24, impact on 1 file(s) - 16 : "ldo.c" line 25, impact on 1 file(s) - 17 : "ldump.c" line 17, impact on 1 file(s) - 18 : "lfunc.c" line 22, impact on 1 file(s) - 19 : "lgc.c" line 23, impact on 1 file(s) - 20 : "llex.c" line 23, impact on 1 file(s) - 21 : "lmem.c" line 21, impact on 1 file(s) - 22 : "lobject.c" line 26, impact on 1 file(s) - 23 : "lparser.c" line 24, impact on 1 file(s) - 24 : "lstring.c" line 20, impact on 1 file(s) - 25 : "ltable.c" line 35, impact on 1 file(s) - 26 : "ltm.c" line 20, impact on 1 file(s) - 27 : "lundump.c" line 22, impact on 1 file(s) - 28 : "lvm.c" line 25, impact on 1 file(s) -6 : "ltm.h" impact on 27 file(s) + 1 : "ltm.h" line 11, impact on 27 files + 2 : "lstate.h" line 12, impact on 26 files + 3 : "ldo.h" line 11, impact on 19 files + 4 : "lgc.h" line 11, impact on 19 files + 5 : "lstring.h" line 11, impact on 16 files + 6 : "ltable.h" line 10, impact on 13 files + 7 : "lfunc.h" line 11, impact on 11 files + 8 : "lvm.h" line 12, impact on 9 files + 9 : "llex.h" line 10, impact on 8 files + 10 : "lparser.h" line 11, impact on 8 files + 11 : "lcode.h" line 11, impact on 5 files + 12 : "lundump.h" line 11, impact on 5 files + 13 : "lapi.c" line 25, impact on 1 file + 14 : "lcode.c" line 25, impact on 1 file + 15 : "ldebug.c" line 24, impact on 1 file + 16 : "ldo.c" line 25, impact on 1 file + 17 : "ldump.c" line 17, impact on 1 file + 18 : "lfunc.c" line 22, impact on 1 file + 19 : "lgc.c" line 23, impact on 1 file + 20 : "llex.c" line 23, impact on 1 file + 21 : "lmem.c" line 21, impact on 1 file + 22 : "lobject.c" line 26, impact on 1 file + 23 : "lparser.c" line 24, impact on 1 file + 24 : "lstring.c" line 20, impact on 1 file + 25 : "ltable.c" line 35, impact on 1 file + 26 : "ltm.c" line 20, impact on 1 file + 27 : "lundump.c" line 22, impact on 1 file + 28 : "lvm.c" line 25, impact on 1 file +6 : "ltm.h" impact on 27 files Included by: - 1 : "lstate.h" line 13, impact on 26 file(s) - 2 : "lvm.h" line 13, impact on 9 file(s) - 3 : "lapi.c" line 29, impact on 1 file(s) - 4 : "ldebug.c" line 29, impact on 1 file(s) - 5 : "ldo.c" line 31, impact on 1 file(s) - 6 : "lgc.c" line 27, impact on 1 file(s) - 7 : "lstate.c" line 28, impact on 1 file(s) - 8 : "ltm.c" line 24, impact on 1 file(s) - 9 : "lvm.c" line 30, impact on 1 file(s) -7 : "lstate.h" impact on 26 file(s) + 1 : "lstate.h" line 13, impact on 26 files + 2 : "lvm.h" line 13, impact on 9 files + 3 : "lapi.c" line 29, impact on 1 file + 4 : "ldebug.c" line 29, impact on 1 file + 5 : "ldo.c" line 31, impact on 1 file + 6 : "lgc.c" line 27, impact on 1 file + 7 : "lstate.c" line 28, impact on 1 file + 8 : "ltm.c" line 24, impact on 1 file + 9 : "lvm.c" line 30, impact on 1 file +7 : "lstate.h" impact on 26 files Included by: - 1 : "ldo.h" line 12, impact on 19 file(s) - 2 : "lgc.h" line 12, impact on 19 file(s) - 3 : "ldebug.h" line 11, impact on 18 file(s) - 4 : "lstring.h" line 12, impact on 16 file(s) - 5 : "lapi.h" line 12, impact on 6 file(s) - 6 : "lapi.c" line 26, impact on 1 file(s) - 7 : "ldebug.c" line 26, impact on 1 file(s) - 8 : "ldo.c" line 28, impact on 1 file(s) - 9 : "ldump.c" line 18, impact on 1 file(s) - 10 : "lfunc.c" line 23, impact on 1 file(s) - 11 : "lgc.c" line 24, impact on 1 file(s) - 12 : "llex.c" line 25, impact on 1 file(s) - 13 : "lmem.c" line 22, impact on 1 file(s) - 14 : "lobject.c" line 27, impact on 1 file(s) - 15 : "lparser.c" line 27, impact on 1 file(s) - 16 : "lstate.c" line 25, impact on 1 file(s) - 17 : "lstring.c" line 21, impact on 1 file(s) - 18 : "ltable.c" line 36, impact on 1 file(s) - 19 : "ltm.c" line 21, impact on 1 file(s) - 20 : "lvm.c" line 27, impact on 1 file(s) - 21 : "lzio.c" line 19, impact on 1 file(s) + 1 : "ldo.h" line 12, impact on 19 files + 2 : "lgc.h" line 12, impact on 19 files + 3 : "ldebug.h" line 11, impact on 18 files + 4 : "lstring.h" line 12, impact on 16 files + 5 : "lapi.h" line 12, impact on 6 files + 6 : "lapi.c" line 26, impact on 1 file + 7 : "ldebug.c" line 26, impact on 1 file + 8 : "ldo.c" line 28, impact on 1 file + 9 : "ldump.c" line 18, impact on 1 file + 10 : "lfunc.c" line 23, impact on 1 file + 11 : "lgc.c" line 24, impact on 1 file + 12 : "llex.c" line 25, impact on 1 file + 13 : "lmem.c" line 22, impact on 1 file + 14 : "lobject.c" line 27, impact on 1 file + 15 : "lparser.c" line 27, impact on 1 file + 16 : "lstate.c" line 25, impact on 1 file + 17 : "lstring.c" line 21, impact on 1 file + 18 : "ltable.c" line 36, impact on 1 file + 19 : "ltm.c" line 21, impact on 1 file + 20 : "lvm.c" line 27, impact on 1 file + 21 : "lzio.c" line 19, impact on 1 file 22 : "ltests.c" line 31 -8 : "ldo.h" impact on 19 file(s) +8 : "ldo.h" impact on 19 files Included by: - 1 : "lvm.h" line 11, impact on 9 file(s) - 2 : "lapi.c" line 21, impact on 1 file(s) - 3 : "lcode.c" line 21, impact on 1 file(s) - 4 : "ldebug.c" line 22, impact on 1 file(s) - 5 : "ldo.c" line 21, impact on 1 file(s) - 6 : "lfunc.c" line 18, impact on 1 file(s) - 7 : "lgc.c" line 19, impact on 1 file(s) - 8 : "llex.c" line 20, impact on 1 file(s) - 9 : "lmem.c" line 18, impact on 1 file(s) - 10 : "lobject.c" line 24, impact on 1 file(s) - 11 : "lparser.c" line 20, impact on 1 file(s) - 12 : "lstate.c" line 20, impact on 1 file(s) - 13 : "lstring.c" line 18, impact on 1 file(s) - 14 : "ltable.c" line 32, impact on 1 file(s) - 15 : "ltm.c" line 18, impact on 1 file(s) - 16 : "lundump.c" line 19, impact on 1 file(s) - 17 : "lvm.c" line 22, impact on 1 file(s) + 1 : "lvm.h" line 11, impact on 9 files + 2 : "lapi.c" line 21, impact on 1 file + 3 : "lcode.c" line 21, impact on 1 file + 4 : "ldebug.c" line 22, impact on 1 file + 5 : "ldo.c" line 21, impact on 1 file + 6 : "lfunc.c" line 18, impact on 1 file + 7 : "lgc.c" line 19, impact on 1 file + 8 : "llex.c" line 20, impact on 1 file + 9 : "lmem.c" line 18, impact on 1 file + 10 : "lobject.c" line 24, impact on 1 file + 11 : "lparser.c" line 20, impact on 1 file + 12 : "lstate.c" line 20, impact on 1 file + 13 : "lstring.c" line 18, impact on 1 file + 14 : "ltable.c" line 32, impact on 1 file + 15 : "ltm.c" line 18, impact on 1 file + 16 : "lundump.c" line 19, impact on 1 file + 17 : "lvm.c" line 22, impact on 1 file 18 : "ltests.c" line 26 -9 : "lgc.h" impact on 19 file(s) +9 : "lgc.h" impact on 19 files Included by: - 1 : "lstring.h" line 10, impact on 16 file(s) - 2 : "lapi.c" line 23, impact on 1 file(s) - 3 : "lcode.c" line 22, impact on 1 file(s) - 4 : "ldo.c" line 23, impact on 1 file(s) - 5 : "lfunc.c" line 20, impact on 1 file(s) - 6 : "lgc.c" line 21, impact on 1 file(s) - 7 : "llex.c" line 21, impact on 1 file(s) - 8 : "lmem.c" line 19, impact on 1 file(s) - 9 : "lstate.c" line 22, impact on 1 file(s) - 10 : "ltable.c" line 33, impact on 1 file(s) - 11 : "ltm.c" line 19, impact on 1 file(s) - 12 : "lvm.c" line 24, impact on 1 file(s) -10 : "lauxlib.h" impact on 18 file(s) + 1 : "lstring.h" line 10, impact on 16 files + 2 : "lapi.c" line 23, impact on 1 file + 3 : "lcode.c" line 22, impact on 1 file + 4 : "ldo.c" line 23, impact on 1 file + 5 : "lfunc.c" line 20, impact on 1 file + 6 : "lgc.c" line 21, impact on 1 file + 7 : "llex.c" line 21, impact on 1 file + 8 : "lmem.c" line 19, impact on 1 file + 9 : "lstate.c" line 22, impact on 1 file + 10 : "ltable.c" line 33, impact on 1 file + 11 : "ltm.c" line 19, impact on 1 file + 12 : "lvm.c" line 24, impact on 1 file +10 : "lauxlib.h" impact on 18 files Included by: - 1 : "lauxlib.c" line 27, impact on 1 file(s) - 2 : "lbaselib.c" line 20, impact on 1 file(s) - 3 : "lcorolib.c" line 17, impact on 1 file(s) - 4 : "ldblib.c" line 19, impact on 1 file(s) - 5 : "linit.c" line 35, impact on 1 file(s) - 6 : "liolib.c" line 22, impact on 1 file(s) - 7 : "lmathlib.c" line 21, impact on 1 file(s) - 8 : "loadlib.c" line 23, impact on 1 file(s) - 9 : "loslib.c" line 21, impact on 1 file(s) - 10 : "lstrlib.c" line 25, impact on 1 file(s) - 11 : "ltablib.c" line 19, impact on 1 file(s) - 12 : "lua.c" line 20, impact on 1 file(s) - 13 : "lutf8lib.c" line 20, impact on 1 file(s) + 1 : "lauxlib.c" line 27, impact on 1 file + 2 : "lbaselib.c" line 20, impact on 1 file + 3 : "lcorolib.c" line 17, impact on 1 file + 4 : "ldblib.c" line 19, impact on 1 file + 5 : "linit.c" line 35, impact on 1 file + 6 : "liolib.c" line 22, impact on 1 file + 7 : "lmathlib.c" line 21, impact on 1 file + 8 : "loadlib.c" line 23, impact on 1 file + 9 : "loslib.c" line 21, impact on 1 file + 10 : "lstrlib.c" line 25, impact on 1 file + 11 : "ltablib.c" line 19, impact on 1 file + 12 : "lua.c" line 20, impact on 1 file + 13 : "lutf8lib.c" line 20, impact on 1 file 14 : "ltests.c" line 22 15 : "testes/libs/lib1.c" line 2 16 : "testes/libs/lib2.c" line 2 17 : "testes/libs/lib22.c" line 2 -11 : "ldebug.h" impact on 18 file(s) +11 : "ldebug.h" impact on 18 files Included by: - 1 : "lapi.c" line 20, impact on 1 file(s) - 2 : "lcode.c" line 20, impact on 1 file(s) - 3 : "ldebug.c" line 21, impact on 1 file(s) - 4 : "ldo.c" line 20, impact on 1 file(s) - 5 : "lfunc.c" line 17, impact on 1 file(s) - 6 : "lgc.c" line 18, impact on 1 file(s) - 7 : "llex.c" line 19, impact on 1 file(s) - 8 : "lmem.c" line 17, impact on 1 file(s) - 9 : "lobject.c" line 23, impact on 1 file(s) - 10 : "lparser.c" line 19, impact on 1 file(s) - 11 : "lstate.c" line 19, impact on 1 file(s) - 12 : "lstring.c" line 17, impact on 1 file(s) - 13 : "ltable.c" line 31, impact on 1 file(s) - 14 : "ltm.c" line 17, impact on 1 file(s) - 15 : "lundump.c" line 18, impact on 1 file(s) - 16 : "lvm.c" line 21, impact on 1 file(s) + 1 : "lapi.c" line 20, impact on 1 file + 2 : "lcode.c" line 20, impact on 1 file + 3 : "ldebug.c" line 21, impact on 1 file + 4 : "ldo.c" line 20, impact on 1 file + 5 : "lfunc.c" line 17, impact on 1 file + 6 : "lgc.c" line 18, impact on 1 file + 7 : "llex.c" line 19, impact on 1 file + 8 : "lmem.c" line 17, impact on 1 file + 9 : "lobject.c" line 23, impact on 1 file + 10 : "lparser.c" line 19, impact on 1 file + 11 : "lstate.c" line 19, impact on 1 file + 12 : "lstring.c" line 17, impact on 1 file + 13 : "ltable.c" line 31, impact on 1 file + 14 : "ltm.c" line 17, impact on 1 file + 15 : "lundump.c" line 18, impact on 1 file + 16 : "lvm.c" line 21, impact on 1 file 17 : "ltests.c" line 25 -12 : "lstring.h" impact on 16 file(s) +12 : "lstring.h" impact on 16 files Included by: - 1 : "lapi.c" line 27, impact on 1 file(s) - 2 : "lcode.c" line 28, impact on 1 file(s) - 3 : "ldebug.c" line 27, impact on 1 file(s) - 4 : "ldo.c" line 29, impact on 1 file(s) - 5 : "lgc.c" line 25, impact on 1 file(s) - 6 : "llex.c" line 26, impact on 1 file(s) - 7 : "lobject.c" line 28, impact on 1 file(s) - 8 : "lparser.c" line 28, impact on 1 file(s) - 9 : "lstate.c" line 26, impact on 1 file(s) - 10 : "lstring.c" line 22, impact on 1 file(s) - 11 : "ltable.c" line 37, impact on 1 file(s) - 12 : "ltm.c" line 22, impact on 1 file(s) - 13 : "lundump.c" line 23, impact on 1 file(s) - 14 : "lvm.c" line 28, impact on 1 file(s) + 1 : "lapi.c" line 27, impact on 1 file + 2 : "lcode.c" line 28, impact on 1 file + 3 : "ldebug.c" line 27, impact on 1 file + 4 : "ldo.c" line 29, impact on 1 file + 5 : "lgc.c" line 25, impact on 1 file + 6 : "llex.c" line 26, impact on 1 file + 7 : "lobject.c" line 28, impact on 1 file + 8 : "lparser.c" line 28, impact on 1 file + 9 : "lstate.c" line 26, impact on 1 file + 10 : "lstring.c" line 22, impact on 1 file + 11 : "ltable.c" line 37, impact on 1 file + 12 : "ltm.c" line 22, impact on 1 file + 13 : "lundump.c" line 23, impact on 1 file + 14 : "lvm.c" line 28, impact on 1 file 15 : "ltests.c" line 32 -13 : "lmem.h" impact on 15 file(s) +13 : "lmem.h" impact on 15 files Included by: - 1 : "lapi.c" line 24, impact on 1 file(s) - 2 : "lcode.c" line 24, impact on 1 file(s) - 3 : "ldo.c" line 24, impact on 1 file(s) - 4 : "lfunc.c" line 21, impact on 1 file(s) - 5 : "lgc.c" line 22, impact on 1 file(s) - 6 : "lmem.c" line 20, impact on 1 file(s) - 7 : "lobject.c" line 25, impact on 1 file(s) - 8 : "lparser.c" line 23, impact on 1 file(s) - 9 : "lstate.c" line 24, impact on 1 file(s) - 10 : "lstring.c" line 19, impact on 1 file(s) - 11 : "ltable.c" line 34, impact on 1 file(s) - 12 : "lundump.c" line 21, impact on 1 file(s) - 13 : "lzio.c" line 18, impact on 1 file(s) + 1 : "lapi.c" line 24, impact on 1 file + 2 : "lcode.c" line 24, impact on 1 file + 3 : "ldo.c" line 24, impact on 1 file + 4 : "lfunc.c" line 21, impact on 1 file + 5 : "lgc.c" line 22, impact on 1 file + 6 : "lmem.c" line 20, impact on 1 file + 7 : "lobject.c" line 25, impact on 1 file + 8 : "lparser.c" line 23, impact on 1 file + 9 : "lstate.c" line 24, impact on 1 file + 10 : "lstring.c" line 19, impact on 1 file + 11 : "ltable.c" line 34, impact on 1 file + 12 : "lundump.c" line 21, impact on 1 file + 13 : "lzio.c" line 18, impact on 1 file 14 : "ltests.c" line 28 -14 : "lualib.h" impact on 14 file(s) +14 : "lualib.h" impact on 14 files Included by: - 1 : "lbaselib.c" line 21, impact on 1 file(s) - 2 : "lcorolib.c" line 18, impact on 1 file(s) - 3 : "ldblib.c" line 20, impact on 1 file(s) - 4 : "linit.c" line 34, impact on 1 file(s) - 5 : "liolib.c" line 23, impact on 1 file(s) - 6 : "lmathlib.c" line 22, impact on 1 file(s) - 7 : "loadlib.c" line 24, impact on 1 file(s) - 8 : "loslib.c" line 22, impact on 1 file(s) - 9 : "lstrlib.c" line 26, impact on 1 file(s) - 10 : "ltablib.c" line 20, impact on 1 file(s) - 11 : "lua.c" line 21, impact on 1 file(s) - 12 : "lutf8lib.c" line 21, impact on 1 file(s) + 1 : "lbaselib.c" line 21, impact on 1 file + 2 : "lcorolib.c" line 18, impact on 1 file + 3 : "ldblib.c" line 20, impact on 1 file + 4 : "linit.c" line 34, impact on 1 file + 5 : "liolib.c" line 23, impact on 1 file + 6 : "lmathlib.c" line 22, impact on 1 file + 7 : "loadlib.c" line 24, impact on 1 file + 8 : "loslib.c" line 22, impact on 1 file + 9 : "lstrlib.c" line 26, impact on 1 file + 10 : "ltablib.c" line 20, impact on 1 file + 11 : "lua.c" line 21, impact on 1 file + 12 : "lutf8lib.c" line 21, impact on 1 file 13 : "ltests.c" line 34 -15 : "ltable.h" impact on 13 file(s) +15 : "ltable.h" impact on 13 files Included by: - 1 : "lapi.c" line 28, impact on 1 file(s) - 2 : "lcode.c" line 29, impact on 1 file(s) - 3 : "ldebug.c" line 28, impact on 1 file(s) - 4 : "ldo.c" line 30, impact on 1 file(s) - 5 : "lgc.c" line 26, impact on 1 file(s) - 6 : "llex.c" line 27, impact on 1 file(s) - 7 : "lparser.c" line 29, impact on 1 file(s) - 8 : "lstate.c" line 27, impact on 1 file(s) - 9 : "ltable.c" line 38, impact on 1 file(s) - 10 : "ltm.c" line 23, impact on 1 file(s) - 11 : "lvm.c" line 29, impact on 1 file(s) + 1 : "lapi.c" line 28, impact on 1 file + 2 : "lcode.c" line 29, impact on 1 file + 3 : "ldebug.c" line 28, impact on 1 file + 4 : "ldo.c" line 30, impact on 1 file + 5 : "lgc.c" line 26, impact on 1 file + 6 : "llex.c" line 27, impact on 1 file + 7 : "lparser.c" line 29, impact on 1 file + 8 : "lstate.c" line 27, impact on 1 file + 9 : "ltable.c" line 38, impact on 1 file + 10 : "ltm.c" line 23, impact on 1 file + 11 : "lvm.c" line 29, impact on 1 file 12 : "ltests.c" line 33 -16 : "lfunc.h" impact on 11 file(s) +16 : "lfunc.h" impact on 11 files Included by: - 1 : "lapi.c" line 22, impact on 1 file(s) - 2 : "ldebug.c" line 23, impact on 1 file(s) - 3 : "ldo.c" line 22, impact on 1 file(s) - 4 : "lfunc.c" line 19, impact on 1 file(s) - 5 : "lgc.c" line 20, impact on 1 file(s) - 6 : "lparser.c" line 21, impact on 1 file(s) - 7 : "lstate.c" line 21, impact on 1 file(s) - 8 : "lundump.c" line 20, impact on 1 file(s) - 9 : "lvm.c" line 23, impact on 1 file(s) + 1 : "lapi.c" line 22, impact on 1 file + 2 : "ldebug.c" line 23, impact on 1 file + 3 : "ldo.c" line 22, impact on 1 file + 4 : "lfunc.c" line 19, impact on 1 file + 5 : "lgc.c" line 20, impact on 1 file + 6 : "lparser.c" line 21, impact on 1 file + 7 : "lstate.c" line 21, impact on 1 file + 8 : "lundump.c" line 20, impact on 1 file + 9 : "lvm.c" line 23, impact on 1 file 10 : "ltests.c" line 27 -17 : "lopcodes.h" impact on 9 file(s) +17 : "lopcodes.h" impact on 9 files Included by: - 1 : "lcode.h" line 12, impact on 5 file(s) - 2 : "lcode.c" line 26, impact on 1 file(s) - 3 : "ldebug.c" line 25, impact on 1 file(s) - 4 : "ldo.c" line 26, impact on 1 file(s) - 5 : "lopcodes.c" line 13, impact on 1 file(s) - 6 : "lparser.c" line 25, impact on 1 file(s) - 7 : "lvm.c" line 26, impact on 1 file(s) + 1 : "lcode.h" line 12, impact on 5 files + 2 : "lcode.c" line 26, impact on 1 file + 3 : "ldebug.c" line 25, impact on 1 file + 4 : "ldo.c" line 26, impact on 1 file + 5 : "lopcodes.c" line 13, impact on 1 file + 6 : "lparser.c" line 25, impact on 1 file + 7 : "lvm.c" line 26, impact on 1 file 8 : "ltests.c" line 29 -18 : "lvm.h" impact on 9 file(s) +18 : "lvm.h" impact on 9 files Included by: - 1 : "lapi.c" line 31, impact on 1 file(s) - 2 : "lcode.c" line 30, impact on 1 file(s) - 3 : "ldebug.c" line 30, impact on 1 file(s) - 4 : "ldo.c" line 33, impact on 1 file(s) - 5 : "lobject.c" line 29, impact on 1 file(s) - 6 : "ltable.c" line 39, impact on 1 file(s) - 7 : "ltm.c" line 25, impact on 1 file(s) - 8 : "lvm.c" line 31, impact on 1 file(s) -19 : "llex.h" impact on 8 file(s) + 1 : "lapi.c" line 31, impact on 1 file + 2 : "lcode.c" line 30, impact on 1 file + 3 : "ldebug.c" line 30, impact on 1 file + 4 : "ldo.c" line 33, impact on 1 file + 5 : "lobject.c" line 29, impact on 1 file + 6 : "ltable.c" line 39, impact on 1 file + 7 : "ltm.c" line 25, impact on 1 file + 8 : "lvm.c" line 31, impact on 1 file +19 : "llex.h" impact on 8 files Included by: - 1 : "lcode.h" line 10, impact on 5 file(s) - 2 : "lcode.c" line 23, impact on 1 file(s) - 3 : "llex.c" line 22, impact on 1 file(s) - 4 : "lparser.c" line 22, impact on 1 file(s) - 5 : "lstate.c" line 23, impact on 1 file(s) -20 : "lparser.h" impact on 8 file(s) + 1 : "lcode.h" line 10, impact on 5 files + 2 : "lcode.c" line 23, impact on 1 file + 3 : "llex.c" line 22, impact on 1 file + 4 : "lparser.c" line 22, impact on 1 file + 5 : "lstate.c" line 23, impact on 1 file +20 : "lparser.h" impact on 8 files Included by: - 1 : "lcode.h" line 13, impact on 5 file(s) - 2 : "lcode.c" line 27, impact on 1 file(s) - 3 : "ldo.c" line 27, impact on 1 file(s) - 4 : "llex.c" line 24, impact on 1 file(s) - 5 : "lparser.c" line 26, impact on 1 file(s) -21 : "lapi.h" impact on 6 file(s) + 1 : "lcode.h" line 13, impact on 5 files + 2 : "lcode.c" line 27, impact on 1 file + 3 : "ldo.c" line 27, impact on 1 file + 4 : "llex.c" line 24, impact on 1 file + 5 : "lparser.c" line 26, impact on 1 file +21 : "lapi.h" impact on 6 files Included by: - 1 : "lapi.c" line 19, impact on 1 file(s) - 2 : "ldebug.c" line 19, impact on 1 file(s) - 3 : "ldo.c" line 19, impact on 1 file(s) - 4 : "lstate.c" line 18, impact on 1 file(s) + 1 : "lapi.c" line 19, impact on 1 file + 2 : "ldebug.c" line 19, impact on 1 file + 3 : "ldo.c" line 19, impact on 1 file + 4 : "lstate.c" line 18, impact on 1 file 5 : "ltests.c" line 21 -22 : "lcode.h" impact on 5 file(s) +22 : "lcode.h" impact on 5 files Included by: - 1 : "lcode.c" line 19, impact on 1 file(s) - 2 : "ldebug.c" line 20, impact on 1 file(s) - 3 : "lparser.c" line 18, impact on 1 file(s) + 1 : "lcode.c" line 19, impact on 1 file + 2 : "ldebug.c" line 20, impact on 1 file + 3 : "lparser.c" line 18, impact on 1 file 4 : "ltests.c" line 23 -23 : "lctype.h" impact on 5 file(s) +23 : "lctype.h" impact on 5 files Included by: - 1 : "lctype.c" line 13, impact on 1 file(s) - 2 : "llex.c" line 18, impact on 1 file(s) - 3 : "lobject.c" line 22, impact on 1 file(s) + 1 : "lctype.c" line 13, impact on 1 file + 2 : "llex.c" line 18, impact on 1 file + 3 : "lobject.c" line 22, impact on 1 file 4 : "ltests.c" line 24 -24 : "lundump.h" impact on 5 file(s) +24 : "lundump.h" impact on 5 files Included by: - 1 : "lapi.c" line 30, impact on 1 file(s) - 2 : "ldo.c" line 32, impact on 1 file(s) - 3 : "ldump.c" line 19, impact on 1 file(s) - 4 : "lundump.c" line 24, impact on 1 file(s) -25 : "ljumptab.h" impact on 2 file(s) + 1 : "lapi.c" line 30, impact on 1 file + 2 : "ldo.c" line 32, impact on 1 file + 3 : "ldump.c" line 19, impact on 1 file + 4 : "lundump.c" line 24, impact on 1 file +25 : "ljumptab.h" impact on 2 files Included by: - 1 : "lvm.c" line 1134, impact on 1 file(s) -26 : "lapi.c" impact on 1 file(s) + 1 : "lvm.c" line 1 134, impact on 1 file +26 : "lapi.c" impact on 1 file Included by: 1 : "onelua.c" line 79 -27 : "lauxlib.c" impact on 1 file(s) +27 : "lauxlib.c" impact on 1 file Included by: 1 : "onelua.c" line 82 -28 : "lbaselib.c" impact on 1 file(s) +28 : "lbaselib.c" impact on 1 file Included by: 1 : "onelua.c" line 86 -29 : "lcode.c" impact on 1 file(s) +29 : "lcode.c" impact on 1 file Included by: 1 : "onelua.c" line 69 -30 : "lcorolib.c" impact on 1 file(s) +30 : "lcorolib.c" impact on 1 file Included by: 1 : "onelua.c" line 87 ... 30 of 59 files -Unincluded headers: +Unincluded header: 1 : "ltests.h" diff --git a/docs/examples/lua/output_win.txt b/docs/examples/lua/output_win.txt index f55ae49..afbffe5 100644 --- a/docs/examples/lua/output_win.txt +++ b/docs/examples/lua/output_win.txt @@ -2,374 +2,374 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "luaconf.h" impact on 62 file(s) +1 : "luaconf.h" impact on 62 files Included by: - 1 : "lua.h" line 16, impact on 61 file(s) + 1 : "lua.h" line 16, impact on 61 files 2 : "onelua.c" line 49 -2 : "lua.h" impact on 61 file(s) +2 : "lua.h" impact on 61 files Included by: - 1 : "llimits.h" line 15, impact on 40 file(s) - 2 : "lobject.h" line 16, impact on 34 file(s) - 3 : "lstate.h" line 10, impact on 26 file(s) - 4 : "lauxlib.h" line 15, impact on 18 file(s) - 5 : "lmem.h" line 14, impact on 15 file(s) - 6 : "lualib.h" line 11, impact on 14 file(s) - 7 : "lctype.h" line 10, impact on 5 file(s) - 8 : "lapi.c" line 17, impact on 1 file(s) - 9 : "lauxlib.c" line 25, impact on 1 file(s) - 10 : "lbaselib.c" line 18, impact on 1 file(s) - 11 : "lcode.c" line 17, impact on 1 file(s) - 12 : "lcorolib.c" line 15, impact on 1 file(s) - 13 : "ldblib.c" line 17, impact on 1 file(s) - 14 : "ldebug.c" line 17, impact on 1 file(s) - 15 : "ldo.c" line 17, impact on 1 file(s) - 16 : "ldump.c" line 15, impact on 1 file(s) - 17 : "lfunc.c" line 15, impact on 1 file(s) - 18 : "lgc.c" line 16, impact on 1 file(s) - 19 : "linit.c" line 32, impact on 1 file(s) - 20 : "liolib.c" line 20, impact on 1 file(s) - 21 : "llex.c" line 16, impact on 1 file(s) - 22 : "lmathlib.c" line 19, impact on 1 file(s) - 23 : "lmem.c" line 15, impact on 1 file(s) - 24 : "loadlib.c" line 21, impact on 1 file(s) - 25 : "lobject.c" line 20, impact on 1 file(s) - 26 : "loslib.c" line 19, impact on 1 file(s) - 27 : "lparser.c" line 16, impact on 1 file(s) - 28 : "lstate.c" line 16, impact on 1 file(s) - 29 : "lstring.c" line 15, impact on 1 file(s) - 30 : "lstrlib.c" line 23, impact on 1 file(s) + 1 : "llimits.h" line 15, impact on 40 files + 2 : "lobject.h" line 16, impact on 34 files + 3 : "lstate.h" line 10, impact on 26 files + 4 : "lauxlib.h" line 15, impact on 18 files + 5 : "lmem.h" line 14, impact on 15 files + 6 : "lualib.h" line 11, impact on 14 files + 7 : "lctype.h" line 10, impact on 5 files + 8 : "lapi.c" line 17, impact on 1 file + 9 : "lauxlib.c" line 25, impact on 1 file + 10 : "lbaselib.c" line 18, impact on 1 file + 11 : "lcode.c" line 17, impact on 1 file + 12 : "lcorolib.c" line 15, impact on 1 file + 13 : "ldblib.c" line 17, impact on 1 file + 14 : "ldebug.c" line 17, impact on 1 file + 15 : "ldo.c" line 17, impact on 1 file + 16 : "ldump.c" line 15, impact on 1 file + 17 : "lfunc.c" line 15, impact on 1 file + 18 : "lgc.c" line 16, impact on 1 file + 19 : "linit.c" line 32, impact on 1 file + 20 : "liolib.c" line 20, impact on 1 file + 21 : "llex.c" line 16, impact on 1 file + 22 : "lmathlib.c" line 19, impact on 1 file + 23 : "lmem.c" line 15, impact on 1 file + 24 : "loadlib.c" line 21, impact on 1 file + 25 : "lobject.c" line 20, impact on 1 file + 26 : "loslib.c" line 19, impact on 1 file + 27 : "lparser.c" line 16, impact on 1 file + 28 : "lstate.c" line 16, impact on 1 file + 29 : "lstring.c" line 15, impact on 1 file + 30 : "lstrlib.c" line 23, impact on 1 file ... 30 of 44 details -3 : "llimits.h" impact on 40 file(s) +3 : "llimits.h" impact on 40 files Included by: - 1 : "lobject.h" line 15, impact on 34 file(s) - 2 : "lmem.h" line 13, impact on 15 file(s) - 3 : "lopcodes.h" line 10, impact on 9 file(s) - 4 : "lparser.h" line 10, impact on 8 file(s) - 5 : "lapi.h" line 11, impact on 6 file(s) - 6 : "lctype.h" line 36, impact on 5 file(s) - 7 : "lundump.h" line 10, impact on 5 file(s) - 8 : "lzio.c" line 17, impact on 1 file(s) -4 : "lprefix.h" impact on 35 file(s) + 1 : "lobject.h" line 15, impact on 34 files + 2 : "lmem.h" line 13, impact on 15 files + 3 : "lopcodes.h" line 10, impact on 9 files + 4 : "lparser.h" line 10, impact on 8 files + 5 : "lapi.h" line 11, impact on 6 files + 6 : "lctype.h" line 36, impact on 5 files + 7 : "lundump.h" line 10, impact on 5 files + 8 : "lzio.c" line 17, impact on 1 file +4 : "lprefix.h" impact on 35 files Included by: - 1 : "lapi.c" line 10, impact on 1 file(s) - 2 : "lauxlib.c" line 10, impact on 1 file(s) - 3 : "lbaselib.c" line 10, impact on 1 file(s) - 4 : "lcode.c" line 10, impact on 1 file(s) - 5 : "lcorolib.c" line 10, impact on 1 file(s) - 6 : "lctype.c" line 10, impact on 1 file(s) - 7 : "ldblib.c" line 10, impact on 1 file(s) - 8 : "ldebug.c" line 10, impact on 1 file(s) - 9 : "ldo.c" line 10, impact on 1 file(s) - 10 : "ldump.c" line 10, impact on 1 file(s) - 11 : "lfunc.c" line 10, impact on 1 file(s) - 12 : "lgc.c" line 10, impact on 1 file(s) - 13 : "linit.c" line 27, impact on 1 file(s) - 14 : "liolib.c" line 10, impact on 1 file(s) - 15 : "llex.c" line 10, impact on 1 file(s) - 16 : "lmathlib.c" line 10, impact on 1 file(s) - 17 : "lmem.c" line 10, impact on 1 file(s) - 18 : "loadlib.c" line 14, impact on 1 file(s) - 19 : "lobject.c" line 10, impact on 1 file(s) - 20 : "lopcodes.c" line 10, impact on 1 file(s) - 21 : "loslib.c" line 10, impact on 1 file(s) - 22 : "lparser.c" line 10, impact on 1 file(s) - 23 : "lstate.c" line 10, impact on 1 file(s) - 24 : "lstring.c" line 10, impact on 1 file(s) - 25 : "lstrlib.c" line 10, impact on 1 file(s) - 26 : "ltable.c" line 10, impact on 1 file(s) - 27 : "ltablib.c" line 10, impact on 1 file(s) - 28 : "ltm.c" line 10, impact on 1 file(s) - 29 : "lua.c" line 9, impact on 1 file(s) - 30 : "lundump.c" line 10, impact on 1 file(s) + 1 : "lapi.c" line 10, impact on 1 file + 2 : "lauxlib.c" line 10, impact on 1 file + 3 : "lbaselib.c" line 10, impact on 1 file + 4 : "lcode.c" line 10, impact on 1 file + 5 : "lcorolib.c" line 10, impact on 1 file + 6 : "lctype.c" line 10, impact on 1 file + 7 : "ldblib.c" line 10, impact on 1 file + 8 : "ldebug.c" line 10, impact on 1 file + 9 : "ldo.c" line 10, impact on 1 file + 10 : "ldump.c" line 10, impact on 1 file + 11 : "lfunc.c" line 10, impact on 1 file + 12 : "lgc.c" line 10, impact on 1 file + 13 : "linit.c" line 27, impact on 1 file + 14 : "liolib.c" line 10, impact on 1 file + 15 : "llex.c" line 10, impact on 1 file + 16 : "lmathlib.c" line 10, impact on 1 file + 17 : "lmem.c" line 10, impact on 1 file + 18 : "loadlib.c" line 14, impact on 1 file + 19 : "lobject.c" line 10, impact on 1 file + 20 : "lopcodes.c" line 10, impact on 1 file + 21 : "loslib.c" line 10, impact on 1 file + 22 : "lparser.c" line 10, impact on 1 file + 23 : "lstate.c" line 10, impact on 1 file + 24 : "lstring.c" line 10, impact on 1 file + 25 : "lstrlib.c" line 10, impact on 1 file + 26 : "ltable.c" line 10, impact on 1 file + 27 : "ltablib.c" line 10, impact on 1 file + 28 : "ltm.c" line 10, impact on 1 file + 29 : "lua.c" line 9, impact on 1 file + 30 : "lundump.c" line 10, impact on 1 file ... 30 of 35 details -5 : "lobject.h" impact on 34 file(s) +5 : "lobject.h" impact on 34 files Included by: - 1 : "ltm.h" line 11, impact on 27 file(s) - 2 : "lstate.h" line 12, impact on 26 file(s) - 3 : "ldo.h" line 11, impact on 19 file(s) - 4 : "lgc.h" line 11, impact on 19 file(s) - 5 : "lstring.h" line 11, impact on 16 file(s) - 6 : "ltable.h" line 10, impact on 13 file(s) - 7 : "lfunc.h" line 11, impact on 11 file(s) - 8 : "lvm.h" line 12, impact on 9 file(s) - 9 : "llex.h" line 10, impact on 8 file(s) - 10 : "lparser.h" line 11, impact on 8 file(s) - 11 : "lcode.h" line 11, impact on 5 file(s) - 12 : "lundump.h" line 11, impact on 5 file(s) - 13 : "lapi.c" line 25, impact on 1 file(s) - 14 : "lcode.c" line 25, impact on 1 file(s) - 15 : "ldebug.c" line 24, impact on 1 file(s) - 16 : "ldo.c" line 25, impact on 1 file(s) - 17 : "ldump.c" line 17, impact on 1 file(s) - 18 : "lfunc.c" line 22, impact on 1 file(s) - 19 : "lgc.c" line 23, impact on 1 file(s) - 20 : "llex.c" line 23, impact on 1 file(s) - 21 : "lmem.c" line 21, impact on 1 file(s) - 22 : "lobject.c" line 26, impact on 1 file(s) - 23 : "lparser.c" line 24, impact on 1 file(s) - 24 : "lstring.c" line 20, impact on 1 file(s) - 25 : "ltable.c" line 35, impact on 1 file(s) - 26 : "ltm.c" line 20, impact on 1 file(s) - 27 : "lundump.c" line 22, impact on 1 file(s) - 28 : "lvm.c" line 25, impact on 1 file(s) -6 : "ltm.h" impact on 27 file(s) + 1 : "ltm.h" line 11, impact on 27 files + 2 : "lstate.h" line 12, impact on 26 files + 3 : "ldo.h" line 11, impact on 19 files + 4 : "lgc.h" line 11, impact on 19 files + 5 : "lstring.h" line 11, impact on 16 files + 6 : "ltable.h" line 10, impact on 13 files + 7 : "lfunc.h" line 11, impact on 11 files + 8 : "lvm.h" line 12, impact on 9 files + 9 : "llex.h" line 10, impact on 8 files + 10 : "lparser.h" line 11, impact on 8 files + 11 : "lcode.h" line 11, impact on 5 files + 12 : "lundump.h" line 11, impact on 5 files + 13 : "lapi.c" line 25, impact on 1 file + 14 : "lcode.c" line 25, impact on 1 file + 15 : "ldebug.c" line 24, impact on 1 file + 16 : "ldo.c" line 25, impact on 1 file + 17 : "ldump.c" line 17, impact on 1 file + 18 : "lfunc.c" line 22, impact on 1 file + 19 : "lgc.c" line 23, impact on 1 file + 20 : "llex.c" line 23, impact on 1 file + 21 : "lmem.c" line 21, impact on 1 file + 22 : "lobject.c" line 26, impact on 1 file + 23 : "lparser.c" line 24, impact on 1 file + 24 : "lstring.c" line 20, impact on 1 file + 25 : "ltable.c" line 35, impact on 1 file + 26 : "ltm.c" line 20, impact on 1 file + 27 : "lundump.c" line 22, impact on 1 file + 28 : "lvm.c" line 25, impact on 1 file +6 : "ltm.h" impact on 27 files Included by: - 1 : "lstate.h" line 13, impact on 26 file(s) - 2 : "lvm.h" line 13, impact on 9 file(s) - 3 : "lapi.c" line 29, impact on 1 file(s) - 4 : "ldebug.c" line 29, impact on 1 file(s) - 5 : "ldo.c" line 31, impact on 1 file(s) - 6 : "lgc.c" line 27, impact on 1 file(s) - 7 : "lstate.c" line 28, impact on 1 file(s) - 8 : "ltm.c" line 24, impact on 1 file(s) - 9 : "lvm.c" line 30, impact on 1 file(s) -7 : "lstate.h" impact on 26 file(s) + 1 : "lstate.h" line 13, impact on 26 files + 2 : "lvm.h" line 13, impact on 9 files + 3 : "lapi.c" line 29, impact on 1 file + 4 : "ldebug.c" line 29, impact on 1 file + 5 : "ldo.c" line 31, impact on 1 file + 6 : "lgc.c" line 27, impact on 1 file + 7 : "lstate.c" line 28, impact on 1 file + 8 : "ltm.c" line 24, impact on 1 file + 9 : "lvm.c" line 30, impact on 1 file +7 : "lstate.h" impact on 26 files Included by: - 1 : "ldo.h" line 12, impact on 19 file(s) - 2 : "lgc.h" line 12, impact on 19 file(s) - 3 : "ldebug.h" line 11, impact on 18 file(s) - 4 : "lstring.h" line 12, impact on 16 file(s) - 5 : "lapi.h" line 12, impact on 6 file(s) - 6 : "lapi.c" line 26, impact on 1 file(s) - 7 : "ldebug.c" line 26, impact on 1 file(s) - 8 : "ldo.c" line 28, impact on 1 file(s) - 9 : "ldump.c" line 18, impact on 1 file(s) - 10 : "lfunc.c" line 23, impact on 1 file(s) - 11 : "lgc.c" line 24, impact on 1 file(s) - 12 : "llex.c" line 25, impact on 1 file(s) - 13 : "lmem.c" line 22, impact on 1 file(s) - 14 : "lobject.c" line 27, impact on 1 file(s) - 15 : "lparser.c" line 27, impact on 1 file(s) - 16 : "lstate.c" line 25, impact on 1 file(s) - 17 : "lstring.c" line 21, impact on 1 file(s) - 18 : "ltable.c" line 36, impact on 1 file(s) - 19 : "ltm.c" line 21, impact on 1 file(s) - 20 : "lvm.c" line 27, impact on 1 file(s) - 21 : "lzio.c" line 19, impact on 1 file(s) + 1 : "ldo.h" line 12, impact on 19 files + 2 : "lgc.h" line 12, impact on 19 files + 3 : "ldebug.h" line 11, impact on 18 files + 4 : "lstring.h" line 12, impact on 16 files + 5 : "lapi.h" line 12, impact on 6 files + 6 : "lapi.c" line 26, impact on 1 file + 7 : "ldebug.c" line 26, impact on 1 file + 8 : "ldo.c" line 28, impact on 1 file + 9 : "ldump.c" line 18, impact on 1 file + 10 : "lfunc.c" line 23, impact on 1 file + 11 : "lgc.c" line 24, impact on 1 file + 12 : "llex.c" line 25, impact on 1 file + 13 : "lmem.c" line 22, impact on 1 file + 14 : "lobject.c" line 27, impact on 1 file + 15 : "lparser.c" line 27, impact on 1 file + 16 : "lstate.c" line 25, impact on 1 file + 17 : "lstring.c" line 21, impact on 1 file + 18 : "ltable.c" line 36, impact on 1 file + 19 : "ltm.c" line 21, impact on 1 file + 20 : "lvm.c" line 27, impact on 1 file + 21 : "lzio.c" line 19, impact on 1 file 22 : "ltests.c" line 31 -8 : "ldo.h" impact on 19 file(s) +8 : "ldo.h" impact on 19 files Included by: - 1 : "lvm.h" line 11, impact on 9 file(s) - 2 : "lapi.c" line 21, impact on 1 file(s) - 3 : "lcode.c" line 21, impact on 1 file(s) - 4 : "ldebug.c" line 22, impact on 1 file(s) - 5 : "ldo.c" line 21, impact on 1 file(s) - 6 : "lfunc.c" line 18, impact on 1 file(s) - 7 : "lgc.c" line 19, impact on 1 file(s) - 8 : "llex.c" line 20, impact on 1 file(s) - 9 : "lmem.c" line 18, impact on 1 file(s) - 10 : "lobject.c" line 24, impact on 1 file(s) - 11 : "lparser.c" line 20, impact on 1 file(s) - 12 : "lstate.c" line 20, impact on 1 file(s) - 13 : "lstring.c" line 18, impact on 1 file(s) - 14 : "ltable.c" line 32, impact on 1 file(s) - 15 : "ltm.c" line 18, impact on 1 file(s) - 16 : "lundump.c" line 19, impact on 1 file(s) - 17 : "lvm.c" line 22, impact on 1 file(s) + 1 : "lvm.h" line 11, impact on 9 files + 2 : "lapi.c" line 21, impact on 1 file + 3 : "lcode.c" line 21, impact on 1 file + 4 : "ldebug.c" line 22, impact on 1 file + 5 : "ldo.c" line 21, impact on 1 file + 6 : "lfunc.c" line 18, impact on 1 file + 7 : "lgc.c" line 19, impact on 1 file + 8 : "llex.c" line 20, impact on 1 file + 9 : "lmem.c" line 18, impact on 1 file + 10 : "lobject.c" line 24, impact on 1 file + 11 : "lparser.c" line 20, impact on 1 file + 12 : "lstate.c" line 20, impact on 1 file + 13 : "lstring.c" line 18, impact on 1 file + 14 : "ltable.c" line 32, impact on 1 file + 15 : "ltm.c" line 18, impact on 1 file + 16 : "lundump.c" line 19, impact on 1 file + 17 : "lvm.c" line 22, impact on 1 file 18 : "ltests.c" line 26 -9 : "lgc.h" impact on 19 file(s) +9 : "lgc.h" impact on 19 files Included by: - 1 : "lstring.h" line 10, impact on 16 file(s) - 2 : "lapi.c" line 23, impact on 1 file(s) - 3 : "lcode.c" line 22, impact on 1 file(s) - 4 : "ldo.c" line 23, impact on 1 file(s) - 5 : "lfunc.c" line 20, impact on 1 file(s) - 6 : "lgc.c" line 21, impact on 1 file(s) - 7 : "llex.c" line 21, impact on 1 file(s) - 8 : "lmem.c" line 19, impact on 1 file(s) - 9 : "lstate.c" line 22, impact on 1 file(s) - 10 : "ltable.c" line 33, impact on 1 file(s) - 11 : "ltm.c" line 19, impact on 1 file(s) - 12 : "lvm.c" line 24, impact on 1 file(s) -10 : "lauxlib.h" impact on 18 file(s) + 1 : "lstring.h" line 10, impact on 16 files + 2 : "lapi.c" line 23, impact on 1 file + 3 : "lcode.c" line 22, impact on 1 file + 4 : "ldo.c" line 23, impact on 1 file + 5 : "lfunc.c" line 20, impact on 1 file + 6 : "lgc.c" line 21, impact on 1 file + 7 : "llex.c" line 21, impact on 1 file + 8 : "lmem.c" line 19, impact on 1 file + 9 : "lstate.c" line 22, impact on 1 file + 10 : "ltable.c" line 33, impact on 1 file + 11 : "ltm.c" line 19, impact on 1 file + 12 : "lvm.c" line 24, impact on 1 file +10 : "lauxlib.h" impact on 18 files Included by: - 1 : "lauxlib.c" line 27, impact on 1 file(s) - 2 : "lbaselib.c" line 20, impact on 1 file(s) - 3 : "lcorolib.c" line 17, impact on 1 file(s) - 4 : "ldblib.c" line 19, impact on 1 file(s) - 5 : "linit.c" line 35, impact on 1 file(s) - 6 : "liolib.c" line 22, impact on 1 file(s) - 7 : "lmathlib.c" line 21, impact on 1 file(s) - 8 : "loadlib.c" line 23, impact on 1 file(s) - 9 : "loslib.c" line 21, impact on 1 file(s) - 10 : "lstrlib.c" line 25, impact on 1 file(s) - 11 : "ltablib.c" line 19, impact on 1 file(s) - 12 : "lua.c" line 20, impact on 1 file(s) - 13 : "lutf8lib.c" line 20, impact on 1 file(s) + 1 : "lauxlib.c" line 27, impact on 1 file + 2 : "lbaselib.c" line 20, impact on 1 file + 3 : "lcorolib.c" line 17, impact on 1 file + 4 : "ldblib.c" line 19, impact on 1 file + 5 : "linit.c" line 35, impact on 1 file + 6 : "liolib.c" line 22, impact on 1 file + 7 : "lmathlib.c" line 21, impact on 1 file + 8 : "loadlib.c" line 23, impact on 1 file + 9 : "loslib.c" line 21, impact on 1 file + 10 : "lstrlib.c" line 25, impact on 1 file + 11 : "ltablib.c" line 19, impact on 1 file + 12 : "lua.c" line 20, impact on 1 file + 13 : "lutf8lib.c" line 20, impact on 1 file 14 : "ltests.c" line 22 15 : "testes\libs\lib1.c" line 2 16 : "testes\libs\lib2.c" line 2 17 : "testes\libs\lib22.c" line 2 -11 : "ldebug.h" impact on 18 file(s) +11 : "ldebug.h" impact on 18 files Included by: - 1 : "lapi.c" line 20, impact on 1 file(s) - 2 : "lcode.c" line 20, impact on 1 file(s) - 3 : "ldebug.c" line 21, impact on 1 file(s) - 4 : "ldo.c" line 20, impact on 1 file(s) - 5 : "lfunc.c" line 17, impact on 1 file(s) - 6 : "lgc.c" line 18, impact on 1 file(s) - 7 : "llex.c" line 19, impact on 1 file(s) - 8 : "lmem.c" line 17, impact on 1 file(s) - 9 : "lobject.c" line 23, impact on 1 file(s) - 10 : "lparser.c" line 19, impact on 1 file(s) - 11 : "lstate.c" line 19, impact on 1 file(s) - 12 : "lstring.c" line 17, impact on 1 file(s) - 13 : "ltable.c" line 31, impact on 1 file(s) - 14 : "ltm.c" line 17, impact on 1 file(s) - 15 : "lundump.c" line 18, impact on 1 file(s) - 16 : "lvm.c" line 21, impact on 1 file(s) + 1 : "lapi.c" line 20, impact on 1 file + 2 : "lcode.c" line 20, impact on 1 file + 3 : "ldebug.c" line 21, impact on 1 file + 4 : "ldo.c" line 20, impact on 1 file + 5 : "lfunc.c" line 17, impact on 1 file + 6 : "lgc.c" line 18, impact on 1 file + 7 : "llex.c" line 19, impact on 1 file + 8 : "lmem.c" line 17, impact on 1 file + 9 : "lobject.c" line 23, impact on 1 file + 10 : "lparser.c" line 19, impact on 1 file + 11 : "lstate.c" line 19, impact on 1 file + 12 : "lstring.c" line 17, impact on 1 file + 13 : "ltable.c" line 31, impact on 1 file + 14 : "ltm.c" line 17, impact on 1 file + 15 : "lundump.c" line 18, impact on 1 file + 16 : "lvm.c" line 21, impact on 1 file 17 : "ltests.c" line 25 -12 : "lstring.h" impact on 16 file(s) +12 : "lstring.h" impact on 16 files Included by: - 1 : "lapi.c" line 27, impact on 1 file(s) - 2 : "lcode.c" line 28, impact on 1 file(s) - 3 : "ldebug.c" line 27, impact on 1 file(s) - 4 : "ldo.c" line 29, impact on 1 file(s) - 5 : "lgc.c" line 25, impact on 1 file(s) - 6 : "llex.c" line 26, impact on 1 file(s) - 7 : "lobject.c" line 28, impact on 1 file(s) - 8 : "lparser.c" line 28, impact on 1 file(s) - 9 : "lstate.c" line 26, impact on 1 file(s) - 10 : "lstring.c" line 22, impact on 1 file(s) - 11 : "ltable.c" line 37, impact on 1 file(s) - 12 : "ltm.c" line 22, impact on 1 file(s) - 13 : "lundump.c" line 23, impact on 1 file(s) - 14 : "lvm.c" line 28, impact on 1 file(s) + 1 : "lapi.c" line 27, impact on 1 file + 2 : "lcode.c" line 28, impact on 1 file + 3 : "ldebug.c" line 27, impact on 1 file + 4 : "ldo.c" line 29, impact on 1 file + 5 : "lgc.c" line 25, impact on 1 file + 6 : "llex.c" line 26, impact on 1 file + 7 : "lobject.c" line 28, impact on 1 file + 8 : "lparser.c" line 28, impact on 1 file + 9 : "lstate.c" line 26, impact on 1 file + 10 : "lstring.c" line 22, impact on 1 file + 11 : "ltable.c" line 37, impact on 1 file + 12 : "ltm.c" line 22, impact on 1 file + 13 : "lundump.c" line 23, impact on 1 file + 14 : "lvm.c" line 28, impact on 1 file 15 : "ltests.c" line 32 -13 : "lmem.h" impact on 15 file(s) +13 : "lmem.h" impact on 15 files Included by: - 1 : "lapi.c" line 24, impact on 1 file(s) - 2 : "lcode.c" line 24, impact on 1 file(s) - 3 : "ldo.c" line 24, impact on 1 file(s) - 4 : "lfunc.c" line 21, impact on 1 file(s) - 5 : "lgc.c" line 22, impact on 1 file(s) - 6 : "lmem.c" line 20, impact on 1 file(s) - 7 : "lobject.c" line 25, impact on 1 file(s) - 8 : "lparser.c" line 23, impact on 1 file(s) - 9 : "lstate.c" line 24, impact on 1 file(s) - 10 : "lstring.c" line 19, impact on 1 file(s) - 11 : "ltable.c" line 34, impact on 1 file(s) - 12 : "lundump.c" line 21, impact on 1 file(s) - 13 : "lzio.c" line 18, impact on 1 file(s) + 1 : "lapi.c" line 24, impact on 1 file + 2 : "lcode.c" line 24, impact on 1 file + 3 : "ldo.c" line 24, impact on 1 file + 4 : "lfunc.c" line 21, impact on 1 file + 5 : "lgc.c" line 22, impact on 1 file + 6 : "lmem.c" line 20, impact on 1 file + 7 : "lobject.c" line 25, impact on 1 file + 8 : "lparser.c" line 23, impact on 1 file + 9 : "lstate.c" line 24, impact on 1 file + 10 : "lstring.c" line 19, impact on 1 file + 11 : "ltable.c" line 34, impact on 1 file + 12 : "lundump.c" line 21, impact on 1 file + 13 : "lzio.c" line 18, impact on 1 file 14 : "ltests.c" line 28 -14 : "lualib.h" impact on 14 file(s) +14 : "lualib.h" impact on 14 files Included by: - 1 : "lbaselib.c" line 21, impact on 1 file(s) - 2 : "lcorolib.c" line 18, impact on 1 file(s) - 3 : "ldblib.c" line 20, impact on 1 file(s) - 4 : "linit.c" line 34, impact on 1 file(s) - 5 : "liolib.c" line 23, impact on 1 file(s) - 6 : "lmathlib.c" line 22, impact on 1 file(s) - 7 : "loadlib.c" line 24, impact on 1 file(s) - 8 : "loslib.c" line 22, impact on 1 file(s) - 9 : "lstrlib.c" line 26, impact on 1 file(s) - 10 : "ltablib.c" line 20, impact on 1 file(s) - 11 : "lua.c" line 21, impact on 1 file(s) - 12 : "lutf8lib.c" line 21, impact on 1 file(s) + 1 : "lbaselib.c" line 21, impact on 1 file + 2 : "lcorolib.c" line 18, impact on 1 file + 3 : "ldblib.c" line 20, impact on 1 file + 4 : "linit.c" line 34, impact on 1 file + 5 : "liolib.c" line 23, impact on 1 file + 6 : "lmathlib.c" line 22, impact on 1 file + 7 : "loadlib.c" line 24, impact on 1 file + 8 : "loslib.c" line 22, impact on 1 file + 9 : "lstrlib.c" line 26, impact on 1 file + 10 : "ltablib.c" line 20, impact on 1 file + 11 : "lua.c" line 21, impact on 1 file + 12 : "lutf8lib.c" line 21, impact on 1 file 13 : "ltests.c" line 34 -15 : "ltable.h" impact on 13 file(s) +15 : "ltable.h" impact on 13 files Included by: - 1 : "lapi.c" line 28, impact on 1 file(s) - 2 : "lcode.c" line 29, impact on 1 file(s) - 3 : "ldebug.c" line 28, impact on 1 file(s) - 4 : "ldo.c" line 30, impact on 1 file(s) - 5 : "lgc.c" line 26, impact on 1 file(s) - 6 : "llex.c" line 27, impact on 1 file(s) - 7 : "lparser.c" line 29, impact on 1 file(s) - 8 : "lstate.c" line 27, impact on 1 file(s) - 9 : "ltable.c" line 38, impact on 1 file(s) - 10 : "ltm.c" line 23, impact on 1 file(s) - 11 : "lvm.c" line 29, impact on 1 file(s) + 1 : "lapi.c" line 28, impact on 1 file + 2 : "lcode.c" line 29, impact on 1 file + 3 : "ldebug.c" line 28, impact on 1 file + 4 : "ldo.c" line 30, impact on 1 file + 5 : "lgc.c" line 26, impact on 1 file + 6 : "llex.c" line 27, impact on 1 file + 7 : "lparser.c" line 29, impact on 1 file + 8 : "lstate.c" line 27, impact on 1 file + 9 : "ltable.c" line 38, impact on 1 file + 10 : "ltm.c" line 23, impact on 1 file + 11 : "lvm.c" line 29, impact on 1 file 12 : "ltests.c" line 33 -16 : "lfunc.h" impact on 11 file(s) +16 : "lfunc.h" impact on 11 files Included by: - 1 : "lapi.c" line 22, impact on 1 file(s) - 2 : "ldebug.c" line 23, impact on 1 file(s) - 3 : "ldo.c" line 22, impact on 1 file(s) - 4 : "lfunc.c" line 19, impact on 1 file(s) - 5 : "lgc.c" line 20, impact on 1 file(s) - 6 : "lparser.c" line 21, impact on 1 file(s) - 7 : "lstate.c" line 21, impact on 1 file(s) - 8 : "lundump.c" line 20, impact on 1 file(s) - 9 : "lvm.c" line 23, impact on 1 file(s) + 1 : "lapi.c" line 22, impact on 1 file + 2 : "ldebug.c" line 23, impact on 1 file + 3 : "ldo.c" line 22, impact on 1 file + 4 : "lfunc.c" line 19, impact on 1 file + 5 : "lgc.c" line 20, impact on 1 file + 6 : "lparser.c" line 21, impact on 1 file + 7 : "lstate.c" line 21, impact on 1 file + 8 : "lundump.c" line 20, impact on 1 file + 9 : "lvm.c" line 23, impact on 1 file 10 : "ltests.c" line 27 -17 : "lopcodes.h" impact on 9 file(s) +17 : "lopcodes.h" impact on 9 files Included by: - 1 : "lcode.h" line 12, impact on 5 file(s) - 2 : "lcode.c" line 26, impact on 1 file(s) - 3 : "ldebug.c" line 25, impact on 1 file(s) - 4 : "ldo.c" line 26, impact on 1 file(s) - 5 : "lopcodes.c" line 13, impact on 1 file(s) - 6 : "lparser.c" line 25, impact on 1 file(s) - 7 : "lvm.c" line 26, impact on 1 file(s) + 1 : "lcode.h" line 12, impact on 5 files + 2 : "lcode.c" line 26, impact on 1 file + 3 : "ldebug.c" line 25, impact on 1 file + 4 : "ldo.c" line 26, impact on 1 file + 5 : "lopcodes.c" line 13, impact on 1 file + 6 : "lparser.c" line 25, impact on 1 file + 7 : "lvm.c" line 26, impact on 1 file 8 : "ltests.c" line 29 -18 : "lvm.h" impact on 9 file(s) +18 : "lvm.h" impact on 9 files Included by: - 1 : "lapi.c" line 31, impact on 1 file(s) - 2 : "lcode.c" line 30, impact on 1 file(s) - 3 : "ldebug.c" line 30, impact on 1 file(s) - 4 : "ldo.c" line 33, impact on 1 file(s) - 5 : "lobject.c" line 29, impact on 1 file(s) - 6 : "ltable.c" line 39, impact on 1 file(s) - 7 : "ltm.c" line 25, impact on 1 file(s) - 8 : "lvm.c" line 31, impact on 1 file(s) -19 : "llex.h" impact on 8 file(s) + 1 : "lapi.c" line 31, impact on 1 file + 2 : "lcode.c" line 30, impact on 1 file + 3 : "ldebug.c" line 30, impact on 1 file + 4 : "ldo.c" line 33, impact on 1 file + 5 : "lobject.c" line 29, impact on 1 file + 6 : "ltable.c" line 39, impact on 1 file + 7 : "ltm.c" line 25, impact on 1 file + 8 : "lvm.c" line 31, impact on 1 file +19 : "llex.h" impact on 8 files Included by: - 1 : "lcode.h" line 10, impact on 5 file(s) - 2 : "lcode.c" line 23, impact on 1 file(s) - 3 : "llex.c" line 22, impact on 1 file(s) - 4 : "lparser.c" line 22, impact on 1 file(s) - 5 : "lstate.c" line 23, impact on 1 file(s) -20 : "lparser.h" impact on 8 file(s) + 1 : "lcode.h" line 10, impact on 5 files + 2 : "lcode.c" line 23, impact on 1 file + 3 : "llex.c" line 22, impact on 1 file + 4 : "lparser.c" line 22, impact on 1 file + 5 : "lstate.c" line 23, impact on 1 file +20 : "lparser.h" impact on 8 files Included by: - 1 : "lcode.h" line 13, impact on 5 file(s) - 2 : "lcode.c" line 27, impact on 1 file(s) - 3 : "ldo.c" line 27, impact on 1 file(s) - 4 : "llex.c" line 24, impact on 1 file(s) - 5 : "lparser.c" line 26, impact on 1 file(s) -21 : "lapi.h" impact on 6 file(s) + 1 : "lcode.h" line 13, impact on 5 files + 2 : "lcode.c" line 27, impact on 1 file + 3 : "ldo.c" line 27, impact on 1 file + 4 : "llex.c" line 24, impact on 1 file + 5 : "lparser.c" line 26, impact on 1 file +21 : "lapi.h" impact on 6 files Included by: - 1 : "lapi.c" line 19, impact on 1 file(s) - 2 : "ldebug.c" line 19, impact on 1 file(s) - 3 : "ldo.c" line 19, impact on 1 file(s) - 4 : "lstate.c" line 18, impact on 1 file(s) + 1 : "lapi.c" line 19, impact on 1 file + 2 : "ldebug.c" line 19, impact on 1 file + 3 : "ldo.c" line 19, impact on 1 file + 4 : "lstate.c" line 18, impact on 1 file 5 : "ltests.c" line 21 -22 : "lcode.h" impact on 5 file(s) +22 : "lcode.h" impact on 5 files Included by: - 1 : "lcode.c" line 19, impact on 1 file(s) - 2 : "ldebug.c" line 20, impact on 1 file(s) - 3 : "lparser.c" line 18, impact on 1 file(s) + 1 : "lcode.c" line 19, impact on 1 file + 2 : "ldebug.c" line 20, impact on 1 file + 3 : "lparser.c" line 18, impact on 1 file 4 : "ltests.c" line 23 -23 : "lctype.h" impact on 5 file(s) +23 : "lctype.h" impact on 5 files Included by: - 1 : "lctype.c" line 13, impact on 1 file(s) - 2 : "llex.c" line 18, impact on 1 file(s) - 3 : "lobject.c" line 22, impact on 1 file(s) + 1 : "lctype.c" line 13, impact on 1 file + 2 : "llex.c" line 18, impact on 1 file + 3 : "lobject.c" line 22, impact on 1 file 4 : "ltests.c" line 24 -24 : "lundump.h" impact on 5 file(s) +24 : "lundump.h" impact on 5 files Included by: - 1 : "lapi.c" line 30, impact on 1 file(s) - 2 : "ldo.c" line 32, impact on 1 file(s) - 3 : "ldump.c" line 19, impact on 1 file(s) - 4 : "lundump.c" line 24, impact on 1 file(s) -25 : "ljumptab.h" impact on 2 file(s) + 1 : "lapi.c" line 30, impact on 1 file + 2 : "ldo.c" line 32, impact on 1 file + 3 : "ldump.c" line 19, impact on 1 file + 4 : "lundump.c" line 24, impact on 1 file +25 : "ljumptab.h" impact on 2 files Included by: - 1 : "lvm.c" line 1134, impact on 1 file(s) -26 : "lapi.c" impact on 1 file(s) + 1 : "lvm.c" line 1 134, impact on 1 file +26 : "lapi.c" impact on 1 file Included by: 1 : "onelua.c" line 79 -27 : "lauxlib.c" impact on 1 file(s) +27 : "lauxlib.c" impact on 1 file Included by: 1 : "onelua.c" line 82 -28 : "lbaselib.c" impact on 1 file(s) +28 : "lbaselib.c" impact on 1 file Included by: 1 : "onelua.c" line 86 -29 : "lcode.c" impact on 1 file(s) +29 : "lcode.c" impact on 1 file Included by: 1 : "onelua.c" line 69 -30 : "lcorolib.c" impact on 1 file(s) +30 : "lcorolib.c" impact on 1 file Included by: 1 : "onelua.c" line 87 ... 30 of 59 files -Unincluded headers: +Unincluded header: 1 : "ltests.h" diff --git a/docs/examples/notepad-plus-plus/output_unix.txt b/docs/examples/notepad-plus-plus/output_unix.txt index a47447e..d521c07 100644 --- a/docs/examples/notepad-plus-plus/output_unix.txt +++ b/docs/examples/notepad-plus-plus/output_unix.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "scintilla/include/Sci_Position.h" impact on 249 file(s) +1 : "scintilla/include/Sci_Position.h" impact on 249 files Included by: - 1 : "scintilla/include/Scintilla.h" line 37, impact on 243 file(s) - 2 : "scintilla/include/ILexer.h" line 11, impact on 141 file(s) - 3 : "scintilla/include/ILoader.h" line 11, impact on 17 file(s) + 1 : "scintilla/include/Scintilla.h" line 37, impact on 243 files + 2 : "scintilla/include/ILexer.h" line 11, impact on 141 files + 3 : "scintilla/include/ILoader.h" line 11, impact on 17 files 4 : "scintilla/test/unit/testSparseState.cxx" line 11 -2 : "scintilla/include/Scintilla.h" impact on 243 file(s) +2 : "scintilla/include/Scintilla.h" impact on 243 files Included by: - 1 : "PowerEditor/src/WinControls/shortcut/shortcut.h" line 32, impact on 82 file(s) - 2 : "PowerEditor/src/Parameters.h" line 32, impact on 81 file(s) - 3 : "PowerEditor/src/ScitillaComponent/ScintillaEditView.h" line 32, impact on 43 file(s) - 4 : "PowerEditor/src/MISC/PluginsManager/PluginInterface.h" line 31, impact on 17 file(s) - 5 : "scintilla/qt/ScintillaEditBase/ScintillaEditBase.h" line 22, impact on 2 file(s) - 6 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 30, impact on 2 file(s) + 1 : "PowerEditor/src/WinControls/shortcut/shortcut.h" line 32, impact on 82 files + 2 : "PowerEditor/src/Parameters.h" line 32, impact on 81 files + 3 : "PowerEditor/src/ScitillaComponent/ScintillaEditView.h" line 32, impact on 43 files + 4 : "PowerEditor/src/MISC/PluginsManager/PluginInterface.h" line 31, impact on 17 files + 5 : "scintilla/qt/ScintillaEditBase/ScintillaEditBase.h" line 22, impact on 2 files + 6 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 30, impact on 2 files 7 : "PowerEditor/src/EncodingMapper.cpp" line 31 8 : "PowerEditor/src/ScitillaComponent/Buffer.cpp" line 33 9 : "scintilla/boostregex/BoostRegExSearch.cxx" line 16 10 : "scintilla/boostregex/UTF8DocumentIterator.cxx" line 7 ... 10 of 161 details -3 : "scintilla/include/SciLexer.h" impact on 214 file(s) +3 : "scintilla/include/SciLexer.h" impact on 214 files Included by: - 1 : "PowerEditor/src/ScitillaComponent/UserDefineLangReference.h" line 31, impact on 82 file(s) - 2 : "PowerEditor/src/ScitillaComponent/UserDefineDialog.h" line 36, impact on 44 file(s) - 3 : "PowerEditor/src/ScitillaComponent/ScintillaEditView.h" line 34, impact on 43 file(s) - 4 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 63, impact on 2 file(s) + 1 : "PowerEditor/src/ScitillaComponent/UserDefineLangReference.h" line 31, impact on 82 files + 2 : "PowerEditor/src/ScitillaComponent/UserDefineDialog.h" line 36, impact on 44 files + 3 : "PowerEditor/src/ScitillaComponent/ScintillaEditView.h" line 34, impact on 43 files + 4 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 63, impact on 2 files 5 : "scintilla/cocoa/ScintillaCocoa.h" line 31 6 : "scintilla/gtk/ScintillaGTK.cxx" line 46 7 : "scintilla/gtk/ScintillaGTKAccessible.cxx" line 96 @@ -34,9 +34,9 @@ Included by: 9 : "scintilla/lexers/LexAPDL.cxx" line 18 10 : "scintilla/lexers/LexASY.cxx" line 13 ... 10 of 132 details -4 : "scintilla/include/ILexer.h" impact on 141 file(s) +4 : "scintilla/include/ILexer.h" impact on 141 files Included by: - 1 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 33, impact on 2 file(s) + 1 : "scintilla/qt/ScintillaEditBase/ScintillaQt.h" line 33, impact on 2 files 2 : "scintilla/boostregex/BoostRegExSearch.cxx" line 19 3 : "scintilla/boostregex/UTF8DocumentIterator.cxx" line 6 4 : "scintilla/cocoa/ScintillaCocoa.h" line 28 @@ -47,33 +47,33 @@ Included by: 9 : "scintilla/lexers/LexASY.cxx" line 11 10 : "scintilla/lexers/LexAU3.cxx" line 60 ... 10 of 139 details -5 : "PowerEditor/src/MISC/Common/Common.h" impact on 139 file(s) +5 : "PowerEditor/src/MISC/Common/Common.h" impact on 139 files Included by: - 1 : "PowerEditor/src/TinyXml/tinyxml.h" line 64, impact on 89 file(s) - 2 : "PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.h" line 63, impact on 88 file(s) - 3 : "PowerEditor/src/WinControls/ContextMenu/ContextMenu.h" line 28, impact on 83 file(s) - 4 : "PowerEditor/src/WinControls/ToolBar/ToolBar.h" line 31, impact on 82 file(s) - 5 : "PowerEditor/src/WinControls/shortcut/shortcut.h" line 34, impact on 82 file(s) - 6 : "PowerEditor/src/WinControls/AboutDlg/URLCtrl.h" line 32, impact on 50 file(s) - 7 : "PowerEditor/src/WinControls/TabBar/ControlsTab.h" line 33, impact on 48 file(s) - 8 : "PowerEditor/src/WinControls/DockingWnd/DockingDlgInterface.h" line 35, impact on 31 file(s) - 9 : "PowerEditor/src/localization.h" line 31, impact on 29 file(s) - 10 : "PowerEditor/src/WinControls/AnsiCharPanel/ListView.h" line 32, impact on 21 file(s) + 1 : "PowerEditor/src/TinyXml/tinyxml.h" line 64, impact on 89 files + 2 : "PowerEditor/src/TinyXml/tinyXmlA/tinyxmlA.h" line 63, impact on 88 files + 3 : "PowerEditor/src/WinControls/ContextMenu/ContextMenu.h" line 28, impact on 83 files + 4 : "PowerEditor/src/WinControls/ToolBar/ToolBar.h" line 31, impact on 82 files + 5 : "PowerEditor/src/WinControls/shortcut/shortcut.h" line 34, impact on 82 files + 6 : "PowerEditor/src/WinControls/AboutDlg/URLCtrl.h" line 32, impact on 50 files + 7 : "PowerEditor/src/WinControls/TabBar/ControlsTab.h" line 33, impact on 48 files + 8 : "PowerEditor/src/WinControls/DockingWnd/DockingDlgInterface.h" line 35, impact on 31 files + 9 : "PowerEditor/src/localization.h" line 31, impact on 29 files + 10 : "PowerEditor/src/WinControls/AnsiCharPanel/ListView.h" line 32, impact on 21 files ... 10 of 30 details -6 : "PowerEditor/src/WinControls/Window.h" impact on 137 file(s) +6 : "PowerEditor/src/WinControls/Window.h" impact on 137 files Included by: - 1 : "PowerEditor/src/WinControls/StaticDialog/StaticDialog.h" line 29, impact on 109 file(s) - 2 : "PowerEditor/src/WinControls/ToolBar/ToolBar.h" line 32, impact on 82 file(s) - 3 : "PowerEditor/src/WinControls/TabBar/TabBar.h" line 40, impact on 53 file(s) - 4 : "PowerEditor/src/WinControls/AboutDlg/URLCtrl.h" line 31, impact on 50 file(s) - 5 : "PowerEditor/src/WinControls/ColourPicker/ColourPicker.h" line 31, impact on 49 file(s) - 6 : "PowerEditor/src/WinControls/TabBar/ControlsTab.h" line 32, impact on 48 file(s) - 7 : "PowerEditor/src/WinControls/AnsiCharPanel/ListView.h" line 31, impact on 21 file(s) - 8 : "PowerEditor/src/WinControls/SplitterContainer/Splitter.h" line 29, impact on 21 file(s) - 9 : "PowerEditor/src/WinControls/StatusBar/StatusBar.h" line 33, impact on 18 file(s) - 10 : "PowerEditor/src/WinControls/DockingWnd/DockingManager.h" line 33, impact on 16 file(s) + 1 : "PowerEditor/src/WinControls/StaticDialog/StaticDialog.h" line 29, impact on 109 files + 2 : "PowerEditor/src/WinControls/ToolBar/ToolBar.h" line 32, impact on 82 files + 3 : "PowerEditor/src/WinControls/TabBar/TabBar.h" line 40, impact on 53 files + 4 : "PowerEditor/src/WinControls/AboutDlg/URLCtrl.h" line 31, impact on 50 files + 5 : "PowerEditor/src/WinControls/ColourPicker/ColourPicker.h" line 31, impact on 49 files + 6 : "PowerEditor/src/WinControls/TabBar/ControlsTab.h" line 32, impact on 48 files + 7 : "PowerEditor/src/WinControls/AnsiCharPanel/ListView.h" line 31, impact on 21 files + 8 : "PowerEditor/src/WinControls/SplitterContainer/Splitter.h" line 29, impact on 21 files + 9 : "PowerEditor/src/WinControls/StatusBar/StatusBar.h" line 33, impact on 18 files + 10 : "PowerEditor/src/WinControls/DockingWnd/DockingManager.h" line 33, impact on 16 files ... 10 of 20 details -7 : "scintilla/lexlib/LexerModule.h" impact on 127 file(s) +7 : "scintilla/lexlib/LexerModule.h" impact on 127 files Included by: 1 : "scintilla/gtk/ScintillaGTK.cxx" line 51 2 : "scintilla/gtk/ScintillaGTKAccessible.cxx" line 101 @@ -86,7 +86,7 @@ Included by: 9 : "scintilla/lexers/LexAbaqus.cxx" line 27 10 : "scintilla/lexers/LexAda.cxx" line 26 ... 10 of 127 details -8 : "scintilla/lexlib/LexAccessor.h" impact on 121 file(s) +8 : "scintilla/lexlib/LexAccessor.h" impact on 121 files Included by: 1 : "scintilla/lexers/LexA68k.cxx" line 23 2 : "scintilla/lexers/LexAPDL.cxx" line 21 @@ -99,7 +99,7 @@ Included by: 9 : "scintilla/lexers/LexAsm.cxx" line 28 10 : "scintilla/lexers/LexAsn1.cxx" line 20 ... 10 of 121 details -9 : "scintilla/lexlib/WordList.h" impact on 121 file(s) +9 : "scintilla/lexlib/WordList.h" impact on 121 files Included by: 1 : "scintilla/lexers/LexA68k.cxx" line 22 2 : "scintilla/lexers/LexAPDL.cxx" line 20 @@ -112,7 +112,7 @@ Included by: 9 : "scintilla/lexers/LexAsm.cxx" line 27 10 : "scintilla/lexers/LexAsn1.cxx" line 19 ... 10 of 121 details -10 : "scintilla/lexlib/CharacterSet.h" impact on 119 file(s) +10 : "scintilla/lexlib/CharacterSet.h" impact on 119 files Included by: 1 : "scintilla/lexers/LexA68k.cxx" line 26 2 : "scintilla/lexers/LexAPDL.cxx" line 24 diff --git a/docs/examples/notepad-plus-plus/output_win.txt b/docs/examples/notepad-plus-plus/output_win.txt index dbea16b..b693fae 100644 --- a/docs/examples/notepad-plus-plus/output_win.txt +++ b/docs/examples/notepad-plus-plus/output_win.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "scintilla\include\Sci_Position.h" impact on 249 file(s) +1 : "scintilla\include\Sci_Position.h" impact on 249 files Included by: - 1 : "scintilla\include\Scintilla.h" line 37, impact on 243 file(s) - 2 : "scintilla\include\ILexer.h" line 11, impact on 141 file(s) - 3 : "scintilla\include\ILoader.h" line 11, impact on 17 file(s) + 1 : "scintilla\include\Scintilla.h" line 37, impact on 243 files + 2 : "scintilla\include\ILexer.h" line 11, impact on 141 files + 3 : "scintilla\include\ILoader.h" line 11, impact on 17 files 4 : "scintilla\test\unit\testSparseState.cxx" line 11 -2 : "scintilla\include\Scintilla.h" impact on 243 file(s) +2 : "scintilla\include\Scintilla.h" impact on 243 files Included by: - 1 : "PowerEditor\src\WinControls\shortcut\shortcut.h" line 32, impact on 82 file(s) - 2 : "PowerEditor\src\Parameters.h" line 32, impact on 81 file(s) - 3 : "PowerEditor\src\ScitillaComponent\ScintillaEditView.h" line 32, impact on 43 file(s) - 4 : "PowerEditor\src\MISC\PluginsManager\PluginInterface.h" line 31, impact on 17 file(s) - 5 : "scintilla\qt\ScintillaEditBase\ScintillaEditBase.h" line 22, impact on 2 file(s) - 6 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 30, impact on 2 file(s) + 1 : "PowerEditor\src\WinControls\shortcut\shortcut.h" line 32, impact on 82 files + 2 : "PowerEditor\src\Parameters.h" line 32, impact on 81 files + 3 : "PowerEditor\src\ScitillaComponent\ScintillaEditView.h" line 32, impact on 43 files + 4 : "PowerEditor\src\MISC\PluginsManager\PluginInterface.h" line 31, impact on 17 files + 5 : "scintilla\qt\ScintillaEditBase\ScintillaEditBase.h" line 22, impact on 2 files + 6 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 30, impact on 2 files 7 : "PowerEditor\src\EncodingMapper.cpp" line 31 8 : "PowerEditor\src\ScitillaComponent\Buffer.cpp" line 33 9 : "scintilla\boostregex\BoostRegExSearch.cxx" line 16 10 : "scintilla\boostregex\UTF8DocumentIterator.cxx" line 7 ... 10 of 161 details -3 : "scintilla\include\SciLexer.h" impact on 214 file(s) +3 : "scintilla\include\SciLexer.h" impact on 214 files Included by: - 1 : "PowerEditor\src\ScitillaComponent\UserDefineLangReference.h" line 31, impact on 82 file(s) - 2 : "PowerEditor\src\ScitillaComponent\UserDefineDialog.h" line 36, impact on 44 file(s) - 3 : "PowerEditor\src\ScitillaComponent\ScintillaEditView.h" line 34, impact on 43 file(s) - 4 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 63, impact on 2 file(s) + 1 : "PowerEditor\src\ScitillaComponent\UserDefineLangReference.h" line 31, impact on 82 files + 2 : "PowerEditor\src\ScitillaComponent\UserDefineDialog.h" line 36, impact on 44 files + 3 : "PowerEditor\src\ScitillaComponent\ScintillaEditView.h" line 34, impact on 43 files + 4 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 63, impact on 2 files 5 : "scintilla\cocoa\ScintillaCocoa.h" line 31 6 : "scintilla\gtk\ScintillaGTK.cxx" line 46 7 : "scintilla\gtk\ScintillaGTKAccessible.cxx" line 96 @@ -34,9 +34,9 @@ Included by: 9 : "scintilla\lexers\LexAPDL.cxx" line 18 10 : "scintilla\lexers\LexASY.cxx" line 13 ... 10 of 132 details -4 : "scintilla\include\ILexer.h" impact on 141 file(s) +4 : "scintilla\include\ILexer.h" impact on 141 files Included by: - 1 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 33, impact on 2 file(s) + 1 : "scintilla\qt\ScintillaEditBase\ScintillaQt.h" line 33, impact on 2 files 2 : "scintilla\boostregex\BoostRegExSearch.cxx" line 19 3 : "scintilla\boostregex\UTF8DocumentIterator.cxx" line 6 4 : "scintilla\cocoa\ScintillaCocoa.h" line 28 @@ -47,33 +47,33 @@ Included by: 9 : "scintilla\lexers\LexASY.cxx" line 11 10 : "scintilla\lexers\LexAU3.cxx" line 60 ... 10 of 139 details -5 : "PowerEditor\src\MISC\Common\Common.h" impact on 139 file(s) +5 : "PowerEditor\src\MISC\Common\Common.h" impact on 139 files Included by: - 1 : "PowerEditor\src\TinyXml\tinyxml.h" line 64, impact on 89 file(s) - 2 : "PowerEditor\src\TinyXml\tinyXmlA\tinyxmlA.h" line 63, impact on 88 file(s) - 3 : "PowerEditor\src\WinControls\ContextMenu\ContextMenu.h" line 28, impact on 83 file(s) - 4 : "PowerEditor\src\WinControls\ToolBar\ToolBar.h" line 31, impact on 82 file(s) - 5 : "PowerEditor\src\WinControls\shortcut\shortcut.h" line 34, impact on 82 file(s) - 6 : "PowerEditor\src\WinControls\AboutDlg\URLCtrl.h" line 32, impact on 50 file(s) - 7 : "PowerEditor\src\WinControls\TabBar\ControlsTab.h" line 33, impact on 48 file(s) - 8 : "PowerEditor\src\WinControls\DockingWnd\DockingDlgInterface.h" line 35, impact on 31 file(s) - 9 : "PowerEditor\src\localization.h" line 31, impact on 29 file(s) - 10 : "PowerEditor\src\WinControls\AnsiCharPanel\ListView.h" line 32, impact on 21 file(s) + 1 : "PowerEditor\src\TinyXml\tinyxml.h" line 64, impact on 89 files + 2 : "PowerEditor\src\TinyXml\tinyXmlA\tinyxmlA.h" line 63, impact on 88 files + 3 : "PowerEditor\src\WinControls\ContextMenu\ContextMenu.h" line 28, impact on 83 files + 4 : "PowerEditor\src\WinControls\ToolBar\ToolBar.h" line 31, impact on 82 files + 5 : "PowerEditor\src\WinControls\shortcut\shortcut.h" line 34, impact on 82 files + 6 : "PowerEditor\src\WinControls\AboutDlg\URLCtrl.h" line 32, impact on 50 files + 7 : "PowerEditor\src\WinControls\TabBar\ControlsTab.h" line 33, impact on 48 files + 8 : "PowerEditor\src\WinControls\DockingWnd\DockingDlgInterface.h" line 35, impact on 31 files + 9 : "PowerEditor\src\localization.h" line 31, impact on 29 files + 10 : "PowerEditor\src\WinControls\AnsiCharPanel\ListView.h" line 32, impact on 21 files ... 10 of 30 details -6 : "PowerEditor\src\WinControls\Window.h" impact on 137 file(s) +6 : "PowerEditor\src\WinControls\Window.h" impact on 137 files Included by: - 1 : "PowerEditor\src\WinControls\StaticDialog\StaticDialog.h" line 29, impact on 109 file(s) - 2 : "PowerEditor\src\WinControls\ToolBar\ToolBar.h" line 32, impact on 82 file(s) - 3 : "PowerEditor\src\WinControls\TabBar\TabBar.h" line 40, impact on 53 file(s) - 4 : "PowerEditor\src\WinControls\AboutDlg\URLCtrl.h" line 31, impact on 50 file(s) - 5 : "PowerEditor\src\WinControls\ColourPicker\ColourPicker.h" line 31, impact on 49 file(s) - 6 : "PowerEditor\src\WinControls\TabBar\ControlsTab.h" line 32, impact on 48 file(s) - 7 : "PowerEditor\src\WinControls\AnsiCharPanel\ListView.h" line 31, impact on 21 file(s) - 8 : "PowerEditor\src\WinControls\SplitterContainer\Splitter.h" line 29, impact on 21 file(s) - 9 : "PowerEditor\src\WinControls\StatusBar\StatusBar.h" line 33, impact on 18 file(s) - 10 : "PowerEditor\src\WinControls\DockingWnd\DockingManager.h" line 33, impact on 16 file(s) + 1 : "PowerEditor\src\WinControls\StaticDialog\StaticDialog.h" line 29, impact on 109 files + 2 : "PowerEditor\src\WinControls\ToolBar\ToolBar.h" line 32, impact on 82 files + 3 : "PowerEditor\src\WinControls\TabBar\TabBar.h" line 40, impact on 53 files + 4 : "PowerEditor\src\WinControls\AboutDlg\URLCtrl.h" line 31, impact on 50 files + 5 : "PowerEditor\src\WinControls\ColourPicker\ColourPicker.h" line 31, impact on 49 files + 6 : "PowerEditor\src\WinControls\TabBar\ControlsTab.h" line 32, impact on 48 files + 7 : "PowerEditor\src\WinControls\AnsiCharPanel\ListView.h" line 31, impact on 21 files + 8 : "PowerEditor\src\WinControls\SplitterContainer\Splitter.h" line 29, impact on 21 files + 9 : "PowerEditor\src\WinControls\StatusBar\StatusBar.h" line 33, impact on 18 files + 10 : "PowerEditor\src\WinControls\DockingWnd\DockingManager.h" line 33, impact on 16 files ... 10 of 20 details -7 : "scintilla\lexlib\LexerModule.h" impact on 127 file(s) +7 : "scintilla\lexlib\LexerModule.h" impact on 127 files Included by: 1 : "scintilla\gtk\ScintillaGTK.cxx" line 51 2 : "scintilla\gtk\ScintillaGTKAccessible.cxx" line 101 @@ -86,7 +86,7 @@ Included by: 9 : "scintilla\lexers\LexAbaqus.cxx" line 27 10 : "scintilla\lexers\LexAda.cxx" line 26 ... 10 of 127 details -8 : "scintilla\lexlib\LexAccessor.h" impact on 121 file(s) +8 : "scintilla\lexlib\LexAccessor.h" impact on 121 files Included by: 1 : "scintilla\lexers\LexA68k.cxx" line 23 2 : "scintilla\lexers\LexAPDL.cxx" line 21 @@ -99,7 +99,7 @@ Included by: 9 : "scintilla\lexers\LexAsm.cxx" line 28 10 : "scintilla\lexers\LexAsn1.cxx" line 20 ... 10 of 121 details -9 : "scintilla\lexlib\WordList.h" impact on 121 file(s) +9 : "scintilla\lexlib\WordList.h" impact on 121 files Included by: 1 : "scintilla\lexers\LexA68k.cxx" line 22 2 : "scintilla\lexers\LexAPDL.cxx" line 20 @@ -112,7 +112,7 @@ Included by: 9 : "scintilla\lexers\LexAsm.cxx" line 27 10 : "scintilla\lexers\LexAsn1.cxx" line 19 ... 10 of 121 details -10 : "scintilla\lexlib\CharacterSet.h" impact on 119 file(s) +10 : "scintilla\lexlib\CharacterSet.h" impact on 119 files Included by: 1 : "scintilla\lexers\LexA68k.cxx" line 26 2 : "scintilla\lexers\LexAPDL.cxx" line 24 diff --git a/docs/examples/simple_example/output_unix.txt b/docs/examples/simple_example/output_unix.txt index 39ccf84..7ed21b7 100644 --- a/docs/examples/simple_example/output_unix.txt +++ b/docs/examples/simple_example/output_unix.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "char_a.hpp" impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 2 : "main.cpp" line 2 diff --git a/docs/examples/simple_example/output_win.txt b/docs/examples/simple_example/output_win.txt index 3395e67..6d24c1f 100644 --- a/docs/examples/simple_example/output_win.txt +++ b/docs/examples/simple_example/output_win.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "char_a.hpp" impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 2 : "main.cpp" line 2 diff --git a/docs/examples/simple_example_cmake/output_unix.txt b/docs/examples/simple_example_cmake/output_unix.txt index d6a204f..99ef5da 100644 --- a/docs/examples/simple_example_cmake/output_unix.txt +++ b/docs/examples/simple_example_cmake/output_unix.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "../char_kind.hpp" impact on 11 file(s) +1 : "../char_kind.hpp" impact on 11 files Included by: - 1 : "../base_char.hpp" line 3, impact on 10 file(s) -2 : "../base_char.hpp" impact on 10 file(s) + 1 : "../base_char.hpp" line 3, impact on 10 files +2 : "../base_char.hpp" impact on 10 files Included by: - 1 : "../base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "../char_a.hpp" line 3, impact on 2 file(s) - 3 : "../char_b.hpp" line 3, impact on 2 file(s) -3 : "../base_char_factory.hpp" impact on 5 file(s) + 1 : "../base_char_factory.hpp" line 3, impact on 5 files + 2 : "../char_a.hpp" line 3, impact on 2 files + 3 : "../char_b.hpp" line 3, impact on 2 files +3 : "../base_char_factory.hpp" impact on 5 files Included by: - 1 : "../char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "../char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "../char_a.hpp" impact on 2 file(s) + 1 : "../char_a_factory.hpp" line 3, impact on 2 files + 2 : "../char_b_factory.hpp" line 3, impact on 2 files +4 : "../char_a.hpp" impact on 2 files Included by: 1 : "../char_a.cpp" line 1 2 : "../char_a_factory.cpp" line 3 -5 : "../char_a_factory.hpp" impact on 2 file(s) +5 : "../char_a_factory.hpp" impact on 2 files Included by: 1 : "../char_a_factory.cpp" line 1 2 : "../main.cpp" line 1 -6 : "../char_b.hpp" impact on 2 file(s) +6 : "../char_b.hpp" impact on 2 files Included by: 1 : "../char_b.cpp" line 1 2 : "../char_b_factory.cpp" line 3 -7 : "../char_b_factory.hpp" impact on 2 file(s) +7 : "../char_b_factory.hpp" impact on 2 files Included by: 1 : "../char_b_factory.cpp" line 1 2 : "../main.cpp" line 2 diff --git a/docs/examples/simple_example_cmake/output_win.txt b/docs/examples/simple_example_cmake/output_win.txt index 6847c6c..943a25c 100644 --- a/docs/examples/simple_example_cmake/output_win.txt +++ b/docs/examples/simple_example_cmake/output_win.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "..\char_kind.hpp" impact on 11 file(s) +1 : "..\char_kind.hpp" impact on 11 files Included by: - 1 : "..\base_char.hpp" line 3, impact on 10 file(s) -2 : "..\base_char.hpp" impact on 10 file(s) + 1 : "..\base_char.hpp" line 3, impact on 10 files +2 : "..\base_char.hpp" impact on 10 files Included by: - 1 : "..\base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "..\char_a.hpp" line 3, impact on 2 file(s) - 3 : "..\char_b.hpp" line 3, impact on 2 file(s) -3 : "..\base_char_factory.hpp" impact on 5 file(s) + 1 : "..\base_char_factory.hpp" line 3, impact on 5 files + 2 : "..\char_a.hpp" line 3, impact on 2 files + 3 : "..\char_b.hpp" line 3, impact on 2 files +3 : "..\base_char_factory.hpp" impact on 5 files Included by: - 1 : "..\char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "..\char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "..\char_a.hpp" impact on 2 file(s) + 1 : "..\char_a_factory.hpp" line 3, impact on 2 files + 2 : "..\char_b_factory.hpp" line 3, impact on 2 files +4 : "..\char_a.hpp" impact on 2 files Included by: 1 : "..\char_a.cpp" line 1 2 : "..\char_a_factory.cpp" line 3 -5 : "..\char_a_factory.hpp" impact on 2 file(s) +5 : "..\char_a_factory.hpp" impact on 2 files Included by: 1 : "..\char_a_factory.cpp" line 1 2 : "..\main.cpp" line 1 -6 : "..\char_b.hpp" impact on 2 file(s) +6 : "..\char_b.hpp" impact on 2 files Included by: 1 : "..\char_b.cpp" line 1 2 : "..\char_b_factory.cpp" line 3 -7 : "..\char_b_factory.hpp" impact on 2 file(s) +7 : "..\char_b_factory.hpp" impact on 2 files Included by: 1 : "..\char_b_factory.cpp" line 1 2 : "..\main.cpp" line 2 diff --git a/docs/examples/simple_example_for_different_type_report/output_unix.txt b/docs/examples/simple_example_for_different_type_report/output_unix.txt index ee89d32..e0501c0 100644 --- a/docs/examples/simple_example_for_different_type_report/output_unix.txt +++ b/docs/examples/simple_example_for_different_type_report/output_unix.txt @@ -1,15 +1,15 @@ Start initialization project ... Start analyze sources ... Start report results ... -Files that are included by different ways: -1. base_char.hpp +Files that are included by different ways ( #include "..." and #include <...> ) : +1 : base_char.hpp With double quotation marks ( #include "..." ) in files: - 1. base_char_factory.hpp line 3 - 2. char_b.hpp line 3 -With angle brackets ( #include <...> ) in files: - 1. char_a.hpp line 3 -2. base_char_factory.hpp -With double quotation marks ( #include "..." ) in files: - 1. char_b_factory.hpp line 3 -With angle brackets ( #include <...> ) in files: - 1. char_a_factory.hpp line 3 + 1 : base_char_factory.hpp line 3 + 2 : char_b.hpp line 3 +With angle brackets ( #include <...> ) in file: + 1 : char_a.hpp line 3 +2 : base_char_factory.hpp +With double quotation marks ( #include "..." ) in file: + 1 : char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in file: + 1 : char_a_factory.hpp line 3 diff --git a/docs/examples/simple_example_for_different_type_report/output_win.txt b/docs/examples/simple_example_for_different_type_report/output_win.txt index a380293..29309bd 100644 --- a/docs/examples/simple_example_for_different_type_report/output_win.txt +++ b/docs/examples/simple_example_for_different_type_report/output_win.txt @@ -1,15 +1,15 @@ Start initialization project ... Start analyze sources ... Start report results ... -Files that are included by different ways: -1. base_char.hpp +Files that are included by different ways ( #include "..." and #include <...> ) : +1 : base_char.hpp With double quotation marks ( #include "..." ) in files: - 1. base_char_factory.hpp line 3 - 2. char_b.hpp line 3 -With angle brackets ( #include <...> ) in files: - 1. char_a.hpp line 3 -2. base_char_factory.hpp -With double quotation marks ( #include "..." ) in files: - 1. char_b_factory.hpp line 3 -With angle brackets ( #include <...> ) in files: - 1. char_a_factory.hpp line 3 + 1 : base_char_factory.hpp line 3 + 2 : char_b.hpp line 3 +With angle brackets ( #include <...> ) in file: + 1 : char_a.hpp line 3 +2 : base_char_factory.hpp +With double quotation marks ( #include "..." ) in file: + 1 : char_b_factory.hpp line 3 +With angle brackets ( #include <...> ) in file: + 1 : char_a_factory.hpp line 3 diff --git a/docs/examples/simple_example_with_forward_declaration/output_unix.txt b/docs/examples/simple_example_with_forward_declaration/output_unix.txt index 8d7ef2d..7b4c7eb 100644 --- a/docs/examples/simple_example_with_forward_declaration/output_unix.txt +++ b/docs/examples/simple_example_with_forward_declaration/output_unix.txt @@ -2,33 +2,33 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "base_char.hpp" impact on 7 file(s) +1 : "base_char.hpp" impact on 7 files Included by: - 1 : "char_a.hpp" line 3, impact on 2 file(s) - 2 : "char_b.hpp" line 3, impact on 2 file(s) - 3 : "main.cpp" line 4 -2 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "char_a.hpp" line 3, impact on 2 files + 2 : "char_b.hpp" line 3, impact on 2 files + 3 : "main.cpp" line 1 +2 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -3 : "char_kind.hpp" impact on 3 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +3 : "char_kind.hpp" impact on 3 files Included by: 1 : "char_a.cpp" line 3 2 : "char_b.cpp" line 3 - 3 : "main.cpp" line 3 -4 : "char_a.hpp" impact on 2 file(s) + 3 : "main.cpp" line 4 +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 - 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) + 2 : "main.cpp" line 2 +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 - 2 : "main.cpp" line 2 + 2 : "main.cpp" line 3 diff --git a/docs/examples/simple_example_with_forward_declaration/output_win.txt b/docs/examples/simple_example_with_forward_declaration/output_win.txt index 22b5b55..a6350c1 100644 --- a/docs/examples/simple_example_with_forward_declaration/output_win.txt +++ b/docs/examples/simple_example_with_forward_declaration/output_win.txt @@ -2,33 +2,33 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "base_char.hpp" impact on 7 file(s) +1 : "base_char.hpp" impact on 7 files Included by: - 1 : "char_a.hpp" line 3, impact on 2 file(s) - 2 : "char_b.hpp" line 3, impact on 2 file(s) - 3 : "main.cpp" line 4 -2 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "char_a.hpp" line 3, impact on 2 files + 2 : "char_b.hpp" line 3, impact on 2 files + 3 : "main.cpp" line 1 +2 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -3 : "char_kind.hpp" impact on 3 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +3 : "char_kind.hpp" impact on 3 files Included by: 1 : "char_a.cpp" line 3 2 : "char_b.cpp" line 3 - 3 : "main.cpp" line 3 -4 : "char_a.hpp" impact on 2 file(s) + 3 : "main.cpp" line 4 +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 - 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) + 2 : "main.cpp" line 2 +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 - 2 : "main.cpp" line 2 + 2 : "main.cpp" line 3 diff --git a/docs/examples/simple_example_with_include_path_cmake/output_unix.txt b/docs/examples/simple_example_with_include_path_cmake/output_unix.txt index 56b73f0..458febe 100644 --- a/docs/examples/simple_example_with_include_path_cmake/output_unix.txt +++ b/docs/examples/simple_example_with_include_path_cmake/output_unix.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "../lib/char_kind.hpp" impact on 11 file(s) +1 : "../lib/char_kind.hpp" impact on 11 files Included by: - 1 : "../lib/base/base_char.hpp" line 3, impact on 10 file(s) -2 : "../lib/base/base_char.hpp" impact on 10 file(s) + 1 : "../lib/base/base_char.hpp" line 3, impact on 10 files +2 : "../lib/base/base_char.hpp" impact on 10 files Included by: - 1 : "../lib/base/base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "../lib/a/char_a.hpp" line 3, impact on 2 file(s) - 3 : "../lib/b/char_b.hpp" line 3, impact on 2 file(s) -3 : "../lib/base/base_char_factory.hpp" impact on 5 file(s) + 1 : "../lib/base/base_char_factory.hpp" line 3, impact on 5 files + 2 : "../lib/a/char_a.hpp" line 3, impact on 2 files + 3 : "../lib/b/char_b.hpp" line 3, impact on 2 files +3 : "../lib/base/base_char_factory.hpp" impact on 5 files Included by: - 1 : "../lib/a/char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "../lib/b/char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "../lib/a/char_a.hpp" impact on 2 file(s) + 1 : "../lib/a/char_a_factory.hpp" line 3, impact on 2 files + 2 : "../lib/b/char_b_factory.hpp" line 3, impact on 2 files +4 : "../lib/a/char_a.hpp" impact on 2 files Included by: 1 : "../lib/a/char_a.cpp" line 1 2 : "../lib/a/char_a_factory.cpp" line 3 -5 : "../lib/a/char_a_factory.hpp" impact on 2 file(s) +5 : "../lib/a/char_a_factory.hpp" impact on 2 files Included by: 1 : "../lib/a/char_a_factory.cpp" line 1 2 : "../main.cpp" line 1 -6 : "../lib/b/char_b.hpp" impact on 2 file(s) +6 : "../lib/b/char_b.hpp" impact on 2 files Included by: 1 : "../lib/b/char_b.cpp" line 1 2 : "../lib/b/char_b_factory.cpp" line 3 -7 : "../lib/b/char_b_factory.hpp" impact on 2 file(s) +7 : "../lib/b/char_b_factory.hpp" impact on 2 files Included by: 1 : "../lib/b/char_b_factory.cpp" line 1 2 : "../main.cpp" line 2 diff --git a/docs/examples/simple_example_with_include_path_cmake/output_win.txt b/docs/examples/simple_example_with_include_path_cmake/output_win.txt index aa9a265..9f1c8e6 100644 --- a/docs/examples/simple_example_with_include_path_cmake/output_win.txt +++ b/docs/examples/simple_example_with_include_path_cmake/output_win.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "..\lib\char_kind.hpp" impact on 11 file(s) +1 : "..\lib\char_kind.hpp" impact on 11 files Included by: - 1 : "..\lib\base\base_char.hpp" line 3, impact on 10 file(s) -2 : "..\lib\base\base_char.hpp" impact on 10 file(s) + 1 : "..\lib\base\base_char.hpp" line 3, impact on 10 files +2 : "..\lib\base\base_char.hpp" impact on 10 files Included by: - 1 : "..\lib\base\base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "..\lib\a\char_a.hpp" line 3, impact on 2 file(s) - 3 : "..\lib\b\char_b.hpp" line 3, impact on 2 file(s) -3 : "..\lib\base\base_char_factory.hpp" impact on 5 file(s) + 1 : "..\lib\base\base_char_factory.hpp" line 3, impact on 5 files + 2 : "..\lib\a\char_a.hpp" line 3, impact on 2 files + 3 : "..\lib\b\char_b.hpp" line 3, impact on 2 files +3 : "..\lib\base\base_char_factory.hpp" impact on 5 files Included by: - 1 : "..\lib\a\char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "..\lib\b\char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "..\lib\a\char_a.hpp" impact on 2 file(s) + 1 : "..\lib\a\char_a_factory.hpp" line 3, impact on 2 files + 2 : "..\lib\b\char_b_factory.hpp" line 3, impact on 2 files +4 : "..\lib\a\char_a.hpp" impact on 2 files Included by: 1 : "..\lib\a\char_a.cpp" line 1 2 : "..\lib\a\char_a_factory.cpp" line 3 -5 : "..\lib\a\char_a_factory.hpp" impact on 2 file(s) +5 : "..\lib\a\char_a_factory.hpp" impact on 2 files Included by: 1 : "..\lib\a\char_a_factory.cpp" line 1 2 : "..\main.cpp" line 1 -6 : "..\lib\b\char_b.hpp" impact on 2 file(s) +6 : "..\lib\b\char_b.hpp" impact on 2 files Included by: 1 : "..\lib\b\char_b.cpp" line 1 2 : "..\lib\b\char_b_factory.cpp" line 3 -7 : "..\lib\b\char_b_factory.hpp" impact on 2 file(s) +7 : "..\lib\b\char_b_factory.hpp" impact on 2 files Included by: 1 : "..\lib\b\char_b_factory.cpp" line 1 2 : "..\main.cpp" line 2 diff --git a/docs/examples/simple_example_with_unincluded_headers/output_unix.txt b/docs/examples/simple_example_with_unincluded_headers/output_unix.txt index 9ab3f31..06edd24 100644 --- a/docs/examples/simple_example_with_unincluded_headers/output_unix.txt +++ b/docs/examples/simple_example_with_unincluded_headers/output_unix.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "char_a.hpp" impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 2 : "main.cpp" line 2 diff --git a/docs/examples/simple_example_with_unincluded_headers/output_win.txt b/docs/examples/simple_example_with_unincluded_headers/output_win.txt index 0a9025c..6d4d269 100644 --- a/docs/examples/simple_example_with_unincluded_headers/output_win.txt +++ b/docs/examples/simple_example_with_unincluded_headers/output_win.txt @@ -2,31 +2,31 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "char_kind.hpp" impact on 11 file(s) +1 : "char_kind.hpp" impact on 11 files Included by: - 1 : "base_char.hpp" line 3, impact on 10 file(s) -2 : "base_char.hpp" impact on 10 file(s) + 1 : "base_char.hpp" line 3, impact on 10 files +2 : "base_char.hpp" impact on 10 files Included by: - 1 : "base_char_factory.hpp" line 3, impact on 5 file(s) - 2 : "char_a.hpp" line 3, impact on 2 file(s) - 3 : "char_b.hpp" line 3, impact on 2 file(s) -3 : "base_char_factory.hpp" impact on 5 file(s) + 1 : "base_char_factory.hpp" line 3, impact on 5 files + 2 : "char_a.hpp" line 3, impact on 2 files + 3 : "char_b.hpp" line 3, impact on 2 files +3 : "base_char_factory.hpp" impact on 5 files Included by: - 1 : "char_a_factory.hpp" line 3, impact on 2 file(s) - 2 : "char_b_factory.hpp" line 3, impact on 2 file(s) -4 : "char_a.hpp" impact on 2 file(s) + 1 : "char_a_factory.hpp" line 3, impact on 2 files + 2 : "char_b_factory.hpp" line 3, impact on 2 files +4 : "char_a.hpp" impact on 2 files Included by: 1 : "char_a.cpp" line 1 2 : "char_a_factory.cpp" line 3 -5 : "char_a_factory.hpp" impact on 2 file(s) +5 : "char_a_factory.hpp" impact on 2 files Included by: 1 : "char_a_factory.cpp" line 1 2 : "main.cpp" line 1 -6 : "char_b.hpp" impact on 2 file(s) +6 : "char_b.hpp" impact on 2 files Included by: 1 : "char_b.cpp" line 1 2 : "char_b_factory.cpp" line 3 -7 : "char_b_factory.hpp" impact on 2 file(s) +7 : "char_b_factory.hpp" impact on 2 files Included by: 1 : "char_b_factory.cpp" line 1 2 : "main.cpp" line 2 diff --git a/docs/examples/vlc/output_unix.txt b/docs/examples/vlc/output_unix.txt index 811cecb..1fa89cc 100644 --- a/docs/examples/vlc/output_unix.txt +++ b/docs/examples/vlc/output_unix.txt @@ -2,87 +2,87 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "include/vlc_arrays.h" impact on 1581 file(s) +1 : "include/vlc_arrays.h" impact on 1 581 files Included by: - 1 : "include/vlc_common.h" line 779, impact on 1569 file(s) - 2 : "include/vlc_events.h" line 28, impact on 424 file(s) - 3 : "include/vlc_extensions.h" line 28, impact on 15 file(s) - 4 : "include/vlc_http.h" line 37, impact on 12 file(s) - 5 : "modules/text_renderer/freetype/freetype.h" line 43, impact on 10 file(s) - 6 : "include/vlc_addons.h" line 24, impact on 9 file(s) - 7 : "include/vlc_fingerprinter.h" line 27, impact on 6 file(s) - 8 : "modules/lua/extension.h" line 28, impact on 3 file(s) - 9 : "src/input/mrl_helpers.h" line 29, impact on 3 file(s) + 1 : "include/vlc_common.h" line 779, impact on 1 569 files + 2 : "include/vlc_events.h" line 28, impact on 424 files + 3 : "include/vlc_extensions.h" line 28, impact on 15 files + 4 : "include/vlc_http.h" line 37, impact on 12 files + 5 : "modules/text_renderer/freetype/freetype.h" line 43, impact on 10 files + 6 : "include/vlc_addons.h" line 24, impact on 9 files + 7 : "include/vlc_fingerprinter.h" line 27, impact on 6 files + 8 : "modules/lua/extension.h" line 28, impact on 3 files + 9 : "src/input/mrl_helpers.h" line 29, impact on 3 files 10 : "modules/demux/adaptive/playlist/BaseAdaptationSet.cpp" line 33 ... 10 of 29 details -2 : "include/vlc_threads.h" impact on 1573 file(s) +2 : "include/vlc_threads.h" impact on 1 573 files Included by: - 1 : "include/vlc_common.h" line 409, impact on 1569 file(s) - 2 : "modules/gui/qt/util/singleton.hpp" line 27, impact on 60 file(s) - 3 : "include/vlc_interrupt.h" line 28, impact on 57 file(s) - 4 : "modules/demux/hls/playlist/M3U8.hpp" line 25, impact on 6 file(s) - 5 : "modules/demux/mkv/Ebml_dispatcher.hpp" line 31, impact on 3 file(s) + 1 : "include/vlc_common.h" line 409, impact on 1 569 files + 2 : "modules/gui/qt/util/singleton.hpp" line 27, impact on 60 files + 3 : "include/vlc_interrupt.h" line 28, impact on 57 files + 4 : "modules/demux/hls/playlist/M3U8.hpp" line 25, impact on 6 files + 5 : "modules/demux/mkv/Ebml_dispatcher.hpp" line 31, impact on 3 files 6 : "modules/codec/omxil/mediacodec.c" line 40 7 : "modules/codec/x265.c" line 33 8 : "modules/demux/adaptive/PlaylistManager.cpp" line 42 9 : "modules/demux/adaptive/http/Downloader.cpp" line 26 10 : "modules/gui/skins2/src/skin_main.cpp" line 34 ... 10 of 18 details -3 : "include/vlc_configuration.h" impact on 1570 file(s) +3 : "include/vlc_configuration.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 1025, impact on 1569 file(s) - 2 : "modules/codec/avcodec/avcommon.h" line 32, impact on 17 file(s) + 1 : "include/vlc_common.h" line 1 025, impact on 1 569 files + 2 : "modules/codec/avcodec/avcommon.h" line 32, impact on 17 files 3 : "modules/access/vdr.c" line 64 4 : "modules/gui/qt/components/simple_preferences.cpp" line 34 5 : "modules/hw/d3d11/d3d11_filters.c" line 31 6 : "src/config/core.c" line 33 7 : "src/win32/dirs.c" line 44 8 : "test/src/config/chain.c" line 30 -4 : "include/vlc_main.h" impact on 1570 file(s) +4 : "include/vlc_main.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 1024, impact on 1569 file(s) -5 : "include/vlc_messages.h" impact on 1570 file(s) + 1 : "include/vlc_common.h" line 1 024, impact on 1 569 files +5 : "include/vlc_messages.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 1021, impact on 1569 file(s) + 1 : "include/vlc_common.h" line 1 021, impact on 1 569 files 2 : "modules/access/rtsp/real.c" line 33 3 : "modules/access/rtsp/real_rmff.c" line 29 4 : "modules/access/rtsp/rtsp.c" line 33 5 : "src/misc/httpcookies.c" line 34 -6 : "include/vlc_mtime.h" impact on 1570 file(s) +6 : "include/vlc_mtime.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 408, impact on 1569 file(s) + 1 : "include/vlc_common.h" line 408, impact on 1 569 files 2 : "modules/control/dbus/dbus.c" line 63 3 : "modules/video_filter/oldmovie.c" line 39 4 : "modules/video_filter/vhs.c" line 37 5 : "test/libvlc/media_list_player.c" line 28 -7 : "include/vlc_objects.h" impact on 1570 file(s) +7 : "include/vlc_objects.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 1022, impact on 1569 file(s) -8 : "include/vlc_variables.h" impact on 1570 file(s) + 1 : "include/vlc_common.h" line 1 022, impact on 1 569 files +8 : "include/vlc_variables.h" impact on 1 570 files Included by: - 1 : "include/vlc_common.h" line 1023, impact on 1569 file(s) - 2 : "modules/codec/avcodec/avcommon.h" line 33, impact on 17 file(s) + 1 : "include/vlc_common.h" line 1 023, impact on 1 569 files + 2 : "modules/codec/avcodec/avcommon.h" line 33, impact on 17 files 3 : "modules/access/dsm/access.c" line 35 -9 : "include/vlc_common.h" impact on 1569 file(s) +9 : "include/vlc_common.h" impact on 1 569 files Included by: - 1 : "include/vlc_viewpoint.h" line 24, impact on 974 file(s) - 2 : "include/vlc_es.h" line 27, impact on 971 file(s) - 3 : "modules/gui/skins2/src/skin_common.hpp" line 32, impact on 230 file(s) - 4 : "modules/gui/qt/qt.hpp" line 32, impact on 134 file(s) - 5 : "include/vlc_vout_window.h" line 29, impact on 91 file(s) - 6 : "modules/demux/adaptive/http/ConnectionParams.hpp" line 23, impact on 78 file(s) - 7 : "modules/demux/adaptive/http/BytesRange.hpp" line 23, impact on 77 file(s) - 8 : "modules/demux/adaptive/playlist/Url.hpp" line 25, impact on 73 file(s) - 9 : "modules/demux/adaptive/Time.hpp" line 23, impact on 67 file(s) - 10 : "include/vlc_bits.h" line 28, impact on 45 file(s) + 1 : "include/vlc_viewpoint.h" line 24, impact on 974 files + 2 : "include/vlc_es.h" line 27, impact on 971 files + 3 : "modules/gui/skins2/src/skin_common.hpp" line 32, impact on 230 files + 4 : "modules/gui/qt/qt.hpp" line 32, impact on 134 files + 5 : "include/vlc_vout_window.h" line 29, impact on 91 files + 6 : "modules/demux/adaptive/http/ConnectionParams.hpp" line 23, impact on 78 files + 7 : "modules/demux/adaptive/http/BytesRange.hpp" line 23, impact on 77 files + 8 : "modules/demux/adaptive/playlist/Url.hpp" line 25, impact on 73 files + 9 : "modules/demux/adaptive/Time.hpp" line 23, impact on 67 files + 10 : "include/vlc_bits.h" line 28, impact on 45 files ... 10 of 982 details -10 : "include/vlc_text_style.h" impact on 977 file(s) +10 : "include/vlc_text_style.h" impact on 977 files Included by: - 1 : "include/vlc_es.h" line 29, impact on 971 file(s) - 2 : "include/vlc_subpicture.h" line 33, impact on 482 file(s) - 3 : "modules/codec/substext.h" line 25, impact on 10 file(s) - 4 : "modules/text_renderer/freetype/freetype.h" line 42, impact on 10 file(s) - 5 : "modules/spu/dynamicoverlay/dynamicoverlay.h" line 29, impact on 5 file(s) + 1 : "include/vlc_es.h" line 29, impact on 971 files + 2 : "include/vlc_subpicture.h" line 33, impact on 482 files + 3 : "modules/codec/substext.h" line 25, impact on 10 files + 4 : "modules/text_renderer/freetype/freetype.h" line 42, impact on 10 files + 5 : "modules/spu/dynamicoverlay/dynamicoverlay.h" line 29, impact on 5 files 6 : "modules/codec/ttml/substtml.c" line 31 7 : "modules/codec/webvtt/css_style.c" line 25 8 : "modules/text_renderer/freetype/freetype.c" line 43 @@ -90,5 +90,5 @@ Included by: 10 : "modules/text_renderer/freetype/text_layout.c" line 44 ... 10 of 11 details ... 10 of 725 files -Unincluded headers: +Unincluded header: 1 : "modules/audio_output/coreaudio_common.h" diff --git a/docs/examples/vlc/output_win.txt b/docs/examples/vlc/output_win.txt index a37f59a..acfe4c4 100644 --- a/docs/examples/vlc/output_win.txt +++ b/docs/examples/vlc/output_win.txt @@ -2,87 +2,87 @@ Start initialization project ... Start analyze sources ... Start report results ... Most impact files: -1 : "include\vlc_arrays.h" impact on 1581 file(s) +1 : "include\vlc_arrays.h" impact on 1 581 files Included by: - 1 : "include\vlc_common.h" line 779, impact on 1569 file(s) - 2 : "include\vlc_events.h" line 28, impact on 424 file(s) - 3 : "include\vlc_extensions.h" line 28, impact on 15 file(s) - 4 : "include\vlc_http.h" line 37, impact on 12 file(s) - 5 : "modules\text_renderer\freetype\freetype.h" line 43, impact on 10 file(s) - 6 : "include\vlc_addons.h" line 24, impact on 9 file(s) - 7 : "include\vlc_fingerprinter.h" line 27, impact on 6 file(s) - 8 : "modules\lua\extension.h" line 28, impact on 3 file(s) - 9 : "src\input\mrl_helpers.h" line 29, impact on 3 file(s) + 1 : "include\vlc_common.h" line 779, impact on 1 569 files + 2 : "include\vlc_events.h" line 28, impact on 424 files + 3 : "include\vlc_extensions.h" line 28, impact on 15 files + 4 : "include\vlc_http.h" line 37, impact on 12 files + 5 : "modules\text_renderer\freetype\freetype.h" line 43, impact on 10 files + 6 : "include\vlc_addons.h" line 24, impact on 9 files + 7 : "include\vlc_fingerprinter.h" line 27, impact on 6 files + 8 : "modules\lua\extension.h" line 28, impact on 3 files + 9 : "src\input\mrl_helpers.h" line 29, impact on 3 files 10 : "modules\demux\adaptive\playlist\BaseAdaptationSet.cpp" line 33 ... 10 of 29 details -2 : "include\vlc_threads.h" impact on 1573 file(s) +2 : "include\vlc_threads.h" impact on 1 573 files Included by: - 1 : "include\vlc_common.h" line 409, impact on 1569 file(s) - 2 : "modules\gui\qt\util\singleton.hpp" line 27, impact on 60 file(s) - 3 : "include\vlc_interrupt.h" line 28, impact on 57 file(s) - 4 : "modules\demux\hls\playlist\M3U8.hpp" line 25, impact on 6 file(s) - 5 : "modules\demux\mkv\Ebml_dispatcher.hpp" line 31, impact on 3 file(s) + 1 : "include\vlc_common.h" line 409, impact on 1 569 files + 2 : "modules\gui\qt\util\singleton.hpp" line 27, impact on 60 files + 3 : "include\vlc_interrupt.h" line 28, impact on 57 files + 4 : "modules\demux\hls\playlist\M3U8.hpp" line 25, impact on 6 files + 5 : "modules\demux\mkv\Ebml_dispatcher.hpp" line 31, impact on 3 files 6 : "modules\codec\omxil\mediacodec.c" line 40 7 : "modules\codec\x265.c" line 33 8 : "modules\demux\adaptive\PlaylistManager.cpp" line 42 9 : "modules\demux\adaptive\http\Downloader.cpp" line 26 10 : "modules\gui\skins2\src\skin_main.cpp" line 34 ... 10 of 18 details -3 : "include\vlc_configuration.h" impact on 1570 file(s) +3 : "include\vlc_configuration.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 1025, impact on 1569 file(s) - 2 : "modules\codec\avcodec\avcommon.h" line 32, impact on 17 file(s) + 1 : "include\vlc_common.h" line 1 025, impact on 1 569 files + 2 : "modules\codec\avcodec\avcommon.h" line 32, impact on 17 files 3 : "modules\access\vdr.c" line 64 4 : "modules\gui\qt\components\simple_preferences.cpp" line 34 5 : "modules\hw\d3d11\d3d11_filters.c" line 31 6 : "src\config\core.c" line 33 7 : "src\win32\dirs.c" line 44 8 : "test\src\config\chain.c" line 30 -4 : "include\vlc_main.h" impact on 1570 file(s) +4 : "include\vlc_main.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 1024, impact on 1569 file(s) -5 : "include\vlc_messages.h" impact on 1570 file(s) + 1 : "include\vlc_common.h" line 1 024, impact on 1 569 files +5 : "include\vlc_messages.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 1021, impact on 1569 file(s) + 1 : "include\vlc_common.h" line 1 021, impact on 1 569 files 2 : "modules\access\rtsp\real.c" line 33 3 : "modules\access\rtsp\real_rmff.c" line 29 4 : "modules\access\rtsp\rtsp.c" line 33 5 : "src\misc\httpcookies.c" line 34 -6 : "include\vlc_mtime.h" impact on 1570 file(s) +6 : "include\vlc_mtime.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 408, impact on 1569 file(s) + 1 : "include\vlc_common.h" line 408, impact on 1 569 files 2 : "modules\control\dbus\dbus.c" line 63 3 : "modules\video_filter\oldmovie.c" line 39 4 : "modules\video_filter\vhs.c" line 37 5 : "test\libvlc\media_list_player.c" line 28 -7 : "include\vlc_objects.h" impact on 1570 file(s) +7 : "include\vlc_objects.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 1022, impact on 1569 file(s) -8 : "include\vlc_variables.h" impact on 1570 file(s) + 1 : "include\vlc_common.h" line 1 022, impact on 1 569 files +8 : "include\vlc_variables.h" impact on 1 570 files Included by: - 1 : "include\vlc_common.h" line 1023, impact on 1569 file(s) - 2 : "modules\codec\avcodec\avcommon.h" line 33, impact on 17 file(s) + 1 : "include\vlc_common.h" line 1 023, impact on 1 569 files + 2 : "modules\codec\avcodec\avcommon.h" line 33, impact on 17 files 3 : "modules\access\dsm\access.c" line 35 -9 : "include\vlc_common.h" impact on 1569 file(s) +9 : "include\vlc_common.h" impact on 1 569 files Included by: - 1 : "include\vlc_viewpoint.h" line 24, impact on 974 file(s) - 2 : "include\vlc_es.h" line 27, impact on 971 file(s) - 3 : "modules\gui\skins2\src\skin_common.hpp" line 32, impact on 230 file(s) - 4 : "modules\gui\qt\qt.hpp" line 32, impact on 134 file(s) - 5 : "include\vlc_vout_window.h" line 29, impact on 91 file(s) - 6 : "modules\demux\adaptive\http\ConnectionParams.hpp" line 23, impact on 78 file(s) - 7 : "modules\demux\adaptive\http\BytesRange.hpp" line 23, impact on 77 file(s) - 8 : "modules\demux\adaptive\playlist\Url.hpp" line 25, impact on 73 file(s) - 9 : "modules\demux\adaptive\Time.hpp" line 23, impact on 67 file(s) - 10 : "include\vlc_bits.h" line 28, impact on 45 file(s) + 1 : "include\vlc_viewpoint.h" line 24, impact on 974 files + 2 : "include\vlc_es.h" line 27, impact on 971 files + 3 : "modules\gui\skins2\src\skin_common.hpp" line 32, impact on 230 files + 4 : "modules\gui\qt\qt.hpp" line 32, impact on 134 files + 5 : "include\vlc_vout_window.h" line 29, impact on 91 files + 6 : "modules\demux\adaptive\http\ConnectionParams.hpp" line 23, impact on 78 files + 7 : "modules\demux\adaptive\http\BytesRange.hpp" line 23, impact on 77 files + 8 : "modules\demux\adaptive\playlist\Url.hpp" line 25, impact on 73 files + 9 : "modules\demux\adaptive\Time.hpp" line 23, impact on 67 files + 10 : "include\vlc_bits.h" line 28, impact on 45 files ... 10 of 982 details -10 : "include\vlc_text_style.h" impact on 977 file(s) +10 : "include\vlc_text_style.h" impact on 977 files Included by: - 1 : "include\vlc_es.h" line 29, impact on 971 file(s) - 2 : "include\vlc_subpicture.h" line 33, impact on 482 file(s) - 3 : "modules\codec\substext.h" line 25, impact on 10 file(s) - 4 : "modules\text_renderer\freetype\freetype.h" line 42, impact on 10 file(s) - 5 : "modules\spu\dynamicoverlay\dynamicoverlay.h" line 29, impact on 5 file(s) + 1 : "include\vlc_es.h" line 29, impact on 971 files + 2 : "include\vlc_subpicture.h" line 33, impact on 482 files + 3 : "modules\codec\substext.h" line 25, impact on 10 files + 4 : "modules\text_renderer\freetype\freetype.h" line 42, impact on 10 files + 5 : "modules\spu\dynamicoverlay\dynamicoverlay.h" line 29, impact on 5 files 6 : "modules\codec\ttml\substtml.c" line 31 7 : "modules\codec\webvtt\css_style.c" line 25 8 : "modules\text_renderer\freetype\freetype.c" line 43 @@ -90,5 +90,5 @@ Included by: 10 : "modules\text_renderer\freetype\text_layout.c" line 44 ... 10 of 11 details ... 10 of 725 files -Unincluded headers: +Unincluded header: 1 : "modules\audio_output\coreaudio_common.h" diff --git a/docs/versions/VERSION_0.5.0.md b/docs/versions/VERSION_0.5.0.md new file mode 100644 index 0000000..186edf4 --- /dev/null +++ b/docs/versions/VERSION_0.5.0.md @@ -0,0 +1,101 @@ +# VERSION 0.5.0 + +## Added + +### New argument show_details + +Show or hide details of reports. Example [lua](docs/examples/lua) : + +**Before:** + +``` +cppinclude --report_details_limit=3 +... +Most impact files: +1 : "luaconf.h" impact on 62 files +Included by: + 1 : "lua.h" line 16, impact on 61 files + 2 : "onelua.c" line 49 +2 : "lua.h" impact on 61 files +Included by: + 1 : "llimits.h" line 15, impact on 40 files + 2 : "lobject.h" line 16, impact on 34 files + 3 : "lstate.h" line 10, impact on 26 files + ... 3 of 44 details +3 : "llimits.h" impact on 40 files +Included by: + 1 : "lobject.h" line 15, impact on 34 files + 2 : "lmem.h" line 13, impact on 15 files + 3 : "lopcodes.h" line 10, impact on 9 files + ... 3 of 8 details +4 : "lprefix.h" impact on 35 files +Included by: + 1 : "lapi.c" line 10, impact on 1 file + 2 : "lauxlib.c" line 10, impact on 1 file + 3 : "lbaselib.c" line 10, impact on 1 file + ... 3 of 35 details +5 : "lobject.h" impact on 34 files +... + +``` + +**After:** + +``` +cppinclude --show_details=false --report_details_limit=3 +... +Most impact files: +1 : "luaconf.h" impact on 62 files +2 : "lua.h" impact on 61 files +3 : "llimits.h" impact on 40 files +4 : "lprefix.h" impact on 35 files +5 : "lobject.h" impact on 34 files +... + +``` + +### New argument thousands_separator + +Set thousands separator. Example : + +**Before:** + +``` +cppinclude +... +Most impact files: +1 : "supper_header.h" impact on 123456 files +2 : "config.h" impact on 12345 files +3 : "limits.h" impact on 1234 files +... + +``` + +**After:** + +``` +cppinclude --thousands_separator=, +... +Most impact files: +1 : "supper_header.h" impact on 123,456 files +2 : "config.h" impact on 12,345 files +3 : "limits.h" impact on 1,234 files +... + +``` + +### New argument verbose_ignore + +Show ignored files and foldes + +``` +cppinclude --verbose_ignore + +Path "sys/types.h" was ignored by "sys/.*.h" +Path "mach/mach_init.h" was ignored by "mach/.*.h" +Folder ".../3rdparty" was ignored +... + +``` + + diff --git a/src/3rd-part/.clang-format b/src/3rd-part/.clang-format new file mode 100644 index 0000000..c9f63d1 --- /dev/null +++ b/src/3rd-part/.clang-format @@ -0,0 +1,5 @@ +--- +DisableFormat: true +SortIncludes: false + +... diff --git a/src/3rd-part/cxxopts/include/cxxopts.hpp b/src/3rd-part/cxxopts/include/cxxopts.hpp index d81d6e5..e7ea1b8 100644 --- a/src/3rd-part/cxxopts/include/cxxopts.hpp +++ b/src/3rd-part/cxxopts/include/cxxopts.hpp @@ -1442,7 +1442,11 @@ namespace cxxopts !o.default_value.empty() ) { - desc += toLocalString(" (default: " + o.default_value + ")"); + desc += toLocalString( + " (default: " + + ( o.default_value != " " ? o.default_value : "' '") + + ")" + ); } String result; diff --git a/src/3rd-part/fmt/CMakeLists.txt b/src/3rd-part/fmt/CMakeLists.txt index d181726..867c00c 100644 --- a/src/3rd-part/fmt/CMakeLists.txt +++ b/src/3rd-part/fmt/CMakeLists.txt @@ -1,10 +1,8 @@ -cmake_minimum_required(VERSION 3.1.0) +cmake_minimum_required(VERSION 3.1...3.18) -# Use newer policies if available, up to most recent tested version of CMake. -if(${CMAKE_VERSION} VERSION_LESS 3.11) +# Fallback for using newer policies on CMake <3.12. +if(${CMAKE_VERSION} VERSION_LESS 3.12) cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}) -else() - cmake_policy(VERSION 3.11) endif() # Determine if fmt is built as a subproject (using add_subdirectory) @@ -24,15 +22,40 @@ function(join result_var) set(${result_var} "${result}" PARENT_SCOPE) endfunction() +include(CMakeParseArguments) + +# Sets a cache variable with a docstring joined from multiple arguments: +# set( ... CACHE ...) +# This allows splitting a long docstring for readability. +function(set_verbose) + # cmake_parse_arguments is broken in CMake 3.4 (cannot parse CACHE) so use + # list instead. + list(GET ARGN 0 var) + list(REMOVE_AT ARGN 0) + list(GET ARGN 0 val) + list(REMOVE_AT ARGN 0) + list(REMOVE_AT ARGN 0) + list(GET ARGN 0 type) + list(REMOVE_AT ARGN 0) + join(doc ${ARGN}) + set(${var} ${val} CACHE ${type} ${doc}) +endfunction() + # Set the default CMAKE_BUILD_TYPE to Release. # This should be done before the project command since the latter can set # CMAKE_BUILD_TYPE itself (it does so for nmake). if (MASTER_PROJECT AND NOT CMAKE_BUILD_TYPE) - join(doc "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " - "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") - set(CMAKE_BUILD_TYPE Release CACHE STRING ${doc}) + set_verbose(CMAKE_BUILD_TYPE Release CACHE STRING + "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or " + "CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel.") endif () +project(FMT CXX) +include(GNUInstallDirs) +set_verbose(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE STRING + "Installation directory for include files, a relative path that " + "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute path.") + option(FMT_PEDANTIC "Enable extra warnings and expensive tests." OFF) option(FMT_WERROR "Halt the compilation with an error on compiler warnings." OFF) @@ -43,8 +66,7 @@ option(FMT_INSTALL "Generate the install target." ${MASTER_PROJECT}) option(FMT_TEST "Generate the test target." ${MASTER_PROJECT}) option(FMT_FUZZ "Generate the fuzz target." OFF) option(FMT_CUDA_TEST "Generate the cuda-test target." OFF) - -project(FMT CXX) +option(FMT_OS "Include core requiring OS (Windows/Posix) " ON) # Get version from core.h file(READ include/fmt/core.h core_h) @@ -61,26 +83,35 @@ message(STATUS "Version: ${FMT_VERSION}") message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +if (NOT CMAKE_RUNTIME_OUTPUT_DIRECTORY) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +endif () set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/support/cmake") include(cxx14) include(CheckCXXCompilerFlag) +include(JoinPaths) -set(FMT_REQUIRED_FEATURES cxx_auto_type cxx_variadic_templates) +list(FIND CMAKE_CXX_COMPILE_FEATURES "cxx_variadic_templates" index) +if (${index} GREATER -1) + # Use cxx_variadic_templates instead of more appropriate cxx_std_11 for + # compatibility with older CMake versions. + set(FMT_REQUIRED_FEATURES cxx_variadic_templates) +endif () +message(STATUS "Required features: ${FMT_REQUIRED_FEATURES}") if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") set(PEDANTIC_COMPILE_FLAGS -pedantic-errors -Wall -Wextra -pedantic -Wold-style-cast -Wundef -Wredundant-decls -Wwrite-strings -Wpointer-arith -Wcast-qual -Wformat=2 -Wmissing-include-dirs - -Wcast-align -Wnon-virtual-dtor + -Wcast-align -Wctor-dtor-privacy -Wdisabled-optimization -Winvalid-pch -Woverloaded-virtual - -Wconversion -Wswitch-enum - -Wno-ctor-dtor-privacy -Wno-format-nonliteral -Wno-shadow) + -Wconversion -Wswitch-enum -Wundef + -Wno-ctor-dtor-privacy -Wno-format-nonliteral) if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.6) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} -Wnoexcept -Wno-dangling-else -Wno-unused-local-typedefs) @@ -98,8 +129,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") endif () if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion - -Wno-sign-conversion -Wdeprecated -Wweak-vtables) + set(PEDANTIC_COMPILE_FLAGS -Wall -Wextra -pedantic -Wconversion -Wundef + -Wdeprecated -Wweak-vtables) check_cxx_compiler_flag(-Wzero-as-null-pointer-constant HAS_NULLPTR_WARNING) if (HAS_NULLPTR_WARNING) set(PEDANTIC_COMPILE_FLAGS ${PEDANTIC_COMPILE_FLAGS} @@ -123,7 +154,9 @@ if (MASTER_PROJECT AND CMAKE_GENERATOR MATCHES "Visual Studio") set(MSBUILD_SETUP "call \"${WINSDK_SETENV}\"") endif () # Set FrameworkPathOverride to get rid of MSB3644 warnings. - set(netfxpath "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.0") + join(netfxpath + "C:\\Program Files\\Reference Assemblies\\Microsoft\\Framework\\" + ".NETFramework\\v4.0") file(WRITE run-msbuild.bat " ${MSBUILD_SETUP} ${CMAKE_MAKE_PROGRAM} -p:FrameworkPathOverride=\"${netfxpath}\" %*") @@ -151,8 +184,12 @@ endfunction() # Define the fmt library, its includes and the needed defines. add_headers(FMT_HEADERS chrono.h color.h compile.h core.h format.h format-inl.h - locale.h ostream.h posix.h printf.h ranges.h) -set(FMT_SOURCES src/format.cc src/posix.cc) + locale.h os.h ostream.h posix.h printf.h ranges.h) +if (FMT_OS) + set(FMT_SOURCES src/format.cc src/os.cc) +else() + set(FMT_SOURCES src/format.cc) +endif () add_library(fmt ${FMT_SOURCES} ${FMT_HEADERS}) add_library(fmt::fmt ALIAS fmt) @@ -161,6 +198,13 @@ if (HAVE_STRTOD_L) target_compile_definitions(fmt PUBLIC FMT_LOCALE) endif () +if (MINGW) + check_cxx_compiler_flag("Wa,-mbig-obj" FMT_HAS_MBIG_OBJ) + if (${FMT_HAS_MBIG_OBJ}) + target_compile_options(fmt PUBLIC "-Wa,-mbig-obj") + endif() +endif () + if (FMT_WERROR) target_compile_options(fmt PRIVATE ${WERROR_FLAG}) endif () @@ -172,14 +216,24 @@ target_compile_features(fmt INTERFACE ${FMT_REQUIRED_FEATURES}) target_include_directories(fmt PUBLIC $ - $) + $) + +set(FMT_DEBUG_POSTFIX d CACHE STRING "Debug library postfix.") set_target_properties(fmt PROPERTIES VERSION ${FMT_VERSION} SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR} - DEBUG_POSTFIX d) + DEBUG_POSTFIX "${FMT_DEBUG_POSTFIX}") + +# Set FMT_LIB_NAME for pkg-config fmt.pc. We cannot use the OUTPUT_NAME target +# property because it's not set by default. +set(FMT_LIB_NAME fmt) +if (CMAKE_BUILD_TYPE STREQUAL "Debug") + set(FMT_LIB_NAME ${FMT_LIB_NAME}${FMT_DEBUG_POSTFIX}) +endif () if (BUILD_SHARED_LIBS) - if (UNIX AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS") + if (UNIX AND NOT APPLE AND NOT ${CMAKE_SYSTEM_NAME} MATCHES "SunOS" AND + NOT EMSCRIPTEN) # Fix rpmlint warning: # unused-direct-shlib-dependency /usr/lib/libformat.so.1.1.0 /lib/libm.so.6. target_link_libraries(fmt -Wl,--as-needed) @@ -194,43 +248,42 @@ add_library(fmt-header-only INTERFACE) add_library(fmt::fmt-header-only ALIAS fmt-header-only) target_compile_definitions(fmt-header-only INTERFACE FMT_HEADER_ONLY=1) - target_compile_features(fmt-header-only INTERFACE ${FMT_REQUIRED_FEATURES}) target_include_directories(fmt-header-only INTERFACE $ - $) + $) # Install targets. if (FMT_INSTALL) - include(GNUInstallDirs) include(CMakePackageConfigHelpers) - set(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING - "Installation directory for cmake files, relative to ${CMAKE_INSTALL_PREFIX}.") + set_verbose(FMT_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/fmt CACHE STRING + "Installation directory for cmake files, a relative path that " + "will be joined with ${CMAKE_INSTALL_PREFIX} or an absolute " + "path.") set(version_config ${PROJECT_BINARY_DIR}/fmt-config-version.cmake) set(project_config ${PROJECT_BINARY_DIR}/fmt-config.cmake) set(pkgconfig ${PROJECT_BINARY_DIR}/fmt.pc) set(targets_export_name fmt-targets) - set (INSTALL_TARGETS fmt) - if (TARGET fmt-header-only) - set(INSTALL_TARGETS ${INSTALL_TARGETS} fmt-header-only) - endif () - - set(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING - "Installation directory for libraries, relative to ${CMAKE_INSTALL_PREFIX}.") - - set(FMT_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR}/fmt CACHE STRING - "Installation directory for include files, relative to ${CMAKE_INSTALL_PREFIX}.") + set_verbose(FMT_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE STRING + "Installation directory for libraries, a relative path that " + "will be joined to ${CMAKE_INSTALL_PREFIX} or an absolute path.") - set(FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE PATH - "Installation directory for pkgconfig (.pc) files, relative to ${CMAKE_INSTALL_PREFIX}.") + set_verbose(FMT_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE PATH + "Installation directory for pkgconfig (.pc) files, a relative " + "path that will be joined with ${CMAKE_INSTALL_PREFIX} or an " + "absolute path.") # Generate the version, config and target files into the build directory. write_basic_package_version_file( ${version_config} VERSION ${FMT_VERSION} COMPATIBILITY AnyNewerVersion) + + join_paths(libdir_for_pc_file "\${exec_prefix}" "${FMT_LIB_DIR}") + join_paths(includedir_for_pc_file "\${prefix}" "${FMT_INC_DIR}") + configure_file( "${PROJECT_SOURCE_DIR}/support/cmake/fmt.pc.in" "${pkgconfig}" @@ -239,6 +292,8 @@ if (FMT_INSTALL) ${PROJECT_SOURCE_DIR}/support/cmake/fmt-config.cmake.in ${project_config} INSTALL_DESTINATION ${FMT_CMAKE_DIR}) + + set(INSTALL_TARGETS fmt fmt-header-only) # Use a namespace because CMake provides better diagnostics for namespaced # imported targets. export(TARGETS ${INSTALL_TARGETS} NAMESPACE fmt:: @@ -259,7 +314,7 @@ if (FMT_INSTALL) install(FILES $ DESTINATION ${FMT_LIB_DIR} OPTIONAL) - install(FILES ${FMT_HEADERS} DESTINATION ${FMT_INC_DIR}) + install(FILES ${FMT_HEADERS} DESTINATION "${FMT_INC_DIR}/fmt") install(FILES "${pkgconfig}" DESTINATION "${FMT_PKGCONFIG_DIR}") endif () @@ -275,13 +330,20 @@ endif () # Control fuzzing independent of the unit tests. if (FMT_FUZZ) add_subdirectory(test/fuzzing) + + # The FMT_FUZZ macro is used to prevent resource exhaustion in fuzzing + # mode and make fuzzing practically possible. It is similar to + # FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION but uses a different name to + # avoid interfering with fuzzing of projects that use {fmt}. + # See also https://llvm.org/docs/LibFuzzer.html#fuzzer-friendly-build-mode. + target_compile_definitions(fmt PUBLIC FMT_FUZZ) endif () set(gitignore ${PROJECT_SOURCE_DIR}/.gitignore) if (MASTER_PROJECT AND EXISTS ${gitignore}) # Get the list of ignored files from .gitignore. file (STRINGS ${gitignore} lines) - LIST(REMOVE_ITEM lines /doc/html) + list(REMOVE_ITEM lines /doc/html) foreach (line ${lines}) string(REPLACE "." "[.]" line "${line}") string(REPLACE "*" ".*" line "${line}") @@ -294,6 +356,6 @@ if (MASTER_PROJECT AND EXISTS ${gitignore}) set(CPACK_SOURCE_IGNORE_FILES ${ignored_files}) set(CPACK_SOURCE_PACKAGE_FILE_NAME fmt-${FMT_VERSION}) set(CPACK_PACKAGE_NAME fmt) - set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst) +# set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.rst) include(CPack) endif () diff --git a/src/3rd-part/fmt/include/fmt/chrono.h b/src/3rd-part/fmt/include/fmt/chrono.h index ca4ed30..1a3b8d5 100644 --- a/src/3rd-part/fmt/include/fmt/chrono.h +++ b/src/3rd-part/fmt/include/fmt/chrono.h @@ -8,14 +8,14 @@ #ifndef FMT_CHRONO_H_ #define FMT_CHRONO_H_ -#include "format.h" -#include "locale.h" - #include #include #include #include +#include "format.h" +#include "locale.h" + FMT_BEGIN_NAMESPACE // Enable safe chrono durations, unless explicitly disabled. @@ -48,7 +48,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { // From fits in To without any problem. } else { // From does not always fit in To, resort to a dynamic check. - if (from < T::min() || from > T::max()) { + if (from < (T::min)() || from > (T::max)()) { // outside range. ec = 1; return {}; @@ -72,43 +72,27 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { static_assert(F::is_integer, "From must be integral"); static_assert(T::is_integer, "To must be integral"); - if (F::is_signed && !T::is_signed) { + if (detail::const_check(F::is_signed && !T::is_signed)) { // From may be negative, not allowed! - if (fmt::internal::is_negative(from)) { + if (fmt::detail::is_negative(from)) { ec = 1; return {}; } - // From is positive. Can it always fit in To? - if (F::digits <= T::digits) { - // yes, From always fits in To. - } else { - // from may not fit in To, we have to do a dynamic check - if (from > static_cast(T::max())) { - ec = 1; - return {}; - } + if (F::digits > T::digits && + from > static_cast(detail::max_value())) { + ec = 1; + return {}; } } - if (!F::is_signed && T::is_signed) { - // can from be held in To? - if (F::digits < T::digits) { - // yes, From always fits in To. - } else { - // from may not fit in To, we have to do a dynamic check - if (from > static_cast(T::max())) { - // outside range. - ec = 1; - return {}; - } - } + if (!F::is_signed && T::is_signed && F::digits >= T::digits && + from > static_cast(detail::max_value())) { + ec = 1; + return {}; } - - // reaching here means all is ok for lossless conversion. - return static_cast(from); - -} // function + return static_cast(from); // Lossless conversion. +} template ::value)> @@ -141,7 +125,7 @@ FMT_CONSTEXPR To safe_float_conversion(const From from, int& ec) { // catch the only happy case if (std::isfinite(from)) { - if (from >= T::lowest() && from <= T::max()) { + if (from >= T::lowest() && from <= (T::max)()) { return static_cast(from); } // not within range. @@ -190,17 +174,16 @@ To safe_duration_cast(std::chrono::duration from, // safe conversion to IntermediateRep IntermediateRep count = lossless_integral_conversion(from.count(), ec); - if (ec) { - return {}; - } + if (ec) return {}; // multiply with Factor::num without overflow or underflow - if (Factor::num != 1) { - const auto max1 = internal::max_value() / Factor::num; + if (detail::const_check(Factor::num != 1)) { + const auto max1 = detail::max_value() / Factor::num; if (count > max1) { ec = 1; return {}; } - const auto min1 = std::numeric_limits::min() / Factor::num; + const auto min1 = + (std::numeric_limits::min)() / Factor::num; if (count < min1) { ec = 1; return {}; @@ -208,17 +191,9 @@ To safe_duration_cast(std::chrono::duration from, count *= Factor::num; } - // this can't go wrong, right? den>0 is checked earlier. - if (Factor::den != 1) { - count /= Factor::den; - } - // convert to the to type, safely - using ToRep = typename To::rep; - const ToRep tocount = lossless_integral_conversion(count, ec); - if (ec) { - return {}; - } - return To{tocount}; + if (detail::const_check(Factor::den != 1)) count /= Factor::den; + auto tocount = lossless_integral_conversion(count, ec); + return ec ? To() : To(tocount); } /** @@ -269,7 +244,7 @@ To safe_duration_cast(std::chrono::duration from, // multiply with Factor::num without overflow or underflow if (Factor::num != 1) { - constexpr auto max1 = internal::max_value() / + constexpr auto max1 = detail::max_value() / static_cast(Factor::num); if (count > max1) { ec = 1; @@ -306,12 +281,12 @@ To safe_duration_cast(std::chrono::duration from, // Usage: f FMT_NOMACRO() #define FMT_NOMACRO -namespace internal { +namespace detail { inline null<> localtime_r FMT_NOMACRO(...) { return null<>(); } inline null<> localtime_s(...) { return null<>(); } inline null<> gmtime_r(...) { return null<>(); } inline null<> gmtime_s(...) { return null<>(); } -} // namespace internal +} // namespace detail // Thread-safe replacement for std::localtime inline std::tm localtime(std::time_t time) { @@ -322,22 +297,22 @@ inline std::tm localtime(std::time_t time) { dispatcher(std::time_t t) : time_(t) {} bool run() { - using namespace fmt::internal; + using namespace fmt::detail; return handle(localtime_r(&time_, &tm_)); } bool handle(std::tm* tm) { return tm != nullptr; } - bool handle(internal::null<>) { - using namespace fmt::internal; + bool handle(detail::null<>) { + using namespace fmt::detail; return fallback(localtime_s(&tm_, &time_)); } bool fallback(int res) { return res == 0; } #if !FMT_MSC_VER - bool fallback(internal::null<>) { - using namespace fmt::internal; + bool fallback(detail::null<>) { + using namespace fmt::detail; std::tm* tm = std::localtime(&time_); if (tm) tm_ = *tm; return tm != nullptr; @@ -350,6 +325,11 @@ inline std::tm localtime(std::time_t time) { return lt.tm_; } +inline std::tm localtime( + std::chrono::time_point time_point) { + return localtime(std::chrono::system_clock::to_time_t(time_point)); +} + // Thread-safe replacement for std::gmtime inline std::tm gmtime(std::time_t time) { struct dispatcher { @@ -359,21 +339,21 @@ inline std::tm gmtime(std::time_t time) { dispatcher(std::time_t t) : time_(t) {} bool run() { - using namespace fmt::internal; + using namespace fmt::detail; return handle(gmtime_r(&time_, &tm_)); } bool handle(std::tm* tm) { return tm != nullptr; } - bool handle(internal::null<>) { - using namespace fmt::internal; + bool handle(detail::null<>) { + using namespace fmt::detail; return fallback(gmtime_s(&tm_, &time_)); } bool fallback(int res) { return res == 0; } #if !FMT_MSC_VER - bool fallback(internal::null<>) { + bool fallback(detail::null<>) { std::tm* tm = std::gmtime(&time_); if (tm) tm_ = *tm; return tm != nullptr; @@ -386,17 +366,33 @@ inline std::tm gmtime(std::time_t time) { return gt.tm_; } -namespace internal { -inline std::size_t strftime(char* str, std::size_t count, const char* format, - const std::tm* time) { +inline std::tm gmtime( + std::chrono::time_point time_point) { + return gmtime(std::chrono::system_clock::to_time_t(time_point)); +} + +namespace detail { +inline size_t strftime(char* str, size_t count, const char* format, + const std::tm* time) { return std::strftime(str, count, format, time); } -inline std::size_t strftime(wchar_t* str, std::size_t count, - const wchar_t* format, const std::tm* time) { +inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format, + const std::tm* time) { return std::wcsftime(str, count, format, time); } -} // namespace internal +} // namespace detail + +template +struct formatter, Char> + : formatter { + template + auto format(std::chrono::time_point val, + FormatContext& ctx) -> decltype(ctx.out()) { + std::tm time = localtime(val); + return formatter::format(time, ctx); + } +}; template struct formatter { template @@ -405,7 +401,7 @@ template struct formatter { if (it != ctx.end() && *it == ':') ++it; auto end = it; while (end != ctx.end() && *end != '}') ++end; - tm_format.reserve(internal::to_unsigned(end - it + 1)); + tm_format.reserve(detail::to_unsigned(end - it + 1)); tm_format.append(it, end); tm_format.push_back('\0'); return end; @@ -414,11 +410,10 @@ template struct formatter { template auto format(const std::tm& tm, FormatContext& ctx) -> decltype(ctx.out()) { basic_memory_buffer buf; - std::size_t start = buf.size(); + size_t start = buf.size(); for (;;) { - std::size_t size = buf.capacity() - start; - std::size_t count = - internal::strftime(&buf[start], size, &tm_format[0], &tm); + size_t size = buf.capacity() - start; + size_t count = detail::strftime(&buf[start], size, &tm_format[0], &tm); if (count != 0) { buf.resize(start + count); break; @@ -430,7 +425,7 @@ template struct formatter { // https://github.com/fmtlib/fmt/issues/367 break; } - const std::size_t MIN_GROWTH = 10; + const size_t MIN_GROWTH = 10; buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); } return std::copy(buf.begin(), buf.end(), ctx.out()); @@ -439,7 +434,7 @@ template struct formatter { basic_memory_buffer tm_format; }; -namespace internal { +namespace detail { template FMT_CONSTEXPR const char* get_units() { return nullptr; } @@ -495,12 +490,12 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, handler.on_text(ptr - 1, ptr); break; case 'n': { - const char newline[] = "\n"; + const Char newline[] = {'\n'}; handler.on_text(newline, newline + 1); break; } case 't': { - const char tab[] = "\t"; + const Char tab[] = {'\t'}; handler.on_text(tab, tab + 1); break; } @@ -759,18 +754,36 @@ inline std::chrono::duration get_milliseconds( return std::chrono::duration(static_cast(ms)); } -template -OutputIt format_chrono_duration_value(OutputIt out, Rep val, int precision) { - if (precision >= 0) return format_to(out, "{:.{}f}", val, precision); - return format_to(out, std::is_floating_point::value ? "{:g}" : "{}", +template +OutputIt format_duration_value(OutputIt out, Rep val, int precision) { + const Char pr_f[] = {'{', ':', '.', '{', '}', 'f', '}', 0}; + if (precision >= 0) return format_to(out, pr_f, val, precision); + const Char fp_f[] = {'{', ':', 'g', '}', 0}; + const Char format[] = {'{', '}', 0}; + return format_to(out, std::is_floating_point::value ? fp_f : format, val); } +template +OutputIt copy_unit(string_view unit, OutputIt out, Char) { + return std::copy(unit.begin(), unit.end(), out); +} + +template +OutputIt copy_unit(string_view unit, OutputIt out, wchar_t) { + // This works when wchar_t is UTF-32 because units only contain characters + // that have the same representation in UTF-16 and UTF-32. + utf8_to_utf16 u(unit); + return std::copy(u.c_str(), u.c_str() + u.size(), out); +} -template -static OutputIt format_chrono_duration_unit(OutputIt out) { - if (const char* unit = get_units()) return format_to(out, "{}", unit); - if (Period::den == 1) return format_to(out, "[{}]s", Period::num); - return format_to(out, "[{}/{}]s", Period::num, Period::den); +template +OutputIt format_duration_unit(OutputIt out) { + if (const char* unit = get_units()) + return copy_unit(string_view(unit), out, Char()); + const Char num_f[] = {'[', '{', '}', ']', 's', 0}; + if (const_check(Period::den == 1)) return format_to(out, num_f, Period::num); + const Char num_def_f[] = {'[', '{', '}', '/', '{', '}', ']', 's', 0}; + return format_to(out, num_def_f, Period::num, Period::den); } template n = to_unsigned(to_nonnegative_int(value, max_value())); - int num_digits = internal::count_digits(n); + int num_digits = detail::count_digits(n); if (width > num_digits) out = std::fill_n(out, width - num_digits, '0'); - out = format_decimal(out, n, num_digits); + out = format_decimal(out, n, num_digits).end; } void write_nan() { std::copy_n("nan", 3, out); } void write_pinf() { std::copy_n("inf", 3, out); } void write_ninf() { std::copy_n("-inf", 4, out); } - void format_localized(const tm& time, const char* format) { + void format_localized(const tm& time, char format, char modifier = 0) { if (isnan(val)) return write_nan(); auto locale = context.locale().template get(); auto& facet = std::use_facet>(locale); std::basic_ostringstream os; os.imbue(locale); - facet.put(os, os, ' ', &time, format, format + std::strlen(format)); + facet.put(os, os, ' ', &time, format, modifier); auto str = os.str(); std::copy(str.begin(), str.end(), out); } @@ -907,7 +920,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour(), 24); - format_localized(time, "%OH"); + format_localized(time, 'H', 'O'); } void on_12_hour(numeric_system ns) { @@ -916,7 +929,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour12(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour12(), 12); - format_localized(time, "%OI"); + format_localized(time, 'I', 'O'); } void on_minute(numeric_system ns) { @@ -925,7 +938,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(minute(), 2); auto time = tm(); time.tm_min = to_nonnegative_int(minute(), 60); - format_localized(time, "%OM"); + format_localized(time, 'M', 'O'); } void on_second(numeric_system ns) { @@ -950,13 +963,12 @@ struct chrono_formatter { } auto time = tm(); time.tm_sec = to_nonnegative_int(second(), 60); - format_localized(time, "%OS"); + format_localized(time, 'S', 'O'); } void on_12_hour_time() { if (handle_nan_inf()) return; - - format_localized(time(), "%r"); + format_localized(time(), 'r'); } void on_24_hour_time() { @@ -980,25 +992,27 @@ struct chrono_formatter { void on_am_pm() { if (handle_nan_inf()) return; - format_localized(time(), "%p"); + format_localized(time(), 'p'); } void on_duration_value() { if (handle_nan_inf()) return; write_sign(); - out = format_chrono_duration_value(out, val, precision); + out = format_duration_value(out, val, precision); } - void on_duration_unit() { out = format_chrono_duration_unit(out); } + void on_duration_unit() { + out = format_duration_unit(out); + } }; -} // namespace internal +} // namespace detail template struct formatter, Char> { private: basic_format_specs specs; int precision; - using arg_ref_type = internal::arg_ref; + using arg_ref_type = detail::arg_ref; arg_ref_type width_ref; arg_ref_type precision_ref; mutable basic_string_view format_str; @@ -1019,12 +1033,12 @@ struct formatter, Char> { return arg_ref_type(arg_id); } - FMT_CONSTEXPR arg_ref_type make_arg_ref(internal::auto_id) { + FMT_CONSTEXPR arg_ref_type make_arg_ref(detail::auto_id) { return arg_ref_type(context.next_arg_id()); } void on_error(const char* msg) { FMT_THROW(format_error(msg)); } - void on_fill(Char fill) { f.specs.fill[0] = fill; } + void on_fill(basic_string_view fill) { f.specs.fill = fill; } void on_align(align_t align) { f.specs.align = align; } void on_width(int width) { f.specs.width = width; } void on_precision(int _precision) { f.precision = _precision; } @@ -1049,17 +1063,17 @@ struct formatter, Char> { auto begin = ctx.begin(), end = ctx.end(); if (begin == end || *begin == '}') return {begin, begin}; spec_handler handler{*this, ctx, format_str}; - begin = internal::parse_align(begin, end, handler); + begin = detail::parse_align(begin, end, handler); if (begin == end) return {begin, begin}; - begin = internal::parse_width(begin, end, handler); + begin = detail::parse_width(begin, end, handler); if (begin == end) return {begin, begin}; if (*begin == '.') { if (std::is_floating_point::value) - begin = internal::parse_precision(begin, end, handler); + begin = detail::parse_precision(begin, end, handler); else handler.on_error("precision not allowed for this argument type"); } - end = parse_chrono_format(begin, end, internal::chrono_format_checker()); + end = parse_chrono_format(begin, end, detail::chrono_format_checker()); return {begin, end}; } @@ -1070,7 +1084,7 @@ struct formatter, Char> { -> decltype(ctx.begin()) { auto range = do_parse(ctx); format_str = basic_string_view( - &*range.begin, internal::to_unsigned(range.end - range.begin)); + &*range.begin, detail::to_unsigned(range.end - range.begin)); return range.end; } @@ -1081,23 +1095,21 @@ struct formatter, Char> { // is not specified. basic_memory_buffer buf; auto out = std::back_inserter(buf); - using range = internal::output_range; - internal::basic_writer w(range(ctx.out())); - internal::handle_dynamic_spec(specs.width, - width_ref, ctx); - internal::handle_dynamic_spec( - precision, precision_ref, ctx); + detail::handle_dynamic_spec(specs.width, width_ref, + ctx); + detail::handle_dynamic_spec(precision, + precision_ref, ctx); if (begin == end || *begin == '}') { - out = internal::format_chrono_duration_value(out, d.count(), precision); - internal::format_chrono_duration_unit(out); + out = detail::format_duration_value(out, d.count(), precision); + detail::format_duration_unit(out); } else { - internal::chrono_formatter f( + detail::chrono_formatter f( ctx, out, d); f.precision = precision; parse_chrono_format(begin, end, f); } - w.write(buf.data(), buf.size(), specs); - return w.out(); + return detail::write( + ctx.out(), basic_string_view(buf.data(), buf.size()), specs); } }; diff --git a/src/3rd-part/fmt/include/fmt/color.h b/src/3rd-part/fmt/include/fmt/color.h index 362a95e..94e3419 100644 --- a/src/3rd-part/fmt/include/fmt/color.h +++ b/src/3rd-part/fmt/include/fmt/color.h @@ -198,7 +198,7 @@ struct rgb { uint8_t b; }; -namespace internal { +namespace detail { // color is a struct of either a rgb color or a terminal color. struct color_type { @@ -221,7 +221,7 @@ struct color_type { uint32_t rgb_color; } value; }; -} // namespace internal +} // namespace detail // Experimental text formatting support. class text_style { @@ -298,11 +298,11 @@ class text_style { FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT { return static_cast(ems) != 0; } - FMT_CONSTEXPR internal::color_type get_foreground() const FMT_NOEXCEPT { + FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT { FMT_ASSERT(has_foreground(), "no foreground specified for this style"); return foreground_color; } - FMT_CONSTEXPR internal::color_type get_background() const FMT_NOEXCEPT { + FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT { FMT_ASSERT(has_background(), "no background specified for this style"); return background_color; } @@ -313,7 +313,7 @@ class text_style { private: FMT_CONSTEXPR text_style(bool is_foreground, - internal::color_type text_color) FMT_NOEXCEPT + detail::color_type text_color) FMT_NOEXCEPT : set_foreground_color(), set_background_color(), ems() { @@ -326,23 +326,23 @@ class text_style { } } - friend FMT_CONSTEXPR_DECL text_style fg(internal::color_type foreground) + friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground) FMT_NOEXCEPT; - friend FMT_CONSTEXPR_DECL text_style bg(internal::color_type background) + friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background) FMT_NOEXCEPT; - internal::color_type foreground_color; - internal::color_type background_color; + detail::color_type foreground_color; + detail::color_type background_color; bool set_foreground_color; bool set_background_color; emphasis ems; }; -FMT_CONSTEXPR text_style fg(internal::color_type foreground) FMT_NOEXCEPT { +FMT_CONSTEXPR text_style fg(detail::color_type foreground) FMT_NOEXCEPT { return text_style(/*is_foreground=*/true, foreground); } -FMT_CONSTEXPR text_style bg(internal::color_type background) FMT_NOEXCEPT { +FMT_CONSTEXPR text_style bg(detail::color_type background) FMT_NOEXCEPT { return text_style(/*is_foreground=*/false, background); } @@ -350,21 +350,21 @@ FMT_CONSTEXPR text_style operator|(emphasis lhs, emphasis rhs) FMT_NOEXCEPT { return text_style(lhs) | rhs; } -namespace internal { +namespace detail { template struct ansi_color_escape { - FMT_CONSTEXPR ansi_color_escape(internal::color_type text_color, + FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color, const char* esc) FMT_NOEXCEPT { // If we have a terminal color, we need to output another escape code // sequence. if (!text_color.is_rgb) { - bool is_background = esc == internal::data::background_color; + bool is_background = esc == detail::data::background_color; uint32_t value = text_color.value.term_color; // Background ASCII codes are the same as the foreground ones but with // 10 more. if (is_background) value += 10u; - std::size_t index = 0; + size_t index = 0; buffer[index++] = static_cast('\x1b'); buffer[index++] = static_cast('['); @@ -398,7 +398,7 @@ template struct ansi_color_escape { if (em_bits & static_cast(emphasis::strikethrough)) em_codes[3] = 9; - std::size_t index = 0; + size_t index = 0; for (int i = 0; i < 4; ++i) { if (!em_codes[i]) continue; buffer[index++] = static_cast('\x1b'); @@ -412,7 +412,7 @@ template struct ansi_color_escape { FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; } FMT_CONSTEXPR const Char* end() const FMT_NOEXCEPT { - return buffer + std::strlen(buffer); + return buffer + std::char_traits::length(buffer); } private: @@ -429,14 +429,14 @@ template struct ansi_color_escape { template FMT_CONSTEXPR ansi_color_escape make_foreground_color( - internal::color_type foreground) FMT_NOEXCEPT { - return ansi_color_escape(foreground, internal::data::foreground_color); + detail::color_type foreground) FMT_NOEXCEPT { + return ansi_color_escape(foreground, detail::data::foreground_color); } template FMT_CONSTEXPR ansi_color_escape make_background_color( - internal::color_type background) FMT_NOEXCEPT { - return ansi_color_escape(background, internal::data::background_color); + detail::color_type background) FMT_NOEXCEPT { + return ansi_color_escape(background, detail::data::background_color); } template @@ -455,73 +455,71 @@ inline void fputs(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT { } template inline void reset_color(FILE* stream) FMT_NOEXCEPT { - fputs(internal::data::reset_color, stream); + fputs(detail::data::reset_color, stream); } template <> inline void reset_color(FILE* stream) FMT_NOEXCEPT { - fputs(internal::data::wreset_color, stream); + fputs(detail::data::wreset_color, stream); } template -inline void reset_color(basic_memory_buffer& buffer) FMT_NOEXCEPT { +inline void reset_color(buffer& buffer) FMT_NOEXCEPT { const char* begin = data::reset_color; const char* end = begin + sizeof(data::reset_color) - 1; buffer.append(begin, end); } template -void vformat_to(basic_memory_buffer& buf, const text_style& ts, +void vformat_to(buffer& buf, const text_style& ts, basic_string_view format_str, - basic_format_args> args) { + basic_format_args>> args) { bool has_style = false; if (ts.has_emphasis()) { has_style = true; - auto emphasis = internal::make_emphasis(ts.get_emphasis()); + auto emphasis = detail::make_emphasis(ts.get_emphasis()); buf.append(emphasis.begin(), emphasis.end()); } if (ts.has_foreground()) { has_style = true; - auto foreground = - internal::make_foreground_color(ts.get_foreground()); + auto foreground = detail::make_foreground_color(ts.get_foreground()); buf.append(foreground.begin(), foreground.end()); } if (ts.has_background()) { has_style = true; - auto background = - internal::make_background_color(ts.get_background()); + auto background = detail::make_background_color(ts.get_background()); buf.append(background.begin(), background.end()); } - vformat_to(buf, format_str, args); - if (has_style) { - internal::reset_color(buf); - } + detail::vformat_to(buf, format_str, args); + if (has_style) detail::reset_color(buf); } -} // namespace internal +} // namespace detail template > void vprint(std::FILE* f, const text_style& ts, const S& format, - basic_format_args> args) { + basic_format_args>> args) { basic_memory_buffer buf; - internal::vformat_to(buf, ts, to_string_view(format), args); + detail::vformat_to(buf, ts, to_string_view(format), args); buf.push_back(Char(0)); - internal::fputs(buf.data(), f); + detail::fputs(buf.data(), f); } /** + \rst Formats a string and prints it to the specified file stream using ANSI escape sequences to specify text formatting. - Example: + + **Example**:: + fmt::print(fmt::emphasis::bold | fg(fmt::color::red), "Elapsed time: {0:.2f} seconds", 1.23); + \endrst */ template ::value)> + FMT_ENABLE_IF(detail::is_string::value)> void print(std::FILE* f, const text_style& ts, const S& format_str, const Args&... args) { - internal::check_format_string(format_str); - using context = buffer_context>; - format_arg_store as{args...}; - vprint(f, ts, format_str, basic_format_args(as)); + vprint(f, ts, format_str, + fmt::make_args_checked(format_str, args...)); } /** @@ -532,7 +530,7 @@ void print(std::FILE* f, const text_style& ts, const S& format_str, "Elapsed time: {0:.2f} seconds", 1.23); */ template ::value)> + FMT_ENABLE_IF(detail::is_string::value)> void print(const text_style& ts, const S& format_str, const Args&... args) { return print(stdout, ts, format_str, args...); } @@ -540,9 +538,9 @@ void print(const text_style& ts, const S& format_str, const Args&... args) { template > inline std::basic_string vformat( const text_style& ts, const S& format_str, - basic_format_args> args) { + basic_format_args>> args) { basic_memory_buffer buf; - internal::vformat_to(buf, ts, to_string_view(format_str), args); + detail::vformat_to(buf, ts, to_string_view(format_str), args); return fmt::to_string(buf); } @@ -562,7 +560,42 @@ template > inline std::basic_string format(const text_style& ts, const S& format_str, const Args&... args) { return vformat(ts, to_string_view(format_str), - {internal::make_args_checked(format_str, args...)}); + fmt::make_args_checked(format_str, args...)); +} + +/** + Formats a string with the given text_style and writes the output to ``out``. + */ +template ::value)> +OutputIt vformat_to( + OutputIt out, const text_style& ts, basic_string_view format_str, + basic_format_args>> args) { + decltype(detail::get_buffer(out)) buf(detail::get_buffer_init(out)); + detail::vformat_to(buf, ts, format_str, args); + return detail::get_iterator(buf); +} + +/** + \rst + Formats arguments with the given text_style, writes the result to the output + iterator ``out`` and returns the iterator past the end of the output range. + + **Example**:: + + std::vector out; + fmt::format_to(std::back_inserter(out), + fmt::emphasis::bold | fg(fmt::color::red), "{}", 42); + \endrst +*/ +template >::value&& + detail::is_string::value> +inline auto format_to(OutputIt out, const text_style& ts, const S& format_str, + Args&&... args) -> + typename std::enable_if::type { + return vformat_to(out, ts, to_string_view(format_str), + fmt::make_args_checked(format_str, args...)); } FMT_END_NAMESPACE diff --git a/src/3rd-part/fmt/include/fmt/compile.h b/src/3rd-part/fmt/include/fmt/compile.h index e403c0a..3a33b02 100644 --- a/src/3rd-part/fmt/include/fmt/compile.h +++ b/src/3rd-part/fmt/include/fmt/compile.h @@ -9,10 +9,37 @@ #define FMT_COMPILE_H_ #include + #include "format.h" FMT_BEGIN_NAMESPACE -namespace internal { +namespace detail { + +// A compile-time string which is compiled into fast formatting code. +class compiled_string {}; + +template +struct is_compiled_string : std::is_base_of {}; + +/** + \rst + Converts a string literal *s* into a format string that will be parsed at + compile time and converted into efficient formatting code. Requires C++17 + ``constexpr if`` compiler support. + + **Example**:: + + // Converts 42 into std::string using the most efficient method and no + // runtime format string processing. + std::string s = fmt::format(FMT_COMPILE("{}"), 42); + \endrst + */ +#define FMT_COMPILE(s) FMT_STRING_IMPL(s, fmt::detail::compiled_string) + +template +const T& first(const T& value, const Tail&...) { + return value; +} // Part of a compiled format string. It can be either literal text or a // replacement field. @@ -61,13 +88,15 @@ template struct part_counter { if (begin != end) ++num_parts; } - FMT_CONSTEXPR void on_arg_id() { ++num_parts; } - FMT_CONSTEXPR void on_arg_id(int) { ++num_parts; } - FMT_CONSTEXPR void on_arg_id(basic_string_view) { ++num_parts; } + FMT_CONSTEXPR int on_arg_id() { return ++num_parts, 0; } + FMT_CONSTEXPR int on_arg_id(int) { return ++num_parts, 0; } + FMT_CONSTEXPR int on_arg_id(basic_string_view) { + return ++num_parts, 0; + } - FMT_CONSTEXPR void on_replacement_field(const Char*) {} + FMT_CONSTEXPR void on_replacement_field(int, const Char*) {} - FMT_CONSTEXPR const Char* on_format_specs(const Char* begin, + FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin, const Char* end) { // Find the matching brace. unsigned brace_counter = 0; @@ -115,25 +144,28 @@ class format_string_compiler : public error_handler { handler_(part::make_text({begin, to_unsigned(end - begin)})); } - FMT_CONSTEXPR void on_arg_id() { + FMT_CONSTEXPR int on_arg_id() { part_ = part::make_arg_index(parse_context_.next_arg_id()); + return 0; } - FMT_CONSTEXPR void on_arg_id(int id) { + FMT_CONSTEXPR int on_arg_id(int id) { parse_context_.check_arg_id(id); part_ = part::make_arg_index(id); + return 0; } - FMT_CONSTEXPR void on_arg_id(basic_string_view id) { + FMT_CONSTEXPR int on_arg_id(basic_string_view id) { part_ = part::make_arg_name(id); + return 0; } - FMT_CONSTEXPR void on_replacement_field(const Char* ptr) { + FMT_CONSTEXPR void on_replacement_field(int, const Char* ptr) { part_.arg_id_end = ptr; handler_(part_); } - FMT_CONSTEXPR const Char* on_format_specs(const Char* begin, + FMT_CONSTEXPR const Char* on_format_specs(int, const Char* begin, const Char* end) { auto repl = typename part::replacement(); dynamic_specs_handler> handler( @@ -159,23 +191,24 @@ FMT_CONSTEXPR void compile_format_string(basic_string_view format_str, format_string_compiler(format_str, handler)); } -template +template void format_arg( - basic_format_parse_context& parse_ctx, + basic_format_parse_context& parse_ctx, Context& ctx, Id arg_id) { - ctx.advance_to( - visit_format_arg(arg_formatter(ctx, &parse_ctx), ctx.arg(arg_id))); + ctx.advance_to(visit_format_arg( + arg_formatter(ctx, &parse_ctx), + ctx.arg(arg_id))); } // vformat_to is defined in a subnamespace to prevent ADL. namespace cf { -template -auto vformat_to(Range out, CompiledFormat& cf, basic_format_args args) - -> typename Context::iterator { +template +auto vformat_to(OutputIt out, CompiledFormat& cf, + basic_format_args args) -> typename Context::iterator { using char_type = typename Context::char_type; basic_format_parse_context parse_ctx( to_string_view(cf.format_str_)); - Context ctx(out.begin(), args); + Context ctx(out, args); const auto& parts = cf.parts(); for (auto part_it = std::begin(parts); part_it != std::end(parts); @@ -196,12 +229,12 @@ auto vformat_to(Range out, CompiledFormat& cf, basic_format_args args) case format_part_t::kind::arg_index: advance_to(parse_ctx, part.arg_id_end); - internal::format_arg(parse_ctx, ctx, value.arg_index); + detail::format_arg(parse_ctx, ctx, value.arg_index); break; case format_part_t::kind::arg_name: advance_to(parse_ctx, part.arg_id_end); - internal::format_arg(parse_ctx, ctx, value.str); + detail::format_arg(parse_ctx, ctx, value.str); break; case format_part_t::kind::replacement: { @@ -225,7 +258,9 @@ auto vformat_to(Range out, CompiledFormat& cf, basic_format_args args) advance_to(parse_ctx, part.arg_id_end); ctx.advance_to( - visit_format_arg(arg_formatter(ctx, nullptr, &specs), arg)); + visit_format_arg(arg_formatter( + ctx, nullptr, &specs), + arg)); break; } } @@ -239,7 +274,7 @@ struct basic_compiled_format {}; template struct compiled_format_base : basic_compiled_format { using char_type = char_t; - using parts_container = std::vector>; + using parts_container = std::vector>; parts_container compiled_parts; @@ -304,7 +339,7 @@ struct compiled_format_base::value>> const parts_container& parts() const { static FMT_CONSTEXPR_DECL const auto compiled_parts = compile_to_parts( - internal::to_string_view(S())); + detail::to_string_view(S())); return compiled_parts.data; } }; @@ -317,8 +352,8 @@ class compiled_format : private compiled_format_base { private: basic_string_view format_str_; - template - friend auto cf::vformat_to(Range out, CompiledFormat& cf, + template + friend auto cf::vformat_to(OutputIt out, CompiledFormat& cf, basic_format_args args) -> typename Context::iterator; @@ -333,7 +368,8 @@ template struct type_list {}; // Returns a reference to the argument at index N from [first, rest...]. template -constexpr const auto& get(const T& first, const Args&... rest) { +constexpr const auto& get([[maybe_unused]] const T& first, + [[maybe_unused]] const Args&... rest) { static_assert(N < 1 + sizeof...(Args), "index is out of bounds"); if constexpr (N == 0) return first; @@ -350,47 +386,39 @@ template struct get_type_impl> { template using get_type = typename get_type_impl::type; +template struct is_compiled_format : std::false_type {}; + template struct text { basic_string_view data; using char_type = Char; template OutputIt format(OutputIt out, const Args&...) const { - return copy_str(data.begin(), data.end(), out); + return write(out, data); } }; +template +struct is_compiled_format> : std::true_type {}; + template constexpr text make_text(basic_string_view s, size_t pos, size_t size) { return {{&s[pos], size}}; } -template , int> = 0> -OutputIt format_default(OutputIt out, T value) { - format_int fi(value); - return std::copy(fi.data(), fi.data() + fi.size(), out); -} - -template -OutputIt format_default(OutputIt out, double value) { - writer w(out); - w.write(value); - return w.out(); -} +template struct code_unit { + Char value; + using char_type = Char; -template -OutputIt format_default(OutputIt out, Char value) { - *out++ = value; - return out; -} + template + OutputIt format(OutputIt out, const Args&...) const { + return write(out, value); + } +}; -template -OutputIt format_default(OutputIt out, const Char* value) { - auto length = std::char_traits::length(value); - return copy_str(value, value + length, out); -} +template +struct is_compiled_format> : std::true_type {}; // A replacement field that refers to argument N. template struct field { @@ -400,10 +428,32 @@ template struct field { OutputIt format(OutputIt out, const Args&... args) const { // This ensures that the argument type is convertile to `const T&`. const T& arg = get(args...); - return format_default(out, arg); + return write(out, arg); + } +}; + +template +struct is_compiled_format> : std::true_type {}; + +// A replacement field that refers to argument N and has format specifiers. +template struct spec_field { + using char_type = Char; + mutable formatter fmt; + + template + OutputIt format(OutputIt out, const Args&... args) const { + // This ensures that the argument type is convertile to `const T&`. + const T& arg = get(args...); + const auto& vargs = + make_format_args>(args...); + basic_format_context ctx(out, vargs); + return fmt.format(arg, ctx); } }; +template +struct is_compiled_format> : std::true_type {}; + template struct concat { L lhs; R rhs; @@ -416,6 +466,9 @@ template struct concat { } }; +template +struct is_compiled_format> : std::true_type {}; + template constexpr concat make_concat(L lhs, R rhs) { return {lhs, rhs}; @@ -436,7 +489,8 @@ constexpr auto compile_format_string(S format_str); template constexpr auto parse_tail(T head, S format_str) { - if constexpr (POS != to_string_view(format_str).size()) { + if constexpr (POS != + basic_string_view(format_str).size()) { constexpr auto tail = compile_format_string(format_str); if constexpr (std::is_same, unknown_format>()) @@ -448,6 +502,22 @@ constexpr auto parse_tail(T head, S format_str) { } } +template struct parse_specs_result { + formatter fmt; + size_t end; + int next_arg_id; +}; + +template +constexpr parse_specs_result parse_specs(basic_string_view str, + size_t pos, int arg_id) { + str.remove_prefix(pos); + auto ctx = basic_format_parse_context(str, {}, arg_id + 1); + auto f = formatter(); + auto end = f.parse(ctx); + return {f, pos + (end - str.data()) + 1, ctx.next_arg_id()}; +} + // Compiles a non-empty format string and returns the compiled representation // or unknown_format() on unrecognized input. template @@ -461,12 +531,13 @@ constexpr auto compile_format_string(S format_str) { return parse_tail(make_text(str, POS, 1), format_str); } else if constexpr (str[POS + 1] == '}') { using type = get_type; - if constexpr (std::is_same::value) { - return parse_tail(field(), - format_str); - } else { - return unknown_format(); - } + return parse_tail(field(), + format_str); + } else if constexpr (str[POS + 1] == ':') { + using type = get_type; + constexpr auto result = parse_specs(str, POS + 2, ID); + return parse_tail( + spec_field{result.fmt}, format_str); } else { return unknown_format(); } @@ -476,106 +547,153 @@ constexpr auto compile_format_string(S format_str) { return parse_tail(make_text(str, POS, 1), format_str); } else { constexpr auto end = parse_text(str, POS + 1); - return parse_tail(make_text(str, POS, end - POS), - format_str); + if constexpr (end - POS > 1) { + return parse_tail(make_text(str, POS, end - POS), + format_str); + } else { + return parse_tail(code_unit{str[POS]}, + format_str); + } } } -#endif // __cpp_if_constexpr -} // namespace internal -#if FMT_USE_CONSTEXPR -# ifdef __cpp_if_constexpr template ::value)> + FMT_ENABLE_IF(is_compile_string::value || + detail::is_compiled_string::value)> constexpr auto compile(S format_str) { constexpr basic_string_view str = format_str; if constexpr (str.size() == 0) { - return internal::make_text(str, 0, 0); + return detail::make_text(str, 0, 0); } else { constexpr auto result = - internal::compile_format_string, 0, 0>( + detail::compile_format_string, 0, 0>( format_str); if constexpr (std::is_same, - internal::unknown_format>()) { - return internal::compiled_format(to_string_view(format_str)); + detail::unknown_format>()) { + return detail::compiled_format(to_string_view(format_str)); } else { return result; } } } +#else +template ::value)> +constexpr auto compile(S format_str) -> detail::compiled_format { + return detail::compiled_format(to_string_view(format_str)); +} +#endif // __cpp_if_constexpr + +// Compiles the format string which must be a string literal. +template +auto compile(const Char (&format_str)[N]) + -> detail::compiled_format { + return detail::compiled_format( + basic_string_view(format_str, N - 1)); +} +} // namespace detail + +// DEPRECATED! use FMT_COMPILE instead. +template +FMT_DEPRECATED auto compile(const Args&... args) + -> decltype(detail::compile(args...)) { + return detail::compile(args...); +} + +#if FMT_USE_CONSTEXPR +# ifdef __cpp_if_constexpr template ::value)> -std::basic_string format(const CompiledFormat& cf, const Args&... args) { + FMT_ENABLE_IF(detail::is_compiled_format::value)> +FMT_INLINE std::basic_string format(const CompiledFormat& cf, + const Args&... args) { basic_memory_buffer buffer; - cf.format(std::back_inserter(buffer), args...); + cf.format(detail::buffer_appender(buffer), args...); return to_string(buffer); } template ::value)> + FMT_ENABLE_IF(detail::is_compiled_format::value)> OutputIt format_to(OutputIt out, const CompiledFormat& cf, const Args&... args) { return cf.format(out, args...); } -# else -template ::value)> -constexpr auto compile(S format_str) -> internal::compiled_format { - return internal::compiled_format(to_string_view(format_str)); -} # endif // __cpp_if_constexpr #endif // FMT_USE_CONSTEXPR -// Compiles the format string which must be a string literal. -template -auto compile(const Char (&format_str)[N]) - -> internal::compiled_format { - return internal::compiled_format( - basic_string_view(format_str, N - 1)); -} - template ::value)> std::basic_string format(const CompiledFormat& cf, const Args&... args) { basic_memory_buffer buffer; - using range = buffer_range; using context = buffer_context; - internal::cf::vformat_to(range(buffer), cf, - {make_format_args(args...)}); + detail::cf::vformat_to(detail::buffer_appender(buffer), cf, + make_format_args(args...)); return to_string(buffer); } +template ::value)> +FMT_INLINE std::basic_string format(const S&, + Args&&... args) { +#ifdef __cpp_if_constexpr + if constexpr (std::is_same::value) { + constexpr basic_string_view str = S(); + if (str.size() == 2 && str[0] == '{' && str[1] == '}') + return fmt::to_string(detail::first(args...)); + } +#endif + constexpr auto compiled = detail::compile(S()); + return format(compiled, std::forward(args)...); +} + template ::value)> OutputIt format_to(OutputIt out, const CompiledFormat& cf, const Args&... args) { using char_type = typename CompiledFormat::char_type; - using range = internal::output_range; using context = format_context_t; - return internal::cf::vformat_to( - range(out), cf, {make_format_args(args...)}); + return detail::cf::vformat_to(out, cf, + make_format_args(args...)); } -template ::value)> -format_to_n_result format_to_n(OutputIt out, size_t n, - const CompiledFormat& cf, - const Args&... args) { +template ::value)> +OutputIt format_to(OutputIt out, const S&, const Args&... args) { + constexpr auto compiled = detail::compile(S()); + return format_to(out, compiled, args...); +} + +template +auto format_to_n(OutputIt out, size_t n, const CompiledFormat& cf, + const Args&... args) -> + typename std::enable_if< + detail::is_output_iterator::value && + std::is_base_of::value, + format_to_n_result>::type { auto it = - format_to(internal::truncating_iterator(out, n), cf, args...); + format_to(detail::truncating_iterator(out, n), cf, args...); + return {it.base(), it.count()}; +} + +template ::value)> +format_to_n_result format_to_n(OutputIt out, size_t n, const S&, + const Args&... args) { + constexpr auto compiled = detail::compile(S()); + auto it = format_to(detail::truncating_iterator(out, n), compiled, + args...); return {it.base(), it.count()}; } template -std::size_t formatted_size(const CompiledFormat& cf, const Args&... args) { - return format_to(internal::counting_iterator(), cf, args...).count(); +size_t formatted_size(const CompiledFormat& cf, const Args&... args) { + return format_to(detail::counting_iterator(), cf, args...).count(); } FMT_END_NAMESPACE diff --git a/src/3rd-part/fmt/include/fmt/core.h b/src/3rd-part/fmt/include/fmt/core.h index 9fd8df2..0a81e0c 100644 --- a/src/3rd-part/fmt/include/fmt/core.h +++ b/src/3rd-part/fmt/include/fmt/core.h @@ -10,30 +10,20 @@ #include // std::FILE #include +#include #include +#include #include #include +#include // The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 60102 +#define FMT_VERSION 70103 -#ifdef __has_feature -# define FMT_HAS_FEATURE(x) __has_feature(x) -#else -# define FMT_HAS_FEATURE(x) 0 -#endif - -#if defined(__has_include) && !defined(__INTELLISENSE__) && \ - !(defined(__INTEL_COMPILER) && __INTEL_COMPILER < 1600) -# define FMT_HAS_INCLUDE(x) __has_include(x) +#ifdef __clang__ +# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else -# define FMT_HAS_INCLUDE(x) 0 -#endif - -#ifdef __has_cpp_attribute -# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -# define FMT_HAS_CPP_ATTRIBUTE(x) 0 +# define FMT_CLANG_VERSION 0 #endif #if defined(__GNUC__) && !defined(__clang__) @@ -42,6 +32,12 @@ # define FMT_GCC_VERSION 0 #endif +#if defined(__INTEL_COMPILER) +# define FMT_ICC_VERSION __INTEL_COMPILER +#else +# define FMT_ICC_VERSION 0 +#endif + #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) # define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION #else @@ -56,17 +52,44 @@ #ifdef _MSC_VER # define FMT_MSC_VER _MSC_VER +# define FMT_SUPPRESS_MSC_WARNING(n) __pragma(warning(suppress : n)) #else # define FMT_MSC_VER 0 +# define FMT_SUPPRESS_MSC_WARNING(n) +#endif + +#ifdef __has_feature +# define FMT_HAS_FEATURE(x) __has_feature(x) +#else +# define FMT_HAS_FEATURE(x) 0 +#endif + +#if defined(__has_include) && !defined(__INTELLISENSE__) && \ + (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600) +# define FMT_HAS_INCLUDE(x) __has_include(x) +#else +# define FMT_HAS_INCLUDE(x) 0 +#endif + +#ifdef __has_cpp_attribute +# define FMT_HAS_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +# define FMT_HAS_CPP_ATTRIBUTE(x) 0 #endif +#define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ + (__cplusplus >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + +#define FMT_HAS_CPP17_ATTRIBUTE(attribute) \ + (__cplusplus >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + // Check if relaxed C++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR # define FMT_USE_CONSTEXPR \ (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ - !FMT_NVCC + !FMT_NVCC && !FMT_ICC_VERSION #endif #if FMT_USE_CONSTEXPR # define FMT_CONSTEXPR constexpr @@ -77,7 +100,7 @@ #endif #ifndef FMT_OVERRIDE -# if FMT_HAS_FEATURE(cxx_override) || \ +# if FMT_HAS_FEATURE(cxx_override_control) || \ (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 # define FMT_OVERRIDE override # else @@ -117,19 +140,20 @@ # endif #endif -// [[noreturn]] is disabled on MSVC because of bogus unreachable code warnings. -#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER +// [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code +// warnings. +#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \ + !FMT_NVCC # define FMT_NORETURN [[noreturn]] #else # define FMT_NORETURN #endif #ifndef FMT_DEPRECATED -# if (FMT_HAS_CPP_ATTRIBUTE(deprecated) && __cplusplus >= 201402L) || \ - FMT_MSC_VER >= 1900 +# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900 # define FMT_DEPRECATED [[deprecated]] # else -# if defined(__GNUC__) || defined(__clang__) +# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) # define FMT_DEPRECATED __attribute__((deprecated)) # elif FMT_MSC_VER # define FMT_DEPRECATED __declspec(deprecated) @@ -139,16 +163,32 @@ # endif #endif -// Workaround broken [[deprecated]] in the Intel compiler and NVCC. -#if defined(__INTEL_COMPILER) || FMT_NVCC +// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers. +#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC # define FMT_DEPRECATED_ALIAS #else # define FMT_DEPRECATED_ALIAS FMT_DEPRECATED #endif -#ifndef FMT_BEGIN_NAMESPACE +#ifndef FMT_INLINE +# if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_INLINE inline __attribute__((always_inline)) +# else +# define FMT_INLINE inline +# endif +#endif + +#ifndef FMT_USE_INLINE_NAMESPACES # if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ - FMT_MSC_VER >= 1900 + (FMT_MSC_VER >= 1900 && !_MANAGED) +# define FMT_USE_INLINE_NAMESPACES 1 +# else +# define FMT_USE_INLINE_NAMESPACES 0 +# endif +#endif + +#ifndef FMT_BEGIN_NAMESPACE +# if FMT_USE_INLINE_NAMESPACES # define FMT_INLINE_NAMESPACE inline namespace # define FMT_END_NAMESPACE \ } \ @@ -157,21 +197,26 @@ # define FMT_INLINE_NAMESPACE namespace # define FMT_END_NAMESPACE \ } \ - using namespace v6; \ + using namespace v7; \ } # endif # define FMT_BEGIN_NAMESPACE \ namespace fmt { \ - FMT_INLINE_NAMESPACE v6 { + FMT_INLINE_NAMESPACE v7 { #endif #if !defined(FMT_HEADER_ONLY) && defined(_WIN32) +# define FMT_CLASS_API FMT_SUPPRESS_MSC_WARNING(4275) # ifdef FMT_EXPORT # define FMT_API __declspec(dllexport) +# define FMT_EXTERN_TEMPLATE_API FMT_API +# define FMT_EXPORTED # elif defined(FMT_SHARED) # define FMT_API __declspec(dllimport) # define FMT_EXTERN_TEMPLATE_API FMT_API # endif +#else +# define FMT_CLASS_API #endif #ifndef FMT_API # define FMT_API @@ -179,6 +224,9 @@ #ifndef FMT_EXTERN_TEMPLATE_API # define FMT_EXTERN_TEMPLATE_API #endif +#ifndef FMT_INSTANTIATION_DEF_API +# define FMT_INSTANTIATION_DEF_API FMT_API +#endif #ifndef FMT_HEADER_ONLY # define FMT_EXTERN extern @@ -197,9 +245,16 @@ # define FMT_USE_EXPERIMENTAL_STRING_VIEW #endif +#ifndef FMT_UNICODE +# define FMT_UNICODE !FMT_MSC_VER +#endif +#if FMT_UNICODE && FMT_MSC_VER +# pragma execution_character_set("utf-8") +#endif + FMT_BEGIN_NAMESPACE -// Implementations of enable_if_t and other types for pre-C++14 systems. +// Implementations of enable_if_t and other metafunctions for older systems. template using enable_if_t = typename std::enable_if::type; template @@ -211,6 +266,8 @@ template using remove_const_t = typename std::remove_const::type; template using remove_cvref_t = typename std::remove_cv>::type; +template struct type_identity { using type = T; }; +template using type_identity_t = typename type_identity::type; struct monostate {}; @@ -219,21 +276,23 @@ struct monostate {}; // to workaround a bug in MSVC 2019 (see #1140 and #1186). #define FMT_ENABLE_IF(...) enable_if_t<(__VA_ARGS__), int> = 0 -namespace internal { +namespace detail { -// A workaround for gcc 4.8 to make void_t work in a SFINAE context. -template struct void_t_impl { using type = void; }; +// A helper function to suppress "conditional expression is constant" warnings. +template constexpr T const_check(T value) { return value; } -FMT_API void assert_fail(const char* file, int line, const char* message); +FMT_NORETURN FMT_API void assert_fail(const char* file, int line, + const char* message); #ifndef FMT_ASSERT # ifdef NDEBUG -# define FMT_ASSERT(condition, message) +// FMT_ASSERT is not empty to avoid -Werror=empty-body. +# define FMT_ASSERT(condition, message) ((void)0) # else -# define FMT_ASSERT(condition, message) \ - ((condition) \ - ? void() \ - : fmt::internal::assert_fail(__FILE__, __LINE__, (message))) +# define FMT_ASSERT(condition, message) \ + ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ + ? (void)0 \ + : ::fmt::detail::assert_fail(__FILE__, __LINE__, (message))) # endif #endif @@ -248,7 +307,8 @@ template struct std_string_view {}; #ifdef FMT_USE_INT128 // Do nothing. -#elif defined(__SIZEOF_INT128__) +#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \ + !(FMT_CLANG_VERSION && FMT_MSC_VER) # define FMT_USE_INT128 1 using int128_t = __int128_t; using uint128_t = __uint128_t; @@ -266,10 +326,24 @@ FMT_CONSTEXPR typename std::make_unsigned::type to_unsigned(Int value) { FMT_ASSERT(value >= 0, "negative value"); return static_cast::type>(value); } -} // namespace internal -template -using void_t = typename internal::void_t_impl::type; +FMT_SUPPRESS_MSC_WARNING(4566) constexpr unsigned char micro[] = "\u00B5"; + +template constexpr bool is_unicode() { + return FMT_UNICODE || sizeof(Char) != 1 || + (sizeof(micro) == 3 && micro[0] == 0xC2 && micro[1] == 0xB5); +} + +#ifdef __cpp_char8_t +using char8_type = char8_t; +#else +enum char8_type : unsigned char {}; +#endif +} // namespace detail + +#ifdef FMT_USE_INTERNAL +namespace internal = detail; // DEPRECATED +#endif /** An implementation of ``std::basic_string_view`` for pre-C++17. It provides a @@ -284,13 +358,13 @@ template class basic_string_view { size_t size_; public: - using char_type = Char; + using value_type = Char; using iterator = const Char*; - FMT_CONSTEXPR basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} + constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} /** Constructs a string reference object from a C string and a size. */ - FMT_CONSTEXPR basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT + constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT : data_(s), size_(count) {} @@ -300,6 +374,9 @@ template class basic_string_view { the size with ``std::char_traits::length``. \endrst */ +#if __cplusplus >= 201703L // C++17's char_traits::length() is constexpr. + FMT_CONSTEXPR +#endif basic_string_view(const Char* s) : data_(s), size_(std::char_traits::length(s)) {} @@ -310,22 +387,21 @@ template class basic_string_view { : data_(s.data()), size_(s.size()) {} - template < - typename S, - FMT_ENABLE_IF(std::is_same>::value)> + template >::value)> FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), size_(s.size()) {} /** Returns a pointer to the string data. */ - FMT_CONSTEXPR const Char* data() const { return data_; } + constexpr const Char* data() const { return data_; } /** Returns the string size. */ - FMT_CONSTEXPR size_t size() const { return size_; } + constexpr size_t size() const { return size_; } - FMT_CONSTEXPR iterator begin() const { return data_; } - FMT_CONSTEXPR iterator end() const { return data_ + size_; } + constexpr iterator begin() const { return data_; } + constexpr iterator end() const { return data_ + size_; } - FMT_CONSTEXPR const Char& operator[](size_t pos) const { return data_[pos]; } + constexpr const Char& operator[](size_t pos) const { return data_[pos]; } FMT_CONSTEXPR void remove_prefix(size_t n) { data_ += n; @@ -364,16 +440,11 @@ template class basic_string_view { using string_view = basic_string_view; using wstring_view = basic_string_view; -#ifndef __cpp_char8_t -// A UTF-8 code unit type. -enum char8_t : unsigned char {}; -#endif - /** Specifies if ``T`` is a character type. Can be specialized by users. */ template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; -template <> struct is_char : std::true_type {}; +template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; template <> struct is_char : std::true_type {}; @@ -410,14 +481,13 @@ inline basic_string_view to_string_view(basic_string_view s) { } template >::value)> -inline basic_string_view to_string_view( - internal::std_string_view s) { + FMT_ENABLE_IF(!std::is_empty>::value)> +inline basic_string_view to_string_view(detail::std_string_view s) { return s; } // A base class for compile-time strings. It is defined in the fmt namespace to -// make formatting functions visible via ADL, e.g. format(fmt("{}"), 42). +// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42). struct compile_string {}; template @@ -428,9 +498,9 @@ constexpr basic_string_view to_string_view(const S& s) { return s; } -namespace internal { +namespace detail { void to_string_view(...); -using fmt::v6::to_string_view; +using fmt::v7::to_string_view; // Specifies whether S is a string type convertible to fmt::basic_string_view. // It should be a constexpr function but MSVC 2017 fails to compile it in @@ -442,20 +512,32 @@ struct is_string : std::is_class()))> { template struct char_t_impl {}; template struct char_t_impl::value>> { using result = decltype(to_string_view(std::declval())); - using type = typename result::char_type; + using type = typename result::value_type; }; +// Reports a compile-time error if S is not a valid format string. +template ::value)> +FMT_INLINE void check_format_string(const S&) { +#ifdef FMT_ENFORCE_COMPILE_STRING + static_assert(is_compile_string::value, + "FMT_ENFORCE_COMPILE_STRING requires all format strings to use " + "FMT_STRING."); +#endif +} +template ::value)> +void check_format_string(S); + struct error_handler { - FMT_CONSTEXPR error_handler() = default; - FMT_CONSTEXPR error_handler(const error_handler&) = default; + constexpr error_handler() = default; + constexpr error_handler(const error_handler&) = default; // This function is intentionally not constexpr to give a compile-time error. FMT_NORETURN FMT_API void on_error(const char* message); }; -} // namespace internal +} // namespace detail /** String's character type. */ -template using char_t = typename internal::char_t_impl::type; +template using char_t = typename detail::char_t_impl::type; /** \rst @@ -473,7 +555,7 @@ template using char_t = typename internal::char_t_impl::type; +-----------------------+-------------------------------------+ \endrst */ -template +template class basic_format_parse_context : private ErrorHandler { private: basic_string_view format_str_; @@ -483,26 +565,25 @@ class basic_format_parse_context : private ErrorHandler { using char_type = Char; using iterator = typename basic_string_view::iterator; - explicit FMT_CONSTEXPR basic_format_parse_context( - basic_string_view format_str, ErrorHandler eh = ErrorHandler()) - : ErrorHandler(eh), format_str_(format_str), next_arg_id_(0) {} + explicit constexpr basic_format_parse_context( + basic_string_view format_str, ErrorHandler eh = {}, + int next_arg_id = 0) + : ErrorHandler(eh), format_str_(format_str), next_arg_id_(next_arg_id) {} /** Returns an iterator to the beginning of the format string range being parsed. */ - FMT_CONSTEXPR iterator begin() const FMT_NOEXCEPT { - return format_str_.begin(); - } + constexpr iterator begin() const FMT_NOEXCEPT { return format_str_.begin(); } /** Returns an iterator past the end of the format string range being parsed. */ - FMT_CONSTEXPR iterator end() const FMT_NOEXCEPT { return format_str_.end(); } + constexpr iterator end() const FMT_NOEXCEPT { return format_str_.end(); } /** Advances the begin iterator to ``it``. */ FMT_CONSTEXPR void advance_to(iterator it) { - format_str_.remove_prefix(internal::to_unsigned(it - begin())); + format_str_.remove_prefix(detail::to_unsigned(it - begin())); } /** @@ -510,6 +591,8 @@ class basic_format_parse_context : private ErrorHandler { the next argument index and switches to the automatic indexing. */ FMT_CONSTEXPR int next_arg_id() { + // Don't check if the argument id is valid to avoid overhead and because it + // will be checked during formatting anyway. if (next_arg_id_ >= 0) return next_arg_id_++; on_error("cannot switch from manual to automatic argument indexing"); return 0; @@ -532,20 +615,15 @@ class basic_format_parse_context : private ErrorHandler { ErrorHandler::on_error(message); } - FMT_CONSTEXPR ErrorHandler error_handler() const { return *this; } + constexpr ErrorHandler error_handler() const { return *this; } }; using format_parse_context = basic_format_parse_context; using wformat_parse_context = basic_format_parse_context; -template -using basic_parse_context FMT_DEPRECATED_ALIAS = - basic_format_parse_context; -using parse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context; -using wparse_context FMT_DEPRECATED_ALIAS = basic_format_parse_context; - template class basic_format_arg; template class basic_format_args; +template class dynamic_format_arg_store; // A formatter for objects of type T. template @@ -554,43 +632,62 @@ struct formatter { formatter() = delete; }; -template -struct FMT_DEPRECATED convert_to_int - : bool_constant::value && - std::is_convertible::value> {}; - // Specifies if T has an enabled formatter specialization. A type can be // formattable even if it doesn't have a formatter e.g. via a conversion. template using has_formatter = std::is_constructible>; -namespace internal { +// Checks whether T is a container with contiguous storage. +template struct is_contiguous : std::false_type {}; +template +struct is_contiguous> : std::true_type {}; + +namespace detail { + +// Extracts a reference to the container from back_insert_iterator. +template +inline Container& get_container(std::back_insert_iterator it) { + using bi_iterator = std::back_insert_iterator; + struct accessor : bi_iterator { + accessor(bi_iterator iter) : bi_iterator(iter) {} + using bi_iterator::container; + }; + return *accessor(it).container; +} -/** A contiguous memory buffer with an optional growing ability. */ +/** + \rst + A contiguous memory buffer with an optional growing ability. It is an internal + class and shouldn't be used directly, only via `~fmt::basic_memory_buffer`. + \endrst + */ template class buffer { private: T* ptr_; - std::size_t size_; - std::size_t capacity_; + size_t size_; + size_t capacity_; protected: // Don't initialize ptr_ since it is not accessed to save a few cycles. - buffer(std::size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} + FMT_SUPPRESS_MSC_WARNING(26495) + buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} - buffer(T* p = nullptr, std::size_t sz = 0, std::size_t cap = 0) FMT_NOEXCEPT + buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) FMT_NOEXCEPT : ptr_(p), size_(sz), capacity_(cap) {} + ~buffer() = default; + /** Sets the buffer data and capacity. */ - void set(T* buf_data, std::size_t buf_capacity) FMT_NOEXCEPT { + void set(T* buf_data, size_t buf_capacity) FMT_NOEXCEPT { ptr_ = buf_data; capacity_ = buf_capacity; } /** Increases the buffer capacity to hold at least *capacity* elements. */ - virtual void grow(std::size_t capacity) = 0; + virtual void grow(size_t capacity) = 0; public: using value_type = T; @@ -598,16 +695,18 @@ template class buffer { buffer(const buffer&) = delete; void operator=(const buffer&) = delete; - virtual ~buffer() = default; T* begin() FMT_NOEXCEPT { return ptr_; } T* end() FMT_NOEXCEPT { return ptr_ + size_; } + const T* begin() const FMT_NOEXCEPT { return ptr_; } + const T* end() const FMT_NOEXCEPT { return ptr_ + size_; } + /** Returns the size of this buffer. */ - std::size_t size() const FMT_NOEXCEPT { return size_; } + size_t size() const FMT_NOEXCEPT { return size_; } /** Returns the capacity of this buffer. */ - std::size_t capacity() const FMT_NOEXCEPT { return capacity_; } + size_t capacity() const FMT_NOEXCEPT { return capacity_; } /** Returns a pointer to the buffer data. */ T* data() FMT_NOEXCEPT { return ptr_; } @@ -615,60 +714,182 @@ template class buffer { /** Returns a pointer to the buffer data. */ const T* data() const FMT_NOEXCEPT { return ptr_; } - /** - Resizes the buffer. If T is a POD type new elements may not be initialized. - */ - void resize(std::size_t new_size) { - reserve(new_size); - size_ = new_size; - } - /** Clears this buffer. */ void clear() { size_ = 0; } - /** Reserves space to store at least *capacity* elements. */ - void reserve(std::size_t new_capacity) { + // Tries resizing the buffer to contain *count* elements. If T is a POD type + // the new elements may not be initialized. + void try_resize(size_t count) { + try_reserve(count); + size_ = count <= capacity_ ? count : capacity_; + } + + // Tries increasing the buffer capacity to *new_capacity*. It can increase the + // capacity by a smaller amount than requested but guarantees there is space + // for at least one additional element either by increasing the capacity or by + // flushing the buffer if it is full. + void try_reserve(size_t new_capacity) { if (new_capacity > capacity_) grow(new_capacity); } void push_back(const T& value) { - reserve(size_ + 1); + try_reserve(size_ + 1); ptr_[size_++] = value; } /** Appends data to the end of the buffer. */ template void append(const U* begin, const U* end); - T& operator[](std::size_t index) { return ptr_[index]; } - const T& operator[](std::size_t index) const { return ptr_[index]; } + template T& operator[](I index) { return ptr_[index]; } + template const T& operator[](I index) const { + return ptr_[index]; + } +}; + +struct buffer_traits { + explicit buffer_traits(size_t) {} + size_t count() const { return 0; } + size_t limit(size_t size) { return size; } +}; + +class fixed_buffer_traits { + private: + size_t count_ = 0; + size_t limit_; + + public: + explicit fixed_buffer_traits(size_t limit) : limit_(limit) {} + size_t count() const { return count_; } + size_t limit(size_t size) { + size_t n = limit_ > count_ ? limit_ - count_ : 0; + count_ += size; + return size < n ? size : n; + } }; -// A container-backed buffer. +// A buffer that writes to an output iterator when flushed. +template +class iterator_buffer final : public Traits, public buffer { + private: + OutputIt out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + protected: + void grow(size_t) final FMT_OVERRIDE { + if (this->size() == buffer_size) flush(); + } + void flush(); + + public: + explicit iterator_buffer(OutputIt out, size_t n = buffer_size) + : Traits(n), + buffer(data_, 0, buffer_size), + out_(out) {} + ~iterator_buffer() { flush(); } + + OutputIt out() { + flush(); + return out_; + } + size_t count() const { return Traits::count() + this->size(); } +}; + +template class iterator_buffer final : public buffer { + protected: + void grow(size_t) final FMT_OVERRIDE {} + + public: + explicit iterator_buffer(T* out, size_t = 0) : buffer(out, 0, ~size_t()) {} + + T* out() { return &*this->end(); } +}; + +// A buffer that writes to a container with the contiguous storage. template -class container_buffer : public buffer { +class iterator_buffer, + enable_if_t::value, + typename Container::value_type>> + final : public buffer { private: Container& container_; protected: - void grow(std::size_t capacity) FMT_OVERRIDE { + void grow(size_t capacity) final FMT_OVERRIDE { container_.resize(capacity); this->set(&container_[0], capacity); } public: - explicit container_buffer(Container& c) + explicit iterator_buffer(Container& c) : buffer(c.size()), container_(c) {} + explicit iterator_buffer(std::back_insert_iterator out, size_t = 0) + : iterator_buffer(get_container(out)) {} + std::back_insert_iterator out() { + return std::back_inserter(container_); + } }; -// Extracts a reference to the container from back_insert_iterator. -template -inline Container& get_container(std::back_insert_iterator it) { - using bi_iterator = std::back_insert_iterator; - struct accessor : bi_iterator { - accessor(bi_iterator iter) : bi_iterator(iter) {} - using bi_iterator::container; - }; - return *accessor(it).container; +// A buffer that counts the number of code units written discarding the output. +template class counting_buffer final : public buffer { + private: + enum { buffer_size = 256 }; + T data_[buffer_size]; + size_t count_ = 0; + + protected: + void grow(size_t) final FMT_OVERRIDE { + if (this->size() != buffer_size) return; + count_ += this->size(); + this->clear(); + } + + public: + counting_buffer() : buffer(data_, 0, buffer_size) {} + + size_t count() { return count_ + this->size(); } +}; + +// An output iterator that appends to the buffer. +// It is used to reduce symbol sizes for the common case. +template +class buffer_appender : public std::back_insert_iterator> { + using base = std::back_insert_iterator>; + + public: + explicit buffer_appender(buffer& buf) : base(buf) {} + buffer_appender(base it) : base(it) {} + + buffer_appender& operator++() { + base::operator++(); + return *this; + } + + buffer_appender operator++(int) { + buffer_appender tmp = *this; + ++*this; + return tmp; + } +}; + +// Maps an output iterator into a buffer. +template +iterator_buffer get_buffer(OutputIt); +template buffer& get_buffer(buffer_appender); + +template OutputIt get_buffer_init(OutputIt out) { + return out; +} +template buffer& get_buffer_init(buffer_appender out) { + return get_container(out); +} + +template +auto get_iterator(Buffer& buf) -> decltype(buf.out()) { + return buf.out(); +} +template buffer_appender get_iterator(buffer& buf) { + return buffer_appender(buf); } template @@ -681,12 +902,80 @@ template using has_fallback_formatter = std::is_constructible>; -template struct named_arg_base; -template struct named_arg; +struct view {}; + +template struct named_arg : view { + const Char* name; + const T& value; + named_arg(const Char* n, const T& v) : name(n), value(v) {} +}; + +template struct named_arg_info { + const Char* name; + int id; +}; + +template +struct arg_data { + // args_[0].named_args points to named_args_ to avoid bloating format_args. + // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. + T args_[1 + (NUM_ARGS != 0 ? NUM_ARGS : +1)]; + named_arg_info named_args_[NUM_NAMED_ARGS]; + + template + arg_data(const U&... init) : args_{T(named_args_, NUM_NAMED_ARGS), init...} {} + arg_data(const arg_data& other) = delete; + const T* args() const { return args_ + 1; } + named_arg_info* named_args() { return named_args_; } +}; + +template +struct arg_data { + // +1 to workaround a bug in gcc 7.5 that causes duplicated-branches warning. + T args_[NUM_ARGS != 0 ? NUM_ARGS : +1]; + + template + FMT_INLINE arg_data(const U&... init) : args_{init...} {} + FMT_INLINE const T* args() const { return args_; } + FMT_INLINE std::nullptr_t named_args() { return nullptr; } +}; + +template +inline void init_named_args(named_arg_info*, int, int) {} + +template +void init_named_args(named_arg_info* named_args, int arg_count, + int named_arg_count, const T&, const Tail&... args) { + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template +void init_named_args(named_arg_info* named_args, int arg_count, + int named_arg_count, const named_arg& arg, + const Tail&... args) { + named_args[named_arg_count++] = {arg.name, arg_count}; + init_named_args(named_args, arg_count + 1, named_arg_count, args...); +} + +template +FMT_INLINE void init_named_args(std::nullptr_t, int, int, const Args&...) {} + +template struct is_named_arg : std::false_type {}; + +template +struct is_named_arg> : std::true_type {}; -enum type { +template constexpr size_t count() { return B ? 1 : 0; } +template constexpr size_t count() { + return (B1 ? 1 : 0) + count(); +} + +template constexpr size_t count_named_args() { + return count::value...>(); +} + +enum class type { none_type, - named_arg_type, // Integer types should go first, int_type, uint_type, @@ -710,13 +999,13 @@ enum type { // Maps core type T to the corresponding type enum constant. template -struct type_constant : std::integral_constant {}; +struct type_constant : std::integral_constant {}; #define FMT_TYPE_CONSTANT(Type, constant) \ template \ - struct type_constant : std::integral_constant {} + struct type_constant \ + : std::integral_constant {} -FMT_TYPE_CONSTANT(const named_arg_base&, named_arg_type); FMT_TYPE_CONSTANT(int, int_type); FMT_TYPE_CONSTANT(unsigned, uint_type); FMT_TYPE_CONSTANT(long long, long_long_type); @@ -732,23 +1021,26 @@ FMT_TYPE_CONSTANT(const Char*, cstring_type); FMT_TYPE_CONSTANT(basic_string_view, string_type); FMT_TYPE_CONSTANT(const void*, pointer_type); -FMT_CONSTEXPR bool is_integral_type(type t) { - FMT_ASSERT(t != named_arg_type, "invalid argument type"); - return t > none_type && t <= last_integer_type; +constexpr bool is_integral_type(type t) { + return t > type::none_type && t <= type::last_integer_type; } -FMT_CONSTEXPR bool is_arithmetic_type(type t) { - FMT_ASSERT(t != named_arg_type, "invalid argument type"); - return t > none_type && t <= last_numeric_type; +constexpr bool is_arithmetic_type(type t) { + return t > type::none_type && t <= type::last_numeric_type; } template struct string_value { const Char* data; - std::size_t size; + size_t size; +}; + +template struct named_arg_value { + const named_arg_info* data; + size_t size; }; template struct custom_value { - using parse_context = basic_format_parse_context; + using parse_context = typename Context::parse_context_type; const void* value; void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); }; @@ -773,28 +1065,30 @@ template class value { const void* pointer; string_value string; custom_value custom; - const named_arg_base* named_arg; + named_arg_value named_args; }; - FMT_CONSTEXPR value(int val = 0) : int_value(val) {} - FMT_CONSTEXPR value(unsigned val) : uint_value(val) {} - value(long long val) : long_long_value(val) {} - value(unsigned long long val) : ulong_long_value(val) {} - value(int128_t val) : int128_value(val) {} - value(uint128_t val) : uint128_value(val) {} - value(float val) : float_value(val) {} - value(double val) : double_value(val) {} - value(long double val) : long_double_value(val) {} - value(bool val) : bool_value(val) {} - value(char_type val) : char_value(val) {} - value(const char_type* val) { string.data = val; } - value(basic_string_view val) { + constexpr FMT_INLINE value(int val = 0) : int_value(val) {} + constexpr FMT_INLINE value(unsigned val) : uint_value(val) {} + FMT_INLINE value(long long val) : long_long_value(val) {} + FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {} + FMT_INLINE value(int128_t val) : int128_value(val) {} + FMT_INLINE value(uint128_t val) : uint128_value(val) {} + FMT_INLINE value(float val) : float_value(val) {} + FMT_INLINE value(double val) : double_value(val) {} + FMT_INLINE value(long double val) : long_double_value(val) {} + FMT_INLINE value(bool val) : bool_value(val) {} + FMT_INLINE value(char_type val) : char_value(val) {} + FMT_INLINE value(const char_type* val) { string.data = val; } + FMT_INLINE value(basic_string_view val) { string.data = val.data(); string.size = val.size(); } - value(const void* val) : pointer(val) {} + FMT_INLINE value(const void* val) : pointer(val) {} + FMT_INLINE value(const named_arg_info* args, size_t size) + : named_args{args, size} {} - template value(const T& val) { + template FMT_INLINE value(const T& val) { custom.value = &val; // Get the formatter type through the context to allow different contexts // have different extension points, e.g. `formatter` for `format` and @@ -805,14 +1099,12 @@ template class value { fallback_formatter>>; } - value(const named_arg_base& val) { named_arg = &val; } - private: // Formats an argument of a custom type, such as a user-defined class. template - static void format_custom_arg( - const void* arg, basic_format_parse_context& parse_ctx, - Context& ctx) { + static void format_custom_arg(const void* arg, + typename Context::parse_context_type& parse_ctx, + Context& ctx) { Formatter f; parse_ctx.advance_to(f.parse(parse_ctx)); ctx.advance_to(f.format(*static_cast(arg), ctx)); @@ -828,6 +1120,8 @@ enum { long_short = sizeof(long) == sizeof(int) }; using long_type = conditional_t; using ulong_type = conditional_t; +struct unformattable {}; + // Maps formatting arguments to core types. template struct arg_mapper { using char_type = typename Context::char_type; @@ -869,7 +1163,8 @@ template struct arg_mapper { template , T>::value && - !is_string::value)> + !is_string::value && !has_formatter::value && + !has_fallback_formatter::value)> FMT_CONSTEXPR basic_string_view map(const T& val) { return basic_string_view(val); } @@ -878,7 +1173,8 @@ template struct arg_mapper { FMT_ENABLE_IF( std::is_constructible, T>::value && !std::is_constructible, T>::value && - !is_string::value && !has_formatter::value)> + !is_string::value && !has_formatter::value && + !has_fallback_formatter::value)> FMT_CONSTEXPR basic_string_view map(const T& val) { return std_string_view(val); } @@ -890,6 +1186,14 @@ template struct arg_mapper { static_assert(std::is_same::value, "invalid string type"); return reinterpret_cast(val); } + FMT_CONSTEXPR const char* map(signed char* val) { + const auto* const_val = val; + return map(const_val); + } + FMT_CONSTEXPR const char* map(unsigned char* val) { + const auto* const_val = val; + return map(const_val); + } FMT_CONSTEXPR const void* map(void* val) { return val; } FMT_CONSTEXPR const void* map(const void* val) { return val; } @@ -907,29 +1211,26 @@ template struct arg_mapper { FMT_ENABLE_IF(std::is_enum::value && !has_formatter::value && !has_fallback_formatter::value)> - FMT_CONSTEXPR auto map(const T& val) -> decltype( - map(static_cast::type>(val))) { + FMT_CONSTEXPR auto map(const T& val) + -> decltype(std::declval().map( + static_cast::type>(val))) { return map(static_cast::type>(val)); } - template < - typename T, - FMT_ENABLE_IF( - !is_string::value && !is_char::value && - !std::is_constructible, T>::value && - (has_formatter::value || - (has_fallback_formatter::value && - !std::is_constructible, T>::value)))> + template ::value && !is_char::value && + (has_formatter::value || + has_fallback_formatter::value))> FMT_CONSTEXPR const T& map(const T& val) { return val; } template - FMT_CONSTEXPR const named_arg_base& map( - const named_arg& val) { - auto arg = make_arg(val.value); - std::memcpy(val.data, &arg, sizeof(arg)); - return val; + FMT_CONSTEXPR auto map(const named_arg& val) + -> decltype(std::declval().map(val.value)) { + return map(val.value); } + + unformattable map(...) { return {}; } }; // A type constant after applying arg_mapper. @@ -938,23 +1239,22 @@ using mapped_type_constant = type_constant().map(std::declval())), typename Context::char_type>; -enum { packed_arg_bits = 5 }; +enum { packed_arg_bits = 4 }; // Maximum number of arguments with packed types. -enum { max_packed_args = 63 / packed_arg_bits }; +enum { max_packed_args = 62 / packed_arg_bits }; enum : unsigned long long { is_unpacked_bit = 1ULL << 63 }; - -template class arg_map; -} // namespace internal +enum : unsigned long long { has_named_args_bit = 1ULL << 62 }; +} // namespace detail // A formatting argument. It is a trivially copyable/constructible type to // allow storage in basic_memory_buffer. template class basic_format_arg { private: - internal::value value_; - internal::type type_; + detail::value value_; + detail::type type_; template - friend FMT_CONSTEXPR basic_format_arg internal::make_arg( + friend FMT_CONSTEXPR basic_format_arg detail::make_arg( const T& value); template @@ -963,34 +1263,40 @@ template class basic_format_arg { -> decltype(vis(0)); friend class basic_format_args; - friend class internal::arg_map; + friend class dynamic_format_arg_store; using char_type = typename Context::char_type; + template + friend struct detail::arg_data; + + basic_format_arg(const detail::named_arg_info* args, size_t size) + : value_(args, size) {} + public: class handle { public: - explicit handle(internal::custom_value custom) : custom_(custom) {} + explicit handle(detail::custom_value custom) : custom_(custom) {} - void format(basic_format_parse_context& parse_ctx, + void format(typename Context::parse_context_type& parse_ctx, Context& ctx) const { custom_.format(custom_.value, parse_ctx, ctx); } private: - internal::custom_value custom_; + detail::custom_value custom_; }; - FMT_CONSTEXPR basic_format_arg() : type_(internal::none_type) {} + constexpr basic_format_arg() : type_(detail::type::none_type) {} - FMT_CONSTEXPR explicit operator bool() const FMT_NOEXCEPT { - return type_ != internal::none_type; + constexpr explicit operator bool() const FMT_NOEXCEPT { + return type_ != detail::type::none_type; } - internal::type type() const { return type_; } + detail::type type() const { return type_; } - bool is_integral() const { return internal::is_integral_type(type_); } - bool is_arithmetic() const { return internal::is_arithmetic_type(type_); } + bool is_integral() const { return detail::is_integral_type(type_); } + bool is_arithmetic() const { return detail::is_arithmetic_type(type_); } }; /** @@ -1001,92 +1307,86 @@ template class basic_format_arg { \endrst */ template -FMT_CONSTEXPR auto visit_format_arg(Visitor&& vis, - const basic_format_arg& arg) - -> decltype(vis(0)) { +FMT_CONSTEXPR_DECL FMT_INLINE auto visit_format_arg( + Visitor&& vis, const basic_format_arg& arg) -> decltype(vis(0)) { using char_type = typename Context::char_type; switch (arg.type_) { - case internal::none_type: + case detail::type::none_type: break; - case internal::named_arg_type: - FMT_ASSERT(false, "invalid argument type"); - break; - case internal::int_type: + case detail::type::int_type: return vis(arg.value_.int_value); - case internal::uint_type: + case detail::type::uint_type: return vis(arg.value_.uint_value); - case internal::long_long_type: + case detail::type::long_long_type: return vis(arg.value_.long_long_value); - case internal::ulong_long_type: + case detail::type::ulong_long_type: return vis(arg.value_.ulong_long_value); #if FMT_USE_INT128 - case internal::int128_type: + case detail::type::int128_type: return vis(arg.value_.int128_value); - case internal::uint128_type: + case detail::type::uint128_type: return vis(arg.value_.uint128_value); #else - case internal::int128_type: - case internal::uint128_type: + case detail::type::int128_type: + case detail::type::uint128_type: break; #endif - case internal::bool_type: + case detail::type::bool_type: return vis(arg.value_.bool_value); - case internal::char_type: + case detail::type::char_type: return vis(arg.value_.char_value); - case internal::float_type: + case detail::type::float_type: return vis(arg.value_.float_value); - case internal::double_type: + case detail::type::double_type: return vis(arg.value_.double_value); - case internal::long_double_type: + case detail::type::long_double_type: return vis(arg.value_.long_double_value); - case internal::cstring_type: + case detail::type::cstring_type: return vis(arg.value_.string.data); - case internal::string_type: + case detail::type::string_type: return vis(basic_string_view(arg.value_.string.data, arg.value_.string.size)); - case internal::pointer_type: + case detail::type::pointer_type: return vis(arg.value_.pointer); - case internal::custom_type: + case detail::type::custom_type: return vis(typename basic_format_arg::handle(arg.value_.custom)); } return vis(monostate()); } -namespace internal { -// A map from argument names to their values for named arguments. -template class arg_map { - private: - using char_type = typename Context::char_type; +template struct formattable : std::false_type {}; - struct entry { - basic_string_view name; - basic_format_arg arg; - }; +namespace detail { + +// A workaround for gcc 4.8 to make void_t work in a SFINAE context. +template struct void_t_impl { using type = void; }; +template +using void_t = typename detail::void_t_impl::type; - entry* map_; - unsigned size_; +template +struct is_output_iterator : std::false_type {}; - void push_back(value val) { - const auto& named = *val.named_arg; - map_[size_] = {named.name, named.template deserialize()}; - ++size_; - } +template +struct is_output_iterator< + It, T, + void_t::iterator_category, + decltype(*std::declval() = std::declval())>> + : std::true_type {}; - public: - arg_map(const arg_map&) = delete; - void operator=(const arg_map&) = delete; - arg_map() : map_(nullptr), size_(0) {} - void init(const basic_format_args& args); - ~arg_map() { delete[] map_; } - - basic_format_arg find(basic_string_view name) const { - // The list is unsorted, so just return the first matching name. - for (entry *it = map_, *end = map_ + size_; it != end; ++it) { - if (it->name == name) return it->arg; - } - return {}; - } -}; +template +struct is_back_insert_iterator : std::false_type {}; +template +struct is_back_insert_iterator> + : std::true_type {}; + +template +struct is_contiguous_back_insert_iterator : std::false_type {}; +template +struct is_contiguous_back_insert_iterator> + : is_contiguous {}; +template +struct is_contiguous_back_insert_iterator> + : std::true_type {}; // A type-erased reference to an std::locale to avoid heavy include. class locale_ref { @@ -1106,7 +1406,7 @@ template constexpr unsigned long long encode_types() { return 0; } template constexpr unsigned long long encode_types() { - return mapped_type_constant::value | + return static_cast(mapped_type_constant::value) | (encode_types() << packed_arg_bits); } @@ -1118,18 +1418,73 @@ FMT_CONSTEXPR basic_format_arg make_arg(const T& value) { return arg; } -template int check(unformattable) { + static_assert( + formattable(), + "Cannot format an argument. To make type T formattable provide a " + "formatter specialization: https://fmt.dev/latest/api.html#udt"); + return 0; +} +template inline const U& check(const U& val) { + return val; +} + +// The type template parameter is there to avoid an ODR violation when using +// a fallback formatter in one translation unit and an implicit conversion in +// another (not recommended). +template inline value make_arg(const T& val) { - return arg_mapper().map(val); + return check(arg_mapper().map(val)); } -template inline basic_format_arg make_arg(const T& value) { return make_arg(value); } -} // namespace internal + +template struct is_reference_wrapper : std::false_type {}; +template +struct is_reference_wrapper> : std::true_type {}; + +template const T& unwrap(const T& v) { return v; } +template const T& unwrap(const std::reference_wrapper& v) { + return static_cast(v); +} + +class dynamic_arg_list { + // Workaround for clang's -Wweak-vtables. Unlike for regular classes, for + // templates it doesn't complain about inability to deduce single translation + // unit for placing vtable. So storage_node_base is made a fake template. + template struct node { + virtual ~node() = default; + std::unique_ptr> next; + }; + + template struct typed_node : node<> { + T value; + + template + FMT_CONSTEXPR typed_node(const Arg& arg) : value(arg) {} + + template + FMT_CONSTEXPR typed_node(const basic_string_view& arg) + : value(arg.data(), arg.size()) {} + }; + + std::unique_ptr> head_; + + public: + template const T& push(const Arg& arg) { + auto new_node = std::unique_ptr>(new typed_node(arg)); + auto& value = new_node->value; + new_node->next = std::move(head_); + head_ = std::move(new_node); + return value; + } +}; +} // namespace detail // Formatting context. template class basic_format_context { @@ -1140,12 +1495,12 @@ template class basic_format_context { private: OutputIt out_; basic_format_args args_; - internal::arg_map map_; - internal::locale_ref loc_; + detail::locale_ref loc_; public: using iterator = OutputIt; using format_arg = basic_format_arg; + using parse_context_type = basic_format_parse_context; template using formatter_type = formatter; basic_format_context(const basic_format_context&) = delete; @@ -1156,34 +1511,38 @@ template class basic_format_context { */ basic_format_context(OutputIt out, basic_format_args ctx_args, - internal::locale_ref loc = internal::locale_ref()) + detail::locale_ref loc = detail::locale_ref()) : out_(out), args_(ctx_args), loc_(loc) {} format_arg arg(int id) const { return args_.get(id); } + format_arg arg(basic_string_view name) { return args_.get(name); } + int arg_id(basic_string_view name) { return args_.get_id(name); } + const basic_format_args& args() const { return args_; } - // Checks if manual indexing is used and returns the argument with the - // specified name. - format_arg arg(basic_string_view name); - - internal::error_handler error_handler() { return {}; } + detail::error_handler error_handler() { return {}; } void on_error(const char* message) { error_handler().on_error(message); } // Returns an iterator to the beginning of the output range. iterator out() { return out_; } // Advances the begin iterator to ``it``. - void advance_to(iterator it) { out_ = it; } + void advance_to(iterator it) { + if (!detail::is_back_insert_iterator()) out_ = it; + } - internal::locale_ref locale() { return loc_; } + detail::locale_ref locale() { return loc_; } }; template using buffer_context = - basic_format_context>, - Char>; + basic_format_context, Char>; using format_context = buffer_context; using wformat_context = buffer_context; +// Workaround an alias issue: https://stackoverflow.com/q/62767544/471164. +#define FMT_BUFFER_CONTEXT(Char) \ + basic_format_context, Char> + /** \rst An array of references to arguments. It can be implicitly converted into @@ -1191,31 +1550,50 @@ using wformat_context = buffer_context; such as `~fmt::vformat`. \endrst */ -template class format_arg_store { +template +class format_arg_store +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 + // Workaround a GCC template argument substitution bug. + : public basic_format_args +#endif +{ private: static const size_t num_args = sizeof...(Args); - static const bool is_packed = num_args < internal::max_packed_args; + static const size_t num_named_args = detail::count_named_args(); + static const bool is_packed = num_args <= detail::max_packed_args; - using value_type = conditional_t, + using value_type = conditional_t, basic_format_arg>; - // If the arguments are not packed, add one more element to mark the end. - value_type data_[num_args + (num_args == 0 ? 1 : 0)]; + detail::arg_data + data_; friend class basic_format_args; - public: - static constexpr unsigned long long types = - is_packed ? internal::encode_types() - : internal::is_unpacked_bit | num_args; + static constexpr unsigned long long desc = + (is_packed ? detail::encode_types() + : detail::is_unpacked_bit | num_args) | + (num_named_args != 0 + ? static_cast(detail::has_named_args_bit) + : 0); + public: format_arg_store(const Args&... args) - : data_{internal::make_arg(args)...} {} + : +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 + basic_format_args(*this), +#endif + data_{detail::make_arg< + is_packed, Context, + detail::mapped_type_constant::value>(args)...} { + detail::init_named_args(data_.named_args(), 0, 0, args...); + } }; /** \rst - Constructs an `~fmt::format_arg_store` object that contains references to + Constructs a `~fmt::format_arg_store` object that contains references to arguments and can be implicitly converted to `~fmt::format_args`. `Context` can be omitted in which case it defaults to `~fmt::context`. See `~fmt::arg` for lifetime considerations. @@ -1227,56 +1605,266 @@ inline format_arg_store make_format_args( return {args...}; } -/** Formatting arguments. */ +/** + \rst + Constructs a `~fmt::format_arg_store` object that contains references + to arguments and can be implicitly converted to `~fmt::format_args`. + If ``format_str`` is a compile-time string then `make_args_checked` checks + its validity at compile time. + \endrst + */ +template > +inline auto make_args_checked(const S& format_str, + const remove_reference_t&... args) + -> format_arg_store, remove_reference_t...> { + static_assert( + detail::count<( + std::is_base_of>::value && + std::is_reference::value)...>() == 0, + "passing views as lvalues is disallowed"); + detail::check_format_string(format_str); + return {args...}; +} + +/** + \rst + Returns a named argument to be used in a formatting function. It should only + be used in a call to a formatting function. + + **Example**:: + + fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); + \endrst + */ +template +inline detail::named_arg arg(const Char* name, const T& arg) { + static_assert(!detail::is_named_arg(), "nested named arguments"); + return {name, arg}; +} + +/** + \rst + A dynamic version of `fmt::format_arg_store`. + It's equipped with a storage to potentially temporary objects which lifetimes + could be shorter than the format arguments object. + + It can be implicitly converted into `~fmt::basic_format_args` for passing + into type-erased formatting functions such as `~fmt::vformat`. + \endrst + */ +template +class dynamic_format_arg_store +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 + // Workaround a GCC template argument substitution bug. + : public basic_format_args +#endif +{ + private: + using char_type = typename Context::char_type; + + template struct need_copy { + static constexpr detail::type mapped_type = + detail::mapped_type_constant::value; + + enum { + value = !(detail::is_reference_wrapper::value || + std::is_same>::value || + std::is_same>::value || + (mapped_type != detail::type::cstring_type && + mapped_type != detail::type::string_type && + mapped_type != detail::type::custom_type)) + }; + }; + + template + using stored_type = conditional_t::value, + std::basic_string, T>; + + // Storage of basic_format_arg must be contiguous. + std::vector> data_; + std::vector> named_info_; + + // Storage of arguments not fitting into basic_format_arg must grow + // without relocation because items in data_ refer to it. + detail::dynamic_arg_list dynamic_args_; + + friend class basic_format_args; + + unsigned long long get_types() const { + return detail::is_unpacked_bit | data_.size() | + (named_info_.empty() + ? 0ULL + : static_cast(detail::has_named_args_bit)); + } + + const basic_format_arg* data() const { + return named_info_.empty() ? data_.data() : data_.data() + 1; + } + + template void emplace_arg(const T& arg) { + data_.emplace_back(detail::make_arg(arg)); + } + + template + void emplace_arg(const detail::named_arg& arg) { + if (named_info_.empty()) { + constexpr const detail::named_arg_info* zero_ptr{nullptr}; + data_.insert(data_.begin(), {zero_ptr, 0}); + } + data_.emplace_back(detail::make_arg(detail::unwrap(arg.value))); + auto pop_one = [](std::vector>* data) { + data->pop_back(); + }; + std::unique_ptr>, decltype(pop_one)> + guard{&data_, pop_one}; + named_info_.push_back({arg.name, static_cast(data_.size() - 2u)}); + data_[0].value_.named_args = {named_info_.data(), named_info_.size()}; + guard.release(); + } + + public: + /** + \rst + Adds an argument into the dynamic store for later passing to a formatting + function. + + Note that custom types and string types (but not string views) are copied + into the store dynamically allocating memory if necessary. + + **Example**:: + + fmt::dynamic_format_arg_store store; + store.push_back(42); + store.push_back("abc"); + store.push_back(1.5f); + std::string result = fmt::vformat("{} and {} and {}", store); + \endrst + */ + template void push_back(const T& arg) { + if (detail::const_check(need_copy::value)) + emplace_arg(dynamic_args_.push>(arg)); + else + emplace_arg(detail::unwrap(arg)); + } + + /** + \rst + Adds a reference to the argument into the dynamic store for later passing to + a formatting function. Supports named arguments wrapped in + ``std::reference_wrapper`` via ``std::ref()``/``std::cref()``. + + **Example**:: + + fmt::dynamic_format_arg_store store; + char str[] = "1234567890"; + store.push_back(std::cref(str)); + int a1_val{42}; + auto a1 = fmt::arg("a1_", a1_val); + store.push_back(std::cref(a1)); + + // Changing str affects the output but only for string and custom types. + str[0] = 'X'; + + std::string result = fmt::vformat("{} and {a1_}"); + assert(result == "X234567890 and 42"); + \endrst + */ + template void push_back(std::reference_wrapper arg) { + static_assert( + detail::is_named_arg::type>::value || + need_copy::value, + "objects of built-in types and string views are always copied"); + emplace_arg(arg.get()); + } + + /** + Adds named argument into the dynamic store for later passing to a formatting + function. ``std::reference_wrapper`` is supported to avoid copying of the + argument. + */ + template + void push_back(const detail::named_arg& arg) { + const char_type* arg_name = + dynamic_args_.push>(arg.name).c_str(); + if (detail::const_check(need_copy::value)) { + emplace_arg( + fmt::arg(arg_name, dynamic_args_.push>(arg.value))); + } else { + emplace_arg(fmt::arg(arg_name, arg.value)); + } + } + + /** Erase all elements from the store */ + void clear() { + data_.clear(); + named_info_.clear(); + dynamic_args_ = detail::dynamic_arg_list(); + } + + /** + \rst + Reserves space to store at least *new_cap* arguments including + *new_cap_named* named arguments. + \endrst + */ + void reserve(size_t new_cap, size_t new_cap_named) { + FMT_ASSERT(new_cap >= new_cap_named, + "Set of arguments includes set of named arguments"); + data_.reserve(new_cap); + named_info_.reserve(new_cap_named); + } +}; + +/** + \rst + A view of a collection of formatting arguments. To avoid lifetime issues it + should only be used as a parameter type in type-erased functions such as + ``vformat``:: + + void vlog(string_view format_str, format_args args); // OK + format_args args = make_format_args(42); // Error: dangling reference + \endrst + */ template class basic_format_args { public: using size_type = int; using format_arg = basic_format_arg; private: - // To reduce compiled code size per formatting function call, types of first - // max_packed_args arguments are passed in the types_ field. - unsigned long long types_; + // A descriptor that contains information about formatting arguments. + // If the number of arguments is less or equal to max_packed_args then + // argument types are passed in the descriptor. This reduces binary code size + // per formatting function call. + unsigned long long desc_; union { - // If the number of arguments is less than max_packed_args, the argument - // values are stored in values_, otherwise they are stored in args_. - // This is done to reduce compiled code size as storing larger objects + // If is_packed() returns true then argument values are stored in values_; + // otherwise they are stored in args_. This is done to improve cache + // locality and reduce compiled code size since storing larger objects // may require more code (at least on x86-64) even if the same amount of // data is actually copied to stack. It saves ~10% on the bloat test. - const internal::value* values_; + const detail::value* values_; const format_arg* args_; }; - bool is_packed() const { return (types_ & internal::is_unpacked_bit) == 0; } - - internal::type type(int index) const { - int shift = index * internal::packed_arg_bits; - unsigned int mask = (1 << internal::packed_arg_bits) - 1; - return static_cast((types_ >> shift) & mask); + bool is_packed() const { return (desc_ & detail::is_unpacked_bit) == 0; } + bool has_named_args() const { + return (desc_ & detail::has_named_args_bit) != 0; } - friend class internal::arg_map; - - void set_data(const internal::value* values) { values_ = values; } - void set_data(const format_arg* args) { args_ = args; } - - format_arg do_get(int index) const { - format_arg arg; - if (!is_packed()) { - auto num_args = max_size(); - if (index < num_args) arg = args_[index]; - return arg; - } - if (index > internal::max_packed_args) return arg; - arg.type_ = type(index); - if (arg.type_ == internal::none_type) return arg; - internal::value& val = arg.value_; - val = values_[index]; - return arg; + detail::type type(int index) const { + int shift = index * detail::packed_arg_bits; + unsigned int mask = (1 << detail::packed_arg_bits) - 1; + return static_cast((desc_ >> shift) & mask); } + basic_format_args(unsigned long long desc, + const detail::value* values) + : desc_(desc), values_(values) {} + basic_format_args(unsigned long long desc, const format_arg* args) + : desc_(desc), args_(args) {} + public: - basic_format_args() : types_(0) {} + basic_format_args() : desc_(0) {} /** \rst @@ -1284,10 +1872,17 @@ template class basic_format_args { \endrst */ template - basic_format_args(const format_arg_store& store) - : types_(store.types) { - set_data(store.data_); - } + FMT_INLINE basic_format_args(const format_arg_store& store) + : basic_format_args(store.desc, store.data_.args()) {} + + /** + \rst + Constructs a `basic_format_args` object from + `~fmt::dynamic_format_arg_store`. + \endrst + */ + FMT_INLINE basic_format_args(const dynamic_format_arg_store& store) + : basic_format_args(store.get_types(), store.data()) {} /** \rst @@ -1295,168 +1890,172 @@ template class basic_format_args { \endrst */ basic_format_args(const format_arg* args, int count) - : types_(internal::is_unpacked_bit | internal::to_unsigned(count)) { - set_data(args); - } + : basic_format_args(detail::is_unpacked_bit | detail::to_unsigned(count), + args) {} - /** Returns the argument at specified index. */ - format_arg get(int index) const { - format_arg arg = do_get(index); - if (arg.type_ == internal::named_arg_type) - arg = arg.value_.named_arg->template deserialize(); + /** Returns the argument with the specified id. */ + format_arg get(int id) const { + format_arg arg; + if (!is_packed()) { + if (id < max_size()) arg = args_[id]; + return arg; + } + if (id >= detail::max_packed_args) return arg; + arg.type_ = type(id); + if (arg.type_ == detail::type::none_type) return arg; + arg.value_ = values_[id]; return arg; } + template format_arg get(basic_string_view name) const { + int id = get_id(name); + return id >= 0 ? get(id) : format_arg(); + } + + template int get_id(basic_string_view name) const { + if (!has_named_args()) return -1; + const auto& named_args = + (is_packed() ? values_[-1] : args_[-1].value_).named_args; + for (size_t i = 0; i < named_args.size; ++i) { + if (named_args.data[i].name == name) return named_args.data[i].id; + } + return -1; + } + int max_size() const { - unsigned long long max_packed = internal::max_packed_args; + unsigned long long max_packed = detail::max_packed_args; return static_cast(is_packed() ? max_packed - : types_ & ~internal::is_unpacked_bit); + : desc_ & ~detail::is_unpacked_bit); } }; -/** An alias to ``basic_format_args``. */ +#ifdef FMT_ARM_ABI_COMPATIBILITY +/** An alias to ``basic_format_args``. */ +// Separate types would result in shorter symbols but break ABI compatibility +// between clang and gcc on ARM (#1919). +using format_args = basic_format_args; +using wformat_args = basic_format_args; +#else +// DEPRECATED! These are kept for ABI compatibility. // It is a separate type rather than an alias to make symbols readable. struct format_args : basic_format_args { template - format_args(Args&&... args) - : basic_format_args(std::forward(args)...) {} + FMT_INLINE format_args(const Args&... args) : basic_format_args(args...) {} }; struct wformat_args : basic_format_args { - template - wformat_args(Args&&... args) - : basic_format_args(std::forward(args)...) {} + using basic_format_args::basic_format_args; }; +#endif -template struct is_contiguous : std::false_type {}; - -template -struct is_contiguous> : std::true_type {}; - -template -struct is_contiguous> : std::true_type {}; - -namespace internal { - -template -struct is_contiguous_back_insert_iterator : std::false_type {}; -template -struct is_contiguous_back_insert_iterator> - : is_contiguous {}; - -template struct named_arg_base { - basic_string_view name; +namespace detail { - // Serialized value. - mutable char data[sizeof(basic_format_arg>)]; +template ::value)> +std::basic_string vformat( + basic_string_view format_str, + basic_format_args>> args); - named_arg_base(basic_string_view nm) : name(nm) {} +FMT_API std::string vformat(string_view format_str, format_args args); - template basic_format_arg deserialize() const { - basic_format_arg arg; - std::memcpy(&arg, data, sizeof(basic_format_arg)); - return arg; - } -}; +template +void vformat_to( + buffer& buf, basic_string_view format_str, + basic_format_args)> args, + detail::locale_ref loc = {}); -template struct named_arg : named_arg_base { - const T& value; +template ::value)> +inline void vprint_mojibake(std::FILE*, basic_string_view, const Args&) {} - named_arg(basic_string_view name, const T& val) - : named_arg_base(name), value(val) {} -}; - -template ::value)> -inline void check_format_string(const S&) { -#if defined(FMT_ENFORCE_COMPILE_STRING) - static_assert(is_compile_string::value, - "FMT_ENFORCE_COMPILE_STRING requires all format strings to " - "utilize FMT_STRING() or fmt()."); +FMT_API void vprint_mojibake(std::FILE*, string_view, format_args); +#ifndef _WIN32 +inline void vprint_mojibake(std::FILE*, string_view, format_args) {} #endif -} -template ::value)> -void check_format_string(S); +} // namespace detail -struct view {}; -template struct bool_pack; -template -using all_true = - std::is_same, bool_pack>; - -template > -inline format_arg_store, remove_reference_t...> -make_args_checked(const S& format_str, - const remove_reference_t&... args) { - static_assert(all_true<(!std::is_base_of>() || - !std::is_reference())...>::value, - "passing views as lvalues is disallowed"); - check_format_string>...>(format_str); - return {args...}; +/** Formats a string and writes the output to ``out``. */ +// GCC 8 and earlier cannot handle std::back_insert_iterator with +// vformat_to(...) overload, so SFINAE on iterator type instead. +template , + bool enable = detail::is_output_iterator::value> +auto vformat_to(OutputIt out, const S& format_str, + basic_format_args>> args) + -> typename std::enable_if::type { + decltype(detail::get_buffer(out)) buf(detail::get_buffer_init(out)); + detail::vformat_to(buf, to_string_view(format_str), args); + return detail::get_iterator(buf); } -template -std::basic_string vformat(basic_string_view format_str, - basic_format_args> args); - -template -typename buffer_context::iterator vformat_to( - buffer& buf, basic_string_view format_str, - basic_format_args> args); -} // namespace internal - /** - \rst - Returns a named argument to be used in a formatting function. + \rst + Formats arguments, writes the result to the output iterator ``out`` and returns + the iterator past the end of the output range. - The named argument holds a reference and does not extend the lifetime - of its arguments. - Consequently, a dangling reference can accidentally be created. - The user should take care to only pass this function temporaries when - the named argument is itself a temporary, as per the following example. + **Example**:: - **Example**:: - - fmt::print("Elapsed time: {s:.2f} seconds", fmt::arg("s", 1.23)); - \endrst + std::vector out; + fmt::format_to(std::back_inserter(out), "{}", 42); + \endrst */ -template > -inline internal::named_arg arg(const S& name, const T& arg) { - static_assert(internal::is_string::value, ""); - return {name, arg}; +// We cannot use FMT_ENABLE_IF because of a bug in gcc 8.3. +template >::value> +inline auto format_to(OutputIt out, const S& format_str, Args&&... args) -> + typename std::enable_if::type { + const auto& vargs = fmt::make_args_checked(format_str, args...); + return vformat_to(out, to_string_view(format_str), vargs); } -// Disable nested named arguments, e.g. ``arg("a", arg("b", 42))``. -template -void arg(S, internal::named_arg) = delete; +template struct format_to_n_result { + /** Iterator past the end of the output range. */ + OutputIt out; + /** Total (not truncated) output size. */ + size_t size; +}; + +template ::value)> +inline format_to_n_result vformat_to_n( + OutputIt out, size_t n, basic_string_view format_str, + basic_format_args>> args) { + detail::iterator_buffer buf(out, + n); + detail::vformat_to(buf, format_str, args); + return {buf.out(), buf.count()}; +} -/** Formats a string and writes the output to ``out``. */ -// GCC 8 and earlier cannot handle std::back_insert_iterator with -// vformat_to(...) overload, so SFINAE on iterator type instead. -template , - FMT_ENABLE_IF( - internal::is_contiguous_back_insert_iterator::value)> -OutputIt vformat_to(OutputIt out, const S& format_str, - basic_format_args> args) { - using container = remove_reference_t; - internal::container_buffer buf((internal::get_container(out))); - internal::vformat_to(buf, to_string_view(format_str), args); - return out; +/** + \rst + Formats arguments, writes up to ``n`` characters of the result to the output + iterator ``out`` and returns the total output size and the iterator past the + end of the output range. + \endrst + */ +template >::value> +inline auto format_to_n(OutputIt out, size_t n, const S& format_str, + const Args&... args) -> + typename std::enable_if>::type { + const auto& vargs = fmt::make_args_checked(format_str, args...); + return vformat_to_n(out, n, to_string_view(format_str), vargs); } -template ::value&& internal::is_string::value)> -inline std::back_insert_iterator format_to( - std::back_insert_iterator out, const S& format_str, - Args&&... args) { - return vformat_to( - out, to_string_view(format_str), - {internal::make_args_checked(format_str, args...)}); +/** + Returns the number of characters in the output of + ``format(format_str, args...)``. + */ +template +inline size_t formatted_size(string_view format_str, Args&&... args) { + const auto& vargs = fmt::make_args_checked(format_str, args...); + detail::counting_buffer<> buf; + detail::vformat_to(buf, format_str, vargs); + return buf.count(); } template > -inline std::basic_string vformat( - const S& format_str, basic_format_args> args) { - return internal::vformat(to_string_view(format_str), args); +FMT_INLINE std::basic_string vformat( + const S& format_str, + basic_format_args>> args) { + return detail::vformat(to_string_view(format_str), args); } /** @@ -1472,47 +2071,51 @@ inline std::basic_string vformat( // Pass char_t as a default template parameter instead of using // std::basic_string> to reduce the symbol size. template > -inline std::basic_string format(const S& format_str, Args&&... args) { - return internal::vformat( - to_string_view(format_str), - {internal::make_args_checked(format_str, args...)}); +FMT_INLINE std::basic_string format(const S& format_str, Args&&... args) { + const auto& vargs = fmt::make_args_checked(format_str, args...); + return detail::vformat(to_string_view(format_str), vargs); } -FMT_API void vprint(std::FILE* f, string_view format_str, format_args args); -FMT_API void vprint(string_view format_str, format_args args); +FMT_API void vprint(string_view, format_args); +FMT_API void vprint(std::FILE*, string_view, format_args); /** \rst - Prints formatted data to the file *f*. For wide format strings, - *f* should be in wide-oriented mode set via ``fwide(f, 1)`` or - ``_setmode(_fileno(f), _O_U8TEXT)`` on Windows. + Formats ``args`` according to specifications in ``format_str`` and writes the + output to the file ``f``. Strings are assumed to be Unicode-encoded unless the + ``FMT_UNICODE`` macro is set to 0. **Example**:: fmt::print(stderr, "Don't {}!", "panic"); \endrst */ -template ::value)> +template > inline void print(std::FILE* f, const S& format_str, Args&&... args) { - vprint(f, to_string_view(format_str), - internal::make_args_checked(format_str, args...)); + const auto& vargs = fmt::make_args_checked(format_str, args...); + return detail::is_unicode() + ? vprint(f, to_string_view(format_str), vargs) + : detail::vprint_mojibake(f, to_string_view(format_str), vargs); } /** \rst - Prints formatted data to ``stdout``. + Formats ``args`` according to specifications in ``format_str`` and writes + the output to ``stdout``. Strings are assumed to be Unicode-encoded unless + the ``FMT_UNICODE`` macro is set to 0. **Example**:: fmt::print("Elapsed time: {0:.2f} seconds", 1.23); \endrst */ -template ::value)> +template > inline void print(const S& format_str, Args&&... args) { - vprint(to_string_view(format_str), - internal::make_args_checked(format_str, args...)); + const auto& vargs = fmt::make_args_checked(format_str, args...); + return detail::is_unicode() + ? vprint(to_string_view(format_str), vargs) + : detail::vprint_mojibake(stdout, to_string_view(format_str), + vargs); } FMT_END_NAMESPACE diff --git a/src/3rd-part/fmt/include/fmt/format-inl.h b/src/3rd-part/fmt/include/fmt/format-inl.h index fbda002..8f2fe73 100644 --- a/src/3rd-part/fmt/include/fmt/format-inl.h +++ b/src/3rd-part/fmt/include/fmt/format-inl.h @@ -8,56 +8,40 @@ #ifndef FMT_FORMAT_INL_H_ #define FMT_FORMAT_INL_H_ -#include "format.h" - #include #include #include #include #include -#include // for std::memmove +#include // std::memmove #include -#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) -# include -#endif +#include -#if FMT_USE_WINDOWS_H -# if !defined(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN) -# define WIN32_LEAN_AND_MEAN -# endif -# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX) -# include -# else -# define NOMINMAX -# include -# undef NOMINMAX -# endif +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR +# include #endif -#if FMT_EXCEPTIONS -# define FMT_TRY try -# define FMT_CATCH(x) catch (x) -#else -# define FMT_TRY if (true) -# define FMT_CATCH(x) if (false) +#ifdef _WIN32 +# include // _isatty #endif -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4702) // unreachable code -#endif +#include "format.h" // Dummy implementations of strerror_r and strerror_s called if corresponding // system functions are not available. -inline fmt::internal::null<> strerror_r(int, char*, ...) { return {}; } -inline fmt::internal::null<> strerror_s(char*, std::size_t, ...) { return {}; } +inline fmt::detail::null<> strerror_r(int, char*, ...) { return {}; } +inline fmt::detail::null<> strerror_s(char*, size_t, ...) { return {}; } FMT_BEGIN_NAMESPACE -namespace internal { +namespace detail { FMT_FUNC void assert_fail(const char* file, int line, const char* message) { - print(stderr, "{}:{}: assertion failed: {}", file, line, message); - std::abort(); + // Use unchecked std::fprintf to avoid triggering another assertion when + // writing to stderr fails + std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message); + // Chosen instead of std::abort to satisfy Clang in CUDA mode during device + // code pass. + std::terminate(); } #ifndef _MSC_VER @@ -73,8 +57,6 @@ inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { # define FMT_SNPRINTF fmt_snprintf #endif // _MSC_VER -using format_func = void (*)(internal::buffer&, int, string_view); - // A portable thread-safe version of strerror. // Sets buffer to point to a string describing the error code. // This can be either a pointer to a string stored in buffer, @@ -84,15 +66,15 @@ using format_func = void (*)(internal::buffer&, int, string_view); // ERANGE - buffer is not large enough to store the error message // other - failure // Buffer should be at least of size 1. -FMT_FUNC int safe_strerror(int error_code, char*& buffer, - std::size_t buffer_size) FMT_NOEXCEPT { +inline int safe_strerror(int error_code, char*& buffer, + size_t buffer_size) FMT_NOEXCEPT { FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer"); class dispatcher { private: int error_code_; char*& buffer_; - std::size_t buffer_size_; + size_t buffer_size_; // A noop assignment operator to avoid bogus warnings. void operator=(const dispatcher&) {} @@ -104,6 +86,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer, } // Handle the result of GNU-specific version of strerror_r. + FMT_MAYBE_UNUSED int handle(char* message) { // If the buffer is full then the message is probably truncated. if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1) @@ -113,11 +96,13 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer, } // Handle the case when strerror_r is not available. - int handle(internal::null<>) { + FMT_MAYBE_UNUSED + int handle(detail::null<>) { return fallback(strerror_s(buffer_, buffer_size_, error_code_)); } // Fallback to strerror_s when strerror_r is not available. + FMT_MAYBE_UNUSED int fallback(int result) { // If the buffer is full then the message is probably truncated. return result == 0 && strlen(buffer_) == buffer_size_ - 1 ? ERANGE @@ -126,7 +111,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer, #if !FMT_MSC_VER // Fallback to strerror if strerror_r and strerror_s are not available. - int fallback(internal::null<>) { + int fallback(detail::null<>) { errno = 0; buffer_ = strerror(error_code_); return errno; @@ -134,7 +119,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer, #endif public: - dispatcher(int err_code, char*& buf, std::size_t buf_size) + dispatcher(int err_code, char*& buf, size_t buf_size) : error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {} int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); } @@ -142,41 +127,29 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer, return dispatcher(error_code, buffer, buffer_size).run(); } -FMT_FUNC void format_error_code(internal::buffer& out, int error_code, +FMT_FUNC void format_error_code(detail::buffer& out, int error_code, string_view message) FMT_NOEXCEPT { // Report error code making sure that the output fits into // inline_buffer_size to avoid dynamic memory allocation and potential // bad_alloc. - out.resize(0); + out.try_resize(0); static const char SEP[] = ": "; static const char ERROR_STR[] = "error "; // Subtract 2 to account for terminating null characters in SEP and ERROR_STR. - std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; + size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2; auto abs_value = static_cast>(error_code); - if (internal::is_negative(error_code)) { + if (detail::is_negative(error_code)) { abs_value = 0 - abs_value; ++error_code_size; } - error_code_size += internal::to_unsigned(internal::count_digits(abs_value)); - internal::writer w(out); - if (message.size() <= inline_buffer_size - error_code_size) { - w.write(message); - w.write(SEP); - } - w.write(ERROR_STR); - w.write(error_code); + error_code_size += detail::to_unsigned(detail::count_digits(abs_value)); + auto it = buffer_appender(out); + if (message.size() <= inline_buffer_size - error_code_size) + format_to(it, "{}{}", message, SEP); + format_to(it, "{}{}", ERROR_STR, error_code); assert(out.size() <= inline_buffer_size); } -// A wrapper around fwrite that throws on error. -FMT_FUNC void fwrite_fully(const void* ptr, size_t size, size_t count, - FILE* stream) { - size_t written = std::fwrite(ptr, size, count, stream); - if (written < count) { - FMT_THROW(system_error(errno, "cannot write to file")); - } -} - FMT_FUNC void report_error(format_func func, int error_code, string_view message) FMT_NOEXCEPT { memory_buffer full_message; @@ -185,10 +158,17 @@ FMT_FUNC void report_error(format_func func, int error_code, (void)std::fwrite(full_message.data(), full_message.size(), 1, stderr); std::fputc('\n', stderr); } -} // namespace internal + +// A wrapper around fwrite that throws on error. +inline void fwrite_fully(const void* ptr, size_t size, size_t count, + FILE* stream) { + size_t written = std::fwrite(ptr, size, count, stream); + if (written < count) FMT_THROW(system_error(errno, "cannot write to file")); +} +} // namespace detail #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) -namespace internal { +namespace detail { template locale_ref::locale_ref(const Locale& loc) : locale_(&loc) { @@ -211,18 +191,16 @@ template FMT_FUNC Char decimal_point_impl(locale_ref loc) { return std::use_facet>(loc.get()) .decimal_point(); } -} // namespace internal +} // namespace detail #else template -FMT_FUNC std::string internal::grouping_impl(locale_ref) { +FMT_FUNC std::string detail::grouping_impl(locale_ref) { return "\03"; } -template -FMT_FUNC Char internal::thousands_sep_impl(locale_ref) { +template FMT_FUNC Char detail::thousands_sep_impl(locale_ref) { return FMT_STATIC_THOUSANDS_SEPARATOR; } -template -FMT_FUNC Char internal::decimal_point_impl(locale_ref) { +template FMT_FUNC Char detail::decimal_point_impl(locale_ref) { return '.'; } #endif @@ -239,9 +217,9 @@ FMT_FUNC void system_error::init(int err_code, string_view format_str, base = std::runtime_error(to_string(buffer)); } -namespace internal { +namespace detail { -template <> FMT_FUNC int count_digits<4>(internal::fallback_uintptr n) { +template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { // fallback_uintptr is always stored in little endian. int i = static_cast(sizeof(void*)) - 1; while (i > 0 && n.value[i] == 0) --i; @@ -250,12 +228,24 @@ template <> FMT_FUNC int count_digits<4>(internal::fallback_uintptr n) { } template -const char basic_data::digits[] = - "0001020304050607080910111213141516171819" - "2021222324252627282930313233343536373839" - "4041424344454647484950515253545556575859" - "6061626364656667686970717273747576777879" - "8081828384858687888990919293949596979899"; +const typename basic_data::digit_pair basic_data::digits[] = { + {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, + {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, + {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, + {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, + {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, + {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'}, + {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, + {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, + {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, + {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, + {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'}, + {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'}, + {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'}, + {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, + {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, + {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, + {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; template const char basic_data::hex_digits[] = "0123456789abcdef"; @@ -273,16 +263,24 @@ const uint64_t basic_data::powers_of_10_64[] = { template const uint32_t basic_data::zero_or_powers_of_10_32[] = {0, FMT_POWERS_OF_10(1)}; - template const uint64_t basic_data::zero_or_powers_of_10_64[] = { 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL), 10000000000000000000ULL}; +template +const uint32_t basic_data::zero_or_powers_of_10_32_new[] = { + 0, 0, FMT_POWERS_OF_10(1)}; + +template +const uint64_t basic_data::zero_or_powers_of_10_64_new[] = { + 0, 0, FMT_POWERS_OF_10(1), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; + // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. // These are generated by support/compute-powers.py. template -const uint64_t basic_data::pow10_significands[] = { +const uint64_t basic_data::grisu_pow10_significands[] = { 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, @@ -317,7 +315,7 @@ const uint64_t basic_data::pow10_significands[] = { // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding // to significands above. template -const int16_t basic_data::pow10_exponents[] = { +const int16_t basic_data::grisu_pow10_exponents[] = { -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, @@ -327,6 +325,744 @@ const int16_t basic_data::pow10_exponents[] = { 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}; +template +const divtest_table_entry basic_data::divtest_table_for_pow5_32[] = + {{0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333}, + {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba}, + {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5}, + {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf}, + {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897}, + {0x3ed61f49, 0x000001b7}}; + +template +const divtest_table_entry basic_data::divtest_table_for_pow5_64[] = + {{0x0000000000000001, 0xffffffffffffffff}, + {0xcccccccccccccccd, 0x3333333333333333}, + {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70}, + {0x1cac083126e978d5, 0x020c49ba5e353f7c}, + {0xd288ce703afb7e91, 0x0068db8bac710cb2}, + {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0}, + {0x790fb65668c26139, 0x000431bde82d7b63}, + {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a}, + {0xc767074b22e90e21, 0x00002af31dc46118}, + {0x8e47ce423a2e9c6d, 0x0000089705f4136b}, + {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b}, + {0x0fee64690c913975, 0x00000057f5ff85e5}, + {0x3662e0e1cf503eb1, 0x000000119799812d}, + {0xa47a2cf9f6433fbd, 0x0000000384b84d09}, + {0x54186f653140a659, 0x00000000b424dc35}, + {0x7738164770402145, 0x0000000024075f3d}, + {0xe4a4d1417cd9a041, 0x000000000734aca5}, + {0xc75429d9e5c5200d, 0x000000000170ef54}, + {0xc1773b91fac10669, 0x000000000049c977}, + {0x26b172506559ce15, 0x00000000000ec1e4}, + {0xd489e3a9addec2d1, 0x000000000002f394}, + {0x90e860bb892c8d5d, 0x000000000000971d}, + {0x502e79bf1b6f4f79, 0x0000000000001e39}, + {0xdcd618596be30fe5, 0x000000000000060b}}; + +template +const uint64_t basic_data::dragonbox_pow10_significands_64[] = { + 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, + 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, + 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, + 0xf1c90080baf72cb2, 0x971da05074da7bef, 0xbce5086492111aeb, + 0xec1e4a7db69561a6, 0x9392ee8e921d5d08, 0xb877aa3236a4b44a, + 0xe69594bec44de15c, 0x901d7cf73ab0acda, 0xb424dc35095cd810, + 0xe12e13424bb40e14, 0x8cbccc096f5088cc, 0xafebff0bcb24aaff, + 0xdbe6fecebdedd5bf, 0x89705f4136b4a598, 0xabcc77118461cefd, + 0xd6bf94d5e57a42bd, 0x8637bd05af6c69b6, 0xa7c5ac471b478424, + 0xd1b71758e219652c, 0x83126e978d4fdf3c, 0xa3d70a3d70a3d70b, + 0xcccccccccccccccd, 0x8000000000000000, 0xa000000000000000, + 0xc800000000000000, 0xfa00000000000000, 0x9c40000000000000, + 0xc350000000000000, 0xf424000000000000, 0x9896800000000000, + 0xbebc200000000000, 0xee6b280000000000, 0x9502f90000000000, + 0xba43b74000000000, 0xe8d4a51000000000, 0x9184e72a00000000, + 0xb5e620f480000000, 0xe35fa931a0000000, 0x8e1bc9bf04000000, + 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, + 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, + 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, + 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, + 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296, + 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6, + 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, + 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, + 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719, + 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e}; + +template +const uint128_wrapper basic_data::dragonbox_pow10_significands_128[] = { +#if FMT_USE_FULL_CACHE_DRAGONBOX + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0x9faacf3df73609b1, 0x77b191618c54e9ad}, + {0xc795830d75038c1d, 0xd59df5b9ef6a2418}, + {0xf97ae3d0d2446f25, 0x4b0573286b44ad1e}, + {0x9becce62836ac577, 0x4ee367f9430aec33}, + {0xc2e801fb244576d5, 0x229c41f793cda740}, + {0xf3a20279ed56d48a, 0x6b43527578c11110}, + {0x9845418c345644d6, 0x830a13896b78aaaa}, + {0xbe5691ef416bd60c, 0x23cc986bc656d554}, + {0xedec366b11c6cb8f, 0x2cbfbe86b7ec8aa9}, + {0x94b3a202eb1c3f39, 0x7bf7d71432f3d6aa}, + {0xb9e08a83a5e34f07, 0xdaf5ccd93fb0cc54}, + {0xe858ad248f5c22c9, 0xd1b3400f8f9cff69}, + {0x91376c36d99995be, 0x23100809b9c21fa2}, + {0xb58547448ffffb2d, 0xabd40a0c2832a78b}, + {0xe2e69915b3fff9f9, 0x16c90c8f323f516d}, + {0x8dd01fad907ffc3b, 0xae3da7d97f6792e4}, + {0xb1442798f49ffb4a, 0x99cd11cfdf41779d}, + {0xdd95317f31c7fa1d, 0x40405643d711d584}, + {0x8a7d3eef7f1cfc52, 0x482835ea666b2573}, + {0xad1c8eab5ee43b66, 0xda3243650005eed0}, + {0xd863b256369d4a40, 0x90bed43e40076a83}, + {0x873e4f75e2224e68, 0x5a7744a6e804a292}, + {0xa90de3535aaae202, 0x711515d0a205cb37}, + {0xd3515c2831559a83, 0x0d5a5b44ca873e04}, + {0x8412d9991ed58091, 0xe858790afe9486c3}, + {0xa5178fff668ae0b6, 0x626e974dbe39a873}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0x80fa687f881c7f8e, 0x7ce66634bc9d0b9a}, + {0xa139029f6a239f72, 0x1c1fffc1ebc44e81}, + {0xc987434744ac874e, 0xa327ffb266b56221}, + {0xfbe9141915d7a922, 0x4bf1ff9f0062baa9}, + {0x9d71ac8fada6c9b5, 0x6f773fc3603db4aa}, + {0xc4ce17b399107c22, 0xcb550fb4384d21d4}, + {0xf6019da07f549b2b, 0x7e2a53a146606a49}, + {0x99c102844f94e0fb, 0x2eda7444cbfc426e}, + {0xc0314325637a1939, 0xfa911155fefb5309}, + {0xf03d93eebc589f88, 0x793555ab7eba27cb}, + {0x96267c7535b763b5, 0x4bc1558b2f3458df}, + {0xbbb01b9283253ca2, 0x9eb1aaedfb016f17}, + {0xea9c227723ee8bcb, 0x465e15a979c1cadd}, + {0x92a1958a7675175f, 0x0bfacd89ec191eca}, + {0xb749faed14125d36, 0xcef980ec671f667c}, + {0xe51c79a85916f484, 0x82b7e12780e7401b}, + {0x8f31cc0937ae58d2, 0xd1b2ecb8b0908811}, + {0xb2fe3f0b8599ef07, 0x861fa7e6dcb4aa16}, + {0xdfbdcece67006ac9, 0x67a791e093e1d49b}, + {0x8bd6a141006042bd, 0xe0c8bb2c5c6d24e1}, + {0xaecc49914078536d, 0x58fae9f773886e19}, + {0xda7f5bf590966848, 0xaf39a475506a899f}, + {0x888f99797a5e012d, 0x6d8406c952429604}, + {0xaab37fd7d8f58178, 0xc8e5087ba6d33b84}, + {0xd5605fcdcf32e1d6, 0xfb1e4a9a90880a65}, + {0x855c3be0a17fcd26, 0x5cf2eea09a550680}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0xd0601d8efc57b08b, 0xf13b94daf124da27}, + {0x823c12795db6ce57, 0x76c53d08d6b70859}, + {0xa2cb1717b52481ed, 0x54768c4b0c64ca6f}, + {0xcb7ddcdda26da268, 0xa9942f5dcf7dfd0a}, + {0xfe5d54150b090b02, 0xd3f93b35435d7c4d}, + {0x9efa548d26e5a6e1, 0xc47bc5014a1a6db0}, + {0xc6b8e9b0709f109a, 0x359ab6419ca1091c}, + {0xf867241c8cc6d4c0, 0xc30163d203c94b63}, + {0x9b407691d7fc44f8, 0x79e0de63425dcf1e}, + {0xc21094364dfb5636, 0x985915fc12f542e5}, + {0xf294b943e17a2bc4, 0x3e6f5b7b17b2939e}, + {0x979cf3ca6cec5b5a, 0xa705992ceecf9c43}, + {0xbd8430bd08277231, 0x50c6ff782a838354}, + {0xece53cec4a314ebd, 0xa4f8bf5635246429}, + {0x940f4613ae5ed136, 0x871b7795e136be9a}, + {0xb913179899f68584, 0x28e2557b59846e40}, + {0xe757dd7ec07426e5, 0x331aeada2fe589d0}, + {0x9096ea6f3848984f, 0x3ff0d2c85def7622}, + {0xb4bca50b065abe63, 0x0fed077a756b53aa}, + {0xe1ebce4dc7f16dfb, 0xd3e8495912c62895}, + {0x8d3360f09cf6e4bd, 0x64712dd7abbbd95d}, + {0xb080392cc4349dec, 0xbd8d794d96aacfb4}, + {0xdca04777f541c567, 0xecf0d7a0fc5583a1}, + {0x89e42caaf9491b60, 0xf41686c49db57245}, + {0xac5d37d5b79b6239, 0x311c2875c522ced6}, + {0xd77485cb25823ac7, 0x7d633293366b828c}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xa8530886b54dbdeb, 0xd9f57f830283fdfd}, + {0xd267caa862a12d66, 0xd072df63c324fd7c}, + {0x8380dea93da4bc60, 0x4247cb9e59f71e6e}, + {0xa46116538d0deb78, 0x52d9be85f074e609}, + {0xcd795be870516656, 0x67902e276c921f8c}, + {0x806bd9714632dff6, 0x00ba1cd8a3db53b7}, + {0xa086cfcd97bf97f3, 0x80e8a40eccd228a5}, + {0xc8a883c0fdaf7df0, 0x6122cd128006b2ce}, + {0xfad2a4b13d1b5d6c, 0x796b805720085f82}, + {0x9cc3a6eec6311a63, 0xcbe3303674053bb1}, + {0xc3f490aa77bd60fc, 0xbedbfc4411068a9d}, + {0xf4f1b4d515acb93b, 0xee92fb5515482d45}, + {0x991711052d8bf3c5, 0x751bdd152d4d1c4b}, + {0xbf5cd54678eef0b6, 0xd262d45a78a0635e}, + {0xef340a98172aace4, 0x86fb897116c87c35}, + {0x9580869f0e7aac0e, 0xd45d35e6ae3d4da1}, + {0xbae0a846d2195712, 0x8974836059cca10a}, + {0xe998d258869facd7, 0x2bd1a438703fc94c}, + {0x91ff83775423cc06, 0x7b6306a34627ddd0}, + {0xb67f6455292cbf08, 0x1a3bc84c17b1d543}, + {0xe41f3d6a7377eeca, 0x20caba5f1d9e4a94}, + {0x8e938662882af53e, 0x547eb47b7282ee9d}, + {0xb23867fb2a35b28d, 0xe99e619a4f23aa44}, + {0xdec681f9f4c31f31, 0x6405fa00e2ec94d5}, + {0x8b3c113c38f9f37e, 0xde83bc408dd3dd05}, + {0xae0b158b4738705e, 0x9624ab50b148d446}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0x87f8a8d4cfa417c9, 0xe54ca5d70a80e5d7}, + {0xa9f6d30a038d1dbc, 0x5e9fcf4ccd211f4d}, + {0xd47487cc8470652b, 0x7647c32000696720}, + {0x84c8d4dfd2c63f3b, 0x29ecd9f40041e074}, + {0xa5fb0a17c777cf09, 0xf468107100525891}, + {0xcf79cc9db955c2cc, 0x7182148d4066eeb5}, + {0x81ac1fe293d599bf, 0xc6f14cd848405531}, + {0xa21727db38cb002f, 0xb8ada00e5a506a7d}, + {0xca9cf1d206fdc03b, 0xa6d90811f0e4851d}, + {0xfd442e4688bd304a, 0x908f4a166d1da664}, + {0x9e4a9cec15763e2e, 0x9a598e4e043287ff}, + {0xc5dd44271ad3cdba, 0x40eff1e1853f29fe}, + {0xf7549530e188c128, 0xd12bee59e68ef47d}, + {0x9a94dd3e8cf578b9, 0x82bb74f8301958cf}, + {0xc13a148e3032d6e7, 0xe36a52363c1faf02}, + {0xf18899b1bc3f8ca1, 0xdc44e6c3cb279ac2}, + {0x96f5600f15a7b7e5, 0x29ab103a5ef8c0ba}, + {0xbcb2b812db11a5de, 0x7415d448f6b6f0e8}, + {0xebdf661791d60f56, 0x111b495b3464ad22}, + {0x936b9fcebb25c995, 0xcab10dd900beec35}, + {0xb84687c269ef3bfb, 0x3d5d514f40eea743}, + {0xe65829b3046b0afa, 0x0cb4a5a3112a5113}, + {0x8ff71a0fe2c2e6dc, 0x47f0e785eaba72ac}, + {0xb3f4e093db73a093, 0x59ed216765690f57}, + {0xe0f218b8d25088b8, 0x306869c13ec3532d}, + {0x8c974f7383725573, 0x1e414218c73a13fc}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0xdbac6c247d62a583, 0xdf45f746b74abf3a}, + {0x894bc396ce5da772, 0x6b8bba8c328eb784}, + {0xab9eb47c81f5114f, 0x066ea92f3f326565}, + {0xd686619ba27255a2, 0xc80a537b0efefebe}, + {0x8613fd0145877585, 0xbd06742ce95f5f37}, + {0xa798fc4196e952e7, 0x2c48113823b73705}, + {0xd17f3b51fca3a7a0, 0xf75a15862ca504c6}, + {0x82ef85133de648c4, 0x9a984d73dbe722fc}, + {0xa3ab66580d5fdaf5, 0xc13e60d0d2e0ebbb}, + {0xcc963fee10b7d1b3, 0x318df905079926a9}, + {0xffbbcfe994e5c61f, 0xfdf17746497f7053}, + {0x9fd561f1fd0f9bd3, 0xfeb6ea8bedefa634}, + {0xc7caba6e7c5382c8, 0xfe64a52ee96b8fc1}, + {0xf9bd690a1b68637b, 0x3dfdce7aa3c673b1}, + {0x9c1661a651213e2d, 0x06bea10ca65c084f}, + {0xc31bfa0fe5698db8, 0x486e494fcff30a63}, + {0xf3e2f893dec3f126, 0x5a89dba3c3efccfb}, + {0x986ddb5c6b3a76b7, 0xf89629465a75e01d}, + {0xbe89523386091465, 0xf6bbb397f1135824}, + {0xee2ba6c0678b597f, 0x746aa07ded582e2d}, + {0x94db483840b717ef, 0xa8c2a44eb4571cdd}, + {0xba121a4650e4ddeb, 0x92f34d62616ce414}, + {0xe896a0d7e51e1566, 0x77b020baf9c81d18}, + {0x915e2486ef32cd60, 0x0ace1474dc1d122f}, + {0xb5b5ada8aaff80b8, 0x0d819992132456bb}, + {0xe3231912d5bf60e6, 0x10e1fff697ed6c6a}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xb1736b96b6fd83b3, 0xbd308ff8a6b17cb3}, + {0xddd0467c64bce4a0, 0xac7cb3f6d05ddbdf}, + {0x8aa22c0dbef60ee4, 0x6bcdf07a423aa96c}, + {0xad4ab7112eb3929d, 0x86c16c98d2c953c7}, + {0xd89d64d57a607744, 0xe871c7bf077ba8b8}, + {0x87625f056c7c4a8b, 0x11471cd764ad4973}, + {0xa93af6c6c79b5d2d, 0xd598e40d3dd89bd0}, + {0xd389b47879823479, 0x4aff1d108d4ec2c4}, + {0x843610cb4bf160cb, 0xcedf722a585139bb}, + {0xa54394fe1eedb8fe, 0xc2974eb4ee658829}, + {0xce947a3da6a9273e, 0x733d226229feea33}, + {0x811ccc668829b887, 0x0806357d5a3f5260}, + {0xa163ff802a3426a8, 0xca07c2dcb0cf26f8}, + {0xc9bcff6034c13052, 0xfc89b393dd02f0b6}, + {0xfc2c3f3841f17c67, 0xbbac2078d443ace3}, + {0x9d9ba7832936edc0, 0xd54b944b84aa4c0e}, + {0xc5029163f384a931, 0x0a9e795e65d4df12}, + {0xf64335bcf065d37d, 0x4d4617b5ff4a16d6}, + {0x99ea0196163fa42e, 0x504bced1bf8e4e46}, + {0xc06481fb9bcf8d39, 0xe45ec2862f71e1d7}, + {0xf07da27a82c37088, 0x5d767327bb4e5a4d}, + {0x964e858c91ba2655, 0x3a6a07f8d510f870}, + {0xbbe226efb628afea, 0x890489f70a55368c}, + {0xeadab0aba3b2dbe5, 0x2b45ac74ccea842f}, + {0x92c8ae6b464fc96f, 0x3b0b8bc90012929e}, + {0xb77ada0617e3bbcb, 0x09ce6ebb40173745}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0x8f57fa54c2a9eab6, 0x9fa946824a12232e}, + {0xb32df8e9f3546564, 0x47939822dc96abfa}, + {0xdff9772470297ebd, 0x59787e2b93bc56f8}, + {0x8bfbea76c619ef36, 0x57eb4edb3c55b65b}, + {0xaefae51477a06b03, 0xede622920b6b23f2}, + {0xdab99e59958885c4, 0xe95fab368e45ecee}, + {0x88b402f7fd75539b, 0x11dbcb0218ebb415}, + {0xaae103b5fcd2a881, 0xd652bdc29f26a11a}, + {0xd59944a37c0752a2, 0x4be76d3346f04960}, + {0x857fcae62d8493a5, 0x6f70a4400c562ddc}, + {0xa6dfbd9fb8e5b88e, 0xcb4ccd500f6bb953}, + {0xd097ad07a71f26b2, 0x7e2000a41346a7a8}, + {0x825ecc24c873782f, 0x8ed400668c0c28c9}, + {0xa2f67f2dfa90563b, 0x728900802f0f32fb}, + {0xcbb41ef979346bca, 0x4f2b40a03ad2ffba}, + {0xfea126b7d78186bc, 0xe2f610c84987bfa9}, + {0x9f24b832e6b0f436, 0x0dd9ca7d2df4d7ca}, + {0xc6ede63fa05d3143, 0x91503d1c79720dbc}, + {0xf8a95fcf88747d94, 0x75a44c6397ce912b}, + {0x9b69dbe1b548ce7c, 0xc986afbe3ee11abb}, + {0xc24452da229b021b, 0xfbe85badce996169}, + {0xf2d56790ab41c2a2, 0xfae27299423fb9c4}, + {0x97c560ba6b0919a5, 0xdccd879fc967d41b}, + {0xbdb6b8e905cb600f, 0x5400e987bbc1c921}, + {0xed246723473e3813, 0x290123e9aab23b69}, + {0x9436c0760c86e30b, 0xf9a0b6720aaf6522}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0xe7958cb87392c2c2, 0xb60b1d1230b20e05}, + {0x90bd77f3483bb9b9, 0xb1c6f22b5e6f48c3}, + {0xb4ecd5f01a4aa828, 0x1e38aeb6360b1af4}, + {0xe2280b6c20dd5232, 0x25c6da63c38de1b1}, + {0x8d590723948a535f, 0x579c487e5a38ad0f}, + {0xb0af48ec79ace837, 0x2d835a9df0c6d852}, + {0xdcdb1b2798182244, 0xf8e431456cf88e66}, + {0x8a08f0f8bf0f156b, 0x1b8e9ecb641b5900}, + {0xac8b2d36eed2dac5, 0xe272467e3d222f40}, + {0xd7adf884aa879177, 0x5b0ed81dcc6abb10}, + {0x86ccbb52ea94baea, 0x98e947129fc2b4ea}, + {0xa87fea27a539e9a5, 0x3f2398d747b36225}, + {0xd29fe4b18e88640e, 0x8eec7f0d19a03aae}, + {0x83a3eeeef9153e89, 0x1953cf68300424ad}, + {0xa48ceaaab75a8e2b, 0x5fa8c3423c052dd8}, + {0xcdb02555653131b6, 0x3792f412cb06794e}, + {0x808e17555f3ebf11, 0xe2bbd88bbee40bd1}, + {0xa0b19d2ab70e6ed6, 0x5b6aceaeae9d0ec5}, + {0xc8de047564d20a8b, 0xf245825a5a445276}, + {0xfb158592be068d2e, 0xeed6e2f0f0d56713}, + {0x9ced737bb6c4183d, 0x55464dd69685606c}, + {0xc428d05aa4751e4c, 0xaa97e14c3c26b887}, + {0xf53304714d9265df, 0xd53dd99f4b3066a9}, + {0x993fe2c6d07b7fab, 0xe546a8038efe402a}, + {0xbf8fdb78849a5f96, 0xde98520472bdd034}, + {0xef73d256a5c0f77c, 0x963e66858f6d4441}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xbb127c53b17ec159, 0x5560c018580d5d53}, + {0xe9d71b689dde71af, 0xaab8f01e6e10b4a7}, + {0x9226712162ab070d, 0xcab3961304ca70e9}, + {0xb6b00d69bb55c8d1, 0x3d607b97c5fd0d23}, + {0xe45c10c42a2b3b05, 0x8cb89a7db77c506b}, + {0x8eb98a7a9a5b04e3, 0x77f3608e92adb243}, + {0xb267ed1940f1c61c, 0x55f038b237591ed4}, + {0xdf01e85f912e37a3, 0x6b6c46dec52f6689}, + {0x8b61313bbabce2c6, 0x2323ac4b3b3da016}, + {0xae397d8aa96c1b77, 0xabec975e0a0d081b}, + {0xd9c7dced53c72255, 0x96e7bd358c904a22}, + {0x881cea14545c7575, 0x7e50d64177da2e55}, + {0xaa242499697392d2, 0xdde50bd1d5d0b9ea}, + {0xd4ad2dbfc3d07787, 0x955e4ec64b44e865}, + {0x84ec3c97da624ab4, 0xbd5af13bef0b113f}, + {0xa6274bbdd0fadd61, 0xecb1ad8aeacdd58f}, + {0xcfb11ead453994ba, 0x67de18eda5814af3}, + {0x81ceb32c4b43fcf4, 0x80eacf948770ced8}, + {0xa2425ff75e14fc31, 0xa1258379a94d028e}, + {0xcad2f7f5359a3b3e, 0x096ee45813a04331}, + {0xfd87b5f28300ca0d, 0x8bca9d6e188853fd}, + {0x9e74d1b791e07e48, 0x775ea264cf55347e}, + {0xc612062576589dda, 0x95364afe032a819e}, + {0xf79687aed3eec551, 0x3a83ddbd83f52205}, + {0x9abe14cd44753b52, 0xc4926a9672793543}, + {0xc16d9a0095928a27, 0x75b7053c0f178294}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0x971da05074da7bee, 0xd3f6fc16ebca5e04}, + {0xbce5086492111aea, 0x88f4bb1ca6bcf585}, + {0xec1e4a7db69561a5, 0x2b31e9e3d06c32e6}, + {0x9392ee8e921d5d07, 0x3aff322e62439fd0}, + {0xb877aa3236a4b449, 0x09befeb9fad487c3}, + {0xe69594bec44de15b, 0x4c2ebe687989a9b4}, + {0x901d7cf73ab0acd9, 0x0f9d37014bf60a11}, + {0xb424dc35095cd80f, 0x538484c19ef38c95}, + {0xe12e13424bb40e13, 0x2865a5f206b06fba}, + {0x8cbccc096f5088cb, 0xf93f87b7442e45d4}, + {0xafebff0bcb24aafe, 0xf78f69a51539d749}, + {0xdbe6fecebdedd5be, 0xb573440e5a884d1c}, + {0x89705f4136b4a597, 0x31680a88f8953031}, + {0xabcc77118461cefc, 0xfdc20d2b36ba7c3e}, + {0xd6bf94d5e57a42bc, 0x3d32907604691b4d}, + {0x8637bd05af6c69b5, 0xa63f9a49c2c1b110}, + {0xa7c5ac471b478423, 0x0fcf80dc33721d54}, + {0xd1b71758e219652b, 0xd3c36113404ea4a9}, + {0x83126e978d4fdf3b, 0x645a1cac083126ea}, + {0xa3d70a3d70a3d70a, 0x3d70a3d70a3d70a4}, + {0xcccccccccccccccc, 0xcccccccccccccccd}, + {0x8000000000000000, 0x0000000000000000}, + {0xa000000000000000, 0x0000000000000000}, + {0xc800000000000000, 0x0000000000000000}, + {0xfa00000000000000, 0x0000000000000000}, + {0x9c40000000000000, 0x0000000000000000}, + {0xc350000000000000, 0x0000000000000000}, + {0xf424000000000000, 0x0000000000000000}, + {0x9896800000000000, 0x0000000000000000}, + {0xbebc200000000000, 0x0000000000000000}, + {0xee6b280000000000, 0x0000000000000000}, + {0x9502f90000000000, 0x0000000000000000}, + {0xba43b74000000000, 0x0000000000000000}, + {0xe8d4a51000000000, 0x0000000000000000}, + {0x9184e72a00000000, 0x0000000000000000}, + {0xb5e620f480000000, 0x0000000000000000}, + {0xe35fa931a0000000, 0x0000000000000000}, + {0x8e1bc9bf04000000, 0x0000000000000000}, + {0xb1a2bc2ec5000000, 0x0000000000000000}, + {0xde0b6b3a76400000, 0x0000000000000000}, + {0x8ac7230489e80000, 0x0000000000000000}, + {0xad78ebc5ac620000, 0x0000000000000000}, + {0xd8d726b7177a8000, 0x0000000000000000}, + {0x878678326eac9000, 0x0000000000000000}, + {0xa968163f0a57b400, 0x0000000000000000}, + {0xd3c21bcecceda100, 0x0000000000000000}, + {0x84595161401484a0, 0x0000000000000000}, + {0xa56fa5b99019a5c8, 0x0000000000000000}, + {0xcecb8f27f4200f3a, 0x0000000000000000}, + {0x813f3978f8940984, 0x4000000000000000}, + {0xa18f07d736b90be5, 0x5000000000000000}, + {0xc9f2c9cd04674ede, 0xa400000000000000}, + {0xfc6f7c4045812296, 0x4d00000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xc5371912364ce305, 0x6c28000000000000}, + {0xf684df56c3e01bc6, 0xc732000000000000}, + {0x9a130b963a6c115c, 0x3c7f400000000000}, + {0xc097ce7bc90715b3, 0x4b9f100000000000}, + {0xf0bdc21abb48db20, 0x1e86d40000000000}, + {0x96769950b50d88f4, 0x1314448000000000}, + {0xbc143fa4e250eb31, 0x17d955a000000000}, + {0xeb194f8e1ae525fd, 0x5dcfab0800000000}, + {0x92efd1b8d0cf37be, 0x5aa1cae500000000}, + {0xb7abc627050305ad, 0xf14a3d9e40000000}, + {0xe596b7b0c643c719, 0x6d9ccd05d0000000}, + {0x8f7e32ce7bea5c6f, 0xe4820023a2000000}, + {0xb35dbf821ae4f38b, 0xdda2802c8a800000}, + {0xe0352f62a19e306e, 0xd50b2037ad200000}, + {0x8c213d9da502de45, 0x4526f422cc340000}, + {0xaf298d050e4395d6, 0x9670b12b7f410000}, + {0xdaf3f04651d47b4c, 0x3c0cdd765f114000}, + {0x88d8762bf324cd0f, 0xa5880a69fb6ac800}, + {0xab0e93b6efee0053, 0x8eea0d047a457a00}, + {0xd5d238a4abe98068, 0x72a4904598d6d880}, + {0x85a36366eb71f041, 0x47a6da2b7f864750}, + {0xa70c3c40a64e6c51, 0x999090b65f67d924}, + {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, + {0x82818f1281ed449f, 0xbff8f10e7a8921a4}, + {0xa321f2d7226895c7, 0xaff72d52192b6a0d}, + {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490}, + {0xfee50b7025c36a08, 0x02f236d04753d5b4}, + {0x9f4f2726179a2245, 0x01d762422c946590}, + {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5}, + {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2}, + {0x9b934c3b330c8577, 0x63cc55f49f88eb2f}, + {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb}, + {0xf316271c7fc3908a, 0x8bef464e3945ef7a}, + {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac}, + {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317}, + {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd}, + {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a}, + {0xb975d6b6ee39e436, 0xb3e2fd538e122b44}, + {0xe7d34c64a9c85d44, 0x60dbbca87196b616}, + {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd}, + {0xb51d13aea4a488dd, 0x6babab6398bdbe41}, + {0xe264589a4dcdab14, 0xc696963c7eed2dd1}, + {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2}, + {0xb0de65388cc8ada8, 0x3b25a55f43294bcb}, + {0xdd15fe86affad912, 0x49ef0eb713f39ebe}, + {0x8a2dbf142dfcc7ab, 0x6e3569326c784337}, + {0xacb92ed9397bf996, 0x49c2c37f07965404}, + {0xd7e77a8f87daf7fb, 0xdc33745ec97be906}, + {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3}, + {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c}, + {0xd2d80db02aabd62b, 0xf50a3fa490c30190}, + {0x83c7088e1aab65db, 0x792667c6da79e0fa}, + {0xa4b8cab1a1563f52, 0x577001b891185938}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, + {0x80b05e5ac60b6178, 0x544f8158315b05b4}, + {0xa0dc75f1778e39d6, 0x696361ae3db1c721}, + {0xc913936dd571c84c, 0x03bc3a19cd1e38e9}, + {0xfb5878494ace3a5f, 0x04ab48a04065c723}, + {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76}, + {0xc45d1df942711d9a, 0x3ba5d0bd324f8394}, + {0xf5746577930d6500, 0xca8f44ec7ee36479}, + {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb}, + {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e}, + {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e}, + {0x95d04aee3b80ece5, 0xbba1f1d158724a12}, + {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97}, + {0xea1575143cf97226, 0xf52d09d71a3293bd}, + {0x924d692ca61be758, 0x593c2626705f9c56}, + {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c}, + {0xe498f455c38b997a, 0x0b6dfb9c0f956447}, + {0x8edf98b59a373fec, 0x4724bd4189bd5eac}, + {0xb2977ee300c50fe7, 0x58edec91ec2cb657}, + {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed}, + {0x8b865b215899f46c, 0xbd79e0d20082ee74}, + {0xae67f1e9aec07187, 0xecd8590680a3aa11}, + {0xda01ee641a708de9, 0xe80e6f4820cc9495}, + {0x884134fe908658b2, 0x3109058d147fdcdd}, + {0xaa51823e34a7eede, 0xbd4b46f0599fd415}, + {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a}, + {0x850fadc09923329e, 0x03e2cf6bc604ddb0}, + {0xa6539930bf6bff45, 0x84db8346b786151c}, + {0xcfe87f7cef46ff16, 0xe612641865679a63}, + {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e}, + {0xa26da3999aef7749, 0xe3be5e330f38f09d}, + {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5}, + {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6}, + {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa}, + {0xc646d63501a1511d, 0xb281e1fd541501b8}, + {0xf7d88bc24209a565, 0x1f225a7ca91a4226}, + {0x9ae757596946075f, 0x3375788de9b06958}, + {0xc1a12d2fc3978937, 0x0052d6b1641c83ae}, + {0xf209787bb47d6b84, 0xc0678c5dbd23a49a}, + {0x9745eb4d50ce6332, 0xf840b7ba963646e0}, + {0xbd176620a501fbff, 0xb650e5a93bc3d898}, + {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe}, + {0x93ba47c980e98cdf, 0xc66f336c36b10137}, + {0xb8a8d9bbe123f017, 0xb80b0047445d4184}, + {0xe6d3102ad96cec1d, 0xa60dc059157491e5}, + {0x9043ea1ac7e41392, 0x87c89837ad68db2f}, + {0xb454e4a179dd1877, 0x29babe4598c311fb}, + {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a}, + {0x8ce2529e2734bb1d, 0x1899e4a65f58660c}, + {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f}, + {0xdc21a1171d42645d, 0x76707543f4fa1f73}, + {0x899504ae72497eba, 0x6a06494a791c53a8}, + {0xabfa45da0edbde69, 0x0487db9d17636892}, + {0xd6f8d7509292d603, 0x45a9d2845d3c42b6}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, + {0xa7f26836f282b732, 0x8e6cac7768d7141e}, + {0xd1ef0244af2364ff, 0x3207d795430cd926}, + {0x8335616aed761f1f, 0x7f44e6bd49e807b8}, + {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6}, + {0xcd036837130890a1, 0x36dba887c37a8c0f}, + {0x802221226be55a64, 0xc2494954da2c9789}, + {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c}, + {0xc83553c5c8965d3d, 0x6f92829494e5acc7}, + {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9}, + {0x9c69a97284b578d7, 0xff2a760414536efb}, + {0xc38413cf25e2d70d, 0xfef5138519684aba}, + {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69}, + {0x98bf2f79d5993802, 0xef2f773ffbd97a61}, + {0xbeeefb584aff8603, 0xaafb550ffacfd8fa}, + {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38}, + {0x952ab45cfa97a0b2, 0xdd945a747bf26183}, + {0xba756174393d88df, 0x94f971119aeef9e4}, + {0xe912b9d1478ceb17, 0x7a37cd5601aab85d}, + {0x91abb422ccb812ee, 0xac62e055c10ab33a}, + {0xb616a12b7fe617aa, 0x577b986b314d6009}, + {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b}, + {0x8e41ade9fbebc27d, 0x14588f13be847307}, + {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8}, + {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb}, + {0x8aec23d680043bee, 0x25de7bb9480d5854}, + {0xada72ccc20054ae9, 0xaf561aa79a10ae6a}, + {0xd910f7ff28069da4, 0x1b2ba1518094da04}, + {0x87aa9aff79042286, 0x90fb44d2f05d0842}, + {0xa99541bf57452b28, 0x353a1607ac744a53}, + {0xd3fa922f2d1675f2, 0x42889b8997915ce8}, + {0x847c9b5d7c2e09b7, 0x69956135febada11}, + {0xa59bc234db398c25, 0x43fab9837e699095}, + {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb}, + {0x8161afb94b44f57d, 0x1d1be0eebac278f5}, + {0xa1ba1ba79e1632dc, 0x6462d92a69731732}, + {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe}, + {0xfcb2cb35e702af78, 0x5cda735244c3d43e}, + {0x9defbf01b061adab, 0x3a0888136afa64a7}, + {0xc56baec21c7a1916, 0x088aaa1845b8fdd0}, + {0xf6c69a72a3989f5b, 0x8aad549e57273d45}, + {0x9a3c2087a63f6399, 0x36ac54e2f678864b}, + {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd}, + {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5}, + {0x969eb7c47859e743, 0x9f644ae5a4b1b325}, + {0xbc4665b596706114, 0x873d5d9f0dde1fee}, + {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea}, + {0x9316ff75dd87cbd8, 0x09a7f12442d588f2}, + {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f}, + {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa}, + {0x8fa475791a569d10, 0xf96e017d694487bc}, + {0xb38d92d760ec4455, 0x37c981dcc395a9ac}, + {0xe070f78d3927556a, 0x85bbe253f47b1417}, + {0x8c469ab843b89562, 0x93956d7478ccec8e}, + {0xaf58416654a6babb, 0x387ac8d1970027b2}, + {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e}, + {0x88fcf317f22241e2, 0x441fece3bdf81f03}, + {0xab3c2fddeeaad25a, 0xd527e81cad7626c3}, + {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074}, + {0x85c7056562757456, 0xf6872d5667844e49}, + {0xa738c6bebb12d16c, 0xb428f8ac016561db}, + {0xd106f86e69d785c7, 0xe13336d701beba52}, + {0x82a45b450226b39c, 0xecc0024661173473}, + {0xa34d721642b06084, 0x27f002d7f95d0190}, + {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4}, + {0xff290242c83396ce, 0x7e67047175a15271}, + {0x9f79a169bd203e41, 0x0f0062c6e984d386}, + {0xc75809c42c684dd1, 0x52c07b78a3e60868}, + {0xf92e0c3537826145, 0xa7709a56ccdf8a82}, + {0x9bbcc7a142b17ccb, 0x88a66076400bb691}, + {0xc2abf989935ddbfe, 0x6acff893d00ea435}, + {0xf356f7ebf83552fe, 0x0583f6b8c4124d43}, + {0x98165af37b2153de, 0xc3727a337a8b704a}, + {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c}, + {0xeda2ee1c7064130c, 0x1162def06f79df73}, + {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8}, + {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692}, + {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437}, + {0x910ab1d4db9914a0, 0x1d9c9892400a22a2}, + {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b}, + {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, + {0xb10d8e1456105dad, 0x7425a83e872c5f47}, + {0xdd50f1996b947518, 0xd12f124e28f77719}, + {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f}, + {0xace73cbfdc0bfb7b, 0x636cc64d1001550b}, + {0xd8210befd30efa5a, 0x3c47f7e05401aa4e}, + {0x8714a775e3e95c78, 0x65acfaec34810a71}, + {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d}, + {0xd31045a8341ca07c, 0x1ede48111209a050}, + {0x83ea2b892091e44d, 0x934aed0aab460432}, + {0xa4e4b66b68b65d60, 0xf81da84d5617853f}, + {0xce1de40642e3f4b9, 0x36251260ab9d668e}, + {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019}, + {0xa1075a24e4421730, 0xb24cf65b8612f81f}, + {0xc94930ae1d529cfc, 0xdee033f26797b627}, + {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1}, + {0x9d412e0806e88aa5, 0x8e1f289560ee864e}, + {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2}, + {0xf5b5d7ec8acb58a2, 0xae10af696774b1db}, + {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29}, + {0xbff610b0cc6edd3f, 0x17fd090a58d32af3}, + {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0}, + {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e}, + {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1}, + {0xea53df5fd18d5513, 0x84c86189216dc5ed}, + {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4}, + {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, + {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e}, + {0xb2c71d5bca9023f8, 0x743e20e9ef511012}, + {0xdf78e4b2bd342cf6, 0x914da9246b255416}, + {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e}, + {0xae9672aba3d0c320, 0xa184ac2473b529b1}, + {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e}, + {0x8865899617fb1871, 0x7e2fa67c7a658892}, + {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7}, + {0xd51ea6fa85785631, 0x552a74227f3ea565}, + {0x8533285c936b35de, 0xd53a88958f87275f}, + {0xa67ff273b8460356, 0x8a892abaf368f137}, + {0xd01fef10a657842c, 0x2d2b7569b0432d85}, + {0x8213f56a67f6b29b, 0x9c3b29620e29fc73}, + {0xa298f2c501f45f42, 0x8349f3ba91b47b8f}, + {0xcb3f2f7642717713, 0x241c70a936219a73}, + {0xfe0efb53d30dd4d7, 0xed238cd383aa0110}, + {0x9ec95d1463e8a506, 0xf4363804324a40aa}, + {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5}, + {0xf81aa16fdc1b81da, 0xdd94b7868e94050a}, + {0x9b10a4e5e9913128, 0xca7cf2b4191c8326}, + {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0}, + {0xf24a01a73cf2dccf, 0xbc633b39673c8cec}, + {0x976e41088617ca01, 0xd5be0503e085d813}, + {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18}, + {0xec9c459d51852ba2, 0xddf8e7d60ed1219e}, + {0x93e1ab8252f33b45, 0xcabb90e5c942b503}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, + {0xe7109bfba19c0c9d, 0x0cc512670a783ad4}, + {0x906a617d450187e2, 0x27fb2b80668b24c5}, + {0xb484f9dc9641e9da, 0xb1f9f660802dedf6}, + {0xe1a63853bbd26451, 0x5e7873f8a0396973}, + {0x8d07e33455637eb2, 0xdb0b487b6423e1e8}, + {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62}, + {0xdc5c5301c56b75f7, 0x7641a140cc7810fb}, + {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d}, + {0xac2820d9623bf429, 0x546345fa9fbdcd44}, + {0xd732290fbacaf133, 0xa97c177947ad4095}, + {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d}, + {0xa81f301449ee8c70, 0x5c68f256bfff5a74}, + {0xd226fc195c6a2f8c, 0x73832eec6fff3111}, + {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab}, + {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55}, + {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb}, + {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3}, + {0xa0555e361951c366, 0xd7e105bcc332621f}, + {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7}, + {0xfa856334878fc150, 0xb14f98f6f0feb951}, + {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3}, + {0xc3b8358109e84f07, 0x0a862f80ec4700c8}, + {0xf4a642e14c6262c8, 0xcd27bb612758c0fa}, + {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c}, + {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3}, + {0xeeea5d5004981478, 0x1858ccfce06cac74}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc8}, + {0xbaa718e68396cffd, 0xd30560258f54e6ba}, + {0xe950df20247c83fd, 0x47c6b82ef32a2069}, + {0x91d28b7416cdd27e, 0x4cdc331d57fa5441}, + {0xb6472e511c81471d, 0xe0133fe4adf8e952}, + {0xe3d8f9e563a198e5, 0x58180fddd97723a6}, + {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648}, + {0xb201833b35d63f73, 0x2cd2cc6551e513da}, + {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1}, + {0x8b112e86420f6191, 0xfb04afaf27faf782}, + {0xadd57a27d29339f6, 0x79c5db9af1f9b563}, + {0xd94ad8b1c7380874, 0x18375281ae7822bc}, + {0x87cec76f1c830548, 0x8f2293910d0b15b5}, + {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22}, + {0xd433179d9c8cb841, 0x5fa60692a46151eb}, + {0x849feec281d7f328, 0xdbc7c41ba6bcd333}, + {0xa5c7ea73224deff3, 0x12b9b522906c0800}, + {0xcf39e50feae16bef, 0xd768226b34870a00}, + {0x81842f29f2cce375, 0xe6a1158300d46640}, + {0xa1e53af46f801c53, 0x60495ae3c1097fd0}, + {0xca5e89b18b602368, 0x385bb19cb14bdfc4}, + {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5}, + {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1}, + {0xc5a05277621be293, 0xc7098b7305241885}, + {0xf70867153aa2db38, 0xb8cbee4fc66d1ea7} +#else + {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, + {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, + {0xa6b34ad8c9dfc06f, 0xf42faa48c0ea481f}, + {0x86a8d39ef77164bc, 0xae5dff9c02033198}, + {0xd98ddaee19068c76, 0x3badd624dd9b0958}, + {0xafbd2350644eeacf, 0xe5d1929ef90898fb}, + {0x8df5efabc5979c8f, 0xca8d3ffa1ef463c2}, + {0xe55990879ddcaabd, 0xcc420a6a101d0516}, + {0xb94470938fa89bce, 0xf808e40e8d5b3e6a}, + {0x95a8637627989aad, 0xdde7001379a44aa9}, + {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, + {0xc350000000000000, 0x0000000000000000}, + {0x9dc5ada82b70b59d, 0xf020000000000000}, + {0xfee50b7025c36a08, 0x02f236d04753d5b4}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, + {0xa6539930bf6bff45, 0x84db8346b786151c}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, + {0xd910f7ff28069da4, 0x1b2ba1518094da04}, + {0xaf58416654a6babb, 0x387ac8d1970027b2}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc8} +#endif +}; + +#if !FMT_USE_FULL_CACHE_DRAGONBOX +template +const uint64_t basic_data::powers_of_5_64[] = { + 0x0000000000000001, 0x0000000000000005, 0x0000000000000019, + 0x000000000000007d, 0x0000000000000271, 0x0000000000000c35, + 0x0000000000003d09, 0x000000000001312d, 0x000000000005f5e1, + 0x00000000001dcd65, 0x00000000009502f9, 0x0000000002e90edd, + 0x000000000e8d4a51, 0x0000000048c27395, 0x000000016bcc41e9, + 0x000000071afd498d, 0x0000002386f26fc1, 0x000000b1a2bc2ec5, + 0x000003782dace9d9, 0x00001158e460913d, 0x000056bc75e2d631, + 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, + 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; + +template +const uint32_t basic_data::dragonbox_pow10_recovery_errors[] = { + 0x50001400, 0x54044100, 0x54014555, 0x55954415, 0x54115555, 0x00000001, + 0x50000000, 0x00104000, 0x54010004, 0x05004001, 0x55555544, 0x41545555, + 0x54040551, 0x15445545, 0x51555514, 0x10000015, 0x00101100, 0x01100015, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04450514, 0x45414110, + 0x55555145, 0x50544050, 0x15040155, 0x11054140, 0x50111514, 0x11451454, + 0x00400541, 0x00000000, 0x55555450, 0x10056551, 0x10054011, 0x55551014, + 0x69514555, 0x05151109, 0x00155555}; +#endif + template const char basic_data::foreground_color[] = "\x1b[38;2;"; template @@ -334,6 +1070,10 @@ const char basic_data::background_color[] = "\x1b[48;2;"; template const char basic_data::reset_color[] = "\x1b[0m"; template const wchar_t basic_data::wreset_color[] = L"\x1b[0m"; template const char basic_data::signs[] = {0, '-', '+', ' '}; +template +const char basic_data::left_padding_shifts[] = {31, 31, 0, 1, 0}; +template +const char basic_data::right_padding_shifts[] = {0, 31, 0, 1, 0}; template struct bits { static FMT_CONSTEXPR_DECL const int value = @@ -356,6 +1096,14 @@ class fp { private: using significand_type = uint64_t; + template + using is_supported_float = bool_constant; + + public: + significand_type f; + int e; + // All sizes are in bits. // Subtract 1 to account for an implicit most significant bit in the // normalized form. @@ -363,11 +1111,6 @@ class fp { std::numeric_limits::digits - 1; static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = 1ULL << double_significand_size; - - public: - significand_type f; - int e; - static FMT_CONSTEXPR_DECL const int significand_size = bits::value; @@ -378,80 +1121,56 @@ class fp { // errors on platforms where double is not IEEE754. template explicit fp(Double d) { assign(d); } - // Normalizes the value converted from double and multiplied by (1 << SHIFT). - template friend fp normalize(fp value) { - // Handle subnormals. - const auto shifted_implicit_bit = fp::implicit_bit << SHIFT; - while ((value.f & shifted_implicit_bit) == 0) { - value.f <<= 1; - --value.e; - } - // Subtract 1 to account for hidden bit. - const auto offset = - fp::significand_size - fp::double_significand_size - SHIFT - 1; - value.f <<= offset; - value.e -= offset; - return value; - } - // Assigns d to this and return true iff predecessor is closer than successor. - template - bool assign(Double d) { - // Assume double is in the format [sign][exponent][significand]. - using limits = std::numeric_limits; + template ::value)> + bool assign(Float d) { + // Assume float is in the format [sign][exponent][significand]. + using limits = std::numeric_limits; + const int float_significand_size = limits::digits - 1; const int exponent_size = - bits::value - double_significand_size - 1; // -1 for sign - const uint64_t significand_mask = implicit_bit - 1; + bits::value - float_significand_size - 1; // -1 for sign + const uint64_t float_implicit_bit = 1ULL << float_significand_size; + const uint64_t significand_mask = float_implicit_bit - 1; const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask; const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1; - auto u = bit_cast(d); + constexpr bool is_double = sizeof(Float) == sizeof(uint64_t); + auto u = bit_cast>(d); f = u & significand_mask; - auto biased_e = (u & exponent_mask) >> double_significand_size; + int biased_e = + static_cast((u & exponent_mask) >> float_significand_size); // Predecessor is closer if d is a normalized power of 2 (f == 0) other than // the smallest normalized number (biased_e > 1). bool is_predecessor_closer = f == 0 && biased_e > 1; if (biased_e != 0) - f += implicit_bit; + f += float_implicit_bit; else biased_e = 1; // Subnormals use biased exponent 1 (min exponent). - e = static_cast(biased_e - exponent_bias - double_significand_size); + e = biased_e - exponent_bias - float_significand_size; return is_predecessor_closer; } - template - bool assign(Double) { + template ::value)> + bool assign(Float) { *this = fp(); return false; } +}; - // Assigns d to this together with computing lower and upper boundaries, - // where a boundary is a value half way between the number and its predecessor - // (lower) or successor (upper). The upper boundary is normalized and lower - // has the same exponent but may be not normalized. - template boundaries assign_with_boundaries(Double d) { - bool is_lower_closer = assign(d); - fp lower = - is_lower_closer ? fp((f << 2) - 1, e - 2) : fp((f << 1) - 1, e - 1); - // 1 in normalize accounts for the exponent shift above. - fp upper = normalize<1>(fp((f << 1) + 1, e - 1)); - lower.f <<= lower.e - upper.e; - return boundaries{lower.f, upper.f}; - } - - template boundaries assign_float_with_boundaries(Double d) { - assign(d); - constexpr int min_normal_e = std::numeric_limits::min_exponent - - std::numeric_limits::digits; - significand_type half_ulp = 1 << (std::numeric_limits::digits - - std::numeric_limits::digits - 1); - if (min_normal_e > e) half_ulp <<= min_normal_e - e; - fp upper = normalize<0>(fp(f + half_ulp, e)); - fp lower = fp( - f - (half_ulp >> ((f == implicit_bit && e > min_normal_e) ? 1 : 0)), e); - lower.f <<= lower.e - upper.e; - return boundaries{lower.f, upper.f}; +// Normalizes the value converted from double and multiplied by (1 << SHIFT). +template fp normalize(fp value) { + // Handle subnormals. + const auto shifted_implicit_bit = fp::implicit_bit << SHIFT; + while ((value.f & shifted_implicit_bit) == 0) { + value.f <<= 1; + --value.e; } -}; + // Subtract 1 to account for hidden bit. + const auto offset = + fp::significand_size - fp::double_significand_size - SHIFT - 1; + value.f <<= offset; + value.e -= offset; + return value; +} inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; } @@ -477,14 +1196,13 @@ inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; } // Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its // (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`. -FMT_FUNC fp get_cached_power(int min_exponent, int& pow10_exponent) { - const uint64_t one_over_log2_10 = 0x4d104d42; // round(pow(2, 32) / log2(10)) +inline fp get_cached_power(int min_exponent, int& pow10_exponent) { + const int shift = 32; + const auto significand = static_cast(data::log10_2_significand); int index = static_cast( - static_cast( - (min_exponent + fp::significand_size - 1) * one_over_log2_10 + - ((uint64_t(1) << 32) - 1) // ceil - ) >> - 32 // arithmetic shift + ((min_exponent + fp::significand_size - 1) * (significand >> shift) + + ((int64_t(1) << shift) - 1)) // ceil + >> 32 // arithmetic shift ); // Decimal exponent of the first (smallest) cached power of 10. const int first_dec_exp = -348; @@ -492,7 +1210,8 @@ FMT_FUNC fp get_cached_power(int min_exponent, int& pow10_exponent) { const int dec_exp_step = 8; index = (index - first_dec_exp - 1) / dec_exp_step + 1; pow10_exponent = first_dec_exp + index * dec_exp_step; - return {data::pow10_significands[index], data::pow10_exponents[index]}; + return {data::grisu_pow10_significands[index], + data::grisu_pow10_exponents[index]}; } // A simple accumulator to hold the sums of terms in bigint::square if uint128_t @@ -526,20 +1245,23 @@ class bigint { basic_memory_buffer bigits_; int exp_; + bigit operator[](int index) const { return bigits_[to_unsigned(index)]; } + bigit& operator[](int index) { return bigits_[to_unsigned(index)]; } + static FMT_CONSTEXPR_DECL const int bigit_bits = bits::value; friend struct formatter; void subtract_bigits(int index, bigit other, bigit& borrow) { - auto result = static_cast(bigits_[index]) - other - borrow; - bigits_[index] = static_cast(result); + auto result = static_cast((*this)[index]) - other - borrow; + (*this)[index] = static_cast(result); borrow = static_cast(result >> (bigit_bits * 2 - 1)); } void remove_leading_zeros() { int num_bigits = static_cast(bigits_.size()) - 1; - while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits; - bigits_.resize(num_bigits + 1); + while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits; + bigits_.resize(to_unsigned(num_bigits + 1)); } // Computes *this -= other assuming aligned bigints and *this >= other. @@ -548,10 +1270,8 @@ class bigint { FMT_ASSERT(compare(*this, other) >= 0, ""); bigit borrow = 0; int i = other.exp_ - exp_; - for (int j = 0, n = static_cast(other.bigits_.size()); j != n; - ++i, ++j) { + for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) subtract_bigits(i, other.bigits_[j], borrow); - } while (borrow > 0) subtract_bigits(i, 0, borrow); remove_leading_zeros(); } @@ -593,14 +1313,15 @@ class bigint { void operator=(const bigint&) = delete; void assign(const bigint& other) { - bigits_.resize(other.bigits_.size()); + auto size = other.bigits_.size(); + bigits_.resize(size); auto data = other.bigits_.data(); - std::copy(data, data + other.bigits_.size(), bigits_.data()); + std::copy(data, data + size, make_checked(bigits_.data(), size)); exp_ = other.exp_; } void assign(uint64_t n) { - int num_bigits = 0; + size_t num_bigits = 0; do { bigits_[num_bigits++] = n & ~bigit(0); n >>= bigit_bits; @@ -611,7 +1332,7 @@ class bigint { int num_bigits() const { return static_cast(bigits_.size()) + exp_; } - bigint& operator<<=(int shift) { + FMT_NOINLINE bigint& operator<<=(int shift) { assert(shift >= 0); exp_ += shift / bigit_bits; shift %= bigit_bits; @@ -641,7 +1362,7 @@ class bigint { int end = i - j; if (end < 0) end = 0; for (; i >= end; --i, --j) { - bigit lhs_bigit = lhs.bigits_[i], rhs_bigit = rhs.bigits_[j]; + bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j]; if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1; } if (i != j) return i > j ? 1 : -1; @@ -656,7 +1377,7 @@ class bigint { if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; if (max_lhs_bigits > num_rhs_bigits) return 1; auto get_bigit = [](const bigint& n, int i) -> bigit { - return i >= n.exp_ && i < n.num_bigits() ? n.bigits_[i - n.exp_] : 0; + return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0; }; double_bigit borrow = 0; int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_); @@ -696,7 +1417,7 @@ class bigint { basic_memory_buffer n(std::move(bigits_)); int num_bigits = static_cast(bigits_.size()); int num_result_bigits = 2 * num_bigits; - bigits_.resize(num_result_bigits); + bigits_.resize(to_unsigned(num_result_bigits)); using accumulator_t = conditional_t; auto sum = accumulator_t(); for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { @@ -706,7 +1427,7 @@ class bigint { // Most terms are multiplied twice which can be optimized in the future. sum += static_cast(n[i]) * n[j]; } - bigits_[bigit_index] = static_cast(sum); + (*this)[bigit_index] = static_cast(sum); sum >>= bits::value; // Compute the carry. } // Do the same for the top half. @@ -714,7 +1435,7 @@ class bigint { ++bigit_index) { for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) sum += static_cast(n[i++]) * n[j--]; - bigits_[bigit_index] = static_cast(sum); + (*this)[bigit_index] = static_cast(sum); sum >>= bits::value; } --num_result_bigits; @@ -722,22 +1443,26 @@ class bigint { exp_ *= 2; } + // If this bigint has a bigger exponent than other, adds trailing zero to make + // exponents equal. This simplifies some operations such as subtraction. + void align(const bigint& other) { + int exp_difference = exp_ - other.exp_; + if (exp_difference <= 0) return; + int num_bigits = static_cast(bigits_.size()); + bigits_.resize(to_unsigned(num_bigits + exp_difference)); + for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) + bigits_[j] = bigits_[i]; + std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); + exp_ -= exp_difference; + } + // Divides this bignum by divisor, assigning the remainder to this and // returning the quotient. int divmod_assign(const bigint& divisor) { FMT_ASSERT(this != &divisor, ""); if (compare(*this, divisor) < 0) return 0; - int num_bigits = static_cast(bigits_.size()); - FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1] != 0, ""); - int exp_difference = exp_ - divisor.exp_; - if (exp_difference > 0) { - // Align bigints by adding trailing zeros to simplify subtraction. - bigits_.resize(num_bigits + exp_difference); - for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) - bigits_[j] = bigits_[i]; - std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); - exp_ -= exp_difference; - } + FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); + align(divisor); int quotient = 0; do { subtract_aligned(divisor); @@ -747,7 +1472,7 @@ class bigint { } }; -enum round_direction { unknown, up, down }; +enum class round_direction { unknown, up, down }; // Given the divisor (normally a power of 10), the remainder = v % divisor for // some number v and the error, returns whether v should be rounded up, down, or @@ -760,13 +1485,13 @@ inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder, FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. // Round down if (remainder + error) * 2 <= divisor. if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) - return down; + return round_direction::down; // Round up if (remainder - error) * 2 >= divisor. if (remainder >= error && remainder - error >= divisor - (remainder - error)) { - return up; + return round_direction::up; } - return unknown; + return round_direction::unknown; } namespace digits { @@ -842,8 +1567,7 @@ FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error, FMT_ASSERT(false, "invalid number of digits"); } --exp; - uint64_t remainder = - (static_cast(integral) << -one.e) + fractional; + auto remainder = (static_cast(integral) << -one.e) + fractional; result = handler.on_digit(static_cast('0' + digit), data::powers_of_10_64[exp] << -one.e, remainder, error, exp, true); @@ -853,8 +1577,7 @@ FMT_ALWAYS_INLINE digits::result grisu_gen_digits(fp value, uint64_t error, for (;;) { fractional *= 10; error *= 10; - char digit = - static_cast('0' + static_cast(fractional >> -one.e)); + char digit = static_cast('0' + (fractional >> -one.e)); fractional &= one.f - 1; --exp; result = handler.on_digit(digit, one.f, fractional, error, exp, false); @@ -882,8 +1605,8 @@ struct fixed_handler { if (precision > 0) return digits::more; if (precision < 0) return digits::done; auto dir = get_round_direction(divisor, remainder, error); - if (dir == unknown) return digits::error; - buf[size++] = dir == up ? '1' : '0'; + if (dir == round_direction::unknown) return digits::error; + buf[size++] = dir == round_direction::up ? '1' : '0'; return digits::done; } @@ -891,6 +1614,7 @@ struct fixed_handler { uint64_t error, int, bool integral) { FMT_ASSERT(remainder < divisor, ""); buf[size++] = digit; + if (!integral && error >= remainder) return digits::error; if (size < precision) return digits::more; if (!integral) { // Check if error * 2 < divisor with overflow prevention. @@ -901,7 +1625,8 @@ struct fixed_handler { FMT_ASSERT(error == 1 && divisor > 2, ""); } auto dir = get_round_direction(divisor, remainder, error); - if (dir != up) return dir == down ? digits::done : digits::error; + if (dir != round_direction::up) + return dir == round_direction::down ? digits::done : digits::error; ++buf[size - 1]; for (int i = size - 1; i > 0 && buf[i] > '9'; --i) { buf[i] = '0'; @@ -909,59 +1634,684 @@ struct fixed_handler { } if (buf[0] > '9') { buf[0] = '1'; - buf[size++] = '0'; + if (fixed) + buf[size++] = '0'; + else + ++exp10; } return digits::done; } }; -// The shortest representation digit handler. -struct grisu_shortest_handler { - char* buf; - int size; - // Distance between scaled value and upper bound (wp_W in Grisu3). - uint64_t diff; +// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. +namespace dragonbox { +// Computes 128-bit result of multiplication of two 64-bit unsigned integers. +FMT_SAFEBUFFERS inline uint128_wrapper umul128(uint64_t x, + uint64_t y) FMT_NOEXCEPT { +#if FMT_USE_INT128 + return static_cast(x) * static_cast(y); +#elif defined(_MSC_VER) && defined(_M_X64) + uint128_wrapper result; + result.low_ = _umul128(x, y, &result.high_); + return result; +#else + const uint64_t mask = (uint64_t(1) << 32) - uint64_t(1); + + uint64_t a = x >> 32; + uint64_t b = x & mask; + uint64_t c = y >> 32; + uint64_t d = y & mask; + + uint64_t ac = a * c; + uint64_t bc = b * c; + uint64_t ad = a * d; + uint64_t bd = b * d; + + uint64_t intermediate = (bd >> 32) + (ad & mask) + (bc & mask); + + return {ac + (intermediate >> 32) + (ad >> 32) + (bc >> 32), + (intermediate << 32) + (bd & mask)}; +#endif +} + +// Computes upper 64 bits of multiplication of two 64-bit unsigned integers. +FMT_SAFEBUFFERS inline uint64_t umul128_upper64(uint64_t x, + uint64_t y) FMT_NOEXCEPT { +#if FMT_USE_INT128 + auto p = static_cast(x) * static_cast(y); + return static_cast(p >> 64); +#elif defined(_MSC_VER) && defined(_M_X64) + return __umulh(x, y); +#else + return umul128(x, y).high(); +#endif +} + +// Computes upper 64 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +FMT_SAFEBUFFERS inline uint64_t umul192_upper64(uint64_t x, uint128_wrapper y) + FMT_NOEXCEPT { + uint128_wrapper g0 = umul128(x, y.high()); + g0 += umul128_upper64(x, y.low()); + return g0.high(); +} + +// Computes upper 32 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline uint32_t umul96_upper32(uint32_t x, uint64_t y) FMT_NOEXCEPT { + return static_cast(umul128_upper64(x, y)); +} + +// Computes middle 64 bits of multiplication of a 64-bit unsigned integer and a +// 128-bit unsigned integer. +FMT_SAFEBUFFERS inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) + FMT_NOEXCEPT { + uint64_t g01 = x * y.high(); + uint64_t g10 = umul128_upper64(x, y.low()); + return g01 + g10; +} + +// Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a +// 64-bit unsigned integer. +inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT { + return x * y; +} + +// Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from +// https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4. +inline int floor_log10_pow2(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); + const int shift = 22; + return (e * static_cast(data::log10_2_significand >> (64 - shift))) >> + shift; +} + +// Various fast log computations. +inline int floor_log2_pow10(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent"); + const uint64_t log2_10_integer_part = 3; + const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9; + const int shift_amount = 19; + return (e * static_cast( + (log2_10_integer_part << shift_amount) | + (log2_10_fractional_digits >> (64 - shift_amount)))) >> + shift_amount; +} +inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT { + FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); + const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375; + const int shift_amount = 22; + return (e * static_cast(data::log10_2_significand >> + (64 - shift_amount)) - + static_cast(log10_4_over_3_fractional_digits >> + (64 - shift_amount))) >> + shift_amount; +} + +// Returns true iff x is divisible by pow(2, exp). +inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp >= 1, ""); + FMT_ASSERT(x != 0, ""); +#ifdef FMT_BUILTIN_CTZ + return FMT_BUILTIN_CTZ(x) >= exp; +#else + return exp < num_bits() && x == ((x >> exp) << exp); +#endif +} +inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp >= 1, ""); + FMT_ASSERT(x != 0, ""); +#ifdef FMT_BUILTIN_CTZLL + return FMT_BUILTIN_CTZLL(x) >= exp; +#else + return exp < num_bits() && x == ((x >> exp) << exp); +#endif +} + +// Returns true iff x is divisible by pow(5, exp). +inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp <= 10, "too large exponent"); + return x * data::divtest_table_for_pow5_32[exp].mod_inv <= + data::divtest_table_for_pow5_32[exp].max_quotient; +} +inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT { + FMT_ASSERT(exp <= 23, "too large exponent"); + return x * data::divtest_table_for_pow5_64[exp].mod_inv <= + data::divtest_table_for_pow5_64[exp].max_quotient; +} + +// Replaces n by floor(n / pow(5, N)) returning true if and only if n is +// divisible by pow(5, N). +// Precondition: n <= 2 * pow(5, N + 1). +template +bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT { + static constexpr struct { + uint32_t magic_number; + int bits_for_comparison; + uint32_t threshold; + int shift_amount; + } infos[] = {{0xcccd, 16, 0x3333, 18}, {0xa429, 8, 0x0a, 20}}; + constexpr auto info = infos[N - 1]; + n *= info.magic_number; + const uint32_t comparison_mask = (1u << info.bits_for_comparison) - 1; + bool result = (n & comparison_mask) <= info.threshold; + n >>= info.shift_amount; + return result; +} + +// Computes floor(n / pow(10, N)) for small n and N. +// Precondition: n <= pow(10, N + 1). +template uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT { + static constexpr struct { + uint32_t magic_number; + int shift_amount; + uint32_t divisor_times_10; + } infos[] = {{0xcccd, 19, 100}, {0xa3d8, 22, 1000}}; + constexpr auto info = infos[N - 1]; + FMT_ASSERT(n <= info.divisor_times_10, "n is too large"); + return n * info.magic_number >> info.shift_amount; +} + +// Computes floor(n / 10^(kappa + 1)) (float) +inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) FMT_NOEXCEPT { + return n / float_info::big_divisor; +} +// Computes floor(n / 10^(kappa + 1)) (double) +inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT { + return umul128_upper64(n, 0x83126e978d4fdf3c) >> 9; +} + +// Various subroutines using pow10 cache +template struct cache_accessor; + +template <> struct cache_accessor { + using carrier_uint = float_info::carrier_uint; + using cache_entry_type = uint64_t; + + static uint64_t get_cached_power(int k) FMT_NOEXCEPT { + FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, + "k is out of range"); + return data::dragonbox_pow10_significands_64[k - float_info::min_k]; + } + + static carrier_uint compute_mul(carrier_uint u, + const cache_entry_type& cache) FMT_NOEXCEPT { + return umul96_upper32(u, cache); + } + + static uint32_t compute_delta(const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + return static_cast(cache >> (64 - 1 - beta_minus_1)); + } + + static bool compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + FMT_ASSERT(beta_minus_1 >= 1, ""); + FMT_ASSERT(beta_minus_1 < 64, ""); + + return ((umul96_lower64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; + } + + static carrier_uint compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return static_cast( + (cache - (cache >> (float_info::significand_bits + 2))) >> + (64 - float_info::significand_bits - 1 - beta_minus_1)); + } + + static carrier_uint compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return static_cast( + (cache + (cache >> (float_info::significand_bits + 1))) >> + (64 - float_info::significand_bits - 1 - beta_minus_1)); + } + + static carrier_uint compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (static_cast( + cache >> + (64 - float_info::significand_bits - 2 - beta_minus_1)) + + 1) / + 2; + } +}; + +template <> struct cache_accessor { + using carrier_uint = float_info::carrier_uint; + using cache_entry_type = uint128_wrapper; + + static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT { + FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, + "k is out of range"); + +#if FMT_USE_FULL_CACHE_DRAGONBOX + return data::dragonbox_pow10_significands_128[k - + float_info::min_k]; +#else + static const int compression_ratio = 27; + + // Compute base index. + int cache_index = (k - float_info::min_k) / compression_ratio; + int kb = cache_index * compression_ratio + float_info::min_k; + int offset = k - kb; + + // Get base cache. + uint128_wrapper base_cache = + data::dragonbox_pow10_significands_128[cache_index]; + if (offset == 0) return base_cache; + + // Compute the required amount of bit-shift. + int alpha = floor_log2_pow10(kb + offset) - floor_log2_pow10(kb) - offset; + FMT_ASSERT(alpha > 0 && alpha < 64, "shifting error detected"); + + // Try to recover the real cache. + uint64_t pow5 = data::powers_of_5_64[offset]; + uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); + uint128_wrapper middle_low = + umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5); + + recovered_cache += middle_low.high(); + + uint64_t high_to_middle = recovered_cache.high() << (64 - alpha); + uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); + + recovered_cache = + uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; + + if (kb < 0) recovered_cache += 1; + + // Get error. + int error_idx = (k - float_info::min_k) / 16; + uint32_t error = (data::dragonbox_pow10_recovery_errors[error_idx] >> + ((k - float_info::min_k) % 16) * 2) & + 0x3; + + // Add the error back. + FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); + return {recovered_cache.high(), recovered_cache.low() + error}; +#endif + } + + static carrier_uint compute_mul(carrier_uint u, + const cache_entry_type& cache) FMT_NOEXCEPT { + return umul192_upper64(u, cache); + } + + static uint32_t compute_delta(cache_entry_type const& cache, + int beta_minus_1) FMT_NOEXCEPT { + return static_cast(cache.high() >> (64 - 1 - beta_minus_1)); + } + + static bool compute_mul_parity(carrier_uint two_f, + const cache_entry_type& cache, + int beta_minus_1) FMT_NOEXCEPT { + FMT_ASSERT(beta_minus_1 >= 1, ""); + FMT_ASSERT(beta_minus_1 < 64, ""); - digits::result on_start(uint64_t, uint64_t, uint64_t, int&) { - return digits::more; + return ((umul192_middle64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; } - // Decrement the generated number approaching value from above. - void round(uint64_t d, uint64_t divisor, uint64_t& remainder, - uint64_t error) { - while ( - remainder < d && error - remainder >= divisor && - (remainder + divisor < d || d - remainder >= remainder + divisor - d)) { - --buf[size - 1]; - remainder += divisor; + static carrier_uint compute_left_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (cache.high() - + (cache.high() >> (float_info::significand_bits + 2))) >> + (64 - float_info::significand_bits - 1 - beta_minus_1); + } + + static carrier_uint compute_right_endpoint_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return (cache.high() + + (cache.high() >> (float_info::significand_bits + 1))) >> + (64 - float_info::significand_bits - 1 - beta_minus_1); + } + + static carrier_uint compute_round_up_for_shorter_interval_case( + const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + return ((cache.high() >> + (64 - float_info::significand_bits - 2 - beta_minus_1)) + + 1) / + 2; + } +}; + +// Various integer checks +template +bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT { + return exponent >= + float_info< + T>::case_shorter_interval_left_endpoint_lower_threshold && + exponent <= + float_info::case_shorter_interval_left_endpoint_upper_threshold; +} +template +bool is_endpoint_integer(typename float_info::carrier_uint two_f, + int exponent, int minus_k) FMT_NOEXCEPT { + if (exponent < float_info::case_fc_pm_half_lower_threshold) return false; + // For k >= 0. + if (exponent <= float_info::case_fc_pm_half_upper_threshold) return true; + // For k < 0. + if (exponent > float_info::divisibility_check_by_5_threshold) return false; + return divisible_by_power_of_5(two_f, minus_k); +} + +template +bool is_center_integer(typename float_info::carrier_uint two_f, int exponent, + int minus_k) FMT_NOEXCEPT { + // Exponent for 5 is negative. + if (exponent > float_info::divisibility_check_by_5_threshold) return false; + if (exponent > float_info::case_fc_upper_threshold) + return divisible_by_power_of_5(two_f, minus_k); + // Both exponents are nonnegative. + if (exponent >= float_info::case_fc_lower_threshold) return true; + // Exponent for 2 is negative. + return divisible_by_power_of_2(two_f, minus_k - exponent + 1); +} + +// Remove trailing zeros from n and return the number of zeros removed (float) +FMT_ALWAYS_INLINE int remove_trailing_zeros(uint32_t& n) FMT_NOEXCEPT { +#ifdef FMT_BUILTIN_CTZ + int t = FMT_BUILTIN_CTZ(n); +#else + int t = ctz(n); +#endif + if (t > float_info::max_trailing_zeros) + t = float_info::max_trailing_zeros; + + const uint32_t mod_inv1 = 0xcccccccd; + const uint32_t max_quotient1 = 0x33333333; + const uint32_t mod_inv2 = 0xc28f5c29; + const uint32_t max_quotient2 = 0x0a3d70a3; + + int s = 0; + for (; s < t - 1; s += 2) { + if (n * mod_inv2 > max_quotient2) break; + n *= mod_inv2; + } + if (s < t && n * mod_inv1 <= max_quotient1) { + n *= mod_inv1; + ++s; + } + n >>= s; + return s; +} + +// Removes trailing zeros and returns the number of zeros removed (double) +FMT_ALWAYS_INLINE int remove_trailing_zeros(uint64_t& n) FMT_NOEXCEPT { +#ifdef FMT_BUILTIN_CTZLL + int t = FMT_BUILTIN_CTZLL(n); +#else + int t = ctzll(n); +#endif + if (t > float_info::max_trailing_zeros) + t = float_info::max_trailing_zeros; + // Divide by 10^8 and reduce to 32-bits + // Since ret_value.significand <= (2^64 - 1) / 1000 < 10^17, + // both of the quotient and the r should fit in 32-bits + + const uint32_t mod_inv1 = 0xcccccccd; + const uint32_t max_quotient1 = 0x33333333; + const uint64_t mod_inv8 = 0xc767074b22e90e21; + const uint64_t max_quotient8 = 0x00002af31dc46118; + + // If the number is divisible by 1'0000'0000, work with the quotient + if (t >= 8) { + auto quotient_candidate = n * mod_inv8; + + if (quotient_candidate <= max_quotient8) { + auto quotient = static_cast(quotient_candidate >> 8); + + int s = 8; + for (; s < t; ++s) { + if (quotient * mod_inv1 > max_quotient1) break; + quotient *= mod_inv1; + } + quotient >>= (s - 8); + n = quotient; + return s; } } - // Implements Grisu's round_weed. - digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, - uint64_t error, int exp, bool integral) { - buf[size++] = digit; - if (remainder >= error) return digits::more; - uint64_t unit = integral ? 1 : data::powers_of_10_64[-exp]; - uint64_t up = (diff - 1) * unit; // wp_Wup - round(up, divisor, remainder, error); - uint64_t down = (diff + 1) * unit; // wp_Wdown - if (remainder < down && error - remainder >= divisor && - (remainder + divisor < down || - down - remainder > remainder + divisor - down)) { - return digits::error; + // Otherwise, work with the remainder + auto quotient = static_cast(n / 100000000); + auto remainder = static_cast(n - 100000000 * quotient); + + if (t == 0 || remainder * mod_inv1 > max_quotient1) { + return 0; + } + remainder *= mod_inv1; + + if (t == 1 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 1) + quotient * 10000000ull; + return 1; + } + remainder *= mod_inv1; + + if (t == 2 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 2) + quotient * 1000000ull; + return 2; + } + remainder *= mod_inv1; + + if (t == 3 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 3) + quotient * 100000ull; + return 3; + } + remainder *= mod_inv1; + + if (t == 4 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 4) + quotient * 10000ull; + return 4; + } + remainder *= mod_inv1; + + if (t == 5 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 5) + quotient * 1000ull; + return 5; + } + remainder *= mod_inv1; + + if (t == 6 || remainder * mod_inv1 > max_quotient1) { + n = (remainder >> 6) + quotient * 100ull; + return 6; + } + remainder *= mod_inv1; + + n = (remainder >> 7) + quotient * 10ull; + return 7; +} + +// The main algorithm for shorter interval case +template +FMT_ALWAYS_INLINE FMT_SAFEBUFFERS decimal_fp shorter_interval_case( + int exponent) FMT_NOEXCEPT { + decimal_fp ret_value; + // Compute k and beta + const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent); + const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + + // Compute xi and zi + using cache_entry_type = typename cache_accessor::cache_entry_type; + const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); + + auto xi = cache_accessor::compute_left_endpoint_for_shorter_interval_case( + cache, beta_minus_1); + auto zi = cache_accessor::compute_right_endpoint_for_shorter_interval_case( + cache, beta_minus_1); + + // If the left endpoint is not an integer, increase it + if (!is_left_endpoint_integer_shorter_interval(exponent)) ++xi; + + // Try bigger divisor + ret_value.significand = zi / 10; + + // If succeed, remove trailing zeros if necessary and return + if (ret_value.significand * 10 >= xi) { + ret_value.exponent = minus_k + 1; + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + } + + // Otherwise, compute the round-up of y + ret_value.significand = + cache_accessor::compute_round_up_for_shorter_interval_case( + cache, beta_minus_1); + ret_value.exponent = minus_k; + + // When tie occurs, choose one of them according to the rule + if (exponent >= float_info::shorter_interval_tie_lower_threshold && + exponent <= float_info::shorter_interval_tie_upper_threshold) { + ret_value.significand = ret_value.significand % 2 == 0 + ? ret_value.significand + : ret_value.significand - 1; + } else if (ret_value.significand < xi) { + ++ret_value.significand; + } + return ret_value; +} + +template +FMT_SAFEBUFFERS decimal_fp to_decimal(T x) FMT_NOEXCEPT { + // Step 1: integer promotion & Schubfach multiplier calculation. + + using carrier_uint = typename float_info::carrier_uint; + using cache_entry_type = typename cache_accessor::cache_entry_type; + auto br = bit_cast(x); + + // Extract significand bits and exponent bits. + const carrier_uint significand_mask = + (static_cast(1) << float_info::significand_bits) - 1; + carrier_uint significand = (br & significand_mask); + int exponent = static_cast((br & exponent_mask()) >> + float_info::significand_bits); + + if (exponent != 0) { // Check if normal. + exponent += float_info::exponent_bias - float_info::significand_bits; + + // Shorter interval case; proceed like Schubfach. + if (significand == 0) return shorter_interval_case(exponent); + + significand |= + (static_cast(1) << float_info::significand_bits); + } else { + // Subnormal case; the interval is always regular. + if (significand == 0) return {0, 0}; + exponent = float_info::min_exponent - float_info::significand_bits; + } + + const bool include_left_endpoint = (significand % 2 == 0); + const bool include_right_endpoint = include_left_endpoint; + + // Compute k and beta. + const int minus_k = floor_log10_pow2(exponent) - float_info::kappa; + const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); + const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + + // Compute zi and deltai + // 10^kappa <= deltai < 10^(kappa + 1) + const uint32_t deltai = cache_accessor::compute_delta(cache, beta_minus_1); + const carrier_uint two_fc = significand << 1; + const carrier_uint two_fr = two_fc | 1; + const carrier_uint zi = + cache_accessor::compute_mul(two_fr << beta_minus_1, cache); + + // Step 2: Try larger divisor; remove trailing zeros if necessary + + // Using an upper bound on zi, we might be able to optimize the division + // better than the compiler; we are computing zi / big_divisor here + decimal_fp ret_value; + ret_value.significand = divide_by_10_to_kappa_plus_1(zi); + uint32_t r = static_cast(zi - float_info::big_divisor * + ret_value.significand); + + if (r > deltai) { + goto small_divisor_case_label; + } else if (r < deltai) { + // Exclude the right endpoint if necessary + if (r == 0 && !include_right_endpoint && + is_endpoint_integer(two_fr, exponent, minus_k)) { + --ret_value.significand; + r = float_info::big_divisor; + goto small_divisor_case_label; + } + } else { + // r == deltai; compare fractional parts + // Check conditions in the order different from the paper + // to take advantage of short-circuiting + const carrier_uint two_fl = two_fc - 1; + if ((!include_left_endpoint || + !is_endpoint_integer(two_fl, exponent, minus_k)) && + !cache_accessor::compute_mul_parity(two_fl, cache, beta_minus_1)) { + goto small_divisor_case_label; } - return 2 * unit <= remainder && remainder <= error - 4 * unit - ? digits::done - : digits::error; } -}; + ret_value.exponent = minus_k + float_info::kappa + 1; + + // We may need to remove trailing zeros + ret_value.exponent += remove_trailing_zeros(ret_value.significand); + return ret_value; + + // Step 3: Find the significand with the smaller divisor + +small_divisor_case_label: + ret_value.significand *= 10; + ret_value.exponent = minus_k + float_info::kappa; + + const uint32_t mask = (1u << float_info::kappa) - 1; + auto dist = r - (deltai / 2) + (float_info::small_divisor / 2); + + // Is dist divisible by 2^kappa? + if ((dist & mask) == 0) { + const bool approx_y_parity = + ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; + dist >>= float_info::kappa; + + // Is dist divisible by 5^kappa? + if (check_divisibility_and_divide_by_pow5::kappa>(dist)) { + ret_value.significand += dist; + + // Check z^(f) >= epsilon^(f) + // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, + // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f) + // Since there are only 2 possibilities, we only need to care about the + // parity. Also, zi and r should have the same parity since the divisor + // is an even number + if (cache_accessor::compute_mul_parity(two_fc, cache, beta_minus_1) != + approx_y_parity) { + --ret_value.significand; + } else { + // If z^(f) >= epsilon^(f), we might have a tie + // when z^(f) == epsilon^(f), or equivalently, when y is an integer + if (is_center_integer(two_fc, exponent, minus_k)) { + ret_value.significand = ret_value.significand % 2 == 0 + ? ret_value.significand + : ret_value.significand - 1; + } + } + } + // Is dist not divisible by 5^kappa? + else { + ret_value.significand += dist; + } + } + // Is dist not divisible by 2^kappa? + else { + // Since we know dist is small, we might be able to optimize the division + // better than the compiler; we are computing dist / small_divisor here + ret_value.significand += + small_division_by_pow10::kappa>(dist); + } + return ret_value; +} +} // namespace dragonbox // Formats value using a variation of the Fixed-Precision Positive // Floating-Point Printout ((FPP)^2) algorithm by Steele & White: // https://fmt.dev/p372-steele.pdf. template -void fallback_format(Double d, buffer& buf, int& exp10) { +void fallback_format(Double d, int num_digits, bool binary32, buffer& buf, + int& exp10) { bigint numerator; // 2 * R in (FPP)^2. bigint denominator; // 2 * S in (FPP)^2. // lower and upper are differences between value and corresponding boundaries. @@ -972,7 +2322,9 @@ void fallback_format(Double d, buffer& buf, int& exp10) { // Shift numerator and denominator by an extra bit or two (if lower boundary // is closer) to make lower and upper integers. This eliminates multiplication // by 2 during later computations. - int shift = value.assign(d) ? 2 : 1; + const bool is_predecessor_closer = + binary32 ? value.assign(static_cast(d)) : value.assign(d); + int shift = is_predecessor_closer ? 2 : 1; uint64_t significand = value.f << shift; if (value.e >= 0) { numerator.assign(significand); @@ -985,7 +2337,7 @@ void fallback_format(Double d, buffer& buf, int& exp10) { upper = &upper_store; } denominator.assign_pow10(exp10); - denominator <<= 1; + denominator <<= shift; } else if (exp10 < 0) { numerator.assign_pow10(-exp10); lower.assign(numerator); @@ -1007,42 +2359,76 @@ void fallback_format(Double d, buffer& buf, int& exp10) { upper = &upper_store; } } - if (!upper) upper = &lower; // Invariant: value == (numerator / denominator) * pow(10, exp10). - bool even = (value.f & 1) == 0; - int num_digits = 0; - char* data = buf.data(); - for (;;) { - int digit = numerator.divmod_assign(denominator); - bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. - // numerator + upper >[=] pow10: - bool high = add_compare(numerator, *upper, denominator) + even > 0; - data[num_digits++] = static_cast('0' + digit); - if (low || high) { - if (!low) { - ++data[num_digits - 1]; - } else if (high) { - int result = add_compare(numerator, numerator, denominator); - // Round half to even. - if (result > 0 || (result == 0 && (digit % 2) != 0)) + if (num_digits < 0) { + // Generate the shortest representation. + if (!upper) upper = &lower; + bool even = (value.f & 1) == 0; + num_digits = 0; + char* data = buf.data(); + for (;;) { + int digit = numerator.divmod_assign(denominator); + bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. + // numerator + upper >[=] pow10: + bool high = add_compare(numerator, *upper, denominator) + even > 0; + data[num_digits++] = static_cast('0' + digit); + if (low || high) { + if (!low) { ++data[num_digits - 1]; + } else if (high) { + int result = add_compare(numerator, numerator, denominator); + // Round half to even. + if (result > 0 || (result == 0 && (digit % 2) != 0)) + ++data[num_digits - 1]; + } + buf.try_resize(to_unsigned(num_digits)); + exp10 -= num_digits - 1; + return; } - buf.resize(num_digits); - exp10 -= num_digits - 1; - return; + numerator *= 10; + lower *= 10; + if (upper != &lower) *upper *= 10; } + } + // Generate the given number of digits. + exp10 -= num_digits - 1; + if (num_digits == 0) { + buf.try_resize(1); + denominator *= 10; + buf[0] = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; + return; + } + buf.try_resize(to_unsigned(num_digits)); + for (int i = 0; i < num_digits - 1; ++i) { + int digit = numerator.divmod_assign(denominator); + buf[i] = static_cast('0' + digit); numerator *= 10; - lower *= 10; - if (upper != &lower) *upper *= 10; } + int digit = numerator.divmod_assign(denominator); + auto result = add_compare(numerator, numerator, denominator); + if (result > 0 || (result == 0 && (digit % 2) != 0)) { + if (digit == 9) { + const auto overflow = '0' + 10; + buf[num_digits - 1] = overflow; + // Propagate the carry. + for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] == overflow) { + buf[0] = '1'; + ++exp10; + } + return; + } + ++digit; + } + buf[num_digits - 1] = static_cast('0' + digit); } -// Formats value using the Grisu algorithm -// (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf) -// if T is a IEEE754 binary32 or binary64 and snprintf otherwise. template int format_float(T value, int precision, float_specs specs, buffer& buf) { - static_assert(!std::is_same(), ""); + static_assert(!std::is_same::value, ""); FMT_ASSERT(value >= 0, "value is negative"); const bool fixed = specs.format == float_format::fixed; @@ -1051,73 +2437,64 @@ int format_float(T value, int precision, float_specs specs, buffer& buf) { buf.push_back('0'); return 0; } - buf.resize(to_unsigned(precision)); + buf.try_resize(to_unsigned(precision)); std::uninitialized_fill_n(buf.data(), precision, '0'); return -precision; } if (!specs.use_grisu) return snprintf_float(value, precision, specs, buf); + if (precision < 0) { + // Use Dragonbox for the shortest format. + if (specs.binary32) { + auto dec = dragonbox::to_decimal(static_cast(value)); + write(buffer_appender(buf), dec.significand); + return dec.exponent; + } + auto dec = dragonbox::to_decimal(static_cast(value)); + write(buffer_appender(buf), dec.significand); + return dec.exponent; + } + + // Use Grisu + Dragon4 for the given precision: + // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf. int exp = 0; const int min_exp = -60; // alpha in Grisu. int cached_exp10 = 0; // K in Grisu. - if (precision != -1) { - if (precision > 17) return snprintf_float(value, precision, specs, buf); - fp normalized = normalize(fp(value)); - const auto cached_pow = get_cached_power( - min_exp - (normalized.e + fp::significand_size), cached_exp10); - normalized = normalized * cached_pow; - fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; - if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error) - return snprintf_float(value, precision, specs, buf); - int num_digits = handler.size; - if (!fixed) { - // Remove trailing zeros. - while (num_digits > 0 && buf[num_digits - 1] == '0') { - --num_digits; - ++exp; - } - } - buf.resize(to_unsigned(num_digits)); + fp normalized = normalize(fp(value)); + const auto cached_pow = get_cached_power( + min_exp - (normalized.e + fp::significand_size), cached_exp10); + normalized = normalized * cached_pow; + // Limit precision to the maximum possible number of significant digits in an + // IEEE754 double because we don't need to generate zeros. + const int max_double_digits = 767; + if (precision > max_double_digits) precision = max_double_digits; + fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; + if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error) { + exp += handler.size - cached_exp10 - 1; + fallback_format(value, handler.precision, specs.binary32, buf, exp); } else { - fp fp_value; - auto boundaries = specs.binary32 - ? fp_value.assign_float_with_boundaries(value) - : fp_value.assign_with_boundaries(value); - fp_value = normalize(fp_value); - // Find a cached power of 10 such that multiplying value by it will bring - // the exponent in the range [min_exp, -32]. - const fp cached_pow = get_cached_power( - min_exp - (fp_value.e + fp::significand_size), cached_exp10); - // Multiply value and boundaries by the cached power of 10. - fp_value = fp_value * cached_pow; - boundaries.lower = multiply(boundaries.lower, cached_pow.f); - boundaries.upper = multiply(boundaries.upper, cached_pow.f); - assert(min_exp <= fp_value.e && fp_value.e <= -32); - --boundaries.lower; // \tilde{M}^- - 1 ulp -> M^-_{\downarrow}. - ++boundaries.upper; // \tilde{M}^+ + 1 ulp -> M^+_{\uparrow}. - // Numbers outside of (lower, upper) definitely do not round to value. - grisu_shortest_handler handler{buf.data(), 0, - boundaries.upper - fp_value.f}; - auto result = - grisu_gen_digits(fp(boundaries.upper, fp_value.e), - boundaries.upper - boundaries.lower, exp, handler); - if (result == digits::error) { - exp += handler.size - cached_exp10 - 1; - fallback_format(value, buf, exp); - return exp; + exp += handler.exp10; + buf.try_resize(to_unsigned(handler.size)); + } + if (!fixed && !specs.showpoint) { + // Remove trailing zeros. + auto num_digits = buf.size(); + while (num_digits > 0 && buf[num_digits - 1] == '0') { + --num_digits; + ++exp; } - buf.resize(to_unsigned(handler.size)); + buf.try_resize(num_digits); } - return exp - cached_exp10; -} + return exp; +} // namespace detail template int snprintf_float(T value, int precision, float_specs specs, buffer& buf) { // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer"); - static_assert(!std::is_same(), ""); + static_assert(!std::is_same::value, ""); // Subtract 1 to account for the difference in precision since we use %e for // both general and exponent format. @@ -1126,11 +2503,11 @@ int snprintf_float(T value, int precision, float_specs specs, precision = (precision >= 0 ? precision : 6) - 1; // Build the format string. - enum { max_format_size = 7 }; // Ths longest format is "%#.*Le". + enum { max_format_size = 7 }; // The longest format is "%#.*Le". char format[max_format_size]; char* format_ptr = format; *format_ptr++ = '%'; - if (specs.trailing_zeros) *format_ptr++ = '#'; + if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#'; if (precision >= 0) { *format_ptr++ = '.'; *format_ptr++ = '*'; @@ -1146,30 +2523,32 @@ int snprintf_float(T value, int precision, float_specs specs, for (;;) { auto begin = buf.data() + offset; auto capacity = buf.capacity() - offset; -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#ifdef FMT_FUZZ if (precision > 100000) throw std::runtime_error( "fuzz mode - avoid large allocation inside snprintf"); #endif // Suppress the warning about a nonliteral format string. - auto snprintf_ptr = FMT_SNPRINTF; + // Cannot use auto because of a bug in MinGW (#1532). + int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; int result = precision >= 0 ? snprintf_ptr(begin, capacity, format, precision, value) : snprintf_ptr(begin, capacity, format, value); if (result < 0) { - buf.reserve(buf.capacity() + 1); // The buffer will grow exponentially. + // The buffer will grow exponentially. + buf.try_reserve(buf.capacity() + 1); continue; } - unsigned size = to_unsigned(result); + auto size = to_unsigned(result); // Size equal to capacity means that the last character was truncated. if (size >= capacity) { - buf.reserve(size + offset + 1); // Add 1 for the terminating '\0'. + buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'. continue; } auto is_digit = [](char c) { return c >= '0' && c <= '9'; }; if (specs.format == float_format::fixed) { if (precision == 0) { - buf.resize(size); + buf.try_resize(size); return 0; } // Find and remove the decimal point. @@ -1178,12 +2557,12 @@ int snprintf_float(T value, int precision, float_specs specs, --p; } while (is_digit(*p)); int fraction_size = static_cast(end - p - 1); - std::memmove(p, p + 1, fraction_size); - buf.resize(size - 1); + std::memmove(p, p + 1, to_unsigned(fraction_size)); + buf.try_resize(size - 1); return -fraction_size; } if (specs.format == float_format::hex) { - buf.resize(size + offset); + buf.try_resize(size + offset); return 0; } // Find and parse the exponent. @@ -1207,25 +2586,86 @@ int snprintf_float(T value, int precision, float_specs specs, while (*fraction_end == '0') --fraction_end; // Move the fractional part left to get rid of the decimal point. fraction_size = static_cast(fraction_end - begin - 1); - std::memmove(begin + 1, begin + 2, fraction_size); + std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size)); } - buf.resize(fraction_size + offset + 1); + buf.try_resize(to_unsigned(fraction_size) + offset + 1); return exp - fraction_size; } } -} // namespace internal -template <> struct formatter { +// A public domain branchless UTF-8 decoder by Christopher Wellons: +// https://github.com/skeeto/branchless-utf8 +/* Decode the next character, c, from buf, reporting errors in e. + * + * Since this is a branchless decoder, four bytes will be read from the + * buffer regardless of the actual length of the next character. This + * means the buffer _must_ have at least three bytes of zero padding + * following the end of the data stream. + * + * Errors are reported in e, which will be non-zero if the parsed + * character was somehow invalid: invalid byte sequence, non-canonical + * encoding, or a surrogate half. + * + * The function returns a pointer to the next character. When an error + * occurs, this pointer will be a guess that depends on the particular + * error, but it will always advance at least one byte. + */ +inline const char* utf8_decode(const char* buf, uint32_t* c, int* e) { + static const int masks[] = {0x00, 0x7f, 0x1f, 0x0f, 0x07}; + static const uint32_t mins[] = {4194304, 0, 128, 2048, 65536}; + static const int shiftc[] = {0, 18, 12, 6, 0}; + static const int shifte[] = {0, 6, 4, 2, 0}; + + int len = code_point_length(buf); + const char* next = buf + len; + + // Assume a four-byte character and load four bytes. Unused bits are + // shifted out. + auto s = reinterpret_cast(buf); + *c = uint32_t(s[0] & masks[len]) << 18; + *c |= uint32_t(s[1] & 0x3f) << 12; + *c |= uint32_t(s[2] & 0x3f) << 6; + *c |= uint32_t(s[3] & 0x3f) << 0; + *c >>= shiftc[len]; + + // Accumulate the various error conditions. + *e = (*c < mins[len]) << 6; // non-canonical encoding + *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? + *e |= (*c > 0x10FFFF) << 8; // out of range? + *e |= (s[1] & 0xc0) >> 2; + *e |= (s[2] & 0xc0) >> 4; + *e |= (s[3]) >> 6; + *e ^= 0x2a; // top two bits of each tail byte correct? + *e >>= shifte[len]; + + return next; +} + +struct stringifier { + template FMT_INLINE std::string operator()(T value) const { + return to_string(value); + } + std::string operator()(basic_format_arg::handle h) const { + memory_buffer buf; + format_parse_context parse_ctx({}); + format_context format_ctx(buffer_appender(buf), {}, {}); + h.format(parse_ctx, format_ctx); + return to_string(buf); + } +}; +} // namespace detail + +template <> struct formatter { format_parse_context::iterator parse(format_parse_context& ctx) { return ctx.begin(); } - format_context::iterator format(const internal::bigint& n, + format_context::iterator format(const detail::bigint& n, format_context& ctx) { auto out = ctx.out(); bool first = true; for (auto i = n.bigits_.size(); i > 0; --i) { - auto value = n.bigits_[i - 1]; + auto value = n.bigits_[i - 1u]; if (first) { out = format_to(out, "{:x}", value); first = false; @@ -1234,107 +2674,43 @@ template <> struct formatter { out = format_to(out, "{:08x}", value); } if (n.exp_ > 0) - out = format_to(out, "p{}", n.exp_ * internal::bigint::bigit_bits); + out = format_to(out, "p{}", n.exp_ * detail::bigint::bigit_bits); return out; } }; -#if FMT_USE_WINDOWS_H - -FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) { - static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16"; - if (s.size() > INT_MAX) - FMT_THROW(windows_error(ERROR_INVALID_PARAMETER, ERROR_MSG)); - int s_size = static_cast(s.size()); - if (s_size == 0) { - // MultiByteToWideChar does not support zero length, handle separately. - buffer_.resize(1); - buffer_[0] = 0; - return; - } - - int length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), - s_size, nullptr, 0); - if (length == 0) FMT_THROW(windows_error(GetLastError(), ERROR_MSG)); - buffer_.resize(length + 1); - length = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, - &buffer_[0], length); - if (length == 0) FMT_THROW(windows_error(GetLastError(), ERROR_MSG)); - buffer_[length] = 0; -} - -FMT_FUNC internal::utf16_to_utf8::utf16_to_utf8(wstring_view s) { - if (int error_code = convert(s)) { - FMT_THROW(windows_error(error_code, - "cannot convert string from UTF-16 to UTF-8")); - } -} - -FMT_FUNC int internal::utf16_to_utf8::convert(wstring_view s) { - if (s.size() > INT_MAX) return ERROR_INVALID_PARAMETER; - int s_size = static_cast(s.size()); - if (s_size == 0) { - // WideCharToMultiByte does not support zero length, handle separately. - buffer_.resize(1); - buffer_[0] = 0; - return 0; - } - - int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, nullptr, 0, - nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_.resize(length + 1); - length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, &buffer_[0], - length, nullptr, nullptr); - if (length == 0) return GetLastError(); - buffer_[length] = 0; - return 0; -} - -FMT_FUNC void windows_error::init(int err_code, string_view format_str, - format_args args) { - error_code_ = err_code; - memory_buffer buffer; - internal::format_windows_error(buffer, err_code, vformat(format_str, args)); - std::runtime_error& base = *this; - base = std::runtime_error(to_string(buffer)); -} - -FMT_FUNC void internal::format_windows_error(internal::buffer& out, - int error_code, - string_view message) FMT_NOEXCEPT { - FMT_TRY { - wmemory_buffer buf; - buf.resize(inline_buffer_size); - for (;;) { - wchar_t* system_message = &buf[0]; - int result = FormatMessageW( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, - error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), system_message, - static_cast(buf.size()), nullptr); - if (result != 0) { - utf16_to_utf8 utf8_message; - if (utf8_message.convert(system_message) == ERROR_SUCCESS) { - internal::writer w(out); - w.write(message); - w.write(": "); - w.write(utf8_message); - return; - } - break; - } - if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) - break; // Can't get error message, report error code instead. - buf.resize(buf.size() * 2); +FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { + auto transcode = [this](const char* p) { + auto cp = uint32_t(); + auto error = 0; + p = utf8_decode(p, &cp, &error); + if (error != 0) FMT_THROW(std::runtime_error("invalid utf8")); + if (cp <= 0xFFFF) { + buffer_.push_back(static_cast(cp)); + } else { + cp -= 0x10000; + buffer_.push_back(static_cast(0xD800 + (cp >> 10))); + buffer_.push_back(static_cast(0xDC00 + (cp & 0x3FF))); } + return p; + }; + auto p = s.data(); + const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars. + if (s.size() >= block_size) { + for (auto end = p + s.size() - block_size + 1; p < end;) p = transcode(p); } - FMT_CATCH(...) {} - format_error_code(out, error_code, message); + if (auto num_chars_left = s.data() + s.size() - p) { + char buf[2 * block_size - 1] = {}; + memcpy(buf, p, to_unsigned(num_chars_left)); + p = buf; + do { + p = transcode(p); + } while (p - buf < num_chars_left); + } + buffer_.push_back(0); } -#endif // FMT_USE_WINDOWS_H - -FMT_FUNC void format_system_error(internal::buffer& out, int error_code, +FMT_FUNC void format_system_error(detail::buffer& out, int error_code, string_view message) FMT_NOEXCEPT { FMT_TRY { memory_buffer buf; @@ -1342,12 +2718,10 @@ FMT_FUNC void format_system_error(internal::buffer& out, int error_code, for (;;) { char* system_message = &buf[0]; int result = - internal::safe_strerror(error_code, system_message, buf.size()); + detail::safe_strerror(error_code, system_message, buf.size()); if (result == 0) { - internal::writer w(out); - w.write(message); - w.write(": "); - w.write(system_message); + format_to(detail::buffer_appender(out), "{}: {}", message, + system_message); return; } if (result != ERANGE) @@ -1359,7 +2733,7 @@ FMT_FUNC void format_system_error(internal::buffer& out, int error_code, format_error_code(out, error_code, message); } -FMT_FUNC void internal::error_handler::on_error(const char* message) { +FMT_FUNC void detail::error_handler::on_error(const char* message) { FMT_THROW(format_error(message)); } @@ -1368,19 +2742,55 @@ FMT_FUNC void report_system_error(int error_code, report_error(format_system_error, error_code, message); } -#if FMT_USE_WINDOWS_H -FMT_FUNC void report_windows_error(int error_code, - fmt::string_view message) FMT_NOEXCEPT { - report_error(internal::format_windows_error, error_code, message); +FMT_FUNC std::string detail::vformat(string_view format_str, format_args args) { + if (format_str.size() == 2 && equal2(format_str.data(), "{}")) { + auto arg = args.get(0); + if (!arg) error_handler().on_error("argument not found"); + return visit_format_arg(stringifier(), arg); + } + memory_buffer buffer; + detail::vformat_to(buffer, format_str, args); + return to_string(buffer); } + +#ifdef _WIN32 +namespace detail { +using dword = conditional_t; +extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // + void*, const void*, dword, dword*, void*); +} // namespace detail #endif FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) { memory_buffer buffer; - internal::vformat_to(buffer, format_str, - basic_format_args>(args)); - internal::fwrite_fully(buffer.data(), 1, buffer.size(), f); + detail::vformat_to(buffer, format_str, + basic_format_args>(args)); +#ifdef _WIN32 + auto fd = _fileno(f); + if (_isatty(fd)) { + detail::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size())); + auto written = detail::dword(); + if (!detail::WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), + u16.c_str(), static_cast(u16.size()), + &written, nullptr)) { + FMT_THROW(format_error("failed to write to console")); + } + return; + } +#endif + detail::fwrite_fully(buffer.data(), 1, buffer.size(), f); +} + +#ifdef _WIN32 +// Print assuming legacy (non-Unicode) encoding. +FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str, + format_args args) { + memory_buffer buffer; + detail::vformat_to(buffer, format_str, + basic_format_args>(args)); + fwrite_fully(buffer.data(), 1, buffer.size(), f); } +#endif FMT_FUNC void vprint(string_view format_str, format_args args) { vprint(stdout, format_str, args); @@ -1388,8 +2798,4 @@ FMT_FUNC void vprint(string_view format_str, format_args args) { FMT_END_NAMESPACE -#ifdef _MSC_VER -# pragma warning(pop) -#endif - #endif // FMT_FORMAT_INL_H_ diff --git a/src/3rd-part/fmt/include/fmt/format.h b/src/3rd-part/fmt/include/fmt/format.h index 01f41f5..1a037b0 100644 --- a/src/3rd-part/fmt/include/fmt/format.h +++ b/src/3rd-part/fmt/include/fmt/format.h @@ -33,8 +33,6 @@ #ifndef FMT_FORMAT_H_ #define FMT_FORMAT_H_ -#include "core.h" - #include #include #include @@ -43,11 +41,7 @@ #include #include -#ifdef __clang__ -# define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) -#else -# define FMT_CLANG_VERSION 0 -#endif +#include "core.h" #ifdef __INTEL_COMPILER # define FMT_ICC_VERSION __INTEL_COMPILER @@ -69,27 +63,52 @@ # define FMT_HAS_BUILTIN(x) 0 #endif -#if FMT_HAS_CPP_ATTRIBUTE(fallthrough) && \ - (__cplusplus >= 201703 || FMT_GCC_VERSION != 0) +#if FMT_GCC_VERSION || FMT_CLANG_VERSION +# define FMT_NOINLINE __attribute__((noinline)) +#else +# define FMT_NOINLINE +#endif + +#if __cplusplus == 201103L || __cplusplus == 201402L +# if defined(__INTEL_COMPILER) || defined(__PGI) +# define FMT_FALLTHROUGH +# elif defined(__clang__) +# define FMT_FALLTHROUGH [[clang::fallthrough]] +# elif FMT_GCC_VERSION >= 700 && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) +# define FMT_FALLTHROUGH [[gnu::fallthrough]] +# else +# define FMT_FALLTHROUGH +# endif +#elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) || \ + (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) # define FMT_FALLTHROUGH [[fallthrough]] #else # define FMT_FALLTHROUGH #endif +#ifndef FMT_MAYBE_UNUSED +# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) +# define FMT_MAYBE_UNUSED [[maybe_unused]] +# else +# define FMT_MAYBE_UNUSED +# endif +#endif + #ifndef FMT_THROW # if FMT_EXCEPTIONS -# if FMT_MSC_VER +# if FMT_MSC_VER || FMT_NVCC FMT_BEGIN_NAMESPACE -namespace internal { +namespace detail { template inline void do_throw(const Exception& x) { - // Silence unreachable code warnings in MSVC because these are nearly - // impossible to fix in a generic code. + // Silence unreachable code warnings in MSVC and NVCC because these + // are nearly impossible to fix in a generic code. volatile bool b = true; if (b) throw x; } -} // namespace internal +} // namespace detail FMT_END_NAMESPACE -# define FMT_THROW(x) internal::do_throw(x) +# define FMT_THROW(x) detail::do_throw(x) # else # define FMT_THROW(x) throw x # endif @@ -102,12 +121,19 @@ FMT_END_NAMESPACE # endif #endif +#if FMT_EXCEPTIONS +# define FMT_TRY try +# define FMT_CATCH(x) catch (x) +#else +# define FMT_TRY if (true) +# define FMT_CATCH(x) if (false) +#endif + #ifndef FMT_USE_USER_DEFINED_LITERALS -// For Intel and NVIDIA compilers both they and the system gcc/msc support UDLs. -# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ - FMT_MSC_VER >= 1900) && \ - (!(FMT_ICC_VERSION || FMT_CUDA_VERSION) || FMT_ICC_VERSION >= 1500 || \ - FMT_CUDA_VERSION >= 700) +// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs. +# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ + FMT_MSC_VER >= 1900) && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480) # define FMT_USE_USER_DEFINED_LITERALS 1 # else # define FMT_USE_USER_DEFINED_LITERALS 0 @@ -115,19 +141,39 @@ FMT_END_NAMESPACE #endif #ifndef FMT_USE_UDL_TEMPLATE -// EDG front end based compilers (icc, nvcc) do not support UDL templates yet -// and GCC 9 warns about them. -# if FMT_USE_USER_DEFINED_LITERALS && FMT_ICC_VERSION == 0 && \ - FMT_CUDA_VERSION == 0 && \ - ((FMT_GCC_VERSION >= 600 && FMT_GCC_VERSION <= 900 && \ - __cplusplus >= 201402L) || \ - FMT_CLANG_VERSION >= 304) +// EDG frontend based compilers (icc, nvcc, PGI, etc) and GCC < 6.4 do not +// properly support UDL templates and GCC >= 9 warns about them. +# if FMT_USE_USER_DEFINED_LITERALS && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 501) && \ + ((FMT_GCC_VERSION >= 604 && __cplusplus >= 201402L) || \ + FMT_CLANG_VERSION >= 304) && \ + !defined(__PGI) && !defined(__NVCC__) # define FMT_USE_UDL_TEMPLATE 1 # else # define FMT_USE_UDL_TEMPLATE 0 # endif #endif +#ifndef FMT_USE_FLOAT +# define FMT_USE_FLOAT 1 +#endif + +#ifndef FMT_USE_DOUBLE +# define FMT_USE_DOUBLE 1 +#endif + +#ifndef FMT_USE_LONG_DOUBLE +# define FMT_USE_LONG_DOUBLE 1 +#endif + +// Defining FMT_REDUCE_INT_INSTANTIATIONS to 1, will reduce the number of +// int_writer template instances to just one by only using the largest integer +// type. This results in a reduction in binary size but will cause a decrease in +// integer formatting performance. +#if !defined(FMT_REDUCE_INT_INSTANTIATIONS) +# define FMT_REDUCE_INT_INSTANTIATIONS 0 +#endif + // __builtin_clz is broken in clang with Microsoft CodeGen: // https://github.com/fmtlib/fmt/issues/519 #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER @@ -136,76 +182,98 @@ FMT_END_NAMESPACE #if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER # define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) #endif +#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz)) +# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) +#endif +#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll)) +# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) +#endif + +#if FMT_MSC_VER +# include // _BitScanReverse[64], _BitScanForward[64], _umul128 +#endif // Some compilers masquerade as both MSVC and GCC-likes or otherwise support // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the // MSVC intrinsics if the clz and clzll builtins are not available. -#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(_MANAGED) -# include // _BitScanReverse, _BitScanReverse64 - +#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && \ + !defined(FMT_BUILTIN_CTZLL) && !defined(_MANAGED) FMT_BEGIN_NAMESPACE -namespace internal { +namespace detail { // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. # ifndef __clang__ +# pragma intrinsic(_BitScanForward) # pragma intrinsic(_BitScanReverse) # endif -inline uint32_t clz(uint32_t x) { +# if defined(_WIN64) && !defined(__clang__) +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif + +inline int clz(uint32_t x) { unsigned long r = 0; _BitScanReverse(&r, x); - FMT_ASSERT(x != 0, ""); // Static analysis complains about using uninitialized data // "r", but the only way that can happen is if "x" is 0, // which the callers guarantee to not happen. -# pragma warning(suppress : 6102) - return 31 - r; + FMT_SUPPRESS_MSC_WARNING(6102) + return 31 ^ static_cast(r); } -# define FMT_BUILTIN_CLZ(n) internal::clz(n) +# define FMT_BUILTIN_CLZ(n) detail::clz(n) -# if defined(_WIN64) && !defined(__clang__) -# pragma intrinsic(_BitScanReverse64) -# endif - -inline uint32_t clzll(uint64_t x) { +inline int clzll(uint64_t x) { unsigned long r = 0; # ifdef _WIN64 _BitScanReverse64(&r, x); # else // Scan the high 32 bits. - if (_BitScanReverse(&r, static_cast(x >> 32))) return 63 - (r + 32); - + if (_BitScanReverse(&r, static_cast(x >> 32))) return 63 ^ (r + 32); // Scan the low 32 bits. _BitScanReverse(&r, static_cast(x)); # endif + FMT_ASSERT(x != 0, ""); + FMT_SUPPRESS_MSC_WARNING(6102) // Suppress a bogus static analysis warning. + return 63 ^ static_cast(r); +} +# define FMT_BUILTIN_CLZLL(n) detail::clzll(n) +inline int ctz(uint32_t x) { + unsigned long r = 0; + _BitScanForward(&r, x); FMT_ASSERT(x != 0, ""); - // Static analysis complains about using uninitialized data - // "r", but the only way that can happen is if "x" is 0, - // which the callers guarantee to not happen. -# pragma warning(suppress : 6102) - return 63 - r; + FMT_SUPPRESS_MSC_WARNING(6102) // Suppress a bogus static analysis warning. + return static_cast(r); +} +# define FMT_BUILTIN_CTZ(n) detail::ctz(n) + +inline int ctzll(uint64_t x) { + unsigned long r = 0; + FMT_ASSERT(x != 0, ""); + FMT_SUPPRESS_MSC_WARNING(6102) // Suppress a bogus static analysis warning. +# ifdef _WIN64 + _BitScanForward64(&r, x); +# else + // Scan the low 32 bits. + if (_BitScanForward(&r, static_cast(x))) return static_cast(r); + // Scan the high 32 bits. + _BitScanForward(&r, static_cast(x >> 32)); + r += 32; +# endif + return static_cast(r); } -# define FMT_BUILTIN_CLZLL(n) internal::clzll(n) -} // namespace internal +# define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) +} // namespace detail FMT_END_NAMESPACE #endif // Enable the deprecated numeric alignment. -#ifndef FMT_NUMERIC_ALIGN -# define FMT_NUMERIC_ALIGN 1 -#endif - -// Enable the deprecated percent specifier. -#ifndef FMT_DEPRECATED_PERCENT -# define FMT_DEPRECATED_PERCENT 0 +#ifndef FMT_DEPRECATED_NUMERIC_ALIGN +# define FMT_DEPRECATED_NUMERIC_ALIGN 0 #endif FMT_BEGIN_NAMESPACE -namespace internal { - -// A helper function to suppress bogus "conditional expression is constant" -// warnings. -template inline T const_check(T value) { return value; } +namespace detail { // An equivalent of `*reinterpret_cast(&source)` that doesn't have // undefined behavior (e.g. due to type aliasing). @@ -219,7 +287,7 @@ inline Dest bit_cast(const Source& source) { } inline bool is_big_endian() { - auto u = 1u; + const auto u = 1u; struct bytes { char data[sizeof(u)]; }; @@ -257,47 +325,25 @@ template constexpr T max_value() { template constexpr int num_bits() { return std::numeric_limits::digits; } +// std::numeric_limits::digits may return 0 for 128-bit ints. +template <> constexpr int num_bits() { return 128; } +template <> constexpr int num_bits() { return 128; } template <> constexpr int num_bits() { return static_cast(sizeof(void*) * std::numeric_limits::digits); } +FMT_INLINE void assume(bool condition) { + (void)condition; +#if FMT_HAS_BUILTIN(__builtin_assume) + __builtin_assume(condition); +#endif +} + // An approximation of iterator_t for pre-C++20 systems. template using iterator_t = decltype(std::begin(std::declval())); - -// Detect the iterator category of *any* given type in a SFINAE-friendly way. -// Unfortunately, older implementations of std::iterator_traits are not safe -// for use in a SFINAE-context. -template -struct iterator_category : std::false_type {}; - -template struct iterator_category { - using type = std::random_access_iterator_tag; -}; - -template -struct iterator_category> { - using type = typename It::iterator_category; -}; - -// Detect if *any* given type models the OutputIterator concept. -template class is_output_iterator { - // Check for mutability because all iterator categories derived from - // std::input_iterator_tag *may* also meet the requirements of an - // OutputIterator, thereby falling into the category of 'mutable iterators' - // [iterator.requirements.general] clause 4. The compiler reveals this - // property only at the point of *actually dereferencing* the iterator! - template - static decltype(*(std::declval())) test(std::input_iterator_tag); - template static char& test(std::output_iterator_tag); - template static const char& test(...); - - using type = decltype(test(typename iterator_category::type{})); - - public: - static const bool value = !std::is_const>::value; -}; +template using sentinel_t = decltype(std::end(std::declval())); // A workaround for std::string not having mutable data() until C++17. template inline Char* get_data(std::basic_string& s) { @@ -308,28 +354,61 @@ inline typename Container::value_type* get_data(Container& c) { return c.data(); } -#ifdef _SECURE_SCL +#if defined(_SECURE_SCL) && _SECURE_SCL // Make a checked iterator to avoid MSVC warnings. template using checked_ptr = stdext::checked_array_iterator; -template checked_ptr make_checked(T* p, std::size_t size) { +template checked_ptr make_checked(T* p, size_t size) { return {p, size}; } #else template using checked_ptr = T*; -template inline T* make_checked(T* p, std::size_t) { return p; } +template inline T* make_checked(T* p, size_t) { return p; } #endif template ::value)> -inline checked_ptr reserve( - std::back_insert_iterator& it, std::size_t n) { +#if FMT_CLANG_VERSION +__attribute__((no_sanitize("undefined"))) +#endif +inline checked_ptr +reserve(std::back_insert_iterator it, size_t n) { Container& c = get_container(it); - std::size_t size = c.size(); + size_t size = c.size(); c.resize(size + n); return make_checked(get_data(c) + size, n); } +template +inline buffer_appender reserve(buffer_appender it, size_t n) { + buffer& buf = get_container(it); + buf.try_reserve(buf.size() + n); + return it; +} + +template inline Iterator& reserve(Iterator& it, size_t) { + return it; +} + +template +constexpr T* to_pointer(OutputIt, size_t) { + return nullptr; +} +template T* to_pointer(buffer_appender it, size_t n) { + buffer& buf = get_container(it); + auto size = buf.size(); + if (buf.capacity() < size + n) return nullptr; + buf.try_resize(size + n); + return buf.data() + size; +} + +template ::value)> +inline std::back_insert_iterator base_iterator( + std::back_insert_iterator& it, + checked_ptr) { + return it; +} + template -inline Iterator& reserve(Iterator& it, std::size_t) { +inline Iterator base_iterator(Iterator, Iterator it) { return it; } @@ -337,7 +416,7 @@ inline Iterator& reserve(Iterator& it, std::size_t) { // discards them. class counting_iterator { private: - std::size_t count_; + size_t count_; public: using iterator_category = std::output_iterator_tag; @@ -352,33 +431,38 @@ class counting_iterator { counting_iterator() : count_(0) {} - std::size_t count() const { return count_; } + size_t count() const { return count_; } counting_iterator& operator++() { ++count_; return *this; } - counting_iterator operator++(int) { auto it = *this; ++*this; return it; } + friend counting_iterator operator+(counting_iterator it, difference_type n) { + it.count_ += static_cast(n); + return it; + } + value_type operator*() const { return {}; } }; template class truncating_iterator_base { protected: OutputIt out_; - std::size_t limit_; - std::size_t count_; + size_t limit_; + size_t count_; - truncating_iterator_base(OutputIt out, std::size_t limit) + truncating_iterator_base(OutputIt out, size_t limit) : out_(out), limit_(limit), count_(0) {} public: using iterator_category = std::output_iterator_tag; + using value_type = typename std::iterator_traits::value_type; using difference_type = void; using pointer = void; using reference = void; @@ -386,7 +470,7 @@ template class truncating_iterator_base { truncating_iterator_base; // Mark iterator as checked. OutputIt base() const { return out_; } - std::size_t count() const { return count_; } + size_t count() const { return count_; } }; // An output iterator that truncates the output and counts the number of objects @@ -399,14 +483,12 @@ class truncating_iterator; template class truncating_iterator : public truncating_iterator_base { - using traits = std::iterator_traits; - - mutable typename traits::value_type blackhole_; + mutable typename truncating_iterator_base::value_type blackhole_; public: - using value_type = typename traits::value_type; + using value_type = typename truncating_iterator_base::value_type; - truncating_iterator(OutputIt out, std::size_t limit) + truncating_iterator(OutputIt out, size_t limit) : truncating_iterator_base(out, limit) {} truncating_iterator& operator++() { @@ -429,13 +511,11 @@ template class truncating_iterator : public truncating_iterator_base { public: - using value_type = typename OutputIt::container_type::value_type; - - truncating_iterator(OutputIt out, std::size_t limit) + truncating_iterator(OutputIt out, size_t limit) : truncating_iterator_base(out, limit) {} - truncating_iterator& operator=(value_type val) { - if (this->count_++ < this->limit_) this->out_ = val; + template truncating_iterator& operator=(T val) { + if (this->count_++ < this->limit_) *this->out_++ = val; return *this; } @@ -444,30 +524,14 @@ class truncating_iterator truncating_iterator& operator*() { return *this; } }; -// A range with the specified output iterator and value type. -template -class output_range { - private: - OutputIt it_; - - public: - using value_type = T; - using iterator = OutputIt; - struct sentinel {}; - - explicit output_range(OutputIt it) : it_(it) {} - OutputIt begin() const { return it_; } - sentinel end() const { return {}; } // Sentinel is not used yet. -}; - template inline size_t count_code_points(basic_string_view s) { return s.size(); } // Counts the number of code points in a UTF-8 string. -inline size_t count_code_points(basic_string_view s) { - const char8_t* data = s.data(); +inline size_t count_code_points(basic_string_view s) { + const char* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80) ++num_code_points; @@ -475,6 +539,11 @@ inline size_t count_code_points(basic_string_view s) { return num_code_points; } +inline size_t count_code_points(basic_string_view s) { + return count_code_points(basic_string_view( + reinterpret_cast(s.data()), s.size())); +} + template inline size_t code_point_index(basic_string_view s, size_t n) { size_t size = s.size(); @@ -482,8 +551,8 @@ inline size_t code_point_index(basic_string_view s, size_t n) { } // Calculates the index of the nth code point in a UTF-8 string. -inline size_t code_point_index(basic_string_view s, size_t n) { - const char8_t* data = s.data(); +inline size_t code_point_index(basic_string_view s, size_t n) { + const char8_type* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) { @@ -493,13 +562,11 @@ inline size_t code_point_index(basic_string_view s, size_t n) { return s.size(); } -inline char8_t to_char8_t(char c) { return static_cast(c); } - template using needs_conversion = bool_constant< std::is_same::value_type, char>::value && - std::is_same::value>; + std::is_same::value>; template ::value)> @@ -510,56 +577,44 @@ OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { template ::value)> OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) { - return std::transform(begin, end, it, to_char8_t); + return std::transform(begin, end, it, + [](char c) { return static_cast(c); }); } -#ifndef FMT_USE_GRISU -# define FMT_USE_GRISU 1 -#endif - -template constexpr bool use_grisu() { - return FMT_USE_GRISU && std::numeric_limits::is_iec559 && - sizeof(T) <= sizeof(double); +template +inline counting_iterator copy_str(InputIt begin, InputIt end, + counting_iterator it) { + return it + (end - begin); } +template +using is_fast_float = bool_constant::is_iec559 && + sizeof(T) <= sizeof(double)>; + +#ifndef FMT_USE_FULL_CACHE_DRAGONBOX +# define FMT_USE_FULL_CACHE_DRAGONBOX 0 +#endif + template template void buffer::append(const U* begin, const U* end) { - std::size_t new_size = size_ + to_unsigned(end - begin); - reserve(new_size); - std::uninitialized_copy(begin, end, make_checked(ptr_, capacity_) + size_); - size_ = new_size; + do { + auto count = to_unsigned(end - begin); + try_reserve(size_ + count); + auto free_cap = capacity_ - size_; + if (free_cap < count) count = free_cap; + std::uninitialized_copy_n(begin, count, make_checked(ptr_ + size_, count)); + size_ += count; + begin += count; + } while (begin != end); } -} // namespace internal - -// A range with an iterator appending to a buffer. -template -class buffer_range : public internal::output_range< - std::back_insert_iterator>, T> { - public: - using iterator = std::back_insert_iterator>; - using internal::output_range::output_range; - buffer_range(internal::buffer& buf) - : internal::output_range(std::back_inserter(buf)) {} -}; -// A UTF-8 string view. -class u8string_view : public basic_string_view { - public: - u8string_view(const char* s) - : basic_string_view(reinterpret_cast(s)) {} - u8string_view(const char* s, size_t count) FMT_NOEXCEPT - : basic_string_view(reinterpret_cast(s), count) { - } -}; - -#if FMT_USE_USER_DEFINED_LITERALS -inline namespace literals { -inline u8string_view operator"" _u(const char* s, std::size_t n) { - return {s, n}; +template +void iterator_buffer::flush() { + out_ = std::copy_n(data_, this->limit(this->size()), out_); + this->clear(); } -} // namespace literals -#endif +} // namespace detail // The number of characters to store in the basic_memory_buffer object itself // to avoid dynamic memory allocation. @@ -594,42 +649,44 @@ enum { inline_buffer_size = 500 }; The output can be converted to an ``std::string`` with ``to_string(out)``. \endrst */ -template > -class basic_memory_buffer : private Allocator, public internal::buffer { +class basic_memory_buffer final : public detail::buffer { private: T store_[SIZE]; + // Don't inherit from Allocator avoid generating type_info for it. + Allocator alloc_; + // Deallocate memory allocated by the buffer. void deallocate() { T* data = this->data(); - if (data != store_) Allocator::deallocate(data, this->capacity()); + if (data != store_) alloc_.deallocate(data, this->capacity()); } protected: - void grow(std::size_t size) FMT_OVERRIDE; + void grow(size_t size) final FMT_OVERRIDE; public: using value_type = T; using const_reference = const T&; explicit basic_memory_buffer(const Allocator& alloc = Allocator()) - : Allocator(alloc) { + : alloc_(alloc) { this->set(store_, SIZE); } - ~basic_memory_buffer() FMT_OVERRIDE { deallocate(); } + ~basic_memory_buffer() { deallocate(); } private: // Move data from other to this buffer. void move(basic_memory_buffer& other) { - Allocator &this_alloc = *this, &other_alloc = other; - this_alloc = std::move(other_alloc); + alloc_ = std::move(other.alloc_); T* data = other.data(); - std::size_t size = other.size(), capacity = other.capacity(); + size_t size = other.size(), capacity = other.capacity(); if (data == other.store_) { this->set(store_, capacity); std::uninitialized_copy(other.store_, other.store_ + size, - internal::make_checked(store_, capacity)); + detail::make_checked(store_, capacity)); } else { this->set(data, capacity); // Set pointer to the inline array so that delete is not called @@ -661,33 +718,55 @@ class basic_memory_buffer : private Allocator, public internal::buffer { } // Returns a copy of the allocator associated with this buffer. - Allocator get_allocator() const { return *this; } + Allocator get_allocator() const { return alloc_; } + + /** + Resizes the buffer to contain *count* elements. If T is a POD type new + elements may not be initialized. + */ + void resize(size_t count) { this->try_resize(count); } + + /** Increases the buffer capacity to *new_capacity*. */ + void reserve(size_t new_capacity) { this->try_reserve(new_capacity); } + + // Directly append data into the buffer + using detail::buffer::append; + template + void append(const ContiguousRange& range) { + append(range.data(), range.data() + range.size()); + } }; -template -void basic_memory_buffer::grow(std::size_t size) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if (size > 1000) throw std::runtime_error("fuzz mode - won't grow that much"); +template +void basic_memory_buffer::grow(size_t size) { +#ifdef FMT_FUZZ + if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much"); #endif - std::size_t old_capacity = this->capacity(); - std::size_t new_capacity = old_capacity + old_capacity / 2; + size_t old_capacity = this->capacity(); + size_t new_capacity = old_capacity + old_capacity / 2; if (size > new_capacity) new_capacity = size; T* old_data = this->data(); - T* new_data = std::allocator_traits::allocate(*this, new_capacity); + T* new_data = + std::allocator_traits::allocate(alloc_, new_capacity); // The following code doesn't throw, so the raw pointer above doesn't leak. std::uninitialized_copy(old_data, old_data + this->size(), - internal::make_checked(new_data, new_capacity)); + detail::make_checked(new_data, new_capacity)); this->set(new_data, new_capacity); // deallocate must not throw according to the standard, but even if it does, // the buffer already uses the new storage and will deallocate it in // destructor. - if (old_data != store_) Allocator::deallocate(old_data, old_capacity); + if (old_data != store_) alloc_.deallocate(old_data, old_capacity); } using memory_buffer = basic_memory_buffer; using wmemory_buffer = basic_memory_buffer; +template +struct is_contiguous> : std::true_type { +}; + /** A formatting error such as invalid format string. */ +FMT_CLASS_API class FMT_API format_error : public std::runtime_error { public: explicit format_error(const char* message) : std::runtime_error(message) {} @@ -700,43 +779,138 @@ class FMT_API format_error : public std::runtime_error { ~format_error() FMT_NOEXCEPT FMT_OVERRIDE; }; -namespace internal { +namespace detail { + +template +using is_signed = + std::integral_constant::is_signed || + std::is_same::value>; // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. -template ::is_signed)> +template ::value)> FMT_CONSTEXPR bool is_negative(T value) { return value < 0; } -template ::is_signed)> +template ::value)> FMT_CONSTEXPR bool is_negative(T) { return false; } +template ::value)> +FMT_CONSTEXPR bool is_supported_floating_point(T) { + return (std::is_same::value && FMT_USE_FLOAT) || + (std::is_same::value && FMT_USE_DOUBLE) || + (std::is_same::value && FMT_USE_LONG_DOUBLE); +} + // Smallest of uint32_t, uint64_t, uint128_t that is large enough to -// represent all values of T. +// represent all values of an integral type T. template -using uint32_or_64_or_128_t = conditional_t< - std::numeric_limits::digits <= 32, uint32_t, - conditional_t::digits <= 64, uint64_t, uint128_t>>; +using uint32_or_64_or_128_t = + conditional_t() <= 32 && !FMT_REDUCE_INT_INSTANTIATIONS, + uint32_t, + conditional_t() <= 64, uint64_t, uint128_t>>; + +// 128-bit integer type used internally +struct FMT_EXTERN_TEMPLATE_API uint128_wrapper { + uint128_wrapper() = default; + +#if FMT_USE_INT128 + uint128_t internal_; + + uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT + : internal_{static_cast(low) | + (static_cast(high) << 64)} {} + + uint128_wrapper(uint128_t u) : internal_{u} {} + + uint64_t high() const FMT_NOEXCEPT { return uint64_t(internal_ >> 64); } + uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); } + + uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { + internal_ += n; + return *this; + } +#else + uint64_t high_; + uint64_t low_; + + uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT : high_{high}, + low_{low} {} + + uint64_t high() const FMT_NOEXCEPT { return high_; } + uint64_t low() const FMT_NOEXCEPT { return low_; } + + uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { +# if defined(_MSC_VER) && defined(_M_X64) + unsigned char carry = _addcarry_u64(0, low_, n, &low_); + _addcarry_u64(carry, high_, 0, &high_); + return *this; +# else + uint64_t sum = low_ + n; + high_ += (sum < low_ ? 1 : 0); + low_ = sum; + return *this; +# endif + } +#endif +}; + +// Table entry type for divisibility test used internally +template struct FMT_EXTERN_TEMPLATE_API divtest_table_entry { + T mod_inv; + T max_quotient; +}; // Static data is placed in this class template for the header-only config. template struct FMT_EXTERN_TEMPLATE_API basic_data { static const uint64_t powers_of_10_64[]; - static const uint32_t zero_or_powers_of_10_32[]; - static const uint64_t zero_or_powers_of_10_64[]; - static const uint64_t pow10_significands[]; - static const int16_t pow10_exponents[]; - static const char digits[]; + static const uint32_t zero_or_powers_of_10_32_new[]; + static const uint64_t zero_or_powers_of_10_64_new[]; + static const uint64_t grisu_pow10_significands[]; + static const int16_t grisu_pow10_exponents[]; + static const divtest_table_entry divtest_table_for_pow5_32[]; + static const divtest_table_entry divtest_table_for_pow5_64[]; + static const uint64_t dragonbox_pow10_significands_64[]; + static const uint128_wrapper dragonbox_pow10_significands_128[]; + // log10(2) = 0x0.4d104d427de7fbcc... + static const uint64_t log10_2_significand = 0x4d104d427de7fbcc; +#if !FMT_USE_FULL_CACHE_DRAGONBOX + static const uint64_t powers_of_5_64[]; + static const uint32_t dragonbox_pow10_recovery_errors[]; +#endif + // GCC generates slightly better code for pairs than chars. + using digit_pair = char[2]; + static const digit_pair digits[]; static const char hex_digits[]; static const char foreground_color[]; static const char background_color[]; static const char reset_color[5]; static const wchar_t wreset_color[5]; static const char signs[]; + static const char left_padding_shifts[5]; + static const char right_padding_shifts[5]; + + // DEPRECATED! These are for ABI compatibility. + static const uint32_t zero_or_powers_of_10_32[]; + static const uint64_t zero_or_powers_of_10_64[]; }; +// Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). +// This is a function instead of an array to workaround a bug in GCC10 (#1810). +FMT_INLINE uint16_t bsr2log10(int bsr) { + static constexpr uint16_t data[] = { + 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; + return data[bsr]; +} + +#ifndef FMT_EXPORTED FMT_EXTERN template struct basic_data; +#endif // This is a struct rather than an alias to avoid shadowing warnings in gcc. struct data : basic_data<> {}; @@ -745,10 +919,9 @@ struct data : basic_data<> {}; // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. inline int count_digits(uint64_t n) { - // Based on http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog10 - // and the benchmark https://github.com/localvoid/cxx-benchmark-count-digits. - int t = (64 - FMT_BUILTIN_CLZLL(n | 1)) * 1233 >> 12; - return t - (n < data::zero_or_powers_of_10_64[t]) + 1; + // https://github.com/fmtlib/format-benchmark/blob/master/digits10 + auto t = bsr2log10(FMT_BUILTIN_CLZLL(n | 1) ^ 63); + return t - (n < data::zero_or_powers_of_10_64_new[t]); } #else // Fallback version of count_digits used when __builtin_clz is not available. @@ -794,22 +967,37 @@ template inline int count_digits(UInt n) { return num_digits; } -template <> int count_digits<4>(internal::fallback_uintptr n); +template <> int count_digits<4>(detail::fallback_uintptr n); #if FMT_GCC_VERSION || FMT_CLANG_VERSION # define FMT_ALWAYS_INLINE inline __attribute__((always_inline)) +#elif FMT_MSC_VER +# define FMT_ALWAYS_INLINE __forceinline +#else +# define FMT_ALWAYS_INLINE inline +#endif + +// To suppress unnecessary security cookie checks +#if FMT_MSC_VER && !FMT_CLANG_VERSION +# define FMT_SAFEBUFFERS __declspec(safebuffers) #else -# define FMT_ALWAYS_INLINE +# define FMT_SAFEBUFFERS #endif #ifdef FMT_BUILTIN_CLZ // Optional version of count_digits for better performance on 32-bit platforms. inline int count_digits(uint32_t n) { - int t = (32 - FMT_BUILTIN_CLZ(n | 1)) * 1233 >> 12; - return t - (n < data::zero_or_powers_of_10_32[t]) + 1; + auto t = bsr2log10(FMT_BUILTIN_CLZ(n | 1) ^ 31); + return t - (n < data::zero_or_powers_of_10_32_new[t]); } #endif +template constexpr int digits10() FMT_NOEXCEPT { + return std::numeric_limits::digits10; +} +template <> constexpr int digits10() FMT_NOEXCEPT { return 38; } +template <> constexpr int digits10() FMT_NOEXCEPT { return 38; } + template FMT_API std::string grouping_impl(locale_ref loc); template inline std::string grouping(locale_ref loc) { return grouping_impl(loc); @@ -834,57 +1022,60 @@ template <> inline wchar_t decimal_point(locale_ref loc) { return decimal_point_impl(loc); } -// Formats a decimal unsigned integer value writing into buffer. -// add_thousands_sep is called after writing each char to add a thousands -// separator if necessary. -template -inline Char* format_decimal(Char* buffer, UInt value, int num_digits, - F add_thousands_sep) { - FMT_ASSERT(num_digits >= 0, "invalid digit count"); - buffer += num_digits; - Char* end = buffer; +// Compares two characters for equality. +template bool equal2(const Char* lhs, const char* rhs) { + return lhs[0] == rhs[0] && lhs[1] == rhs[1]; +} +inline bool equal2(const char* lhs, const char* rhs) { + return memcmp(lhs, rhs, 2) == 0; +} + +// Copies two characters from src to dst. +template void copy2(Char* dst, const char* src) { + *dst++ = static_cast(*src++); + *dst = static_cast(*src); +} +FMT_INLINE void copy2(char* dst, const char* src) { memcpy(dst, src, 2); } + +template struct format_decimal_result { + Iterator begin; + Iterator end; +}; + +// Formats a decimal unsigned integer value writing into out pointing to a +// buffer of specified size. The caller must ensure that the buffer is large +// enough. +template +inline format_decimal_result format_decimal(Char* out, UInt value, + int size) { + FMT_ASSERT(size >= count_digits(value), "invalid digit count"); + out += size; + Char* end = out; while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. - auto index = static_cast((value % 100) * 2); + out -= 2; + copy2(out, data::digits[value % 100]); value /= 100; - *--buffer = static_cast(data::digits[index + 1]); - add_thousands_sep(buffer); - *--buffer = static_cast(data::digits[index]); - add_thousands_sep(buffer); } if (value < 10) { - *--buffer = static_cast('0' + value); - return end; + *--out = static_cast('0' + value); + return {out, end}; } - auto index = static_cast(value * 2); - *--buffer = static_cast(data::digits[index + 1]); - add_thousands_sep(buffer); - *--buffer = static_cast(data::digits[index]); - return end; -} - -template constexpr int digits10() noexcept { - return std::numeric_limits::digits10; -} -template <> constexpr int digits10() noexcept { return 38; } -template <> constexpr int digits10() noexcept { return 38; } - -template -inline Iterator format_decimal(Iterator out, UInt value, int num_digits, - F add_thousands_sep) { - FMT_ASSERT(num_digits >= 0, "invalid digit count"); - // Buffer should be large enough to hold all digits (<= digits10 + 1). - enum { max_size = digits10() + 1 }; - Char buffer[2 * max_size]; - auto end = format_decimal(buffer, value, num_digits, add_thousands_sep); - return internal::copy_str(buffer, end, out); + out -= 2; + copy2(out, data::digits[value]); + return {out, end}; } -template -inline It format_decimal(It out, UInt value, int num_digits) { - return format_decimal(out, value, num_digits, [](Char*) {}); +template >::value)> +inline format_decimal_result format_decimal(Iterator out, UInt value, + int size) { + // Buffer is large enough to hold all digits (digits10 + 1). + Char buffer[digits10() + 1]; + auto end = format_decimal(buffer, value, size).end; + return {out, detail::copy_str(buffer, end, out)}; } template @@ -902,7 +1093,7 @@ inline Char* format_uint(Char* buffer, UInt value, int num_digits, } template -Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits, +Char* format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, bool = false) { auto char_digits = std::numeric_limits::digits / 4; int start = (num_digits + char_digits - 1) / char_digits - 1; @@ -925,79 +1116,58 @@ Char* format_uint(Char* buffer, internal::fallback_uintptr n, int num_digits, template inline It format_uint(It out, UInt value, int num_digits, bool upper = false) { + if (auto ptr = to_pointer(out, to_unsigned(num_digits))) { + format_uint(ptr, value, num_digits, upper); + return out; + } // Buffer should be large enough to hold all digits (digits / BASE_BITS + 1). char buffer[num_bits() / BASE_BITS + 1]; format_uint(buffer, value, num_digits, upper); - return internal::copy_str(buffer, buffer + num_digits, out); + return detail::copy_str(buffer, buffer + num_digits, out); } -#ifndef _WIN32 -# define FMT_USE_WINDOWS_H 0 -#elif !defined(FMT_USE_WINDOWS_H) -# define FMT_USE_WINDOWS_H 1 -#endif - -// Define FMT_USE_WINDOWS_H to 0 to disable use of windows.h. -// All the functionality that relies on it will be disabled too. -#if FMT_USE_WINDOWS_H // A converter from UTF-8 to UTF-16. -// It is only provided for Windows since other systems support UTF-8 natively. class utf8_to_utf16 { private: wmemory_buffer buffer_; public: FMT_API explicit utf8_to_utf16(string_view s); - operator wstring_view() const { return wstring_view(&buffer_[0], size()); } + operator wstring_view() const { return {&buffer_[0], size()}; } size_t size() const { return buffer_.size() - 1; } const wchar_t* c_str() const { return &buffer_[0]; } - std::wstring str() const { return std::wstring(&buffer_[0], size()); } -}; - -// A converter from UTF-16 to UTF-8. -// It is only provided for Windows since other systems support UTF-8 natively. -class utf16_to_utf8 { - private: - memory_buffer buffer_; - - public: - utf16_to_utf8() {} - FMT_API explicit utf16_to_utf8(wstring_view s); - operator string_view() const { return string_view(&buffer_[0], size()); } - size_t size() const { return buffer_.size() - 1; } - const char* c_str() const { return &buffer_[0]; } - std::string str() const { return std::string(&buffer_[0], size()); } - - // Performs conversion returning a system error code instead of - // throwing exception on conversion error. This method may still throw - // in case of memory allocation error. - FMT_API int convert(wstring_view s); + std::wstring str() const { return {&buffer_[0], size()}; } }; -FMT_API void format_windows_error(internal::buffer& out, int error_code, - string_view message) FMT_NOEXCEPT; -#endif - template struct null {}; // Workaround an array initialization issue in gcc 4.8. template struct fill_t { private: - Char data_[6]; + enum { max_size = 4 }; + Char data_[max_size] = {Char(' '), Char(0), Char(0), Char(0)}; + unsigned char size_ = 1; public: + FMT_CONSTEXPR void operator=(basic_string_view s) { + auto size = s.size(); + if (size > max_size) { + FMT_THROW(format_error("invalid fill")); + return; + } + for (size_t i = 0; i < size; ++i) data_[i] = s[i]; + size_ = static_cast(size); + } + + size_t size() const { return size_; } + const Char* data() const { return data_; } + FMT_CONSTEXPR Char& operator[](size_t index) { return data_[index]; } FMT_CONSTEXPR const Char& operator[](size_t index) const { return data_[index]; } - - static FMT_CONSTEXPR fill_t make() { - auto fill = fill_t(); - fill[0] = Char(' '); - return fill; - } }; -} // namespace internal +} // namespace detail // We cannot use enum classes as bit fields because of a gcc bug // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. @@ -1019,7 +1189,7 @@ template struct basic_format_specs { align_t align : 4; sign_t sign : 3; bool alt : 1; // Alternate form ('#'). - internal::fill_t fill; + detail::fill_t fill; constexpr basic_format_specs() : width(0), @@ -1027,13 +1197,84 @@ template struct basic_format_specs { type(0), align(align::none), sign(sign::none), - alt(false), - fill(internal::fill_t::make()) {} + alt(false) {} }; using format_specs = basic_format_specs; -namespace internal { +namespace detail { +namespace dragonbox { + +// Type-specific information that Dragonbox uses. +template struct float_info; + +template <> struct float_info { + using carrier_uint = uint32_t; + static const int significand_bits = 23; + static const int exponent_bits = 8; + static const int min_exponent = -126; + static const int max_exponent = 127; + static const int exponent_bias = -127; + static const int decimal_digits = 9; + static const int kappa = 1; + static const int big_divisor = 100; + static const int small_divisor = 10; + static const int min_k = -31; + static const int max_k = 46; + static const int cache_bits = 64; + static const int divisibility_check_by_5_threshold = 39; + static const int case_fc_pm_half_lower_threshold = -1; + static const int case_fc_pm_half_upper_threshold = 6; + static const int case_fc_lower_threshold = -2; + static const int case_fc_upper_threshold = 6; + static const int case_shorter_interval_left_endpoint_lower_threshold = 2; + static const int case_shorter_interval_left_endpoint_upper_threshold = 3; + static const int shorter_interval_tie_lower_threshold = -35; + static const int shorter_interval_tie_upper_threshold = -35; + static const int max_trailing_zeros = 7; +}; + +template <> struct float_info { + using carrier_uint = uint64_t; + static const int significand_bits = 52; + static const int exponent_bits = 11; + static const int min_exponent = -1022; + static const int max_exponent = 1023; + static const int exponent_bias = -1023; + static const int decimal_digits = 17; + static const int kappa = 2; + static const int big_divisor = 1000; + static const int small_divisor = 100; + static const int min_k = -292; + static const int max_k = 326; + static const int cache_bits = 128; + static const int divisibility_check_by_5_threshold = 86; + static const int case_fc_pm_half_lower_threshold = -2; + static const int case_fc_pm_half_upper_threshold = 9; + static const int case_fc_lower_threshold = -4; + static const int case_fc_upper_threshold = 9; + static const int case_shorter_interval_left_endpoint_lower_threshold = 2; + static const int case_shorter_interval_left_endpoint_upper_threshold = 3; + static const int shorter_interval_tie_lower_threshold = -77; + static const int shorter_interval_tie_upper_threshold = -77; + static const int max_trailing_zeros = 16; +}; + +template struct decimal_fp { + using significand_type = typename float_info::carrier_uint; + significand_type significand; + int exponent; +}; + +template FMT_API decimal_fp to_decimal(T x) FMT_NOEXCEPT; +} // namespace dragonbox + +template +constexpr typename dragonbox::float_info::carrier_uint exponent_mask() { + using uint = typename dragonbox::float_info::carrier_uint; + return ((uint(1) << dragonbox::float_info::exponent_bits) - 1) + << dragonbox::float_info::significand_bits; +} // A floating-point presentation format. enum class float_format : unsigned char { @@ -1049,10 +1290,9 @@ struct float_specs { sign_t sign : 8; bool upper : 1; bool locale : 1; - bool percent : 1; bool binary32 : 1; bool use_grisu : 1; - bool trailing_zeros : 1; + bool showpoint : 1; }; // Writes the exponent exp in the form "[+-]d{2,3}" to buffer. @@ -1065,123 +1305,17 @@ template It write_exponent(int exp, It it) { *it++ = static_cast('+'); } if (exp >= 100) { - const char* top = data::digits + (exp / 100) * 2; + const char* top = data::digits[exp / 100]; if (exp >= 1000) *it++ = static_cast(top[0]); *it++ = static_cast(top[1]); exp %= 100; } - const char* d = data::digits + exp * 2; + const char* d = data::digits[exp]; *it++ = static_cast(d[0]); *it++ = static_cast(d[1]); return it; } -template class float_writer { - private: - // The number is given as v = digits_ * pow(10, exp_). - const char* digits_; - int num_digits_; - int exp_; - size_t size_; - float_specs specs_; - Char decimal_point_; - - template It prettify(It it) const { - // pow(10, full_exp - 1) <= v <= pow(10, full_exp). - int full_exp = num_digits_ + exp_; - if (specs_.format == float_format::exp) { - // Insert a decimal point after the first digit and add an exponent. - *it++ = static_cast(*digits_); - int num_zeros = specs_.precision - num_digits_; - bool trailing_zeros = num_zeros > 0 && specs_.trailing_zeros; - if (num_digits_ > 1 || trailing_zeros) *it++ = decimal_point_; - it = copy_str(digits_ + 1, digits_ + num_digits_, it); - if (trailing_zeros) - it = std::fill_n(it, num_zeros, static_cast('0')); - *it++ = static_cast(specs_.upper ? 'E' : 'e'); - return write_exponent(full_exp - 1, it); - } - if (num_digits_ <= full_exp) { - // 1234e7 -> 12340000000[.0+] - it = copy_str(digits_, digits_ + num_digits_, it); - it = std::fill_n(it, full_exp - num_digits_, static_cast('0')); - if (specs_.trailing_zeros) { - *it++ = decimal_point_; - int num_zeros = specs_.precision - full_exp; - if (num_zeros <= 0) { - if (specs_.format != float_format::fixed) - *it++ = static_cast('0'); - return it; - } -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - if (num_zeros > 1000) - throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); -#endif - it = std::fill_n(it, num_zeros, static_cast('0')); - } - } else if (full_exp > 0) { - // 1234e-2 -> 12.34[0+] - it = copy_str(digits_, digits_ + full_exp, it); - if (!specs_.trailing_zeros) { - // Remove trailing zeros. - int num_digits = num_digits_; - while (num_digits > full_exp && digits_[num_digits - 1] == '0') - --num_digits; - if (num_digits != full_exp) *it++ = decimal_point_; - return copy_str(digits_ + full_exp, digits_ + num_digits, it); - } - *it++ = decimal_point_; - it = copy_str(digits_ + full_exp, digits_ + num_digits_, it); - if (specs_.precision > num_digits_) { - // Add trailing zeros. - int num_zeros = specs_.precision - num_digits_; - it = std::fill_n(it, num_zeros, static_cast('0')); - } - } else { - // 1234e-6 -> 0.001234 - *it++ = static_cast('0'); - int num_zeros = -full_exp; - if (specs_.precision >= 0 && specs_.precision < num_zeros) - num_zeros = specs_.precision; - int num_digits = num_digits_; - if (!specs_.trailing_zeros) - while (num_digits > 0 && digits_[num_digits - 1] == '0') --num_digits; - if (num_zeros != 0 || num_digits != 0) { - *it++ = decimal_point_; - it = std::fill_n(it, num_zeros, static_cast('0')); - it = copy_str(digits_, digits_ + num_digits, it); - } - } - return it; - } - - public: - float_writer(const char* digits, int num_digits, int exp, float_specs specs, - Char decimal_point) - : digits_(digits), - num_digits_(num_digits), - exp_(exp), - specs_(specs), - decimal_point_(decimal_point) { - int full_exp = num_digits + exp - 1; - int precision = specs.precision > 0 ? specs.precision : 16; - if (specs_.format == float_format::general && - !(full_exp >= -4 && full_exp < precision)) { - specs_.format = float_format::exp; - } - size_ = prettify(counting_iterator()).count(); - size_ += specs.sign ? 1 : 0; - } - - size_t size() const { return size_; } - size_t width() const { return size(); } - - template void operator()(It&& it) { - if (specs_.sign) *it++ = static_cast(data::signs[specs_.sign]); - it = prettify(it); - } -}; - template int format_float(T value, int precision, float_specs specs, buffer& buf); @@ -1191,7 +1325,7 @@ int snprintf_float(T value, int precision, float_specs specs, buffer& buf); template T promote_float(T value) { return value; } -inline double promote_float(float value) { return value; } +inline double promote_float(float value) { return static_cast(value); } template FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) { @@ -1211,9 +1345,15 @@ FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) { case 'o': handler.on_oct(); break; +#ifdef FMT_DEPRECATED_N_SPECIFIER case 'n': +#endif + case 'L': handler.on_num(); break; + case 'c': + handler.on_chr(); + break; default: handler.on_error(); } @@ -1223,11 +1363,11 @@ template FMT_CONSTEXPR float_specs parse_float_type_spec( const basic_format_specs& specs, ErrorHandler&& eh = {}) { auto result = float_specs(); - result.trailing_zeros = specs.alt; + result.showpoint = specs.alt; switch (specs.type) { case 0: result.format = float_format::general; - result.trailing_zeros |= specs.precision != 0; + result.showpoint |= specs.precision > 0; break; case 'G': result.upper = true; @@ -1240,28 +1380,25 @@ FMT_CONSTEXPR float_specs parse_float_type_spec( FMT_FALLTHROUGH; case 'e': result.format = float_format::exp; - result.trailing_zeros |= specs.precision != 0; + result.showpoint |= specs.precision != 0; break; case 'F': result.upper = true; FMT_FALLTHROUGH; case 'f': result.format = float_format::fixed; - result.trailing_zeros |= specs.precision != 0; + result.showpoint |= specs.precision != 0; break; -#if FMT_DEPRECATED_PERCENT - case '%': - result.format = float_format::fixed; - result.percent = true; - break; -#endif case 'A': result.upper = true; FMT_FALLTHROUGH; case 'a': result.format = float_format::hex; break; +#ifdef FMT_DEPRECATED_N_SPECIFIER case 'n': +#endif + case 'L': result.locale = true; break; default: @@ -1310,6 +1447,7 @@ template class int_type_checker : private ErrorHandler { FMT_CONSTEXPR void on_bin() {} FMT_CONSTEXPR void on_oct() {} FMT_CONSTEXPR void on_num() {} + FMT_CONSTEXPR void on_chr() {} FMT_CONSTEXPR void on_error() { ErrorHandler::on_error("invalid type specifier"); @@ -1341,386 +1479,669 @@ class cstring_type_checker : public ErrorHandler { FMT_CONSTEXPR void on_pointer() {} }; -template -void arg_map::init(const basic_format_args& args) { - if (map_) return; - map_ = new entry[internal::to_unsigned(args.max_size())]; - if (args.is_packed()) { - for (int i = 0;; ++i) { - internal::type arg_type = args.type(i); - if (arg_type == internal::none_type) return; - if (arg_type == internal::named_arg_type) push_back(args.values_[i]); - } - } - for (int i = 0, n = args.max_size(); i < n; ++i) { - auto type = args.args_[i].type_; - if (type == internal::named_arg_type) push_back(args.args_[i].value_); - } +template +FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t& fill) { + auto fill_size = fill.size(); + if (fill_size == 1) return std::fill_n(it, n, fill[0]); + for (size_t i = 0; i < n; ++i) it = std::copy_n(fill.data(), fill_size, it); + return it; } -template struct nonfinite_writer { - sign_t sign; - const char* str; - static constexpr size_t str_size = 3; - - size_t size() const { return str_size + (sign ? 1 : 0); } - size_t width() const { return size(); } - - template void operator()(It&& it) const { - if (sign) *it++ = static_cast(data::signs[sign]); - it = copy_str(str, str + str_size, it); +// Writes the output of f, padded according to format specifications in specs. +// size: output size in code units. +// width: output display width in (terminal) column positions. +template +inline OutputIt write_padded(OutputIt out, + const basic_format_specs& specs, size_t size, + size_t width, F&& f) { + static_assert(align == align::left || align == align::right, ""); + unsigned spec_width = to_unsigned(specs.width); + size_t padding = spec_width > width ? spec_width - width : 0; + auto* shifts = align == align::left ? data::left_padding_shifts + : data::right_padding_shifts; + size_t left_padding = padding >> shifts[specs.align]; + auto it = reserve(out, size + padding * specs.fill.size()); + it = fill(it, left_padding, specs.fill); + it = f(it); + it = fill(it, padding - left_padding, specs.fill); + return base_iterator(out, it); +} + +template +inline OutputIt write_padded(OutputIt out, + const basic_format_specs& specs, size_t size, + F&& f) { + return write_padded(out, specs, size, size, f); +} + +template +OutputIt write_bytes(OutputIt out, string_view bytes, + const basic_format_specs& specs) { + using iterator = remove_reference_t; + return write_padded(out, specs, bytes.size(), [bytes](iterator it) { + const char* data = bytes.data(); + return copy_str(data, data + bytes.size(), it); + }); +} + +// Data for write_int that doesn't depend on output iterator type. It is used to +// avoid template code bloat. +template struct write_int_data { + size_t size; + size_t padding; + + write_int_data(int num_digits, string_view prefix, + const basic_format_specs& specs) + : size(prefix.size() + to_unsigned(num_digits)), padding(0) { + if (specs.align == align::numeric) { + auto width = to_unsigned(specs.width); + if (width > size) { + padding = width - size; + size = width; + } + } else if (specs.precision > num_digits) { + size = prefix.size() + to_unsigned(specs.precision); + padding = to_unsigned(specs.precision - num_digits); + } } }; -// This template provides operations for formatting and writing data into a -// character range. -template class basic_writer { - public: - using char_type = typename Range::value_type; - using iterator = typename Range::iterator; - using format_specs = basic_format_specs; - - private: - iterator out_; // Output iterator. - locale_ref locale_; - - // Attempts to reserve space for n extra characters in the output range. - // Returns a pointer to the reserved range or a reference to out_. - auto reserve(std::size_t n) -> decltype(internal::reserve(out_, n)) { - return internal::reserve(out_, n); +// Writes an integer in the format +// +// where are written by f(it). +template +OutputIt write_int(OutputIt out, int num_digits, string_view prefix, + const basic_format_specs& specs, F f) { + auto data = write_int_data(num_digits, prefix, specs); + using iterator = remove_reference_t; + return write_padded(out, specs, data.size, [=](iterator it) { + if (prefix.size() != 0) + it = copy_str(prefix.begin(), prefix.end(), it); + it = std::fill_n(it, data.padding, static_cast('0')); + return f(it); + }); +} + +template +OutputIt write(OutputIt out, basic_string_view s, + const basic_format_specs& specs) { + auto data = s.data(); + auto size = s.size(); + if (specs.precision >= 0 && to_unsigned(specs.precision) < size) + size = code_point_index(s, to_unsigned(specs.precision)); + auto width = specs.width != 0 + ? count_code_points(basic_string_view(data, size)) + : 0; + using iterator = remove_reference_t; + return write_padded(out, specs, size, width, [=](iterator it) { + return copy_str(data, data + size, it); + }); +} + +// The handle_int_type_spec handler that writes an integer. +template struct int_writer { + OutputIt out; + locale_ref locale; + const basic_format_specs& specs; + UInt abs_value; + char prefix[4]; + unsigned prefix_size; + + using iterator = + remove_reference_t(), 0))>; + + string_view get_prefix() const { return string_view(prefix, prefix_size); } + + template + int_writer(OutputIt output, locale_ref loc, Int value, + const basic_format_specs& s) + : out(output), + locale(loc), + specs(s), + abs_value(static_cast(value)), + prefix_size(0) { + static_assert(std::is_same, UInt>::value, ""); + if (is_negative(value)) { + prefix[0] = '-'; + ++prefix_size; + abs_value = 0 - abs_value; + } else if (specs.sign != sign::none && specs.sign != sign::minus) { + prefix[0] = specs.sign == sign::plus ? '+' : ' '; + ++prefix_size; + } } - template struct padded_int_writer { - size_t size_; - string_view prefix; - char_type fill; - std::size_t padding; - F f; - - size_t size() const { return size_; } - size_t width() const { return size_; } + void on_dec() { + auto num_digits = count_digits(abs_value); + out = write_int( + out, num_digits, get_prefix(), specs, [this, num_digits](iterator it) { + return format_decimal(it, abs_value, num_digits).end; + }); + } - template void operator()(It&& it) const { - if (prefix.size() != 0) - it = copy_str(prefix.begin(), prefix.end(), it); - it = std::fill_n(it, padding, fill); - f(it); + void on_hex() { + if (specs.alt) { + prefix[prefix_size++] = '0'; + prefix[prefix_size++] = specs.type; } - }; - - // Writes an integer in the format - // - // where are written by f(it). - template - void write_int(int num_digits, string_view prefix, format_specs specs, F f) { - std::size_t size = prefix.size() + to_unsigned(num_digits); - char_type fill = specs.fill[0]; - std::size_t padding = 0; - if (specs.align == align::numeric) { - auto unsiged_width = to_unsigned(specs.width); - if (unsiged_width > size) { - padding = unsiged_width - size; - size = unsiged_width; - } - } else if (specs.precision > num_digits) { - size = prefix.size() + to_unsigned(specs.precision); - padding = to_unsigned(specs.precision - num_digits); - fill = static_cast('0'); + int num_digits = count_digits<4>(abs_value); + out = write_int(out, num_digits, get_prefix(), specs, + [this, num_digits](iterator it) { + return format_uint<4, Char>(it, abs_value, num_digits, + specs.type != 'x'); + }); + } + + void on_bin() { + if (specs.alt) { + prefix[prefix_size++] = '0'; + prefix[prefix_size++] = static_cast(specs.type); + } + int num_digits = count_digits<1>(abs_value); + out = write_int(out, num_digits, get_prefix(), specs, + [this, num_digits](iterator it) { + return format_uint<1, Char>(it, abs_value, num_digits); + }); + } + + void on_oct() { + int num_digits = count_digits<3>(abs_value); + if (specs.alt && specs.precision <= num_digits && abs_value != 0) { + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + prefix[prefix_size++] = '0'; } - if (specs.align == align::none) specs.align = align::right; - write_padded(specs, padded_int_writer{size, prefix, fill, padding, f}); + out = write_int(out, num_digits, get_prefix(), specs, + [this, num_digits](iterator it) { + return format_uint<3, Char>(it, abs_value, num_digits); + }); } - // Writes a decimal integer. - template void write_decimal(Int value) { - auto abs_value = static_cast>(value); - bool negative = is_negative(value); - // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. - if (negative) abs_value = ~abs_value + 1; + enum { sep_size = 1 }; + + void on_num() { + std::string groups = grouping(locale); + if (groups.empty()) return on_dec(); + auto sep = thousands_sep(locale); + if (!sep) return on_dec(); int num_digits = count_digits(abs_value); - auto&& it = reserve((negative ? 1 : 0) + static_cast(num_digits)); - if (negative) *it++ = static_cast('-'); - it = format_decimal(it, abs_value, num_digits); - } - - // The handle_int_type_spec handler that writes an integer. - template struct int_writer { - using unsigned_type = uint32_or_64_or_128_t; - - basic_writer& writer; - const Specs& specs; - unsigned_type abs_value; - char prefix[4]; - unsigned prefix_size; - - string_view get_prefix() const { return string_view(prefix, prefix_size); } - - int_writer(basic_writer& w, Int value, const Specs& s) - : writer(w), - specs(s), - abs_value(static_cast(value)), - prefix_size(0) { - if (is_negative(value)) { - prefix[0] = '-'; - ++prefix_size; - abs_value = 0 - abs_value; - } else if (specs.sign != sign::none && specs.sign != sign::minus) { - prefix[0] = specs.sign == sign::plus ? '+' : ' '; - ++prefix_size; + int size = num_digits, n = num_digits; + std::string::const_iterator group = groups.cbegin(); + while (group != groups.cend() && n > *group && *group > 0 && + *group != max_value()) { + size += sep_size; + n -= *group; + ++group; + } + if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back()); + char digits[40]; + format_decimal(digits, abs_value, num_digits); + basic_memory_buffer buffer; + size += static_cast(prefix_size); + const auto usize = to_unsigned(size); + buffer.resize(usize); + basic_string_view s(&sep, sep_size); + // Index of a decimal digit with the least significant digit having index 0. + int digit_index = 0; + group = groups.cbegin(); + auto p = buffer.data() + size - 1; + for (int i = num_digits - 1; i > 0; --i) { + *p-- = static_cast(digits[i]); + if (*group <= 0 || ++digit_index % *group != 0 || + *group == max_value()) + continue; + if (group + 1 != groups.cend()) { + digit_index = 0; + ++group; } + std::uninitialized_copy(s.data(), s.data() + s.size(), + make_checked(p, s.size())); + p -= s.size(); } + *p-- = static_cast(*digits); + if (prefix_size != 0) *p = static_cast('-'); + auto data = buffer.data(); + out = write_padded( + out, specs, usize, usize, + [=](iterator it) { return copy_str(data, data + size, it); }); + } - struct dec_writer { - unsigned_type abs_value; - int num_digits; + void on_chr() { *out++ = static_cast(abs_value); } - template void operator()(It&& it) const { - it = internal::format_decimal(it, abs_value, num_digits); - } - }; + FMT_NORETURN void on_error() { + FMT_THROW(format_error("invalid type specifier")); + } +}; - void on_dec() { - int num_digits = count_digits(abs_value); - writer.write_int(num_digits, get_prefix(), specs, - dec_writer{abs_value, num_digits}); - } +template +OutputIt write_nonfinite(OutputIt out, bool isinf, + const basic_format_specs& specs, + const float_specs& fspecs) { + auto str = + isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan"); + constexpr size_t str_size = 3; + auto sign = fspecs.sign; + auto size = str_size + (sign ? 1 : 0); + using iterator = remove_reference_t; + return write_padded(out, specs, size, [=](iterator it) { + if (sign) *it++ = static_cast(data::signs[sign]); + return copy_str(str, str + str_size, it); + }); +} - struct hex_writer { - int_writer& self; - int num_digits; +// A decimal floating-point number significand * pow(10, exp). +struct big_decimal_fp { + const char* significand; + int significand_size; + int exponent; +}; - template void operator()(It&& it) const { - it = format_uint<4, char_type>(it, self.abs_value, num_digits, - self.specs.type != 'x'); - } - }; +inline int get_significand_size(const big_decimal_fp& fp) { + return fp.significand_size; +} +template +inline int get_significand_size(const dragonbox::decimal_fp& fp) { + return count_digits(fp.significand); +} + +template +inline OutputIt write_significand(OutputIt out, const char* significand, + int& significand_size) { + return copy_str(significand, significand + significand_size, out); +} +template +inline OutputIt write_significand(OutputIt out, UInt significand, + int significand_size) { + return format_decimal(out, significand, significand_size).end; +} + +template ::value)> +inline Char* write_significand(Char* out, UInt significand, + int significand_size, int integral_size, + Char decimal_point) { + if (!decimal_point) + return format_decimal(out, significand, significand_size).end; + auto end = format_decimal(out + 1, significand, significand_size).end; + if (integral_size == 1) + out[0] = out[1]; + else + std::copy_n(out + 1, integral_size, out); + out[integral_size] = decimal_point; + return end; +} - void on_hex() { - if (specs.alt) { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = specs.type; - } - int num_digits = count_digits<4>(abs_value); - writer.write_int(num_digits, get_prefix(), specs, - hex_writer{*this, num_digits}); +template >::value)> +inline OutputIt write_significand(OutputIt out, UInt significand, + int significand_size, int integral_size, + Char decimal_point) { + // Buffer is large enough to hold digits (digits10 + 1) and a decimal point. + Char buffer[digits10() + 2]; + auto end = write_significand(buffer, significand, significand_size, + integral_size, decimal_point); + return detail::copy_str(buffer, end, out); +} + +template +inline OutputIt write_significand(OutputIt out, const char* significand, + int significand_size, int integral_size, + Char decimal_point) { + out = detail::copy_str(significand, significand + integral_size, out); + if (!decimal_point) return out; + *out++ = decimal_point; + return detail::copy_str(significand + integral_size, + significand + significand_size, out); +} + +template +OutputIt write_float(OutputIt out, const DecimalFP& fp, + const basic_format_specs& specs, float_specs fspecs, + Char decimal_point) { + auto significand = fp.significand; + int significand_size = get_significand_size(fp); + static const Char zero = static_cast('0'); + auto sign = fspecs.sign; + size_t size = to_unsigned(significand_size) + (sign ? 1 : 0); + using iterator = remove_reference_t; + + int output_exp = fp.exponent + significand_size - 1; + auto use_exp_format = [=]() { + if (fspecs.format == float_format::exp) return true; + if (fspecs.format != float_format::general) return false; + // Use the fixed notation if the exponent is in [exp_lower, exp_upper), + // e.g. 0.0001 instead of 1e-04. Otherwise use the exponent notation. + const int exp_lower = -4, exp_upper = 16; + return output_exp < exp_lower || + output_exp >= (fspecs.precision > 0 ? fspecs.precision : exp_upper); + }; + if (use_exp_format()) { + int num_zeros = 0; + if (fspecs.showpoint) { + num_zeros = (std::max)(fspecs.precision - significand_size, 0); + size += to_unsigned(num_zeros); + } else if (significand_size == 1) { + decimal_point = Char(); + } + auto abs_output_exp = output_exp >= 0 ? output_exp : -output_exp; + int exp_digits = 2; + if (abs_output_exp >= 100) exp_digits = abs_output_exp >= 1000 ? 4 : 3; + + size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits); + char exp_char = fspecs.upper ? 'E' : 'e'; + auto write = [=](iterator it) { + if (sign) *it++ = static_cast(data::signs[sign]); + // Insert a decimal point after the first digit and add an exponent. + it = write_significand(it, significand, significand_size, 1, + decimal_point); + if (num_zeros > 0) it = std::fill_n(it, num_zeros, zero); + *it++ = static_cast(exp_char); + return write_exponent(output_exp, it); + }; + return specs.width > 0 ? write_padded(out, specs, size, write) + : base_iterator(out, write(reserve(out, size))); + } + + int exp = fp.exponent + significand_size; + if (fp.exponent >= 0) { + // 1234e5 -> 123400000[.0+] + size += to_unsigned(fp.exponent); + int num_zeros = fspecs.precision - exp; +#ifdef FMT_FUZZ + if (num_zeros > 5000) + throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); +#endif + if (fspecs.showpoint) { + if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1; + if (num_zeros > 0) size += to_unsigned(num_zeros); } + return write_padded(out, specs, size, [&](iterator it) { + if (sign) *it++ = static_cast(data::signs[sign]); + it = write_significand(it, significand, significand_size); + it = std::fill_n(it, fp.exponent, zero); + if (!fspecs.showpoint) return it; + *it++ = decimal_point; + return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it; + }); + } else if (exp > 0) { + // 1234e-2 -> 12.34[0+] + int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0; + size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0); + return write_padded(out, specs, size, [&](iterator it) { + if (sign) *it++ = static_cast(data::signs[sign]); + it = write_significand(it, significand, significand_size, exp, + decimal_point); + return num_zeros > 0 ? std::fill_n(it, num_zeros, zero) : it; + }); + } + // 1234e-6 -> 0.001234 + int num_zeros = -exp; + if (significand_size == 0 && fspecs.precision >= 0 && + fspecs.precision < num_zeros) { + num_zeros = fspecs.precision; + } + size += 2 + to_unsigned(num_zeros); + return write_padded(out, specs, size, [&](iterator it) { + if (sign) *it++ = static_cast(data::signs[sign]); + *it++ = zero; + if (num_zeros == 0 && significand_size == 0 && !fspecs.showpoint) return it; + *it++ = decimal_point; + it = std::fill_n(it, num_zeros, zero); + return write_significand(it, significand, significand_size); + }); +} + +template ::value)> +OutputIt write(OutputIt out, T value, basic_format_specs specs, + locale_ref loc = {}) { + if (const_check(!is_supported_floating_point(value))) return out; + float_specs fspecs = parse_float_type_spec(specs); + fspecs.sign = specs.sign; + if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. + fspecs.sign = sign::minus; + value = -value; + } else if (fspecs.sign == sign::minus) { + fspecs.sign = sign::none; + } + + if (!std::isfinite(value)) + return write_nonfinite(out, std::isinf(value), specs, fspecs); + + if (specs.align == align::numeric && fspecs.sign) { + auto it = reserve(out, 1); + *it++ = static_cast(data::signs[fspecs.sign]); + out = base_iterator(out, it); + fspecs.sign = sign::none; + if (specs.width != 0) --specs.width; + } + + memory_buffer buffer; + if (fspecs.format == float_format::hex) { + if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); + snprintf_float(promote_float(value), specs.precision, fspecs, buffer); + return write_bytes(out, {buffer.data(), buffer.size()}, specs); + } + int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; + if (fspecs.format == float_format::exp) { + if (precision == max_value()) + FMT_THROW(format_error("number is too big")); + else + ++precision; + } + if (const_check(std::is_same())) fspecs.binary32 = true; + fspecs.use_grisu = is_fast_float(); + int exp = format_float(promote_float(value), precision, fspecs, buffer); + fspecs.precision = precision; + Char point = + fspecs.locale ? decimal_point(loc) : static_cast('.'); + auto fp = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; + return write_float(out, fp, specs, fspecs, point); +} - template struct bin_writer { - unsigned_type abs_value; - int num_digits; +template ::value)> +OutputIt write(OutputIt out, T value) { + if (const_check(!is_supported_floating_point(value))) return out; - template void operator()(It&& it) const { - it = format_uint(it, abs_value, num_digits); - } - }; + using floaty = conditional_t::value, double, T>; + using uint = typename dragonbox::float_info::carrier_uint; + auto bits = bit_cast(value); - void on_bin() { - if (specs.alt) { - prefix[prefix_size++] = '0'; - prefix[prefix_size++] = static_cast(specs.type); - } - int num_digits = count_digits<1>(abs_value); - writer.write_int(num_digits, get_prefix(), specs, - bin_writer<1>{abs_value, num_digits}); - } + auto fspecs = float_specs(); + auto sign_bit = bits & (uint(1) << (num_bits() - 1)); + if (sign_bit != 0) { + fspecs.sign = sign::minus; + value = -value; + } - void on_oct() { - int num_digits = count_digits<3>(abs_value); - if (specs.alt && specs.precision <= num_digits && abs_value != 0) { - // Octal prefix '0' is counted as a digit, so only add it if precision - // is not greater than the number of digits. - prefix[prefix_size++] = '0'; - } - writer.write_int(num_digits, get_prefix(), specs, - bin_writer<3>{abs_value, num_digits}); - } + static const auto specs = basic_format_specs(); + uint mask = exponent_mask(); + if ((bits & mask) == mask) + return write_nonfinite(out, std::isinf(value), specs, fspecs); - enum { sep_size = 1 }; - - struct num_writer { - unsigned_type abs_value; - int size; - const std::string& groups; - char_type sep; - - template void operator()(It&& it) const { - basic_string_view s(&sep, sep_size); - // Index of a decimal digit with the least significant digit having - // index 0. - int digit_index = 0; - std::string::const_iterator group = groups.cbegin(); - it = format_decimal( - it, abs_value, size, - [this, s, &group, &digit_index](char_type*& buffer) { - if (*group <= 0 || ++digit_index % *group != 0 || - *group == max_value()) - return; - if (group + 1 != groups.cend()) { - digit_index = 0; - ++group; - } - buffer -= s.size(); - std::uninitialized_copy(s.data(), s.data() + s.size(), - make_checked(buffer, s.size())); - }); - } - }; + auto dec = dragonbox::to_decimal(static_cast(value)); + return write_float(out, dec, specs, fspecs, static_cast('.')); +} - void on_num() { - std::string groups = grouping(writer.locale_); - if (groups.empty()) return on_dec(); - auto sep = thousands_sep(writer.locale_); - if (!sep) return on_dec(); - int num_digits = count_digits(abs_value); - int size = num_digits; - std::string::const_iterator group = groups.cbegin(); - while (group != groups.cend() && num_digits > *group && *group > 0 && - *group != max_value()) { - size += sep_size; - num_digits -= *group; - ++group; - } - if (group == groups.cend()) - size += sep_size * ((num_digits - 1) / groups.back()); - writer.write_int(size, get_prefix(), specs, - num_writer{abs_value, size, groups, sep}); - } +template ::value && + !is_fast_float::value)> +inline OutputIt write(OutputIt out, T value) { + return write(out, value, basic_format_specs()); +} - FMT_NORETURN void on_error() { - FMT_THROW(format_error("invalid type specifier")); - } +template +OutputIt write_char(OutputIt out, Char value, + const basic_format_specs& specs) { + using iterator = remove_reference_t; + return write_padded(out, specs, 1, [=](iterator it) { + *it++ = value; + return it; + }); +} + +template +OutputIt write_ptr(OutputIt out, UIntPtr value, + const basic_format_specs* specs) { + int num_digits = count_digits<4>(value); + auto size = to_unsigned(num_digits) + size_t(2); + using iterator = remove_reference_t; + auto write = [=](iterator it) { + *it++ = static_cast('0'); + *it++ = static_cast('x'); + return format_uint<4, Char>(it, value, num_digits); }; + return specs ? write_padded(out, *specs, size, write) + : base_iterator(out, write(reserve(out, size))); +} - template struct str_writer { - const Char* s; - size_t size_; +template struct is_integral : std::is_integral {}; +template <> struct is_integral : std::true_type {}; +template <> struct is_integral : std::true_type {}; - size_t size() const { return size_; } - size_t width() const { - return count_code_points(basic_string_view(s, size_)); - } +template +OutputIt write(OutputIt out, monostate) { + FMT_ASSERT(false, ""); + return out; +} - template void operator()(It&& it) const { - it = copy_str(s, s + size_, it); - } - }; +template ::value)> +OutputIt write(OutputIt out, string_view value) { + auto it = reserve(out, value.size()); + it = copy_str(value.begin(), value.end(), it); + return base_iterator(out, it); +} - template struct pointer_writer { - UIntPtr value; - int num_digits; +template +OutputIt write(OutputIt out, basic_string_view value) { + auto it = reserve(out, value.size()); + it = std::copy(value.begin(), value.end(), it); + return base_iterator(out, it); +} - size_t size() const { return to_unsigned(num_digits) + 2; } - size_t width() const { return size(); } +template +buffer_appender write(buffer_appender out, + basic_string_view value) { + get_container(out).append(value.begin(), value.end()); + return out; +} + +template ::value && + !std::is_same::value && + !std::is_same::value)> +OutputIt write(OutputIt out, T value) { + auto abs_value = static_cast>(value); + bool negative = is_negative(value); + // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. + if (negative) abs_value = ~abs_value + 1; + int num_digits = count_digits(abs_value); + auto size = (negative ? 1 : 0) + static_cast(num_digits); + auto it = reserve(out, size); + if (auto ptr = to_pointer(it, size)) { + if (negative) *ptr++ = static_cast('-'); + format_decimal(ptr, abs_value, num_digits); + return out; + } + if (negative) *it++ = static_cast('-'); + it = format_decimal(it, abs_value, num_digits).end; + return base_iterator(out, it); +} - template void operator()(It&& it) const { - *it++ = static_cast('0'); - *it++ = static_cast('x'); - it = format_uint<4, char_type>(it, value, num_digits); - } - }; +template +OutputIt write(OutputIt out, bool value) { + return write(out, string_view(value ? "true" : "false")); +} - public: - explicit basic_writer(Range out, locale_ref loc = locale_ref()) - : out_(out.begin()), locale_(loc) {} - - iterator out() const { return out_; } - - // Writes a value in the format - // - // where is written by f(it). - template void write_padded(const format_specs& specs, F&& f) { - // User-perceived width (in code points). - unsigned width = to_unsigned(specs.width); - size_t size = f.size(); // The number of code units. - size_t num_code_points = width != 0 ? f.width() : size; - if (width <= num_code_points) return f(reserve(size)); - auto&& it = reserve(width + (size - num_code_points)); - char_type fill = specs.fill[0]; - std::size_t padding = width - num_code_points; - if (specs.align == align::right) { - it = std::fill_n(it, padding, fill); - f(it); - } else if (specs.align == align::center) { - std::size_t left_padding = padding / 2; - it = std::fill_n(it, left_padding, fill); - f(it); - it = std::fill_n(it, padding - left_padding, fill); - } else { - f(it); - it = std::fill_n(it, padding, fill); - } +template +OutputIt write(OutputIt out, Char value) { + auto it = reserve(out, 1); + *it++ = value; + return base_iterator(out, it); +} + +template +OutputIt write(OutputIt out, const Char* value) { + if (!value) { + FMT_THROW(format_error("string pointer is null")); + } else { + auto length = std::char_traits::length(value); + out = write(out, basic_string_view(value, length)); } + return out; +} - void write(int value) { write_decimal(value); } - void write(long value) { write_decimal(value); } - void write(long long value) { write_decimal(value); } +template +OutputIt write(OutputIt out, const void* value) { + return write_ptr(out, to_uintptr(value), nullptr); +} - void write(unsigned value) { write_decimal(value); } - void write(unsigned long value) { write_decimal(value); } - void write(unsigned long long value) { write_decimal(value); } +template +auto write(OutputIt out, const T& value) -> typename std::enable_if< + mapped_type_constant>::value == + type::custom_type, + OutputIt>::type { + using context_type = basic_format_context; + using formatter_type = + conditional_t::value, + typename context_type::template formatter_type, + fallback_formatter>; + context_type ctx(out, {}, {}); + return formatter_type().format(value, ctx); +} -#if FMT_USE_INT128 - void write(int128_t value) { write_decimal(value); } - void write(uint128_t value) { write_decimal(value); } -#endif +// An argument visitor that formats the argument and writes it via the output +// iterator. It's a class and not a generic lambda for compatibility with C++11. +template struct default_arg_formatter { + using context = basic_format_context; - template - void write_int(T value, const Spec& spec) { - handle_int_type_spec(spec.type, int_writer(*this, value, spec)); + OutputIt out; + basic_format_args args; + locale_ref loc; + + template OutputIt operator()(T value) { + return write(out, value); } - template ::value)> - void write(T value, format_specs specs = {}) { - float_specs fspecs = parse_float_type_spec(specs); - fspecs.sign = specs.sign; - if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. - fspecs.sign = sign::minus; - value = -value; - } else if (fspecs.sign == sign::minus) { - fspecs.sign = sign::none; - } + OutputIt operator()(typename basic_format_arg::handle handle) { + basic_format_parse_context parse_ctx({}); + basic_format_context format_ctx(out, args, loc); + handle.format(parse_ctx, format_ctx); + return format_ctx.out(); + } +}; - if (!std::isfinite(value)) { - auto str = std::isinf(value) ? (fspecs.upper ? "INF" : "inf") - : (fspecs.upper ? "NAN" : "nan"); - return write_padded(specs, nonfinite_writer{fspecs.sign, str}); - } +template +class arg_formatter_base { + public: + using iterator = OutputIt; + using char_type = Char; + using format_specs = basic_format_specs; - if (specs.align == align::none) { - specs.align = align::right; - } else if (specs.align == align::numeric) { - if (fspecs.sign) { - auto&& it = reserve(1); - *it++ = static_cast(data::signs[fspecs.sign]); - fspecs.sign = sign::none; - if (specs.width != 0) --specs.width; - } - specs.align = align::right; - } + private: + iterator out_; + locale_ref locale_; + format_specs* specs_; - memory_buffer buffer; - if (fspecs.format == float_format::hex) { - if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); - snprintf_float(promote_float(value), specs.precision, fspecs, buffer); - write_padded(specs, str_writer{buffer.data(), buffer.size()}); - return; - } - int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; - if (fspecs.format == float_format::exp) ++precision; - if (const_check(std::is_same())) fspecs.binary32 = true; - fspecs.use_grisu = use_grisu(); - if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) value *= 100; - int exp = format_float(promote_float(value), precision, fspecs, buffer); - if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) { - buffer.push_back('%'); - --exp; // Adjust decimal place position. - } - fspecs.precision = precision; - char_type point = fspecs.locale ? decimal_point(locale_) - : static_cast('.'); - write_padded(specs, float_writer(buffer.data(), - static_cast(buffer.size()), - exp, fspecs, point)); + // Attempts to reserve space for n extra characters in the output range. + // Returns a pointer to the reserved range or a reference to out_. + auto reserve(size_t n) -> decltype(detail::reserve(out_, n)) { + return detail::reserve(out_, n); + } + + using reserve_iterator = remove_reference_t(), 0))>; + + template void write_int(T value, const format_specs& spec) { + using uint_type = uint32_or_64_or_128_t; + int_writer w(out_, locale_, value, spec); + handle_int_type_spec(spec.type, w); + out_ = w.out; } void write(char value) { @@ -1728,191 +2149,193 @@ template class basic_writer { *it++ = value; } - template ::value)> - void write(Char value) { - auto&& it = reserve(1); - *it++ = value; + template ::value)> + void write(Ch value) { + out_ = detail::write(out_, value); } void write(string_view value) { auto&& it = reserve(value.size()); - it = copy_str(value.begin(), value.end(), it); + it = copy_str(value.begin(), value.end(), it); } void write(wstring_view value) { - static_assert(std::is_same::value, ""); + static_assert(std::is_same::value, ""); auto&& it = reserve(value.size()); it = std::copy(value.begin(), value.end(), it); } - template - void write(const Char* s, std::size_t size, const format_specs& specs) { - write_padded(specs, str_writer{s, size}); + template + void write(const Ch* s, size_t size, const format_specs& specs) { + auto width = specs.width != 0 + ? count_code_points(basic_string_view(s, size)) + : 0; + out_ = write_padded(out_, specs, size, width, [=](reserve_iterator it) { + return copy_str(s, s + size, it); + }); } - template - void write(basic_string_view s, const format_specs& specs = {}) { - const Char* data = s.data(); - std::size_t size = s.size(); - if (specs.precision >= 0 && to_unsigned(specs.precision) < size) - size = code_point_index(s, to_unsigned(specs.precision)); - write(data, size, specs); + template + void write(basic_string_view s, const format_specs& specs = {}) { + out_ = detail::write(out_, s, specs); } - template - void write_pointer(UIntPtr value, const format_specs* specs) { - int num_digits = count_digits<4>(value); - auto pw = pointer_writer{value, num_digits}; - if (!specs) return pw(reserve(to_unsigned(num_digits) + 2)); - format_specs specs_copy = *specs; - if (specs_copy.align == align::none) specs_copy.align = align::right; - write_padded(specs_copy, pw); + void write_pointer(const void* p) { + out_ = write_ptr(out_, to_uintptr(p), specs_); } -}; - -using writer = basic_writer>; -template struct is_integral : std::is_integral {}; -template <> struct is_integral : std::true_type {}; -template <> struct is_integral : std::true_type {}; + struct char_spec_handler : ErrorHandler { + arg_formatter_base& formatter; + Char value; -template -class arg_formatter_base { - public: - using char_type = typename Range::value_type; - using iterator = typename Range::iterator; - using format_specs = basic_format_specs; + char_spec_handler(arg_formatter_base& f, Char val) + : formatter(f), value(val) {} - private: - using writer_type = basic_writer; - writer_type writer_; - format_specs* specs_; + void on_int() { + // char is only formatted as int if there are specs. + formatter.write_int(static_cast(value), *formatter.specs_); + } + void on_char() { + if (formatter.specs_) + formatter.out_ = write_char(formatter.out_, value, *formatter.specs_); + else + formatter.write(value); + } + }; - struct char_writer { - char_type value; + struct cstring_spec_handler : error_handler { + arg_formatter_base& formatter; + const Char* value; - size_t size() const { return 1; } - size_t width() const { return 1; } + cstring_spec_handler(arg_formatter_base& f, const Char* val) + : formatter(f), value(val) {} - template void operator()(It&& it) const { *it++ = value; } + void on_string() { formatter.write(value); } + void on_pointer() { formatter.write_pointer(value); } }; - void write_char(char_type value) { - if (specs_) - writer_.write_padded(*specs_, char_writer{value}); - else - writer_.write(value); - } - - void write_pointer(const void* p) { - writer_.write_pointer(internal::to_uintptr(p), specs_); - } - protected: - writer_type& writer() { return writer_; } - FMT_DEPRECATED format_specs* spec() { return specs_; } + iterator out() { return out_; } format_specs* specs() { return specs_; } - iterator out() { return writer_.out(); } void write(bool value) { - string_view sv(value ? "true" : "false"); - specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); + if (specs_) + write(string_view(value ? "true" : "false"), *specs_); + else + out_ = detail::write(out_, value); } - void write(const char_type* value) { + void write(const Char* value) { if (!value) { FMT_THROW(format_error("string pointer is null")); } else { auto length = std::char_traits::length(value); basic_string_view sv(value, length); - specs_ ? writer_.write(sv, *specs_) : writer_.write(sv); + specs_ ? write(sv, *specs_) : write(sv); } } public: - arg_formatter_base(Range r, format_specs* s, locale_ref loc) - : writer_(r, loc), specs_(s) {} + arg_formatter_base(OutputIt out, format_specs* s, locale_ref loc) + : out_(out), locale_(loc), specs_(s) {} iterator operator()(monostate) { FMT_ASSERT(false, "invalid argument type"); - return out(); + return out_; } template ::value)> - iterator operator()(T value) { + FMT_INLINE iterator operator()(T value) { if (specs_) - writer_.write_int(value, *specs_); + write_int(value, *specs_); else - writer_.write(value); - return out(); + out_ = detail::write(out_, value); + return out_; } - iterator operator()(char_type value) { - internal::handle_char_specs( - specs_, char_spec_handler(*this, static_cast(value))); - return out(); + iterator operator()(Char value) { + handle_char_specs(specs_, + char_spec_handler(*this, static_cast(value))); + return out_; } iterator operator()(bool value) { if (specs_ && specs_->type) return (*this)(value ? 1 : 0); write(value != 0); - return out(); + return out_; } template ::value)> iterator operator()(T value) { - writer_.write(value, specs_ ? *specs_ : format_specs()); - return out(); + auto specs = specs_ ? *specs_ : format_specs(); + if (const_check(is_supported_floating_point(value))) + out_ = detail::write(out_, value, specs, locale_); + else + FMT_ASSERT(false, "unsupported float argument type"); + return out_; } - struct char_spec_handler : ErrorHandler { - arg_formatter_base& formatter; - char_type value; - - char_spec_handler(arg_formatter_base& f, char_type val) - : formatter(f), value(val) {} - - void on_int() { - if (formatter.specs_) - formatter.writer_.write_int(value, *formatter.specs_); - else - formatter.writer_.write(value); - } - void on_char() { formatter.write_char(value); } - }; - - struct cstring_spec_handler : internal::error_handler { - arg_formatter_base& formatter; - const char_type* value; - - cstring_spec_handler(arg_formatter_base& f, const char_type* val) - : formatter(f), value(val) {} - - void on_string() { formatter.write(value); } - void on_pointer() { formatter.write_pointer(value); } - }; - - iterator operator()(const char_type* value) { - if (!specs_) return write(value), out(); - internal::handle_cstring_type_spec(specs_->type, - cstring_spec_handler(*this, value)); - return out(); + iterator operator()(const Char* value) { + if (!specs_) return write(value), out_; + handle_cstring_type_spec(specs_->type, cstring_spec_handler(*this, value)); + return out_; } - iterator operator()(basic_string_view value) { + iterator operator()(basic_string_view value) { if (specs_) { - internal::check_string_type_spec(specs_->type, internal::error_handler()); - writer_.write(value, *specs_); + check_string_type_spec(specs_->type, error_handler()); + write(value, *specs_); } else { - writer_.write(value); + write(value); } - return out(); + return out_; } iterator operator()(const void* value) { - if (specs_) - check_pointer_type_spec(specs_->type, internal::error_handler()); + if (specs_) check_pointer_type_spec(specs_->type, error_handler()); write_pointer(value); - return out(); + return out_; + } +}; + +/** The default argument formatter. */ +template +class arg_formatter : public arg_formatter_base { + private: + using char_type = Char; + using base = arg_formatter_base; + using context_type = basic_format_context; + + context_type& ctx_; + basic_format_parse_context* parse_ctx_; + const Char* ptr_; + + public: + using iterator = typename base::iterator; + using format_specs = typename base::format_specs; + + /** + \rst + Constructs an argument formatter object. + *ctx* is a reference to the formatting context, + *specs* contains format specifier information for standard argument types. + \endrst + */ + explicit arg_formatter( + context_type& ctx, + basic_format_parse_context* parse_ctx = nullptr, + format_specs* specs = nullptr, const Char* ptr = nullptr) + : base(ctx.out(), specs, ctx.locale()), + ctx_(ctx), + parse_ctx_(parse_ctx), + ptr_(ptr) {} + + using base::operator(); + + /** Formats an argument of a user-defined type. */ + iterator operator()(typename basic_format_arg::handle handle) { + if (ptr_) advance_to(*parse_ctx_, ptr_); + handle.format(*parse_ctx_, ctx_); + return ctx_.out(); } }; @@ -1926,10 +2349,6 @@ template FMT_CONSTEXPR int parse_nonnegative_int(const Char*& begin, const Char* end, ErrorHandler&& eh) { FMT_ASSERT(begin != end && '0' <= *begin && *begin <= '9', ""); - if (*begin == '0') { - ++begin; - return 0; - } unsigned value = 0; // Convert to unsigned to prevent a warning. constexpr unsigned max_int = max_value(); @@ -1959,12 +2378,11 @@ template class custom_formatter { Context& ctx) : parse_ctx_(parse_ctx), ctx_(ctx) {} - bool operator()(typename basic_format_arg::handle h) const { + void operator()(typename basic_format_arg::handle h) const { h.format(parse_ctx_, ctx_); - return true; } - template bool operator()(T) const { return false; } + template void operator()(T) const {} }; template @@ -2023,7 +2441,9 @@ template class specs_setter { : specs_(other.specs_) {} FMT_CONSTEXPR void on_align(align_t align) { specs_.align = align; } - FMT_CONSTEXPR void on_fill(Char fill) { specs_.fill[0] = fill; } + FMT_CONSTEXPR void on_fill(basic_string_view fill) { + specs_.fill = fill; + } FMT_CONSTEXPR void on_plus() { specs_.sign = sign::plus; } FMT_CONSTEXPR void on_minus() { specs_.sign = sign::minus; } FMT_CONSTEXPR void on_space() { specs_.sign = sign::space; } @@ -2050,7 +2470,7 @@ template class specs_setter { template class numeric_specs_checker { public: - FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, internal::type arg_type) + FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, detail::type arg_type) : error_handler_(eh), arg_type_(arg_type) {} FMT_CONSTEXPR void require_numeric_argument() { @@ -2060,31 +2480,37 @@ template class numeric_specs_checker { FMT_CONSTEXPR void check_sign() { require_numeric_argument(); - if (is_integral_type(arg_type_) && arg_type_ != int_type && - arg_type_ != long_long_type && arg_type_ != internal::char_type) { + if (is_integral_type(arg_type_) && arg_type_ != type::int_type && + arg_type_ != type::long_long_type && arg_type_ != type::char_type) { error_handler_.on_error("format specifier requires signed argument"); } } FMT_CONSTEXPR void check_precision() { - if (is_integral_type(arg_type_) || arg_type_ == internal::pointer_type) + if (is_integral_type(arg_type_) || arg_type_ == type::pointer_type) error_handler_.on_error("precision not allowed for this argument type"); } private: ErrorHandler& error_handler_; - internal::type arg_type_; + detail::type arg_type_; }; // A format specifier handler that checks if specifiers are consistent with the // argument type. template class specs_checker : public Handler { + private: + numeric_specs_checker checker_; + + // Suppress an MSVC warning about using this in initializer list. + FMT_CONSTEXPR Handler& error_handler() { return *this; } + public: - FMT_CONSTEXPR specs_checker(const Handler& handler, internal::type arg_type) - : Handler(handler), checker_(*this, arg_type) {} + FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type) + : Handler(handler), checker_(error_handler(), arg_type) {} FMT_CONSTEXPR specs_checker(const specs_checker& other) - : Handler(other), checker_(*this, other.arg_type_) {} + : Handler(other), checker_(error_handler(), other.arg_type_) {} FMT_CONSTEXPR void on_align(align_t align) { if (align == align::numeric) checker_.require_numeric_argument(); @@ -2117,9 +2543,6 @@ template class specs_checker : public Handler { } FMT_CONSTEXPR void end_precision() { checker_.check_precision(); } - - private: - numeric_specs_checker checker_; }; template