From b8cf34c691623e4ec329053cbbf68522a855882d Mon Sep 17 00:00:00 2001 From: DongHun Kwak Date: Thu, 5 Dec 2019 15:12:59 +0900 Subject: Imported Upstream version 1.67.0 --- tools/boostdep/depinst/exceptions.txt | 9 + tools/build/doc/src/overview.xml | 40 + tools/build/doc/src/reference.xml | 173 +- tools/build/src/build-system.jam | 223 +- tools/build/src/build/ac.jam | 58 +- tools/build/src/build/alias.jam | 4 + tools/build/src/build/build-request.jam | 55 +- tools/build/src/build/config-cache.jam | 5 + tools/build/src/build/configure.jam | 271 ++- tools/build/src/build/feature.jam | 174 +- tools/build/src/build/generators.jam | 51 +- tools/build/src/build/project.jam | 46 +- tools/build/src/build/property-set.jam | 78 +- tools/build/src/build/property.jam | 85 +- tools/build/src/build/targets.jam | 201 +- tools/build/src/build/toolset.jam | 104 +- tools/build/src/build/type.jam | 3 + tools/build/src/build/version.jam | 6 +- tools/build/src/build/virtual-target.jam | 46 +- tools/build/src/contrib/boost.jam | 8 +- tools/build/src/engine/Jambase | 2318 -------------------- tools/build/src/engine/build.jam | 114 +- tools/build/src/engine/compile.c | 2 +- tools/build/src/engine/debugger.c | 42 +- tools/build/src/engine/execcmd.h | 6 + tools/build/src/engine/execnt.c | 31 +- tools/build/src/engine/execunix.c | 15 + tools/build/src/engine/execvms.c | 1 + tools/build/src/engine/filesys.c | 37 + tools/build/src/engine/filesys.h | 1 + tools/build/src/engine/fileunix.c | 21 - tools/build/src/engine/filevms.c | 21 - tools/build/src/engine/function.c | 32 +- tools/build/src/engine/jam.c | 3 +- tools/build/src/engine/jambase.c | 1621 +------------- tools/build/src/engine/jamgram.c | 1916 ++++++++-------- tools/build/src/engine/jamgram.h | 140 +- tools/build/src/engine/jamgram.y | 145 +- tools/build/src/engine/jamgram.yy | 145 +- tools/build/src/engine/make1.c | 94 +- tools/build/src/engine/output.c | 9 - tools/build/src/engine/patchlevel.h | 12 +- tools/build/src/engine/scan.c | 314 ++- tools/build/src/engine/scan.h | 9 +- tools/build/src/engine/timestamp.c | 10 + tools/build/src/kernel/errors.jam | 14 +- tools/build/src/kernel/modules.jam | 6 +- tools/build/src/tools/asciidoctor.jam | 5 +- tools/build/src/tools/bison.jam | 14 +- tools/build/src/tools/boostbook.jam | 44 +- tools/build/src/tools/bzip2.jam | 29 +- tools/build/src/tools/clang-darwin.jam | 33 +- tools/build/src/tools/clang-linux.jam | 28 +- tools/build/src/tools/clang-vxworks.jam | 33 +- tools/build/src/tools/clang-win.jam | 4 +- tools/build/src/tools/clang.jam | 33 + tools/build/src/tools/common.jam | 30 +- tools/build/src/tools/common_clang_vc.jam | 987 --------- tools/build/src/tools/cw.jam | 2 +- tools/build/src/tools/darwin.jam | 13 +- tools/build/src/tools/diab.jam | 5 +- tools/build/src/tools/doxygen.jam | 22 +- .../build/src/tools/features/relevant-feature.jam | 10 + .../build/src/tools/features/threadapi-feature.jam | 2 +- tools/build/src/tools/flags.jam | 152 ++ tools/build/src/tools/gcc.jam | 760 +++---- tools/build/src/tools/generate.jam | 3 + .../src/tools/generators/archive-generator.jam | 9 +- tools/build/src/tools/generators/lib-generator.jam | 8 +- .../src/tools/generators/linking-generator.jam | 20 +- .../tools/generators/searched-lib-generator.jam | 9 +- tools/build/src/tools/ifort.jam | 2 +- tools/build/src/tools/intel-darwin.jam | 15 +- tools/build/src/tools/intel-linux.jam | 4 +- tools/build/src/tools/intel-vxworks.jam | 4 +- tools/build/src/tools/intel-win.jam | 62 +- tools/build/src/tools/lex.jam | 12 +- tools/build/src/tools/libjpeg.jam | 52 +- tools/build/src/tools/libpng.jam | 45 +- tools/build/src/tools/libtiff.jam | 48 +- tools/build/src/tools/link.jam | 20 +- tools/build/src/tools/lzma.jam | 36 +- tools/build/src/tools/make.jam | 10 +- tools/build/src/tools/mipspro.jam | 4 +- tools/build/src/tools/mpi.jam | 6 +- tools/build/src/tools/msvc.jam | 357 +-- tools/build/src/tools/pgi.jam | 2 - tools/build/src/tools/python.jam | 71 +- tools/build/src/tools/qcc.jam | 3 +- tools/build/src/tools/qt3.jam | 4 +- tools/build/src/tools/qt4.jam | 6 +- tools/build/src/tools/qt5.jam | 6 +- tools/build/src/tools/rc.jam | 2 +- tools/build/src/tools/sass.jam | 2 +- tools/build/src/tools/stage.jam | 4 +- tools/build/src/tools/stlport.jam | 3 + tools/build/src/tools/testing.jam | 142 +- tools/build/src/tools/types/man.jam | 2 +- tools/build/src/tools/types/xml.jam | 2 +- tools/build/src/tools/vmsdecc.jam | 4 +- tools/build/src/tools/xsltproc-config.jam | 2 +- tools/build/src/tools/xsltproc.jam | 84 +- tools/build/src/tools/zlib.jam | 31 +- tools/build/src/tools/zstd.jam | 98 + tools/build/src/util/assert.jam | 32 +- tools/build/src/util/doc.jam | 165 +- tools/build/src/util/indirect.jam | 19 +- tools/build/src/util/option.jam | 2 +- tools/build/src/util/os.jam | 6 +- tools/build/src/util/param.jam | 54 + tools/build/src/util/path.jam | 2 +- tools/build/src/util/print.jam | 10 +- tools/build/src/util/regex.jam | 6 +- tools/build/src/util/sequence.jam | 36 + tools/build/src/util/string.jam | 2 +- tools/build/src/util/utility.jam | 16 +- tools/build/test/BoostBuild.py | 78 +- tools/build/test/Jamfile.jam | 29 + tools/build/test/MockToolset.py | 23 +- tools/build/test/TestToolset.py | 121 + tools/build/test/alias.py | 4 +- tools/build/test/alternatives.py | 21 +- tools/build/test/build_hooks.py | 39 + tools/build/test/builtin_glob.py | 4 +- tools/build/test/builtin_glob_archive.py | 2 +- tools/build/test/command_line_properties.py | 166 ++ tools/build/test/conditionals3.py | 2 +- tools/build/test/conditionals_multiple.py | 2 +- tools/build/test/configuration.py | 69 + tools/build/test/configure.py | 219 ++ tools/build/test/core_action_output.py | 4 +- tools/build/test/core_arguments.py | 2 +- tools/build/test/core_at_file.py | 2 +- tools/build/test/core_bindrule.py | 4 +- tools/build/test/core_d12.py | 2 +- tools/build/test/core_fail_expected.py | 139 ++ tools/build/test/core_import_module.py | 4 +- tools/build/test/core_jamshell.py | 2 +- tools/build/test/core_multifile_actions.py | 2 +- tools/build/test/core_nt_cmd_line.py | 6 +- tools/build/test/core_option_d2.py | 2 +- tools/build/test/core_option_n.py | 2 +- tools/build/test/core_parallel_actions.py | 2 +- .../test/core_parallel_multifile_actions_1.py | 2 +- .../test/core_parallel_multifile_actions_2.py | 2 +- tools/build/test/core_scanner.py | 36 + tools/build/test/core_typecheck.py | 2 +- tools/build/test/core_update_now.py | 18 +- tools/build/test/core_variables_in_actions.py | 2 +- tools/build/test/custom_generator.py | 2 +- tools/build/test/debugger.py | 146 +- tools/build/test/dependency_property.py | 11 +- tools/build/test/dependency_test.py | 4 +- tools/build/test/direct_request_test.py | 68 - tools/build/test/dll_path.py | 17 + tools/build/test/example_make.py | 2 +- tools/build/test/expansion.py | 72 +- tools/build/test/feature_implicit_dependency.py | 113 + tools/build/test/feature_relevant.py | 142 ++ tools/build/test/feature_suppress_import_lib.py | 33 + tools/build/test/file_types.py | 44 + tools/build/test/flags.py | 74 + tools/build/test/free_features_request.py | 42 - tools/build/test/gcc_runtime.py | 5 +- tools/build/test/generator_selection.py | 10 +- tools/build/test/generators_test.py | 18 +- tools/build/test/inline.py | 13 +- tools/build/test/lib_zlib.py | 184 ++ tools/build/test/libjpeg.py | 8 +- tools/build/test/liblzma.py | 118 + tools/build/test/libzstd.py | 118 + tools/build/test/link.py | 4 +- tools/build/test/make_rule.py | 4 +- tools/build/test/message.py | 2 +- tools/build/test/param.py | 61 + tools/build/test/path_features.py | 19 +- tools/build/test/project-test3/jamroot.jam | 4 + tools/build/test/project-test4/jamroot.jam | 7 +- tools/build/test/project_id.py | 4 +- tools/build/test/project_root_rule.py | 2 +- tools/build/test/project_test3.py | 16 +- tools/build/test/project_test4.py | 4 +- tools/build/test/rebuilds.py | 2 +- tools/build/test/regression.py | 113 - tools/build/test/remove_requirement.py | 6 +- tools/build/test/rescan_header.py | 20 +- tools/build/test/source_order.py | 4 +- tools/build/test/space_in_path.py | 32 +- tools/build/test/static_and_shared_library.py | 2 +- tools/build/test/suffix.py | 2 +- tools/build/test/tag.py | 8 +- tools/build/test/test_all.py | 30 +- tools/build/test/test_rc.py | 4 +- tools/build/test/test_result_dumping.py | 33 - tools/build/test/testing.py | 535 +++++ tools/build/test/testing_support.py | 61 - tools/build/test/toolset-mock/Jamroot.jam | 8 + tools/build/test/toolset-mock/lib.cpp | 7 + tools/build/test/toolset-mock/main.cpp | 7 + tools/build/test/toolset-mock/project-config.jam | 40 + tools/build/test/toolset-mock/src/Jamroot.jam | 61 + tools/build/test/toolset-mock/src/MockProgram.py | 260 +++ tools/build/test/toolset-mock/src/ar.py | 24 + .../test/toolset-mock/src/clang-3.9.0-darwin.py | 49 + .../test/toolset-mock/src/clang-linux-3.9.0.py | 48 + .../test/toolset-mock/src/clang-vxworks-4.0.1.py | 42 + tools/build/test/toolset-mock/src/darwin-4.2.1.py | 38 + .../test/toolset-mock/src/gcc-4.2.1-darwin.py | 37 + .../build/test/toolset-mock/src/gcc-4.8.3-linux.py | 50 + .../test/toolset-mock/src/intel-darwin-10.2.py | 43 + tools/build/test/toolset-mock/src/ld.py | 33 + tools/build/test/toolset-mock/src/libtool.py | 14 + tools/build/test/toolset-mock/src/mock-program.cpp | 42 + .../build/test/toolset-mock/src/project-config.jam | 5 + tools/build/test/toolset-mock/src/ranlib.py | 22 + tools/build/test/toolset-mock/src/strip.py | 13 + tools/build/test/toolset-mock/src/verify.py | 9 + tools/build/test/toolset_clang_darwin.py | 20 + tools/build/test/toolset_clang_linux.py | 19 + tools/build/test/toolset_clang_vxworks.py | 20 + tools/build/test/toolset_darwin.py | 21 + tools/build/test/toolset_defaults.py | 60 + tools/build/test/toolset_gcc.py | 26 + tools/build/test/toolset_intel_darwin.py | 19 + tools/build/test/zlib.py | 119 - tools/check_build/README.md | 3 + tools/check_build/test/Jamfile | 96 + tools/check_build/test/main.cpp | 3 + tools/quickbook/Jamfile.v2 | 11 + tools/quickbook/_clang-format | 57 + tools/quickbook/build/warning-check | 2 +- tools/quickbook/doc/Jamfile.v2 | 4 + tools/quickbook/doc/change_log.qbk | 8 +- tools/quickbook/src/Jamfile.v2 | 10 - tools/quickbook/src/actions.cpp | 1064 +++++---- tools/quickbook/src/actions.hpp | 175 +- tools/quickbook/src/block_element_grammar.cpp | 40 +- tools/quickbook/src/block_tags.hpp | 3 + tools/quickbook/src/cleanup.hpp | 42 +- tools/quickbook/src/code_snippet.cpp | 192 +- tools/quickbook/src/collector.cpp | 46 +- tools/quickbook/src/collector.hpp | 68 +- tools/quickbook/src/dependency_tracker.cpp | 75 +- tools/quickbook/src/dependency_tracker.hpp | 14 +- tools/quickbook/src/doc_info_actions.cpp | 467 ++-- tools/quickbook/src/doc_info_grammar.cpp | 86 +- tools/quickbook/src/doc_info_tags.hpp | 4 + tools/quickbook/src/document_state.cpp | 319 +-- tools/quickbook/src/document_state.hpp | 44 +- tools/quickbook/src/document_state_impl.hpp | 97 +- tools/quickbook/src/files.cpp | 364 ++- tools/quickbook/src/files.hpp | 85 +- tools/quickbook/src/fwd.hpp | 2 +- tools/quickbook/src/glob.cpp | 191 +- tools/quickbook/src/glob.hpp | 13 +- tools/quickbook/src/grammar.cpp | 16 +- tools/quickbook/src/grammar.hpp | 31 +- tools/quickbook/src/grammar_impl.hpp | 52 +- tools/quickbook/src/id_generation.cpp | 144 +- tools/quickbook/src/id_xml.cpp | 95 +- tools/quickbook/src/include_paths.cpp | 224 +- tools/quickbook/src/include_paths.hpp | 31 +- tools/quickbook/src/iterator.hpp | 37 +- tools/quickbook/src/main_grammar.cpp | 310 +-- tools/quickbook/src/markups.cpp | 94 +- tools/quickbook/src/markups.hpp | 8 +- tools/quickbook/src/native_text.cpp | 74 +- tools/quickbook/src/native_text.hpp | 22 +- tools/quickbook/src/parsers.hpp | 165 +- tools/quickbook/src/path.cpp | 117 +- tools/quickbook/src/path.hpp | 28 +- tools/quickbook/src/phrase_element_grammar.cpp | 30 +- tools/quickbook/src/phrase_tags.hpp | 4 + tools/quickbook/src/post_process.cpp | 262 +-- tools/quickbook/src/post_process.hpp | 13 +- tools/quickbook/src/quickbook.cpp | 347 ++- tools/quickbook/src/quickbook.hpp | 11 +- tools/quickbook/src/scoped.hpp | 8 +- tools/quickbook/src/state.cpp | 72 +- tools/quickbook/src/state.hpp | 111 +- tools/quickbook/src/state_save.hpp | 6 +- tools/quickbook/src/stream.cpp | 292 +-- tools/quickbook/src/stream.hpp | 4 +- tools/quickbook/src/string_view.hpp | 6 +- tools/quickbook/src/symbols.hpp | 149 +- tools/quickbook/src/syntax_highlight.cpp | 197 +- tools/quickbook/src/syntax_highlight.hpp | 27 +- tools/quickbook/src/template_stack.cpp | 60 +- tools/quickbook/src/template_stack.hpp | 49 +- tools/quickbook/src/template_tags.hpp | 4 + tools/quickbook/src/utils.cpp | 172 +- tools/quickbook/src/utils.hpp | 32 +- tools/quickbook/src/value_tags.hpp | 123 +- tools/quickbook/src/values.cpp | 661 +++--- tools/quickbook/src/values.hpp | 242 +- tools/quickbook/src/values_parse.hpp | 62 +- tools/quickbook/test/callouts.cpp | 2 + tools/quickbook/test/quickbook-testing.jam | 23 +- tools/quickbook/test/snippets/pass_thru.cpp | 2 + .../test/snippets/unbalanced_snippet2.cpp | 1 - tools/quickbook/test/src/Jamfile.v2 | 9 - tools/quickbook/test/src/text_diff.cpp | 52 +- tools/quickbook/test/stub.cpp | 2 + tools/quickbook/test/unit/cleanup_test.cpp | 22 +- tools/quickbook/test/unit/glob_test.cpp | 5 +- tools/quickbook/test/unit/path_test.cpp | 129 +- tools/quickbook/test/unit/post_process_test.cpp | 19 +- tools/quickbook/test/unit/source_map_test.cpp | 426 ++-- tools/quickbook/test/unit/symbols_find_null.cpp | 11 +- tools/quickbook/test/unit/symbols_tests.cpp | 154 +- tools/quickbook/test/unit/utils_test.cpp | 23 +- tools/quickbook/test/unit/values_test.cpp | 36 +- 312 files changed, 13159 insertions(+), 12596 deletions(-) delete mode 100644 tools/build/src/tools/common_clang_vc.jam create mode 100644 tools/build/src/tools/features/relevant-feature.jam create mode 100644 tools/build/src/tools/flags.jam create mode 100644 tools/build/src/tools/zstd.jam create mode 100644 tools/build/src/util/param.jam create mode 100644 tools/build/test/Jamfile.jam create mode 100644 tools/build/test/TestToolset.py create mode 100644 tools/build/test/build_hooks.py create mode 100644 tools/build/test/command_line_properties.py create mode 100644 tools/build/test/configure.py create mode 100644 tools/build/test/core_fail_expected.py create mode 100644 tools/build/test/core_scanner.py delete mode 100644 tools/build/test/direct_request_test.py create mode 100644 tools/build/test/feature_implicit_dependency.py create mode 100644 tools/build/test/feature_relevant.py create mode 100644 tools/build/test/feature_suppress_import_lib.py create mode 100644 tools/build/test/file_types.py create mode 100644 tools/build/test/flags.py delete mode 100644 tools/build/test/free_features_request.py create mode 100755 tools/build/test/lib_zlib.py create mode 100755 tools/build/test/liblzma.py create mode 100755 tools/build/test/libzstd.py create mode 100644 tools/build/test/param.py delete mode 100644 tools/build/test/regression.py delete mode 100755 tools/build/test/test_result_dumping.py create mode 100755 tools/build/test/testing.py delete mode 100755 tools/build/test/testing_support.py create mode 100644 tools/build/test/toolset-mock/Jamroot.jam create mode 100644 tools/build/test/toolset-mock/lib.cpp create mode 100644 tools/build/test/toolset-mock/main.cpp create mode 100644 tools/build/test/toolset-mock/project-config.jam create mode 100644 tools/build/test/toolset-mock/src/Jamroot.jam create mode 100644 tools/build/test/toolset-mock/src/MockProgram.py create mode 100644 tools/build/test/toolset-mock/src/ar.py create mode 100644 tools/build/test/toolset-mock/src/clang-3.9.0-darwin.py create mode 100644 tools/build/test/toolset-mock/src/clang-linux-3.9.0.py create mode 100644 tools/build/test/toolset-mock/src/clang-vxworks-4.0.1.py create mode 100644 tools/build/test/toolset-mock/src/darwin-4.2.1.py create mode 100644 tools/build/test/toolset-mock/src/gcc-4.2.1-darwin.py create mode 100644 tools/build/test/toolset-mock/src/gcc-4.8.3-linux.py create mode 100644 tools/build/test/toolset-mock/src/intel-darwin-10.2.py create mode 100644 tools/build/test/toolset-mock/src/ld.py create mode 100644 tools/build/test/toolset-mock/src/libtool.py create mode 100644 tools/build/test/toolset-mock/src/mock-program.cpp create mode 100644 tools/build/test/toolset-mock/src/project-config.jam create mode 100644 tools/build/test/toolset-mock/src/ranlib.py create mode 100644 tools/build/test/toolset-mock/src/strip.py create mode 100644 tools/build/test/toolset-mock/src/verify.py create mode 100644 tools/build/test/toolset_clang_darwin.py create mode 100644 tools/build/test/toolset_clang_linux.py create mode 100644 tools/build/test/toolset_clang_vxworks.py create mode 100644 tools/build/test/toolset_darwin.py create mode 100644 tools/build/test/toolset_defaults.py create mode 100644 tools/build/test/toolset_gcc.py create mode 100644 tools/build/test/toolset_intel_darwin.py delete mode 100755 tools/build/test/zlib.py create mode 100644 tools/check_build/README.md create mode 100644 tools/check_build/test/Jamfile create mode 100644 tools/check_build/test/main.cpp create mode 100644 tools/quickbook/_clang-format delete mode 100644 tools/quickbook/test/src/Jamfile.v2 (limited to 'tools') diff --git a/tools/boostdep/depinst/exceptions.txt b/tools/boostdep/depinst/exceptions.txt index e716d37925..da78cd762e 100644 --- a/tools/boostdep/depinst/exceptions.txt +++ b/tools/boostdep/depinst/exceptions.txt @@ -25,6 +25,15 @@ config: boost/detail/workaround.hpp boost/limits.hpp boost/version.hpp +container_hash: + boost/functional/hash.hpp + boost/functional/hash/detail/float_functions.hpp + boost/functional/hash/detail/hash_float.hpp + boost/functional/hash/detail/limits.hpp + boost/functional/hash/extensions.hpp + boost/functional/hash/hash.hpp + boost/functional/hash/hash_fwd.hpp + boost/functional/hash_fwd.hpp contract: boost/contract_macro.hpp conversion: diff --git a/tools/build/doc/src/overview.xml b/tools/build/doc/src/overview.xml index 44fc2e8fda..65aa966b07 100644 --- a/tools/build/doc/src/overview.xml +++ b/tools/build/doc/src/overview.xml @@ -449,6 +449,8 @@ actions create-file-from-another + Any of these files may also be overridden on the command line + You can use the --debug-configuration option to @@ -785,6 +787,38 @@ b2 toolset=gcc variant=debug optimization=space + + + + config + Override all configuration files + + + + + + + site-config.jam + Override the default site-config.jam + + + + + + + user-config.jam + Override the default user-config.jam + + + + + + + project-config.jam + Override the default project-config.jam + + + @@ -1021,6 +1055,12 @@ b2 include=static,shared is not treated specially. + Multiple features may be grouped by using a forwards slash. + +b2 gcc/link=shared msvc/link=static,shared + + This will build 3 different variants, altogether. +
diff --git a/tools/build/doc/src/reference.xml b/tools/build/doc/src/reference.xml index 24652f15f0..59a03483ba 100644 --- a/tools/build/doc/src/reference.xml +++ b/tools/build/doc/src/reference.xml @@ -856,6 +856,60 @@ path-constant DATA : data/a.txt ; + relevant + + + featuresrelevance + relevant + + + Allowed values: the name of any feature. + + + + This feature is used to indicate which other features are relevant for + a given target. It is usually not necessary to manage it explicitly, + as Boost.Build can deduce it in most cases. Features which are not + relevant will not affect target paths, and will not cause conflicts. + + + + A feature will be considered relevant if any of the following are true + + It is referenced by toolset.flags or toolset.uses-features + It is used by the requirements of a generator + It is a subfeature of a relevant feature + It has a subfeature which is relevant + It is a composite feature, and any composed feature is relevant + It affects target alternative selection for a main target + It is a propagated feature and is relevant for any dependency + It is relevant for any dependency created by the same main target + It is used in the condition of a conditional property and the corresponding value is relevant + It is explicitly named as relevent + + + + Relevant features cannot be automatically deduced in the following cases: + + Indirect conditionals. Solution: return properties of the form + <relevant>result-feature:<relevant>condition-feature + This isn't really a conditional, + although for most purposes it functions like one. In particular, it does not support + multiple comma-separated elements in the condition, and it does work correctly even + in contexts where conditional properties are not allowed + + Action rules that read properties. Solution: add toolset.uses-features + to tell Boost.Build that the feature is actually used. + + + Generators and targets that manipulate property-sets directly. + Solution: set <relevant> manually. + + + + + +
@@ -1783,6 +1837,122 @@ using bzip2 : 1.0.6 : <source>C:/Devel/src/bzip2-1.0.6 : <toolset>ms using bzip2 : 1.0.6 : : <toolset>gcc ; + +
+ Python + Python + + Provides support for the + python language + environment to be linked in as a library. + + python can be initialized using the following syntax + +using python : version : command-or-prefix : includes : libraries : conditions : extension-suffix ; + + Options for using python: + + + version + + the version of Python to use. Should be in Major.Minor + format, for example 2.3. Do not include the subminor version. + + + + + command-or-prefix + + Preferably, a command that invokes a Python interpreter. + Alternatively, the installation prefix for Python libraries + and includes. If empty, will be guessed from the version, the + platform's installation patterns, and the python executables + that can be found in PATH. + + + + includes + + the include path to Python headers. If empty, will be + guessed. + + + + libraries + + the path to Python library binaries. If empty, will + be guessed. On MacOS/Darwin, you can also pass the path of the + Python framework. + + + + conditions + + if specified, should be a set of properties that are + matched against the build configuration when Boost.Build + selects a Python configuration to use. + + + + extension-suffix + + A string to append to the name of extension modules + before the true filename extension. Ordinarily we would just + compute this based on the value of the <python-debugging> + feature. However ubuntu's python-dbg package uses the windows + convention of appending _d to debug-build extension modules. We + have no way of detecting ubuntu, or of probing python for the + "_d" requirement, and if you configure and build python using + --with-pydebug, you'll be using the standard *nix convention. + Defaults to "" (or "_d" when targeting windows and + <python-debugging> is set). + + + + Examples: + +# Find python in the default system location +using python ; +# 2.7 +using python : 2.7 ; +# 3.5 +using python : 3.5 ; + +# On ubuntu 16.04 +using python +: 2.7 # version +: # Interpreter/path to dir +: /usr/include/python2.7 # includes +: /usr/lib/x86_64-linux-gnu # libs +: # conditions +; + +using python +: 3.5 # version +: # Interpreter/path to dir +: /usr/include/python3.5 # includes +: /usr/lib/x86_64-linux-gnu # libs +: # conditions +; + +# On windows +using python +: 2.7 # version +: C:\\Python27-32\\python.exe # Interperter/path to dir +: C:\\Python27-32\\include # includes +: C:\\Python27-32\\libs # libs +: <address-model>32 <address-model> # conditions - both 32 and unspecified +; + +using python +: 2.7 # version +: C:\\Python27-64\\python.exe # Interperter/path to dir +: C:\\Python27-64\\include # includes +: C:\\Python27-64\\libs # libs +: <address-model>64 # conditions +; + +
@@ -2423,7 +2593,8 @@ exe a : a.cpp the directory bin unless this is overridden by the build-dir project attribute. Under bin is a path that depends on the properties used to build each target. This path is uniquely determined by - all non-free, non-incidental properties. For example, + all relevant + non-free, non-incidental properties. For example, given a property set containing: <toolset>gcc <toolset-gcc:version>4.6.1 <variant>debug <warnings>all <define>_DEBUG <include>/usr/local/include diff --git a/tools/build/src/build-system.jam b/tools/build/src/build-system.jam index 185526c702..ac43e167fb 100644 --- a/tools/build/src/build-system.jam +++ b/tools/build/src/build-system.jam @@ -15,6 +15,7 @@ import configure ; import config-cache ; import feature ; import generators ; +import indirect ; import make ; import modules ; import os ; @@ -101,16 +102,21 @@ rule set-default-toolset ( toolset : version ? ) .default-toolset-version = $(version) ; } -rule set-pre-build-hook ( function ) +rule add-pre-build-hook ( function ) { - .pre-build-hook = $(function) ; + .pre-build-hook += [ indirect.make $(function) : [ CALLER_MODULE ] ] ; } -rule set-post-build-hook ( function ) +rule add-post-build-hook ( function ) { - .post-build-hook = $(function) ; + .post-build-hook += [ indirect.make $(function) : [ CALLER_MODULE ] ] ; } +# Old names for backwards compatibility +IMPORT build-system : add-pre-build-hook : build-system : set-pre-build-hook ; +IMPORT build-system : add-post-build-hook : build-system : set-post-build-hook ; +EXPORT build-system : set-pre-build-hook set-post-build-hook ; + ################################################################################ # # Local rules. @@ -225,7 +231,7 @@ local rule load-config ( module-name : filename : path + : must-find ? ) { local path-string = $(path) ; if $(path-string) = "" { path-string = . ; } - ECHO notice: Searching '$(path-string)' for $(module-name) + ECHO "notice:" Searching '$(path-string)' for $(module-name) configuration file '$(filename)'. ; } local where = [ GLOB $(path) : $(filename) ] ; @@ -237,7 +243,7 @@ local rule load-config ( module-name : filename : path + : must-find ? ) local where-string = $(where:D) ; if $(where-string) = "" { where-string = . ; } where-string = '$(where-string)' ; - ECHO notice: Loading $(module-name) configuration file '$(filename)' + ECHO "notice:" Loading $(module-name) configuration file '$(filename)' from $(where-string:J=" "). ; } @@ -261,12 +267,41 @@ local rule load-config ( module-name : filename : path + : must-find ? ) errors.user-error Configuration file '$(filename)' not found "in" $(path-string). ; } - ECHO notice: Configuration file '$(filename)' not found "in" + ECHO "notice:" Configuration file '$(filename)' not found "in" $(path-string). ; } return $(where) ; } +# Parses options of the form --xxx-config=path/to/config.jam +# and environmental variables of the form BOOST_BUILD_XXX_CONFIG. +# If not found, returns an empty list. The option may be +# explicitly set to the empty string, in which case, handle-config-option +# will return "". +# +local rule handle-config-option ( name : env ? ) +{ + local result = [ MATCH ^--$(name)=(.*)$ : $(.argv) ] ; + if ! $(result)-is-defined && $(env) + { + result = [ os.environ $(env) ] ; + } + # Special handling for the case when the OS does not strip the quotes + # around the file name, as is the case when using Cygwin bash. + result = [ utility.unquote $(result[-1]) ] ; + if ! $(result) + { + return $(result) ; + } + # Treat explicitly entered user paths as native OS path + # references and, if non-absolute, root them at the current + # working directory. + result = [ path.make $(result) ] ; + result = [ path.root $(result) [ path.pwd ] ] ; + result = [ path.native $(result) ] ; + return $(result) ; +} + # Loads all the configuration files used by Boost Build in the following order: # @@ -277,11 +312,21 @@ local rule load-config ( module-name : filename : path + : must-find ? ) # files will not be. If a relative path is specified, file is searched for in # the current folder. # +# -- all-config -- +# Loaded only if specified on the command-line using the --config command +# line option. If a file name is specified, it must exist and replaces all +# other configuration files. If an empty file name is passed, no configuration +# files will be loaded. +# # -- site-config -- -# Always named site-config.jam. Will only be found if located on the system -# root path (Windows), /etc (non-Windows), user's home folder or the Boost Build -# path, in that order. Not loaded in case the test-config configuration file is -# loaded or the --ignore-site-config command-line option is specified. +# Named site-config.jam by default or may be named explicitly using the +# --site-config command-line option. If named explicitly, the file is found +# relative to the current working directory and must exist. If the default one +# is used then it is searched for in the system root path (Windows), +# /etc (non-Windows), user's home folder or the Boost Build path, in that +# order. Not loaded in case the test-config configuration file is loaded, +# the file is explicitly set to the empty string or the --ignore-site-config +# command-line option is specified. # # -- user-config -- # Named user-config.jam by default or may be named explicitly using the @@ -294,8 +339,12 @@ local rule load-config ( module-name : filename : path + : must-find ? ) # file must exist. # # -- project-config -- -# Always named project-config.jam. Looked up in the current working folder and -# then upwards through its parents up to the root folder. +# Named project-config.jam. Looked up in the current working folder and +# then upwards through its parents up to the root folder. It may also be +# named explicitly using the --project-config command-line option. If a file +# is specified explicitly, it is found relative to the current working +# directory and must exist. If an empty file name is passed, project-config +# will not be loaded. # # Test configurations have been added primarily for use by Boost Build's # internal unit testing system but may be used freely in other places as well. @@ -305,14 +354,11 @@ local rule load-configuration-files # Flag indicating that site configuration should not be loaded. local ignore-site-config = [ MATCH ^(--ignore-site-config)$ : $(.argv) ] ; + local ignore-user-config ; + local ignore-project-config ; initialize-config-module test-config ; - local test-config = [ MATCH ^--test-config=(.*)$ : $(.argv) ] ; - local uq = [ MATCH \"(.*)\" : $(test-config) ] ; - if $(uq) - { - test-config = $(uq) ; - } + local test-config = [ handle-config-option test-config ] ; if $(test-config) { local where = [ load-config test-config : $(test-config:BS) : @@ -325,12 +371,32 @@ local rule load-configuration-files ECHO "notice: be ignored due to the test configuration being" "loaded." ; } + ignore-site-config = true ; + ignore-user-config = true ; } - else + } + + initialize-config-module all-config ; + local all-config = [ handle-config-option config ] ; + if $(all-config) + { + load-config all-config : $(all-config:D=) : $(all-config:D) : required ; + if $(.debug-config) { - test-config = ; + ECHO "notice: Regular configuration files will be ignored due" ; + ECHO "notice: to the global configuration being loaded." ; } } + if $(all-config)-is-defined + { + if $(.debug-config) && ! $(all-config) + { + ECHO "notice: Configuration file loading explicitly disabled." ; + } + ignore-site-config = true ; + ignore-user-config = true ; + ignore-project-config = true ; + } local user-path = [ os.home-directories ] [ os.environ BOOST_BUILD_PATH ] ; local site-path = /etc $(user-path) ; @@ -339,59 +405,56 @@ local rule load-configuration-files site-path = [ modules.peek : SystemRoot ] $(user-path) ; } - if $(.debug-config) && ! $(test-config) && $(ignore-site-config) + if $(.debug-config) && $(ignore-site-config) = --ignore-site-config { ECHO "notice: Site configuration files will be ignored due to the" ; ECHO "notice: --ignore-site-config command-line option." ; } initialize-config-module site-config ; - if ! $(test-config) && ! $(ignore-site-config) + if ! $(ignore-site-config) { - load-config site-config : site-config.jam : $(site-path) ; + local site-config = [ handle-config-option site-config ] ; + if $(site-config) + { + load-config site-config : $(site-config:D=) : $(site-config:D) + : must-exist ; + } + else if ! $(site-config)-is-defined + { + load-config site-config : site-config.jam : $(site-path) ; + } + else if $(.debug-config) + { + ECHO "notice:" Site configuration file loading explicitly disabled. ; + } } initialize-config-module user-config ; - if ! $(test-config) + if ! $(ignore-user-config) { - local user-config = [ MATCH ^--user-config=(.*)$ : $(.argv) ] ; - user-config = $(user-config[-1]) ; - user-config ?= [ os.environ BOOST_BUILD_USER_CONFIG ] ; - # Special handling for the case when the OS does not strip the quotes - # around the file name, as is the case when using Cygwin bash. - user-config = [ utility.unquote $(user-config) ] ; - local explicitly-requested = $(user-config) ; - user-config ?= user-config.jam ; + local user-config = + [ handle-config-option user-config : BOOST_BUILD_USER_CONFIG ] ; if $(user-config) { - if $(explicitly-requested) - { - # Treat explicitly entered user paths as native OS path - # references and, if non-absolute, root them at the current - # working directory. - user-config = [ path.make $(user-config) ] ; - user-config = [ path.root $(user-config) [ path.pwd ] ] ; - user-config = [ path.native $(user-config) ] ; - - if $(.debug-config) - { - ECHO notice: Loading explicitly specified user configuration - file: ; - ECHO " $(user-config)" ; - } - - load-config user-config : $(user-config:BS) : $(user-config:D) - : must-exist ; - } - else + if $(.debug-config) { - load-config user-config : $(user-config) : $(user-path) ; + ECHO "notice:" Loading explicitly specified user configuration + "file:" ; + ECHO " $(user-config)" ; } + + load-config user-config : $(user-config:D=) : $(user-config:D) + : must-exist ; + } + else if ! $(user-config)-is-defined + { + load-config user-config : user-config.jam : $(user-path) ; } else if $(.debug-config) { - ECHO notice: User configuration file loading explicitly disabled. ; + ECHO "notice:" User configuration file loading explicitly disabled. ; } } @@ -401,15 +464,33 @@ local rule load-configuration-files # - We need to load project-config.jam before Jamroot # - We probably need to load project-config.jam even if there is no Jamroot # - e.g. to implement automake-style out-of-tree builds. - local file = [ path.glob "." : project-config.jam ] ; - if ! $(file) + if ! $(ignore-project-config) { - file = [ path.glob-in-parents "." : project-config.jam ] ; - } - if $(file) - { - initialize-config-module project-config : $(file:D) ; - load-config project-config : project-config.jam : $(file:D) ; + local project-config = [ handle-config-option project-config ] ; + if $(project-config) + { + initialize-config-module project-config : $(project-config:D=) ; + load-config project-config : $(project-config:D=) + : $(project-config:D) : must-exist ; + } + else if ! $(project-config)-is-defined + { + local file = [ path.glob "." : project-config.jam ] ; + if ! $(file) + { + file = [ path.glob-in-parents "." : project-config.jam ] ; + } + if $(file) + { + initialize-config-module project-config : $(file:D) ; + load-config project-config : project-config.jam : $(file:D) ; + } + } + else if $(.debug-config) + { + ECHO "notice:" Project configuration file loading explicitly + disabled. ; + } } project.end-load ; @@ -430,7 +511,7 @@ local rule process-explicit-toolset-requests for local t in $(option-toolsets) $(feature-toolsets) { # Parse toolset-version/properties. - local toolset = [ MATCH ([^/]+)/?.* : $(t) ] ; + local toolset = [ MATCH "([^/]+)/?.*" : $(t) ] ; local properties = [ feature.expand-subfeatures $(toolset) : true ] ; local toolset-property = [ property.select : $(properties) ] ; local known ; @@ -457,8 +538,10 @@ local rule process-explicit-toolset-requests ECHO "notice: [cmdline-cfg] toolset $(toolset) not" "previously configured; attempting to auto-configure now" ; } - local t,v = [ MATCH ([^-]+)-?(.+)? : $(toolset) ] ; + local t,v = [ MATCH "([^-]+)-?(.+)?" : $(toolset) ] ; + project.push-current ; toolset.using $(t,v[1]) : $(t,v[2]) ; + project.pop-current ; } # Make sure we get an appropriate property into the build request in @@ -468,7 +551,7 @@ local rule process-explicit-toolset-requests { if $(.debug-config) { - ECHO notice: [cmdline-cfg] adding toolset=$(t) to the build + ECHO "notice:" "[cmdline-cfg]" adding toolset=$(t) to the build request. ; } extra-properties += toolset=$(t) ; @@ -963,9 +1046,9 @@ local rule should-clean-project ( project ) { configure.print-configure-checks-summary ; - if $(.pre-build-hook) + for local function in $(.pre-build-hook) { - $(.pre-build-hook) ; + indirect.call $(function) ; } DEPENDS all : $(actual-targets) ; @@ -980,9 +1063,9 @@ local rule should-clean-project ( project ) { UPDATE_NOW $(.out-xml) : : ignore-minus-n ; } - if $(.post-build-hook) + for local function in $(.post-build-hook) { - $(.post-build-hook) $(ok) ; + indirect.call $(function) $(ok) ; } # Prevent automatic update of the 'all' target, now that we have # explicitly updated what we wanted. diff --git a/tools/build/src/build/ac.jam b/tools/build/src/build/ac.jam index c01dc59973..09eb26ea98 100644 --- a/tools/build/src/build/ac.jam +++ b/tools/build/src/build/ac.jam @@ -11,6 +11,7 @@ import modules ; import "class" ; import errors ; import configure ; +import feature ; import project ; import virtual-target ; import generators ; @@ -22,11 +23,21 @@ project.initialize $(__name__) ; .project = [ project.current ] ; project ac ; +feature.feature ac.print-text : : free ; + rule generate-include ( target : sources * : properties * ) { - local header = [ property.select : $(properties) ] ; print.output $(target) ; - print.text "#include <$(header:G=)>\n" : true ; + local text = [ property.select : $(properties) ] ; + if $(text) + { + print.text $(text:G=) : true ; + } + else + { + local header = [ property.select : $(properties) ] ; + print.text "#include <$(header:G=)>\n" : true ; + } } rule generate-main ( target : sources * : properties * ) @@ -35,7 +46,7 @@ rule generate-main ( target : sources * : properties * ) print.text "int main() {}" : true ; } -rule find-include-path ( properties : header : provided-path ? ) +rule find-include-path ( properties : header : provided-path ? : test-source ? ) { if $(provided-path) && [ path.exists [ path.root $(header) $(provided-path) ] ] { @@ -43,21 +54,23 @@ rule find-include-path ( properties : header : provided-path ? ) } else { - local a = [ class.new action : ac.generate-include : [ property-set.create $(header) ] ] ; + local a = [ class.new action : ac.generate-include : [ property-set.create $(header) $(test-source) ] ] ; # Create a new CPP target named after the header. # Replace dots (".") in target basename for portability. local basename = [ regex.replace $(header:D=) "[.]" "_" ] ; local header-target = $(header:S=:B=$(basename)) ; local cpp = [ class.new file-target $(header-target:S=.cpp) exact : CPP : $(.project) : $(a) ] ; cpp = [ virtual-target.register $(cpp) ] ; + $(cpp).root true ; local result = [ generators.construct $(.project) $(header-target) : OBJ : $(properties) : $(cpp) : true ] ; + configure.maybe-force-rebuild $(result[2-]) ; local jam-targets ; - for t in $(result[2-]) + for local t in $(result[2-]) { jam-targets += [ $(t).actualize ] ; } if [ UPDATE_NOW $(jam-targets) : [ modules.peek configure : .log-fd ] - : ignore-minus-n : ignore-minus-q ] + : ignore-minus-n ] { return %default ; } @@ -66,7 +79,6 @@ rule find-include-path ( properties : header : provided-path ? ) rule construct-library ( name : property-set : provided-path ? ) { - property-set = [ $(property-set).refine [ property-set.create $(link-opt) ] ] ; local lib-props = [ $(property-set).add-raw $(name) $(provided-path) ] ; return [ generators.construct $(.project) lib-$(name) : SEARCHED_LIB : $(lib-props) : : true ] ; @@ -96,16 +108,18 @@ rule find-library ( properties : names + : provided-path ? ) [ property-set.empty ] ] ; local main.cpp = [ virtual-target.register [ class.new file-target main-$(name).cpp exact : CPP : $(.project) : $(a) ] ] ; + $(main.cpp).root true ; local test = [ generators.construct $(.project) $(name) : EXE : [ $(properties).add $(lib[1]) ] : $(main.cpp) $(lib[2-]) : true ] ; + configure.maybe-force-rebuild $(test[2-]) ; local jam-targets ; for t in $(test[2-]) { jam-targets += [ $(t).actualize ] ; } if [ UPDATE_NOW $(jam-targets) : [ modules.peek configure : .log-fd ] - : ignore-minus-n : ignore-minus-q ] + : ignore-minus-n ] { result = $(name) $(link-opts[1]) ; names-iter = ; link-opts = ; # break @@ -125,6 +139,7 @@ class ac-library : basic-target import ac ; import configure ; import config-cache ; + import os ; rule __init__ ( name : project : requirements * : include-path ? : library-path ? : library-name ? ) { @@ -143,6 +158,11 @@ class ac-library : basic-target self.default-names = $(names) ; } + rule set-header-test ( source ) + { + self.header-test = $(source) ; + } + rule reconfigure ( include-path ? : library-path ? : library-name ? ) { if $(include-path) || $(library-path) || $(library-name) @@ -185,30 +205,27 @@ class ac-library : basic-target local libnames = $(self.library-name) ; if ! $(libnames) && $(use-environment) { - libnames = [ modules.peek : $(name:U)_NAME ] ; + libnames = [ os.environ $(name:U)_NAME ] ; # Backward compatibility only. - libnames ?= [ modules.peek : $(name:U)_BINARY ] ; + libnames ?= [ os.environ $(name:U)_BINARY ] ; } libnames ?= $(self.default-names) ; local include-path = $(self.include-path) ; if ! $(include-path) && $(use-environment) { - include-path = [ modules.peek : $(name:U)_INCLUDE ] ; + include-path = [ os.environ $(name:U)_INCLUDE ] ; } local library-path = $(self.library-path) ; if ! $(library-path) && $(use-environment) { - library-path = [ modules.peek : $(name:U)_LIBRARY_PATH ] ; + library-path = [ os.environ $(name:U)_LIBRARY_PATH ] ; # Backwards compatibility only - library-path ?= [ modules.peek : $(name:U)_LIBPATH ] ; + library-path ?= [ os.environ $(name:U)_LIBPATH ] ; } - local toolset = [ $(property-set).get ] ; - local toolset-version-property = "" ; - local relevant = [ property.select - $(toolset-version-property) : + local relevant = [ property.select [ configure.get-relevant-features ] : [ $(property-set).raw ] ] ; local key = ac-library-$(name)-$(relevant:J=-) ; @@ -236,7 +253,7 @@ class ac-library : basic-target } else { - local includes = [ ac.find-include-path $(property-set) : $(self.header) : $(include-path) ] ; + local includes = [ ac.find-include-path $(property-set) : $(self.header) : $(include-path) : $(self.header-test) ] ; local library = [ ac.find-library $(property-set) : $(libnames) : $(library-path) ] ; if $(includes) && $(library) { @@ -300,5 +317,8 @@ rule check-library ( target : true-properties * : false-properties * ) { local instance = [ class.new check-library-worker $(target) : $(true-properties) : $(false-properties) ] ; - return @$(instance).check ; + return @$(instance).check + [ property.evaluate-conditional-relevance + $(true-properties) $(false-properties) + : [ configure.get-relevant-features ] ] ; } diff --git a/tools/build/src/build/alias.jam b/tools/build/src/build/alias.jam index 9ac8cb8950..3a97b72637 100644 --- a/tools/build/src/build/alias.jam +++ b/tools/build/src/build/alias.jam @@ -24,6 +24,7 @@ # import "class" : new ; +import param ; import project ; import property-set ; import targets ; @@ -57,6 +58,9 @@ class alias-target-class : basic-target rule alias ( name : sources * : requirements * : default-build * : usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; + local project = [ project.current ] ; targets.main-target-alternative diff --git a/tools/build/src/build/build-request.jam b/tools/build/src/build/build-request.jam index 3110713b70..4c767c3b25 100644 --- a/tools/build/src/build/build-request.jam +++ b/tools/build/src/build/build-request.jam @@ -38,6 +38,23 @@ rule expand-no-defaults ( property-sets * ) } +# Update the list of expected conflicts based on the new +# features. +# +local rule remove-conflicts ( conflicts * : features * ) +{ + local result ; + for local c in $(conflicts) + { + if ! [ set.intersection [ regex.split $(c) "/" ] : $(features) ] + { + result += $(c) ; + } + } + return $(result) ; +} + + # Implementation of x-product, below. Expects all the project files to already # be loaded. # @@ -47,36 +64,54 @@ local rule x-product-aux ( property-sets + ) local p = [ feature.split $(property-sets[1]) ] ; local f = [ set.difference $(p:G) : [ feature.free-features ] ] ; local seen ; + local extra-conflicts ; + # No conflict with things used at a higher level? if ! [ set.intersection $(f) : $(x-product-used) ] { local x-product-seen ; + local x-product-conflicts = + [ remove-conflicts $(x-product-conflicts) : $(f) ] ; { # Do not mix in any conflicting features. local x-product-used = $(x-product-used) $(f) ; if $(property-sets[2]) { - local rest = [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; + local rest = [ x-product-aux $(property-sets[2-]) ] ; result = $(property-sets[1])/$(rest) ; } - - result ?= $(property-sets[1]) ; + if ! $(x-product-conflicts) + { + result ?= $(property-sets[1]) ; + } } # If we did not encounter a conflicting feature lower down, do not # recurse again. - if ! [ set.intersection $(f) : $(x-product-seen) ] + if ! [ set.intersection $(f) : $(x-product-seen) ] + || [ remove-conflicts $(x-product-conflicts) : $(x-product-seen) ] { property-sets = ; } + else + { + # A property is only allowed to be absent if it conflicts + # with either a higher or lower layer. We don't need to + # bother setting this if we already know that we don't need + # to recurse again. + extra-conflicts = $(f:J=/) ; + } seen = $(x-product-seen) ; } if $(property-sets[2]) { - result += [ x-product-aux $(property-sets[2-]) : $(feature-space) ] ; + # Lower layers expansion must conflict with this + local x-product-conflicts = $(x-product-conflicts) $(extra-conflicts) ; + + result += [ x-product-aux $(property-sets[2-]) ] ; } # Note that we have seen these features so that higher levels will recurse @@ -90,13 +125,21 @@ local rule x-product-aux ( property-sets + ) # contain conflicting values for single-valued features. Expects all the project # files to already be loaded. # +# Formal definition: +# Returns all maximum non-conflicting subsets of property-sets. +# The result is a list of all property-sets p such that +# 1. p is composed by joining a subset of property-sets without removing +# duplicates +# 2. p contains at most one instance of every single-valued feature +# 3. Adding any additional element of property-sets to p be would +# violate (2) local rule x-product ( property-sets * ) { if $(property-sets).non-empty { # Prepare some "scoped globals" that can be used by the implementation # function, x-product-aux. - local x-product-seen x-product-used ; + local x-product-seen x-product-used x-product-conflicts ; return [ x-product-aux $(property-sets) : $(feature-space) ] ; } # Otherwise return empty. diff --git a/tools/build/src/build/config-cache.jam b/tools/build/src/build/config-cache.jam index ff69ff6f69..4afba419f3 100644 --- a/tools/build/src/build/config-cache.jam +++ b/tools/build/src/build/config-cache.jam @@ -42,6 +42,8 @@ rule save ( ) ALWAYS $(target) ; config-cache.write $(target) ; UPDATE_NOW $(target) : [ modules.peek configure : .log-fd ] : ignore-minus-n ; + import common ; + common.Clean clean-all : $(target) ; } } @@ -67,6 +69,9 @@ rule load ( cache-file ) cache-file = [ path.native $(cache-file) ] ; if [ path.exists $(cache-file) ] && ! ( --reconfigure in [ modules.peek : ARGV ] ) { + FILE_CONTENTS on $(cache-file) = "" ; + config-cache.write $(cache-file) ; + UPDATE_NOW $(cache-file) : [ modules.peek configure : .log-fd ] ; include $(cache-file) ; } .cache-file = $(cache-file) ; diff --git a/tools/build/src/build/configure.jam b/tools/build/src/build/configure.jam index 78683d6a01..f9df172b61 100644 --- a/tools/build/src/build/configure.jam +++ b/tools/build/src/build/configure.jam @@ -20,7 +20,9 @@ import targets ; import config-cache ; import feature ; import modules ; +import sequence ; import utility ; +import virtual-target ; # The configure feature allows external definition of what features are @@ -144,6 +146,28 @@ rule print-configure-checks-summary ( ) } } +if --reconfigure in [ modules.peek : ARGV ] +{ + .reconfigure = true ; +} + +# Handle the --reconfigure option +rule maybe-force-rebuild ( targets * ) +{ + if $(.reconfigure) + { + local all-targets ; + for local t in $(targets) + { + all-targets += [ virtual-target.traverse $(t) ] ; + } + for local t in [ sequence.unique $(all-targets) ] + { + $(t).always ; + } + } +} + # Attempts to build a set of virtual targets rule try-build ( targets * : ps : what : retry ? ) { @@ -154,6 +178,8 @@ rule try-build ( targets * : ps : what : retry ? ) local result ; local jam-targets ; + maybe-force-rebuild $(targets) ; + for local t in $(targets) { jam-targets += [ $(t).actualize ] ; @@ -206,6 +232,90 @@ rule try-build ( targets * : ps : what : retry ? ) return $(result) ; } +# Attempts to build several sets of virtual targets. Returns the +# the index of the first set that builds. +rule try-find-build ( ps : what : * ) +{ + local args = 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; + # The outer layer only needs to check $(what), but we + # also need to check the individual elements, in case + # the set of targets has changed since the last build. + local cache-name = $(what) $($(args)[1]) [ $(ps).raw ] ; + cache-name = $(cache-name:J=-) ; + local value = [ config-cache.get $(cache-name) ] ; + + local result ; + local jam-targets ; + + maybe-force-rebuild $($(args)[2-]) ; + + # Make sure that the targets are always actualized, + # even if the result is cached. This is needed to + # allow clean-all to find them and also to avoid + # unintentional behavior changes. + for local t in $($(args)[2-]) + { + $(t).actualize ; + } + + if $(value) + { + local none = none ; # What to show when the argument + local name = $(value) ; + if $(name) != none + { + name = [ CALC $(name) + 2 ] ; + } + local x = [ PAD " - $(what)" : $(.width) ] ; + local y = [ PAD $($(name)[1]) : 3 ] ; + result = $(value) ; + log-check-result "$(x) : $(y) (cached)" ; + } + else + { + local x = [ PAD " - $(what)" : $(.width) ] ; + for local i in $(args) + { + if ! $($(i)[1]) + { + break ; + } + local jam-targets ; + for local t in $($(i)[2-]) + { + jam-targets += [ $(t).actualize ] ; + } + if [ UPDATE_NOW $(jam-targets) : + $(.log-fd) : ignore-minus-n : ignore-minus-q ] + { + result = [ CALC $(i) - 2 ] ; + log-check-result "$(x) : $($(i)[1])" ; + break ; + } + } + if ! $(result) + { + log-check-result "$(x) : none" ; + result = none ; + } + } + if ! $(value) + { + if $(result) + { + config-cache.set $(cache-name) : $(result) ; + } + else + { + config-cache.set $(cache-name) : $(result) ; + } + } + if $(result) != none + { + return $(result) ; + } +} + # Attempt to build a metatarget named by 'metatarget-reference' # in context of 'project' with properties 'ps'. # Returns non-empty value if build is OK. @@ -232,7 +342,69 @@ rule builds-raw ( metatarget-reference : project : ps : what : retry ? ) } } -local rule get-relevant-features ( ) +# Attempt to build a metatarget named by 'metatarget-reference' +# in context of 'project' with properties 'ps'. +# Returns the 1-based index of the first target +# that builds. +rule find-builds-raw ( project : ps : what : * ) +{ + local result ; + local args = 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; + + if ! $(.$(what)-tested.$(ps)) + { + .$(what)-tested.$(ps) = true ; + local targets.$(i) what.$(i) ; + for local i in $(args) + { + if ! $($(i)) + { + break ; + } + targets.$(i) = [ targets.generate-from-reference + $($(i)[1]) : $(project) : $(ps) ] ; + # ignore usage requirements + targets.$(i) = $(targets.$(i)[2-]) ; + if $($(i)[2]) + { + what.$(i) = $($(i)[2]) ; + } + else + { + local t = [ targets.resolve-reference + $($(i)[1]) : $(project) ] ; + what.$(i) = [ $(t[1]).name ] ; + } + } + + result = [ try-find-build $(ps) : $(what) + : $(what.4) $(targets.4) + : $(what.5) $(targets.5) + : $(what.6) $(targets.6) + : $(what.7) $(targets.7) + : $(what.8) $(targets.8) + : $(what.9) $(targets.9) + : $(what.10) $(targets.10) + : $(what.11) $(targets.11) + : $(what.12) $(targets.12) + : $(what.13) $(targets.13) + : $(what.14) $(targets.14) + : $(what.15) $(targets.15) + : $(what.16) $(targets.16) + : $(what.17) $(targets.17) + : $(what.18) $(targets.18) + : $(what.19) $(targets.19) ] ; + .$(what)-result.$(ps) = $(result) ; + + return $(result) ; + } + else + { + return $(.$(what)-result.$(ps)) ; + } +} + +rule get-relevant-features ( ) { local relevant = [ feature.expand ] ; local result = ; @@ -270,6 +442,19 @@ rule builds ( metatarget-reference : properties * : what ? : retry ? ) $(retry) ] ; } +rule find-builds ( what : properties * : * ) +{ + local relevant = [ property.select [ get-relevant-features ] : $(properties) ] ; + local ps = [ property-set.create $(relevant) ] ; + local t = [ targets.current ] ; + local p = [ $(t).project ] ; + + return [ find-builds-raw $(p) : $(ps) : $(what) : + $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : + $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : + $(16) : $(17) : $(18) : $(19) ] ; +} + # Called by Boost.Build startup code to specify the file to receive the # configuration check results. Should never be called by user code. @@ -277,7 +462,11 @@ rule builds ( metatarget-reference : properties * : what ? : retry ? ) rule set-log-file ( log-file ) { path.makedirs [ path.parent $(log-file) ] ; - .log-fd = [ FILE_OPEN $(log-file) : "w" ] ; + .log-fd = [ FILE_OPEN [ path.native $(log-file) ] : "w" ] ; + if ! $(.log-fd) + { + ECHO "warning:" failed to open log file $(log-file) for writing ; + } } @@ -314,13 +503,89 @@ class check-target-builds-worker } } +class configure-choose-worker +{ + import configure ; + import property ; + rule __init__ ( message : * ) + { + self.message = $(message) ; + for i in 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 + { + local name = [ CALC $(i) - 1 ] ; + self.targets.$(name) = $($(i)[1]) ; + if ! $($(i)[2]:G) # Check whether the second argument is a property + { + self.what.$(name) = $($(i)[2]) ; + self.props.$(name) = $($(i)[3-]) ; + } + else + { + self.props.$(name) = $($(i)[2-]) ; + } + } + } + rule all-properties ( ) + { + local i = 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ; + return $(self.props.$(i)) ; + } + rule check ( properties * ) + { + local i = [ configure.find-builds $(self.message) : $(properties) + : $(self.targets.1) $(self.what.1) + : $(self.targets.2) $(self.what.2) + : $(self.targets.3) $(self.what.3) + : $(self.targets.4) $(self.what.4) + : $(self.targets.5) $(self.what.5) + : $(self.targets.6) $(self.what.6) + : $(self.targets.7) $(self.what.7) + : $(self.targets.8) $(self.what.8) + : $(self.targets.9) $(self.what.9) + : $(self.targets.10) $(self.what.10) + : $(self.targets.11) $(self.what.11) + : $(self.targets.12) $(self.what.12) + : $(self.targets.13) $(self.what.13) + : $(self.targets.14) $(self.what.14) + : $(self.targets.15) $(self.what.15) + : $(self.targets.16) $(self.what.16) + : $(self.targets.17) $(self.what.17) + : $(self.targets.18) $(self.what.18) + : $(self.targets.19) $(self.what.19) ] ; + if $(self.props.$(i)) + { + return [ property.evaluate-conditionals-in-context $(self.props.$(i)) : $(properties) ] ; + } + } +} + rule check-target-builds ( target message ? : true-properties * : false-properties * ) { local instance = [ new check-target-builds-worker $(target) $(message) : $(true-properties) : $(false-properties) ] ; - return @$(instance).check ; + return @$(instance).check + [ property.evaluate-conditional-relevance + $(true-properties) $(false-properties) + : [ configure.get-relevant-features ] ] ; +} + +# Usage: +# [ configure.choose "architecture" +# : /config//x86 x86 x86 +# : /config//mips mips mips +# ] +rule choose ( message : * ) +{ + local instance = [ new configure-choose-worker $(message) + : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) + : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) + : $(17) : $(18) : $(19) ] ; + return @$(instance).check + [ property.evaluate-conditional-relevance + [ $(instance).all-properties ] + : [ configure.get-relevant-features ] ] ; } diff --git a/tools/build/src/build/feature.jam b/tools/build/src/build/feature.jam index e58edcbedb..182d39f80d 100644 --- a/tools/build/src/build/feature.jam +++ b/tools/build/src/build/feature.jam @@ -108,12 +108,12 @@ rule feature ( # Check for any unknown attributes. if ! ( $(attributes) in $(.all-attributes) ) { - error = unknown attributes: + error = unknown "attributes:" [ set.difference $(attributes) : $(.all-attributes) ] ; } else if $(name) in $(.all-features) { - error = feature already defined: ; + error = feature already "defined:" ; } else if implicit in $(attributes) && free in $(attributes) { @@ -136,7 +136,7 @@ rule feature ( { import errors ; errors.error $(error) - : "in" feature declaration: + : "in" feature "declaration:" : feature [ errors.lol->list $(1) : $(2) : $(3) ] ; } @@ -182,7 +182,7 @@ rule set-default ( feature : value ) { import errors ; errors.error The specified default value, '$(value)' is invalid : - allowed values are: $($(f).values) ; + allowed values "are:" $($(f).values) ; } $(f).default = $(value) ; } @@ -289,7 +289,8 @@ local rule find-implied-subfeature ( feature subvalue : value-string ? ) import errors ; errors.error invalid feature $(feature) ; } - return $($(feature)$(value-string:E="")<>$(subvalue).subfeature) ; + value-string += "" ; + return $($(feature)$(value-string)<>$(subvalue).subfeature) ; } @@ -371,12 +372,8 @@ local rule expand-subfeatures-aux ( local result = $(components[1]:G=$(feature)) ; - local subvalues = $(components[2-]) ; - while $(subvalues) + for local subvalue in $(components[2-]) { - local subvalue = $(subvalues[1]) ; # Pop the head off of subvalues. - subvalues = $(subvalues[2-]) ; - local subfeature = [ find-implied-subfeature $(feature) $(subvalue) : $(value) ] ; @@ -385,7 +382,7 @@ local rule expand-subfeatures-aux ( { result = $(components:J=-) ; result = $(result:G=$(feature)) ; - subvalues = ; # Stop looping. + break ; } else { @@ -491,7 +488,7 @@ rule validate-value-string ( feature value-string ) { import errors ; errors.error \"$(values[1])\" is not a known value of feature - $(feature) : legal values: \"$($(feature).values)\" ; + $(feature) : legal "values:" \"$($(feature).values)\" ; } for local v in $(values[2-]) @@ -619,7 +616,7 @@ rule extend ( feature-or-property subfeature ? : values * ) import errors ; errors.error can only specify a property as the first argument when extending a subfeature - : usage: + : "usage:" : " extend" feature ":" values... : " | extend" value-string subfeature ":" values... ; } @@ -631,7 +628,7 @@ rule extend ( feature-or-property subfeature ? : values * ) local rule get-subfeature-name ( subfeature value-string ? ) { - local prefix = $(value-string): ; + local prefix = "$(value-string):" ; return $(prefix:E="")$(subfeature) ; } @@ -665,6 +662,10 @@ rule subfeature ( local f = [ utility.ungrist $(feature) ] ; feature $(f)-$(subfeature-name) : $(subvalues) : $(attributes) subfeature ; + # Features and subfeatures are always relevent as a group + .feature-dependencies.$(f) += $(f)-$(subfeature-name) ; + .feature-dependencies.$(f)-$(subfeature-name) += $(f) ; + # Now make sure the subfeature values are known. extend-subfeature $(feature) $(value-string) : $(subfeature) : $(subvalues) ; } @@ -685,7 +686,7 @@ rule compose ( composite-property : component-properties * ) if $($(composite-property).components) { import errors ; - errors.error components of "$(composite-property)" already set: + errors.error components of "$(composite-property)" already "set:" $($(composite-property).components) ; } @@ -695,6 +696,10 @@ rule compose ( composite-property : component-properties * ) errors.error composite property "$(composite-property)" cannot have itself as a component ; } $(composite-property).components = $(component-properties) ; + + # A composite feature is relevant if any composed feature is relevant + local component-features = [ sequence.transform utility.ungrist : $(component-properties:G) ] ; + .feature-dependencies.$(component-features) += [ utility.ungrist $(feature) ] ; } @@ -764,7 +769,7 @@ rule expand-composites ( properties * ) import errors ; errors.error expansions of composite features result in conflicting values for $(f) - : values: [ get-values $(f) : $(result) ] $(x:G=) + : "values:" [ get-values $(f) : $(result) ] $(x:G=) : one contributing composite property was $(p) ; } else @@ -993,7 +998,7 @@ rule compress-subproperties ( properties * ) if ! $(p:G) { # Expecting fully-gristed properties. - assert.variable-not-empty p:G ; + assert.variable-not-empty "p:G" ; } if ! subfeature in $($(p:G).attributes) @@ -1043,6 +1048,8 @@ local rule split-top-feature ( feature-plus ) # Given a set of properties, add default values for features not represented in # the set. # +# properties must be fully expanded and must not contain conditionals. +# # Note: if there's an ordinary feature F1 and a composite feature F2 which # includes some value for F1 and both feature have default values then the # default value of F1 will be added (as opposed to the value in F2). This might @@ -1070,27 +1077,65 @@ rule add-defaults ( properties * ) feature ; } } - # We don't add default for elements with ":" inside. This catches: - # 1. Conditional properties --- we don't want debug:DEBUG - # to be takes as specified value for - # 2. Free properties with ":" in values. We don't care, since free - # properties don't have defaults. - local xproperties = [ MATCH "^([^:]+)$" : $(properties) ] ; - local missing-top = [ set.difference $(.all-top-features) : $(xproperties:G) ] ; + local missing-top = [ set.difference $(.all-top-features) : $(properties:G) ] ; local more = [ defaults $(missing-top) ] ; - properties += $(more) ; - xproperties += $(more) ; - # Add defaults for subfeatures of features which are present. - for local p in $(xproperties) + # This is similar to property.refine, except that it + # does not remove subfeatures, because we might be adding + # the default value of a subfeature. + local to-remove ; + for local f in $(properties:G) { - local s = $($(p:G).subfeatures) ; - local f = [ utility.ungrist $(p:G) ] ; - local missing-subs = [ set.difference <$(f)-$(s)> : $(properties:G) ] ; - properties += [ defaults [ select-subfeatures $(p) : $(missing-subs) ] ] ; + if ! free in [ attributes $(f) ] + { + to-remove += $(f) ; + } } - return $(properties) ; + local worklist = $(properties) ; + local expanded-from-composite ; + local to-expand = $(more) ; + while $(worklist) + { + # Add defaults for subfeatures of features which are present. + for local p in $(worklist) + { + local s = $($(p:G).subfeatures) ; + local f = [ utility.ungrist $(p:G) ] ; + local missing-subs = [ set.difference <$(f)-$(s)> : $(properties:G) ] ; + local sd = [ defaults [ select-subfeatures $(p) : $(missing-subs) ] ] ; + to-expand += $(sd) ; + } + worklist = ; + + # Expand subfeatures of newly added properties + for local m in [ sequence.transform expand-composite : $(to-expand) ] + { + if ! $(m:G) in $(to-remove) + { + local att = [ attributes $(m:G) ] ; + if $(m:G) in $(expanded-from-composite) && + ! free in $(att) && + ! $(m) in $(more) + { + import errors ; + errors.error "default values for $(p:G) conflict" ; + } + if ! $(m) in $(to-expand) + { + expanded-from-composite += $(m:G) ; + } + more += $(m) ; + if ! subfeature in $(att) && ! free in $(att) + { + worklist += $(m) ; + } + } + } + to-expand = ; + } + + return [ sequence.unique $(properties) $(more) ] ; } @@ -1106,7 +1151,7 @@ rule add-defaults ( properties * ) # rule split ( property-set ) { - local pieces = [ regex.split $(property-set) [\\/] ] ; + local pieces = [ regex.split $(property-set) "[\\/]" ] ; local result ; for local x in $(pieces) @@ -1124,6 +1169,41 @@ rule split ( property-set ) return $(result) ; } +# Returns all the features that also must be relevant when these features are relevant +rule expand-relevant ( features * ) +{ + local conditional ; + local result ; + for f in $(features) + { + # This looks like a conditional, even though it isn't really. + # (Free features can never be used in conditionals) + local split = [ MATCH "^(.*):(.*)$" : $(f) ] ; + if $(split) + { + local-dependencies.$(split[1]) += $(split[2]) ; + conditional += local-dependencies.$(split[1]) ; + } + else + { + result += $(f) ; + } + } + local queue = $(result) ; + while $(queue) + { + local added = [ set.difference + $(.feature-dependencies.$(queue)) + $(local-dependencies.$(queue)) + : $(result) ] ; + result += $(added) ; + queue = $(added) ; + } + # Clean up local map + $(conditional) = ; + return $(result) ; +} + # Tests of module feature. # @@ -1202,6 +1282,9 @@ rule __test__ ( ) assert.result foo=x-y : expand-subfeatures foo=x-y ; + assert.result minus=- + : expand-subfeatures minus=- ; + assert.result gcc 3.0.1 : expand-subfeatures gcc-3.0.1 ; @@ -1234,17 +1317,18 @@ rule __test__ ( ) assert.result optional : attributes ; - assert.result static foobar on - gcc:FOO gcc debug native - dummy1 2.95.2 - : add-defaults static foobar on - gcc:FOO ; + assert.result [ SORT _DEBUG static + foobar on + gcc debug native + dummy1 2.95.2 ] + : add-defaults static foobar on ; - assert.result static foobar on - gcc:FOO fu1 gcc debug - native dummy1 q 2.95.2 + assert.result [ SORT _DEBUG static + foobar on + fu1 gcc debug + native dummy1 q 2.95.2 ] : add-defaults static foobar on - gcc:FOO fu1 ; + fu1 ; set-default : static ; assert.result static : defaults ; @@ -1307,14 +1391,14 @@ rule __test__ ( ) { feature foobar : : baz ; } - catch unknown attributes: baz ; + catch unknown "attributes:" baz ; feature feature1 ; try ; { feature feature1 ; } - catch feature already defined: ; + catch feature already "defined:" ; try ; { diff --git a/tools/build/src/build/generators.jam b/tools/build/src/build/generators.jam index c26db72578..631251b3c6 100644 --- a/tools/build/src/build/generators.jam +++ b/tools/build/src/build/generators.jam @@ -167,8 +167,10 @@ class generator import utility ; import path ; import property ; + import property-set ; import sequence ; import set ; + import toolset ; import type ; import virtual-target ; @@ -215,7 +217,7 @@ class generator # name. We use parallel lists for prefix and postfix (as opposed to # mapping), because given target type might occur several times, for # example "H H(%_symbols)". - local m = [ MATCH ([^\\(]*)(\\((.*)%(.*)\\))? : $(e) ] ; + local m = [ MATCH "([^\\(]*)(\\((.*)%(.*)\\))?" : $(e) ] ; self.target-types += $(m[1]) ; self.name-prefix += $(m[3]:E="") ; self.name-postfix += $(m[4]:E="") ; @@ -236,6 +238,10 @@ class generator # Note that 'transform' here, is the same as 'for_each'. sequence.transform type.validate : $(self.source-types) ; sequence.transform type.validate : $(self.target-types) ; + + local relevant-for-generator = + [ sequence.transform utility.ungrist : $(requirements:G) ] ; + self.relevant-features = [ property-set.create $(relevant-for-generator) ] ; } ################# End of constructor ################# @@ -327,7 +333,7 @@ class generator local target-types ; for local t in $(self.target-types-and-names) { - local m = [ MATCH ([^\\(]*)(\\(.*\\))? : $(t) ] ; + local m = [ MATCH "([^\\(]*)(\\(.*\\))?" : $(t) ] ; if $(m) = $(base) { target-types += $(type)$(m[2]:E="") ; @@ -406,10 +412,10 @@ class generator } local result ; - if $(consumed) + if $(consumed[2]) { - result = [ construct-result $(consumed) : $(project) $(name) : - $(property-set) ] ; + result = [ construct-result $(consumed[2-]) : $(project) $(name) : + [ $(property-set).add $(consumed[1]) ] ] ; } if $(result) @@ -421,7 +427,11 @@ class generator generators.dout [ indent ] " FAILURE" ; } generators.dout ; - return $(result) ; + if $(result) + { + # Make sure that we propagate usage-requirements up the stack. + return [ $(result[1]).add $(consumed[1]) ] $(result[2-]) ; + } } # Constructs the dependency graph to be returned by this generator. @@ -443,6 +453,11 @@ class generator ) { local result ; + + local relevant = [ toolset.relevant $(self.rule-name) ] ; + relevant = [ $(relevant).add $(self.relevant-features) ] ; + property-set = [ $(property-set).add $(relevant) ] ; + # If this is a 1->1 transformation, apply it to all consumed targets in # order. if ! $(self.source-types[2]) && ! $(self.composing) @@ -458,7 +473,10 @@ class generator result += [ generated-targets $(consumed) : $(property-set) : $(project) $(name) ] ; } - return $(result) ; + if $(result) + { + return $(relevant) $(result) ; + } } # Determine target name from fullname (maybe including path components) @@ -576,6 +594,7 @@ class generator { local _consumed ; local missing-types ; + local usage-requirements ; if $(sources[2]) { @@ -588,6 +607,7 @@ class generator local temp = [ consume-directly $(sources) ] ; if $(temp[1]) { + usage-requirements = [ property-set.empty ] ; _consumed = $(temp[1]) ; } missing-types = $(temp[2-]) ; @@ -613,7 +633,7 @@ class generator # everything to the required type. There is no need to rerun it on # targets of different types. - # NOTE: ignoring usage requirements. + usage-requirements = $(transformed[1]) ; for local t in $(transformed[2-]) { if [ $(t).type ] in $(missing-types) @@ -623,7 +643,7 @@ class generator } } - return [ sequence.unique $(_consumed) ] ; + return $(usage-requirements) [ sequence.unique $(_consumed) ] ; } # Converts several files to consumable types. Called for composing @@ -638,10 +658,11 @@ class generator if ! $(self.source-types) { # Anything is acceptible - return $(sources) ; + return [ property-set.empty ] $(sources) ; } else { + local usage-requirements = [ property-set.empty ] ; local acceptible-types = [ sequence.unique [ sequence.transform type.all-derived : $(self.source-types) ] ] ; for local source in $(sources) @@ -661,13 +682,17 @@ class generator { generators.dout [ indent ] " failed to convert " $(source) ; } + else + { + usage-requirements = [ $(usage-requirements).add $(transformed[1]) ] ; + } } else { result += $(source) ; } } - return [ sequence.unique $(result) : stable ] ; + return $(usage-requirements) [ sequence.unique $(result) : stable ] ; } } @@ -1354,7 +1379,9 @@ rule construct ( project name ? : target-type : property-set * : sources * : top .active-generators = ; } - if (.construct-stack) + # FIXME This is probably not intended be be run unconditionally, + # but changing it causes no_type to fail. + if "(.construct-stack)" { ensure-type $(sources) ; } diff --git a/tools/build/src/build/project.jam b/tools/build/src/build/project.jam index 2b3386a135..2ad621acdd 100644 --- a/tools/build/src/build/project.jam +++ b/tools/build/src/build/project.jam @@ -96,7 +96,7 @@ rule load-used-projects ( module-name ) # 'jamroot'. With the latter, we would get duplicate matches on Windows and # would have to eliminate duplicates. JAMROOT ?= [ modules.peek : JAMROOT ] ; -JAMROOT ?= project-root.jam [Jj]amroot [Jj]amroot. [Jj]amroot.jam ; +JAMROOT ?= project-root.jam "[Jj]amroot" "[Jj]amroot." "[Jj]amroot.jam" ; # Loads parent of Jamfile at 'location'. Issues an error if nothing is found. @@ -191,7 +191,7 @@ rule module-name ( jamfile-location ) # Default patterns to search for the Jamfiles to use for build declarations. # JAMFILE = [ modules.peek : JAMFILE ] ; -JAMFILE ?= [Bb]uild.jam [Jj]amfile.v2 [Jj]amfile [Jj]amfile. [Jj]amfile.jam ; +JAMFILE ?= "[Bb]uild.jam" "[Jj]amfile.v2" "[Jj]amfile" "[Jj]amfile." "[Jj]amfile.jam" ; # Find the Jamfile at the given location. This returns the exact names of all @@ -234,7 +234,7 @@ rule find-jamfile ( # if $(jamfile-to-load[2-]) { - local v2-jamfiles = [ MATCH ^(.*[Jj]amfile\\.v2)|(.*[Bb]uild\\.jam)$ : + local v2-jamfiles = [ MATCH "^(.*[Jj]amfile\\.v2)|(.*[Bb]uild\\.jam)$" : $(jamfile-to-load) ] ; if $(v2-jamfiles) && ! $(v2-jamfiles[2]) @@ -259,7 +259,7 @@ rule find-jamfile ( errors.error Unable to load Jamfile. : Could not find a Jamfile in directory '$(dir)'. : Attempted to find it with pattern '$(JAMFILE:J=" ")'. - : Please consult the documentation at 'http://www.boost.org'. ; + : Please consult the documentation at "'http://www.boost.org'." ; } return $(jamfile-to-load) ; @@ -441,7 +441,7 @@ rule initialize ( local jamroot ; local parent-module ; - if $(module-name) = test-config + if $(module-name) in test-config all-config { # No parent. } @@ -502,7 +502,7 @@ rule initialize ( } else { - local cfgs = project site test user ; + local cfgs = project site test user all ; if ! $(module-name) in $(cfgs)-config { # This is a standalone project with known location. Set its @@ -627,7 +627,7 @@ rule register-id ( id : module ) { import errors ; errors.user-error Project id may not contain two consecutive slash - characters (project id: '$(id)'). ; + characters (project "id:" '$(id)'). ; } local orig-module = $($(id).jamfile-module) ; @@ -645,16 +645,16 @@ rule register-id ( id : module ) import errors ; errors.user-error Attempt to redeclare already registered project id '$(id)'. - : Original project: - : " " Name: $(orig-name:E=---) - : " " Module: $(orig-module) - : " " Main id: $(orig-main-id:E=---) - : " " File: $(orig-file:E=---) - : " " Location: $(orig-location:E=---) - : New project: - : " " Module: $(module) - : " " File: $(new-file:E=---) - : " " Location: $(new-location:E=---) ; + : Original "project:" + : " " "Name:" $(orig-name:E=---) + : " " "Module:" $(orig-module) + : " " "Main id: "$(orig-main-id:E=---) + : " " "File:" $(orig-file:E=---) + : " " "Location:" $(orig-location:E=---) + : New "project:" + : " " "Module:" $(module) + : " " "File:" $(new-file:E=---) + : " " "Location:" $(new-location:E=---) ; } $(id).jamfile-module = $(module) ; @@ -703,7 +703,7 @@ class project-attributes { import errors : error : errors.error ; errors.error Requirements for project at '$(self.location)' - conflict with parent's. : Explanation: $(result[2-]) ; + conflict with parent's. : "Explanation:" $(result[2-]) ; } self.requirements = $(result) ; @@ -833,7 +833,7 @@ rule current ( ) # Temporarily changes the current project to 'project'. Should be followed by # 'pop-current'. # -rule push-current ( project ) +rule push-current ( project ? ) { .saved-current-project += $(.current-project) ; .current-project = $(project) ; @@ -900,9 +900,9 @@ rule get-jamroot-module ( project ) # Returns the project target corresponding to the 'project-module'. # -rule target ( project-module ) +rule target ( project-module : allow-missing ? ) { - if ! $(.target.$(project-module)) + if ! $(.target.$(project-module)) && ! $(allow-missing) { import errors ; errors.user-error Project target requested but not yet assigned for @@ -1261,13 +1261,13 @@ module project-rules rule conditional ( condition + : requirements * ) { local condition = $(condition:J=,) ; - if [ MATCH (:) : $(condition) ] + if [ MATCH "(:)" : $(condition) ] { return $(condition)$(requirements) ; } else { - return $(condition):$(requirements) ; + return "$(condition):$(requirements)" ; } } diff --git a/tools/build/src/build/property-set.jam b/tools/build/src/build/property-set.jam index 55cb556453..d7d737f059 100644 --- a/tools/build/src/build/property-set.jam +++ b/tools/build/src/build/property-set.jam @@ -34,6 +34,7 @@ class property-set { import errors ; import feature ; + import modules ; import path ; import property ; import property-set ; @@ -86,6 +87,48 @@ class property-set return $(self.free) ; } + # Returns relevant base properties. This is used for computing + # target paths, so it must return the expanded set of relevant + # properties. + # + rule base-relevant ( ) + { + if ! $(self.relevant-initialized) + { + init-relevant ; + } + return $(self.base-relevant) ; + } + + # Returns all properties marked as relevant by features-ps + # Does not attempt to expand features-ps in any way, as + # this matches what virtual-target.register needs. + # + rule relevant ( features-ps ) + { + if ! $(self.relevant.$(features-ps)) + { + local result ; + local features = [ $(features-ps).get ] ; + features = <$(features)> ; + local ignore-relevance = [ modules.peek + property-set : .ignore-relevance ] ; + for local p in $(self.raw) + { + if $(ignore-relevance) || $(p:G) in $(features) + { + local att = [ feature.attributes $(p:G) ] ; + if ! ( incidental in $(att) ) + { + result += $(p) ; + } + } + } + self.relevant.$(features-ps) = [ property-set.create $(result) ] ; + } + return $(self.relevant.$(features-ps)) ; + } + # Returns dependency properties. # rule dependency ( ) @@ -215,7 +258,7 @@ class property-set { if ! $(self.as-path) { - self.as-path = [ property.as-path [ base ] ] ; + self.as-path = [ property.as-path [ base-relevant ] ] ; } return $(self.as-path) ; } @@ -345,6 +388,30 @@ class property-set self.base-initialized = true ; } + rule init-relevant ( ) + { + local relevant-features = [ get ] ; + relevant-features = [ feature.expand-relevant $(relevant-features) ] ; + relevant-features = <$(relevant-features)> ; + ignore-relevance = [ modules.peek property-set : .ignore-relevance ] ; + for local p in $(self.raw) + { + if $(ignore-relevance) || $(p:G) in $(relevant-features) + { + local att = [ feature.attributes $(p:G) ] ; + if ! ( incidental in $(att) ) + { + self.relevant += $(p) ; + if ! ( free in $(att) ) + { + self.base-relevant += $(p) ; + } + } + } + } + self.relevant-initialized = true ; + } + rule init-dependency ( ) { for local p in $(self.raw) @@ -369,7 +436,7 @@ class property-set # characters as well, e.g. free or indirect properties. Indirect # properties for example contain a full Jamfile path in their value # which on Windows file systems contains ':' as the drive separator. - if [ MATCH (:) : $(p:G=) ] + if ( [ MATCH "(:)" : $(p:G=) ] && ! ( free in [ feature.attributes $(p:G) ] ) ) || $(p:G) = { self.conditional += $(p) ; } @@ -382,6 +449,13 @@ class property-set } } +# This is a temporary measure to help users work around +# any problems. Remove it once we've verified that +# everything works. +if --ignore-relevance in [ modules.peek : ARGV ] +{ + .ignore-relevance = true ; +} # Creates a new 'property-set' instance for the given raw properties or returns # an already existing ones. diff --git a/tools/build/src/build/property.jam b/tools/build/src/build/property.jam index 78a9744b16..a1bfe3f352 100644 --- a/tools/build/src/build/property.jam +++ b/tools/build/src/build/property.jam @@ -28,8 +28,20 @@ rule refine ( properties * : requirements * ) for local r in $(requirements) { # Do not consider conditional requirements. - if ! [ MATCH (:) : $(r:G=) ] && ! free in [ feature.attributes $(r:G) ] + if ! [ MATCH "(:<)" : $(r:G=) ] && ! free in [ feature.attributes $(r:G) ] { + if ! $(r) in $(properties) + { + # Kill subfeatures of properties that we're changing + local sub = [ modules.peek feature : $(r:G).subfeatures ] ; + if $(sub) + { + # non-specific subfeatures are still valid + sub = [ MATCH "(.*:.*)" : $(sub) ] ; + local name = [ utility.ungrist $(r:G) ] ; + unset += <$(name)-$(sub)> ; + } + } unset += $(r:G) ; } } @@ -37,7 +49,7 @@ rule refine ( properties * : requirements * ) # Remove properties that are overridden by requirements for local p in $(properties) { - if [ MATCH (:) : $(p:G=) ] || ! $(p:G) in $(unset) + if [ MATCH "(:<)" : $(p:G=) ] || ! $(p:G) in $(unset) { result += $(p) ; } @@ -55,12 +67,17 @@ rule evaluate-conditionals-in-context ( properties * : context * ) { local base ; local conditionals ; + local indirect ; for local p in $(properties) { - if [ MATCH (:<) : $(p) ] + if [ MATCH "(:<)" : $(p) ] && ! free in [ feature.attributes $(p:G) ] { conditionals += $(p) ; } + else if $(p:G) = + { + indirect += $(p) ; + } else { base += $(p) ; @@ -71,7 +88,7 @@ rule evaluate-conditionals-in-context ( properties * : context * ) for local p in $(conditionals) { # Separate condition and property. - local s = [ MATCH ^(.*):(<.*) : $(p) ] ; + local s = [ MATCH "^(.*):(<.*)" : $(p) ] ; # Split condition into individual properties. local condition = [ regex.split $(s[1]) "," ] ; # Evaluate condition. @@ -116,16 +133,64 @@ rule evaluate-conditionals-in-context ( properties * : context * ) } } } + # Import here to avoid cyclic dependency + import project ; + for local i in [ MATCH "^@(.*)" : $(indirect:G=) ] + { + # If the rule was set in a project module, translate paths + # relative to that project's location. + local m = [ indirect.get-module $(i) ] ; + local p = [ project.target $(m) : allow-missing ] ; + local new = [ indirect.call $(i) $(context) ] ; + if $(p) && [ $(p).location ] + { + result += [ translate-paths $(new) : [ $(p).location ] ] ; + } + else + { + result += $(new) ; + } + } return $(result) ; } +# Returns properties indicating how the conditionals in +# properties affect feature relevance. If the optional argument cond +# is passed, it is treated as extra conditions for all properties. +# +rule evaluate-conditional-relevance ( properties * : cond * ) +{ + cond = [ sequence.transform utility.ungrist : $(cond:G) ] ; + local result ; + for local p in $(properties) + { + # Separate condition and property. + local s = [ MATCH "^(.*):(<.*)" : $(p) ] ; + if ! $(s) || free in [ feature.attributes $(p:G) ] + { + local value = [ utility.ungrist $(p:G) ] ; + result += $(value):$(cond) ; + } + else + { + local condition = [ regex.split $(s[1]) "," ] ; + condition = [ MATCH "^!?(.*)" : $(condition) ] ; + condition = [ sequence.transform utility.ungrist : $(condition:G) ] $(cond) ; + local value = [ utility.ungrist $(s[2]:G) ] ; + result += $(value):$(condition) ; + } + } + return [ sequence.unique $(result) ] ; +} + + rule expand-subfeatures-in-conditions ( properties * ) { local result ; for local p in $(properties) { - local s = [ MATCH ^(.*):(<.*) : $(p) ] ; + local s = [ MATCH "^(.*):(<.*)" : $(p) ] ; if ! $(s) { result += $(p) ; @@ -156,7 +221,7 @@ rule expand-subfeatures-in-conditions ( properties * ) } else { - result += $(e:J=,):$(value) ; + result += "$(e:J=,):$(value)" ; } } } @@ -508,7 +573,7 @@ rule translate ( properties * : project-id : project-location : context-module ) e += [ feature.expand-subfeatures $(c) : true ] ; } - condition = $(e:J=,): ; + condition = "$(e:J=,):" ; } else { @@ -580,7 +645,7 @@ rule translate-paths ( properties * : path ) local condition = "" ; if $(split) { - condition = $(split[1]): ; + condition = "$(split[1]):" ; p = $(split[2]) ; } @@ -665,7 +730,7 @@ rule translate-dependencies ( specification * : project-id : location ) local condition = "" ; if $(split) { - condition = $(split[1]): ; + condition = "$(split[1]):" ; p = $(split[2]) ; } if dependency in [ feature.attributes $(p:G) ] @@ -898,7 +963,7 @@ rule __test__ ( ) assert.result : split-conditional gcc ; # Test properties with ":". - assert.result : split-conditional FOO=A::B ; + assert.result : split-conditional "FOO=A::B" ; # Test conditional feature. assert.result-set-equal gcc,3.0 FOO diff --git a/tools/build/src/build/targets.jam b/tools/build/src/build/targets.jam index 16caaa8146..b16429d229 100644 --- a/tools/build/src/build/targets.jam +++ b/tools/build/src/build/targets.jam @@ -191,6 +191,7 @@ class project-target : abstract-target import property-set ; import set ; import sequence ; + import toolset ; import "class" : new ; rule __init__ ( name : project-module parent-project ? @@ -584,6 +585,8 @@ class project-target : abstract-target IMPORT $(parent-module) : $(user-rules) : $(this-module) : $(user-rules) ; EXPORT $(this-module) : $(user-rules) ; + + toolset.inherit-flags $(this-module) : $(parent-module) ; } } @@ -621,10 +624,11 @@ class main-target : abstract-target { import assert ; import feature ; - import print ; import property-set ; import sequence ; + import set ; import targets : start-building end-building ; + import utility ; rule __init__ ( name : project ) { @@ -719,6 +723,43 @@ class main-target : abstract-target } } + # Features are relevant here if they could affect alternative + # selection. That is, base, non-conditional properties that + # are not identical in all target alternatives. + rule relevant-features ( ) + { + if $(self.alternatives[2-]) + { + if $(self.relevant-features) + { + return $(self.relevant-features) ; + } + local all-properties ; + for t in $(self.alternatives) + { + local ps = [ $(t).requirements ] ; + ps = [ property-set.create [ $(ps).non-conditional ] ] ; + all-properties += [ $(ps).base ] ; + } + all-properties = [ sequence.unique $(all-properties) ] ; + local result ; + for t in $(self.alternatives) + { + local ps = [ $(t).requirements ] ; + ps = [ property-set.create [ $(ps).non-conditional ] ] ; + local properties = [ set.difference $(all-properties) : [ $(ps).base ] ] ; + result += $(properties:G) ; + } + result = [ sequence.transform utility.ungrist : [ sequence.unique $(result) ] ] ; + self.relevant-features = [ property-set.create $(result) ] ; + return $(self.relevant-features) ; + } + else + { + return [ property-set.empty ] ; + } + } + rule apply-default-build ( property-set ) { return [ targets.apply-default-build $(property-set) : @@ -734,16 +775,13 @@ class main-target : abstract-target { start-building $(__name__) ; - # We want composite properties in the build request to act as if all the - # properties they expand to have been explicitly specified. - property-set = [ $(property-set).expand ] ; - local all-property-sets = [ apply-default-build $(property-set) ] ; + local relevant = [ relevant-features ] ; local usage-requirements = [ property-set.empty ] ; local result ; for local p in $(all-property-sets) { - local r = [ generate-really $(p) ] ; + local r = [ generate-really [ $(p).add $(relevant) ] ] ; if $(r) { usage-requirements = [ $(usage-requirements).add $(r[1]) ] ; @@ -901,8 +939,10 @@ rule apply-default-build ( property-set : default-build ) # 1. First, see what properties from default-build are already present in # property-set. + local expanded = [ $(property-set).expand ] ; local raw = [ $(property-set).raw ] ; - local specified-features = $(raw:G) ; + local specified-features = [ $(expanded).raw ] ; + specified-features = $(specified-features:G) ; local defaults-to-apply ; for local d in [ $(default-build).raw ] @@ -936,7 +976,7 @@ rule apply-default-build ( property-set : default-build ) for local p in $(properties) { result += [ property-set.create - [ feature.expand [ feature.split $(p) ] ] ] ; + [ feature.split $(p) ] ] ; } } else @@ -993,7 +1033,7 @@ rule common-properties ( build-request requirements ) # If 'what' is 'refined' returns context refined with new requirements. If # 'what' is 'added' returns just the requirements to be applied. # -rule evaluate-requirements ( requirements : context : what ) +rule evaluate-requirements ( requirements : context ) { # Apply non-conditional requirements. It is possible that further # conditional requirement change a value set by non-conditional @@ -1017,45 +1057,38 @@ rule evaluate-requirements ( requirements : context : what ) # properties. We now try to figure out what other properties should be added # in order to satisfy rules (4)-(6) from the docs. + local defaults = [ toolset.defaults ] ; + defaults = [ $(defaults).raw ] ; + local conditionals = [ $(requirements).conditional ] ; # The 'count' variable has one element for each conditional feature and for - # each occurrence of '' feature. It is used as a loop + # each occurrence of '' feature. It is used as a loop # counter: for each iteration of the loop before we remove one element and # the property set should stabilize before we are done. It is assumed that # #conditionals iterations should be enough for properties to propagate # along conditions in any direction. - local count = $(conditionals) [ $(requirements).get ] + local count = $(conditionals) $(defaults) and-once-more ; local added-requirements ; + local added-defaults ; local current = $(raw) ; - # It is assumed that ordinary conditional requirements can not add - # properties (a.k.a. indirect conditional properties), and - # that rules referred to by properties can not add new - # properties. So the list of indirect conditionals does not - # change. - local indirect = [ $(requirements).get ] ; - indirect = [ MATCH ^@(.*) : $(indirect) ] ; - local ok ; while $(count) { + # We need to expand composites here so that the requirements can + # safely override composite features. + current = [ feature.expand-composites $(current) ] ; + current = [ feature.add-defaults $(current) ] ; # Evaluate conditionals in context of current properties. local e = [ property.evaluate-conditionals-in-context $(conditionals) : $(current) ] ; + local d = [ property.evaluate-conditionals-in-context $(defaults) : + $(current) ] ; - # Evaluate indirect conditionals. - for local i in $(indirect) - { - local t = [ current ] ; - local p = [ $(t).project ] ; - local new = [ indirect.call $(i) $(current) ] ; - e += [ property.translate-paths $(new) : [ $(p).location ] ] ; - } - - if $(e) = $(added-requirements) + if $(e) = $(added-requirements) && $(d) = $(added-defaults) { # If we got the same result, we have found the final properties. count = ; @@ -1068,6 +1101,8 @@ rule evaluate-requirements ( requirements : context : what ) # using initial properties and conditional requirements. added-requirements = $(e) ; current = [ property.refine $(raw) : [ feature.expand $(e) ] ] ; + added-defaults = $(d) ; + current = [ property.refine $(d) : $(current) ] ; } count = $(count[2-]) ; } @@ -1077,39 +1112,13 @@ rule evaluate-requirements ( requirements : context : what ) errors.error Can not evaluate conditional properties $(conditionals) ; } - if $(what) = added - { - return [ property-set.create $(unconditional) $(added-requirements) ] ; - } - else if $(what) = refined - { - return [ property-set.create $(current) ] ; - } - else - { - import errors ; - errors.error "Invalid value of the 'what' parameter." ; - } + return [ property-set.create $(current) ] ; } rule common-properties2 ( build-request requirements ) { - # This guarantees that default properties are present in the result, unless - # they are overriden by some requirement. FIXME: There is a possibility that - # we have added bar, which is composite and expands to bar2, but - # default value of is not bar2, in which case it is not clear what to - # do. - # - build-request = [ $(build-request).add-defaults ] ; - # Features added by 'add-defaults' can be composite and expand to features - # without default values -- which therefore have not been added yet. It - # could be clearer/faster to expand only newly added properties but that is - # not critical. - build-request = [ $(build-request).expand ] ; - - return [ evaluate-requirements $(requirements) : $(build-request) : - refined ] ; + return [ evaluate-requirements $(requirements) : $(build-request) ] ; } @@ -1214,9 +1223,9 @@ class basic-target : abstract-target # rule match ( property-set debug ? ) { - # The condition is composed of all base non-conditional properties. It - # is not clear if we should expand 'self.requirements' or not. For one - # thing, it would be nice to be able to put + # The condition is composed of all base non-conditional properties. We + # only expand subfeatures in the condition. We do not expand + # composites. We want to be able to put # msvc-6.0 # in requirements. On the other hand, if we have release as a # condition it does not make sense to require full to be @@ -1224,6 +1233,7 @@ class basic-target : abstract-target local bcondition = [ $(self.requirements).base ] ; local ccondition = [ $(self.requirements).conditional ] ; local condition = [ set.difference $(bcondition) : $(ccondition) ] ; + condition = [ feature.expand-subfeatures $(condition) : unchecked ] ; if $(debug) { ECHO " next alternative: required properties:" @@ -1281,11 +1291,11 @@ class basic-target : abstract-target local fn = [ full-name ] ; ECHO [ targets.indent ] "Building target '$(fn)'" ; targets.increase-indent ; - ECHO [ targets.indent ] Build request: $(property-set) + ECHO [ targets.indent ] Build "request:" $(property-set) [ $(property-set).raw ] ; local cf = [ build-system.command-line-free-features ] ; - ECHO [ targets.indent ] Command line free features: [ $(cf).raw ] ; - ECHO [ targets.indent ] Target requirements: + ECHO [ targets.indent ] Command line free "features:" [ $(cf).raw ] ; + ECHO [ targets.indent ] Target "requirements:" [ $(self.requirements).raw ] ; } targets.push-target $(__name__) ; @@ -1294,7 +1304,7 @@ class basic-target : abstract-target # define=FOO # he most likely wants this define to be set for all compiles. # Make it before check for already built. - property-set = [ $(property-set).refine + property-set = [ $(property-set).add [ build-system.command-line-free-features ] ] ; if ! $(self.generated.$(property-set)) @@ -1357,6 +1367,15 @@ class basic-target : abstract-target local gur = $(result[1]) ; result = $(result[2-]) ; + # Relevant is automatically applied to usage requirements + # and only applies for propagated features + local relevant = [ propagated-relevant + [ $(gur).get ] + [ $(rproperties).get ] ] ; + gur = [ property-set.create + [ property.change [ $(gur).raw ] : ] + $(relevant) ] ; + if $(self.always) { for local t in $(result) @@ -1445,8 +1464,37 @@ class basic-target : abstract-target rule compute-usage-requirements ( subvariant ) { local rproperties = [ $(subvariant).build-properties ] ; - xusage-requirements = [ targets.evaluate-requirements - $(self.usage-requirements) : $(rproperties) : added ] ; + xusage-requirements = + [ $(self.usage-requirements).evaluate-conditionals + $(rproperties) ] ; + + # Filter out non-propagated properties + local relevant ; + for local r in [ $(xusage-requirements).get ] + { + local check = [ MATCH "(.*):(.*)" : $(r) ] ; + if $(check) { check = $(check[2]) ; } + else { check = $(r) ; } + if propagated in [ feature.attributes <$(check)> ] + { + relevant += $(r) ; + } + } + local raw = [ $(xusage-requirements).raw ] ; + local free = [ property.take free : $(raw) ] ; + if $(free) != $(raw) + { + if ! $(self.warned-usage-requirements) + { + self.warned-usage-requirements = true ; + ECHO "warning:" non-free usage requirements + [ set.difference $(raw) : $(free) ] ignored ; + ECHO "warning:" in main-target [ name ] at [ location ] ; + } + } + xusage-requirements = [ property-set.create + [ property.change $(free) : ] + $(relevant) ] ; # We generate all dependency properties and add them, as well as their # usage requirements, to the result. @@ -1487,6 +1535,19 @@ class basic-target : abstract-target return [ $(result).add [ property-set.create $(raw) ] ] ; } + local rule propagated-relevant ( values * ) + { + local result ; + for local v in [ feature.expand-relevant $(values) ] + { + if propagated in [ feature.attributes <$(v)> ] + { + result += $(v) ; + } + } + return $(result) ; + } + # Creates new subvariant instances for 'targets'. # 'root-targets' - virtual targets to be returned to dependants # 'all-targets' - virtual targets created while building this main target @@ -1633,7 +1694,8 @@ rule main-target-requirements ( import errors ; errors.error "Conflicting requirements for target:" $(requirements) ; } - return [ $(requirements).add [ toolset.requirements ] ] ; + local result = [ $(requirements).add [ toolset.requirements ] ] ; + return [ $(result).add-raw [ property.evaluate-conditional-relevance [ $(result).raw ] ] ] ; } @@ -1656,7 +1718,10 @@ rule main-target-usage-requirements ( $(specification) : [ $(project).project-module ] [ $(project).get location ] ] ; - return [ $(project-usage-requirements).add $(usage-requirements) ] ; + local result = [ $(project-usage-requirements).add $(usage-requirements) ] ; + local relevant = + [ property.evaluate-conditional-relevance [ $(result).raw ] ] ; + return [ $(result).add-raw $(relevant) ] ; } diff --git a/tools/build/src/build/toolset.jam b/tools/build/src/build/toolset.jam index a942cd9060..6a2ed98734 100644 --- a/tools/build/src/build/toolset.jam +++ b/tools/build/src/build/toolset.jam @@ -19,6 +19,7 @@ import set ; import property-set ; import order ; import "class" : new ; +import utility ; .flag-no = 1 ; @@ -76,6 +77,36 @@ rule pop-checking-for-flags-module ( ) } +# Specifies features that are referenced by the action rule. +# This is necessary in order to detect that these features +# are relevant. +# +rule uses-features ( rule-or-module : features * : unchecked ? ) +{ + local caller = [ CALLER_MODULE ] ; + if ! [ MATCH ".*([.]).*" : $(rule-or-module) ] + && [ MATCH "(Jamfile<.*)" : $(caller) ] + { + # Unqualified rule name, used inside Jamfile. Most likely used with + # 'make' or 'notfile' rules. This prevents setting flags on the entire + # Jamfile module (this will be considered as rule), but who cares? + # Probably, 'flags' rule should be split into 'flags' and + # 'flags-on-module'. + rule-or-module = $(caller).$(rule-or-module) ; + } + else + { + local module_ = [ MATCH "([^.]*).*" : $(rule-or-module) ] ; + if $(unchecked) != unchecked + && $(.flags-module-checking[1]) != unchecked + && $(module_) != $(caller) + { + errors.error "Module $(caller) attempted to set flags for module $(module_)" ; + } + } + .uses-features.$(rule-or-module) += $(features) ; +} + # Specifies the flags (variables) that must be set on targets under certain # conditions, described by arguments. # @@ -336,7 +367,7 @@ rule set-target-variables-aux ( rule-or-module : property-set ) } # Strip away last dot separated part and recurse. - local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ; + local next = [ MATCH "^(.+)\\.([^\\.])*" : $(rule-or-module) ] ; if $(next) { result += [ set-target-variables-aux $(next[1]) : $(property-set) ] ; @@ -380,7 +411,7 @@ rule relevant-features ( rule-or-module ) } # Strip away last dot separated part and recurse. - local next = [ MATCH ^(.+)\\.([^\\.])* : $(rule-or-module) ] ; + local next = [ MATCH "^(.+)\\.([^\\.])*" : $(rule-or-module) ] ; if $(next) { result += [ relevant-features $(next[1]) ] ; @@ -399,6 +430,34 @@ rule relevant-features ( rule-or-module ) } } +# Returns a list of all the features which were +# passed to uses-features. +local rule used-features ( rule-or-module ) +{ + if ! $(.used-features.$(rule-or-module)) + { + local result = $(.uses-features.$(rule-or-module)) ; + + # Strip away last dot separated part and recurse. + local next = [ MATCH "^(.+)\\.([^\\.])*" : $(rule-or-module) ] ; + if $(next) + { + result += [ used-features $(next[1]) ] ; + } + result = [ sequence.unique $(result) ] ; + if $(result[1]) = "" + { + result = $(result) ; + } + .used-features.$(rule-or-module) = $(result) ; + return $(result) ; + } + else + { + return $(.used-features.$(rule-or-module)) ; + } +} + rule filter-property-set ( rule-or-module : property-set ) { local key = .filtered.property-set.$(rule-or-module).$(property-set) ; @@ -454,6 +513,23 @@ rule set-target-variables ( rule-or-module targets + : property-set ) } +# Returns a property-set indicating which features are relevant +# for the given rule. +# +rule relevant ( rule-name ) +{ + if ! $(.relevant-features-ps.$(rule-name)) + { + local features = [ sequence.transform utility.ungrist : + [ relevant-features $(rule-name) ] + [ used-features $(rule-name) ] ] ; + .relevant-features-ps.$(rule-name) = + [ property-set.create $(features) ] ; + } + return $(.relevant-features-ps.$(rule-name)) ; +} + + # Make toolset 'toolset', defined in a module of the same name, inherit from # 'base'. # 1. The 'init' rule from 'base' is imported into 'toolset' with full name. @@ -587,6 +663,30 @@ rule add-requirements ( requirements * ) } } +# Returns the global toolset defaults. +# +.defaults = [ property-set.empty ] ; + +rule defaults ( ) +{ + return $(.defaults) ; +} + +# Add elements to the list of global toolset defaults. These properties +# should be conditional and will override the default value of the feature. +# Do not use this for non-conditionals. Use feature.set-default instead. +# +rule add-defaults ( properties * ) +{ + if ! $(.ignore-requirements) + { + properties = [ property.translate-indirect $(properties) : [ CALLER_MODULE ] ] ; + properties = [ property.expand-subfeatures-in-conditions $(properties) ] ; + properties = [ property.make $(properties) ] ; + .defaults = [ $(.defaults).add-raw $(properties) ] ; + } +} + rule __test__ ( ) { diff --git a/tools/build/src/build/type.jam b/tools/build/src/build/type.jam index e8cc44ebbb..554894cfc8 100644 --- a/tools/build/src/build/type.jam +++ b/tools/build/src/build/type.jam @@ -10,6 +10,7 @@ import "class" : new ; import feature ; import generators : * ; import os ; +import param ; import project ; import property ; import scanner ; @@ -377,6 +378,8 @@ rule type ( filename ) rule main-target-rule ( name : sources * : requirements * : default-build * : usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; # First discover the required target type based on the exact alias used to # invoke this rule. local bt = [ BACKTRACE 1 ] ; diff --git a/tools/build/src/build/version.jam b/tools/build/src/build/version.jam index 8a1a957a14..a66f3f74f8 100644 --- a/tools/build/src/build/version.jam +++ b/tools/build/src/build/version.jam @@ -6,8 +6,8 @@ import numbers ; -.major = "2015" ; -.minor = "07" ; +.major = "2018" ; +.minor = "02" ; rule boost-build ( ) @@ -108,7 +108,7 @@ rule check-jam-version ( version + ) if ! $(version-tag) { import errors ; - errors.error Invalid version specifier: : $(version:E="(undefined)") ; + errors.error Invalid version "specifier:" : $(version:E="(undefined)") ; } if ! $(.jam-version-check.$(version-tag))-is-defined diff --git a/tools/build/src/build/virtual-target.jam b/tools/build/src/build/virtual-target.jam index 2d139bd7f8..78c2058be0 100644 --- a/tools/build/src/build/virtual-target.jam +++ b/tools/build/src/build/virtual-target.jam @@ -58,9 +58,12 @@ # builtin.jam modules. They are shown in the diagram to give the big picture. import "class" : new ; +import feature ; import path ; +import property-set ; import sequence ; import set ; +import toolset ; import type ; import utility ; @@ -118,6 +121,11 @@ class virtual-target .always = 1 ; } + rule fail-expected ( ) + { + .fail-expected = 1 ; + } + # Generates all the actual targets and sets up build actions for this # target. # @@ -138,6 +146,11 @@ class virtual-target ALWAYS $(actual-name) ; } + if $(.fail-expected) + { + FAIL_EXPECTED $(actual-name) ; + } + if ! $(scanner) { return $(actual-name) ; @@ -196,6 +209,14 @@ class virtual-target errors.error "method should be defined in derived classes" ; } + # Returns additional properties that are relevant for this target + # beyond those required by the action. + # + rule relevant ( ) + { + return [ property-set.empty ] ; + } + # implementation rule actualize-no-scanner ( ) { @@ -999,10 +1020,10 @@ rule register ( target ) { local ps1 = [ $(a1).properties ] ; local ps2 = [ $(a2).properties ] ; - local p1 = [ $(ps1).base ] [ $(ps1).free ] [ set.difference - [ $(ps1).dependency ] : [ $(ps1).incidental ] ] ; - local p2 = [ $(ps2).base ] [ $(ps2).free ] [ set.difference - [ $(ps2).dependency ] : [ $(ps2).incidental ] ] ; + local relevant = [ toolset.relevant [ $(a1).action-name ] ] ; + relevant = [ $(relevant).add [ $(target).relevant ] ] ; + local p1 = [ $(ps1).relevant $(relevant) ] ; + local p2 = [ $(ps2).relevant $(relevant) ] ; if $(p1) = $(p2) { result = $(t) ; @@ -1099,8 +1120,17 @@ rule register-actual-name ( actual-name : virtual-target ) if $(action1) && $(action2) { local p1 = [ $(action1).properties ] ; - p1 = [ $(p1).raw ] ; local p2 = [ $(action2).properties ] ; + # Only show features that are relevant for either target. + local relevant = [ $(p1).get ] [ $(p2).get ] ; + relevant = [ feature.expand-relevant $(relevant) ] ; + # The presence of relevant can potentially mess things up, + # so we always need to show it. + relevant += relevant ; + relevant = [ property-set.create $(relevant) ] ; + p1 = [ $(p1).relevant $(relevant) ] ; + p2 = [ $(p2).relevant $(relevant) ] ; + p1 = [ $(p1).raw ] ; p2 = [ $(p2).raw ] ; properties-removed = [ set.difference $(p1) : $(p2) ] ; properties-removed ?= "none" ; @@ -1334,11 +1364,11 @@ class subvariant rule all-target-directories ( target-type ? ) { - if ! $(self.target-directories) + if ! $(self.target-directories.$(target-type:E=)) { compute-target-directories $(target-type) ; } - return $(self.target-directories) ; + return $(self.target-directories.$(target-type:E=)) ; } rule compute-target-directories ( target-type ? ) @@ -1358,6 +1388,6 @@ class subvariant { result += [ $(d).all-target-directories $(target-type) ] ; } - self.target-directories = $(result) ; + self.target-directories.$(target-type:E=) = $(result) ; } } diff --git a/tools/build/src/contrib/boost.jam b/tools/build/src/contrib/boost.jam index c3caa3a3bf..6f75619e3e 100644 --- a/tools/build/src/contrib/boost.jam +++ b/tools/build/src/contrib/boost.jam @@ -94,9 +94,9 @@ rule init { if ! $(.boost_default) { - echo notice: configuring default boost library $(version) ; + echo notice\: configuring default boost library $(version) ; } - echo notice: configuring boost library $(version) ; + echo notice\: configuring boost library $(version) ; } .boost_default ?= $(version) ; # the first configured is default .boost.$(version) = [ property-set.create $(options) ] ; @@ -139,7 +139,7 @@ rule use-project if $(.debug-configuration) { - echo notice: using boost library $(version) [ $(opt).raw ] ; + echo notice\: using boost library $(version) [ $(opt).raw ] ; } .layout = [ $(opt).get ] ; @@ -262,7 +262,7 @@ rule tag_std ( name : type ? : property-set ) local result ; if $(.layout) = system { - local version = [ MATCH ^([0-9]+)_([0-9]+) : $(.version_tag) ] ; + local version = [ MATCH "^([0-9]+)_([0-9]+)" : $(.version_tag) ] ; if $(version[1]) = "1" && [ numbers.less $(version[2]) 39 ] { result = [ tag_tagged $(name) : $(type) : $(property-set) ] ; diff --git a/tools/build/src/engine/Jambase b/tools/build/src/engine/Jambase index a736e26769..385c6f3138 100644 --- a/tools/build/src/engine/Jambase +++ b/tools/build/src/engine/Jambase @@ -119,9 +119,6 @@ rule boost-build ( dir ? ) } -if [ MATCH .*(b2).* : $(ARGV[1]:BL) ] - || [ MATCH .*(bjam).* : $(ARGV[1]:BL) ] - || $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1. { # We attempt to load "boost-build.jam" by searching from the current # invocation directory up to the root of the file-system. @@ -190,2318 +187,3 @@ if [ MATCH .*(b2).* : $(ARGV[1]:BL) ] EXIT "Please consult the documentation at 'http://www.boost.org'." ; } } -else -{ - -# -# JAMBASE - jam 2.3 ruleset providing make(1)-like functionality -# -# Supports UNIX, NT, and VMS. -# -# 12/27/93 (seiwald) - purturb library sources with SOURCE_GRIST -# 04/18/94 (seiwald) - use '?=' when setting OS specific vars -# 04/21/94 (seiwald) - do RmTemps together -# 05/05/94 (seiwald) - all supported C compilers support -o: relegate -# RELOCATE as an option; set Ranlib to "" to disable it -# 06/01/94 (seiwald) - new 'actions existing' to do existing sources -# 08/25/94 (seiwald) - new ObjectCcFlags rule to append to per-target CCFLAGS -# 08/29/94 (seiwald) - new ObjectHdrs rule to append to per-target HDRS -# 09/19/94 (seiwald) - LinkLibraries and Undefs now append -# - Rule names downshifted. -# 10/06/94 (seiwald) - Dumb yyacc stuff moved into Jamfile. -# 10/14/94 (seiwald) - (Crude) support for .s, .C, .cc, .cpp, and .f files. -# 01/08/95 (seiwald) - Shell now handled with awk, not sed -# 01/09/95 (seiwald) - Install* now take dest directory as target -# 01/10/95 (seiwald) - All entries sorted. -# 01/10/95 (seiwald) - NT support moved in, with LauraW's help. -# 01/10/95 (seiwald) - VMS support moved in. -# 02/06/95 (seiwald) - ObjectC++Flags and SubDirC++Flags added. -# 02/07/95 (seiwald) - Iron out when HDRSEARCH uses "" or SEARCH_SOURCE. -# 02/08/95 (seiwald) - SubDir works on VMS. -# 02/14/95 (seiwald) - MkDir and entourage. -# 04/30/95 (seiwald) - Use install -c flag so that it copies, not moves. -# 07/10/95 (taylor) - Support for Microsoft C++. -# 11/21/96 (peterk) - Support for BeOS -# 07/19/99 (sickel) - Support for Mac OS X Server (and maybe client) -# 02/18/00 (belmonte)- Support for Cygwin. -# 02/19/15 (shepilko)- On VMS use POSIX path in rules, translate to VMS via $(:W). - -# Special targets defined in this file: -# -# all - parent of first, shell, files, lib, exe -# first - first dependency of 'all', for potential initialization -# shell - parent of all Shell targets -# files - parent of all File targets -# lib - parent of all Library targets -# exe - parent of all Main targets -# dirs - parent of all MkDir targets -# clean - removes all Shell, File, Library, and Main targets -# uninstall - removes all Install targets -# - -# Rules defined by this file: -# -# as obj.o : source.s ; .s -> .o -# Bulk dir : files ; populate directory with many files -# Cc obj.o : source.c ; .c -> .o -# C++ obj.o : source.cc ; .cc -> .o -# Clean clean : sources ; remove sources with 'jam clean' -# File dest : source ; copy file -# Fortran obj.o : source.f ; .f -> .o -# GenFile source.c : program args ; make custom file -# Hardlink target : source ; make link from source to target -# HdrRule source : headers ; handle #includes -# InstallInto dir : sources ; install any files -# InstallBin dir : sources ; install binaries -# InstallLib dir : sources ; install files -# InstallFile dir : sources ; install files -# InstallMan dir : sources ; install man pages -# InstallShell dir : sources ; install shell scripts -# Lex source.c : source.l ; .l -> .c -# Library lib : source ; archive library from compiled sources -# LibraryFromObjects lib : objects ; archive library from objects -# LinkLibraries images : libraries ; bag libraries onto Mains -# Main image : source ; link executable from compiled sources -# MainFromObjects image : objects ; link executable from objects -# MkDir dir ; make a directory, if not there -# Object object : source ; compile object from source -# ObjectCcFlags source : flags ; add compiler flags for object -# ObjectC++Flags source : flags ; add compiler flags for object -# ObjectHdrs source : dirs ; add include directories for object -# Objects sources ; compile sources -# RmTemps target : sources ; remove temp sources after target made -# Setuid images ; mark executables Setuid -# SubDir TOP d1 d2 ... ; start a subdirectory Jamfile -# SubDirCcFlags flags ; add compiler flags until next SubDir -# SubDirC++Flags flags ; add compiler flags until next SubDir -# SubDirHdrs dirs ; add include dirs until next SubDir -# SubInclude TOP d1 d2 ... ; include a subdirectory Jamfile -# Shell exe : source ; make a shell executable -# Undefines images : symbols ; save undef's for linking -# UserObject object : source ; handle unknown suffixes for Object -# Yacc source.c : source.y ; .y -> .c -# -# Utility rules that have no side effects (not supported): -# -# FAppendSuffix f1 f2 ... : $(SUF) ; return $(<) with suffixes -# FConcat value ... ; return contatenated values -# FDirName d1 d2 ... ; return path from root to dir -# FGrist d1 d2 ... ; return d1!d2!... -# FGristFiles value ; return $(value:G=$(SOURCE_GRIST)) -# FGristSourceFiles value ; return $(value:G=$(SOURCE_GRIST)) -# FRelPath d1 : d2 ; return rel path from d1 to d2 -# FSubDir d1 d2 ... ; return path to root -# - - -# Brief review of the jam language: -# -# Statements: -# rule RULE - statements to process a rule -# actions RULE - system commands to carry out target update -# -# Modifiers on actions: -# together - multiple instances of same rule on target get executed -# once with their sources ($(>)) concatenated -# updated - refers to updated sources ($(>)) only -# ignore - ignore return status of command -# quietly - don't trace its execution unless verbose -# piecemeal - iterate command each time with a small subset of $(>) -# existing - refers to currently existing sources ($(>)) only -# bind vars - subject to binding before expanding in actions -# -# Special rules: -# ALWAYS - always build a target -# DEPENDS - builds the dependency graph -# ECHO - blurt out targets on stdout -# EXIT - blurt out targets and exit -# INCLUDES - marks sources as headers for target (a codependency) -# NOCARE - don't panic if the target can't be built -# NOUPDATE - create the target if needed but never update it -# NOTFILE - ignore the timestamp of the target (it's not a file) -# TEMPORARY - target need not be present if sources haven't changed -# -# Special variables set by jam: -# $(<) - targets of a rule (to the left of the :) -# $(>) - sources of a rule (to the right of the :) -# $(xxx) - true on xxx (UNIX, VMS, NT, OS2, MAC) -# $(OS) - name of OS - varies wildly -# $(JAMVERSION) - version number (2.3) -# -# Special variables used by jam: -# SEARCH - where to find something (used during binding and actions) -# LOCATE - where to plop something not found with SEARCH -# HDRRULE - rule to call to handle include files -# HDRSCAN - egrep regex to extract include files -# -# Special targets: -# all - default if none given on command line -# - -# Initialize variables -# - -# -# OS specific variable settings -# -if $(NT) -{ - # the list of supported toolsets on Windows NT and Windows 95/98 - # - local SUPPORTED_TOOLSETS = "BORLANDC" "VC7" "VISUALC" "VISUALC16" "INTELC" "WATCOM" - "MINGW" "LCC" ; - - # this variable holds the current toolset - # - TOOLSET = "" ; - - # if the JAM_TOOLSET environment variable is defined, check that it is - # one of our supported values - # - if $(JAM_TOOLSET) - { - local t ; - - for t in $(SUPPORTED_TOOLSETS) - { - $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them - if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; } - } - - if ! $(TOOLSET) - { - ECHO "The JAM_TOOLSET environment variable is defined but its value" ; - ECHO "is invalid, please use one of the following:" ; - ECHO ; - - for t in $(SUPPORTED_TOOLSETS) { ECHO " " $(t) ; } - EXIT ; - } - } - - # if TOOLSET is empty, we'll try to detect the toolset from other - # environment variables to remain backwards compatible with Jam 2.3 - # - if ! $(TOOLSET) - { - if $(BCCROOT) - { - TOOLSET = BORLANDC ; - BORLANDC = $(BCCROOT:J=" ") ; - } - else if $(MSVC) - { - TOOLSET = VISUALC16 ; - VISUALC16 = $(MSVC:J=" ") ; - } - else if $(MSVCNT) - { - TOOLSET = VISUALC ; - VISUALC = $(MSVCNT:J=" ") ; - } - else if $(MSVCDir) - { - TOOLSET = VISUALC ; - VISUALC = $(MSVCDir:J=" ") ; - } - else if $(MINGW) - { - TOOLSET = MINGW ; - } - else - { - ECHO "Jam cannot be run because, either:" ; - ECHO " a. You didn't set BOOST_ROOT to indicate the root of your" ; - ECHO " Boost installation." ; - ECHO " b. You are trying to use stock Jam but didn't indicate which" ; - ECHO " compilation toolset to use. To do so, follow these simple" ; - ECHO " instructions:" ; - ECHO ; - ECHO " - define one of the following environment variable, with the" ; - ECHO " appropriate value according to this list:" ; - ECHO ; - ECHO " Variable Toolset Description" ; - ECHO ; - ECHO " BORLANDC Borland C++ BC++ install path" ; - ECHO " VISUALC Microsoft Visual C++ VC++ install path" ; - ECHO " VISUALC16 Microsoft Visual C++ 16 bit VC++ 16 bit install" ; - ECHO " INTELC Intel C/C++ IC++ install path" ; - ECHO " WATCOM Watcom C/C++ Watcom install path" ; - ECHO " MINGW MinGW (gcc) MinGW install path" ; - ECHO " LCC Win32-LCC LCC-Win32 install path" ; - ECHO ; - ECHO " - define the JAM_TOOLSET environment variable with the *name*" ; - ECHO " of the toolset variable you want to use." ; - ECHO ; - ECHO " e.g.: set VISUALC=C:\\Visual6" ; - ECHO " set JAM_TOOLSET=VISUALC" ; - EXIT ; - } - } - - CP ?= copy ; - RM ?= del /f/q ; - SLASH ?= \\ ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - SUFEXE ?= .exe ; - - if $(TOOLSET) = BORLANDC - { - ECHO "Compiler is Borland C++" ; - - AR ?= tlib /C /P64 ; - CC ?= bcc32 ; - CCFLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ; - C++ ?= bcc32 ; - C++FLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ; - LINK ?= $(CC) ; - LINKFLAGS ?= $(CCFLAGS) ; - STDLIBPATH ?= $(BORLANDC)\\lib ; - STDHDRS ?= $(BORLANDC)\\include ; - NOARSCAN ?= true ; - } - else if $(TOOLSET) = VISUALC16 - { - ECHO "Compiler is Microsoft Visual C++ 16 bit" ; - - AR ?= lib /nologo ; - CC ?= cl /nologo ; - CCFLAGS ?= /D \"WIN\" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= $(CC) ; - LINKFLAGS ?= $(CCFLAGS) ; - LINKLIBS ?= - \"$(VISUALC16)\\lib\\mlibce.lib\" - \"$(VISUALC16)\\lib\\oldnames.lib\" - ; - LINKLIBS ?= ; - NOARSCAN ?= true ; - OPTIM ?= "" ; - STDHDRS ?= $(VISUALC16)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = VISUALC - { - ECHO "Compiler is Microsoft Visual C++" ; - - AR ?= lib ; - AS ?= masm386 ; - CC ?= cl /nologo ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= link /nologo ; - LINKFLAGS ?= "" ; - LINKLIBS ?= \"$(VISUALC)\\lib\\advapi32.lib\" - # $(VISUALC)\\lib\\libc.lib - # $(VISUALC)\\lib\\oldnames.lib - \"$(VISUALC)\\lib\\gdi32.lib\" - \"$(VISUALC)\\lib\\user32.lib\" - \"$(VISUALC)\\lib\\kernel32.lib\" ; - OPTIM ?= "" ; - STDHDRS ?= $(VISUALC)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = VC7 - { - ECHO "Compiler is Microsoft Visual C++ .NET" ; - - AR ?= lib ; - AS ?= masm386 ; - CC ?= cl /nologo ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= link /nologo ; - LINKFLAGS ?= "" ; - LINKLIBS ?= \"$(VISUALC)\\PlatformSDK\\lib\\advapi32.lib\" - # $(VISUALC)\\lib\\libc.lib - # $(VISUALC)\\lib\\oldnames.lib - \"$(VISUALC)\\PlatformSDK\\lib\\gdi32.lib\" - \"$(VISUALC)\\PlatformSDK\\lib\\user32.lib\" - \"$(VISUALC)\\PlatformSDK\\lib\\kernel32.lib\" ; - OPTIM ?= "" ; - STDHDRS ?= \"$(VISUALC)\\include\" - \"$(VISUALC)\\PlatformSDK\\include\" ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = INTELC - { - ECHO "Compiler is Intel C/C++" ; - - if ! $(VISUALC) - { - ECHO "As a special exception, when using the Intel C++ compiler, you need" ; - ECHO "to define the VISUALC environment variable to indicate the location" ; - ECHO "of your Visual C++ installation. Aborting.." ; - EXIT ; - } - - AR ?= lib ; - AS ?= masm386 ; - CC ?= icl /nologo ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= link /nologo ; - LINKFLAGS ?= "" ; - LINKLIBS ?= $(VISUALC)\\lib\\advapi32.lib - # $(VISUALC)\\lib\\libc.lib - # $(VISUALC)\\lib\\oldnames.lib - $(VISUALC)\\lib\\kernel32.lib - ; - OPTIM ?= "" ; - STDHDRS ?= $(INTELC)\include $(VISUALC)\\include ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = WATCOM - { - ECHO "Compiler is Watcom C/C++" ; - - AR ?= wlib ; - CC ?= wcc386 ; - CCFLAGS ?= /zq /DWIN32 /I$(WATCOM)\\h ; # zq=quiet - C++ ?= wpp386 ; - C++FLAGS ?= $(CCFLAGS) ; - CP ?= copy ; - DOT ?= . ; - DOTDOT ?= .. ; - LINK ?= wcl386 ; - LINKFLAGS ?= /zq ; # zq=quiet - LINKLIBS ?= ; - MV ?= move ; - NOARSCAN ?= true ; - OPTIM ?= ; - RM ?= del /f ; - SLASH ?= \\ ; - STDHDRS ?= $(WATCOM)\\h $(WATCOM)\\h\\nt ; - SUFEXE ?= .exe ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = MINGW - { - ECHO "Compiler is GCC with Mingw" ; - - AR ?= ar -ru ; - CC ?= gcc ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= $(CC) ; - LINKFLAGS ?= "" ; - LINKLIBS ?= "" ; - OPTIM ?= ; - SUFOBJ = .o ; - SUFLIB = .a ; - SLASH = / ; -# NOARSCAN ?= true ; - } - else if $(TOOLSET) = LCC - { - ECHO "Compiler is Win32-LCC" ; - - AR ?= lcclib ; - CC ?= lcc ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= lcclnk ; - LINKFLAGS ?= "" ; - LINKLIBS ?= "" ; - OPTIM ?= ; - NOARSCAN = true ; - } - else - { -# -# XXX: We need better comments here !! -# - EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the - Borland or Microsoft directories. ; - } - -} -else if $(OS2) -{ - # the list of supported toolsets on Windows NT and Windows 95/98 - # - local SUPPORTED_TOOLSETS = "EMX" "WATCOM" ; - - # this variable holds the current toolset - # - TOOLSET = "" ; - - # if the JAM_TOOLSET environment variable is defined, check that it is - # one of our supported values - # - if $(JAM_TOOLSET) - { - local t ; - - for t in $(SUPPORTED_TOOLSETS) - { - $(t) = $($(t):J=" ") ; # reconstitute paths with spaces in them - if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; } - } - - if ! $(TOOLSET) - { - ECHO "The JAM_TOOLSET environment variable is defined but its value" ; - ECHO "is invalid, please use one of the following:" ; - ECHO ; - - for t in $(SUPPORTED_TOOLSETS) { ECHO " " $(t) ; } - EXIT ; - } - } - - # if TOOLSET is empty, we'll try to detect the toolset from other - # environment variables to remain backwards compatible with Jam 2.3 - # - if ! $(TOOLSET) - { - if $(watcom) - { - WATCOM = $(watcom:J=" ") ; - TOOLSET = WATCOM ; - } - else - { - ECHO "Jam cannot be run because you didn't indicate which compilation toolset" ; - ECHO "to use. To do so, follow these simple instructions:" ; - ECHO ; - ECHO " - define one of the following environment variable, with the" ; - ECHO " appropriate value according to this list:" ; - ECHO ; - ECHO " Variable Toolset Description" ; - ECHO ; - ECHO " WATCOM Watcom C/C++ Watcom install path" ; - ECHO " EMX EMX (gcc) EMX install path" ; - ECHO " VISUALAGE IBM Visual Age C/C++ VisualAge install path" ; - ECHO ; - ECHO " - define the JAM_TOOLSET environment variable with the *name*" ; - ECHO " of the toolset variable you want to use." ; - ECHO ; - ECHO " e.g.: set WATCOM=C:\WATCOM" ; - ECHO " set JAM_TOOLSET=WATCOM" ; - ECHO ; - EXIT ; - } - } - - RM = del /f ; - CP = copy ; - MV ?= move ; - DOT ?= . ; - DOTDOT ?= .. ; - SUFLIB ?= .lib ; - SUFOBJ ?= .obj ; - SUFEXE ?= .exe ; - - if $(TOOLSET) = WATCOM - { - AR ?= wlib ; - BINDIR ?= \\os2\\apps ; - CC ?= wcc386 ; - CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\h ; # zq=quiet - C++ ?= wpp386 ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= wcl386 ; - LINKFLAGS ?= /zq ; # zq=quiet - LINKLIBS ?= ; - NOARSCAN ?= true ; - OPTIM ?= ; - SLASH ?= \\ ; - STDHDRS ?= $(WATCOM)\\h ; - UNDEFFLAG ?= "/u _" ; - } - else if $(TOOLSET) = EMX - { - ECHO "Compiler is GCC-EMX" ; - AR ?= ar -ru ; - CC ?= gcc ; - CCFLAGS ?= "" ; - C++ ?= $(CC) ; - C++FLAGS ?= $(CCFLAGS) ; - LINK ?= $(CC) ; - LINKFLAGS ?= "" ; - LINKLIBS ?= "" ; - OPTIM ?= ; - SUFOBJ = .o ; - SUFLIB = .a ; - UNDEFFLAG ?= "-U" ; - SLASH = / ; -# NOARSCAN ?= true ; - } - else - { - # should never happen - EXIT "Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now" ; - } -} -else if $(VMS) -{ - ## DECC CRTL supports POSIX-style path, JAM is retrofitted to call it. - ## Use POSIX-style path for general handling in JAM rule-scope. - ## Translate the POSIX path to VMS in JAM actions-scope via $(:W) modifier. - C++ ?= cxx ; - C++FLAGS ?= ; - CC ?= cc ; - CCFLAGS ?= ; - CHMOD ?= set file/prot= ; - CP ?= copy/replace ; - CRELIB ?= true ; - DOT ?= . ; ## Use POSIX CRTL - DOTDOT ?= .. ; ## Use POSIX CRTL - EXEMODE ?= (w:e) ; - FILEMODE ?= (w:r) ; - HDRS ?= ; - LINK ?= link ; - LINKFLAGS ?= "" ; - LINKLIBS ?= ; - MKDIR ?= create/dir ; - MV ?= rename /noconf ; - OPTIM ?= "" ; - RM ?= delete /noconf ; - RUNVMS ?= mcr ; - SHELLMODE ?= (w:er) ; - SLASH ?= / ; ## Use POSIX CRTL - STDHDRS ?= decc$library_include ; - SUFEXE ?= .exe ; - SUFLIB ?= .olb ; - SUFOBJ ?= .obj ; - - switch $(OS) - { - case OPENVMS : CCFLAGS ?= /stand=vaxc ; - case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ; - } -} -else if $(MAC) -{ - local OPT ; - - CW ?= "{CW}" ; - - MACHDRS ?= - "$(UMACHDRS):Universal:Interfaces:CIncludes" - "$(CW):MSL:MSL_C:MSL_Common:Include" - "$(CW):MSL:MSL_C:MSL_MacOS:Include" ; - - MACLIBS ?= - "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib" - "$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib" ; - - MPWLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib" ; - - MPWNLLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib" ; - - SIOUXHDRS ?= ; - - SIOUXLIBS ?= - "$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib" - "$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib" ; - - C++ ?= mwcppc ; - C++FLAGS ?= -w off -nomapcr ; - CC ?= mwcppc ; - CCFLAGS ?= -w off -nomapcr ; - CP ?= duplicate -y ; - DOT ?= ":" ; - DOTDOT ?= "::" ; - HDRS ?= $(MACHDRS) $(MPWHDRS) ; - LINK ?= mwlinkppc ; - LINKFLAGS ?= -mpwtool -warn ; - LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ; - MKDIR ?= newfolder ; - MV ?= rename -y ; - NOARSCAN ?= true ; - OPTIM ?= ; - RM ?= delete -y ; - SLASH ?= ":" ; - STDHDRS ?= ; - SUFLIB ?= .lib ; - SUFOBJ ?= .o ; -} -else if $(OS) = BEOS && $(METROWERKS) -{ - AR ?= mwld -xml -o ; - BINDIR ?= /boot/apps ; - CC ?= mwcc ; - CCFLAGS ?= -nosyspath ; - C++ ?= $(CC) ; - C++FLAGS ?= -nosyspath ; - FORTRAN ?= "" ; - LIBDIR ?= /boot/develop/libraries ; - LINK ?= mwld ; - LINKFLAGS ?= "" ; - MANDIR ?= /boot/documentation/"Shell Tools"/HTML ; - NOARSCAN ?= true ; - STDHDRS ?= /boot/develop/headers/posix ; -} -else if $(OS) = BEOS -{ - BINDIR ?= /boot/apps ; - CC ?= gcc ; - C++ ?= $(CC) ; - FORTRAN ?= "" ; - LIBDIR ?= /boot/develop/libraries ; - LINK ?= gcc ; - LINKLIBS ?= -lnet ; - NOARSCAN ?= true ; - STDHDRS ?= /boot/develop/headers/posix ; -} -else if $(OS) = HAIKU -{ - BINDIR ?= /boot/system/non-packaged/bin ; - CC ?= gcc ; - C++ ?= $(CC) ; - FORTRAN ?= "" ; - LIBDIR ?= /boot/system/non-packaged/lib ; - LINK ?= gcc ; - LINKLIBS ?= -lnetwork ; - NOARSCAN ?= true ; - STDHDRS ?= /boot/system/develop/headers/posix ; -} -else if $(UNIX) -{ - switch $(OS) - { - case AIX : - LINKLIBS ?= -lbsd ; - - case AMIGA : - CC ?= gcc ; - YACC ?= "bison -y" ; - - case CYGWIN : - CC ?= gcc ; - CCFLAGS += -D__cygwin__ ; - LEX ?= flex ; - RANLIB ?= "" ; - SUFEXE ?= .exe ; - YACC ?= "bison -y" ; - - case DGUX : - RANLIB ?= "" ; - RELOCATE ?= true ; - - case HPUX : - YACC = ; - CFLAGS += -Ae ; - CCFLAGS += -Ae ; - RANLIB ?= "" ; - - case INTERIX : - CC ?= gcc ; - RANLIB ?= "" ; - - case IRIX : - RANLIB ?= "" ; - - case MPEIX : - CC ?= gcc ; - C++ ?= gcc ; - CCFLAGS += -D_POSIX_SOURCE ; - HDRS += /usr/include ; - RANLIB ?= "" ; - NOARSCAN ?= true ; - NOARUPDATE ?= true ; - - case MVS : - RANLIB ?= "" ; - - case NEXT : - AR ?= libtool -o ; - RANLIB ?= "" ; - - case MACOSX : - AR ?= libtool -o ; - C++ ?= c++ ; - MANDIR ?= /usr/local/share/man ; - RANLIB ?= "" ; - - case NCR : - RANLIB ?= "" ; - - case PTX : - RANLIB ?= "" ; - - case QNX : - AR ?= wlib ; - CC ?= cc ; - CCFLAGS ?= -Q ; # quiet - C++ ?= $(CC) ; - C++FLAGS ?= -Q ; # quiet - LINK ?= $(CC) ; - LINKFLAGS ?= -Q ; # quiet - NOARSCAN ?= true ; - RANLIB ?= "" ; - - case SCO : - RANLIB ?= "" ; - RELOCATE ?= true ; - - case SINIX : - RANLIB ?= "" ; - - case SOLARIS : - RANLIB ?= "" ; - AR ?= "/usr/ccs/bin/ar ru" ; - - case UNICOS : - NOARSCAN ?= true ; - OPTIM ?= -O0 ; - - case UNIXWARE : - RANLIB ?= "" ; - RELOCATE ?= true ; - } - - # UNIX defaults - - CCFLAGS ?= ; - C++FLAGS ?= $(CCFLAGS) ; - CHMOD ?= chmod ; - CHGRP ?= chgrp ; - CHOWN ?= chown ; - LEX ?= lex ; - LINKFLAGS ?= $(CCFLAGS) ; - LINKLIBS ?= ; - OPTIM ?= -O ; - RANLIB ?= ranlib ; - YACC ?= yacc ; - YACCFILES ?= y.tab ; - YACCFLAGS ?= -d ; -} - -# -# General defaults; a lot like UNIX -# - - AR ?= ar ru ; - AS ?= as ; - ASFLAGS ?= ; - AWK ?= awk ; - BINDIR ?= /usr/local/bin ; - C++ ?= cc ; - C++FLAGS ?= ; - CC ?= cc ; - CCFLAGS ?= ; - CP ?= cp -f ; - CRELIB ?= ; - DOT ?= . ; - DOTDOT ?= .. ; - EXEMODE ?= 711 ; - FILEMODE ?= 644 ; - FORTRAN ?= f77 ; - FORTRANFLAGS ?= ; - HDRS ?= ; - INSTALLGRIST ?= installed ; - JAMFILE ?= Jamfile ; - JAMRULES ?= Jamrules ; - LEX ?= ; - LIBDIR ?= /usr/local/lib ; - LINK ?= $(CC) ; - LINKFLAGS ?= ; - LINKLIBS ?= ; - LN ?= ln ; - MANDIR ?= /usr/local/man ; - MKDIR ?= mkdir ; - MV ?= mv -f ; - OPTIM ?= ; - RCP ?= rcp ; - RM ?= rm -f ; - RSH ?= rsh ; - SED ?= sed ; - SHELLHEADER ?= "#!/bin/sh" ; - SHELLMODE ?= 755 ; - SLASH ?= / ; - STDHDRS ?= /usr/include ; - SUFEXE ?= "" ; - SUFLIB ?= .a ; - SUFOBJ ?= .o ; - UNDEFFLAG ?= "-u _" ; - YACC ?= ; - YACCFILES ?= ; - YACCFLAGS ?= ; - - HDRPATTERN = - "^[ ]*#[ ]*include[ ]*[<\"]([^\">]*)[\">].*$" ; - - OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ; - - -# -# Base dependencies - first for "bootstrap" kinds of rules -# - -DEPENDS all : shell files lib exe obj ; -DEPENDS all shell files lib exe obj : first ; -NOTFILE all first shell files lib exe obj dirs clean uninstall ; -ALWAYS clean uninstall ; - -# -# Rules -# - -rule As -{ - DEPENDS $(<) : $(>) ; - ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ; -} - -rule Bulk -{ - local i ; - - for i in $(>) - { - File $(i:D=$(<)) : $(i) ; - } -} - -rule Cc -{ - local _h ; - - DEPENDS $(<) : $(>) ; - - # Just to clarify here: this sets the per-target CCFLAGS to - # be the current value of (global) CCFLAGS and SUBDIRCCFLAGS. - - CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ; - - # If the compiler's -o flag doesn't work, relocate the .o - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; - - if $(VMS) && $(_h) - { - SLASHINC on $(<) = "/inc=(" \"$(_h[1])\" ,\"$(_h[2-])\" ")" ; - } - else if $(MAC) && $(_h) - { - local _i _j ; - _j = $(_h[1]) ; - for _i in $(_h[2-]) - { - _j = $(_j),$(_i) ; - } - MACINC on $(<) = \"$(_j)\" ; - } -} - -rule C++ -{ - local _h ; - - DEPENDS $(<) : $(>) ; - C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ; - - if $(RELOCATE) - { - CcMv $(<) : $(>) ; - } - - _h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; - - if $(VMS) && $(_h) - { - SLASHINC on $(<) = "/inc=(" \"$(_h[1])\" ,\"$(_h[2-])\" ")" ; - } - else if $(MAC) && $(_h) - { - local _i _j ; - _j = $(_h[1]) ; - for _i in $(_h[2-]) - { - _j = $(_j),$(_i) ; - } - MACINC on $(<) = \"$(_j)\" ; - } -} - -rule Chmod -{ - if $(CHMOD) { Chmod1 $(<) ; } -} - -rule File -{ - DEPENDS files : $(<) ; - DEPENDS $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MODE on $(<) = $(FILEMODE) ; - Chmod $(<) ; -} - -rule Fortran -{ - DEPENDS $(<) : $(>) ; -} - -rule GenFile -{ - local _t = [ FGristSourceFiles $(<) ] ; - local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ; - Depends $(_t) : $(_s) $(>[2-]) ; - GenFile1 $(_t) : $(_s) $(>[2-]) ; - Clean clean : $(_t) ; -} - -rule GenFile1 -{ - MakeLocate $(<) : $(LOCATE_SOURCE) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; -} - -rule HardLink -{ - DEPENDS files : $(<) ; - DEPENDS $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; -} - -rule HdrMacroFile -{ - # HdrMacroFile file ; - # - # this rule is used to indicate that a given file contains definitions - # for filename macros (e.g. "#define MYFILE_H ") that can - # later be used in #include statements in the rest of the source - # - # theses files must be parsed before any make is tried.. - # - HDRMACRO $(<) ; -} - -rule HdrRule -{ - # HdrRule source : headers ; - - # N.B. This rule is called during binding, potentially after - # the fate of many targets has been determined, and must be - # used with caution: don't add dependencies to unrelated - # targets, and don't set variables on $(<). - - # Tell Jam that anything depending on $(<) also depends on $(>), - # set SEARCH so Jam can find the headers, but then say we don't - # care if we can't actually find the headers (they may have been - # within ifdefs), - - local s ; - - if $(HDRGRIST) - { - s = $(>:G=$(HDRGRIST)) ; - } else { - s = $(>) ; - } - - INCLUDES $(<) : $(s) ; - SEARCH on $(s) = $(HDRSEARCH) ; - NOCARE $(s) ; - - # Propagate on $(<) to $(>) - - HDRSEARCH on $(s) = $(HDRSEARCH) ; - HDRSCAN on $(s) = $(HDRSCAN) ; - HDRRULE on $(s) = $(HDRRULE) ; - HDRGRIST on $(s) = $(HDRGRIST) ; -} - -rule InstallInto -{ - # InstallInto dir : sources ; - - local i t ; - - t = $(>:G=$(INSTALLGRIST)) ; - - # Arrange for jam install - # Arrange for jam uninstall - # sources are in SEARCH_SOURCE - # targets are in dir - - Depends install : $(t) ; - Clean uninstall : $(t) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MakeLocate $(t) : $(<) ; - - # For each source, make gristed target name - # and Install, Chmod, Chown, and Chgrp - - for i in $(>) - { - local tt = $(i:G=$(INSTALLGRIST)) ; - - Depends $(tt) : $(i) ; - Install $(tt) : $(i) ; - Chmod $(tt) ; - - if $(OWNER) && $(CHOWN) - { - Chown $(tt) ; - OWNER on $(tt) = $(OWNER) ; - } - - if $(GROUP) && $(CHGRP) - { - Chgrp $(tt) ; - GROUP on $(tt) = $(GROUP) ; - } - } -} - -rule InstallBin -{ - local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ; - - InstallInto $(<) : $(_t) ; - MODE on $(_t:G=installed) = $(EXEMODE) ; -} - -rule InstallFile -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(FILEMODE) ; -} - -rule InstallLib -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(FILEMODE) ; -} - -rule InstallMan -{ - # Really this just strips the . from the suffix - - local i s d ; - - for i in $(>) - { - switch $(i:S) - { - case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ; - case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ; - case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ; - case .n : s = n ; case .man : s = 1 ; - } - - d = man$(s) ; - - InstallInto $(d:R=$(<)) : $(i) ; - } - - MODE on $(>:G=installed) = $(FILEMODE) ; -} - -rule InstallShell -{ - InstallInto $(<) : $(>) ; - MODE on $(>:G=installed) = $(SHELLMODE) ; -} - -rule Lex -{ - LexMv $(<) : $(>) ; - DEPENDS $(<) : $(>) ; - MakeLocate $(<) : $(LOCATE_SOURCE) ; - Clean clean : $(<) ; -} - -rule Library -{ - LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -rule LibraryFromObjects -{ - local _i _l _s ; - - # Add grist to file names - - _s = [ FGristFiles $(>) ] ; - _l = $(<:S=$(SUFLIB)) ; - - # library depends on its member objects - - if $(KEEPOBJS) - { - DEPENDS obj : $(_s) ; - } - else - { - DEPENDS lib : $(_l) ; - } - - # Set LOCATE for the library and its contents. The bound - # value shows up as $(NEEDLIBS) on the Link actions. - # For compatibility, we only do this if the library doesn't - # already have a path. - - if ! $(_l:D) - { - MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ; - } - - if $(NOARSCAN) - { - # If we can't scan the library to timestamp its contents, - # we have to just make the library depend directly on the - # on-disk object files. - - DEPENDS $(_l) : $(_s) ; - } - else - { - # If we can scan the library, we make the library depend - # on its members and each member depend on the on-disk - # object file. - - DEPENDS $(_l) : $(_l)($(_s:BS)) ; - - for _i in $(_s) - { - DEPENDS $(_l)($(_i:BS)) : $(_i) ; - } - } - - Clean clean : $(_l) ; - - if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; } - - Archive $(_l) : $(_s) ; - - if $(RANLIB) { Ranlib $(_l) ; } - - # If we can't scan the library, we have to leave the .o's around. - - if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; } -} - -rule Link -{ - MODE on $(<) = $(EXEMODE) ; - Chmod $(<) ; -} - -rule LinkLibraries -{ - # make library dependencies of target - # set NEEDLIBS variable used by 'actions Main' - - local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; - - DEPENDS $(_t) : $(>:S=$(SUFLIB)) ; - NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ; -} - -rule Main -{ - MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ; - Objects $(>) ; -} - -rule MainFromObjects -{ - local _s _t ; - - # Add grist to file names - # Add suffix to exe - - _s = [ FGristFiles $(>) ] ; - _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ; - - if $(_t) != $(<) - { - DEPENDS $(<) : $(_t) ; - NOTFILE $(<) ; - } - - # make compiled sources a dependency of target - - DEPENDS exe : $(_t) ; - DEPENDS $(_t) : $(_s) ; - MakeLocate $(_t) : $(LOCATE_TARGET) ; - - Clean clean : $(_t) ; - - Link $(_t) : $(_s) ; -} - -rule MakeLocate -{ - if $(>) - { - LOCATE on $(<) = $(>) ; - Depends $(<) : $(>[1]) ; - MkDir $(>[1]) ; - } -} - -rule MkDir -{ - # If dir exists, don't update it - # Do this even for $(DOT). - - NOUPDATE $(<) ; - - if $(<) != $(DOT) && ! $($(<)-mkdir) - { - local s ; - - # Cheesy gate to prevent multiple invocations on same dir - # MkDir1 has the actions - # Arrange for jam dirs - - $(<)-mkdir = true ; - MkDir1 $(<) ; - Depends dirs : $(<) ; - - # Recursively make parent directories. - # $(<:P) = $(<)'s parent, & we recurse until root - - s = $(<:P) ; - - if $(NT) - { - switch $(s) - { - case *: : s = ; - case *:\\ : s = ; - } - } - - if $(s) && $(s) != $(<) - { - Depends $(<) : $(s) ; - MkDir $(s) ; - } - else if $(s) - { - NOTFILE $(s) ; - } - - } -} - -rule Object -{ - local h ; - - # locate object and search for source, if wanted - - Clean clean : $(<) ; - - MakeLocate $(<) : $(LOCATE_TARGET) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - - # Save HDRS for -I$(HDRS) on compile. - # We shouldn't need -I$(SEARCH_SOURCE) as cc can find headers - # in the .c file's directory, but generated .c files (from - # yacc, lex, etc) are located in $(LOCATE_TARGET), possibly - # different from $(SEARCH_SOURCE). - - HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ; - - # handle #includes for source: Jam scans for headers with - # the regexp pattern $(HDRSCAN) and then invokes $(HDRRULE) - # with the scanned file as the target and the found headers - # as the sources. HDRSEARCH is the value of SEARCH used for - # the found header files. Finally, if jam must deal with - # header files of the same name in different directories, - # they can be distinguished with HDRGRIST. - - # $(h) is where cc first looks for #include "foo.h" files. - # If the source file is in a distant directory, look there. - # Else, look in "" (the current directory). - - if $(SEARCH_SOURCE) - { - h = $(SEARCH_SOURCE) ; - } - else - { - h = "" ; - } - - HDRRULE on $(>) = HdrRule ; - HDRSCAN on $(>) = $(HDRPATTERN) ; - HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ; - HDRGRIST on $(>) = $(HDRGRIST) ; - - # if source is not .c, generate .c with specific rule - - switch $(>:S) - { - case .asm : As $(<) : $(>) ; - case .c : Cc $(<) : $(>) ; - case .C : C++ $(<) : $(>) ; - case .cc : C++ $(<) : $(>) ; - case .cpp : C++ $(<) : $(>) ; - case .f : Fortran $(<) : $(>) ; - case .l : Cc $(<) : $(<:S=.c) ; - Lex $(<:S=.c) : $(>) ; - case .s : As $(<) : $(>) ; - case .y : Cc $(<) : $(<:S=.c) ; - Yacc $(<:S=.c) : $(>) ; - case * : UserObject $(<) : $(>) ; - } -} - - -rule ObjectCcFlags -{ - CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectC++Flags -{ - C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule ObjectHdrs -{ - HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ; -} - -rule Objects -{ - local _i ; - - for _i in [ FGristFiles $(<) ] - { - Object $(_i:S=$(SUFOBJ)) : $(_i) ; - DEPENDS obj : $(_i:S=$(SUFOBJ)) ; - } -} - -rule RmTemps -{ - TEMPORARY $(>) ; -} - -rule Setuid -{ - MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ; -} - -rule Shell -{ - DEPENDS shell : $(<) ; - DEPENDS $(<) : $(>) ; - SEARCH on $(>) = $(SEARCH_SOURCE) ; - MODE on $(<) = $(SHELLMODE) ; - Clean clean : $(<) ; - Chmod $(<) ; -} - -rule SubDir -{ - local _r _s ; - - # - # SubDir TOP d1 [ ... ] - # - # This introduces a Jamfile that is part of a project tree - # rooted at $(TOP). It (only once) includes the project-specific - # rules file $(TOP)/Jamrules and then sets search & locate stuff. - # - # If the variable $(TOPRULES) is set (where TOP is the first arg - # to SubDir), that file is included instead of $(TOP)/Jamrules. - # - # d1 ... are the directory elements that lead to this directory - # from $(TOP). We construct the system dependent path from these - # directory elements in order to set search & locate stuff. - # - - if ! $($(<[1])) - { - if ! $(<[1]) - { - EXIT SubDir syntax error ; - } - - $(<[1]) = [ FSubDir $(<[2-]) ] ; - } - - # - # If $(TOP)/Jamrules hasn't been included, do so. - # - - if ! $($(<[1])-included) - { - # Gated entry. - - $(<[1])-included = TRUE ; - - # File is $(TOPRULES) or $(TOP)/Jamrules. - - _r = $($(<[1])RULES) ; - - if ! $(_r) - { - _r = $(JAMRULES:R=$($(<[1]))) ; - } - - # Include it. - - include $(_r) ; - } - - # Get path to current directory from root using SubDir. - # Save dir tokens for other potential uses. - - _s = [ FDirName $(<[2-]) ] ; - SUBDIR = $(_s:R=$($(<[1]))) ; - SUBDIR_TOKENS = $(<[2-]) ; - - # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST - # These can be reset if needed. For example, if the source - # directory should not hold object files, LOCATE_TARGET can - # subsequently be redefined. - - SEARCH_SOURCE = $(SUBDIR) ; - LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ; - LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ; - SOURCE_GRIST = [ FGrist $(<[2-]) ] ; - - # Reset per-directory ccflags, hdrs - - SUBDIRCCFLAGS = ; - SUBDIRC++FLAGS = ; - SUBDIRHDRS = ; -} - -rule SubDirCcFlags -{ - SUBDIRCCFLAGS += $(<) ; -} - -rule SubDirC++Flags -{ - SUBDIRC++FLAGS += $(<) ; -} - -rule SubDirHdrs -{ - SUBDIRHDRS += $(<) ; -} - -rule SubInclude -{ - local _s ; - - # That's - # SubInclude TOP d1 [ d2 [ d3 [ d4 ] ] ] - # - # to include a subdirectory's Jamfile. - - if ! $($(<[1])) - { - EXIT Top level of source tree has not been set with $(<[1]) ; - } - - _s = [ FDirName $(<[2-]) ] ; - - include $(JAMFILE:D=$(_s):R=$($(<[1]))) ; -} - -rule Undefines -{ - UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ; -} - -rule UserObject -{ - EXIT "Unknown suffix on" $(>) "- see UserObject rule in Jamfile(5)." ; -} - -rule Yacc -{ - local _h ; - - _h = $(<:BS=.h) ; - - # Some places don't have a yacc. - - MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ; - - if $(YACC) - { - DEPENDS $(<) $(_h) : $(>) ; - Yacc1 $(<) $(_h) : $(>) ; - YaccMv $(<) $(_h) : $(>) ; - Clean clean : $(<) $(_h) ; - } - - # Make sure someone includes $(_h) else it will be a deadly independent - # target. - INCLUDES $(<) : $(_h) ; -} - -# -# Utility rules; no side effects on these. -# - -rule FGrist -{ - # Turn individual elements in $(<) into grist. - - local _g _i ; - - _g = $(<[1]) ; - - for _i in $(<[2-]) - { - _g = $(_g)!$(_i) ; - } - - return $(_g) ; -} - -rule FGristFiles -{ - if ! $(SOURCE_GRIST) - { - return $(<) ; - } - else - { - return $(<:G=$(SOURCE_GRIST)) ; - } -} - -rule FGristSourceFiles -{ - # Produce source file name name with grist in it, - # if SOURCE_GRIST is set. - - # Leave header files alone, because they have a global - # visibility. - - if ! $(SOURCE_GRIST) - { - return $(<) ; - } - else - { - local _i _o ; - - for _i in $(<) - { - switch $(_i) - { - case *.h : _o += $(_i) ; - case * : _o += $(_i:G=$(SOURCE_GRIST)) ; - } - } - - return $(_o) ; - } -} - -rule FConcat -{ - # Puts the variables together, removing spaces. - - local _t _r ; - - $(_r) = $(<[1]) ; - - for _t in $(<[2-]) - { - $(_r) = $(_r)$(_t) ; - } - - return $(_r) ; -} - -rule FSubDir -{ - local _i _d ; - - # If $(>) is the path to the current directory, compute the - # path (using ../../ etc) back to that root directory. - # Sets result in $(<) - - if ! $(<[1]) - { - _d = $(DOT) ; - } - else - { - _d = $(DOTDOT) ; - - for _i in $(<[2-]) - { - _d = $(_d:R=$(DOTDOT)) ; - } - } - - return $(_d) ; -} - -rule FDirName -{ - local _s _i ; - - # Turn individual elements in $(<) into a usable path. - - if ! $(<) - { - _s = $(DOT) ; - } - ## On VMS use general POSIX path handling, JAM resolves it through VMS CRTL. - #else if $(VMS) - #{ - # # This handles the following cases: - # # a -> [.a] - # # a b c -> [.a.b.c] - # # x: -> x: - # # x: a -> x:[a] - # # x:[a] b -> x:[a.b] - # - # switch $(<[1]) - # { - # case *:* : _s = $(<[1]) ; - # case \\[*\\] : _s = $(<[1]) ; - # case * : _s = [.$(<[1])] ; - # } - # - # for _i in [.$(<[2-])] - # { - # _s = $(_i:R=$(_s)) ; - # } - #} - else if $(MAC) - { - _s = $(DOT) ; - - for _i in $(<) - { - _s = $(_i:R=$(_s)) ; - } - } - else - { - _s = $(<[1]) ; - - for _i in $(<[2-]) - { - _s = $(_i:R=$(_s)) ; - } - } - - return $(_s) ; -} - - -rule _makeCommon -{ - # strip common initial elements - - if $($(<)[1]) && $($(<)[1]) = $($(>)[1]) - { - $(<) = $($(<)[2-]) ; - $(>) = $($(>)[2-]) ; - _makeCommon $(<) : $(>) ; - } -} - - -rule FRelPath -{ - local _l _r ; - - # first strip off common parts - - _l = $(<) ; - _r = $(>) ; - - _makeCommon _l : _r ; - - # now make path to root and path down - - _l = [ FSubDir $(_l) ] ; - _r = [ FDirName $(_r) ] ; - - # Concatenate and save - - # XXX This should be better - - if $(_r) = $(DOT) { - return $(_l) ; - } else { - return $(_r:R=$(_l)) ; - } -} - -rule FAppendSuffix -{ - # E.g., "FAppendSuffix yacc lex foo.bat : $(SUFEXE) ;" - # returns (yacc,lex,foo.bat) on Unix and - # (yacc.exe,lex.exe,foo.bat) on NT. - - if $(>) - { - local _i _o ; - - for _i in $(<) - { - if $(_i:S) - { - _o += $(_i) ; - } - else - { - _o += $(_i:S=$(>)) ; - } - } - return $(_o) ; - } - else - { - return $(<) ; - } -} - -rule unmakeDir -{ - if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\ - { - unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ; - } - else - { - $(<) = $(>) ; - } -} - - -rule FConvertToSlashes -{ - local _d, _s, _i ; - - unmakeDir _d : $(<) ; - - _s = $(_d[1]) ; - for _i in $(_d[2-]) - { - _s = $(_s)/$(_i) ; - } - return $(_s) ; -} - - -# -# Actions -# - -# -# First the defaults -# - -actions updated together piecemeal Archive -{ - $(AR) $(<) $(>) -} - -actions As -{ - $(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>) -} - -actions C++ -{ - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) -} - -actions Cc -{ - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>) -} - -actions Chgrp -{ - $(CHGRP) $(GROUP) $(<) -} - -actions Chmod1 -{ - $(CHMOD) $(MODE) $(<) -} - -actions Chown -{ - $(CHOWN) $(OWNER) $(<) -} - -actions piecemeal together existing Clean -{ - $(RM) $(>) -} - -actions File -{ - $(CP) $(>) $(<) -} - -actions GenFile1 -{ - $(>[1]) $(<) $(>[2-]) -} - -actions Fortran -{ - $(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>) -} - -actions HardLink -{ - $(RM) $(<) && $(LN) $(>) $(<) -} - -actions Install -{ - $(CP) $(>) $(<) -} - -actions Lex -{ - $(LEX) $(>) -} - -actions LexMv -{ - $(MV) lex.yy.c $(<) -} - -actions Link bind NEEDLIBS -{ - $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) -} - -actions MkDir1 -{ - $(MKDIR) $(<) -} - -actions together Ranlib -{ - $(RANLIB) $(<) -} - -actions quietly updated piecemeal together RmTemps -{ - $(RM) $(>) -} - -actions Shell -{ - $(AWK) ' - NR == 1 { print "$(SHELLHEADER)" } - NR == 1 && /^[#:]/ { next } - /^##/ { next } - { print } - ' < $(>) > $(<) -} - -actions Yacc1 -{ - $(YACC) $(YACCFLAGS) $(>) -} - -actions YaccMv -{ - $(MV) $(YACCFILES).c $(<[1]) - $(MV) $(YACCFILES).h $(<[2]) -} - -# -# RELOCATE - for compilers with broken -o flags -# - -if $(RELOCATE) -{ - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>) - } - - actions ignore CcMv - { - [ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<) - } -} - -# -# NOARUPDATE - can't update an archive -# - -if $(NOARUPDATE) -{ - actions Archive - { - $(AR) $(<) $(>) - } -} - -# -# NT specific actions -# - -if $(NT) -{ - if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(TOOLSET) = INTELC - { - actions updated together piecemeal Archive - { - if exist $(<) set _$(<:B)_=$(<) - $(AR) /out:$(<) %_$(<:B)_% $(>) - } - - actions As - { - $(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul; - } - - actions Cc - { - $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>) - } - - actions C++ - { - $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - } - else if $(TOOLSET) = VISUALC16 - { - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Cc - { - $(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - } - else if $(TOOLSET) = BORLANDC - { - actions updated together piecemeal Archive - { - $(AR) $(<) -+$(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - } - else if $(TOOLSET) = MINGW - { - actions together piecemeal Archive - { - $(AR) $(<) $(>:T) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - } - else if $(TOOLSET) = WATCOM - { - actions together piecemeal Archive - { - $(AR) $(<) +-$(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } - else if $(TOOLSET) = LCC - { - actions together piecemeal Archive - { - $(AR) /out:$(<) $(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } -} - -# -# OS2 specific actions -# - -else if $(OS2) -{ - if $(TOOLSET) = WATCOM - { - actions together piecemeal Archive - { - $(AR) $(<) +-$(>) - } - - actions Cc - { - $(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions C++ - { - $(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS) - } - - actions Shell - { - $(CP) $(>) $(<) - } - } - else if $(TOOLSET) = EMX - { - actions together piecemeal Archive - { - $(AR) $(<) $(>:T) - } - - actions Cc - { - $(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - - actions C++ - { - $(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>) - } - } -} - -# -# VMS specific actions -# - -else if $(VMS) -{ - actions updated together piecemeal Archive - { - lib/replace $(<:W) $(>[1]:W) ,$(>[2-]:W) - } - - actions Cc - { - $(CC)/obj=$(<:W) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>:W) - } - - actions C++ - { - $(C++)/obj=$(<:W) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>:W) - } - - actions piecemeal together existing Clean - { - $(RM) $(>[1]:W);* ,$(>[2-]:W);* - } - - actions together quietly CreLib - { - if f$search("$(<:W)") .eqs. "" then lib/create $(<:W) - } - - actions GenFile1 - { - mcr $(>[1]:W) $(<:W) $(>[2-]:W) - } - - actions MkDir1 - { - $(MKDIR) $(<:W) - } - - actions Yacc1 - { - $(YACC) $(YACCFLAGS) $(>:W) - } - - actions YaccMv - { - $(MV) $(YACCFILES).c $(<[1]:W) - $(MV) $(YACCFILES).h $(<[2]:W) - } - - actions Link bind NEEDLIBS - { - $(LINK)/exe=$(<:W) $(LINKFLAGS) $(>[1]:W) ,$(>[2-]:W) ,$(NEEDLIBS:W)/lib ,$(LINKLIBS:W) - } - - actions quietly updated piecemeal together RmTemps - { - $(RM) $(>[1]:W);* ,$(>[2-]:W);* - } - - actions Shell - { - $(CP) $(>:W) $(<:W) - } -} - -# -# Mac specifc actions -# - -else if $(MAC) -{ - actions together Archive - { - $(LINK) -library -o $(<) $(>) - } - - actions Cc - { - set -e MWCincludes $(MACINC) - $(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>) - } - - actions C++ - { - set -e MWCincludes $(MACINC) - $(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>) - } - - actions Link bind NEEDLIBS - { - $(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) "$(LINKLIBS)" - } -} - -# -# Backwards compatibility with jam 1, where rules were uppercased. -# - -rule BULK { Bulk $(<) : $(>) ; } -rule FILE { File $(<) : $(>) ; } -rule HDRRULE { HdrRule $(<) : $(>) ; } -rule INSTALL { Install $(<) : $(>) ; } -rule LIBRARY { Library $(<) : $(>) ; } -rule LIBS { LinkLibraries $(<) : $(>) ; } -rule LINK { Link $(<) : $(>) ; } -rule MAIN { Main $(<) : $(>) ; } -rule SETUID { Setuid $(<) ; } -rule SHELL { Shell $(<) : $(>) ; } -rule UNDEFINES { Undefines $(<) : $(>) ; } - -# Old INSTALL* didn't take dest directory. - -rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; } -rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; } -rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; } - -# Compatibility with jam 2.2. - -rule addDirName { $(<) += [ FDirName $(>) ] ; } -rule makeDirName { $(<) = [ FDirName $(>) ] ; } -rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; } -rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; } -rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; } - -# -# Now include the user's Jamfile. -# - -{ - if $(JAMFILE) { include $(JAMFILE) ; } -} - -} diff --git a/tools/build/src/engine/build.jam b/tools/build/src/engine/build.jam index 249eec871e..a92b70f78d 100644 --- a/tools/build/src/engine/build.jam +++ b/tools/build/src/engine/build.jam @@ -184,7 +184,7 @@ toolset borland bcc32 : -e -n : /D : $(--python-lib[1]) ; ## Generic Unix cc if ! $(CC) { CC = cc ; } -toolset cc "$(CC)" : "-o " : -D +toolset cc $(CC) : "-o " : -D : $(CFLAGS) [ opt --release : -s -O ] [ opt --debug : -g ] @@ -283,7 +283,7 @@ toolset kylix bc++ : -o : -D ## MIPS Pro toolset mipspro cc : "-o " : -D : - [ opt --release : -s -O3 -g0 -INLINE:none ] + [ opt --release : -s -O3 -g0 "-INLINE:none" ] [ opt --debug : -g -O0 -INLINE ] -I$(--python-include) -I$(--extra-include) : -L$(--python-lib[1]) -l$(--python-lib[2]) ; @@ -342,16 +342,16 @@ toolset vacpp xlc : "-o " : -D [ opt --release : -s -O3 -qstrict -qinline ] [ opt --debug : -g -qNOOPTimize -qnoinline -pg ] -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) [ if-os AIX : -bmaxdata:0x40000000 ] ; - + : -L$(--python-lib[1]) -l$(--python-lib[2]) [ if-os AIX : "-bmaxdata:0x40000000" ] ; + ## IBM XL C/C++ for Linux (little endian) toolset xlcpp xlC : "-o " : -D : -Wno-unused -Wno-format [ opt --release : -s ] [ opt --debug : -g -qNOOPTimize -qnoinline -pg ] -I$(--python-include) -I$(--extra-include) - : -L$(--python-lib[1]) -l$(--python-lib[2]) ; - + : -L$(--python-lib[1]) -l$(--python-lib[2]) ; + ## Microsoft Visual C++ .NET 7.x toolset vc7 cl : /Fe /Fe /Fd /Fo : -D : /nologo @@ -427,15 +427,15 @@ if ! $(toolset) ECHO "###" ; ECHO "###" No toolset specified. Please use --toolset option. ; ECHO "###" ; - ECHO "###" Known toolsets are: $(toolsets:J=", ") ; + ECHO "###" Known toolsets "are:" $(toolsets:J=", ") ; EXIT "###" ; } if ! $(toolset) in $(toolsets) { ECHO "###" ; - ECHO "###" Unknown toolset: $(toolset) ; + ECHO "###" Unknown "toolset:" $(toolset) ; ECHO "###" ; - ECHO "###" Known toolsets are: $(toolsets:J=", ") ; + ECHO "###" Known toolsets "are:" $(toolsets:J=", ") ; EXIT "###" ; } --cc = $(tool.$(toolset).cc) ; @@ -603,15 +603,15 @@ ALWAYS clean ; # Utility rules and actions... rule .clean { - [DELETE] clean : $(<) ; + "[DELETE]" clean : $(<) ; } -if $(OS) = NT { actions piecemeal together existing [DELETE] { +if $(OS) = NT { actions piecemeal together existing "[DELETE]" { del /F /Q "$(>)" } } -if $(UNIX) = true { actions piecemeal together existing [DELETE] { +if $(UNIX) = true { actions piecemeal together existing "[DELETE]" { rm -f "$(>)" } } -if $(OS) = VMS { actions piecemeal together existing [DELETE] { +if $(OS) = VMS { actions piecemeal together existing "[DELETE]" { DELETE /NOCONF $(>:WJ=;*, );* } } if $(OS) = NT { @@ -628,15 +628,15 @@ rule .mkdir { NOUPDATE $(<) ; if $(<:P) { DEPENDS $(<) : $(<:P) ; .mkdir $(<:P) ; } - if ! $(md<$(<)>) { [MKDIR] $(<) ; md<$(<)> = - ; } + if ! $(md<$(<)>) { "[MKDIR]" $(<) ; md<$(<)> = - ; } } -if $(OS) = NT { actions [MKDIR] { +if $(OS) = NT { actions "[MKDIR]" { md "$(<)" } } -if $(UNIX) = true { actions [MKDIR] { +if $(UNIX) = true { actions "[MKDIR]" { mkdir "$(<)" } } -if $(OS) = VMS { actions [MKDIR] { +if $(OS) = VMS { actions "[MKDIR]" { CREATE/DIR $(<:WJ=, ) } } @@ -663,38 +663,38 @@ rule .exe DEPENDS $(exe) : $(o) ; DEPENDS $(o) : $(s) ; DEPENDS $(o) : $(locate-target) ; - [COMPILE] $(o) : $(s) ; + "[COMPILE]" $(o) : $(s) ; .clean $(o) ; } DEPENDS $(exe) : $(objs) ; DEPENDS $(exe) : $(locate-target) ; - [COMPILE.LINK] $(exe) : $(objs) ; + "[COMPILE.LINK]" $(exe) : $(objs) ; .clean $(exe) ; } else { DEPENDS $(exe) : $(>) ; DEPENDS $(exe) : $(locate-target) ; - [COMPILE] $(exe) : $(>) ; + "[COMPILE]" $(exe) : $(>) ; .clean $(exe) ; } return $(exe) ; } -if $(OS) = VMS { actions [COMPILE] { +if $(OS) = VMS { actions "[COMPILE]" { $(--cc) $(--bin)$(<:WD=) $(--dir)$(<:D)$(./) $(--out)$(<:W) $(--def[1])$(--defs:J=$(--def[2]))$(--def[3]) $(--flags) $(>:W) $(--libs) } } -else if ! $(--def[2]) { actions [COMPILE] { +else if ! $(--def[2]) { actions "[COMPILE]" { "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def)$(--defs)" "$(--flags)" "$(>)" "$(--libs)" } } -else { actions [COMPILE] { +else { actions "[COMPILE]" { "$(--cc)" "$(--bin)$(<:D=)" "$(--dir)$(<:D)$(./)" $(--out)$(<) "$(--def[1])$(--defs:J=$(--def[2]))$(--def[3])" "$(--flags)" "$(>)" "$(--libs)" } } -if $(OS) = VMS { actions [COMPILE.LINK] { +if $(OS) = VMS { actions "[COMPILE.LINK]" { $(--link) $(--link-bin)$(<:WD=) $(--link-dir)$(<:WD)$(./) $(--link-out)$(<:W) $(--link-def)$(--link-defs) $(--link-flags) $(--link-libs) $(>:WJ=, ) } } -else { actions [COMPILE.LINK] { +else { actions "[COMPILE.LINK]" { "$(--link)" "$(--link-bin)$(<:D=)" "$(--link-dir)$(<:D)$(./)" "$(--link-out)$(<)" "$(--link-def)$(--link-defs)" "$(--link-flags)" "$(>)" "$(--link-libs)" } } @@ -702,16 +702,16 @@ rule .link { DEPENDS all : $(<) ; DEPENDS $(<) : $(>) ; - [LINK] $(<) : $(>) ; + "[LINK]" $(<) : $(>) ; .clean $(<) ; } -if $(OS) = NT { actions [LINK] { +if $(OS) = NT { actions "[LINK]" { copy "$(>)" "$(<)" } } -if $(UNIX) = true { actions [LINK] { +if $(UNIX) = true { actions "[LINK]" { ln -fs "$(>)" "$(<)" } } -if $(OS) = VMS { actions [LINK] { +if $(OS) = VMS { actions "[LINK]" { COPY/REPLACE $(>:W) $(<:W) } } @@ -719,31 +719,31 @@ rule .copy { DEPENDS all : $(<) ; DEPENDS $(<) : $(>) ; - [COPY] $(<) : $(>) ; + "[COPY]" $(<) : $(>) ; .clean $(<) ; } # Will be redefined later. -if $(OS) = VMS { actions [COPY] { +if $(OS) = VMS { actions "[COPY]" { COPY/REPLACE $(>:W) $(<:W) } } -else { actions [COPY] { +else { actions "[COPY]" { } } rule .move { DEPENDS $(<) : $(>) ; - [MOVE] $(<) : $(>) ; + "[MOVE]" $(<) : $(>) ; } -if $(OS) = NT { actions [MOVE] { +if $(OS) = NT { actions "[MOVE]" { del /f "$(<)" rename "$(>)" "$(<)" } } -if $(UNIX) = true { actions [MOVE] { +if $(UNIX) = true { actions "[MOVE]" { mv -f "$(>)" "$(<)" } } -if $(OS) = VMS { actions [MOVE] { +if $(OS) = VMS { actions "[MOVE]" { RENAME /NOCONF $(>:W) $(<:W) } } @@ -755,9 +755,9 @@ rule .yyacc DEPENDS $(<) : $(exe) $(>) ; LEAVES $(<) ; yyacc.exe on $(<) = $(exe:R=$(locate-target)) ; - [YYACC] $(<) : $(>) ; + "[YYACC]" $(<) : $(>) ; } -actions [YYACC] { +actions "[YYACC]" { $(--chmod+w)$(<[1]) $(--chmod+w)$(<[2]) "$(yyacc.exe)" "$(<)" "$(>)" @@ -801,9 +801,9 @@ rule .yacc { DEPENDS $(<) : $(>) ; LEAVES $(<) ; - [YACC] $(<) : $(>) ; + "[YACC]" $(<) : $(>) ; } -if $(OS) = NT { actions [YACC] { +if $(OS) = NT { actions "[YACC]" { "$(yacc)" "$(>)" if not errorlevel 1 ( del /f "$(<[1])" @@ -812,7 +812,7 @@ if $(OS) = NT { actions [YACC] { rename y.tab$(<[2]:S) "$(<[2])" ) else set _error_ = } } -if $(UNIX) = true { actions [YACC] { +if $(UNIX) = true { actions "[YACC]" { if ` "$(yacc)" "$(>)" ` ; then mv -f y.tab$(<[1]:S) "$(<[1])" mv -f y.tab$(<[2]:S) "$(<[2])" @@ -820,7 +820,7 @@ if $(UNIX) = true { actions [YACC] { exit 1 fi } } -if $(OS) = VMS { actions [YACC] { +if $(OS) = VMS { actions "[YACC]" { IF $(yacc) $(>) THEN RENAME /NOCONF y_tab$(<[1]:S) $(<[1]:W) @@ -844,9 +844,9 @@ rule .mkjambase DEPENDS $(<) : $(exe) $(>) ; LEAVES $(<) ; mkjambase.exe on $(<) = $(exe:R=$(locate-target)) ; - [MKJAMBASE] $(<) : $(>) ; + "[MKJAMBASE]" $(<) : $(>) ; } -actions [MKJAMBASE] { +actions "[MKJAMBASE]" { $(--chmod+w)$(<) $(mkjambase.exe) "$(<)" "$(>)" } @@ -954,13 +954,13 @@ if $(OS) = NT case 7z* : zip += a -r -tzip -mx=9 ; case zip : zip += -9r ; } - actions piecemeal [PACK] { + actions piecemeal "[PACK]" { "$(zip)" "$(<)" "$(>)" } - actions piecemeal [ZIP] { + actions piecemeal "[ZIP]" { "$(zip)" "$(<)" "$(>)" } - actions piecemeal [COPY] { + actions piecemeal "[COPY]" { copy /Y "$(>)" "$(<)" >NUL: } } @@ -973,16 +973,16 @@ if $(UNIX) = true case star : tar += -c artype=pax -D -d -to-stdout ; case * : tar += -c -f - ; } - actions [PACK] { + actions "[PACK]" { "$(tar)" "$(>)" | gzip -c9 > "$(<)" } - #~ actions [PACK] { + #~ actions "[PACK]" { #~ tar cf "$(<:S=.tar)" "$(>)" #~ } - actions [ZIP] { + actions "[ZIP]" { gzip -c9 "$(>)" > "$(<)" } - actions [COPY] { + actions "[COPY]" { cp -Rpf "$(>)" "$(<)" } } @@ -997,8 +997,8 @@ rule .binary DEPENDS $(zip) : $($(<).exe) ; DEPENDS dist : $(zip) ; #~ LOCATE on $(zip) = $(locate-target) ; - if $(OS) = NT { [ZIP] $(zip) : $($(<).exe) ; } - if $(UNIX) = true { [PACK] $(zip) : $($(<).exe) ; } + if $(OS) = NT { "[ZIP]" $(zip) : $($(<).exe) ; } + if $(UNIX) = true { "[PACK]" $(zip) : $($(<).exe) ; } .clean $(zip) ; } @@ -1038,11 +1038,11 @@ rule .package ( dst-dir : src-files + ) DEPENDS $(dst-file) : $(src-path) $(dst-file:D) ; .mkdir $(dst-file:D) ; - [COPY] $(dst-file) : $(src-path) ; + "[COPY]" $(dst-file) : $(src-path) ; .clean $(dst-file) ; } - [PACK] $(pack) : $(dst-files) ; + "[PACK]" $(pack) : $(dst-files) ; .clean $(pack) ; } @@ -1074,10 +1074,10 @@ rule .rpm ( name : source ) arch on $(target) = $(rpm-arch) ; if $(rpm-arch) = ppc { target-opt on $(target) = --target= ; } else { target-opt on $(target) = "--target " ; } - [RPM] $(target) : $(source) ; + "[RPM]" $(target) : $(source) ; .clean $(name).$(rpm-arch).rpm $(name).src.rpm ; } -actions [RPM] { +actions "[RPM]" { set -e export BOOST_JAM_TOOLSET="$(toolset)" $(rpm-tool) -ta $(target-opt)$(arch) $(>) | tee rpm.out diff --git a/tools/build/src/engine/compile.c b/tools/build/src/engine/compile.c index 6adb83fa24..6ebb4006c6 100644 --- a/tools/build/src/engine/compile.c +++ b/tools/build/src/engine/compile.c @@ -99,7 +99,7 @@ LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * frame ) /* Check traditional targets $(<) and sources $(>). */ if ( !rule->actions && !rule->procedure ) - unknown_rule( frame, NULL, frame->module, rule->name ); + unknown_rule( frame, NULL, frame->module, rulename ); /* If this rule will be executed for updating the targets then construct the * action for make(). diff --git a/tools/build/src/engine/debugger.c b/tools/build/src/engine/debugger.c index bb996031f4..e6788a05f6 100644 --- a/tools/build/src/engine/debugger.c +++ b/tools/build/src/engine/debugger.c @@ -195,8 +195,11 @@ static void debug_lol_read( FILE * in, LOL * lol ) static void debug_frame_write( FILE * out, FRAME * frame ) { - OBJECT * fullname = make_absolute_path( frame->file ); - debug_object_write( out, frame->file ); + OBJECT * fullname = constant_builtin; + OBJECT * file = frame->file; + if ( file == NULL ) file = constant_builtin; + else fullname = make_absolute_path( frame->file ); + debug_object_write( out, file ); debug_int_write( out, frame->line ); debug_object_write( out, fullname ); debug_lol_write( out, frame->args ); @@ -469,7 +472,8 @@ void debug_on_instruction( FRAME * frame, OBJECT * file, int line ) { int breakpoint_id; assert( debug_is_debugging() ); - if ( debug_state == DEBUG_NEXT && debug_depth <= 0 && debug_line != line ) + if ( debug_state == DEBUG_NEXT && + ( debug_depth < 0 || ( debug_depth == 0 && debug_line != line ) ) ) { debug_file = file; debug_line = line; @@ -483,14 +487,15 @@ void debug_on_instruction( FRAME * frame, OBJECT * file, int line ) debug_frame = frame; debug_end_stepping(); } - else if ( debug_state == DEBUG_FINISH && debug_depth <= 0 ) + else if ( debug_state == DEBUG_FINISH && debug_depth < 0 ) { debug_file = file; debug_line = line; debug_frame = frame; debug_end_stepping(); } - else if ( ( debug_file == NULL || ! object_equal( file, debug_file ) || line != debug_line ) && + else if ( ( debug_file == NULL || ! object_equal( file, debug_file ) || + line != debug_line || debug_depth != 0 ) && ( breakpoint_id = handle_line_breakpoint( file, line ) ) ) { debug_file = file; @@ -498,12 +503,19 @@ void debug_on_instruction( FRAME * frame, OBJECT * file, int line ) debug_frame = frame; debug_on_breakpoint( breakpoint_id ); } + else if ( ( debug_state == DEBUG_RUN || debug_state == DEBUG_FINISH ) && + ( debug_depth < 0 || ( debug_depth == 0 && debug_line != line ) ) ) + { + debug_file = NULL; + debug_line = 0; + } } void debug_on_enter_function( FRAME * frame, OBJECT * name, OBJECT * file, int line ) { int breakpoint_id; assert( debug_is_debugging() ); + ++debug_depth; if ( debug_state == DEBUG_STEP && file ) { debug_file = file; @@ -519,18 +531,18 @@ void debug_on_enter_function( FRAME * frame, OBJECT * name, OBJECT * file, int l debug_frame = frame; debug_on_breakpoint( breakpoint_id ); } - else if ( debug_state == DEBUG_NEXT || debug_state == DEBUG_FINISH ) - { - ++debug_depth; - } } void debug_on_exit_function( OBJECT * name ) { assert( debug_is_debugging() ); - if ( debug_state == DEBUG_NEXT || debug_state == DEBUG_FINISH ) + --debug_depth; + if ( debug_depth < 0 ) { - --debug_depth; + /* The current location is no longer valid + after we return from the containing function. */ + debug_file = NULL; + debug_line = 0; } } @@ -544,11 +556,13 @@ static int child_pid; static void debug_child_continue( int argc, const char * * argv ) { debug_state = DEBUG_RUN; + debug_depth = 0; } static void debug_child_step( int argc, const char * * argv ) { debug_state = DEBUG_STEP; + debug_depth = 0; } static void debug_child_next( int argc, const char * * argv ) @@ -560,7 +574,7 @@ static void debug_child_next( int argc, const char * * argv ) static void debug_child_finish( int argc, const char * * argv ) { debug_state = DEBUG_FINISH; - debug_depth = 1; + debug_depth = 0; } static void debug_child_kill( int argc, const char * * argv ) @@ -1102,7 +1116,7 @@ static void debug_start_child( int argc, const char * * argv ) PROCESS_INFORMATION pi = { NULL, NULL, 0, 0 }; STARTUPINFO si = { sizeof( STARTUPINFO ), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - assert( DEBUG_STATE == DEBUG_NO_CHILD ); + assert( debug_state == DEBUG_NO_CHILD ); if ( ! CreatePipe( &pipe1[ 0 ], &pipe1[ 1 ], &sa, 0 ) ) { printf("internal error\n"); @@ -1189,7 +1203,7 @@ static void debug_start_child( int argc, const char * * argv ) int read_fd; int pid; int i; - assert( DEBUG_STATE == DEBUG_NO_CHILD ); + assert( debug_state == DEBUG_NO_CHILD ); pipe(pipe1); pipe(pipe2); pid = fork(); diff --git a/tools/build/src/engine/execcmd.h b/tools/build/src/engine/execcmd.h index 7161381381..f26d97acb9 100644 --- a/tools/build/src/engine/execcmd.h +++ b/tools/build/src/engine/execcmd.h @@ -63,9 +63,15 @@ int exec_check #define EXEC_CHECK_LINE_TOO_LONG 103 #define EXEC_CHECK_TOO_LONG 104 +/* Prevents action output from being written + * immediately to stdout/stderr. + */ +#define EXEC_CMD_QUIET 1 + void exec_cmd ( string const * command, + int flags, ExecCmdCallback func, void * closure, LIST * shell diff --git a/tools/build/src/engine/execnt.c b/tools/build/src/engine/execnt.c index 029aa37c03..431d111221 100644 --- a/tools/build/src/engine/execnt.c +++ b/tools/build/src/engine/execnt.c @@ -140,6 +140,8 @@ static struct _cmdtab_t HANDLE wait_handle; + int flags; + /* Function called when the command completes. */ ExecCmdCallback func; @@ -317,6 +319,7 @@ int exec_check void exec_cmd ( string const * cmd_orig, + int flags, ExecCmdCallback func, void * closure, LIST * shell @@ -382,6 +385,8 @@ void exec_cmd signal( SIGINT, onintr ); } + cmdtab[ slot ].flags = flags; + /* Save input data into the selected running commands table slot. */ cmdtab[ slot ].func = func; cmdtab[ slot ].closure = closure; @@ -748,11 +753,15 @@ static void record_times( HANDLE const process, timing_info * const time ) static char ioBuffer[ IO_BUFFER_SIZE + 1 ]; +#define FORWARD_PIPE_NONE 0 +#define FORWARD_PIPE_STDOUT 1 +#define FORWARD_PIPE_STDERR 2 static void read_pipe ( HANDLE in, /* the pipe to read from */ - string * out + string * out, + int forwarding_mode ) { DWORD bytesInBuffer = 0; @@ -785,6 +794,11 @@ static void read_pipe ioBuffer[ bytesInBuffer ] = '\0'; /* Append to the output. */ string_append( out, ioBuffer ); + /* Copy it to our output if appropriate */ + if ( forwarding_mode == FORWARD_PIPE_STDOUT ) + out_data( ioBuffer ); + else if ( forwarding_mode == FORWARD_PIPE_STDERR ) + err_data( ioBuffer ); /* Subtract what we read in. */ bytesAvailable -= bytesInBuffer; } @@ -804,6 +818,15 @@ static void read_pipe while ( bytesAvailable > 0 ); } +#define EARLY_OUTPUT( cmd ) \ + ( ! ( cmd.flags & EXEC_CMD_QUIET ) ) + +#define FORWARD_STDOUT( c ) \ + ( ( EARLY_OUTPUT( c ) && ( globs.pipe_action != 2 ) ) ? \ + FORWARD_PIPE_STDOUT : FORWARD_PIPE_NONE ) +#define FORWARD_STDERR( c ) \ + ( ( EARLY_OUTPUT( c ) && ( globs.pipe_action & 2 ) ) ? \ + FORWARD_PIPE_STDERR : FORWARD_PIPE_NONE ) static void read_output() { @@ -814,11 +837,11 @@ static void read_output() /* Read stdout data. */ if ( cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ] ) read_pipe( cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ], - cmdtab[ i ].buffer_out ); + cmdtab[ i ].buffer_out, FORWARD_STDOUT( cmdtab[ i ] ) ); /* Read stderr data. */ if ( cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ] ) read_pipe( cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ], - cmdtab[ i ].buffer_err ); + cmdtab[ i ].buffer_err, FORWARD_STDERR( cmdtab[ i ] ) ); } } @@ -1282,7 +1305,9 @@ static void string_new_from_argv( string * result, char const * const * argv ) while ( *argv ) { string_push_back( result, ' ' ); + string_push_back( result, '"' ); string_append( result, *(argv++) ); + string_push_back( result, '"' ); } } diff --git a/tools/build/src/engine/execunix.c b/tools/build/src/engine/execunix.c index a4c73ea17e..0120a6b56e 100644 --- a/tools/build/src/engine/execunix.c +++ b/tools/build/src/engine/execunix.c @@ -83,6 +83,8 @@ static struct int buf_size[ 2 ]; /* buffer sizes in bytes */ timestamp start_dt; /* start of command timestamp */ + int flags; + /* Function called when the command completes. */ ExecCmdCallback func; @@ -170,6 +172,7 @@ int exec_check void exec_cmd ( string const * command, + int flags, ExecCmdCallback func, void * closure, LIST * shell @@ -341,6 +344,8 @@ void exec_cmd if ( globs.pipe_action ) GET_WAIT_FD( slot )[ ERR ].fd = err[ EXECCMD_PIPE_READ ]; + cmdtab[ slot ].flags = flags; + /* Save input data into the selected running commands table slot. */ cmdtab[ slot ].func = func; cmdtab[ slot ].closure = closure; @@ -374,6 +379,16 @@ static int read_descriptor( int i, int s ) cmdtab[ i ].stream[ s ] ) ) ) { buffer[ ret ] = 0; + + /* Copy it to our output if appropriate */ + if ( ! ( cmdtab[ i ].flags & EXEC_CMD_QUIET ) ) + { + if ( s == OUT && ( globs.pipe_action != 2 ) ) + out_data( buffer ); + else if ( s == ERR && ( globs.pipe_action & 2 ) ) + err_data( buffer ); + } + if ( !cmdtab[ i ].buffer[ s ] ) { /* Never been allocated. */ diff --git a/tools/build/src/engine/execvms.c b/tools/build/src/engine/execvms.c index 15e9d28071..6c95011c6f 100644 --- a/tools/build/src/engine/execvms.c +++ b/tools/build/src/engine/execvms.c @@ -101,6 +101,7 @@ int exec_check void exec_cmd ( string const * command, + int flags, ExecCmdCallback func, void * closure, LIST * shell diff --git a/tools/build/src/engine/filesys.c b/tools/build/src/engine/filesys.c index e9612bb2ff..da0e47a2c0 100644 --- a/tools/build/src/engine/filesys.c +++ b/tools/build/src/engine/filesys.c @@ -88,6 +88,7 @@ file_archive_info_t * file_archive_info( OBJECT * const path, int * found ) if ( !*found ) { + archive->name = path_key; archive->file = 0; archive->members = FL0; } @@ -292,6 +293,7 @@ file_info_t * file_query( OBJECT * const path ) return ff; } +#ifndef OS_NT /* * file_query_posix_() - query information about a path using POSIX stat() @@ -329,10 +331,45 @@ void file_query_posix_( file_info_t * const info ) info->is_file = statbuf.st_mode & S_IFREG ? 1 : 0; info->is_dir = statbuf.st_mode & S_IFDIR ? 1 : 0; info->exists = 1; +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809 +#if defined(OS_MACOSX) + timestamp_init( &info->time, statbuf.st_mtimespec.tv_sec, statbuf.st_mtimespec.tv_nsec ); +#else + timestamp_init( &info->time, statbuf.st_mtim.tv_sec, statbuf.st_mtim.tv_nsec ); +#endif +#else timestamp_init( &info->time, statbuf.st_mtime, 0 ); +#endif } } +/* + * file_supported_fmt_resolution() - file modification timestamp resolution + * + * Returns the minimum file modification timestamp resolution supported by this + * Boost Jam implementation. File modification timestamp changes of less than + * the returned value might not be recognized. + * + * Does not take into consideration any OS or file system related restrictions. + * + * Return value 0 indicates that any value supported by the OS is also supported + * here. + */ + +void file_supported_fmt_resolution( timestamp * const t ) +{ +#if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200809 + timestamp_init( t, 0, 1 ); +#else + /* The current implementation does not support file modification timestamp + * resolution of less than one second. + */ + timestamp_init( t, 1, 0 ); +#endif +} + +#endif + /* * file_remove_atexit() - schedule a path to be removed on program exit diff --git a/tools/build/src/engine/filesys.h b/tools/build/src/engine/filesys.h index b13853d17e..24c0556d91 100644 --- a/tools/build/src/engine/filesys.h +++ b/tools/build/src/engine/filesys.h @@ -53,6 +53,7 @@ typedef file_info_t * * FILELISTITER; /* also &FILEITEM equivalent */ typedef struct file_archive_info_t { + OBJECT * name; file_info_t * file; FILELIST * members; } file_archive_info_t; diff --git a/tools/build/src/engine/fileunix.c b/tools/build/src/engine/fileunix.c index 2d21e51496..5f6815725f 100644 --- a/tools/build/src/engine/fileunix.c +++ b/tools/build/src/engine/fileunix.c @@ -201,27 +201,6 @@ void file_query_( file_info_t * const info ) } -/* - * file_supported_fmt_resolution() - file modification timestamp resolution - * - * Returns the minimum file modification timestamp resolution supported by this - * Boost Jam implementation. File modification timestamp changes of less than - * the returned value might not be recognized. - * - * Does not take into consideration any OS or file system related restrictions. - * - * Return value 0 indicates that any value supported by the OS is also supported - * here. - */ - -void file_supported_fmt_resolution( timestamp * const t ) -{ - /* The current implementation does not support file modification timestamp - * resolution of less than one second. - */ - timestamp_init( t, 1, 0 ); -} - int file_collect_archive_content_( file_archive_info_t * const archive ); /* diff --git a/tools/build/src/engine/filevms.c b/tools/build/src/engine/filevms.c index e94e2634c8..ef93b0cdb4 100644 --- a/tools/build/src/engine/filevms.c +++ b/tools/build/src/engine/filevms.c @@ -162,27 +162,6 @@ void file_query_( file_info_t * const info ) } -/* - * file_supported_fmt_resolution() - file modification timestamp resolution - * - * Returns the minimum file modification timestamp resolution supported by this - * Boost Jam implementation. File modification timestamp changes of less than - * the returned value might not be recognized. - * - * Does not take into consideration any OS or file system related restrictions. - * - * Return value 0 indicates that any value supported by the OS is also supported - * here. - */ - -void file_supported_fmt_resolution( timestamp * const t ) -{ - /* The current implementation does not support file modification timestamp - * resolution of less than one second. - */ - timestamp_init( t, 1, 0 ); -} - /*------------------------------------------------------------------------------ * VMS-specific processing: * diff --git a/tools/build/src/engine/function.c b/tools/build/src/engine/function.c index 46ec40fea4..2244c3e307 100644 --- a/tools/build/src/engine/function.c +++ b/tools/build/src/engine/function.c @@ -533,7 +533,20 @@ static LIST * function_call_member_rule( JAM_FUNCTION * function, FRAME * frame, if ( module->class_module ) { rule = bindrule( rulename, module ); - real_rulename = object_copy( function_rulename( rule->procedure ) ); + if ( rule->procedure ) + { + real_rulename = object_copy( function_rulename( rule->procedure ) ); + } + else + { + string buf[ 1 ]; + string_new( buf ); + string_append( buf, object_str( module->name ) ); + string_push_back( buf, '.' ); + string_append( buf, object_str( rulename ) ); + real_rulename = object_new( buf->value ); + string_free( buf ); + } } else { @@ -2434,12 +2447,17 @@ static void compile_append_chain( PARSE * parse, compiler * c ) } } -static void compile_parse( PARSE * parse, compiler * c, int result_location ) +static void compile_emit_debug(compiler * c, int line) { #ifdef JAM_DEBUGGER if ( debug_is_debugging() ) - compile_emit( c, INSTR_DEBUG_LINE, parse->line ); + compile_emit( c, INSTR_DEBUG_LINE, line ); #endif +} + +static void compile_parse( PARSE * parse, compiler * c, int result_location ) +{ + compile_emit_debug(c, parse->line); if ( parse->type == PARSE_APPEND ) { compile_append_chain( parse, c ); @@ -2495,6 +2513,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) compile_emit( c, INSTR_FOR_INIT, 0 ); compile_set_label( c, top ); compile_emit_branch( c, INSTR_FOR_LOOP, end ); + compile_emit_debug( c, parse->line ); compile_emit( c, INSTR_SET, var ); compile_push_break_scope( c, end ); @@ -2649,6 +2668,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) group->elems, 0 ) )->s ); var_parse_group_free( group ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); compile_emit( c, INSTR_PUSH_LOCAL, name ); compile_push_cleanup( c, INSTR_POP_LOCAL, name ); compile_parse( parse->third, c, nested_result ); @@ -2660,6 +2680,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) var_parse_group_compile( group, c ); var_parse_group_free( group ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); compile_emit( c, INSTR_PUSH_LOCAL_GROUP, 0 ); compile_push_cleanup( c, INSTR_POP_LOCAL_GROUP, 0 ); compile_parse( parse->third, c, nested_result ); @@ -2671,6 +2692,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) { compile_parse( parse->left, c, RESULT_STACK ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); compile_emit( c, INSTR_PUSH_LOCAL_GROUP, 0 ); compile_push_cleanup( c, INSTR_POP_LOCAL_GROUP, 0 ); compile_parse( parse->third, c, nested_result ); @@ -2820,6 +2842,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) group->elems, 0 ) )->s ); var_parse_group_free( group ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); if ( result_location != RESULT_NONE ) { compile_emit( c, INSTR_SET_RESULT, 1 ); @@ -2831,6 +2854,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) var_parse_group_compile( group, c ); var_parse_group_free( group ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); if ( result_location != RESULT_NONE ) { compile_emit( c, INSTR_SET_RESULT, 1 ); @@ -2842,6 +2866,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) { compile_parse( parse->left, c, RESULT_STACK ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); if ( result_location != RESULT_NONE ) { compile_emit( c, INSTR_SET_RESULT, 1 ); @@ -2875,6 +2900,7 @@ static void compile_parse( PARSE * parse, compiler * c, int result_location ) compile_parse( parse->third, c, RESULT_STACK ); compile_parse( parse->right, c, RESULT_STACK ); + compile_emit_debug(c, parse->line); switch ( parse->num ) { case ASSIGN_APPEND: compile_emit( c, INSTR_APPEND_ON, 0 ); break; diff --git a/tools/build/src/engine/jam.c b/tools/build/src/engine/jam.c index 92686fc8d8..4bca2fd7b6 100644 --- a/tools/build/src/engine/jam.c +++ b/tools/build/src/engine/jam.c @@ -269,6 +269,7 @@ int main( int argc, char * * argv, char * * arg_environ ) #endif cwd_init(); + constants_init(); #ifdef JAM_DEBUGGER @@ -449,8 +450,6 @@ int main( int argc, char * * argv, char * * arg_environ ) /* ++globs.noexec; */ } - constants_init(); - { PROFILE_ENTER( MAIN ); diff --git a/tools/build/src/engine/jambase.c b/tools/build/src/engine/jambase.c index 80a7e12de2..436c683795 100644 --- a/tools/build/src/engine/jambase.c +++ b/tools/build/src/engine/jambase.c @@ -1,11 +1,15 @@ /* Generated by mkjambase from Jambase */ char *jambase[] = { /* Jambase */ +"\n", +"\n", "if $(NT)\n", "{\n", "SLASH ?= \\\\ ;\n", "}\n", "SLASH ?= / ;\n", +"\n", +"\n", "rule find-to-root ( dir : patterns + )\n", "{\n", "local globs = [ GLOB $(dir) : $(patterns) ] ;\n", @@ -16,13 +20,20 @@ char *jambase[] = { "}\n", "return $(globs) ;\n", "}\n", +"\n", +"\n", ".boost-build-file = ;\n", +"\n", ".bootstrap-file = ;\n", +"\n", "BOOST_BUILD_PATH.user-value = $(BOOST_BUILD_PATH) ;\n", +"\n", "if ! $(BOOST_BUILD_PATH) && $(UNIX)\n", "{\n", "BOOST_BUILD_PATH = /usr/share/boost-build ;\n", "}\n", +"\n", +"\n", "rule _poke ( module-name ? : variables + : value * )\n", "{\n", "module $(<)\n", @@ -30,6 +41,8 @@ char *jambase[] = { "$(>) = $(3) ;\n", "}\n", "}\n", +"\n", +"\n", "rule boost-build ( dir ? )\n", "{\n", "if $(.bootstrap-file)\n", @@ -40,10 +53,14 @@ char *jambase[] = { "ECHO ;\n", "EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", "}\n", +"\n", "BOOST_BUILD_PATH = $(dir:R=$(.boost-build-file:D)) $(BOOST_BUILD_PATH) ;\n", +"\n", "_poke .ENVIRON : BOOST_BUILD_PATH : $(BOOST_BUILD_PATH) ;\n", +"\n", "local bootstrap-file = [ GLOB $(BOOST_BUILD_PATH) : bootstrap.jam ] ;\n", ".bootstrap-file = $(bootstrap-file[1]) ;\n", +"\n", "if ! $(.bootstrap-file)\n", "{\n", "ECHO \"Unable to load Boost.Build: could not find build system.\" ;\n", @@ -57,30 +74,36 @@ char *jambase[] = { "ECHO ;\n", "EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", "}\n", +"\n", "if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n", "{\n", "ECHO \"notice: loading Boost.Build from\"\n", "[ NORMALIZE_PATH $(.bootstrap-file:D) ] ;\n", "}\n", +"\n", "include $(.bootstrap-file) ;\n", "}\n", -"if [ MATCH .*(b2).* : $(ARGV[1]:BL) ] \n", -"|| [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n", -"|| $(BOOST_ROOT) # A temporary measure so Jam works with Boost.Build v1.\n", +"\n", +"\n", "{\n", +"\n", "local search-path = $(BOOST_BUILD_PATH) $(BOOST_ROOT) ;\n", "local self = [ SELF_PATH ] ;\n", "local boost-build-relative = ../../share/boost-build ;\n", "local self-based-path = [ NORMALIZE_PATH $(boost-build-relative:R=$(self)) ] ;\n", +"\n", "local boost-build-files =\n", "[ find-to-root [ PWD ] : boost-build.jam ]\n", "[ GLOB $(self-based-path) : boost-build.jam ]\n", "[ GLOB $(search-path) : boost-build.jam ] ;\n", +"\n", ".boost-build-file = $(boost-build-files[1]) ;\n", +"\n", "if ! $(.boost-build-file)\n", "{\n", "ECHO \"Unable to load Boost.Build: could not find \\\"boost-build.jam\\\"\" ;\n", "ECHO --------------------------------------------------------------- ;\n", +"\n", "if ! [ MATCH .*(bjam).* : $(ARGV[1]:BL) ]\n", "{\n", "ECHO \"BOOST_ROOT must be set, either in the environment, or \" ;\n", @@ -88,17 +111,21 @@ char *jambase[] = { "ECHO \"of the boost installation.\" ;\n", "ECHO ;\n", "}\n", +"\n", "ECHO \"Attempted search from\" [ PWD ] \"up to the root\" ;\n", "ECHO \"at\" $(self-based-path) ;\n", "ECHO \"and in these directories from BOOST_BUILD_PATH and BOOST_ROOT: \"$(search-path:J=\", \")\".\" ;\n", "EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", "}\n", +"\n", "if [ MATCH .*(--debug-configuration).* : $(ARGV) ]\n", "{\n", "ECHO \"notice: found boost-build.jam at\"\n", "[ NORMALIZE_PATH $(.boost-build-file) ] ;\n", "}\n", +"\n", "include $(.boost-build-file) ;\n", +"\n", "if ! $(.bootstrap-file)\n", "{\n", "ECHO \"Unable to load Boost.Build\" ;\n", @@ -112,1592 +139,4 @@ char *jambase[] = { "EXIT \"Please consult the documentation at 'http://www.boost.org'.\" ;\n", "}\n", "}\n", -"else\n", -"{\n", -"if $(NT)\n", -"{\n", -"local SUPPORTED_TOOLSETS = \"BORLANDC\" \"VC7\" \"VISUALC\" \"VISUALC16\" \"INTELC\" \"WATCOM\"\n", -"\"MINGW\" \"LCC\" ;\n", -"TOOLSET = \"\" ;\n", -"if $(JAM_TOOLSET)\n", -"{\n", -"local t ;\n", -"for t in $(SUPPORTED_TOOLSETS)\n", -"{\n", -"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n", -"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"ECHO \"The JAM_TOOLSET environment variable is defined but its value\" ;\n", -"ECHO \"is invalid, please use one of the following:\" ;\n", -"ECHO ;\n", -"for t in $(SUPPORTED_TOOLSETS) { ECHO \" \" $(t) ; }\n", -"EXIT ;\n", -"}\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"if $(BCCROOT)\n", -"{\n", -"TOOLSET = BORLANDC ;\n", -"BORLANDC = $(BCCROOT:J=\" \") ;\n", -"}\n", -"else if $(MSVC)\n", -"{\n", -"TOOLSET = VISUALC16 ;\n", -"VISUALC16 = $(MSVC:J=\" \") ;\n", -"}\n", -"else if $(MSVCNT)\n", -"{\n", -"TOOLSET = VISUALC ;\n", -"VISUALC = $(MSVCNT:J=\" \") ;\n", -"}\n", -"else if $(MSVCDir)\n", -"{\n", -"TOOLSET = VISUALC ;\n", -"VISUALC = $(MSVCDir:J=\" \") ;\n", -"}\n", -"else if $(MINGW)\n", -"{\n", -"TOOLSET = MINGW ;\n", -"}\n", -"else\n", -"{\n", -"ECHO \"Jam cannot be run because, either:\" ;\n", -"ECHO \" a. You didn't set BOOST_ROOT to indicate the root of your\" ;\n", -"ECHO \" Boost installation.\" ;\n", -"ECHO \" b. You are trying to use stock Jam but didn't indicate which\" ;\n", -"ECHO \" compilation toolset to use. To do so, follow these simple\" ;\n", -"ECHO \" instructions:\" ;\n", -"ECHO ;\n", -"ECHO \" - define one of the following environment variable, with the\" ;\n", -"ECHO \" appropriate value according to this list:\" ;\n", -"ECHO ;\n", -"ECHO \" Variable Toolset Description\" ;\n", -"ECHO ;\n", -"ECHO \" BORLANDC Borland C++ BC++ install path\" ;\n", -"ECHO \" VISUALC Microsoft Visual C++ VC++ install path\" ;\n", -"ECHO \" VISUALC16 Microsoft Visual C++ 16 bit VC++ 16 bit install\" ;\n", -"ECHO \" INTELC Intel C/C++ IC++ install path\" ;\n", -"ECHO \" WATCOM Watcom C/C++ Watcom install path\" ;\n", -"ECHO \" MINGW MinGW (gcc) MinGW install path\" ;\n", -"ECHO \" LCC Win32-LCC LCC-Win32 install path\" ;\n", -"ECHO ;\n", -"ECHO \" - define the JAM_TOOLSET environment variable with the *name*\" ;\n", -"ECHO \" of the toolset variable you want to use.\" ;\n", -"ECHO ;\n", -"ECHO \" e.g.: set VISUALC=C:\\\\Visual6\" ;\n", -"ECHO \" set JAM_TOOLSET=VISUALC\" ;\n", -"EXIT ;\n", -"}\n", -"}\n", -"CP ?= copy ;\n", -"RM ?= del /f/q ;\n", -"SLASH ?= \\\\ ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"SUFEXE ?= .exe ;\n", -"if $(TOOLSET) = BORLANDC\n", -"{\n", -"ECHO \"Compiler is Borland C++\" ;\n", -"AR ?= tlib /C /P64 ;\n", -"CC ?= bcc32 ;\n", -"CCFLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus ;\n", -"C++ ?= bcc32 ;\n", -"C++FLAGS ?= -q -y -d -v -w-par -w-ccc -w-rch -w-pro -w-aus -P ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"STDLIBPATH ?= $(BORLANDC)\\\\lib ;\n", -"STDHDRS ?= $(BORLANDC)\\\\include ;\n", -"NOARSCAN ?= true ;\n", -"}\n", -"else if $(TOOLSET) = VISUALC16\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++ 16 bit\" ;\n", -"AR ?= lib /nologo ;\n", -"CC ?= cl /nologo ;\n", -"CCFLAGS ?= /D \\\"WIN\\\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"LINKLIBS ?=\n", -"\\\"$(VISUALC16)\\\\lib\\\\mlibce.lib\\\"\n", -"\\\"$(VISUALC16)\\\\lib\\\\oldnames.lib\\\"\n", -";\n", -"LINKLIBS ?= ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(VISUALC16)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = VISUALC\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++\" ;\n", -"AR ?= lib ;\n", -"AS ?= masm386 ;\n", -"CC ?= cl /nologo ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= link /nologo ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \\\"$(VISUALC)\\\\lib\\\\advapi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\gdi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\user32.lib\\\"\n", -"\\\"$(VISUALC)\\\\lib\\\\kernel32.lib\\\" ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(VISUALC)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = VC7\n", -"{\n", -"ECHO \"Compiler is Microsoft Visual C++ .NET\" ;\n", -"AR ?= lib ;\n", -"AS ?= masm386 ;\n", -"CC ?= cl /nologo ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= link /nologo ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\advapi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\gdi32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\user32.lib\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\lib\\\\kernel32.lib\\\" ;\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= \\\"$(VISUALC)\\\\include\\\"\n", -"\\\"$(VISUALC)\\\\PlatformSDK\\\\include\\\" ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = INTELC\n", -"{\n", -"ECHO \"Compiler is Intel C/C++\" ;\n", -"if ! $(VISUALC)\n", -"{\n", -"ECHO \"As a special exception, when using the Intel C++ compiler, you need\" ;\n", -"ECHO \"to define the VISUALC environment variable to indicate the location\" ;\n", -"ECHO \"of your Visual C++ installation. Aborting..\" ;\n", -"EXIT ;\n", -"}\n", -"AR ?= lib ;\n", -"AS ?= masm386 ;\n", -"CC ?= icl /nologo ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= link /nologo ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= $(VISUALC)\\\\lib\\\\advapi32.lib\n", -"$(VISUALC)\\\\lib\\\\kernel32.lib\n", -";\n", -"OPTIM ?= \"\" ;\n", -"STDHDRS ?= $(INTELC)\\include $(VISUALC)\\\\include ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = WATCOM\n", -"{\n", -"ECHO \"Compiler is Watcom C/C++\" ;\n", -"AR ?= wlib ;\n", -"CC ?= wcc386 ;\n", -"CCFLAGS ?= /zq /DWIN32 /I$(WATCOM)\\\\h ; # zq=quiet\n", -"C++ ?= wpp386 ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"CP ?= copy ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"LINK ?= wcl386 ;\n", -"LINKFLAGS ?= /zq ; # zq=quiet\n", -"LINKLIBS ?= ;\n", -"MV ?= move ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"RM ?= del /f ;\n", -"SLASH ?= \\\\ ;\n", -"STDHDRS ?= $(WATCOM)\\\\h $(WATCOM)\\\\h\\\\nt ;\n", -"SUFEXE ?= .exe ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = MINGW\n", -"{\n", -"ECHO \"Compiler is GCC with Mingw\" ;\n", -"AR ?= ar -ru ;\n", -"CC ?= gcc ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \"\" ;\n", -"OPTIM ?= ;\n", -"SUFOBJ = .o ;\n", -"SUFLIB = .a ;\n", -"SLASH = / ;\n", -"}\n", -"else if $(TOOLSET) = LCC\n", -"{\n", -"ECHO \"Compiler is Win32-LCC\" ;\n", -"AR ?= lcclib ;\n", -"CC ?= lcc ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= lcclnk ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \"\" ;\n", -"OPTIM ?= ;\n", -"NOARSCAN = true ;\n", -"}\n", -"else\n", -"{\n", -"EXIT On NT, set BCCROOT, MSVCNT, MINGW or MSVC to the root of the\n", -"Borland or Microsoft directories. ;\n", -"}\n", -"}\n", -"else if $(OS2)\n", -"{\n", -"local SUPPORTED_TOOLSETS = \"EMX\" \"WATCOM\" ;\n", -"TOOLSET = \"\" ;\n", -"if $(JAM_TOOLSET)\n", -"{\n", -"local t ;\n", -"for t in $(SUPPORTED_TOOLSETS)\n", -"{\n", -"$(t) = $($(t):J=\" \") ; # reconstitute paths with spaces in them\n", -"if $(t) = $(JAM_TOOLSET) { TOOLSET = $(t) ; }\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"ECHO \"The JAM_TOOLSET environment variable is defined but its value\" ;\n", -"ECHO \"is invalid, please use one of the following:\" ;\n", -"ECHO ;\n", -"for t in $(SUPPORTED_TOOLSETS) { ECHO \" \" $(t) ; }\n", -"EXIT ;\n", -"}\n", -"}\n", -"if ! $(TOOLSET)\n", -"{\n", -"if $(watcom)\n", -"{\n", -"WATCOM = $(watcom:J=\" \") ;\n", -"TOOLSET = WATCOM ;\n", -"}\n", -"else\n", -"{\n", -"ECHO \"Jam cannot be run because you didn't indicate which compilation toolset\" ;\n", -"ECHO \"to use. To do so, follow these simple instructions:\" ;\n", -"ECHO ;\n", -"ECHO \" - define one of the following environment variable, with the\" ;\n", -"ECHO \" appropriate value according to this list:\" ;\n", -"ECHO ;\n", -"ECHO \" Variable Toolset Description\" ;\n", -"ECHO ;\n", -"ECHO \" WATCOM Watcom C/C++ Watcom install path\" ;\n", -"ECHO \" EMX EMX (gcc) EMX install path\" ;\n", -"ECHO \" VISUALAGE IBM Visual Age C/C++ VisualAge install path\" ;\n", -"ECHO ;\n", -"ECHO \" - define the JAM_TOOLSET environment variable with the *name*\" ;\n", -"ECHO \" of the toolset variable you want to use.\" ;\n", -"ECHO ;\n", -"ECHO \" e.g.: set WATCOM=C:\\WATCOM\" ;\n", -"ECHO \" set JAM_TOOLSET=WATCOM\" ;\n", -"ECHO ;\n", -"EXIT ;\n", -"}\n", -"}\n", -"RM = del /f ;\n", -"CP = copy ;\n", -"MV ?= move ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .obj ;\n", -"SUFEXE ?= .exe ;\n", -"if $(TOOLSET) = WATCOM\n", -"{\n", -"AR ?= wlib ;\n", -"BINDIR ?= \\\\os2\\\\apps ;\n", -"CC ?= wcc386 ;\n", -"CCFLAGS ?= /zq /DOS2 /I$(WATCOM)\\\\h ; # zq=quiet\n", -"C++ ?= wpp386 ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= wcl386 ;\n", -"LINKFLAGS ?= /zq ; # zq=quiet\n", -"LINKLIBS ?= ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"SLASH ?= \\\\ ;\n", -"STDHDRS ?= $(WATCOM)\\\\h ;\n", -"UNDEFFLAG ?= \"/u _\" ;\n", -"}\n", -"else if $(TOOLSET) = EMX\n", -"{\n", -"ECHO \"Compiler is GCC-EMX\" ;\n", -"AR ?= ar -ru ;\n", -"CC ?= gcc ;\n", -"CCFLAGS ?= \"\" ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= \"\" ;\n", -"OPTIM ?= ;\n", -"SUFOBJ = .o ;\n", -"SUFLIB = .a ;\n", -"UNDEFFLAG ?= \"-U\" ;\n", -"SLASH = / ;\n", -"}\n", -"else\n", -"{\n", -"EXIT \"Sorry, but the $(JAM_TOOLSET) toolset isn't supported for now\" ;\n", -"}\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"C++ ?= cxx ;\n", -"C++FLAGS ?= ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= ;\n", -"CHMOD ?= set file/prot= ;\n", -"CP ?= copy/replace ;\n", -"CRELIB ?= true ;\n", -"DOT ?= . ; ## Use POSIX CRTL\n", -"DOTDOT ?= .. ; ## Use POSIX CRTL\n", -"EXEMODE ?= (w:e) ;\n", -"FILEMODE ?= (w:r) ;\n", -"HDRS ?= ;\n", -"LINK ?= link ;\n", -"LINKFLAGS ?= \"\" ;\n", -"LINKLIBS ?= ;\n", -"MKDIR ?= create/dir ;\n", -"MV ?= rename /noconf ;\n", -"OPTIM ?= \"\" ;\n", -"RM ?= delete /noconf ;\n", -"RUNVMS ?= mcr ;\n", -"SHELLMODE ?= (w:er) ;\n", -"SLASH ?= / ; ## Use POSIX CRTL\n", -"STDHDRS ?= decc$library_include ;\n", -"SUFEXE ?= .exe ;\n", -"SUFLIB ?= .olb ;\n", -"SUFOBJ ?= .obj ;\n", -"switch $(OS)\n", -"{\n", -"case OPENVMS : CCFLAGS ?= /stand=vaxc ;\n", -"case VMS : LINKLIBS ?= sys$library:vaxcrtl.olb/lib ;\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"local OPT ;\n", -"CW ?= \"{CW}\" ;\n", -"MACHDRS ?=\n", -"\"$(UMACHDRS):Universal:Interfaces:CIncludes\"\n", -"\"$(CW):MSL:MSL_C:MSL_Common:Include\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Include\" ;\n", -"MACLIBS ?=\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Interfacelib\"\n", -"\"$(CW):MacOS Support:Universal:Libraries:StubLibraries:Mathlib\" ;\n", -"MPWLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW.Lib\" ;\n", -"MPWNLLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL MPWCRuntime.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC MPW(NL).Lib\" ;\n", -"SIOUXHDRS ?= ;\n", -"SIOUXLIBS ?=\n", -"\"$(CW):MacOS Support:Libraries:Runtime:Runtime PPC:MSL RuntimePPC.lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL SIOUX.PPC.Lib\"\n", -"\"$(CW):MSL:MSL_C:MSL_MacOS:Lib:PPC:MSL C.PPC.Lib\" ;\n", -"C++ ?= mwcppc ;\n", -"C++FLAGS ?= -w off -nomapcr ;\n", -"CC ?= mwcppc ;\n", -"CCFLAGS ?= -w off -nomapcr ;\n", -"CP ?= duplicate -y ;\n", -"DOT ?= \":\" ;\n", -"DOTDOT ?= \"::\" ;\n", -"HDRS ?= $(MACHDRS) $(MPWHDRS) ;\n", -"LINK ?= mwlinkppc ;\n", -"LINKFLAGS ?= -mpwtool -warn ;\n", -"LINKLIBS ?= $(MACLIBS) $(MPWLIBS) ;\n", -"MKDIR ?= newfolder ;\n", -"MV ?= rename -y ;\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= ;\n", -"RM ?= delete -y ;\n", -"SLASH ?= \":\" ;\n", -"STDHDRS ?= ;\n", -"SUFLIB ?= .lib ;\n", -"SUFOBJ ?= .o ;\n", -"}\n", -"else if $(OS) = BEOS && $(METROWERKS)\n", -"{\n", -"AR ?= mwld -xml -o ;\n", -"BINDIR ?= /boot/apps ;\n", -"CC ?= mwcc ;\n", -"CCFLAGS ?= -nosyspath ;\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= -nosyspath ;\n", -"FORTRAN ?= \"\" ;\n", -"LIBDIR ?= /boot/develop/libraries ;\n", -"LINK ?= mwld ;\n", -"LINKFLAGS ?= \"\" ;\n", -"MANDIR ?= /boot/documentation/\"Shell Tools\"/HTML ;\n", -"NOARSCAN ?= true ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"}\n", -"else if $(OS) = BEOS\n", -"{\n", -"BINDIR ?= /boot/apps ;\n", -"CC ?= gcc ;\n", -"C++ ?= $(CC) ;\n", -"FORTRAN ?= \"\" ;\n", -"LIBDIR ?= /boot/develop/libraries ;\n", -"LINK ?= gcc ;\n", -"LINKLIBS ?= -lnet ;\n", -"NOARSCAN ?= true ;\n", -"STDHDRS ?= /boot/develop/headers/posix ;\n", -"}\n", -"else if $(OS) = HAIKU\n", -"{\n", -"BINDIR ?= /boot/system/non-packaged/bin ;\n", -"CC ?= gcc ;\n", -"C++ ?= $(CC) ;\n", -"FORTRAN ?= \"\" ;\n", -"LIBDIR ?= /boot/system/non-packaged/lib ;\n", -"LINK ?= gcc ;\n", -"LINKLIBS ?= -lnetwork ;\n", -"NOARSCAN ?= true ;\n", -"STDHDRS ?= /boot/system/develop/headers/posix ;\n", -"}\n", -"else if $(UNIX)\n", -"{\n", -"switch $(OS)\n", -"{\n", -"case AIX :\n", -"LINKLIBS ?= -lbsd ;\n", -"case AMIGA :\n", -"CC ?= gcc ;\n", -"YACC ?= \"bison -y\" ;\n", -"case CYGWIN :\n", -"CC ?= gcc ;\n", -"CCFLAGS += -D__cygwin__ ;\n", -"LEX ?= flex ;\n", -"RANLIB ?= \"\" ;\n", -"SUFEXE ?= .exe ;\n", -"YACC ?= \"bison -y\" ;\n", -"case DGUX :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case HPUX :\n", -"YACC = ;\n", -"CFLAGS += -Ae ;\n", -"CCFLAGS += -Ae ;\n", -"RANLIB ?= \"\" ;\n", -"case INTERIX :\n", -"CC ?= gcc ;\n", -"RANLIB ?= \"\" ;\n", -"case IRIX :\n", -"RANLIB ?= \"\" ;\n", -"case MPEIX :\n", -"CC ?= gcc ;\n", -"C++ ?= gcc ;\n", -"CCFLAGS += -D_POSIX_SOURCE ;\n", -"HDRS += /usr/include ;\n", -"RANLIB ?= \"\" ;\n", -"NOARSCAN ?= true ;\n", -"NOARUPDATE ?= true ;\n", -"case MVS :\n", -"RANLIB ?= \"\" ;\n", -"case NEXT :\n", -"AR ?= libtool -o ;\n", -"RANLIB ?= \"\" ;\n", -"case MACOSX :\n", -"AR ?= libtool -o ;\n", -"C++ ?= c++ ;\n", -"MANDIR ?= /usr/local/share/man ;\n", -"RANLIB ?= \"\" ;\n", -"case NCR :\n", -"RANLIB ?= \"\" ;\n", -"case PTX :\n", -"RANLIB ?= \"\" ;\n", -"case QNX :\n", -"AR ?= wlib ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= -Q ; # quiet\n", -"C++ ?= $(CC) ;\n", -"C++FLAGS ?= -Q ; # quiet\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= -Q ; # quiet\n", -"NOARSCAN ?= true ;\n", -"RANLIB ?= \"\" ;\n", -"case SCO :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"case SINIX :\n", -"RANLIB ?= \"\" ;\n", -"case SOLARIS :\n", -"RANLIB ?= \"\" ;\n", -"AR ?= \"/usr/ccs/bin/ar ru\" ;\n", -"case UNICOS :\n", -"NOARSCAN ?= true ;\n", -"OPTIM ?= -O0 ;\n", -"case UNIXWARE :\n", -"RANLIB ?= \"\" ;\n", -"RELOCATE ?= true ;\n", -"}\n", -"CCFLAGS ?= ;\n", -"C++FLAGS ?= $(CCFLAGS) ;\n", -"CHMOD ?= chmod ;\n", -"CHGRP ?= chgrp ;\n", -"CHOWN ?= chown ;\n", -"LEX ?= lex ;\n", -"LINKFLAGS ?= $(CCFLAGS) ;\n", -"LINKLIBS ?= ;\n", -"OPTIM ?= -O ;\n", -"RANLIB ?= ranlib ;\n", -"YACC ?= yacc ;\n", -"YACCFILES ?= y.tab ;\n", -"YACCFLAGS ?= -d ;\n", -"}\n", -"AR ?= ar ru ;\n", -"AS ?= as ;\n", -"ASFLAGS ?= ;\n", -"AWK ?= awk ;\n", -"BINDIR ?= /usr/local/bin ;\n", -"C++ ?= cc ;\n", -"C++FLAGS ?= ;\n", -"CC ?= cc ;\n", -"CCFLAGS ?= ;\n", -"CP ?= cp -f ;\n", -"CRELIB ?= ;\n", -"DOT ?= . ;\n", -"DOTDOT ?= .. ;\n", -"EXEMODE ?= 711 ;\n", -"FILEMODE ?= 644 ;\n", -"FORTRAN ?= f77 ;\n", -"FORTRANFLAGS ?= ;\n", -"HDRS ?= ;\n", -"INSTALLGRIST ?= installed ;\n", -"JAMFILE ?= Jamfile ;\n", -"JAMRULES ?= Jamrules ;\n", -"LEX ?= ;\n", -"LIBDIR ?= /usr/local/lib ;\n", -"LINK ?= $(CC) ;\n", -"LINKFLAGS ?= ;\n", -"LINKLIBS ?= ;\n", -"LN ?= ln ;\n", -"MANDIR ?= /usr/local/man ;\n", -"MKDIR ?= mkdir ;\n", -"MV ?= mv -f ;\n", -"OPTIM ?= ;\n", -"RCP ?= rcp ;\n", -"RM ?= rm -f ;\n", -"RSH ?= rsh ;\n", -"SED ?= sed ;\n", -"SHELLHEADER ?= \"#!/bin/sh\" ;\n", -"SHELLMODE ?= 755 ;\n", -"SLASH ?= / ;\n", -"STDHDRS ?= /usr/include ;\n", -"SUFEXE ?= \"\" ;\n", -"SUFLIB ?= .a ;\n", -"SUFOBJ ?= .o ;\n", -"UNDEFFLAG ?= \"-u _\" ;\n", -"YACC ?= ;\n", -"YACCFILES ?= ;\n", -"YACCFLAGS ?= ;\n", -"HDRPATTERN =\n", -"\"^[ ]*#[ ]*include[ ]*[<\\\"]([^\\\">]*)[\\\">].*$\" ;\n", -"OSFULL = $(OS)$(OSVER)$(OSPLAT) $(OS)$(OSPLAT) $(OS)$(OSVER) $(OS) ;\n", -"DEPENDS all : shell files lib exe obj ;\n", -"DEPENDS all shell files lib exe obj : first ;\n", -"NOTFILE all first shell files lib exe obj dirs clean uninstall ;\n", -"ALWAYS clean uninstall ;\n", -"rule As\n", -"{\n", -"DEPENDS $(<) : $(>) ;\n", -"ASFLAGS on $(<) += $(ASFLAGS) $(SUBDIRASFLAGS) ;\n", -"}\n", -"rule Bulk\n", -"{\n", -"local i ;\n", -"for i in $(>)\n", -"{\n", -"File $(i:D=$(<)) : $(i) ;\n", -"}\n", -"}\n", -"rule Cc\n", -"{\n", -"local _h ;\n", -"DEPENDS $(<) : $(>) ;\n", -"CCFLAGS on $(<) += $(CCFLAGS) $(SUBDIRCCFLAGS) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(VMS) && $(_h)\n", -"{\n", -"SLASHINC on $(<) = \"/inc=(\" \\\"$(_h[1])\\\" ,\\\"$(_h[2-])\\\" \")\" ;\n", -"}\n", -"else if $(MAC) && $(_h)\n", -"{\n", -"local _i _j ;\n", -"_j = $(_h[1]) ;\n", -"for _i in $(_h[2-])\n", -"{\n", -"_j = $(_j),$(_i) ;\n", -"}\n", -"MACINC on $(<) = \\\"$(_j)\\\" ;\n", -"}\n", -"}\n", -"rule C++\n", -"{\n", -"local _h ;\n", -"DEPENDS $(<) : $(>) ;\n", -"C++FLAGS on $(<) += $(C++FLAGS) $(SUBDIRC++FLAGS) ;\n", -"if $(RELOCATE)\n", -"{\n", -"CcMv $(<) : $(>) ;\n", -"}\n", -"_h = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(VMS) && $(_h)\n", -"{\n", -"SLASHINC on $(<) = \"/inc=(\" \\\"$(_h[1])\\\" ,\\\"$(_h[2-])\\\" \")\" ;\n", -"}\n", -"else if $(MAC) && $(_h)\n", -"{\n", -"local _i _j ;\n", -"_j = $(_h[1]) ;\n", -"for _i in $(_h[2-])\n", -"{\n", -"_j = $(_j),$(_i) ;\n", -"}\n", -"MACINC on $(<) = \\\"$(_j)\\\" ;\n", -"}\n", -"}\n", -"rule Chmod\n", -"{\n", -"if $(CHMOD) { Chmod1 $(<) ; }\n", -"}\n", -"rule File\n", -"{\n", -"DEPENDS files : $(<) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MODE on $(<) = $(FILEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule Fortran\n", -"{\n", -"DEPENDS $(<) : $(>) ;\n", -"}\n", -"rule GenFile\n", -"{\n", -"local _t = [ FGristSourceFiles $(<) ] ;\n", -"local _s = [ FAppendSuffix $(>[1]) : $(SUFEXE) ] ;\n", -"Depends $(_t) : $(_s) $(>[2-]) ;\n", -"GenFile1 $(_t) : $(_s) $(>[2-]) ;\n", -"Clean clean : $(_t) ;\n", -"}\n", -"rule GenFile1\n", -"{\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HardLink\n", -"{\n", -"DEPENDS files : $(<) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"}\n", -"rule HdrMacroFile\n", -"{\n", -"HDRMACRO $(<) ;\n", -"}\n", -"rule HdrRule\n", -"{\n", -"local s ;\n", -"if $(HDRGRIST)\n", -"{\n", -"s = $(>:G=$(HDRGRIST)) ;\n", -"} else {\n", -"s = $(>) ;\n", -"}\n", -"INCLUDES $(<) : $(s) ;\n", -"SEARCH on $(s) = $(HDRSEARCH) ;\n", -"NOCARE $(s) ;\n", -"HDRSEARCH on $(s) = $(HDRSEARCH) ;\n", -"HDRSCAN on $(s) = $(HDRSCAN) ;\n", -"HDRRULE on $(s) = $(HDRRULE) ;\n", -"HDRGRIST on $(s) = $(HDRGRIST) ;\n", -"}\n", -"rule InstallInto\n", -"{\n", -"local i t ;\n", -"t = $(>:G=$(INSTALLGRIST)) ;\n", -"Depends install : $(t) ;\n", -"Clean uninstall : $(t) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MakeLocate $(t) : $(<) ;\n", -"for i in $(>)\n", -"{\n", -"local tt = $(i:G=$(INSTALLGRIST)) ;\n", -"Depends $(tt) : $(i) ;\n", -"Install $(tt) : $(i) ;\n", -"Chmod $(tt) ;\n", -"if $(OWNER) && $(CHOWN)\n", -"{\n", -"Chown $(tt) ;\n", -"OWNER on $(tt) = $(OWNER) ;\n", -"}\n", -"if $(GROUP) && $(CHGRP)\n", -"{\n", -"Chgrp $(tt) ;\n", -"GROUP on $(tt) = $(GROUP) ;\n", -"}\n", -"}\n", -"}\n", -"rule InstallBin\n", -"{\n", -"local _t = [ FAppendSuffix $(>) : $(SUFEXE) ] ;\n", -"InstallInto $(<) : $(_t) ;\n", -"MODE on $(_t:G=installed) = $(EXEMODE) ;\n", -"}\n", -"rule InstallFile\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallLib\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallMan\n", -"{\n", -"local i s d ;\n", -"for i in $(>)\n", -"{\n", -"switch $(i:S)\n", -"{\n", -"case .1 : s = 1 ; case .2 : s = 2 ; case .3 : s = 3 ;\n", -"case .4 : s = 4 ; case .5 : s = 5 ; case .6 : s = 6 ;\n", -"case .7 : s = 7 ; case .8 : s = 8 ; case .l : s = l ;\n", -"case .n : s = n ; case .man : s = 1 ;\n", -"}\n", -"d = man$(s) ;\n", -"InstallInto $(d:R=$(<)) : $(i) ;\n", -"}\n", -"MODE on $(>:G=installed) = $(FILEMODE) ;\n", -"}\n", -"rule InstallShell\n", -"{\n", -"InstallInto $(<) : $(>) ;\n", -"MODE on $(>:G=installed) = $(SHELLMODE) ;\n", -"}\n", -"rule Lex\n", -"{\n", -"LexMv $(<) : $(>) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"MakeLocate $(<) : $(LOCATE_SOURCE) ;\n", -"Clean clean : $(<) ;\n", -"}\n", -"rule Library\n", -"{\n", -"LibraryFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule LibraryFromObjects\n", -"{\n", -"local _i _l _s ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_l = $(<:S=$(SUFLIB)) ;\n", -"if $(KEEPOBJS)\n", -"{\n", -"DEPENDS obj : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"DEPENDS lib : $(_l) ;\n", -"}\n", -"if ! $(_l:D)\n", -"{\n", -"MakeLocate $(_l) $(_l)($(_s:BS)) : $(LOCATE_TARGET) ;\n", -"}\n", -"if $(NOARSCAN)\n", -"{\n", -"DEPENDS $(_l) : $(_s) ;\n", -"}\n", -"else\n", -"{\n", -"DEPENDS $(_l) : $(_l)($(_s:BS)) ;\n", -"for _i in $(_s)\n", -"{\n", -"DEPENDS $(_l)($(_i:BS)) : $(_i) ;\n", -"}\n", -"}\n", -"Clean clean : $(_l) ;\n", -"if $(CRELIB) { CreLib $(_l) : $(_s[1]) ; }\n", -"Archive $(_l) : $(_s) ;\n", -"if $(RANLIB) { Ranlib $(_l) ; }\n", -"if ! ( $(NOARSCAN) || $(KEEPOBJS) ) { RmTemps $(_l) : $(_s) ; }\n", -"}\n", -"rule Link\n", -"{\n", -"MODE on $(<) = $(EXEMODE) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule LinkLibraries\n", -"{\n", -"local _t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"DEPENDS $(_t) : $(>:S=$(SUFLIB)) ;\n", -"NEEDLIBS on $(_t) += $(>:S=$(SUFLIB)) ;\n", -"}\n", -"rule Main\n", -"{\n", -"MainFromObjects $(<) : $(>:S=$(SUFOBJ)) ;\n", -"Objects $(>) ;\n", -"}\n", -"rule MainFromObjects\n", -"{\n", -"local _s _t ;\n", -"_s = [ FGristFiles $(>) ] ;\n", -"_t = [ FAppendSuffix $(<) : $(SUFEXE) ] ;\n", -"if $(_t) != $(<)\n", -"{\n", -"DEPENDS $(<) : $(_t) ;\n", -"NOTFILE $(<) ;\n", -"}\n", -"DEPENDS exe : $(_t) ;\n", -"DEPENDS $(_t) : $(_s) ;\n", -"MakeLocate $(_t) : $(LOCATE_TARGET) ;\n", -"Clean clean : $(_t) ;\n", -"Link $(_t) : $(_s) ;\n", -"}\n", -"rule MakeLocate\n", -"{\n", -"if $(>)\n", -"{\n", -"LOCATE on $(<) = $(>) ;\n", -"Depends $(<) : $(>[1]) ;\n", -"MkDir $(>[1]) ;\n", -"}\n", -"}\n", -"rule MkDir\n", -"{\n", -"NOUPDATE $(<) ;\n", -"if $(<) != $(DOT) && ! $($(<)-mkdir)\n", -"{\n", -"local s ;\n", -"$(<)-mkdir = true ;\n", -"MkDir1 $(<) ;\n", -"Depends dirs : $(<) ;\n", -"s = $(<:P) ;\n", -"if $(NT)\n", -"{\n", -"switch $(s)\n", -"{\n", -"case *: : s = ;\n", -"case *:\\\\ : s = ;\n", -"}\n", -"}\n", -"if $(s) && $(s) != $(<)\n", -"{\n", -"Depends $(<) : $(s) ;\n", -"MkDir $(s) ;\n", -"}\n", -"else if $(s)\n", -"{\n", -"NOTFILE $(s) ;\n", -"}\n", -"}\n", -"}\n", -"rule Object\n", -"{\n", -"local h ;\n", -"Clean clean : $(<) ;\n", -"MakeLocate $(<) : $(LOCATE_TARGET) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"HDRS on $(<) = $(SEARCH_SOURCE) $(HDRS) $(SUBDIRHDRS) ;\n", -"if $(SEARCH_SOURCE)\n", -"{\n", -"h = $(SEARCH_SOURCE) ;\n", -"}\n", -"else\n", -"{\n", -"h = \"\" ;\n", -"}\n", -"HDRRULE on $(>) = HdrRule ;\n", -"HDRSCAN on $(>) = $(HDRPATTERN) ;\n", -"HDRSEARCH on $(>) = $(HDRS) $(SUBDIRHDRS) $(h) $(STDHDRS) ;\n", -"HDRGRIST on $(>) = $(HDRGRIST) ;\n", -"switch $(>:S)\n", -"{\n", -"case .asm : As $(<) : $(>) ;\n", -"case .c : Cc $(<) : $(>) ;\n", -"case .C : C++ $(<) : $(>) ;\n", -"case .cc : C++ $(<) : $(>) ;\n", -"case .cpp : C++ $(<) : $(>) ;\n", -"case .f : Fortran $(<) : $(>) ;\n", -"case .l : Cc $(<) : $(<:S=.c) ;\n", -"Lex $(<:S=.c) : $(>) ;\n", -"case .s : As $(<) : $(>) ;\n", -"case .y : Cc $(<) : $(<:S=.c) ;\n", -"Yacc $(<:S=.c) : $(>) ;\n", -"case * : UserObject $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule ObjectCcFlags\n", -"{\n", -"CCFLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectC++Flags\n", -"{\n", -"C++FLAGS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule ObjectHdrs\n", -"{\n", -"HDRS on [ FGristFiles $(<:S=$(SUFOBJ)) ] += $(>) ;\n", -"}\n", -"rule Objects\n", -"{\n", -"local _i ;\n", -"for _i in [ FGristFiles $(<) ]\n", -"{\n", -"Object $(_i:S=$(SUFOBJ)) : $(_i) ;\n", -"DEPENDS obj : $(_i:S=$(SUFOBJ)) ;\n", -"}\n", -"}\n", -"rule RmTemps\n", -"{\n", -"TEMPORARY $(>) ;\n", -"}\n", -"rule Setuid\n", -"{\n", -"MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;\n", -"}\n", -"rule Shell\n", -"{\n", -"DEPENDS shell : $(<) ;\n", -"DEPENDS $(<) : $(>) ;\n", -"SEARCH on $(>) = $(SEARCH_SOURCE) ;\n", -"MODE on $(<) = $(SHELLMODE) ;\n", -"Clean clean : $(<) ;\n", -"Chmod $(<) ;\n", -"}\n", -"rule SubDir\n", -"{\n", -"local _r _s ;\n", -"if ! $($(<[1]))\n", -"{\n", -"if ! $(<[1])\n", -"{\n", -"EXIT SubDir syntax error ;\n", -"}\n", -"$(<[1]) = [ FSubDir $(<[2-]) ] ;\n", -"}\n", -"if ! $($(<[1])-included)\n", -"{\n", -"$(<[1])-included = TRUE ;\n", -"_r = $($(<[1])RULES) ;\n", -"if ! $(_r)\n", -"{\n", -"_r = $(JAMRULES:R=$($(<[1]))) ;\n", -"}\n", -"include $(_r) ;\n", -"}\n", -"_s = [ FDirName $(<[2-]) ] ;\n", -"SUBDIR = $(_s:R=$($(<[1]))) ;\n", -"SUBDIR_TOKENS = $(<[2-]) ;\n", -"SEARCH_SOURCE = $(SUBDIR) ;\n", -"LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;\n", -"SOURCE_GRIST = [ FGrist $(<[2-]) ] ;\n", -"SUBDIRCCFLAGS = ;\n", -"SUBDIRC++FLAGS = ;\n", -"SUBDIRHDRS = ;\n", -"}\n", -"rule SubDirCcFlags\n", -"{\n", -"SUBDIRCCFLAGS += $(<) ;\n", -"}\n", -"rule SubDirC++Flags\n", -"{\n", -"SUBDIRC++FLAGS += $(<) ;\n", -"}\n", -"rule SubDirHdrs\n", -"{\n", -"SUBDIRHDRS += $(<) ;\n", -"}\n", -"rule SubInclude\n", -"{\n", -"local _s ;\n", -"if ! $($(<[1]))\n", -"{\n", -"EXIT Top level of source tree has not been set with $(<[1]) ;\n", -"}\n", -"_s = [ FDirName $(<[2-]) ] ;\n", -"include $(JAMFILE:D=$(_s):R=$($(<[1]))) ;\n", -"}\n", -"rule Undefines\n", -"{\n", -"UNDEFS on [ FAppendSuffix $(<) : $(SUFEXE) ] += $(UNDEFFLAG)$(>) ;\n", -"}\n", -"rule UserObject\n", -"{\n", -"EXIT \"Unknown suffix on\" $(>) \"- see UserObject rule in Jamfile(5).\" ;\n", -"}\n", -"rule Yacc\n", -"{\n", -"local _h ;\n", -"_h = $(<:BS=.h) ;\n", -"MakeLocate $(<) $(_h) : $(LOCATE_SOURCE) ;\n", -"if $(YACC)\n", -"{\n", -"DEPENDS $(<) $(_h) : $(>) ;\n", -"Yacc1 $(<) $(_h) : $(>) ;\n", -"YaccMv $(<) $(_h) : $(>) ;\n", -"Clean clean : $(<) $(_h) ;\n", -"}\n", -"INCLUDES $(<) : $(_h) ;\n", -"}\n", -"rule FGrist\n", -"{\n", -"local _g _i ;\n", -"_g = $(<[1]) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_g = $(_g)!$(_i) ;\n", -"}\n", -"return $(_g) ;\n", -"}\n", -"rule FGristFiles\n", -"{\n", -"if ! $(SOURCE_GRIST)\n", -"{\n", -"return $(<) ;\n", -"}\n", -"else\n", -"{\n", -"return $(<:G=$(SOURCE_GRIST)) ;\n", -"}\n", -"}\n", -"rule FGristSourceFiles\n", -"{\n", -"if ! $(SOURCE_GRIST)\n", -"{\n", -"return $(<) ;\n", -"}\n", -"else\n", -"{\n", -"local _i _o ;\n", -"for _i in $(<)\n", -"{\n", -"switch $(_i)\n", -"{\n", -"case *.h : _o += $(_i) ;\n", -"case * : _o += $(_i:G=$(SOURCE_GRIST)) ;\n", -"}\n", -"}\n", -"return $(_o) ;\n", -"}\n", -"}\n", -"rule FConcat\n", -"{\n", -"local _t _r ;\n", -"$(_r) = $(<[1]) ;\n", -"for _t in $(<[2-])\n", -"{\n", -"$(_r) = $(_r)$(_t) ;\n", -"}\n", -"return $(_r) ;\n", -"}\n", -"rule FSubDir\n", -"{\n", -"local _i _d ;\n", -"if ! $(<[1])\n", -"{\n", -"_d = $(DOT) ;\n", -"}\n", -"else\n", -"{\n", -"_d = $(DOTDOT) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_d = $(_d:R=$(DOTDOT)) ;\n", -"}\n", -"}\n", -"return $(_d) ;\n", -"}\n", -"rule FDirName\n", -"{\n", -"local _s _i ;\n", -"if ! $(<)\n", -"{\n", -"_s = $(DOT) ;\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"_s = $(DOT) ;\n", -"for _i in $(<)\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"else\n", -"{\n", -"_s = $(<[1]) ;\n", -"for _i in $(<[2-])\n", -"{\n", -"_s = $(_i:R=$(_s)) ;\n", -"}\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"rule _makeCommon\n", -"{\n", -"if $($(<)[1]) && $($(<)[1]) = $($(>)[1])\n", -"{\n", -"$(<) = $($(<)[2-]) ;\n", -"$(>) = $($(>)[2-]) ;\n", -"_makeCommon $(<) : $(>) ;\n", -"}\n", -"}\n", -"rule FRelPath\n", -"{\n", -"local _l _r ;\n", -"_l = $(<) ;\n", -"_r = $(>) ;\n", -"_makeCommon _l : _r ;\n", -"_l = [ FSubDir $(_l) ] ;\n", -"_r = [ FDirName $(_r) ] ;\n", -"if $(_r) = $(DOT) {\n", -"return $(_l) ;\n", -"} else {\n", -"return $(_r:R=$(_l)) ;\n", -"}\n", -"}\n", -"rule FAppendSuffix\n", -"{\n", -"if $(>)\n", -"{\n", -"local _i _o ;\n", -"for _i in $(<)\n", -"{\n", -"if $(_i:S)\n", -"{\n", -"_o += $(_i) ;\n", -"}\n", -"else\n", -"{\n", -"_o += $(_i:S=$(>)) ;\n", -"}\n", -"}\n", -"return $(_o) ;\n", -"}\n", -"else\n", -"{\n", -"return $(<) ;\n", -"}\n", -"}\n", -"rule unmakeDir\n", -"{\n", -"if $(>[1]:D) && $(>[1]:D) != $(>[1]) && $(>[1]:D) != \\\\\\\\\n", -"{\n", -"unmakeDir $(<) : $(>[1]:D) $(>[1]:BS) $(>[2-]) ;\n", -"}\n", -"else\n", -"{\n", -"$(<) = $(>) ;\n", -"}\n", -"}\n", -"rule FConvertToSlashes\n", -"{\n", -"local _d, _s, _i ;\n", -"unmakeDir _d : $(<) ;\n", -"_s = $(_d[1]) ;\n", -"for _i in $(_d[2-])\n", -"{\n", -"_s = $(_s)/$(_i) ;\n", -"}\n", -"return $(_s) ;\n", -"}\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) $(ASFLAGS) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o $(<) $(>)\n", -"}\n", -"actions Chgrp\n", -"{\n", -"$(CHGRP) $(GROUP) $(<)\n", -"}\n", -"actions Chmod1\n", -"{\n", -"$(CHMOD) $(MODE) $(<)\n", -"}\n", -"actions Chown\n", -"{\n", -"$(CHOWN) $(OWNER) $(<)\n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions File\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"$(>[1]) $(<) $(>[2-])\n", -"}\n", -"actions Fortran\n", -"{\n", -"$(FORTRAN) $(FORTRANFLAGS) -o $(<) $(>)\n", -"}\n", -"actions HardLink\n", -"{\n", -"$(RM) $(<) && $(LN) $(>) $(<)\n", -"}\n", -"actions Install\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"actions Lex\n", -"{\n", -"$(LEX) $(>)\n", -"}\n", -"actions LexMv\n", -"{\n", -"$(MV) lex.yy.c $(<)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions MkDir1\n", -"{\n", -"$(MKDIR) $(<)\n", -"}\n", -"actions together Ranlib\n", -"{\n", -"$(RANLIB) $(<)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(AWK) '\n", -"NR == 1 { print \"$(SHELLHEADER)\" }\n", -"NR == 1 && /^[#:]/ { next }\n", -"/^##/ { next }\n", -"{ print }\n", -"' < $(>) > $(<)\n", -"}\n", -"actions Yacc1\n", -"{\n", -"$(YACC) $(YACCFLAGS) $(>)\n", -"}\n", -"actions YaccMv\n", -"{\n", -"$(MV) $(YACCFILES).c $(<[1])\n", -"$(MV) $(YACCFILES).h $(<[2])\n", -"}\n", -"if $(RELOCATE)\n", -"{\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) $(>)\n", -"}\n", -"actions ignore CcMv\n", -"{\n", -"[ $(<) != $(>:BS=$(SUFOBJ)) ] && $(MV) $(>:BS=$(SUFOBJ)) $(<)\n", -"}\n", -"}\n", -"if $(NOARUPDATE)\n", -"{\n", -"actions Archive\n", -"{\n", -"$(AR) $(<) $(>)\n", -"}\n", -"}\n", -"if $(NT)\n", -"{\n", -"if $(TOOLSET) = VISUALC || $(TOOLSET) = VC7 || $(TOOLSET) = INTELC\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"if exist $(<) set _$(<:B)_=$(<)\n", -"$(AR) /out:$(<) %_$(<:B)_% $(>)\n", -"}\n", -"actions As\n", -"{\n", -"$(AS) /Ml /p /v /w2 $(>) $(<) ,nul,nul;\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /I$(STDHDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = VISUALC16\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) /c $(CCFLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) /c $(C++FLAGS) $(OPTIM) /Fo$(<) /I$(HDRS) /Tp$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /out:$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = BORLANDC\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"$(AR) $(<) -+$(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -e$(<) $(LINKFLAGS) $(UNDEFS) -L$(LINKLIBS) $(NEEDLIBS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = MINGW\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>:T)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = WATCOM\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) +-$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = LCC\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) /out:$(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) -Fo$(<) -I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) -o $(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"}\n", -"else if $(OS2)\n", -"{\n", -"if $(TOOLSET) = WATCOM\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) +-$(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) $(CCFLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) $(C++FLAGS) $(OPTIM) /Fo=$(<) /I$(HDRS) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) $(LINKFLAGS) /Fe=$(<) $(UNDEFS) $(>) $(NEEDLIBS) $(LINKLIBS)\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>) $(<)\n", -"}\n", -"}\n", -"else if $(TOOLSET) = EMX\n", -"{\n", -"actions together piecemeal Archive\n", -"{\n", -"$(AR) $(<) $(>:T)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC) -c $(CCFLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++) -c $(C++FLAGS) $(OPTIM) -I$(HDRS) -o$(<) $(>)\n", -"}\n", -"}\n", -"}\n", -"else if $(VMS)\n", -"{\n", -"actions updated together piecemeal Archive\n", -"{\n", -"lib/replace $(<:W) $(>[1]:W) ,$(>[2-]:W)\n", -"}\n", -"actions Cc\n", -"{\n", -"$(CC)/obj=$(<:W) $(CCFLAGS) $(OPTIM) $(SLASHINC) $(>:W)\n", -"}\n", -"actions C++\n", -"{\n", -"$(C++)/obj=$(<:W) $(C++FLAGS) $(OPTIM) $(SLASHINC) $(>:W)\n", -"}\n", -"actions piecemeal together existing Clean\n", -"{\n", -"$(RM) $(>[1]:W);* ,$(>[2-]:W);*\n", -"}\n", -"actions together quietly CreLib\n", -"{\n", -"if f$search(\"$(<:W)\") .eqs. \"\" then lib/create $(<:W)\n", -"}\n", -"actions GenFile1\n", -"{\n", -"mcr $(>[1]:W) $(<:W) $(>[2-]:W)\n", -"}\n", -"actions MkDir1\n", -"{\n", -"$(MKDIR) $(<:W)\n", -"}\n", -"actions Yacc1\n", -"{\n", -"$(YACC) $(YACCFLAGS) $(>:W)\n", -"}\n", -"actions YaccMv\n", -"{\n", -"$(MV) $(YACCFILES).c $(<[1]:W)\n", -"$(MV) $(YACCFILES).h $(<[2]:W)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK)/exe=$(<:W) $(LINKFLAGS) $(>[1]:W) ,$(>[2-]:W) ,$(NEEDLIBS:W)/lib ,$(LINKLIBS:W)\n", -"}\n", -"actions quietly updated piecemeal together RmTemps\n", -"{\n", -"$(RM) $(>[1]:W);* ,$(>[2-]:W);*\n", -"}\n", -"actions Shell\n", -"{\n", -"$(CP) $(>:W) $(<:W)\n", -"}\n", -"}\n", -"else if $(MAC)\n", -"{\n", -"actions together Archive\n", -"{\n", -"$(LINK) -library -o $(<) $(>)\n", -"}\n", -"actions Cc\n", -"{\n", -"set -e MWCincludes $(MACINC)\n", -"$(CC) -o $(<) $(CCFLAGS) $(OPTIM) $(>)\n", -"}\n", -"actions C++\n", -"{\n", -"set -e MWCincludes $(MACINC)\n", -"$(CC) -o $(<) $(C++FLAGS) $(OPTIM) $(>)\n", -"}\n", -"actions Link bind NEEDLIBS\n", -"{\n", -"$(LINK) -o $(<) $(LINKFLAGS) $(>) $(NEEDLIBS) \"$(LINKLIBS)\"\n", -"}\n", -"}\n", -"rule BULK { Bulk $(<) : $(>) ; }\n", -"rule FILE { File $(<) : $(>) ; }\n", -"rule HDRRULE { HdrRule $(<) : $(>) ; }\n", -"rule INSTALL { Install $(<) : $(>) ; }\n", -"rule LIBRARY { Library $(<) : $(>) ; }\n", -"rule LIBS { LinkLibraries $(<) : $(>) ; }\n", -"rule LINK { Link $(<) : $(>) ; }\n", -"rule MAIN { Main $(<) : $(>) ; }\n", -"rule SETUID { Setuid $(<) ; }\n", -"rule SHELL { Shell $(<) : $(>) ; }\n", -"rule UNDEFINES { Undefines $(<) : $(>) ; }\n", -"rule INSTALLBIN { InstallBin $(BINDIR) : $(<) ; }\n", -"rule INSTALLLIB { InstallLib $(LIBDIR) : $(<) ; }\n", -"rule INSTALLMAN { InstallMan $(MANDIR) : $(<) ; }\n", -"rule addDirName { $(<) += [ FDirName $(>) ] ; }\n", -"rule makeDirName { $(<) = [ FDirName $(>) ] ; }\n", -"rule makeGristedName { $(<) = [ FGristSourceFiles $(>) ] ; }\n", -"rule makeRelPath { $(<[1]) = [ FRelPath $(<[2-]) : $(>) ] ; }\n", -"rule makeSuffixed { $(<[1]) = [ FAppendSuffix $(>) : $(<[2]) ] ; }\n", -"{\n", -"if $(JAMFILE) { include $(JAMFILE) ; }\n", -"}\n", -"}\n", 0 }; diff --git a/tools/build/src/engine/jamgram.c b/tools/build/src/engine/jamgram.c index 916b08d3ea..5afa73e9c1 100644 --- a/tools/build/src/engine/jamgram.c +++ b/tools/build/src/engine/jamgram.c @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 2.6.4. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison implementation for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ @@ -44,7 +44,7 @@ #define YYBISON 1 /* Bison version. */ -#define YYBISON_VERSION "2.6.4" +#define YYBISON_VERSION "3.0.4" /* Skeleton name. */ #define YYSKELETON_NAME "yacc.c" @@ -62,8 +62,7 @@ /* Copy the first part of user declarations. */ -/* Line 358 of yacc.c */ -#line 98 "jamgram.y" +#line 98 "jamgram.y" /* yacc.c:339 */ #include "jam.h" @@ -107,14 +106,13 @@ # define psnode( s,l ) parse_make( F0,l,P0,P0,s,S0,0 ) -/* Line 358 of yacc.c */ -#line 112 "y.tab.c" +#line 110 "y.tab.c" /* yacc.c:339 */ -# ifndef YY_NULL +# ifndef YY_NULLPTR # if defined __cplusplus && 201103L <= __cplusplus -# define YY_NULL nullptr +# define YY_NULLPTR nullptr # else -# define YY_NULL 0 +# define YY_NULLPTR 0 # endif # endif @@ -130,69 +128,68 @@ by #include "y.tab.h". */ #ifndef YY_YY_Y_TAB_H_INCLUDED # define YY_YY_Y_TAB_H_INCLUDED -/* Enabling traces. */ +/* Debug traces. */ #ifndef YYDEBUG -# define YYDEBUG 1 +# define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif -/* Tokens. */ +/* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - _BANG_t = 258, - _BANG_EQUALS_t = 259, - _AMPER_t = 260, - _AMPERAMPER_t = 261, - _LPAREN_t = 262, - _RPAREN_t = 263, - _PLUS_EQUALS_t = 264, - _COLON_t = 265, - _SEMIC_t = 266, - _LANGLE_t = 267, - _LANGLE_EQUALS_t = 268, - _EQUALS_t = 269, - _RANGLE_t = 270, - _RANGLE_EQUALS_t = 271, - _QUESTION_EQUALS_t = 272, - _LBRACKET_t = 273, - _RBRACKET_t = 274, - ACTIONS_t = 275, - BIND_t = 276, - BREAK_t = 277, - CASE_t = 278, - CLASS_t = 279, - CONTINUE_t = 280, - DEFAULT_t = 281, - ELSE_t = 282, - EXISTING_t = 283, - FOR_t = 284, - IF_t = 285, - IGNORE_t = 286, - IN_t = 287, - INCLUDE_t = 288, - LOCAL_t = 289, - MODULE_t = 290, - ON_t = 291, - PIECEMEAL_t = 292, - QUIETLY_t = 293, - RETURN_t = 294, - RULE_t = 295, - SWITCH_t = 296, - TOGETHER_t = 297, - UPDATED_t = 298, - WHILE_t = 299, - _LBRACE_t = 300, - _BAR_t = 301, - _BARBAR_t = 302, - _RBRACE_t = 303, - ARG = 304, - STRING = 305 - }; + enum yytokentype + { + _BANG_t = 258, + _BANG_EQUALS_t = 259, + _AMPER_t = 260, + _AMPERAMPER_t = 261, + _LPAREN_t = 262, + _RPAREN_t = 263, + _PLUS_EQUALS_t = 264, + _COLON_t = 265, + _SEMIC_t = 266, + _LANGLE_t = 267, + _LANGLE_EQUALS_t = 268, + _EQUALS_t = 269, + _RANGLE_t = 270, + _RANGLE_EQUALS_t = 271, + _QUESTION_EQUALS_t = 272, + _LBRACKET_t = 273, + _RBRACKET_t = 274, + ACTIONS_t = 275, + BIND_t = 276, + BREAK_t = 277, + CASE_t = 278, + CLASS_t = 279, + CONTINUE_t = 280, + DEFAULT_t = 281, + ELSE_t = 282, + EXISTING_t = 283, + FOR_t = 284, + IF_t = 285, + IGNORE_t = 286, + IN_t = 287, + INCLUDE_t = 288, + LOCAL_t = 289, + MODULE_t = 290, + ON_t = 291, + PIECEMEAL_t = 292, + QUIETLY_t = 293, + RETURN_t = 294, + RULE_t = 295, + SWITCH_t = 296, + TOGETHER_t = 297, + UPDATED_t = 298, + WHILE_t = 299, + _LBRACE_t = 300, + _BAR_t = 301, + _BARBAR_t = 302, + _RBRACE_t = 303, + ARG = 304, + STRING = 305 + }; #endif /* Tokens. */ #define _BANG_t 258 @@ -244,37 +241,23 @@ extern int yydebug; #define ARG 304 #define STRING 305 - - +/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif + extern YYSTYPE yylval; -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ #endif /* !YY_YY_Y_TAB_H_INCLUDED */ /* Copy the second part of user declarations. */ -/* Line 377 of yacc.c */ -#line 278 "y.tab.c" +#line 261 "y.tab.c" /* yacc.c:358 */ #ifdef short # undef short @@ -288,11 +271,8 @@ typedef unsigned char yytype_uint8; #ifdef YYTYPE_INT8 typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; #else -typedef short int yytype_int8; +typedef signed char yytype_int8; #endif #ifdef YYTYPE_UINT16 @@ -312,8 +292,7 @@ typedef short int yytype_int16; # define YYSIZE_T __SIZE_TYPE__ # elif defined size_t # define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# elif ! defined YYSIZE_T # include /* INFRINGES ON USER NAME SPACE */ # define YYSIZE_T size_t # else @@ -335,6 +314,33 @@ typedef short int yytype_int16; # endif #endif +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + /* Suppress unused-variable warnings by "using" E. */ #if ! defined lint || defined __GNUC__ # define YYUSE(E) ((void) (E)) @@ -342,24 +348,26 @@ typedef short int yytype_int16; # define YYUSE(E) /* empty */ #endif -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(N) (N) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int yyi) +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") #else -static int -YYID (yyi) - int yyi; +# define YY_INITIAL_VALUE(Value) Value #endif -{ - return yyi; -} +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ #endif + #if ! defined yyoverflow || YYERROR_VERBOSE /* The parser invokes alloca or malloc; define the necessary symbols. */ @@ -377,8 +385,7 @@ YYID (yyi) # define alloca _alloca # else # define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS # include /* INFRINGES ON USER NAME SPACE */ /* Use EXIT_SUCCESS as a witness for stdlib.h. */ # ifndef EXIT_SUCCESS @@ -390,8 +397,8 @@ YYID (yyi) # endif # ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) # ifndef YYSTACK_ALLOC_MAXIMUM /* The OS might guarantee only one guard page at the bottom of the stack, and a page size can be as small as 4096 bytes. So we cannot safely @@ -407,7 +414,7 @@ YYID (yyi) # endif # if (defined __cplusplus && ! defined EXIT_SUCCESS \ && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) + && (defined YYFREE || defined free))) # include /* INFRINGES ON USER NAME SPACE */ # ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 @@ -415,15 +422,13 @@ YYID (yyi) # endif # ifndef YYMALLOC # define YYMALLOC malloc -# if ! defined malloc && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined malloc && ! defined EXIT_SUCCESS void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ # endif # endif # ifndef YYFREE # define YYFREE free -# if ! defined free && ! defined EXIT_SUCCESS && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) +# if ! defined free && ! defined EXIT_SUCCESS void free (void *); /* INFRINGES ON USER NAME SPACE */ # endif # endif @@ -433,7 +438,7 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */ #if (! defined yyoverflow \ && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) /* A type that is properly aligned for any stack member. */ union yyalloc @@ -458,16 +463,16 @@ union yyalloc elements in the stack, and YYPTR gives the new location of the stack. Advance YYPTR to a properly aligned location for the next stack. */ -# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ - Stack = &yyptr->Stack_alloc; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) #endif @@ -486,33 +491,35 @@ union yyalloc for (yyi = 0; yyi < (Count); yyi++) \ (Dst)[yyi] = (Src)[yyi]; \ } \ - while (YYID (0)) + while (0) # endif # endif #endif /* !YYCOPY_NEEDED */ /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 47 +#define YYFINAL 42 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 238 +#define YYLAST 242 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 51 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 24 +#define YYNNTS 68 /* YYNRULES -- Number of rules. */ -#define YYNRULES 77 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 163 +#define YYNRULES 121 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 207 -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 #define YYMAXUTOK 305 -#define YYTRANSLATE(YYX) \ +#define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ static const yytype_uint8 yytranslate[] = { 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -549,63 +556,22 @@ static const yytype_uint8 yytranslate[] = }; #if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 6, 8, 10, 12, 15, 21, - 22, 25, 27, 31, 32, 34, 35, 39, 43, 47, - 52, 59, 63, 66, 69, 78, 84, 90, 96, 102, - 108, 116, 122, 126, 127, 128, 138, 140, 142, 144, - 147, 149, 153, 157, 161, 165, 169, 173, 177, 181, - 185, 189, 193, 196, 200, 201, 204, 209, 211, 215, - 217, 218, 221, 223, 224, 229, 232, 237, 242, 243, - 246, 248, 250, 252, 254, 256, 258, 259 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int8 yyrhs[] = -{ - 52, 0, -1, -1, 54, -1, 55, -1, 54, -1, - 59, -1, 59, 54, -1, 34, 67, 56, 11, 53, - -1, -1, 14, 67, -1, 55, -1, 7, 66, 8, - -1, -1, 34, -1, -1, 45, 53, 48, -1, 33, - 67, 11, -1, 49, 66, 11, -1, 69, 62, 67, - 11, -1, 69, 36, 67, 62, 67, 11, -1, 39, - 67, 11, -1, 22, 11, -1, 25, 11, -1, 29, - 58, 49, 32, 67, 45, 53, 48, -1, 41, 67, - 45, 64, 48, -1, 30, 63, 45, 53, 48, -1, - 35, 67, 45, 53, 48, -1, 24, 66, 45, 53, - 48, -1, 44, 63, 45, 53, 48, -1, 30, 63, - 45, 53, 48, 27, 59, -1, 58, 40, 49, 57, - 59, -1, 36, 69, 59, -1, -1, -1, 20, 72, - 49, 74, 45, 60, 50, 61, 48, -1, 14, -1, - 9, -1, 17, -1, 26, 14, -1, 69, -1, 63, - 14, 63, -1, 63, 4, 63, -1, 63, 12, 63, - -1, 63, 13, 63, -1, 63, 15, 63, -1, 63, - 16, 63, -1, 63, 5, 63, -1, 63, 6, 63, - -1, 63, 46, 63, -1, 63, 47, 63, -1, 69, - 32, 67, -1, 3, 63, -1, 7, 63, 8, -1, - -1, 65, 64, -1, 23, 49, 10, 53, -1, 67, - -1, 67, 10, 66, -1, 68, -1, -1, 68, 69, - -1, 49, -1, -1, 18, 70, 71, 19, -1, 49, - 66, -1, 36, 69, 49, 66, -1, 36, 69, 39, - 67, -1, -1, 72, 73, -1, 43, -1, 42, -1, - 31, -1, 38, -1, 37, -1, 28, -1, -1, 21, - 67, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 144, 144, 146, 157, 159, 163, 165, 167, 172, - 175, 177, 181, 184, 187, 190, 193, 195, 197, 199, - 201, 203, 205, 207, 209, 211, 213, 215, 217, 219, - 221, 223, 225, 228, 230, 227, 239, 241, 243, 245, - 252, 254, 256, 258, 260, 262, 264, 266, 268, 270, - 272, 274, 276, 278, 290, 291, 295, 304, 306, 316, - 321, 322, 326, 328, 328, 337, 339, 341, 352, 353, - 357, 359, 361, 363, 365, 367, 377, 378 + 0, 144, 144, 146, 157, 159, 163, 165, 167, 167, + 167, 172, 175, 175, 177, 181, 184, 187, 190, 193, + 196, 198, 200, 200, 202, 202, 204, 204, 206, 206, + 206, 208, 208, 210, 212, 214, 214, 214, 216, 216, + 216, 218, 218, 218, 220, 220, 220, 222, 222, 222, + 224, 224, 224, 226, 226, 226, 226, 228, 231, 233, + 230, 242, 244, 246, 248, 255, 257, 257, 259, 259, + 261, 261, 263, 263, 265, 265, 267, 267, 269, 269, + 271, 271, 273, 273, 275, 275, 277, 277, 279, 279, + 281, 281, 293, 294, 298, 298, 298, 307, 309, 319, + 324, 325, 329, 331, 331, 340, 340, 342, 342, 344, + 344, 355, 356, 360, 362, 364, 366, 368, 370, 380, + 381, 381 }; #endif @@ -623,16 +589,21 @@ static const char *const yytname[] = "INCLUDE_t", "LOCAL_t", "MODULE_t", "ON_t", "PIECEMEAL_t", "QUIETLY_t", "RETURN_t", "RULE_t", "SWITCH_t", "TOGETHER_t", "UPDATED_t", "WHILE_t", "_LBRACE_t", "_BAR_t", "_BARBAR_t", "_RBRACE_t", "ARG", "STRING", - "$accept", "run", "block", "rules", "null", "assign_list_opt", - "arglist_opt", "local_opt", "rule", "$@1", "$@2", "assign", "expr", - "cases", "case", "lol", "list", "listp", "arg", "$@3", "func", "eflags", - "eflag", "bindlist", YY_NULL + "$accept", "run", "block", "rules", "$@1", "$@2", "null", + "assign_list_opt", "$@3", "arglist_opt", "local_opt", "else_opt", "rule", + "$@4", "$@5", "$@6", "$@7", "$@8", "$@9", "$@10", "$@11", "$@12", "$@13", + "$@14", "$@15", "$@16", "$@17", "$@18", "$@19", "$@20", "$@21", "$@22", + "$@23", "$@24", "$@25", "$@26", "assign", "expr", "$@27", "$@28", "$@29", + "$@30", "$@31", "$@32", "$@33", "$@34", "$@35", "$@36", "$@37", "$@38", + "$@39", "cases", "case", "$@40", "$@41", "lol", "list", "listp", "arg", + "@42", "func", "$@43", "$@44", "$@45", "eflags", "eflag", "bindlist", + "$@46", YY_NULLPTR }; #endif # ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, @@ -644,209 +615,229 @@ static const yytype_uint16 yytoknum[] = }; # endif -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint8 yyr1[] = +#define YYPACT_NINF -119 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-119))) + +#define YYTABLE_NINF -25 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = { - 0, 51, 52, 52, 53, 53, 54, 54, 54, 55, - 56, 56, 57, 57, 58, 58, 59, 59, 59, 59, - 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, - 59, 59, 59, 60, 61, 59, 62, 62, 62, 62, - 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 64, 64, 65, 66, 66, 67, - 68, 68, 69, 70, 69, 71, 71, 71, 72, 72, - 73, 73, 73, 73, 73, 73, 74, 74 + 140, -119, -119, 1, -119, 2, -18, -119, -119, -23, + -119, -9, -119, -119, -119, 140, 12, 31, -119, 4, + 140, 77, -17, 186, -119, -119, -119, -119, -7, 3, + -119, -119, -119, -119, 177, -119, -119, 3, -5, -119, + -119, -119, -119, -119, -119, -119, -119, -119, 33, -119, + -119, -9, -119, 29, -119, -119, -119, -119, -119, -119, + 35, -119, 14, 50, -9, 34, -119, -119, 23, 39, + 52, 53, 40, -119, 66, 45, 94, -119, 67, 30, + -119, -119, -119, 16, -119, -119, -119, 47, -119, -119, + -119, -119, 3, 3, -119, -119, -119, -119, -119, -119, + -119, -119, -119, -119, -119, -119, -119, -119, -119, 84, + -119, -119, -119, 51, -119, -119, 32, 105, -119, -119, + -119, -119, -119, 140, -119, -119, -119, 68, 3, 3, + 3, 3, 3, 3, 3, 3, 140, 3, 3, -119, + -119, -119, 140, 95, 140, 110, -119, -119, -119, -119, + -119, 69, 73, 87, -119, 89, 139, 139, -119, -119, + 89, -119, -119, 90, 226, 226, -119, -119, 140, 91, + -119, 97, 95, 98, -119, -119, -119, -119, -119, -119, + -119, -119, 108, -119, -119, 88, -119, -119, -119, 141, + 177, 145, 102, 140, 177, -119, 149, -119, -119, -119, + -119, 115, -119, -119, -119, 140, -119 }; -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = { - 0, 2, 0, 1, 1, 1, 1, 2, 5, 0, - 2, 1, 3, 0, 1, 0, 3, 3, 3, 4, - 6, 3, 2, 2, 8, 5, 5, 5, 5, 5, - 7, 5, 3, 0, 0, 9, 1, 1, 1, 2, - 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 2, 3, 0, 2, 4, 1, 3, 1, - 0, 2, 1, 0, 4, 2, 4, 4, 0, 2, - 1, 1, 1, 1, 1, 1, 0, 2 + 2, 103, 111, 0, 47, 0, 18, 41, 22, 8, + 44, 0, 31, 38, 50, 11, 102, 0, 3, 0, + 6, 0, 0, 0, 33, 100, 34, 17, 0, 0, + 100, 100, 100, 102, 18, 100, 100, 0, 0, 5, + 4, 100, 1, 53, 7, 62, 61, 63, 0, 28, + 26, 0, 105, 0, 118, 115, 117, 116, 114, 113, + 119, 112, 0, 97, 99, 0, 88, 90, 0, 65, + 0, 11, 0, 57, 0, 0, 51, 21, 0, 0, + 64, 100, 100, 0, 100, 104, 120, 0, 48, 100, + 101, 35, 0, 0, 68, 78, 80, 70, 72, 66, + 74, 76, 42, 82, 84, 86, 23, 12, 14, 0, + 45, 32, 39, 0, 25, 54, 0, 0, 109, 107, + 106, 100, 58, 11, 98, 100, 89, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 11, 0, 0, 100, + 100, 9, 11, 92, 11, 16, 29, 27, 100, 100, + 121, 0, 0, 0, 91, 69, 79, 81, 71, 73, + 67, 75, 77, 0, 83, 85, 87, 13, 11, 0, + 94, 0, 92, 0, 100, 55, 100, 110, 108, 59, + 49, 36, 20, 10, 46, 0, 40, 93, 52, 0, + 18, 0, 0, 11, 18, 43, 0, 15, 56, 30, + 60, 0, 19, 95, 37, 11, 96 }; -/* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. - Performed when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint8 yydefact[] = + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = { - 2, 63, 68, 0, 60, 0, 15, 0, 60, 60, - 60, 0, 60, 60, 0, 9, 62, 0, 3, 0, - 6, 0, 0, 0, 22, 0, 57, 59, 23, 14, - 0, 0, 0, 62, 0, 40, 0, 9, 0, 15, - 0, 0, 0, 0, 5, 4, 0, 1, 0, 7, - 37, 36, 38, 0, 60, 60, 0, 60, 0, 75, - 72, 74, 73, 71, 70, 76, 69, 9, 60, 61, - 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 9, 0, 0, 60, 17, 60, 11, 0, 9, - 32, 21, 54, 9, 16, 18, 13, 39, 0, 0, - 0, 65, 64, 60, 0, 0, 58, 60, 53, 42, - 47, 48, 43, 44, 41, 45, 46, 0, 49, 50, - 51, 10, 9, 0, 0, 0, 54, 0, 60, 15, - 60, 19, 60, 60, 77, 33, 28, 0, 26, 8, - 27, 0, 25, 55, 29, 0, 31, 0, 67, 66, - 0, 9, 15, 9, 12, 20, 34, 0, 30, 56, - 0, 24, 35 + -119, -119, -118, 25, -119, -119, 96, -119, -119, -119, + 160, -119, -33, -119, -119, -119, -119, -119, -119, -119, + -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, + -119, -119, -119, -119, -119, -119, 55, -4, -119, -119, + -119, -119, -119, -119, -119, -119, -119, -119, -119, -119, + -119, 5, -119, -119, -119, -27, -28, -119, 0, -119, + -119, -119, -119, -119, -119, -119, -119, -119 }; -/* YYDEFGOTO[NTERM-NUM]. */ + /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - -1, 17, 43, 44, 45, 88, 129, 19, 20, 150, - 160, 55, 34, 125, 126, 25, 26, 27, 35, 22, - 58, 23, 66, 104 + -1, 17, 38, 39, 31, 168, 40, 109, 140, 175, + 19, 195, 20, 30, 41, 82, 81, 176, 35, 125, + 193, 36, 143, 29, 136, 32, 142, 25, 123, 37, + 113, 79, 145, 190, 151, 192, 50, 68, 133, 128, + 131, 132, 134, 135, 129, 130, 137, 138, 139, 92, + 93, 171, 172, 185, 205, 62, 63, 64, 69, 22, + 53, 84, 149, 148, 23, 61, 87, 121 }; -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -50 -static const yytype_int16 yypact[] = + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_int16 yytable[] = { - 161, -50, -50, -1, -50, 6, -25, 5, -50, -5, - -50, -11, -50, -50, 5, 161, 11, 28, -50, -4, - 161, 61, 9, -12, -50, 14, 51, -11, -50, -50, - 27, 5, 5, -50, 37, 53, 69, 72, 43, 189, - 79, 46, 128, 44, -50, -50, 84, -50, 49, -50, - -50, -50, -50, 85, -50, -50, -11, -50, 82, -50, - -50, -50, -50, -50, -50, 92, -50, 161, -50, -50, - 71, -50, 142, 5, 5, 5, 5, 5, 5, 5, - 5, 161, 5, 5, -50, -50, -50, -50, 105, 161, - -50, -50, 95, 161, -50, -50, 112, -50, 48, 109, - -15, -50, -50, -50, 76, 80, -50, -50, -50, 56, - 123, 123, -50, -50, 56, -50, -50, 97, 155, 155, - -50, -50, 161, 101, 75, 114, 95, 115, -50, 189, - -50, -50, -50, -50, -50, -50, -50, 119, 103, -50, - -50, 156, -50, -50, -50, 157, -50, 165, -50, -50, - 122, 161, 189, 161, -50, -50, -50, 129, -50, -50, - 130, -50, -50 + 21, 73, 70, 71, 72, 152, 66, 74, 75, 1, + 67, 34, 24, 26, 78, 21, 27, -17, 163, 51, + 21, 1, -24, -24, 169, 18, 173, 94, 95, 96, + -24, 42, 52, 76, 21, 97, 98, 99, 100, 101, + 33, 45, 65, 77, 43, 44, 46, 80, 85, 47, + 183, 83, 33, 116, 117, 118, 86, 120, 48, 88, + 89, -24, 124, 106, 90, 119, 91, 107, 102, 103, + 104, 105, 94, 95, 96, 201, 154, 111, 114, 115, + 97, 98, 99, 100, 101, 110, 45, 206, 126, 127, + 112, 46, 122, 150, 47, 141, 144, 153, 94, 95, + 96, 97, 98, 48, 100, 101, 97, 98, 99, 100, + 101, 166, 167, 49, 103, 104, 147, 174, 170, 179, + 177, 180, 178, 21, 155, 156, 157, 158, 159, 160, + 161, 162, 181, 164, 165, 194, 21, 196, 182, 184, + 103, 104, 21, 94, 21, 186, 188, 189, 191, 197, + 200, 97, 98, 99, 100, 101, 199, 198, 1, 203, + 2, 202, 3, 204, 4, 5, 28, 108, 21, 6, + 7, 146, 0, 8, 9, 10, 11, 187, 0, 12, + -18, 13, 0, 0, 14, 15, 0, 0, 0, 16, + 21, 0, 0, 21, 21, 1, 0, 2, 0, 3, + 0, 4, 5, 0, 0, 21, 6, 7, 0, 0, + 8, 27, 10, 11, 54, 0, 12, 55, 13, 0, + 0, 14, 15, 56, 57, 0, 16, 0, 58, 59, + 94, 95, 96, 0, 0, 60, 0, 0, 97, 98, + 99, 100, 101 }; -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = +static const yytype_int16 yycheck[] = { - -50, -50, -49, 13, 143, -50, -50, 176, -35, -50, - -50, 86, 32, 66, -50, -2, -7, -50, 0, -50, - -50, -50, -50, -50 + 0, 34, 30, 31, 32, 123, 3, 35, 36, 18, + 7, 11, 11, 11, 41, 15, 34, 40, 136, 36, + 20, 18, 10, 11, 142, 0, 144, 4, 5, 6, + 18, 0, 49, 37, 34, 12, 13, 14, 15, 16, + 49, 9, 49, 48, 40, 20, 14, 14, 19, 17, + 168, 51, 49, 81, 82, 39, 21, 84, 26, 45, + 10, 49, 89, 11, 64, 49, 32, 14, 45, 46, + 47, 32, 4, 5, 6, 193, 8, 11, 11, 49, + 12, 13, 14, 15, 16, 45, 9, 205, 92, 93, + 45, 14, 45, 121, 17, 11, 45, 125, 4, 5, + 6, 12, 13, 26, 15, 16, 12, 13, 14, 15, + 16, 139, 140, 36, 46, 47, 11, 7, 23, 50, + 148, 48, 149, 123, 128, 129, 130, 131, 132, 133, + 134, 135, 45, 137, 138, 27, 136, 49, 48, 48, + 46, 47, 142, 4, 144, 48, 48, 174, 176, 8, + 48, 12, 13, 14, 15, 16, 11, 190, 18, 10, + 20, 194, 22, 48, 24, 25, 6, 71, 168, 29, + 30, 116, -1, 33, 34, 35, 36, 172, -1, 39, + 40, 41, -1, -1, 44, 45, -1, -1, -1, 49, + 190, -1, -1, 193, 194, 18, -1, 20, -1, 22, + -1, 24, 25, -1, -1, 205, 29, 30, -1, -1, + 33, 34, 35, 36, 28, -1, 39, 31, 41, -1, + -1, 44, 45, 37, 38, -1, 49, -1, 42, 43, + 4, 5, 6, -1, -1, 49, -1, -1, 12, 13, + 14, 15, 16 }; -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -61 -static const yytype_int16 yytable[] = + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = { - 21, 36, 37, 38, 90, 40, 41, 1, 31, 29, - 24, 39, 32, 18, 46, 21, 59, 28, 105, 60, - 21, -60, -60, 1, 132, 61, 62, 69, 47, -60, - 63, 64, 117, 49, 133, -14, 48, 65, 33, 21, - 123, 73, 74, 75, 127, 56, 42, 98, 99, 76, - 77, 78, 79, 80, 33, 101, 100, 50, 57, 67, - -60, 68, 51, 71, 72, 52, 106, 21, 76, 77, - 50, 79, 80, 139, 53, 51, 70, 120, 52, 121, - 85, 21, 81, 82, 83, 84, 86, 53, 89, 21, - 91, 92, 94, 21, 146, 95, 134, 54, 96, 97, - 137, 102, 157, 107, 159, 109, 110, 111, 112, 113, - 114, 115, 116, 103, 118, 119, 122, 158, 124, 128, - 131, 135, 21, 147, 141, 148, 145, 73, 136, 21, - 152, 149, 73, 74, 75, 76, 77, 78, 79, 80, - 76, 77, 78, 79, 80, 138, 73, 74, 75, 140, - 108, 21, 21, 21, 76, 77, 78, 79, 80, 73, - 74, 75, 142, 144, 151, 154, 153, 76, 77, 78, - 79, 80, 156, 93, 82, 83, 155, 161, 162, 1, - 87, 2, 30, 3, 130, 4, 5, 0, 82, 83, - 6, 7, 143, 0, 8, 9, 10, 11, 0, 0, - 12, -15, 13, 0, 0, 14, 15, 1, 0, 2, - 16, 3, 0, 4, 5, 0, 0, 0, 6, 7, - 0, 0, 8, 29, 10, 11, 0, 0, 12, 0, - 13, 0, 0, 14, 15, 0, 0, 0, 16 + 0, 18, 20, 22, 24, 25, 29, 30, 33, 34, + 35, 36, 39, 41, 44, 45, 49, 52, 54, 61, + 63, 109, 110, 115, 11, 78, 11, 34, 61, 74, + 64, 55, 76, 49, 109, 69, 72, 80, 53, 54, + 57, 65, 0, 40, 54, 9, 14, 17, 26, 36, + 87, 36, 49, 111, 28, 31, 37, 38, 42, 43, + 49, 116, 106, 107, 108, 49, 3, 7, 88, 109, + 107, 107, 107, 63, 107, 107, 88, 48, 106, 82, + 14, 67, 66, 109, 112, 19, 21, 117, 45, 10, + 109, 32, 100, 101, 4, 5, 6, 12, 13, 14, + 15, 16, 45, 46, 47, 32, 11, 14, 57, 58, + 45, 11, 45, 81, 11, 49, 107, 107, 39, 49, + 106, 118, 45, 79, 106, 70, 88, 88, 90, 95, + 96, 91, 92, 89, 93, 94, 75, 97, 98, 99, + 59, 11, 77, 73, 45, 83, 87, 11, 114, 113, + 107, 85, 53, 107, 8, 88, 88, 88, 88, 88, + 88, 88, 88, 53, 88, 88, 107, 107, 56, 53, + 23, 102, 103, 53, 7, 60, 68, 107, 106, 50, + 48, 45, 48, 53, 48, 104, 48, 102, 48, 106, + 84, 107, 86, 71, 27, 62, 49, 8, 63, 11, + 48, 53, 63, 10, 48, 105, 53 }; -#define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-50))) - -#define yytable_value_is_error(Yytable_value) \ - YYID (0) - -static const yytype_int16 yycheck[] = + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = { - 0, 8, 9, 10, 39, 12, 13, 18, 3, 34, - 11, 11, 7, 0, 16, 15, 28, 11, 67, 31, - 20, 10, 11, 18, 39, 37, 38, 27, 0, 18, - 42, 43, 81, 20, 49, 40, 40, 49, 49, 39, - 89, 4, 5, 6, 93, 36, 14, 54, 55, 12, - 13, 14, 15, 16, 49, 57, 56, 9, 49, 45, - 49, 10, 14, 31, 32, 17, 68, 67, 12, 13, - 9, 15, 16, 122, 26, 14, 49, 84, 17, 86, - 11, 81, 45, 46, 47, 32, 14, 26, 45, 89, - 11, 45, 48, 93, 129, 11, 103, 36, 49, 14, - 107, 19, 151, 32, 153, 73, 74, 75, 76, 77, - 78, 79, 80, 21, 82, 83, 11, 152, 23, 7, - 11, 45, 122, 130, 49, 132, 128, 4, 48, 129, - 27, 133, 4, 5, 6, 12, 13, 14, 15, 16, - 12, 13, 14, 15, 16, 48, 4, 5, 6, 48, - 8, 151, 152, 153, 12, 13, 14, 15, 16, 4, - 5, 6, 48, 48, 45, 8, 10, 12, 13, 14, - 15, 16, 50, 45, 46, 47, 11, 48, 48, 18, - 37, 20, 6, 22, 98, 24, 25, -1, 46, 47, - 29, 30, 126, -1, 33, 34, 35, 36, -1, -1, - 39, 40, 41, -1, -1, 44, 45, 18, -1, 20, - 49, 22, -1, 24, 25, -1, -1, -1, 29, 30, - -1, -1, 33, 34, 35, 36, -1, -1, 39, -1, - 41, -1, -1, 44, 45, -1, -1, -1, 49 + 0, 51, 52, 52, 53, 53, 54, 54, 55, 56, + 54, 57, 59, 58, 58, 60, 60, 61, 61, 62, + 62, 63, 64, 63, 65, 63, 66, 63, 67, 68, + 63, 69, 63, 63, 63, 70, 71, 63, 72, 73, + 63, 74, 75, 63, 76, 77, 63, 78, 79, 63, + 80, 81, 63, 82, 83, 84, 63, 63, 85, 86, + 63, 87, 87, 87, 87, 88, 89, 88, 90, 88, + 91, 88, 92, 88, 93, 88, 94, 88, 95, 88, + 96, 88, 97, 88, 98, 88, 99, 88, 100, 88, + 101, 88, 102, 102, 104, 105, 103, 106, 106, 107, + 108, 108, 109, 110, 109, 112, 111, 113, 111, 114, + 111, 115, 115, 116, 116, 116, 116, 116, 116, 117, + 118, 117 }; -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint8 yystos[] = + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = { - 0, 18, 20, 22, 24, 25, 29, 30, 33, 34, - 35, 36, 39, 41, 44, 45, 49, 52, 54, 58, - 59, 69, 70, 72, 11, 66, 67, 68, 11, 34, - 58, 3, 7, 49, 63, 69, 67, 67, 67, 69, - 67, 67, 63, 53, 54, 55, 66, 0, 40, 54, - 9, 14, 17, 26, 36, 62, 36, 49, 71, 28, - 31, 37, 38, 42, 43, 49, 73, 45, 10, 69, - 49, 63, 63, 4, 5, 6, 12, 13, 14, 15, - 16, 45, 46, 47, 32, 11, 14, 55, 56, 45, - 59, 11, 45, 45, 48, 11, 49, 14, 67, 67, - 69, 66, 19, 21, 74, 53, 66, 32, 8, 63, - 63, 63, 63, 63, 63, 63, 63, 53, 63, 63, - 67, 67, 11, 53, 23, 64, 65, 53, 7, 57, - 62, 11, 39, 49, 67, 45, 48, 67, 48, 53, - 48, 49, 48, 64, 48, 66, 59, 67, 67, 66, - 60, 45, 27, 10, 8, 11, 50, 53, 59, 53, - 61, 48, 48 + 0, 2, 0, 1, 1, 1, 1, 2, 0, 0, + 7, 0, 0, 3, 1, 3, 0, 1, 0, 2, + 0, 3, 0, 4, 0, 4, 0, 5, 0, 0, + 8, 0, 4, 2, 2, 0, 0, 10, 0, 0, + 7, 0, 0, 8, 0, 0, 7, 0, 0, 7, + 0, 0, 7, 0, 0, 0, 8, 3, 0, 0, + 9, 1, 1, 1, 2, 1, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 4, + 0, 4, 0, 4, 0, 4, 0, 4, 0, 3, + 0, 4, 0, 2, 0, 0, 6, 1, 3, 1, + 0, 2, 1, 0, 4, 0, 3, 0, 5, 0, + 5, 0, 2, 1, 1, 1, 1, 1, 1, 0, + 0, 3 }; -#define yyerrok (yyerrstatus = 0) -#define yyclearin (yychar = YYEMPTY) -#define YYEMPTY (-2) -#define YYEOF 0 - -#define YYACCEPT goto yyacceptlab -#define YYABORT goto yyabortlab -#define YYERROR goto yyerrorlab - - -/* Like YYERROR except do call yyerror. This remains here temporarily - to ease the transition to the new meaning of YYERROR, for GCC. - Once GCC version 2 has supplanted version 1, this can go. However, - YYFAIL appears to be in use. Nevertheless, it is formally deprecated - in Bison 2.4.2's NEWS entry, where a plan to phase it out is - discussed. */ - -#define YYFAIL goto yyerrlab -#if defined YYFAIL - /* This is here to suppress warnings from the GCC cpp's - -Wunused-macros. Normally we don't worry about that warning, but - some users do, and we want to make it easy for users to remove - YYFAIL uses, which will produce warnings from Bison 2.5. */ -#endif + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + #define YYRECOVERING() (!!yyerrstatus) @@ -863,56 +854,15 @@ do \ else \ { \ yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) - - - -/* This macro is provided for backward compatibility. */ - -#ifndef YY_LOCATION_PRINT -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -#endif + YYERROR; \ + } \ +while (0) +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 -/* YYLEX -- calling `yylex' with the right arguments. */ -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif /* Enable debugging if requested. */ #if YYDEBUG @@ -922,40 +872,36 @@ while (YYID (0)) # define YYFPRINTF fprintf # endif -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { FILE *yyo = yyoutput; YYUSE (yyo); @@ -964,14 +910,8 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) # ifdef YYPRINT if (yytype < YYNTOKENS) YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); # endif - switch (yytype) - { - default: - break; - } + YYUSE (yytype); } @@ -979,22 +919,11 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep) | Print this symbol on YYOUTPUT. | `--------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif { - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); yy_symbol_value_print (yyoutput, yytype, yyvaluep); YYFPRINTF (yyoutput, ")"); @@ -1005,16 +934,8 @@ yy_symbol_print (yyoutput, yytype, yyvaluep) | TOP (included). | `------------------------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) -#else -static void -yy_stack_print (yybottom, yytop) - yytype_int16 *yybottom; - yytype_int16 *yytop; -#endif { YYFPRINTF (stderr, "Stack now"); for (; yybottom <= yytop; yybottom++) @@ -1025,49 +946,42 @@ yy_stack_print (yybottom, yytop) YYFPRINTF (stderr, "\n"); } -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) /*------------------------------------------------. | Report that the YYRULE is going to be reduced. | `------------------------------------------------*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) { + unsigned long int yylno = yyrline[yyrule]; int yynrhs = yyr2[yyrule]; int yyi; - unsigned long int yylno = yyrline[yyrule]; YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); + yyrule - 1, yylno); /* The symbols being reduced. */ for (yyi = 0; yyi < yynrhs; yyi++) { YYFPRINTF (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); YYFPRINTF (stderr, "\n"); } } -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) /* Nonzero means print parse trace. It is left uninitialized so that multiple parsers can coexist. */ @@ -1081,7 +995,7 @@ int yydebug; /* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH +#ifndef YYINITDEPTH # define YYINITDEPTH 200 #endif @@ -1104,15 +1018,8 @@ int yydebug; # define yystrlen strlen # else /* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static YYSIZE_T yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif { YYSIZE_T yylen; for (yylen = 0; yystr[yylen]; yylen++) @@ -1128,16 +1035,8 @@ yystrlen (yystr) # else /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static char * yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif { char *yyd = yydest; const char *yys = yysrc; @@ -1167,27 +1066,27 @@ yytnamerr (char *yyres, const char *yystr) char const *yyp = yystr; for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } do_not_strip_quotes: ; } @@ -1210,12 +1109,11 @@ static int yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, yytype_int16 *yyssp, int yytoken) { - YYSIZE_T yysize0 = yytnamerr (YY_NULL, yytname[yytoken]); + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; /* Internationalized format string. */ - const char *yyformat = YY_NULL; + const char *yyformat = YY_NULLPTR; /* Arguments of yyformat. */ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; /* Number of reported tokens (one for the "unexpected", one per @@ -1223,10 +1121,6 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, int yycount = 0; /* There are many possibilities here to consider: - - Assume YYFAIL is not used. It's too flawed to consider. See - - for details. YYERROR is fine as it does not invoke this - function. - If this state is a consistent state with a default action, then the only way this function was invoked is if the default action is an error action. In that case, don't check for expected @@ -1275,11 +1169,13 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, break; } yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (YY_NULL, yytname[yyx]); - if (! (yysize <= yysize1 - && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } } } } @@ -1299,10 +1195,12 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, # undef YYCASE_ } - yysize1 = yysize + yystrlen (yyformat); - if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) - return 2; - yysize = yysize1; + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } if (*yymsg_alloc < yysize) { @@ -1339,31 +1237,17 @@ yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, | Release the memory associated to this symbol. | `-----------------------------------------------*/ -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) static void yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif { YYUSE (yyvaluep); - if (!yymsg) yymsg = "Deleting"; YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - switch (yytype) - { - - default: - break; - } + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END } @@ -1372,18 +1256,8 @@ yydestruct (yymsg, yytype, yyvaluep) /* The lookahead symbol. */ int yychar; - -#ifndef YYLVAL_INITIALIZE -# define YYLVAL_INITIALIZE() -#endif -#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN -# define YY_IGNORE_MAYBE_UNINITIALIZED_END -#endif - /* The semantic value of the lookahead symbol. */ YYSTYPE yylval; - /* Number of syntax errors so far. */ int yynerrs; @@ -1392,35 +1266,16 @@ int yynerrs; | yyparse. | `----------*/ -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) int yyparse (void) -#else -int -yyparse () - -#endif -#endif { int yystate; /* Number of tokens to shift before error messages enabled. */ int yyerrstatus; /* The stacks and their tools: - `yyss': related to states. - `yyvs': related to semantic values. + 'yyss': related to states. + 'yyvs': related to semantic values. Refer to the stacks through separate pointers, to allow yyoverflow to reallocate them elsewhere. */ @@ -1458,8 +1313,8 @@ yyparse () Keep to zero when no symbol should be popped. */ int yylen = 0; - yyss = yyssa; - yyvs = yyvsa; + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; yystacksize = YYINITDEPTH; YYDPRINTF ((stderr, "Starting parse\n")); @@ -1468,15 +1323,6 @@ yyparse () yyerrstatus = 0; yynerrs = 0; yychar = YYEMPTY; /* Cause a token to be read. */ - - /* Initialize stack pointers. - Waste one element of value and location stack - so that they stay on the same level as the state stack. - The wasted elements are never initialized. */ - yyssp = yyss; - yyvsp = yyvs; - - YYLVAL_INITIALIZE (); goto yysetstate; /*------------------------------------------------------------. @@ -1497,23 +1343,23 @@ yyparse () #ifdef yyoverflow { - /* Give user a chance to reallocate the stack. Use copies of - these so that the &'s don't force the real ones into - memory. */ - YYSTYPE *yyvs1 = yyvs; - yytype_int16 *yyss1 = yyss; - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; } #else /* no yyoverflow */ # ifndef YYSTACK_RELOCATE @@ -1521,22 +1367,22 @@ yyparse () # else /* Extend the stack our own way. */ if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; + goto yyexhaustedlab; yystacksize *= 2; if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; + yystacksize = YYMAXDEPTH; { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss_alloc, yyss); - YYSTACK_RELOCATE (yyvs_alloc, yyvs); + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); # undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); } # endif #endif /* no yyoverflow */ @@ -1545,10 +1391,10 @@ yyparse () yyvsp = yyvs + yysize - 1; YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); + (unsigned long int) yystacksize)); if (yyss + yystacksize - 1 <= yyssp) - YYABORT; + YYABORT; } YYDPRINTF ((stderr, "Entering state %d\n", yystate)); @@ -1577,7 +1423,7 @@ yybackup: if (yychar == YYEMPTY) { YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; + yychar = yylex (); } if (yychar <= YYEOF) @@ -1642,7 +1488,7 @@ yyreduce: yylen = yyr2[yyn]; /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. + '$$ = $1'. Otherwise, the following line sets YYVAL to garbage. This behavior is undocumented and Bison @@ -1656,458 +1502,721 @@ yyreduce: switch (yyn) { case 3: -/* Line 1813 of yacc.c */ -#line 147 "jamgram.y" - { parse_save( (yyvsp[(1) - (1)]).parse ); } +#line 147 "jamgram.y" /* yacc.c:1646 */ + { parse_save( (yyvsp[0]).parse ); } +#line 1508 "y.tab.c" /* yacc.c:1646 */ break; case 4: -/* Line 1813 of yacc.c */ -#line 158 "jamgram.y" - { (yyval).parse = (yyvsp[(1) - (1)]).parse; } +#line 158 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 1514 "y.tab.c" /* yacc.c:1646 */ break; case 5: -/* Line 1813 of yacc.c */ -#line 160 "jamgram.y" - { (yyval).parse = (yyvsp[(1) - (1)]).parse; } +#line 160 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 1520 "y.tab.c" /* yacc.c:1646 */ break; case 6: -/* Line 1813 of yacc.c */ -#line 164 "jamgram.y" - { (yyval).parse = (yyvsp[(1) - (1)]).parse; } +#line 164 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 1526 "y.tab.c" /* yacc.c:1646 */ break; case 7: -/* Line 1813 of yacc.c */ -#line 166 "jamgram.y" - { (yyval).parse = prules( (yyvsp[(1) - (2)]).parse, (yyvsp[(2) - (2)]).parse ); } +#line 166 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = prules( (yyvsp[-1]).parse, (yyvsp[0]).parse ); } +#line 1532 "y.tab.c" /* yacc.c:1646 */ break; case 8: -/* Line 1813 of yacc.c */ -#line 168 "jamgram.y" - { (yyval).parse = plocal( (yyvsp[(2) - (5)]).parse, (yyvsp[(3) - (5)]).parse, (yyvsp[(5) - (5)]).parse ); } +#line 167 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_ASSIGN ); } +#line 1538 "y.tab.c" /* yacc.c:1646 */ break; case 9: -/* Line 1813 of yacc.c */ -#line 172 "jamgram.y" - { (yyval).parse = pnull(); } +#line 167 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1544 "y.tab.c" /* yacc.c:1646 */ break; case 10: -/* Line 1813 of yacc.c */ -#line 176 "jamgram.y" - { (yyval).parse = (yyvsp[(2) - (2)]).parse; (yyval).number = ASSIGN_SET; } +#line 168 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = plocal( (yyvsp[-4]).parse, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1550 "y.tab.c" /* yacc.c:1646 */ break; case 11: -/* Line 1813 of yacc.c */ -#line 178 "jamgram.y" - { (yyval).parse = (yyvsp[(1) - (1)]).parse; (yyval).number = ASSIGN_APPEND; } +#line 172 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnull(); } +#line 1556 "y.tab.c" /* yacc.c:1646 */ break; case 12: -/* Line 1813 of yacc.c */ -#line 182 "jamgram.y" - { (yyval).parse = (yyvsp[(2) - (3)]).parse; } +#line 175 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1562 "y.tab.c" /* yacc.c:1646 */ break; case 13: -/* Line 1813 of yacc.c */ -#line 184 "jamgram.y" - { (yyval).parse = P0; } +#line 176 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; (yyval).number = ASSIGN_SET; } +#line 1568 "y.tab.c" /* yacc.c:1646 */ break; case 14: -/* Line 1813 of yacc.c */ -#line 188 "jamgram.y" - { (yyval).number = 1; } +#line 178 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; (yyval).number = ASSIGN_APPEND; } +#line 1574 "y.tab.c" /* yacc.c:1646 */ break; case 15: -/* Line 1813 of yacc.c */ -#line 190 "jamgram.y" - { (yyval).number = 0; } +#line 182 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[-1]).parse; } +#line 1580 "y.tab.c" /* yacc.c:1646 */ break; case 16: -/* Line 1813 of yacc.c */ -#line 194 "jamgram.y" - { (yyval).parse = (yyvsp[(2) - (3)]).parse; } +#line 184 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = P0; } +#line 1586 "y.tab.c" /* yacc.c:1646 */ break; case 17: -/* Line 1813 of yacc.c */ -#line 196 "jamgram.y" - { (yyval).parse = pincl( (yyvsp[(2) - (3)]).parse ); } +#line 188 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = 1; } +#line 1592 "y.tab.c" /* yacc.c:1646 */ break; case 18: -/* Line 1813 of yacc.c */ -#line 198 "jamgram.y" - { (yyval).parse = prule( (yyvsp[(1) - (3)]).string, (yyvsp[(2) - (3)]).parse ); } +#line 190 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = 0; } +#line 1598 "y.tab.c" /* yacc.c:1646 */ break; case 19: -/* Line 1813 of yacc.c */ -#line 200 "jamgram.y" - { (yyval).parse = pset( (yyvsp[(1) - (4)]).parse, (yyvsp[(3) - (4)]).parse, (yyvsp[(2) - (4)]).number ); } +#line 194 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 1604 "y.tab.c" /* yacc.c:1646 */ break; case 20: -/* Line 1813 of yacc.c */ -#line 202 "jamgram.y" - { (yyval).parse = pset1( (yyvsp[(1) - (6)]).parse, (yyvsp[(3) - (6)]).parse, (yyvsp[(5) - (6)]).parse, (yyvsp[(4) - (6)]).number ); } +#line 196 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnull(); } +#line 1610 "y.tab.c" /* yacc.c:1646 */ break; case 21: -/* Line 1813 of yacc.c */ -#line 204 "jamgram.y" - { (yyval).parse = preturn( (yyvsp[(2) - (3)]).parse ); } +#line 199 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[-1]).parse; } +#line 1616 "y.tab.c" /* yacc.c:1646 */ break; case 22: -/* Line 1813 of yacc.c */ -#line 206 "jamgram.y" - { (yyval).parse = pbreak(); } +#line 200 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1622 "y.tab.c" /* yacc.c:1646 */ break; case 23: -/* Line 1813 of yacc.c */ -#line 208 "jamgram.y" - { (yyval).parse = pcontinue(); } +#line 201 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pincl( (yyvsp[-1]).parse ); yymode( SCAN_NORMAL ); } +#line 1628 "y.tab.c" /* yacc.c:1646 */ break; case 24: -/* Line 1813 of yacc.c */ -#line 210 "jamgram.y" - { (yyval).parse = pfor( (yyvsp[(3) - (8)]).string, (yyvsp[(5) - (8)]).parse, (yyvsp[(7) - (8)]).parse, (yyvsp[(2) - (8)]).number ); } +#line 202 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1634 "y.tab.c" /* yacc.c:1646 */ break; case 25: -/* Line 1813 of yacc.c */ -#line 212 "jamgram.y" - { (yyval).parse = pswitch( (yyvsp[(2) - (5)]).parse, (yyvsp[(4) - (5)]).parse ); } +#line 203 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = prule( (yyvsp[-3]).string, (yyvsp[-1]).parse ); yymode( SCAN_NORMAL ); } +#line 1640 "y.tab.c" /* yacc.c:1646 */ break; case 26: -/* Line 1813 of yacc.c */ -#line 214 "jamgram.y" - { (yyval).parse = pif( (yyvsp[(2) - (5)]).parse, (yyvsp[(4) - (5)]).parse, pnull() ); } +#line 204 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1646 "y.tab.c" /* yacc.c:1646 */ break; case 27: -/* Line 1813 of yacc.c */ -#line 216 "jamgram.y" - { (yyval).parse = pmodule( (yyvsp[(2) - (5)]).parse, (yyvsp[(4) - (5)]).parse ); } +#line 205 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pset( (yyvsp[-4]).parse, (yyvsp[-1]).parse, (yyvsp[-3]).number ); yymode( SCAN_NORMAL ); } +#line 1652 "y.tab.c" /* yacc.c:1646 */ break; case 28: -/* Line 1813 of yacc.c */ -#line 218 "jamgram.y" - { (yyval).parse = pclass( (yyvsp[(2) - (5)]).parse, (yyvsp[(4) - (5)]).parse ); } +#line 206 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_ASSIGN ); } +#line 1658 "y.tab.c" /* yacc.c:1646 */ break; case 29: -/* Line 1813 of yacc.c */ -#line 220 "jamgram.y" - { (yyval).parse = pwhile( (yyvsp[(2) - (5)]).parse, (yyvsp[(4) - (5)]).parse ); } +#line 206 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1664 "y.tab.c" /* yacc.c:1646 */ break; case 30: -/* Line 1813 of yacc.c */ -#line 222 "jamgram.y" - { (yyval).parse = pif( (yyvsp[(2) - (7)]).parse, (yyvsp[(4) - (7)]).parse, (yyvsp[(7) - (7)]).parse ); } +#line 207 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pset1( (yyvsp[-7]).parse, (yyvsp[-4]).parse, (yyvsp[-1]).parse, (yyvsp[-3]).number ); yymode( SCAN_NORMAL ); } +#line 1670 "y.tab.c" /* yacc.c:1646 */ break; case 31: -/* Line 1813 of yacc.c */ -#line 224 "jamgram.y" - { (yyval).parse = psetc( (yyvsp[(3) - (5)]).string, (yyvsp[(5) - (5)]).parse, (yyvsp[(4) - (5)]).parse, (yyvsp[(1) - (5)]).number ); } +#line 208 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1676 "y.tab.c" /* yacc.c:1646 */ break; case 32: -/* Line 1813 of yacc.c */ -#line 226 "jamgram.y" - { (yyval).parse = pon( (yyvsp[(2) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 209 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = preturn( (yyvsp[-1]).parse ); yymode( SCAN_NORMAL ); } +#line 1682 "y.tab.c" /* yacc.c:1646 */ break; case 33: -/* Line 1813 of yacc.c */ -#line 228 "jamgram.y" - { yymode( SCAN_STRING ); } +#line 211 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pbreak(); } +#line 1688 "y.tab.c" /* yacc.c:1646 */ break; case 34: -/* Line 1813 of yacc.c */ -#line 230 "jamgram.y" - { yymode( SCAN_NORMAL ); } +#line 213 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pcontinue(); } +#line 1694 "y.tab.c" /* yacc.c:1646 */ break; case 35: -/* Line 1813 of yacc.c */ -#line 232 "jamgram.y" - { (yyval).parse = psete( (yyvsp[(3) - (9)]).string,(yyvsp[(4) - (9)]).parse,(yyvsp[(7) - (9)]).string,(yyvsp[(2) - (9)]).number ); } +#line 214 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1700 "y.tab.c" /* yacc.c:1646 */ break; case 36: -/* Line 1813 of yacc.c */ -#line 240 "jamgram.y" - { (yyval).number = ASSIGN_SET; } +#line 214 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1706 "y.tab.c" /* yacc.c:1646 */ break; case 37: -/* Line 1813 of yacc.c */ -#line 242 "jamgram.y" - { (yyval).number = ASSIGN_APPEND; } +#line 215 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pfor( (yyvsp[-7]).string, (yyvsp[-4]).parse, (yyvsp[-1]).parse, (yyvsp[-8]).number ); } +#line 1712 "y.tab.c" /* yacc.c:1646 */ break; case 38: -/* Line 1813 of yacc.c */ -#line 244 "jamgram.y" - { (yyval).number = ASSIGN_DEFAULT; } +#line 216 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1718 "y.tab.c" /* yacc.c:1646 */ break; case 39: -/* Line 1813 of yacc.c */ -#line 246 "jamgram.y" - { (yyval).number = ASSIGN_DEFAULT; } +#line 216 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1724 "y.tab.c" /* yacc.c:1646 */ break; case 40: -/* Line 1813 of yacc.c */ -#line 253 "jamgram.y" - { (yyval).parse = peval( EXPR_EXISTS, (yyvsp[(1) - (1)]).parse, pnull() ); } +#line 217 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pswitch( (yyvsp[-4]).parse, (yyvsp[-1]).parse ); } +#line 1730 "y.tab.c" /* yacc.c:1646 */ break; case 41: -/* Line 1813 of yacc.c */ -#line 255 "jamgram.y" - { (yyval).parse = peval( EXPR_EQUALS, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 218 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1736 "y.tab.c" /* yacc.c:1646 */ break; case 42: -/* Line 1813 of yacc.c */ -#line 257 "jamgram.y" - { (yyval).parse = peval( EXPR_NOTEQ, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 218 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1742 "y.tab.c" /* yacc.c:1646 */ break; case 43: -/* Line 1813 of yacc.c */ -#line 259 "jamgram.y" - { (yyval).parse = peval( EXPR_LESS, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 219 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pif( (yyvsp[-5]).parse, (yyvsp[-2]).parse, (yyvsp[0]).parse ); } +#line 1748 "y.tab.c" /* yacc.c:1646 */ break; case 44: -/* Line 1813 of yacc.c */ -#line 261 "jamgram.y" - { (yyval).parse = peval( EXPR_LESSEQ, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 220 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1754 "y.tab.c" /* yacc.c:1646 */ break; case 45: -/* Line 1813 of yacc.c */ -#line 263 "jamgram.y" - { (yyval).parse = peval( EXPR_MORE, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 220 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1760 "y.tab.c" /* yacc.c:1646 */ break; case 46: -/* Line 1813 of yacc.c */ -#line 265 "jamgram.y" - { (yyval).parse = peval( EXPR_MOREEQ, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 221 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pmodule( (yyvsp[-4]).parse, (yyvsp[-1]).parse ); } +#line 1766 "y.tab.c" /* yacc.c:1646 */ break; case 47: -/* Line 1813 of yacc.c */ -#line 267 "jamgram.y" - { (yyval).parse = peval( EXPR_AND, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 222 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1772 "y.tab.c" /* yacc.c:1646 */ break; case 48: -/* Line 1813 of yacc.c */ -#line 269 "jamgram.y" - { (yyval).parse = peval( EXPR_AND, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 222 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1778 "y.tab.c" /* yacc.c:1646 */ break; case 49: -/* Line 1813 of yacc.c */ -#line 271 "jamgram.y" - { (yyval).parse = peval( EXPR_OR, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 223 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pclass( (yyvsp[-4]).parse, (yyvsp[-1]).parse ); } +#line 1784 "y.tab.c" /* yacc.c:1646 */ break; case 50: -/* Line 1813 of yacc.c */ -#line 273 "jamgram.y" - { (yyval).parse = peval( EXPR_OR, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 224 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1790 "y.tab.c" /* yacc.c:1646 */ break; case 51: -/* Line 1813 of yacc.c */ -#line 275 "jamgram.y" - { (yyval).parse = peval( EXPR_IN, (yyvsp[(1) - (3)]).parse, (yyvsp[(3) - (3)]).parse ); } +#line 224 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1796 "y.tab.c" /* yacc.c:1646 */ break; case 52: -/* Line 1813 of yacc.c */ -#line 277 "jamgram.y" - { (yyval).parse = peval( EXPR_NOT, (yyvsp[(2) - (2)]).parse, pnull() ); } +#line 225 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pwhile( (yyvsp[-4]).parse, (yyvsp[-1]).parse ); } +#line 1802 "y.tab.c" /* yacc.c:1646 */ break; case 53: -/* Line 1813 of yacc.c */ -#line 279 "jamgram.y" - { (yyval).parse = (yyvsp[(2) - (3)]).parse; } +#line 226 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 1808 "y.tab.c" /* yacc.c:1646 */ break; case 54: -/* Line 1813 of yacc.c */ -#line 290 "jamgram.y" - { (yyval).parse = P0; } +#line 226 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PARAMS ); } +#line 1814 "y.tab.c" /* yacc.c:1646 */ break; case 55: -/* Line 1813 of yacc.c */ -#line 292 "jamgram.y" - { (yyval).parse = pnode( (yyvsp[(1) - (2)]).parse, (yyvsp[(2) - (2)]).parse ); } +#line 226 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1820 "y.tab.c" /* yacc.c:1646 */ break; case 56: -/* Line 1813 of yacc.c */ -#line 296 "jamgram.y" - { (yyval).parse = psnode( (yyvsp[(2) - (4)]).string, (yyvsp[(4) - (4)]).parse ); } +#line 227 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = psetc( (yyvsp[-4]).string, (yyvsp[0]).parse, (yyvsp[-2]).parse, (yyvsp[-7]).number ); } +#line 1826 "y.tab.c" /* yacc.c:1646 */ break; case 57: -/* Line 1813 of yacc.c */ -#line 305 "jamgram.y" - { (yyval).parse = pnode( P0, (yyvsp[(1) - (1)]).parse ); } +#line 229 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pon( (yyvsp[-1]).parse, (yyvsp[0]).parse ); } +#line 1832 "y.tab.c" /* yacc.c:1646 */ break; case 58: -/* Line 1813 of yacc.c */ -#line 307 "jamgram.y" - { (yyval).parse = pnode( (yyvsp[(3) - (3)]).parse, (yyvsp[(1) - (3)]).parse ); } +#line 231 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_STRING ); } +#line 1838 "y.tab.c" /* yacc.c:1646 */ break; case 59: -/* Line 1813 of yacc.c */ -#line 317 "jamgram.y" - { (yyval).parse = (yyvsp[(1) - (1)]).parse; yymode( SCAN_NORMAL ); } +#line 233 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 1844 "y.tab.c" /* yacc.c:1646 */ break; case 60: -/* Line 1813 of yacc.c */ -#line 321 "jamgram.y" - { (yyval).parse = pnull(); yymode( SCAN_PUNCT ); } +#line 235 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = psete( (yyvsp[-6]).string,(yyvsp[-5]).parse,(yyvsp[-2]).string,(yyvsp[-7]).number ); } +#line 1850 "y.tab.c" /* yacc.c:1646 */ break; case 61: -/* Line 1813 of yacc.c */ -#line 323 "jamgram.y" - { (yyval).parse = pappend( (yyvsp[(1) - (2)]).parse, (yyvsp[(2) - (2)]).parse ); } +#line 243 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = ASSIGN_SET; } +#line 1856 "y.tab.c" /* yacc.c:1646 */ break; case 62: -/* Line 1813 of yacc.c */ -#line 327 "jamgram.y" - { (yyval).parse = plist( (yyvsp[(1) - (1)]).string ); } +#line 245 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = ASSIGN_APPEND; } +#line 1862 "y.tab.c" /* yacc.c:1646 */ break; case 63: -/* Line 1813 of yacc.c */ -#line 328 "jamgram.y" - { yymode( SCAN_NORMAL ); } +#line 247 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = ASSIGN_DEFAULT; } +#line 1868 "y.tab.c" /* yacc.c:1646 */ break; case 64: -/* Line 1813 of yacc.c */ -#line 329 "jamgram.y" - { (yyval).parse = (yyvsp[(3) - (4)]).parse; } +#line 249 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = ASSIGN_DEFAULT; } +#line 1874 "y.tab.c" /* yacc.c:1646 */ break; case 65: -/* Line 1813 of yacc.c */ -#line 338 "jamgram.y" - { (yyval).parse = prule( (yyvsp[(1) - (2)]).string, (yyvsp[(2) - (2)]).parse ); } +#line 256 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_EXISTS, (yyvsp[0]).parse, pnull() ); yymode( SCAN_COND ); } +#line 1880 "y.tab.c" /* yacc.c:1646 */ break; case 66: -/* Line 1813 of yacc.c */ -#line 340 "jamgram.y" - { (yyval).parse = pon( (yyvsp[(2) - (4)]).parse, prule( (yyvsp[(3) - (4)]).string, (yyvsp[(4) - (4)]).parse ) ); } +#line 257 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1886 "y.tab.c" /* yacc.c:1646 */ break; case 67: -/* Line 1813 of yacc.c */ -#line 342 "jamgram.y" - { (yyval).parse = pon( (yyvsp[(2) - (4)]).parse, (yyvsp[(4) - (4)]).parse ); } +#line 258 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_EQUALS, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1892 "y.tab.c" /* yacc.c:1646 */ break; case 68: -/* Line 1813 of yacc.c */ -#line 352 "jamgram.y" - { (yyval).number = 0; } +#line 259 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1898 "y.tab.c" /* yacc.c:1646 */ break; case 69: -/* Line 1813 of yacc.c */ -#line 354 "jamgram.y" - { (yyval).number = (yyvsp[(1) - (2)]).number | (yyvsp[(2) - (2)]).number; } +#line 260 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_NOTEQ, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1904 "y.tab.c" /* yacc.c:1646 */ break; case 70: -/* Line 1813 of yacc.c */ -#line 358 "jamgram.y" - { (yyval).number = EXEC_UPDATED; } +#line 261 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1910 "y.tab.c" /* yacc.c:1646 */ break; case 71: -/* Line 1813 of yacc.c */ -#line 360 "jamgram.y" - { (yyval).number = EXEC_TOGETHER; } +#line 262 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_LESS, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1916 "y.tab.c" /* yacc.c:1646 */ break; case 72: -/* Line 1813 of yacc.c */ -#line 362 "jamgram.y" - { (yyval).number = EXEC_IGNORE; } +#line 263 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1922 "y.tab.c" /* yacc.c:1646 */ break; case 73: -/* Line 1813 of yacc.c */ -#line 364 "jamgram.y" - { (yyval).number = EXEC_QUIETLY; } +#line 264 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_LESSEQ, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1928 "y.tab.c" /* yacc.c:1646 */ break; case 74: -/* Line 1813 of yacc.c */ -#line 366 "jamgram.y" - { (yyval).number = EXEC_PIECEMEAL; } +#line 265 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1934 "y.tab.c" /* yacc.c:1646 */ break; case 75: -/* Line 1813 of yacc.c */ -#line 368 "jamgram.y" - { (yyval).number = EXEC_EXISTING; } +#line 266 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_MORE, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1940 "y.tab.c" /* yacc.c:1646 */ break; case 76: -/* Line 1813 of yacc.c */ -#line 377 "jamgram.y" - { (yyval).parse = pnull(); } +#line 267 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1946 "y.tab.c" /* yacc.c:1646 */ break; case 77: -/* Line 1813 of yacc.c */ -#line 379 "jamgram.y" - { (yyval).parse = (yyvsp[(2) - (2)]).parse; } +#line 268 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_MOREEQ, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1952 "y.tab.c" /* yacc.c:1646 */ + break; + + case 78: +#line 269 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1958 "y.tab.c" /* yacc.c:1646 */ + break; + + case 79: +#line 270 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_AND, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1964 "y.tab.c" /* yacc.c:1646 */ + break; + + case 80: +#line 271 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1970 "y.tab.c" /* yacc.c:1646 */ + break; + + case 81: +#line 272 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_AND, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1976 "y.tab.c" /* yacc.c:1646 */ + break; + + case 82: +#line 273 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1982 "y.tab.c" /* yacc.c:1646 */ + break; + + case 83: +#line 274 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_OR, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 1988 "y.tab.c" /* yacc.c:1646 */ + break; + + case 84: +#line 275 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 1994 "y.tab.c" /* yacc.c:1646 */ + break; + + case 85: +#line 276 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_OR, (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 2000 "y.tab.c" /* yacc.c:1646 */ + break; + + case 86: +#line 277 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 2006 "y.tab.c" /* yacc.c:1646 */ + break; + + case 87: +#line 278 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_IN, (yyvsp[-3]).parse, (yyvsp[0]).parse ); yymode( SCAN_COND ); } +#line 2012 "y.tab.c" /* yacc.c:1646 */ + break; + + case 88: +#line 279 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 2018 "y.tab.c" /* yacc.c:1646 */ + break; + + case 89: +#line 280 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = peval( EXPR_NOT, (yyvsp[0]).parse, pnull() ); } +#line 2024 "y.tab.c" /* yacc.c:1646 */ + break; + + case 90: +#line 281 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CONDB ); } +#line 2030 "y.tab.c" /* yacc.c:1646 */ + break; + + case 91: +#line 282 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[-1]).parse; } +#line 2036 "y.tab.c" /* yacc.c:1646 */ + break; + + case 92: +#line 293 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = P0; } +#line 2042 "y.tab.c" /* yacc.c:1646 */ + break; + + case 93: +#line 295 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnode( (yyvsp[-1]).parse, (yyvsp[0]).parse ); } +#line 2048 "y.tab.c" /* yacc.c:1646 */ + break; + + case 94: +#line 298 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_CASE ); } +#line 2054 "y.tab.c" /* yacc.c:1646 */ + break; + + case 95: +#line 298 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_NORMAL ); } +#line 2060 "y.tab.c" /* yacc.c:1646 */ + break; + + case 96: +#line 299 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = psnode( (yyvsp[-3]).string, (yyvsp[0]).parse ); } +#line 2066 "y.tab.c" /* yacc.c:1646 */ + break; + + case 97: +#line 308 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnode( P0, (yyvsp[0]).parse ); } +#line 2072 "y.tab.c" /* yacc.c:1646 */ + break; + + case 98: +#line 310 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnode( (yyvsp[0]).parse, (yyvsp[-2]).parse ); } +#line 2078 "y.tab.c" /* yacc.c:1646 */ + break; + + case 99: +#line 320 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 2084 "y.tab.c" /* yacc.c:1646 */ + break; + + case 100: +#line 324 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnull(); } +#line 2090 "y.tab.c" /* yacc.c:1646 */ + break; + + case 101: +#line 326 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pappend( (yyvsp[-1]).parse, (yyvsp[0]).parse ); } +#line 2096 "y.tab.c" /* yacc.c:1646 */ + break; + + case 102: +#line 330 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = plist( (yyvsp[0]).string ); } +#line 2102 "y.tab.c" /* yacc.c:1646 */ + break; + + case 103: +#line 331 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = yymode( SCAN_CALL ); } +#line 2108 "y.tab.c" /* yacc.c:1646 */ + break; + + case 104: +#line 332 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[-1]).parse; yymode( (yyvsp[-2]).number ); } +#line 2114 "y.tab.c" /* yacc.c:1646 */ + break; + + case 105: +#line 340 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 2120 "y.tab.c" /* yacc.c:1646 */ + break; + + case 106: +#line 341 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = prule( (yyvsp[-2]).string, (yyvsp[0]).parse ); } +#line 2126 "y.tab.c" /* yacc.c:1646 */ + break; + + case 107: +#line 342 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 2132 "y.tab.c" /* yacc.c:1646 */ + break; + + case 108: +#line 343 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pon( (yyvsp[-3]).parse, prule( (yyvsp[-2]).string, (yyvsp[0]).parse ) ); } +#line 2138 "y.tab.c" /* yacc.c:1646 */ + break; + + case 109: +#line 344 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 2144 "y.tab.c" /* yacc.c:1646 */ + break; + + case 110: +#line 345 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pon( (yyvsp[-3]).parse, (yyvsp[0]).parse ); } +#line 2150 "y.tab.c" /* yacc.c:1646 */ + break; + + case 111: +#line 355 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = 0; } +#line 2156 "y.tab.c" /* yacc.c:1646 */ + break; + + case 112: +#line 357 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = (yyvsp[-1]).number | (yyvsp[0]).number; } +#line 2162 "y.tab.c" /* yacc.c:1646 */ + break; + + case 113: +#line 361 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_UPDATED; } +#line 2168 "y.tab.c" /* yacc.c:1646 */ + break; + + case 114: +#line 363 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_TOGETHER; } +#line 2174 "y.tab.c" /* yacc.c:1646 */ + break; + + case 115: +#line 365 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_IGNORE; } +#line 2180 "y.tab.c" /* yacc.c:1646 */ break; + case 116: +#line 367 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_QUIETLY; } +#line 2186 "y.tab.c" /* yacc.c:1646 */ + break; + + case 117: +#line 369 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_PIECEMEAL; } +#line 2192 "y.tab.c" /* yacc.c:1646 */ + break; -/* Line 1813 of yacc.c */ -#line 2111 "y.tab.c" + case 118: +#line 371 "jamgram.y" /* yacc.c:1646 */ + { (yyval).number = EXEC_EXISTING; } +#line 2198 "y.tab.c" /* yacc.c:1646 */ + break; + + case 119: +#line 380 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = pnull(); } +#line 2204 "y.tab.c" /* yacc.c:1646 */ + break; + + case 120: +#line 381 "jamgram.y" /* yacc.c:1646 */ + { yymode( SCAN_PUNCT ); } +#line 2210 "y.tab.c" /* yacc.c:1646 */ + break; + + case 121: +#line 382 "jamgram.y" /* yacc.c:1646 */ + { (yyval).parse = (yyvsp[0]).parse; } +#line 2216 "y.tab.c" /* yacc.c:1646 */ + break; + + +#line 2220 "y.tab.c" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -2129,7 +2238,7 @@ yyreduce: *++yyvsp = yyval; - /* Now `shift' the result of the reduction. Determine what state + /* Now 'shift' the result of the reduction. Determine what state that goes to, based on the state we popped back to and the rule number reduced by. */ @@ -2144,9 +2253,9 @@ yyreduce: goto yynewstate; -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ yyerrlab: /* Make sure we have latest lookahead translation. See comments at user semantic actions for why this is necessary. */ @@ -2197,20 +2306,20 @@ yyerrlab: if (yyerrstatus == 3) { /* If just tried and failed to reuse lookahead token after an - error, discard it. */ + error, discard it. */ if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } } /* Else will try to reuse lookahead token after shifting the error @@ -2229,7 +2338,7 @@ yyerrorlab: if (/*CONSTCOND*/ 0) goto yyerrorlab; - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYERROR. */ YYPOPSTACK (yylen); yylen = 0; @@ -2242,29 +2351,29 @@ yyerrorlab: | yyerrlab1 -- common code for both syntax error and YYERROR. | `-------------------------------------------------------------*/ yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ + yyerrstatus = 3; /* Each real token shifted decrements this. */ for (;;) { yyn = yypact[yystate]; if (!yypact_value_is_default (yyn)) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } /* Pop the current state because it cannot handle the error token. */ if (yyssp == yyss) - YYABORT; + YYABORT; yydestruct ("Error: popping", - yystos[yystate], yyvsp); + yystos[yystate], yyvsp); YYPOPSTACK (1); yystate = *yyssp; YY_STACK_PRINT (yyss, yyssp); @@ -2315,14 +2424,14 @@ yyreturn: yydestruct ("Cleanup: discarding lookahead", yytoken, &yylval); } - /* Do not reclaim the symbols of the rule which action triggered + /* Do not reclaim the symbols of the rule whose action triggered this YYABORT or YYACCEPT. */ YYPOPSTACK (yylen); YY_STACK_PRINT (yyss, yyssp); while (yyssp != yyss) { yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); + yystos[*yyssp], yyvsp); YYPOPSTACK (1); } #ifndef yyoverflow @@ -2333,8 +2442,5 @@ yyreturn: if (yymsg != yymsgbuf) YYSTACK_FREE (yymsg); #endif - /* Make sure YYID is used. */ - return YYID (yyresult); + return yyresult; } - - diff --git a/tools/build/src/engine/jamgram.h b/tools/build/src/engine/jamgram.h index 23111972c4..53b046dad4 100644 --- a/tools/build/src/engine/jamgram.h +++ b/tools/build/src/engine/jamgram.h @@ -1,19 +1,19 @@ -/* A Bison parser, made by GNU Bison 2.6.4. */ +/* A Bison parser, made by GNU Bison 3.0.4. */ /* Bison interface for Yacc-like parsers in C - - Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -26,75 +26,74 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ #ifndef YY_YY_Y_TAB_H_INCLUDED # define YY_YY_Y_TAB_H_INCLUDED -/* Enabling traces. */ +/* Debug traces. */ #ifndef YYDEBUG -# define YYDEBUG 1 +# define YYDEBUG 0 #endif #if YYDEBUG extern int yydebug; #endif -/* Tokens. */ +/* Token type. */ #ifndef YYTOKENTYPE # define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - _BANG_t = 258, - _BANG_EQUALS_t = 259, - _AMPER_t = 260, - _AMPERAMPER_t = 261, - _LPAREN_t = 262, - _RPAREN_t = 263, - _PLUS_EQUALS_t = 264, - _COLON_t = 265, - _SEMIC_t = 266, - _LANGLE_t = 267, - _LANGLE_EQUALS_t = 268, - _EQUALS_t = 269, - _RANGLE_t = 270, - _RANGLE_EQUALS_t = 271, - _QUESTION_EQUALS_t = 272, - _LBRACKET_t = 273, - _RBRACKET_t = 274, - ACTIONS_t = 275, - BIND_t = 276, - BREAK_t = 277, - CASE_t = 278, - CLASS_t = 279, - CONTINUE_t = 280, - DEFAULT_t = 281, - ELSE_t = 282, - EXISTING_t = 283, - FOR_t = 284, - IF_t = 285, - IGNORE_t = 286, - IN_t = 287, - INCLUDE_t = 288, - LOCAL_t = 289, - MODULE_t = 290, - ON_t = 291, - PIECEMEAL_t = 292, - QUIETLY_t = 293, - RETURN_t = 294, - RULE_t = 295, - SWITCH_t = 296, - TOGETHER_t = 297, - UPDATED_t = 298, - WHILE_t = 299, - _LBRACE_t = 300, - _BAR_t = 301, - _BARBAR_t = 302, - _RBRACE_t = 303, - ARG = 304, - STRING = 305 - }; + enum yytokentype + { + _BANG_t = 258, + _BANG_EQUALS_t = 259, + _AMPER_t = 260, + _AMPERAMPER_t = 261, + _LPAREN_t = 262, + _RPAREN_t = 263, + _PLUS_EQUALS_t = 264, + _COLON_t = 265, + _SEMIC_t = 266, + _LANGLE_t = 267, + _LANGLE_EQUALS_t = 268, + _EQUALS_t = 269, + _RANGLE_t = 270, + _RANGLE_EQUALS_t = 271, + _QUESTION_EQUALS_t = 272, + _LBRACKET_t = 273, + _RBRACKET_t = 274, + ACTIONS_t = 275, + BIND_t = 276, + BREAK_t = 277, + CASE_t = 278, + CLASS_t = 279, + CONTINUE_t = 280, + DEFAULT_t = 281, + ELSE_t = 282, + EXISTING_t = 283, + FOR_t = 284, + IF_t = 285, + IGNORE_t = 286, + IN_t = 287, + INCLUDE_t = 288, + LOCAL_t = 289, + MODULE_t = 290, + ON_t = 291, + PIECEMEAL_t = 292, + QUIETLY_t = 293, + RETURN_t = 294, + RULE_t = 295, + SWITCH_t = 296, + TOGETHER_t = 297, + UPDATED_t = 298, + WHILE_t = 299, + _LBRACE_t = 300, + _BAR_t = 301, + _BARBAR_t = 302, + _RBRACE_t = 303, + ARG = 304, + STRING = 305 + }; #endif /* Tokens. */ #define _BANG_t 258 @@ -146,29 +145,16 @@ extern int yydebug; #define ARG 304 #define STRING 305 - - +/* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef int YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 #endif + extern YYSTYPE yylval; -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ #endif /* !YY_YY_Y_TAB_H_INCLUDED */ diff --git a/tools/build/src/engine/jamgram.y b/tools/build/src/engine/jamgram.y index 2e980b8f74..8802b89b6c 100644 --- a/tools/build/src/engine/jamgram.y +++ b/tools/build/src/engine/jamgram.y @@ -164,16 +164,16 @@ rules : rule { $$.parse = $1.parse; } | rule rules { $$.parse = prules( $1.parse, $2.parse ); } - | LOCAL_t list assign_list_opt _SEMIC_t block - { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } + | LOCAL_t { yymode( SCAN_ASSIGN ); } list assign_list_opt _SEMIC_t { yymode( SCAN_NORMAL ); } block + { $$.parse = plocal( $3.parse, $4.parse, $7.parse ); } ; null : /* empty */ { $$.parse = pnull(); } ; -assign_list_opt : _EQUALS_t list - { $$.parse = $2.parse; $$.number = ASSIGN_SET; } +assign_list_opt : _EQUALS_t { yymode( SCAN_PUNCT ); } list + { $$.parse = $3.parse; $$.number = ASSIGN_SET; } | null { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } ; @@ -190,38 +190,41 @@ local_opt : LOCAL_t { $$.number = 0; } ; +else_opt : ELSE_t rule + { $$.parse = $2.parse; } + | /* empty */ + { $$.parse = pnull(); } + rule : _LBRACE_t block _RBRACE_t { $$.parse = $2.parse; } - | INCLUDE_t list _SEMIC_t - { $$.parse = pincl( $2.parse ); } - | ARG lol _SEMIC_t - { $$.parse = prule( $1.string, $2.parse ); } - | arg assign list _SEMIC_t - { $$.parse = pset( $1.parse, $3.parse, $2.number ); } - | arg ON_t list assign list _SEMIC_t - { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } - | RETURN_t list _SEMIC_t - { $$.parse = preturn( $2.parse ); } + | INCLUDE_t { yymode( SCAN_PUNCT ); } list _SEMIC_t + { $$.parse = pincl( $3.parse ); yymode( SCAN_NORMAL ); } + | ARG { yymode( SCAN_PUNCT ); } lol _SEMIC_t + { $$.parse = prule( $1.string, $3.parse ); yymode( SCAN_NORMAL ); } + | arg assign { yymode( SCAN_PUNCT ); } list _SEMIC_t + { $$.parse = pset( $1.parse, $4.parse, $2.number ); yymode( SCAN_NORMAL ); } + | arg ON_t { yymode( SCAN_ASSIGN ); } list assign { yymode( SCAN_PUNCT ); } list _SEMIC_t + { $$.parse = pset1( $1.parse, $4.parse, $7.parse, $5.number ); yymode( SCAN_NORMAL ); } + | RETURN_t { yymode( SCAN_PUNCT ); } list _SEMIC_t + { $$.parse = preturn( $3.parse ); yymode( SCAN_NORMAL ); } | BREAK_t _SEMIC_t { $$.parse = pbreak(); } | CONTINUE_t _SEMIC_t { $$.parse = pcontinue(); } - | FOR_t local_opt ARG IN_t list _LBRACE_t block _RBRACE_t - { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } - | SWITCH_t list _LBRACE_t cases _RBRACE_t - { $$.parse = pswitch( $2.parse, $4.parse ); } - | IF_t expr _LBRACE_t block _RBRACE_t - { $$.parse = pif( $2.parse, $4.parse, pnull() ); } - | MODULE_t list _LBRACE_t block _RBRACE_t - { $$.parse = pmodule( $2.parse, $4.parse ); } - | CLASS_t lol _LBRACE_t block _RBRACE_t - { $$.parse = pclass( $2.parse, $4.parse ); } - | WHILE_t expr _LBRACE_t block _RBRACE_t - { $$.parse = pwhile( $2.parse, $4.parse ); } - | IF_t expr _LBRACE_t block _RBRACE_t ELSE_t rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | local_opt RULE_t ARG arglist_opt rule - { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } + | FOR_t local_opt ARG IN_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t + { $$.parse = pfor( $3.string, $6.parse, $9.parse, $2.number ); } + | SWITCH_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } cases _RBRACE_t + { $$.parse = pswitch( $3.parse, $6.parse ); } + | IF_t { yymode( SCAN_CONDB ); } expr _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t else_opt + { $$.parse = pif( $3.parse, $6.parse, $8.parse ); } + | MODULE_t { yymode( SCAN_PUNCT ); } list _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t + { $$.parse = pmodule( $3.parse, $6.parse ); } + | CLASS_t { yymode( SCAN_PUNCT ); } lol _LBRACE_t { yymode( SCAN_NORMAL ); } block _RBRACE_t + { $$.parse = pclass( $3.parse, $6.parse ); } + | WHILE_t { yymode( SCAN_CONDB ); } expr { yymode( SCAN_NORMAL ); } _LBRACE_t block _RBRACE_t + { $$.parse = pwhile( $3.parse, $6.parse ); } + | local_opt RULE_t { yymode( SCAN_PUNCT ); } ARG { yymode( SCAN_PARAMS ); } arglist_opt { yymode( SCAN_NORMAL ); } rule + { $$.parse = psetc( $4.string, $8.parse, $6.parse, $1.number ); } | ON_t arg rule { $$.parse = pon( $2.parse, $3.parse ); } | ACTIONS_t eflags ARG bindlist _LBRACE_t @@ -250,33 +253,33 @@ assign : _EQUALS_t * expr - an expression for if */ expr : arg - { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } - | expr _EQUALS_t expr - { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } - | expr _BANG_EQUALS_t expr - { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } - | expr _LANGLE_t expr - { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } - | expr _LANGLE_EQUALS_t expr - { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } - | expr _RANGLE_t expr - { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } - | expr _RANGLE_EQUALS_t expr - { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } - | expr _AMPER_t expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr _AMPERAMPER_t expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr _BAR_t expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | expr _BARBAR_t expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | arg IN_t list - { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } - | _BANG_t expr - { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } - | _LPAREN_t expr _RPAREN_t - { $$.parse = $2.parse; } + { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); yymode( SCAN_COND ); } + | expr _EQUALS_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_EQUALS, $1.parse, $4.parse ); } + | expr _BANG_EQUALS_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_NOTEQ, $1.parse, $4.parse ); } + | expr _LANGLE_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_LESS, $1.parse, $4.parse ); } + | expr _LANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_LESSEQ, $1.parse, $4.parse ); } + | expr _RANGLE_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_MORE, $1.parse, $4.parse ); } + | expr _RANGLE_EQUALS_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_MOREEQ, $1.parse, $4.parse ); } + | expr _AMPER_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } + | expr _AMPERAMPER_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } + | expr _BAR_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } + | expr _BARBAR_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } + | arg IN_t { yymode( SCAN_PUNCT ); } list + { $$.parse = peval( EXPR_IN, $1.parse, $4.parse ); yymode( SCAN_COND ); } + | _BANG_t { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_NOT, $3.parse, pnull() ); } + | _LPAREN_t { yymode( SCAN_CONDB ); } expr _RPAREN_t + { $$.parse = $3.parse; } ; @@ -292,8 +295,8 @@ cases : /* empty */ { $$.parse = pnode( $1.parse, $2.parse ); } ; -case : CASE_t ARG _COLON_t block - { $$.parse = psnode( $2.string, $4.parse ); } +case : CASE_t { yymode( SCAN_CASE ); } ARG _COLON_t { yymode( SCAN_NORMAL ); } block + { $$.parse = psnode( $3.string, $6.parse ); } ; /* @@ -314,19 +317,19 @@ lol : list */ list : listp - { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } + { $$.parse = $1.parse; } ; listp : /* empty */ - { $$.parse = pnull(); yymode( SCAN_PUNCT ); } + { $$.parse = pnull(); } | listp arg { $$.parse = pappend( $1.parse, $2.parse ); } ; arg : ARG { $$.parse = plist( $1.string ); } - | _LBRACKET_t { yymode( SCAN_NORMAL ); } func _RBRACKET_t - { $$.parse = $3.parse; } + | _LBRACKET_t { $$.number = yymode( SCAN_CALL ); } func _RBRACKET_t + { $$.parse = $3.parse; yymode( $2.number ); } ; /* @@ -334,12 +337,12 @@ arg : ARG * This needs to be split cleanly out of 'rule' */ -func : ARG lol - { $$.parse = prule( $1.string, $2.parse ); } - | ON_t arg ARG lol - { $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); } - | ON_t arg RETURN_t list - { $$.parse = pon( $2.parse, $4.parse ); } +func : ARG { yymode( SCAN_PUNCT ); } lol + { $$.parse = prule( $1.string, $3.parse ); } + | ON_t arg ARG { yymode( SCAN_PUNCT ); } lol + { $$.parse = pon( $2.parse, prule( $3.string, $5.parse ) ); } + | ON_t arg RETURN_t { yymode( SCAN_PUNCT ); } list + { $$.parse = pon( $2.parse, $5.parse ); } ; @@ -375,8 +378,8 @@ eflag : UPDATED_t bindlist : /* empty */ { $$.parse = pnull(); } - | BIND_t list - { $$.parse = $2.parse; } + | BIND_t { yymode( SCAN_PUNCT ); } list + { $$.parse = $3.parse; } ; diff --git a/tools/build/src/engine/jamgram.yy b/tools/build/src/engine/jamgram.yy index a11556b522..640cc02dc3 100644 --- a/tools/build/src/engine/jamgram.yy +++ b/tools/build/src/engine/jamgram.yy @@ -118,16 +118,16 @@ rules : rule { $$.parse = $1.parse; } | rule rules { $$.parse = prules( $1.parse, $2.parse ); } - | `local` list assign_list_opt `;` block - { $$.parse = plocal( $2.parse, $3.parse, $5.parse ); } + | `local` { yymode( SCAN_ASSIGN ); } list assign_list_opt `;` { yymode( SCAN_NORMAL ); } block + { $$.parse = plocal( $3.parse, $4.parse, $7.parse ); } ; null : /* empty */ { $$.parse = pnull(); } ; -assign_list_opt : `=` list - { $$.parse = $2.parse; $$.number = ASSIGN_SET; } +assign_list_opt : `=` { yymode( SCAN_PUNCT ); } list + { $$.parse = $3.parse; $$.number = ASSIGN_SET; } | null { $$.parse = $1.parse; $$.number = ASSIGN_APPEND; } ; @@ -144,38 +144,41 @@ local_opt : `local` { $$.number = 0; } ; +else_opt : `else` rule + { $$.parse = $2.parse; } + | /* empty */ + { $$.parse = pnull(); } + rule : `{` block `}` { $$.parse = $2.parse; } - | `include` list `;` - { $$.parse = pincl( $2.parse ); } - | ARG lol `;` - { $$.parse = prule( $1.string, $2.parse ); } - | arg assign list `;` - { $$.parse = pset( $1.parse, $3.parse, $2.number ); } - | arg `on` list assign list `;` - { $$.parse = pset1( $1.parse, $3.parse, $5.parse, $4.number ); } - | `return` list `;` - { $$.parse = preturn( $2.parse ); } + | `include` { yymode( SCAN_PUNCT ); } list `;` + { $$.parse = pincl( $3.parse ); yymode( SCAN_NORMAL ); } + | ARG { yymode( SCAN_PUNCT ); } lol `;` + { $$.parse = prule( $1.string, $3.parse ); yymode( SCAN_NORMAL ); } + | arg assign { yymode( SCAN_PUNCT ); } list `;` + { $$.parse = pset( $1.parse, $4.parse, $2.number ); yymode( SCAN_NORMAL ); } + | arg `on` { yymode( SCAN_ASSIGN ); } list assign { yymode( SCAN_PUNCT ); } list `;` + { $$.parse = pset1( $1.parse, $4.parse, $7.parse, $5.number ); yymode( SCAN_NORMAL ); } + | `return` { yymode( SCAN_PUNCT ); } list `;` + { $$.parse = preturn( $3.parse ); yymode( SCAN_NORMAL ); } | `break` `;` { $$.parse = pbreak(); } | `continue` `;` { $$.parse = pcontinue(); } - | `for` local_opt ARG `in` list `{` block `}` - { $$.parse = pfor( $3.string, $5.parse, $7.parse, $2.number ); } - | `switch` list `{` cases `}` - { $$.parse = pswitch( $2.parse, $4.parse ); } - | `if` expr `{` block `}` - { $$.parse = pif( $2.parse, $4.parse, pnull() ); } - | `module` list `{` block `}` - { $$.parse = pmodule( $2.parse, $4.parse ); } - | `class` lol `{` block `}` - { $$.parse = pclass( $2.parse, $4.parse ); } - | `while` expr `{` block `}` - { $$.parse = pwhile( $2.parse, $4.parse ); } - | `if` expr `{` block `}` `else` rule - { $$.parse = pif( $2.parse, $4.parse, $7.parse ); } - | local_opt `rule` ARG arglist_opt rule - { $$.parse = psetc( $3.string, $5.parse, $4.parse, $1.number ); } + | `for` local_opt ARG `in` { yymode( SCAN_PUNCT ); } list `{` { yymode( SCAN_NORMAL ); } block `}` + { $$.parse = pfor( $3.string, $6.parse, $9.parse, $2.number ); } + | `switch` { yymode( SCAN_PUNCT ); } list `{` { yymode( SCAN_NORMAL ); } cases `}` + { $$.parse = pswitch( $3.parse, $6.parse ); } + | `if` { yymode( SCAN_CONDB ); } expr `{` { yymode( SCAN_NORMAL ); } block `}` else_opt + { $$.parse = pif( $3.parse, $6.parse, $8.parse ); } + | `module` { yymode( SCAN_PUNCT ); } list `{` { yymode( SCAN_NORMAL ); } block `}` + { $$.parse = pmodule( $3.parse, $6.parse ); } + | `class` { yymode( SCAN_PUNCT ); } lol `{` { yymode( SCAN_NORMAL ); } block `}` + { $$.parse = pclass( $3.parse, $6.parse ); } + | `while` { yymode( SCAN_CONDB ); } expr { yymode( SCAN_NORMAL ); } `{` block `}` + { $$.parse = pwhile( $3.parse, $6.parse ); } + | local_opt `rule` { yymode( SCAN_PUNCT ); } ARG { yymode( SCAN_PARAMS ); } arglist_opt { yymode( SCAN_NORMAL ); } rule + { $$.parse = psetc( $4.string, $8.parse, $6.parse, $1.number ); } | `on` arg rule { $$.parse = pon( $2.parse, $3.parse ); } | `actions` eflags ARG bindlist `{` @@ -204,33 +207,33 @@ assign : `=` * expr - an expression for if */ expr : arg - { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); } - | expr `=` expr - { $$.parse = peval( EXPR_EQUALS, $1.parse, $3.parse ); } - | expr `!=` expr - { $$.parse = peval( EXPR_NOTEQ, $1.parse, $3.parse ); } - | expr `<` expr - { $$.parse = peval( EXPR_LESS, $1.parse, $3.parse ); } - | expr `<=` expr - { $$.parse = peval( EXPR_LESSEQ, $1.parse, $3.parse ); } - | expr `>` expr - { $$.parse = peval( EXPR_MORE, $1.parse, $3.parse ); } - | expr `>=` expr - { $$.parse = peval( EXPR_MOREEQ, $1.parse, $3.parse ); } - | expr `&` expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr `&&` expr - { $$.parse = peval( EXPR_AND, $1.parse, $3.parse ); } - | expr `|` expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | expr `||` expr - { $$.parse = peval( EXPR_OR, $1.parse, $3.parse ); } - | arg `in` list - { $$.parse = peval( EXPR_IN, $1.parse, $3.parse ); } - | `!` expr - { $$.parse = peval( EXPR_NOT, $2.parse, pnull() ); } - | `(` expr `)` - { $$.parse = $2.parse; } + { $$.parse = peval( EXPR_EXISTS, $1.parse, pnull() ); yymode( SCAN_COND ); } + | expr `=` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_EQUALS, $1.parse, $4.parse ); } + | expr `!=` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_NOTEQ, $1.parse, $4.parse ); } + | expr `<` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_LESS, $1.parse, $4.parse ); } + | expr `<=` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_LESSEQ, $1.parse, $4.parse ); } + | expr `>` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_MORE, $1.parse, $4.parse ); } + | expr `>=` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_MOREEQ, $1.parse, $4.parse ); } + | expr `&` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } + | expr `&&` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_AND, $1.parse, $4.parse ); } + | expr `|` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } + | expr `||` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_OR, $1.parse, $4.parse ); } + | arg `in` { yymode( SCAN_PUNCT ); } list + { $$.parse = peval( EXPR_IN, $1.parse, $4.parse ); yymode( SCAN_COND ); } + | `!` { yymode( SCAN_CONDB ); } expr + { $$.parse = peval( EXPR_NOT, $3.parse, pnull() ); } + | `(` { yymode( SCAN_CONDB ); } expr `)` + { $$.parse = $3.parse; } ; @@ -246,8 +249,8 @@ cases : /* empty */ { $$.parse = pnode( $1.parse, $2.parse ); } ; -case : `case` ARG `:` block - { $$.parse = psnode( $2.string, $4.parse ); } +case : `case` { yymode( SCAN_CASE ); } ARG `:` { yymode( SCAN_NORMAL ); } block + { $$.parse = psnode( $3.string, $6.parse ); } ; /* @@ -268,19 +271,19 @@ lol : list */ list : listp - { $$.parse = $1.parse; yymode( SCAN_NORMAL ); } + { $$.parse = $1.parse; } ; listp : /* empty */ - { $$.parse = pnull(); yymode( SCAN_PUNCT ); } + { $$.parse = pnull(); } | listp arg { $$.parse = pappend( $1.parse, $2.parse ); } ; arg : ARG { $$.parse = plist( $1.string ); } - | `[` { yymode( SCAN_NORMAL ); } func `]` - { $$.parse = $3.parse; } + | `[` { $$.number = yymode( SCAN_CALL ); } func `]` + { $$.parse = $3.parse; yymode( $2.number ); } ; /* @@ -288,12 +291,12 @@ arg : ARG * This needs to be split cleanly out of 'rule' */ -func : ARG lol - { $$.parse = prule( $1.string, $2.parse ); } - | `on` arg ARG lol - { $$.parse = pon( $2.parse, prule( $3.string, $4.parse ) ); } - | `on` arg `return` list - { $$.parse = pon( $2.parse, $4.parse ); } +func : ARG { yymode( SCAN_PUNCT ); } lol + { $$.parse = prule( $1.string, $3.parse ); } + | `on` arg ARG { yymode( SCAN_PUNCT ); } lol + { $$.parse = pon( $2.parse, prule( $3.string, $5.parse ) ); } + | `on` arg `return` { yymode( SCAN_PUNCT ); } list + { $$.parse = pon( $2.parse, $5.parse ); } ; @@ -329,8 +332,8 @@ eflag : `updated` bindlist : /* empty */ { $$.parse = pnull(); } - | `bind` list - { $$.parse = $2.parse; } + | `bind` { yymode( SCAN_PUNCT ); } list + { $$.parse = $3.parse; } ; diff --git a/tools/build/src/engine/make1.c b/tools/build/src/engine/make1.c index 0876bdc914..cfebc2becc 100644 --- a/tools/build/src/engine/make1.c +++ b/tools/build/src/engine/make1.c @@ -514,6 +514,7 @@ static void make1c( state const * const pState ) { TARGET * const t = pState->t; CMD * const cmd = (CMD *)t->cmds; + int exec_flags = 0; if ( cmd ) { @@ -542,6 +543,35 @@ static void make1c( state const * const pState ) /* Increment the jobs running counter. */ ++cmdsrunning; + if ( ( globs.jobs == 1 ) && ( DEBUG_MAKEQ || + ( DEBUG_MAKE && !( cmd->rule->actions->flags & RULE_QUIETLY ) ) ) ) + { + OBJECT * action = cmd->rule->name; + OBJECT * target = list_front( lol_get( (LOL *)&cmd->args, 0 ) ); + + out_printf( "%s %s\n", object_str( action ), object_str( target ) ); + + /* Print out the command executed if given -d+2. */ + if ( DEBUG_EXEC ) + { + out_puts( cmd->buf->value ); + out_putc( '\n' ); + } + + /* We only need to flush the streams if there's likely to + * be a wait before it finishes. + */ + if ( ! globs.noexec && ! cmd->noop ) + { + out_flush(); + err_flush(); + } + } + else + { + exec_flags |= EXEC_CMD_QUIET; + } + /* Execute the actual build command or fake it if no-op. */ if ( globs.noexec || cmd->noop ) { @@ -552,7 +582,7 @@ static void make1c( state const * const pState ) } else { - exec_cmd( cmd->buf, make1c_closure, t, cmd->shell ); + exec_cmd( cmd->buf, exec_flags, make1c_closure, t, cmd->shell ); /* Wait until under the concurrent command count limit. */ /* FIXME: This wait could be skipped here and moved to just before @@ -572,11 +602,42 @@ static void make1c( state const * const pState ) /* Tally success/failure for those we tried to update. */ if ( t->progress == T_MAKE_RUNNING ) + { + /* Invert OK/FAIL target status when FAIL_EXPECTED has been applied. */ + if ( t->flags & T_FLAG_FAIL_EXPECTED && !globs.noexec ) + { + switch ( t->status ) + { + case EXEC_CMD_FAIL: t->status = EXEC_CMD_OK; break; + case EXEC_CMD_OK: t->status = EXEC_CMD_FAIL; break; + } + + /* Printing failure has to be delayed until the last + * action is completed for FAIL_EXPECTED targets. + * Do it here. + */ + if ( t->status == EXEC_CMD_FAIL ) + { + out_printf( "...failed %s ", object_str( t->actions->action->rule->name ) ); + out_printf( "%s", object_str( t->boundname ) ); + out_printf( "...\n" ); + } + + /* Handle -q */ + if ( t->status == EXEC_CMD_FAIL && globs.quitquick ) + ++quit; + + /* Delete the target on failure. */ + if ( !( t->flags & ( T_FLAG_PRECIOUS | T_FLAG_NOTFILE ) ) && + !unlink( object_str( t->boundname ) ) ) + out_printf( "...removing %s\n", object_str( t->boundname ) ); + } switch ( t->status ) { case EXEC_CMD_OK: ++counts->made; break; case EXEC_CMD_FAIL: ++counts->failed; break; } + } /* Tell parents their dependency has been built. */ { @@ -823,6 +884,7 @@ static void make1c_closure CMD * const cmd = (CMD *)t->cmds; char const * rule_name = 0; char const * target_name = 0; + int print_buffer = 0; assert( cmd ); @@ -833,16 +895,6 @@ static void make1c_closure /* Store the target's status. */ t->status = status_orig; - /* Invert OK/FAIL target status when FAIL_EXPECTED has been applied. */ - if ( t->flags & T_FLAG_FAIL_EXPECTED && !globs.noexec ) - { - switch ( t->status ) - { - case EXEC_CMD_FAIL: t->status = EXEC_CMD_OK; break; - case EXEC_CMD_OK: t->status = EXEC_CMD_FAIL; break; - } - } - /* Ignore failures for actions marked as 'ignore'. */ if ( t->status == EXEC_CMD_FAIL && cmd->rule->actions->flags & RULE_IGNORE ) @@ -857,8 +909,18 @@ static void make1c_closure ); } - out_action( rule_name, target_name, cmd->buf->value, cmd_stdout, cmd_stderr, - cmd_exit_reason ); + if ( rule_name == NULL || globs.jobs > 1 ) + out_action( rule_name, target_name, cmd->buf->value, cmd_stdout, + cmd_stderr, cmd_exit_reason ); + + /* If the process expired, make user aware with an explicit message, but do + * this only for non-quiet actions. + */ + if ( cmd_exit_reason == EXIT_TIMEOUT && target_name ) + out_printf( "%ld second time limit exceeded\n", globs.timeout ); + + out_flush(); + err_flush(); if ( !globs.noexec ) { @@ -873,7 +935,8 @@ static void make1c_closure } /* Print command text on failure. */ - if ( t->status == EXEC_CMD_FAIL && DEBUG_MAKE ) + if ( t->status == EXEC_CMD_FAIL && DEBUG_MAKE && + ! ( t->flags & T_FLAG_FAIL_EXPECTED ) ) { if ( !DEBUG_EXEC ) out_printf( "%s\n", cmd->buf->value ); @@ -891,7 +954,8 @@ static void make1c_closure ++intr; ++quit; } - if ( t->status == EXEC_CMD_FAIL && globs.quitquick ) + if ( t->status == EXEC_CMD_FAIL && globs.quitquick && + ! ( t->flags & T_FLAG_FAIL_EXPECTED ) ) ++quit; /* If the command was not successful remove all of its targets not marked as diff --git a/tools/build/src/engine/output.c b/tools/build/src/engine/output.c index 2d9f413823..395d6c6df9 100644 --- a/tools/build/src/engine/output.c +++ b/tools/build/src/engine/output.c @@ -122,12 +122,6 @@ void out_action out_putc( '\n' ); } - /* If the process expired, make user aware with an explicit message, but do - * this only for non-quiet actions. - */ - if ( exit_reason == EXIT_TIMEOUT && action ) - out_printf( "%ld second time limit exceeded\n", globs.timeout ); - /* Print out the command output, if requested, or if the program failed, but * only output for non-quiet actions. */ @@ -140,9 +134,6 @@ void out_action if ( err_d && ( globs.pipe_action & 2 /* STDERR_FILENO */ ) ) err_data( err_d ); } - - out_flush(); - err_flush(); } diff --git a/tools/build/src/engine/patchlevel.h b/tools/build/src/engine/patchlevel.h index 0f345ea94d..a9e97affb1 100644 --- a/tools/build/src/engine/patchlevel.h +++ b/tools/build/src/engine/patchlevel.h @@ -7,11 +7,11 @@ /* Keep JAMVERSYM in sync with VERSION. */ /* It can be accessed as $(JAMVERSION) in the Jamfile. */ -#define VERSION_MAJOR 2015 -#define VERSION_MINOR 7 +#define VERSION_MAJOR 2018 +#define VERSION_MINOR 2 #define VERSION_PATCH 0 -#define VERSION_MAJOR_SYM "2015" -#define VERSION_MINOR_SYM "07" +#define VERSION_MAJOR_SYM "2018" +#define VERSION_MINOR_SYM "02" #define VERSION_PATCH_SYM "00" -#define VERSION "2015.07" -#define JAMVERSYM "JAMVERSION=2015.07" +#define VERSION "2018.02" +#define JAMVERSYM "JAMVERSION=2018.02" diff --git a/tools/build/src/engine/scan.c b/tools/build/src/engine/scan.c index 860d98871a..0c27b4bedf 100644 --- a/tools/build/src/engine/scan.c +++ b/tools/build/src/engine/scan.c @@ -57,9 +57,11 @@ static char * symdump( YYSTYPE * ); * Set parser mode: normal, string, or keyword. */ -void yymode( int n ) +int yymode( int n ) { + int result = scanmode; scanmode = n; + return result; } @@ -189,6 +191,35 @@ int yyline() return EOF; } +/* This allows us to get an extra character of lookahead. + * There are a few places where we need to look ahead two + * characters and yyprev only guarantees a single character + * of putback. + */ +int yypeek() +{ + if ( *incp->string ) + { + return *incp->string; + } + else if ( incp->strings ) + { + if ( *incp->strings ) + return **incp->strings; + } + else if ( incp->file ) + { + /* Don't bother opening the file. yypeek is + * only used in special cases and never at the + * beginning of a file. + */ + int ch = fgetc( incp->file ); + if ( ch != EOF ) + ungetc( ch, incp->file ); + return ch; + } + return EOF; +} /* * yylex() - set yylval to current token; return its type. @@ -205,6 +236,20 @@ int yyline() #define yychar() ( *incp->string ? *incp->string++ : yyline() ) #define yyprev() ( incp->string-- ) +static int use_new_scanner = 0; +static int expect_whitespace; + +#define yystartkeyword() if(use_new_scanner) break; else token_warning() +#define yyendkeyword() if(use_new_scanner) break; else if ( 1 ) { expect_whitespace = 1; continue; } else (void)0 + +void do_token_warning() +{ + out_printf( "%s:%d: %s %s\n", object_str( yylval.file ), yylval.line, "Unescaped special character in", + symdump( &yylval ) ); +} + +#define token_warning() has_token_warning = 1 + int yylex() { int c; @@ -271,6 +316,12 @@ int yylex() struct keyword * k; int inquote = 0; int notkeyword; + int hastoken = 0; + int hasquote = 0; + int ingrist = 0; + int invarexpand = 0; + int expect_whitespace = 0; + int has_token_warning = 0; /* Eat white space. */ for ( ; ; ) @@ -294,7 +345,7 @@ int yylex() c0 = c1; c1 = yychar(); } - c = c1; + c = yychar(); } else { @@ -322,17 +373,262 @@ int yylex() ( ( c != EOF ) && ( b < buf + sizeof( buf ) ) && - ( inquote || !isspace( c ) ) + ( inquote || invarexpand || !isspace( c ) ) ) { + if ( expect_whitespace || ( isspace( c ) && ! inquote ) ) + { + token_warning(); + expect_whitespace = 0; + } + if ( !inquote && !invarexpand ) + { + if ( scanmode == SCAN_COND || scanmode == SCAN_CONDB ) + { + if ( hastoken && ( c == '=' || c == '<' || c == '>' || c == '!' || c == '(' || c == ')' || c == '&' || c == '|' ) ) + { + /* Don't treat > as special if we started with a grist. */ + if ( ! ( scanmode == SCAN_CONDB && ingrist == 1 && c == '>' ) ) + { + yystartkeyword(); + } + } + else if ( c == '=' || c == '(' || c == ')' ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + } + else if ( c == '!' || ( scanmode == SCAN_COND && ( c == '<' || c == '>' ) ) ) + { + *b++ = c; + if ( ( c = yychar() ) == '=' ) + { + *b++ = c; + c = yychar(); + } + yyendkeyword(); + } + else if ( c == '&' || c == '|' ) + { + *b++ = c; + if ( yychar() == c ) + { + *b++ = c; + c = yychar(); + } + yyendkeyword(); + } + } + else if ( scanmode == SCAN_PARAMS ) + { + if ( c == '*' || c == '+' || c == '?' || c == '(' || c == ')' ) + { + if ( !hastoken ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + } + else + { + yystartkeyword(); + } + } + } + else if ( scanmode == SCAN_XASSIGN && ! hastoken ) + { + if ( c == '=' ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + } + else if ( c == '+' || c == '?' ) + { + if ( yypeek() == '=' ) + { + *b++ = c; + *b++ = yychar(); + c = yychar(); + yyendkeyword(); + } + } + } + else if ( scanmode == SCAN_NORMAL || scanmode == SCAN_ASSIGN ) + { + if ( c == '=' ) + { + if ( !hastoken ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + } + else + { + yystartkeyword(); + } + } + else if ( c == '+' || c == '?' ) + { + if ( yypeek() == '=' ) + { + if ( hastoken ) + { + yystartkeyword(); + } + else + { + *b++ = c; + *b++ = yychar(); + c = yychar(); + yyendkeyword(); + } + } + } + } + if ( scanmode != SCAN_CASE && ( c == ';' || c == '{' || c == '}' || + ( scanmode != SCAN_PARAMS && ( c == '[' || c == ']' ) ) ) ) + { + if ( ! hastoken ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + } + else + { + yystartkeyword(); + } + } + else if ( c == ':' ) + { + if ( ! hastoken ) + { + *b++ = c; + c = yychar(); + yyendkeyword(); + break; + } + else if ( hasquote ) + { + /* Special rules for ':' do not apply after we quote anything. */ + yystartkeyword(); + } + else if ( ingrist == 0 ) + { + int next = yychar(); + int is_win_path = 0; + int is_conditional = 0; + if ( next == '\\' ) + { + if( yypeek() == '\\' ) + { + is_win_path = 1; + } + } + else if ( next == '/' ) + { + is_win_path = 1; + } + yyprev(); + if ( is_win_path ) + { + /* Accept windows paths iff they are at the start or immediately follow a grist. */ + if ( b > buf && isalpha( b[ -1 ] ) && ( b == buf + 1 || b[ -2 ] == '>' ) ) + { + is_win_path = 1; + } + else + { + is_win_path = 0; + } + } + if ( next == '<' ) + { + /* Accept conditionals only for tokens that start with "<" or "!<" */ + if ( b > buf && buf[ 0 ] == '<' || + ( b > buf + 1 && buf[ 0 ] == '!' && buf[ 1 ] == '<' )) + { + is_conditional = 1; + } + } + if ( !is_conditional && !is_win_path ) + { + yystartkeyword(); + } + } + } + } + hastoken = 1; if ( c == '"' ) { /* begin or end " */ inquote = !inquote; + hasquote = 1; notkeyword = 1; } else if ( c != '\\' ) { + if ( !invarexpand && c == '<' ) + { + if ( ingrist == 0 ) ingrist = 1; + else ingrist = -1; + } + else if ( !invarexpand && c == '>' ) + { + if ( ingrist == 1 ) ingrist = 0; + else ingrist = -1; + } + else if ( c == '$' ) + { + if ( ( c = yychar() ) == EOF ) + { + *b++ = '$'; + break; + } + else if ( c == '(' ) + { + /* inside $(), we only care about quotes */ + *b++ = '$'; + c = '('; + ++invarexpand; + } + else + { + c = '$'; + yyprev(); + } + } + else if ( c == '@' ) + { + if ( ( c = yychar() ) == EOF ) + { + *b++ = '@'; + break; + } + else if ( c == '(' ) + { + /* inside @(), we only care about quotes */ + *b++ = '@'; + c = '('; + ++invarexpand; + } + else + { + c = '@'; + yyprev(); + } + } + else if ( invarexpand && c == '(' ) + { + ++invarexpand; + } + else if ( invarexpand && c == ')' ) + { + --invarexpand; + } /* normal char */ *b++ = c; } @@ -357,6 +653,10 @@ int yylex() c = yychar(); } + /* Automatically switch modes after reading the token. */ + if ( scanmode == SCAN_CONDB ) + scanmode = SCAN_COND; + /* Check obvious errors. */ if ( b == buf + sizeof( buf ) ) { @@ -381,7 +681,7 @@ int yylex() *b = 0; yylval.type = ARG; - if ( !notkeyword && !( isalpha( *buf ) && ( scanmode == SCAN_PUNCT ) ) ) + if ( !notkeyword && !( isalpha( *buf ) && ( scanmode == SCAN_PUNCT || scanmode == SCAN_PARAMS || scanmode == SCAN_ASSIGN ) ) ) for ( k = keywords; k->word; ++k ) if ( ( *buf == *k->word ) && !strcmp( k->word, buf ) ) { @@ -392,6 +692,12 @@ int yylex() if ( yylval.type == ARG ) yylval.string = object_new( buf ); + + if ( scanmode == SCAN_NORMAL && yylval.type == ARG ) + scanmode = SCAN_XASSIGN; + + if ( has_token_warning ) + do_token_warning(); } if ( DEBUG_SCAN ) diff --git a/tools/build/src/engine/scan.h b/tools/build/src/engine/scan.h index 03fd8f3a74..8948a545ef 100644 --- a/tools/build/src/engine/scan.h +++ b/tools/build/src/engine/scan.h @@ -47,7 +47,7 @@ typedef struct _YYSTYPE extern YYSTYPE yylval; -void yymode( int n ); +int yymode( int n ); void yyerror( char const * s ); int yyanyerrors(); void yyfparse( OBJECT * s ); @@ -61,3 +61,10 @@ void yyinput_last_read_token( OBJECT * * name, int * line ); #define SCAN_NORMAL 0 /* normal parsing */ #define SCAN_STRING 1 /* look only for matching } */ #define SCAN_PUNCT 2 /* only punctuation keywords */ +#define SCAN_COND 3 /* look for operators that can appear in conditions. */ +#define SCAN_PARAMS 4 /* The parameters of a rule "()*?+" */ +#define SCAN_CALL 5 /* Inside a rule call. [].*/ +#define SCAN_CASE 6 /* A case statement. We only recognize ':' as special. */ +#define SCAN_CONDB 7 /* The beginning of a condition (ignores leading comparison operators, so that if in $(y) works.)*/ +#define SCAN_ASSIGN 8 /* The list may be terminated by an assignment operator. */ +#define SCAN_XASSIGN 9 /* The next token might be an assignment, but to token afterwards cannot. */ diff --git a/tools/build/src/engine/timestamp.c b/tools/build/src/engine/timestamp.c index b6fd906efb..679cf29828 100644 --- a/tools/build/src/engine/timestamp.c +++ b/tools/build/src/engine/timestamp.c @@ -132,6 +132,16 @@ void timestamp_current( timestamp * const t ) FILETIME ft; GetSystemTimeAsFileTime( &ft ); timestamp_from_filetime( t, &ft ); +#elif defined(_POSIX_TIMERS) && defined(CLOCK_REALTIME) && \ + (!defined(__GLIBC__) || (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 17)) + /* Some older versions of XCode define _POSIX_TIMERS, but don't actually + * have clock_gettime. Check CLOCK_REALTIME as well. Prior to glibc 2.17, + * clock_gettime requires -lrt. This is a non-critical feature, so + * we just disable it to keep bootstrapping simple. + */ + struct timespec ts; + clock_gettime( CLOCK_REALTIME, &ts ); + timestamp_init( t, ts.tv_sec, ts.tv_nsec ); #else /* OS_NT */ timestamp_init( t, time( 0 ), 0 ); #endif /* OS_NT */ diff --git a/tools/build/src/kernel/errors.jam b/tools/build/src/kernel/errors.jam index 9563396eca..531f37f362 100644 --- a/tools/build/src/kernel/errors.jam +++ b/tools/build/src/kernel/errors.jam @@ -45,7 +45,7 @@ rule backtrace ( skip-frames prefix messages * : * ) while $(bt) { local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ; - ECHO $(bt[1]):$(bt[2]): "in" $(bt[4]) "from module" $(m) ; + ECHO "$(bt[1]):$(bt[2]):" "in" $(bt[4]) "from module" $(m) ; # The first time through, print each argument on a separate line. for local n in $(args) @@ -120,7 +120,7 @@ rule error-skip-frames ( skip-frames messages * : * ) { if ! $(.disabled) { - backtrace $(skip-frames) error: $(messages) : $(2) : $(3) : $(4) : $(5) + backtrace $(skip-frames) "error:" $(messages) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ; EXIT ; @@ -156,7 +156,7 @@ rule error ( messages * : * ) { if ! $(first-printed) { - ECHO error: $($(n)) ; + ECHO "error:" $($(n)) ; first-printed = true ; } else @@ -191,7 +191,7 @@ rule user-error ( messages * : * ) # rule warning { - backtrace 2 warning: $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + backtrace 2 "warning:" $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ; } @@ -232,11 +232,11 @@ rule nearest-user-location ( ) while $(bt) && ! $(result) { local m = [ MATCH ^(.+)\\.$ : $(bt[3]) ] ; - local user-modules = ([Jj]amroot(.jam|.v2|)|([Jj]amfile(.jam|.v2|)|user-config.jam|site-config.jam|project-config.jam|project-root.jam) ; + local user-modules = "([Jj]amroot(.jam|.v2|)|([Jj]amfile(.jam|.v2|)|user-config.jam|site-config.jam|project-config.jam|project-root.jam)" ; if [ MATCH $(user-modules) : $(bt[1]:D=) ] { - result = $(bt[1]):$(bt[2]) ; + result = "$(bt[1]):$(bt[2])" ; } bt = $(bt[5-]) ; } @@ -250,7 +250,7 @@ if NEAREST_USER_LOCATION in [ RULENAMES ] rule nearest-user-location ( ) { local r = [ NEAREST_USER_LOCATION ] ; - return $(r[1]):$(r[2]) ; + return "$(r[1]):$(r[2])" ; } } diff --git a/tools/build/src/kernel/modules.jam b/tools/build/src/kernel/modules.jam index 251bdf1918..6915fa7509 100644 --- a/tools/build/src/kernel/modules.jam +++ b/tools/build/src/kernel/modules.jam @@ -27,7 +27,7 @@ local rule run-module-test ( m ) local tested-modules = [ modules.peek modules : .tested ] ; if ( ! $(m) in $(tested-modules) ) # Avoid recursive test invocations. - && ( ( --debug in $(argv) ) || ( --debug-module=$(m) in $(argv) ) ) + && ( ( --debug in $(argv) ) || ( "--debug-module=$(m)" in $(argv) ) ) { modules.poke modules : .tested : $(tested-modules) $(m) ; @@ -36,7 +36,7 @@ local rule run-module-test ( m ) local argv = [ peek : ARGV ] ; if ! ( --quiet in $(argv) ) && ( --debug-tests in $(argv) ) { - ECHO warning: no __test__ rule defined in module $(m) ; + ECHO "warning:" no __test__ rule defined in module $(m) ; } } else @@ -201,7 +201,7 @@ rule load ( { import errors ; errors.error loading \"$(module-name)\" - : circular module loading dependency: + : circular module loading "dependency:" : $(.loading)" ->" $(module-name) ; } } diff --git a/tools/build/src/tools/asciidoctor.jam b/tools/build/src/tools/asciidoctor.jam index d62b335b82..5c5f90e0e5 100644 --- a/tools/build/src/tools/asciidoctor.jam +++ b/tools/build/src/tools/asciidoctor.jam @@ -186,7 +186,7 @@ class asciidoctor-generator : generator for local p in [ $(property-set).raw ] { if $(p:G) in - + { raw-set += $(p) ; } @@ -201,7 +201,6 @@ class asciidoctor-generator : generator _ = " " ; toolset.flags asciidoctor ATTRIBUTE : ; toolset.flags asciidoctor DOCTYPE : ; -toolset.flags asciidoctor INCLUDES : ; toolset.flags asciidoctor BACKEND : ; toolset.flags asciidoctor FLAGS : ; @@ -209,5 +208,5 @@ feature.compose pdf : "-r asciidoctor-pdf" ; actions convert { - "$(ASCIIDOCTOR)" -o$(_)"$(<:D=)" -D$(_)"$(<:D)" -b$(_)"$(BACKEND)" -a$(_)"$(ATTRIBUTE)" -d$(_)"$(DOCTYPE)" -I$(_)"$(INCLUDES)" $(FLAGS) "$(>)" + "$(ASCIIDOCTOR)" -o$(_)"$(<:D=)" -D$(_)"$(<:D)" -b$(_)"$(BACKEND)" -a$(_)"$(ATTRIBUTE)" -d$(_)"$(DOCTYPE)" $(FLAGS) "$(>)" } diff --git a/tools/build/src/tools/bison.jam b/tools/build/src/tools/bison.jam index 0689d4bd89..96b86a327c 100644 --- a/tools/build/src/tools/bison.jam +++ b/tools/build/src/tools/bison.jam @@ -4,8 +4,8 @@ import generators ; import feature ; +import toolset : flags ; import type ; -import property ; feature.feature bison.prefix : : free ; type.register Y : y ; @@ -17,16 +17,10 @@ rule init ( ) { } -rule bison ( dst dst_header : src : properties * ) -{ - local r = [ property.select bison.prefix : $(properties) ] ; - if $(r) - { - PREFIX_OPT on $(<) = -p $(r:G=) ; - } -} +flags bison.bison PREFIX ; +_ = " " ; actions bison { - bison $(PREFIX_OPT) -d -o $(<[1]) $(>) + bison -p$(_)$(PREFIX) -d -o $(<[1]) $(>) } diff --git a/tools/build/src/tools/boostbook.jam b/tools/build/src/tools/boostbook.jam index 43e7366daa..b529b0f44a 100644 --- a/tools/build/src/tools/boostbook.jam +++ b/tools/build/src/tools/boostbook.jam @@ -33,6 +33,7 @@ import generators ; import make ; import modules ; import os ; +import param ; import path ; import print ; import project ; @@ -94,7 +95,7 @@ rule init ( find-tools $(docbook-xsl-dir) : $(docbook-dtd-dir) : $(boostbook-dir) ; # Register generators only if we were called via "using boostbook ;" - local reg-gen = generators.register-standard ; + local reg-gen = generators.register-xslt ; $(reg-gen) boostbook.dtdxml-to-boostbook : DTDXML : XML ; $(reg-gen) boostbook.boostbook-to-docbook : XML : DOCBOOK ; $(reg-gen) boostbook.boostbook-to-tests : XML : TESTS ; @@ -168,8 +169,8 @@ local rule modify-config ( ) rule print-error ( location message * ) { - ECHO error: at $(location) ; - ECHO error: $(message) ; + ECHO "error:" at $(location) ; + ECHO "error:" $(message) ; EXIT ; } @@ -202,12 +203,12 @@ rule check-docbook-xsl-dir ( ) { if ! [ path.glob $(.docbook-xsl-dir) : common/common.xsl ] { - .error-message = [ make-error BoostBook: could not find docbook XSL stylesheets - in: [ path.native $(.docbook-xsl-dir) ] ] ; + .error-message = [ make-error "BoostBook:" could not find docbook XSL stylesheets + "in:" [ path.native $(.docbook-xsl-dir) ] ] ; } else if $(.debug-configuration) { - ECHO notice: BoostBook: found docbook XSL stylesheets in: [ + ECHO "notice:" "BoostBook:" found docbook XSL stylesheets "in:" [ path.native $(.docbook-xsl-dir) ] ; } } @@ -220,12 +221,12 @@ rule check-docbook-dtd-dir ( ) { if ! [ path.glob $(.docbook-dtd-dir) : docbookx.dtd ] { - .error-message = [ make-error BoostBook: could not find docbook DTD in: [ + .error-message = [ make-error "BoostBook:" could not find docbook DTD "in:" [ path.native $(.docbook-dtd-dir) ] ] ; } else if $(.debug-configuration) { - ECHO notice: BoostBook: found docbook DTD in: [ path.native + ECHO "notice:" "BoostBook:" found docbook DTD "in:" [ path.native $(.docbook-dtd-dir) ] ; } } @@ -236,16 +237,16 @@ rule check-boostbook-xsl-dir ( ) { if ! $(.boostbook-xsl-dir) { - .error-message = [ make-error BoostBook: could not find boostbook XSL stylesheets. ] ; + .error-message = [ make-error "BoostBook:" could not find boostbook XSL "stylesheets." ] ; } else if ! [ path.glob $(.boostbook-xsl-dir) : docbook.xsl ] { - .error-message = [ make-error BoostBook: could not find docbook XSL stylesheets in: + .error-message = [ make-error "BoostBook:" could not find docbook XSL stylesheets "in:" [ path.native $(.boostbook-xsl-dir) ] ] ; } else if $(.debug-configuration) { - ECHO notice: BoostBook: found boostbook XSL stylesheets in: [ + ECHO "notice:" "BoostBook:" found boostbook XSL stylesheets "in:" [ path.native $(.boostbook-xsl-dir) ] ; } } @@ -255,16 +256,16 @@ rule check-boostbook-dtd-dir ( ) { if ! $(.boostbook-dtd-dir) { - .error-message = [ make-error BoostBook: could not find boostbook DTD. ] ; + .error-message = [ make-error "BoostBook:" could not find boostbook DTD. ] ; } else if ! [ path.glob $(.boostbook-dtd-dir) : boostbook.dtd ] { - .error-message = [ make-error BoostBook: could not find boostbook DTD in: [ + .error-message = [ make-error "BoostBook:" could not find boostbook DTD "in:" [ path.native $(.boostbook-dtd-dir) ] ] ; } else if $(.debug-configuration) { - ECHO notice: BoostBook: found boostbook DTD in: [ path.native + ECHO "notice:" "BoostBook:" found boostbook DTD "in:" [ path.native $(.boostbook-dtd-dir) ] ; } } @@ -274,7 +275,7 @@ rule check-boostbook-dir ( boostbook-dir ? ) { if $(boostbook-dir) && ! [ path.glob $(boostbook-dir) : xsl ] { - .error-message = [ make-error BoostBook: could not find boostbook in: [ path.native + .error-message = [ make-error "BoostBook:" could not find boostbook "in:" [ path.native $(boostbook-dir) ] ] ; } } @@ -383,8 +384,8 @@ rule find-tools ( docbook-xsl-dir ? : docbook-dtd-dir ? : boostbook-dir ? ) if $(.debug-configuration) { - ECHO notice: Boost.Book: searching XSL/DTD "in" ; - ECHO notice: [ sequence.transform path.native : $(boostbook-dir) ] ; + ECHO "notice:" "Boost.Book:" searching XSL/DTD "in" ; + ECHO "notice:" [ sequence.transform path.native : $(boostbook-dir) ] ; } local boostbook-xsl-dir ; for local dir in $(boostbook-dir) @@ -509,7 +510,7 @@ rule format-catalog-path ( path ) { if [ os.name ] = NT { - drive = [ MATCH ^/(.):(.*)$ : $(path) ] ; + drive = [ MATCH "^/(.):(.*)$" : $(path) ] ; result = /cygdrive/$(drive[1])$(drive[2]) ; } } @@ -716,11 +717,14 @@ class boostbook-target-class : basic-target # Declare a boostbook target. # -rule boostbook ( target-name : sources * : requirements * : default-build * ) +rule boostbook ( target-name : sources * : requirements * : default-build * : + usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; return [ targets.create-metatarget boostbook-target-class : [ project.current ] : $(target-name) : $(sources) : $(requirements) : - $(default-build) ] ; + $(default-build) : $(usage-requirements) ] ; } diff --git a/tools/build/src/tools/bzip2.jam b/tools/build/src/tools/bzip2.jam index e6f9dcc134..a6f8ee460e 100644 --- a/tools/build/src/tools/bzip2.jam +++ b/tools/build/src/tools/bzip2.jam @@ -14,11 +14,11 @@ import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; import make ; import os ; @@ -113,18 +113,12 @@ rule init ( project bzip2 ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local source-path = [ property.select : $(options) ] ; - source-path = $(source-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; - local tag = [ property.select : $(options) ] ; - tag = $(tag:G=) ; - local build-name = [ property.select : $(options) ] ; - build-name = $(build-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local source-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + local tag = [ feature.get-values : $(options) ] ; + local build-name = [ feature.get-values : $(options) ] ; if ! $(library-path) && ! $(include-path) && ! $(source-path) && ! $(library-name) { @@ -148,7 +142,12 @@ rule init ( } else { - source-path ?= [ modules.peek : BZIP2_SOURCE ] ; + source-path ?= [ os.environ BZIP2_SOURCE ] ; + if $(source-path) + { + source-path = [ path.root [ path.make $(source-path) ] + [ path.pwd ] ] ; + } } if $(.configured.$(condition)) @@ -171,7 +170,7 @@ rule init ( build-name ?= bz2 ; library-id = [ CALC $(library-id) + 1 ] ; tag = [ MATCH ^@?(.*)$ : $(tag) ] ; - if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ] + if $(tag) { tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ; } diff --git a/tools/build/src/tools/clang-darwin.jam b/tools/build/src/tools/clang-darwin.jam index 9d01973622..5c175ae4d9 100644 --- a/tools/build/src/tools/clang-darwin.jam +++ b/tools/build/src/tools/clang-darwin.jam @@ -33,8 +33,7 @@ generators.register-c-compiler clang-darwin.compile.mm : OBJECTIVE_CPP : OBJ : < toolset.inherit-rules clang-darwin : gcc ; toolset.inherit-flags clang-darwin : gcc - : off on full space - off all on + : full x86/32 x86/64 ; @@ -65,8 +64,7 @@ rule init ( version ? : command * : options * ) : version $(version) ] ; common.handle-options clang-darwin : $(condition) : $(command) : $(options) ; - - gcc.init-link-flags clang darwin $(condition) ; + clang.init-cxxstd-flags clang-darwin : $(condition) : $(version) ; # - Ranlib. local ranlib = [ feature.get-values : $(options) ] ; @@ -79,42 +77,27 @@ rule init ( version ? : command * : options * ) SPACE = " " ; -toolset.flags clang-darwin.compile OPTIONS ; -toolset.flags clang-darwin.compile.c++ OPTIONS ; toolset.flags clang-darwin.compile.m OPTIONS ; toolset.flags clang-darwin.compile.mm OPTIONS ; toolset.flags clang-darwin.compile.mm OPTIONS ; -# toolset.flags clang-darwin.compile INCLUDES ; # Declare flags and action for compilation. -toolset.flags clang-darwin.compile OPTIONS off : -O0 ; -toolset.flags clang-darwin.compile OPTIONS speed : -O3 ; -toolset.flags clang-darwin.compile OPTIONS space : -Os ; # For clang, 'on' and 'full' are identical -toolset.flags clang-darwin.compile OPTIONS off : -fno-inline ; -toolset.flags clang-darwin.compile OPTIONS on : -Wno-inline ; toolset.flags clang-darwin.compile OPTIONS full : -Wno-inline ; -toolset.flags clang-darwin.compile OPTIONS off : -w ; -toolset.flags clang-darwin.compile OPTIONS on : -Wall ; -toolset.flags clang-darwin.compile OPTIONS all : -Wall -pedantic ; -toolset.flags clang-darwin.compile OPTIONS on : -Werror ; - -toolset.flags clang-darwin.compile OPTIONS on : -g ; -toolset.flags clang-darwin.compile OPTIONS on : -pg ; -toolset.flags clang-darwin.compile OPTIONS off : -fno-rtti ; - +# SJW 12/2017: Support for is widely inconsistant. +# shouldn't this be handled by the common gcc? toolset.flags clang-darwin.compile OPTIONS ; actions compile.c { - "$(CONFIG_COMMAND)" -x c $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" + "$(CONFIG_COMMAND)" -x c $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } actions compile.c++ { - "$(CONFIG_COMMAND)" -x c++ $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" + "$(CONFIG_COMMAND)" -x c++ $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } actions compile.m @@ -127,8 +110,6 @@ actions compile.mm "$(CONFIG_COMMAND)" -x objective-c++ $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } -flags clang-darwin ARFLAGS ; - # Default value. Mostly for the sake of clang-linux # that inherits from gcc, but does not has the same # logic to set the .AR variable. We can put the same @@ -172,8 +153,6 @@ actions piecemeal archive "$(.RANLIB)" "$(<)" } -flags clang-darwin.link USER_OPTIONS ; - # Declare actions for linking rule link ( targets * : sources * : properties * ) { diff --git a/tools/build/src/tools/clang-linux.jam b/tools/build/src/tools/clang-linux.jam index b1c2ad95b5..53c5749e53 100644 --- a/tools/build/src/tools/clang-linux.jam +++ b/tools/build/src/tools/clang-linux.jam @@ -36,9 +36,9 @@ type.set-generated-target-suffix PCH toolset.inherit-rules clang-linux : gcc ; toolset.inherit-flags clang-linux : gcc - : off on full - space speed - off all on ; + : full + multi/windows + ; if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { .debug-configuration = true ; @@ -60,8 +60,7 @@ rule init ( version ? : command * : options * ) { : version $(version) ] ; common.handle-options clang-linux : $(condition) : $(command) : $(options) ; - - gcc.init-link-flags clang linux $(condition) ; + clang.init-cxxstd-flags clang-linux : $(condition) : $(version) ; # - Ranlib. local ranlib = [ feature.get-values : $(options) ] ; @@ -75,27 +74,12 @@ rule init ( version ? : command * : options * ) { ############################################################################### # Flags -toolset.flags clang-linux.compile OPTIONS ; -toolset.flags clang-linux.compile.c++ OPTIONS ; - -toolset.flags clang-linux.compile OPTIONS off : ; -toolset.flags clang-linux.compile OPTIONS speed : -O3 ; -toolset.flags clang-linux.compile OPTIONS space : -Os ; - # note: clang silently ignores some of these inlining options -toolset.flags clang-linux.compile OPTIONS off : -fno-inline ; # For clang, 'on' and 'full' are identical. -toolset.flags clang-linux.compile OPTIONS on : -Wno-inline ; toolset.flags clang-linux.compile OPTIONS full : -Wno-inline ; -toolset.flags clang-linux.compile OPTIONS off : -w ; -toolset.flags clang-linux.compile OPTIONS on : -Wall ; -toolset.flags clang-linux.compile OPTIONS all : -Wall -pedantic ; -toolset.flags clang-linux.compile OPTIONS on : -Werror ; - -toolset.flags clang-linux.compile OPTIONS on : -g ; -toolset.flags clang-linux.compile OPTIONS on : -pg ; -toolset.flags clang-linux.compile OPTIONS off : -fno-rtti ; +toolset.flags clang-linux.compile OPTIONS multi/windows : -pthread ; +toolset.flags clang-linux.link OPTIONS multi/windows : -pthread ; ############################################################################### # C and C++ compilation diff --git a/tools/build/src/tools/clang-vxworks.jam b/tools/build/src/tools/clang-vxworks.jam index 203a3a320a..053f4fb55b 100644 --- a/tools/build/src/tools/clang-vxworks.jam +++ b/tools/build/src/tools/clang-vxworks.jam @@ -31,8 +31,7 @@ generators.override clang-vxworks.searched-lib-generator : searched-lib-generato toolset.inherit-rules clang-vxworks : gcc ; toolset.inherit-flags clang-vxworks : gcc - : off on full space - off all on + : full x86/32 x86/64 ; @@ -41,10 +40,6 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] { .debug-configuration = true ; } - -# vectorization diagnostics -feature vectorize : off on full ; - # Initializes the clang-vxworks toolset # version in optional # compile and link options allow you to specify addition command line options for each version @@ -69,9 +64,11 @@ rule init ( version ? : command * : options * ) common.handle-options clang-vxworks : $(condition) : $(command) : $(options) ; - gcc.init-link-flags clang-vxworks vxworks $(condition) ; - toolset.flags clang-vxworks.link .LD : $(linker) ; + + # - Archive builder. + local archiver = [ feature.get-values : $(options) ] ; + toolset.flags clang-vxworks.archive .AR $(condition) : $(archiver[1]) ; } SPACE = " " ; @@ -80,25 +77,9 @@ toolset.flags clang-vxworks.compile OPTIONS ; toolset.flags clang-vxworks.compile.c++ OPTIONS ; toolset.flags clang-vxworks.compile INCLUDES ; -# Declare flags and action for compilation. -toolset.flags clang-vxworks.compile OPTIONS off : -O0 ; -toolset.flags clang-vxworks.compile OPTIONS speed : -O3 ; -toolset.flags clang-vxworks.compile OPTIONS space : -Os ; - # For clang, 'on' and 'full' are identical -toolset.flags clang-vxworks.compile OPTIONS off : -fno-inline ; -toolset.flags clang-vxworks.compile OPTIONS on : -Wno-inline ; toolset.flags clang-vxworks.compile OPTIONS full : -Wno-inline ; -toolset.flags clang-vxworks.compile OPTIONS off : -w ; -toolset.flags clang-vxworks.compile OPTIONS on : -Wall ; -toolset.flags clang-vxworks.compile OPTIONS all : -Wall -pedantic ; -toolset.flags clang-vxworks.compile OPTIONS on : -Werror ; - -toolset.flags clang-vxworks.compile OPTIONS on : -g ; -toolset.flags clang-vxworks.compile OPTIONS on : -pg ; -toolset.flags clang-vxworks.compile OPTIONS off : -fno-rtti ; - toolset.flags clang-vxworks.compile OPTIONS ; @@ -114,8 +95,6 @@ actions compile.c++ -flags clang-vxworks ARFLAGS ; - # Default value. Mostly for the sake of clang-linux # that inherits from gcc, but does not has the same # logic to set the .AR variable. We can put the same @@ -129,8 +108,6 @@ actions piecemeal archive "$(.AR)" $(AROPTIONS) rcu "$(<)" "$(>)" } -flags clang-vxworks.link USER_OPTIONS ; - # Declare actions for linking rule link ( targets * : sources * : properties * ) { diff --git a/tools/build/src/tools/clang-win.jam b/tools/build/src/tools/clang-win.jam index 25a6d006da..2800e825e5 100644 --- a/tools/build/src/tools/clang-win.jam +++ b/tools/build/src/tools/clang-win.jam @@ -51,14 +51,14 @@ rule init ( version ? : # the compiler version import errors ; errors.error "Please set property for visual studio version!" ; } - local vc_version = [ MATCH vc([0-9]+) : $(compatibility) ] ; + local vc_version = [ MATCH "vc([0-9]+)" : $(compatibility) ] ; if ! $(vc_version) { errors.user-error "Invalid value for compatibility option:" $(compatibility) ; } - local m = [ MATCH ([0-9]+).* : $(version) ] ; + local m = [ MATCH "([0-9]+).*" : $(version) ] ; local major = $(m[1]) ; command = [ common.get-invocation-command clang-win : clang-cl.exe : diff --git a/tools/build/src/tools/clang.jam b/tools/build/src/tools/clang.jam index 2d89f3807a..26c95202a1 100644 --- a/tools/build/src/tools/clang.jam +++ b/tools/build/src/tools/clang.jam @@ -8,6 +8,9 @@ import feature ; import os ; import toolset ; +import sequence ; +import regex ; +import set ; feature.extend toolset : clang ; feature.subfeature toolset clang : platform : : propagated link-incompatible ; @@ -25,3 +28,33 @@ rule init ( * : * ) $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ; } } + + +local rule cxxstd-flags ( toolset : condition * : options * ) +{ + toolset.flags $(toolset).compile.c++ OPTIONS $(condition) : $(options) : unchecked ; + toolset.flags $(toolset).link OPTIONS $(condition) : $(options) : unchecked ; +} + +local rule version-ge ( lhs : rhs ) +{ + lhs = [ regex.split $(lhs) "[.]" ] ; + rhs = [ regex.split $(rhs) "[.]" ] ; + return [ sequence.compare $(rhs) : $(lhs) : numbers.less ] ; +} + +# Version specific flags +rule init-cxxstd-flags ( toolset : condition * : version ) +{ + local cxxstd = [ feature.values ] ; + local dialects = [ feature.values ] ; + dialects = [ set.difference $(dialects) : gnu iso ] ; + local std ; + if [ version-ge $(version) : 3.5 ] { std = 1z ; } + else if [ version-ge $(version) : 3.4 ] { std = 14 ; } + else if [ version-ge $(version) : 3.3 ] { std = 11 ; } + else { std = 03 ; } + cxxstd-flags $(toolset) : $(condition)/latest/iso : -std=c++$(std) ; + cxxstd-flags $(toolset) : $(condition)/latest/gnu : -std=gnu++$(std) ; + cxxstd-flags $(toolset) : $(condition)/latest/$(dialects) : -std=c++$(std) ; +} diff --git a/tools/build/src/tools/common.jam b/tools/build/src/tools/common.jam index 6a92d55c2b..e8d0e911c2 100644 --- a/tools/build/src/tools/common.jam +++ b/tools/build/src/tools/common.jam @@ -178,7 +178,7 @@ rule check-init-parameters ( toolset requirement * : * ) # because in that case it will be impossible to register versionless # intel-linux and intel-win toolsets of a specific version. local t = $(toolset) ; - local m = [ MATCH ([^-]*)- : $(toolset) ] ; + local m = [ MATCH "([^-]*)-" : $(toolset) ] ; if $(m) { t = $(m[1]) ; @@ -242,7 +242,7 @@ rule check-init-parameters ( toolset requirement * : * ) { local r = $(toolset) $(requirement) ; r = $(r:J=,) ; - toolset.add-requirements $(r):$(subcondition) ; + toolset.add-requirements "$(r):$(subcondition)" ; } # We add the requirements, if any, to the condition to scope the toolset @@ -251,7 +251,7 @@ rule check-init-parameters ( toolset requirement * : * ) if $(.show-configuration) { - ECHO notice: $(condition) ; + ECHO "notice:" $(condition) ; } return $(condition:J=/) ; } @@ -275,9 +275,9 @@ rule get-invocation-command-nodefault ( toolset : tool : command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ; if ! $(command) && $(.debug-configuration) { - ECHO warning: toolset $(toolset) initialization: can not find tool + ECHO "warning:" toolset $(toolset) "initialization:" can not find tool $(tool) ; - ECHO warning: initialized from [ errors.nearest-user-location ] ; + ECHO "warning:" initialized from [ errors.nearest-user-location ] ; } } else @@ -285,10 +285,10 @@ rule get-invocation-command-nodefault ( toolset : tool : command = [ check-tool $(user-provided-command) ] ; if ! $(command) && $(.debug-configuration) { - ECHO warning: toolset $(toolset) initialization: ; - ECHO warning: can not find user-provided command + ECHO "warning:" toolset $(toolset) "initialization:" ; + ECHO "warning:" can not find user-provided command '$(user-provided-command)' ; - ECHO warning: initialized from [ errors.nearest-user-location ] ; + ECHO "warning:" initialized from [ errors.nearest-user-location ] ; } } @@ -435,7 +435,7 @@ rule handle-options ( toolset : condition * : command * : options * ) { if $(.debug-configuration) { - ECHO notice: will use '$(command)' for $(toolset), condition + ECHO "notice:" will use '$(command)' for $(toolset), condition $(condition:E=(empty)) ; } @@ -682,8 +682,8 @@ rule MkDir { switch $(s) { - case *: : s = ; - case *:\\ : s = ; + case "*:" : s = ; + case "*:\\" : s = ; } } @@ -925,9 +925,9 @@ local rule toolset-tag ( name : type ? : property-set ) case edg* : tag += edg ; case gcc* : { - switch [ $(property-set).get ] + switch [ $(property-set).get ] { - case *mingw* : tag += mgw ; + case *windows* : tag += mgw ; case * : tag += gcc ; } } @@ -951,7 +951,7 @@ local rule toolset-tag ( name : type ? : property-set ) case tru64cxx* : tag += tru ; case vacpp* : tag += xlc ; } - local version = [ MATCH ([0123456789]+)[.]([0123456789]*) + local version = [ MATCH "([0123456789]+)[.]([0123456789]*)" : $(properties) ] ; # For historical reasons, vc6.0 and vc7.0 use different naming. if $(tag) = vc @@ -1027,7 +1027,7 @@ local rule runtime-tag ( name : type ? : property-set ) # "4.6.0" will result in tag "qt460" local rule qt-tag ( name : type ? : property-set ) { - local v = [ MATCH ([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*) : + local v = [ MATCH "([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*)" : [ $(property-set).get ] ] ; return qt$(v:J=) ; } diff --git a/tools/build/src/tools/common_clang_vc.jam b/tools/build/src/tools/common_clang_vc.jam deleted file mode 100644 index bdf1ca8747..0000000000 --- a/tools/build/src/tools/common_clang_vc.jam +++ /dev/null @@ -1,987 +0,0 @@ -# Copyright 2003, 2005 Dave Abrahams -# Copyright 2005, 2006 Rene Rivera -# Copyright 2005 Toon Knapen -# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -# Provides actions common to all toolsets, such as creating directories and -# removing files. - -import os ; -import modules ; -import utility ; -import print ; -import type ; -import feature ; -import errors ; -import path ; -import sequence ; -import toolset ; -import virtual-target ; - -if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] -{ - .debug-configuration = true ; -} -if [ MATCH (--show-configuration) : [ modules.peek : ARGV ] ] -{ - .show-configuration = true ; -} - -# Configurations -# -# The following class helps to manage toolset configurations. Each configuration -# has a unique ID and one or more parameters. A typical example of a unique ID -# is a condition generated by 'common.check-init-parameters' rule. Other kinds -# of IDs can be used. Parameters may include any details about the configuration -# like 'command', 'path', etc. -# -# A toolset configuration may be in one of the following states: -# -# - registered -# Configuration has been registered (e.g. explicitly or by auto-detection -# code) but has not yet been marked as used, i.e. 'toolset.using' rule has -# not yet been called for it. -# - used -# Once called 'toolset.using' rule marks the configuration as 'used'. -# -# The main difference between the states above is that while a configuration is -# 'registered' its options can be freely changed. This is useful in particular -# for autodetection code - all detected configurations may be safely overwritten -# by user code. - -class configurations -{ - import errors ; - - rule __init__ ( ) - { - } - - # Registers a configuration. - # - # Returns 'true' if the configuration has been added and an empty value if - # it already exists. Reports an error if the configuration is 'used'. - # - rule register ( id ) - { - if $(id) in $(self.used) - { - errors.error "common: the configuration '$(id)' is in use" ; - } - - local retval ; - - if ! $(id) in $(self.all) - { - self.all += $(id) ; - - # Indicate that a new configuration has been added. - retval = true ; - } - - return $(retval) ; - } - - # Mark a configuration as 'used'. - # - # Returns 'true' if the state of the configuration has been changed to - # 'used' and an empty value if it the state has not been changed. Reports an - # error if the configuration is not known. - # - rule use ( id ) - { - if ! $(id) in $(self.all) - { - errors.error "common: the configuration '$(id)' is not known" ; - } - - local retval ; - - if ! $(id) in $(self.used) - { - self.used += $(id) ; - - # Indicate that the configuration has been marked as 'used'. - retval = true ; - } - - return $(retval) ; - } - - # Return all registered configurations. - # - rule all ( ) - { - return $(self.all) ; - } - - # Return all used configurations. - # - rule used ( ) - { - return $(self.used) ; - } - - # Returns the value of a configuration parameter. - # - rule get ( id : param ) - { - return $(self.$(param).$(id)) ; - } - - # Sets the value of a configuration parameter. - # - rule set ( id : param : value * ) - { - self.$(param).$(id) = $(value) ; - } -} - - -# The rule for checking toolset parameters. Trailing parameters should all be -# parameter name/value pairs. The rule will check that each parameter either has -# a value in each invocation or has no value in each invocation. Also, the rule -# will check that the combination of all parameter values is unique in all -# invocations. -# -# Each parameter name corresponds to a subfeature. This rule will declare a -# subfeature the first time a non-empty parameter value is passed and will -# extend it with all the values. -# -# The return value from this rule is a condition to be used for flags settings. -# -rule check-init-parameters ( toolset requirement * : * ) -{ - local sig = $(toolset) ; - local condition = $(toolset) ; - local subcondition ; - for local index in 2 3 4 5 6 7 8 9 - { - local name = $($(index)[1]) ; - local value = $($(index)[2]) ; - - if $(value)-is-not-empty - { - condition = $(condition)-$(value) ; - if $(.had-unspecified-value.$(toolset).$(name)) - { - errors.user-error - "$(toolset) initialization: parameter '$(name)'" - "inconsistent" : "no value was specified in earlier" - "initialization" : "an explicit value is specified now" ; - } - # The below logic is for intel compiler. It calls this rule with - # 'intel-linux' and 'intel-win' as toolset, so we need to get the - # base part of toolset name. We can not pass 'intel' as toolset - # because in that case it will be impossible to register versionless - # intel-linux and intel-win toolsets of a specific version. - local t = $(toolset) ; - local m = [ MATCH ([^-]*)- : $(toolset) ] ; - if $(m) - { - t = $(m[1]) ; - } - if ! $(.had-value.$(toolset).$(name)) - { - if ! $(.declared-subfeature.$(t).$(name)) - { - feature.subfeature toolset $(t) : $(name) : : propagated ; - .declared-subfeature.$(t).$(name) = true ; - } - .had-value.$(toolset).$(name) = true ; - } - feature.extend-subfeature toolset $(t) : $(name) : $(value) ; - subcondition += $(value) ; - } - else - { - if $(.had-value.$(toolset).$(name)) - { - errors.user-error - "$(toolset) initialization: parameter '$(name)'" - "inconsistent" : "an explicit value was specified in an" - "earlier initialization" : "no value is specified now" ; - } - .had-unspecified-value.$(toolset).$(name) = true ; - } - sig = $(sig)$(value:E="")- ; - } - if $(sig) in $(.all-signatures) - { - local message = - "duplicate initialization of $(toolset) with the following parameters: " ; - for local index in 2 3 4 5 6 7 8 9 - { - local p = $($(index)) ; - if $(p) - { - message += "$(p[1]) = $(p[2]:E=)" ; - } - } - message += "previous initialization at $(.init-loc.$(sig))" ; - errors.user-error - $(message[1]) : $(message[2]) : $(message[3]) : $(message[4]) : - $(message[5]) : $(message[6]) : $(message[7]) : $(message[8]) ; - } - .all-signatures += $(sig) ; - .init-loc.$(sig) = [ errors.nearest-user-location ] ; - - # If we have a requirement, this version should only be applied under that - # condition. To accomplish this we add a toolset requirement that imposes - # the toolset subcondition, which encodes the version. - if $(requirement) - { - local r = $(toolset) $(requirement) ; - r = $(r:J=,) ; - toolset.add-requirements $(r):$(subcondition) ; - } - - # We add the requirements, if any, to the condition to scope the toolset - # variables and options to this specific version. - condition += $(requirement) ; - - if $(.show-configuration) - { - ECHO notice: $(condition) ; - } - return $(condition:J=/) ; -} - - -# A helper rule to get the command to invoke some tool. If -# 'user-provided-command' is not given, tries to find binary named 'tool' in -# PATH and in the passed 'additional-path'. Otherwise, verifies that the first -# element of 'user-provided-command' is an existing program. -# -# This rule returns the command to be used when invoking the tool. If we can not -# find the tool, a warning is issued. If 'path-last' is specified, PATH is -# checked after 'additional-paths' when searching for 'tool'. -# -rule get-invocation-command-nodefault ( toolset : tool : - user-provided-command * : additional-paths * : path-last ? ) -{ - local command ; - if ! $(user-provided-command) - { - command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ; - if ! $(command) && $(.debug-configuration) - { - ECHO warning: toolset $(toolset) initialization: can not find tool - $(tool) ; - ECHO warning: initialized from [ errors.nearest-user-location ] ; - } - } - else - { - command = [ check-tool $(user-provided-command) ] ; - if ! $(command) && $(.debug-configuration) - { - ECHO warning: toolset $(toolset) initialization: ; - ECHO warning: can not find user-provided command - '$(user-provided-command)' ; - ECHO warning: initialized from [ errors.nearest-user-location ] ; - } - } - - return $(command) ; -} - - -# Same as get-invocation-command-nodefault, except that if no tool is found, -# returns either the user-provided-command, if present, or the 'tool' parameter. -# -rule get-invocation-command ( toolset : tool : user-provided-command * : - additional-paths * : path-last ? ) -{ - local result = [ get-invocation-command-nodefault $(toolset) : $(tool) : - $(user-provided-command) : $(additional-paths) : $(path-last) ] ; - - if ! $(result) - { - if $(user-provided-command) - { - result = $(user-provided-command) ; - } - else - { - result = $(tool) ; - } - } - return $(result) ; -} - - -# Given an invocation command return the absolute path to the command. This -# works even if command has no path element and was found on the PATH. -# -rule get-absolute-tool-path ( command ) -{ - if $(command:D) - { - return $(command:D) ; - } - else - { - local m = [ GLOB [ modules.peek : PATH Path path ] : $(command) - $(command).exe ] ; - return $(m[1]:D) ; - } -} - - -# Attempts to find tool (binary) named 'name' in PATH and in 'additional-paths'. -# If found in PATH, returns 'name' and if found in additional paths, returns -# absolute name. If the tool is found in several directories, returns the first -# path found. Otherwise, returns an empty string. If 'path-last' is specified, -# PATH is searched after 'additional-paths'. -# -rule find-tool ( name : additional-paths * : path-last ? ) -{ - local path = [ path.programs-path ] ; - local match = [ path.glob $(path) : $(name) $(name).exe ] ; - local additional-match = [ path.glob $(additional-paths) : $(name) - $(name).exe ] ; - - local result ; - if $(path-last) - { - result = $(additional-match) ; - if ! $(result) && $(match) - { - result = $(name) ; - } - } - else - { - if $(match) - { - result = $(name) ; - } - else - { - result = $(additional-match) ; - } - } - if $(result) - { - return [ path.native $(result[1]) ] ; - } -} - - -# Checks if 'command' can be found either in path or is a full name to an -# existing file. -# -local rule check-tool-aux ( command ) -{ - if $(command:D) - { - if [ path.exists $(command) ] - # Both NT and Cygwin will run .exe files by their unqualified names. - || ( [ os.on-windows ] && [ path.exists $(command).exe ] ) - # Only NT will run .bat & .cmd files by their unqualified names. - || ( ( [ os.name ] = NT ) && ( [ path.exists $(command).bat ] || - [ path.exists $(command).cmd ] ) ) - { - return $(command) ; - } - } - else - { - if [ GLOB [ modules.peek : PATH Path path ] : $(command) ] - { - return $(command) ; - } - } -} - - -# Checks that a tool can be invoked by 'command'. If command is not an absolute -# path, checks if it can be found in 'path'. If comand is an absolute path, -# check that it exists. Returns 'command' if ok or empty string otherwise. -# -local rule check-tool ( xcommand + ) -{ - if [ check-tool-aux $(xcommand[1]) ] || - [ check-tool-aux $(xcommand[-1]) ] - { - return $(xcommand) ; - } -} - - -# Handle common options for toolset, specifically sets the following flag -# variables: -# - CONFIG_COMMAND to $(command) -# - OPTIONS for compile to the value of in $(options) -# - OPTIONS for compile.c to the value of in $(options) -# - OPTIONS for compile.c++ to the value of in $(options) -# - OPTIONS for compile.fortran to the value of in $(options) -# - OPTIONS for link to the value of in $(options) -# -rule handle-options ( toolset : condition * : command * : options * ) -{ - if $(.debug-configuration) - { - ECHO notice: will use '$(command)' for $(toolset), condition - $(condition:E=(empty)) ; - } - - # The last parameter ('unchecked') says it is OK to set flags for another - # module. - toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command) - : unchecked ; - - toolset.flags $(toolset).compile OPTIONS $(condition) : - [ feature.get-values : $(options) ] : unchecked ; - - toolset.flags $(toolset).compile.c OPTIONS $(condition) : - [ feature.get-values : $(options) ] : unchecked ; - - toolset.flags $(toolset).compile.c++ OPTIONS $(condition) : - [ feature.get-values : $(options) ] : unchecked ; - - toolset.flags $(toolset).compile.fortran OPTIONS $(condition) : - [ feature.get-values : $(options) ] : unchecked ; - - toolset.flags $(toolset).link OPTIONS $(condition) : - [ feature.get-values : $(options) ] : unchecked ; -} - - -# Returns the location of the "program files" directory on a Windows platform. -# -rule get-program-files-dir ( ) -{ - local ProgramFiles = [ modules.peek : ProgramFiles ] ; - if $(ProgramFiles) - { - ProgramFiles = "$(ProgramFiles:J= )" ; - } - else - { - ProgramFiles = "c:\\Program Files" ; - } - return $(ProgramFiles) ; -} - - -if [ os.name ] = NT -{ - RM = del /f /q ; - CP = copy /b ; - IGNORE = "2>nul >nul & setlocal" ; - LN ?= $(CP) ; - # Ugly hack to convince copy to set the timestamp of the destination to the - # current time by concatenating the source with a nonexistent file. Note - # that this requires /b (binary) as the default when concatenating files is - # /a (ascii). - WINDOWS-CP-HACK = "+ this-file-does-not-exist-A698EE7806899E69" ; -} -else -{ - RM = rm -f ; - CP = cp ; - LN = ln ; -} - - -rule rm-command ( ) -{ - return $(RM) ; -} - - -rule copy-command ( ) -{ - return $(CP) ; -} - - -if "\n" = "n" -{ - # Escape characters not supported so use ugly hacks. Will not work on Cygwin - # - see below. - nl = " -" ; - q = "" ; -} -else -{ - nl = "\n" ; - q = "\"" ; -} - -# Returns the command needed to set an environment variable on the current -# platform. The variable setting persists through all following commands and is -# visible in the environment seen by subsequently executed commands. In other -# words, on Unix systems, the variable is exported, which is consistent with the -# only possible behavior on Windows systems. -# -rule variable-setting-command ( variable : value ) -{ - if [ os.name ] = NT - { - return "set $(variable)=$(value)$(nl)" ; - } - else - { - # If we do not have escape character support in bjam, the cod below - # blows up on CYGWIN, since the $(nl) variable holds a Windows new-line - # \r\n sequence that messes up the executed export command which then - # reports that the passed variable name is incorrect. - # But we have a check for cygwin in kernel/bootstrap.jam already. - return "$(variable)=$(q)$(value)$(q)$(nl)export $(variable)$(nl)" ; - } -} - - -# Returns a command to sets a named shell path variable to the given NATIVE -# paths on the current platform. -# -rule path-variable-setting-command ( variable : paths * ) -{ - local sep = [ os.path-separator ] ; - return [ variable-setting-command $(variable) : $(paths:J=$(sep)) ] ; -} - - -# Returns a command that prepends the given paths to the named path variable on -# the current platform. -# -rule prepend-path-variable-command ( variable : paths * ) -{ - return [ path-variable-setting-command $(variable) - : $(paths) [ os.expand-variable $(variable) ] ] ; -} - - -# Return a command which can create a file. If 'r' is result of invocation, then -# 'r foobar' will create foobar with unspecified content. What happens if file -# already exists is unspecified. -# -rule file-creation-command ( ) -{ - if [ os.name ] = NT - { - # A few alternative implementations on Windows: - # - # 'type NUL >> ' - # That would construct an empty file instead of a file containing - # a space and an end-of-line marker but it would also not change - # the target's timestamp in case the file already exists. - # - # 'type NUL > ' - # That would construct an empty file instead of a file containing - # a space and an end-of-line marker but it would also destroy an - # already existing file by overwriting it with an empty one. - # - # I guess the best solution would be to allow Boost Jam to define - # built-in functions such as 'create a file', 'touch a file' or 'copy a - # file' which could be used from inside action code. That would allow - # completely portable operations without this kind of kludge. - # (22.02.2009.) (Jurko) - return "echo. > " ; - } - else - { - return "touch " ; - } -} - - -# Returns a command that may be used for 'touching' files. It is not a real -# 'touch' command on NT because it adds an empty line at the end of file but it -# works with source files. -# -rule file-touch-command ( ) -{ - if [ os.name ] = NT - { - return "echo. >> " ; - } - else - { - return "touch " ; - } -} - - -rule MkDir -{ - # If dir exists, do not update it. Do this even for $(DOT). - NOUPDATE $(<) ; - - if $(<) != $(DOT) && ! $($(<)-mkdir) - { - # Cheesy gate to prevent multiple invocations on same dir. - $(<)-mkdir = true ; - - # Schedule the mkdir build action. - common.mkdir $(<) ; - - # Prepare a Jam 'dirs' target that can be used to make the build only - # construct all the target directories. - DEPENDS dirs : $(<) ; - - # Recursively create parent directories. $(<:P) = $(<)'s parent & we - # recurse until root. - - local s = $(<:P) ; - if [ os.name ] = NT - { - switch $(s) - { - case *: : s = ; - case *:\\ : s = ; - } - } - - if $(s) - { - if $(s) != $(<) - { - DEPENDS $(<) : $(s) ; - MkDir $(s) ; - } - else - { - NOTFILE $(s) ; - } - } - } -} - - -#actions MkDir1 -#{ -# mkdir "$(<)" -#} - -# The following quick-fix actions should be replaced using the original MkDir1 -# action once Boost Jam gets updated to correctly detect different paths leading -# up to the same filesystem target and triggers their build action only once. -# (todo) (04.07.2008.) (Jurko) - -if [ os.name ] = NT -{ - actions mkdir - { - if not exist "$(<)\\" mkdir "$(<)" - } -} -else -{ - actions mkdir - { - mkdir -p "$(<)" - } -} - -actions piecemeal together existing Clean -{ - $(RM) "$(>)" -} - - -rule copy -{ -} - - -actions copy -{ - $(CP) "$(>)" $(WINDOWS-CP-HACK) "$(<)" -} - - -rule RmTemps -{ -} - - -actions quietly updated piecemeal together RmTemps -{ - $(RM) "$(>)" $(IGNORE) -} - - -actions hard-link -{ - $(RM) "$(<)" 2$(NULL_OUT) $(NULL_OUT) - $(LN) "$(>)" "$(<)" $(NULL_OUT) -} - - -# Given a target, as given to a custom tag rule, returns a string formatted -# according to the passed format. Format is a list of properties that is -# represented in the result. For each element of format the corresponding target -# information is obtained and added to the result string. For all, but the -# literal, the format value is taken as the as string to prepend to the output -# to join the item to the rest of the result. If not given "-" is used as a -# joiner. -# -# The format options can be: -# -# [joiner] -# :: The basename of the target name. -# [joiner] -# :: The abbreviated toolset tag being used to build the target. -# [joiner] -# :: Indication of a multi-threaded build. -# [joiner] -# :: Collective tag of the build runtime. -# [joiner] -# :: Short version tag taken from the given "version-feature" in the -# build properties. Or if not present, the literal value as the -# version number. -# [joiner] -# :: Direct lookup of the given property-name value in the build -# properties. /property-name/ is a regular expression. E.g. -# will match every toolset. -# /otherwise/ -# :: The literal value of the format argument. -# -# For example this format: -# -# boost_ -# -# Might return: -# -# boost_thread-vc80-mt-gd-1_33.dll, or -# boost_regex-vc80-gd-1_33.dll -# -# The returned name also has the target type specific prefix and suffix which -# puts it in a ready form to use as the value from a custom tag rule. -# -rule format-name ( format * : name : type ? : property-set ) -{ - local result = "" ; - for local f in $(format) - { - switch $(f:G) - { - case : - result += $(name:B) ; - - case : - result += [ join-tag $(f:G=) : [ toolset-tag $(name) : $(type) : - $(property-set) ] ] ; - - case : - result += [ join-tag $(f:G=) : [ threading-tag $(name) : $(type) - : $(property-set) ] ] ; - - case : - result += [ join-tag $(f:G=) : [ runtime-tag $(name) : $(type) : - $(property-set) ] ] ; - - case : - result += [ join-tag $(f:G=) : [ qt-tag $(name) : $(type) : - $(property-set) ] ] ; - - case : - result += [ join-tag $(f:G=) : [ address-model-tag $(name) : - $(type) : $(property-set) ] ] ; - - case : - local key = [ MATCH : $(f:G) ] ; - local version = [ $(property-set).get <$(key)> ] ; - version ?= $(key) ; - version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)" : $(version) ] ; - result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ; - - case : - local key = [ MATCH : $(f:G) ] ; - local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ; - if $(p0) - { - local p = [ $(property-set).get <$(p0)> ] ; - if $(p) - { - result += [ join-tag $(f:G=) : $(p) ] ; - } - } - - case * : - result += $(f:G=) ; - } - } - return [ virtual-target.add-prefix-and-suffix $(result:J=) : $(type) : - $(property-set) ] ; -} - - -local rule join-tag ( joiner ? : tag ? ) -{ - if ! $(joiner) { joiner = - ; } - return $(joiner)$(tag) ; -} - - -local rule toolset-tag ( name : type ? : property-set ) -{ - local tag = ; - - local properties = [ $(property-set).raw ] ; - switch [ $(property-set).get ] - { - case borland* : tag += bcb ; - case clang* : - { - switch [ $(property-set).get ] - { - case darwin : tag += clang-darwin ; - case linux : tag += clang ; - case win : tag += clang-win ; - } - } - case como* : tag += como ; - case cw : tag += cw ; - case darwin* : tag += xgcc ; - case edg* : tag += edg ; - case gcc* : - { - switch [ $(property-set).get ] - { - case *mingw* : tag += mgw ; - case * : tag += gcc ; - } - } - case intel : - if [ $(property-set).get ] = win - { - tag += iw ; - } - else - { - tag += il ; - } - case kcc* : tag += kcc ; - case kylix* : tag += bck ; - #case metrowerks* : tag += cw ; - #case mingw* : tag += mgw ; - case mipspro* : tag += mp ; - case msvc* : tag += vc ; - case qcc* : tag += qcc ; - case sun* : tag += sw ; - case tru64cxx* : tag += tru ; - case vacpp* : tag += xlc ; - } - local version = [ MATCH ([0123456789]+)[.]([0123456789]*) - : $(properties) ] ; - # For historical reasons, vc6.0 and vc7.0 use different naming. - if $(tag) = vc - { - if $(version[1]) = 6 - { - # Cancel minor version. - version = 6 ; - } - else if $(version[1]) = 7 && $(version[2]) = 0 - { - version = 7 ; - } - } - # On intel, version is not added, because it does not matter and it is the - # version of vc used as backend that matters. Ideally, we should encode the - # backend version but that would break compatibility with V1. - if $(tag) = iw - { - version = ; - } - if $(tag) = clang-win - { - local my_tmp = [ $(property-set).get ] ; - version = $(version[1])_$(version[2])_$(my_tmp) ; - } - - # On borland, version is not added for compatibility with V1. - if $(tag) = bcb - { - version = ; - } - - tag += $(version) ; - - return $(tag:J=) ; -} - - -local rule threading-tag ( name : type ? : property-set ) -{ - if multi in [ $(property-set).raw ] - { - return mt ; - } -} - - -local rule runtime-tag ( name : type ? : property-set ) -{ - local tag = ; - - local properties = [ $(property-set).raw ] ; - if static in $(properties) { tag += s ; } - - # This is an ugly thing. In V1, there is code to automatically detect which - # properties affect a target. So, if does not affect gcc - # toolset, the tag rules will not even see . Similar - # functionality in V2 is not implemented yet, so we just check for toolsets - # known to care about runtime debugging. - if ( msvc in $(properties) ) || - ( stlport in $(properties) ) || - ( win in $(properties) ) - { - if on in $(properties) { tag += g ; } - } - - if on in $(properties) { tag += y ; } - if debug in $(properties) { tag += d ; } - if stlport in $(properties) { tag += p ; } - if hostios in $(properties) { tag += n ; } - - return $(tag:J=) ; -} - - -# Create a tag for the Qt library version -# "4.6.0" will result in tag "qt460" -local rule qt-tag ( name : type ? : property-set ) -{ - local v = [ MATCH ([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*) : - [ $(property-set).get ] ] ; - return qt$(v:J=) ; -} - - -# Create a tag for the address-model -# 64 will simply generate "64" -local rule address-model-tag ( name : type ? : property-set ) -{ - return [ $(property-set).get ] ; -} - - -rule __test__ ( ) -{ - import assert ; - - local save-os = [ modules.peek os : .name ] ; - - modules.poke os : .name : LINUX ; - assert.result "PATH=\"foo:bar:baz\"\nexport PATH\n" - : path-variable-setting-command PATH : foo bar baz ; - assert.result "PATH=\"foo:bar:$PATH\"\nexport PATH\n" - : prepend-path-variable-command PATH : foo bar ; - - modules.poke os : .name : NT ; - assert.result "set PATH=foo;bar;baz\n" - : path-variable-setting-command PATH : foo bar baz ; - assert.result "set PATH=foo;bar;%PATH%\n" - : prepend-path-variable-command PATH : foo bar ; - - modules.poke os : .name : $(save-os) ; -} diff --git a/tools/build/src/tools/cw.jam b/tools/build/src/tools/cw.jam index ddcbfeb2b6..3b6de0db6e 100644 --- a/tools/build/src/tools/cw.jam +++ b/tools/build/src/tools/cw.jam @@ -86,7 +86,7 @@ rule init ( version ? : command * : options * ) flags cw.link .LD $(condition) : $(prefix)$(linker) ; flags cw.archive .LD $(condition) : $(prefix)$(linker) ; - if [ MATCH ^([89]\\.) : $(version) ] + if [ MATCH "^([89]\\.)" : $(version) ] { if [ os.name ] = NT { diff --git a/tools/build/src/tools/darwin.jam b/tools/build/src/tools/darwin.jam index 1760a19868..57d9c75275 100644 --- a/tools/build/src/tools/darwin.jam +++ b/tools/build/src/tools/darwin.jam @@ -85,7 +85,7 @@ rule init ( version ? : command * : options * : requirement * ) : [ SHELL "/usr/bin/sw_vers -productVersion" ] ] ; if $(.debug-configuration) { - ECHO notice: OSX version on this machine is $(.host-osx-version) ; + ECHO notice\: OSX version on this machine is $(.host-osx-version) ; } } @@ -156,9 +156,6 @@ rule init ( version ? : command * : options * : requirement * ) flags darwin.compile OPTIONS $(condition)/full : -Wno-inline ; } - # - Set the link flags common with the GCC toolset. - gcc.init-link-flags darwin darwin $(condition) ; - # - The symbol strip program. local strip ; if in $(options) @@ -186,7 +183,7 @@ rule init ( version ? : command * : options * : requirement * ) flags darwin.link .STRIP $(condition) : $(strip[1]) ; if $(.debug-configuration) { - ECHO notice: using strip for $(condition) at $(strip[1]) ; + ECHO notice\: using strip for $(condition) at $(strip[1]) ; } } @@ -198,7 +195,7 @@ rule init ( version ? : command * : options * : requirement * ) flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ; if $(.debug-configuration) { - ECHO notice: using archiver for $(condition) at $(archiver[1]) ; + ECHO notice\: using archiver for $(condition) at $(archiver[1]) ; } # - Initialize the SDKs available in the root for this tool. @@ -246,7 +243,7 @@ local rule init-sdk ( condition * : root ? : version + : version-feature ? ) { if $(.debug-configuration) { - ECHO notice: available sdk for $(condition)/$(version-feature) at $(root) ; + ECHO notice\: available sdk for $(condition)/$(version-feature) at $(root) ; } # Add the version to the features for specifying them. @@ -372,7 +369,7 @@ local rule init-available-sdk-versions ( condition * : root ? ) local result ; for local sdk in $(sdks) { - local sdk-match = [ MATCH ([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)? : $(sdk:D=) ] ; + local sdk-match = [ MATCH "([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)?" : $(sdk:D=) ] ; local sdk-platform = $(sdk-match[1]:L) ; local sdk-version = $(sdk-match[2-]) ; if $(sdk-version) diff --git a/tools/build/src/tools/diab.jam b/tools/build/src/tools/diab.jam index e8c596ea21..029cfa5fe7 100644 --- a/tools/build/src/tools/diab.jam +++ b/tools/build/src/tools/diab.jam @@ -63,9 +63,10 @@ flags diab.compile OPTIONS ; flags diab.compile.c++ OPTIONS ; flags diab.compile DEFINES ; -flags diab.compile.c++ OPTIONS off : -Xno-exceptions ; +flags diab.compile.c++ OPTIONS off : -Xno-exceptions ; # So Dinkum STL knows when exceptions are disabled -flags diab.compile DEFINES off : _NO_EX=1 ; +flags diab.compile.c++ DEFINES off : _NO_EX=1 ; +flags diab.compile.c++ DEFINES off : _NO_RTTI ; flags diab.compile INCLUDES ; flags diab.link OPTIONS ; diff --git a/tools/build/src/tools/doxygen.jam b/tools/build/src/tools/doxygen.jam index 1e53624311..0358e8dc5a 100644 --- a/tools/build/src/tools/doxygen.jam +++ b/tools/build/src/tools/doxygen.jam @@ -27,6 +27,7 @@ import make ; import modules ; import generators ; import os ; +import param ; import path ; import print ; import project ; @@ -42,7 +43,7 @@ import virtual-target ; # Use to specify extra configuration paramters. These get translated into a # doxyfile which configures the building of the docs. -feature.feature doxygen:param : : free ; +feature.feature "doxygen:param" : : free ; # Specify the "boost.doxygen.header.prefix" XSLT option. feature.feature prefix : : free ; @@ -63,7 +64,7 @@ feature.feature doxygen.doxproc.id : : free ; feature.feature doxygen.doxproc.title : : free ; # Location for images when generating XML -feature.feature doxygen:xml-imagedir : : free ; +feature.feature "doxygen:xml-imagedir" : : free ; # Indicates whether the entire directory should be deleted feature.feature doxygen.rmdir : off on : optional incidental ; @@ -105,9 +106,9 @@ rule init ( name ? ) : DOXYFILE : DOXYGEN_XML_MULTIFILE ; generators.register-standard doxygen.xml-dir-to-boostbook : DOXYGEN_XML_MULTIFILE : BOOSTBOOK : doxproc ; - generators.register-standard doxygen.xml-to-boostbook + generators.register-xslt doxygen.xml-to-boostbook : DOXYGEN_XML : BOOSTBOOK : xsltproc ; - generators.register-standard doxygen.collect + generators.register-xslt doxygen.collect : DOXYGEN_XML_MULTIFILE : DOXYGEN_XML ; generators.register-standard doxygen.run : DOXYFILE : DOXYGEN_HTML_MULTIFILE ; @@ -252,7 +253,7 @@ rule translate-path ( path ) { if $(.is-cygwin) { - match = [ MATCH ^(.):(.*) : $(path) ] ; + match = [ MATCH "^(.):(.*)" : $(path) ] ; if $(match) { return /cygdrive/$(match[1])$(match[2]:T) ; @@ -274,6 +275,7 @@ rule translate-path ( path ) } } +toolset.uses-features doxygen.headers-to-doxyfile : "" ; # Generates a doxygen configuration file (doxyfile) given a set of C++ sources # and a property list that may contain features. @@ -287,7 +289,7 @@ rule headers-to-doxyfile ( target : sources * : properties * ) # Translate into command line flags. for local param in [ feature.get-values : $(properties) ] { - local namevalue = [ MATCH ([^=]*)=(.*) : $(param) ] ; + local namevalue = [ MATCH "([^=]*)=(.*)" : $(param) ] ; if $(namevalue[1]) = OUTPUT_DIRECTORY { output-dir = [ translate-path [ utility.unquote $(namevalue[2]) ] ] @@ -321,6 +323,7 @@ rule headers-to-doxyfile ( target : sources * : properties * ) print.text $(text) : true ; } +toolset.uses-features doxygen.run : "" ; # Run Doxygen. See doxygen-action for a description of the strange properties of # this rule. @@ -331,7 +334,7 @@ rule run ( target : source : properties * ) if on in $(properties) { local output-dir = [ path.make [ MATCH - OUTPUT_DIRECTORY=\"?([^\"]*) : $(properties) ] ] ; + "OUTPUT_DIRECTORY=\"?([^\"]*)" : $(properties) ] ] ; local html-dir = [ path.make [ MATCH HTML_OUTPUT=(.*) : $(properties) ] ] ; if $(output-dir) && $(html-dir) && @@ -377,7 +380,7 @@ rule check-boostbook ( ) : The boostbook module is not initialized you have attempted to use : the 'doxygen' toolset, which requires BoostBook, but never : initialized BoostBook. - : Hint: add 'using boostbook ;' to your user-config.jam. ; + : "Hint:" add 'using boostbook \;' to your user-config.jam. ; } } @@ -406,6 +409,7 @@ rule collect ( target : source : properties * ) : doxygen.xml.path=$(native-path) ; } +toolset.uses-features doxygen.xml-to-boostbook : ; # Translate Doxygen XML into BoostBook. # @@ -619,6 +623,8 @@ rule check-tools ( target ) rule doxygen ( target : sources + : requirements * : default-build * : usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; requirements += none ; freeze-config ; local project = [ project.current ] ; diff --git a/tools/build/src/tools/features/relevant-feature.jam b/tools/build/src/tools/features/relevant-feature.jam new file mode 100644 index 0000000000..f55bd7f4ca --- /dev/null +++ b/tools/build/src/tools/features/relevant-feature.jam @@ -0,0 +1,10 @@ +# Copyright 2017 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Identifies relevant features. + +import feature ; + +feature.feature relevant : : incidental free ; diff --git a/tools/build/src/tools/features/threadapi-feature.jam b/tools/build/src/tools/features/threadapi-feature.jam index 1a2b0923da..0f9d42fa5d 100644 --- a/tools/build/src/tools/features/threadapi-feature.jam +++ b/tools/build/src/tools/features/threadapi-feature.jam @@ -25,5 +25,5 @@ rule detect ( properties * ) local ps = [ property-set.create $(properties) ] ; local api = [ $(ps).get ] ; if ! $(api) { api = [ get-default $(ps) ] ; } - return $(api) ; + return $(api) threadapi:target-os ; } diff --git a/tools/build/src/tools/flags.jam b/tools/build/src/tools/flags.jam new file mode 100644 index 0000000000..045f9af697 --- /dev/null +++ b/tools/build/src/tools/flags.jam @@ -0,0 +1,152 @@ +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# defines the check-has-flag rule. + +import "class" ; +import common ; +import feature : feature ; +import generators ; +import make ; +import print ; +import project ; +import toolset : flags ; + +rule init ( ) +{ + if ! $(.initialized) + { + .initialized = true ; + project.push-current ; + project.initialize $(__name__) ; + project /check/flags ; + .project = [ project.current ] ; + make empty.c : : @write-main ; + make empty.cpp : : @write-main ; + obj empty.obj : empty.cpp ; + project : requirements on ; + project.pop-current ; + } +} + +rule write-main ( target : : properties * ) +{ + print.output $(target) ; + print.text "int main() { return 0; }\n" : yes ; +} + +# Applies true-properties if the toolset recognizes a specific flag. +# Otherwise applies false-properties. +# +# Option must be one of , , or . +# +# Example:: +# +# exe foo : foo.cpp : +# [ check-has-flag -std=c++11 : -std=c++11 ] ; +# +rule check-has-flag ( option message ? : true-properties * : false-properties * ) +{ + init ; + local id = [ MD5 $(option) ] ; + + if ! $(.targets.$(id)) + { + project.push-current $(.project) ; + switch $(option:G) + { + case : obj flags_$(id) : empty.c : $(option) ; + case : obj flags_$(id) : empty.cpp : $(option) ; + case : exe flags_$(id) : empty.obj : $(option) ; + case * : + import errors ; + errors.user-error "Don't know how to check $(option:G)" ; + } + project.pop-current ; + .targets.$(id) = true ; + } + message ?= "has $(option:G=)" ; + return [ check-target-builds /check/flags//flags_$(id) $(message) + : $(true-properties) : $(false-properties) ] ; +} + +IMPORT $(__name__) : check-has-flag : : check-has-flag ; + +feature flags.check : on : optional composite ; +feature.compose on : on ; + +# Some compilers don't have an easy way to cause an error +# for unknown options. In this case, we need to check +# their stdout/stderr. This generator will copy it's +# source, but will cause an error if the given pattern +# matches the output from the source. +# + +feature flags.pattern : : free ; + +class flag-check-generator : generator +{ + rule __init__ ( type : requirements * : pattern ) + { + generator.__init__ flags.check-output : $(type) : $(type)(%_valid) : + $(requirements) on ; + self.pattern = $(pattern) ; + } + rule run ( project name ? : property-set : sources * ) + { + property-set = [ property-set.create + [ property.change [ $(property-set).raw ] : ] + $(self.pattern) ] ; + return [ generator.run $(project) $(name) + : $(property-set) : $(sources) ] ; + } + rule action-class ( ) + { + return non-scanning-action ; + } +} + +# These generator definitions should probably be moved to the individual toolsets. + +# msvc-7.1 uses 4002. Later versions use 9002. +generators.register + [ class.new flag-check-generator OBJ : msvc : "(D[94]002)" ] ; +generators.register + [ class.new flag-check-generator EXE : msvc : "(LNK4044)" ] ; +generators.register + [ class.new flag-check-generator OBJ : intel : "(#10006)" ] ; +generators.register + [ class.new flag-check-generator EXE : intel : "(#10006)" ] ; +generators.override flags.check-output : all ; + +rule check-output-callback ( targets * : source-targets * : ignored * : output ? ) +{ + if [ MATCH [ on $(targets) return $(PATTERN) ] : $(output) ] + { + FLAG_CHECK_COMMAND on $(targets) = illegal-ad22d215a8bbd73 ; + } +} + +IMPORT $(__name__) : check-output-callback : : flags.check-output-callback ; + +flags flags.check-output PATTERN : ; + +rule check-output ( targets * : sources * : properties * ) +{ + local action = [ on $(sources) return $(.action) ] ; + local all-sources ; + for local t in [ $(action).targets ] + { + all-sources += [ $(t).actualize ] ; + } + REBUILDS $(targets) : $(sources) ; + __ACTION_RULE__ on $(all-sources) = flags.check-output-callback $(targets) ; + common.copy $(targets[1]) : $(sources[1]) ; +} + +actions check-output +{ + $(FLAG_CHECK_COMMAND) +} diff --git a/tools/build/src/tools/gcc.jam b/tools/build/src/tools/gcc.jam index e3b1b95248..13ddd3948f 100644 --- a/tools/build/src/tools/gcc.jam +++ b/tools/build/src/tools/gcc.jam @@ -22,6 +22,7 @@ import property ; import property-set ; import rc ; import regex ; +import sequence ; import set ; import toolset ; import type ; @@ -37,7 +38,6 @@ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] feature.extend toolset : gcc ; -# feature.subfeature toolset gcc : flavor : : optional ; toolset.inherit-generators gcc : unix : unix.link unix.link.dll ; toolset.inherit-flags gcc : unix ; @@ -81,7 +81,7 @@ rule init ( version ? : command * : options * : requirement * ) if ! $(tool-command) { import errors ; - errors.error toolset gcc initialization: + errors.error toolset gcc "initialization:" : provided command '$(command)' not found : initialized from [ errors.nearest-user-location ] ; } @@ -101,8 +101,8 @@ rule init ( version ? : command * : options * : requirement * ) { local tool-command-string = \"$(tool-command)\" ; tool-command-string = $(tool-command-string:J=" ") ; - local tool-version = [ MATCH "^([0-9.]+)" : - [ SHELL "$(tool-command-string) -dumpversion" ] ] ; + local tool-version = [ dump-full-version + $(tool-command-string) ] ; if $(tool-version) != $(version) { # Permit a match betwen a two-digit version specified by the @@ -116,7 +116,7 @@ rule init ( version ? : command * : options * : requirement * ) if $(stripped) != $(version) { import errors ; - errors.error toolset gcc initialization: + errors.error toolset gcc "initialization:" : version '$(version)' requested but 'g++-$(version)' not found and version '$(tool-version)' of default '$(tool-command)' @@ -133,7 +133,7 @@ rule init ( version ? : command * : options * : requirement * ) else { import errors ; - errors.error toolset gcc initialization: + errors.error toolset gcc "initialization:" : version '$(version)' requested but neither 'g++-$(version)' nor default 'g++' found : initialized from [ errors.nearest-user-location ] ; @@ -147,7 +147,7 @@ rule init ( version ? : command * : options * : requirement * ) if ! $(tool-command) { import errors ; - errors.error toolset gcc initialization: + errors.error toolset gcc "initialization:" : no command provided, default command 'g++' not found : initialized from [ errors.nearest-user-location ] ; } @@ -179,30 +179,39 @@ rule init ( version ? : command * : options * : requirement * ) bin ?= [ common.get-absolute-tool-path $(command[-1]) ] ; root ?= $(bin:D) ; } + local target-os ; # Autodetect the version and flavor if not given. if $(command) { local machine = [ MATCH "^([^ ]+)" : [ SHELL "$(command-string) -dumpmachine" ] ] ; - version ?= [ MATCH "^([0-9.]+)" : - [ SHELL "$(command-string) -dumpversion" ] ] ; + version ?= [ dump-full-version $(command-string) ] ; switch $(machine:L) { case *mingw* : flavor ?= mingw ; + case *cygwin* : flavor ?= cygwin ; + } + switch $(machine:L) + { + case *mingw* : target-os ?= windows ; + case *cygwin* : target-os ?= cygwin ; + case *linux* : target-os ?= linux ; + # TODO: finish this list. } } local condition ; - if $(flavor) - { - condition = flavor $(flavor) ; - } condition = [ common.check-init-parameters gcc $(requirement) : version $(version) : $(condition) ] ; common.handle-options gcc : $(condition) : $(command) : $(options) ; - init-link-flags gcc "" $(condition) ; + # Set the default target-os for this toolset. + if $(target-os) && ! [ feature.get-values : $(requirement) ] + { + local conditionx = [ regex.replace $(condition) "/" "," ] ; + toolset.add-defaults $(conditionx)\:$(target-os) ; + } # If gcc is installed in a non-standard location, we would need to add # LD_LIBRARY_PATH when running programs created with it (for unit-test/run @@ -217,7 +226,7 @@ rule init ( version ? : command * : options * : requirement * ) local lib_path = $(root)/bin $(root)/lib $(root)/lib32 $(root)/lib64 ; if $(.debug-configuration) { - ECHO notice: using gcc libraries :: $(condition) :: $(lib_path) ; + ECHO "notice:" using gcc libraries "::" $(condition) "::" $(lib_path) ; } toolset.flags gcc.link RUN_PATH $(condition) : $(lib_path) ; } @@ -235,7 +244,7 @@ rule init ( version ? : command * : options * : requirement * ) toolset.flags gcc.archive .AR $(condition) : $(archiver[1]) ; if $(.debug-configuration) { - ECHO notice: using gcc archiver :: $(condition) :: $(archiver[1]) ; + ECHO "notice:" using gcc archiver "::" $(condition) "::" $(archiver[1]) ; } # - Ranlib. @@ -247,7 +256,7 @@ rule init ( version ? : command * : options * : requirement * ) toolset.flags gcc.archive .RANLIB $(condition) : $(ranlib[1]) ; if $(.debug-configuration) { - ECHO notice: using gcc ranlib :: $(condition) :: $(ranlib[1]) ; + ECHO "notice:" using gcc ranlib "::" $(condition) "::" $(ranlib[1]) ; } # - Resource compiler. @@ -268,6 +277,8 @@ rule init ( version ? : command * : options * : requirement * ) rc.configure $(rc) : $(condition) : $(rc-type) ; toolset.flags gcc VERSION $(condition) : [ regex.split $(version) "[.]" ] ; + + init-cxxstd-flags $(condition) : $(version) ; } if [ os.name ] = NT @@ -278,6 +289,15 @@ if [ os.name ] = NT JAMSHELL = % ; } +local rule dump-full-version ( command-string ) +{ + # -dumpfullversion is only supported for gcc 7+. + # Passing both options works, as the first one that's + # recognized will be used. + return [ MATCH "^([0-9.]+)" : + [ SHELL "$(command-string) -dumpfullversion -dumpversion" ] ] ; +} + # Uses -print-prog-name to get the name of the tool. # Converts the path to native form if using cygwin. rule .get-prog-name ( command-string : tool : flavor ? ) @@ -285,7 +305,7 @@ rule .get-prog-name ( command-string : tool : flavor ? ) local prog-name = [ NORMALIZE_PATH [ MATCH "(.*)[\n]+" : [ SHELL "$(command-string) -print-prog-name=$(tool)" ] ] ] ; - if $(flavor) != vxworks && $(flavor) != mingw && [ os.name ] = NT + if $(flavor) = cygwin && [ os.name ] = NT { prog-name = [ cygwin.cygwin-to-windows-path $(prog-name) ] ; } @@ -296,259 +316,127 @@ rule .get-prog-name ( command-string : tool : flavor ? ) ### Functions that set options on the targets. ### -rule set-fpic-options ( targets * : sources * : properties * ) +local all-os = [ feature.values ] ; + +local rule compile-link-flags ( * ) { - local link = [ feature.get-values link : $(properties) ] ; - if $(link) = shared - { - local target-os = [ feature.get-values target-os : $(properties) ] ; - - # This logic will add -fPIC for all compilations: - # - # lib a : a.cpp b ; - # obj b : b.cpp ; - # exe c : c.cpp a d ; - # obj d : d.cpp ; - # - # This all is fine, except that 'd' will be compiled with -fPIC even - # though it is not needed, as 'd' is used only in exe. However, it is - # hard to detect where a target is going to be used. Alternatively, we - # can set -fPIC only when main target type is LIB but than 'b' would be - # compiled without -fPIC which would lead to link errors on x86-64. So, - # compile everything with -fPIC. - # - # Yet another alternative would be to create a propagated - # feature and set it when building shared libraries, but that would be - # hard to implement and would increase the target path length even more. - - # On Windows, fPIC is the default, and specifying -fPIC explicitly leads - # to a warning. - if ! $(target-os) in cygwin windows - { - OPTIONS on $(targets) += -fPIC ; - } - } + toolset.flags gcc.compile OPTIONS $(1) : $(2) ; + toolset.flags gcc.link OPTIONS $(1) : $(2) ; } -rule set-address-model-options ( targets * : sources * : properties * ) { - local model = [ feature.get-values address-model : $(properties) ] ; - if $(model) - { - local option ; - local target-os = [ feature.get-values target-os : $(properties) ] ; - if $(target-os) = aix - { - if $(model) = 32 - { - option = -maix32 ; - } - else - { - option = -maix64 ; - } - } - else if $(target-os) = hpux - { - if $(model) = 32 - { - option = -milp32 ; - } - else - { - option = -mlp64 ; - } - } - else - { - local arch = [ feature.get-values architecture : $(properties) ] ; - if $(arch) = power || $(arch) = sparc || $(arch) = x86 - { - if $(model) = 32 - { - option = -m32 ; - } - else if $(model) = 64 - { - option = -m64 ; - } - } - # For darwin, the model can be 32_64. darwin.jam will handle that - # on its own. - } - OPTIONS on $(targets) += $(option) ; - } + # This logic will add -fPIC for all compilations: + # + # lib a : a.cpp b ; + # obj b : b.cpp ; + # exe c : c.cpp a d ; + # obj d : d.cpp ; + # + # This all is fine, except that 'd' will be compiled with -fPIC even + # though it is not needed, as 'd' is used only in exe. However, it is + # hard to detect where a target is going to be used. Alternatively, we + # can set -fPIC only when main target type is LIB but than 'b' would be + # compiled without -fPIC which would lead to link errors on x86-64. So, + # compile everything with -fPIC. + # + # Yet another alternative would be to create a propagated + # feature and set it when building shared libraries, but that would be + # hard to implement and would increase the target path length even more. + + # On Windows, fPIC is the default, and specifying -fPIC explicitly leads + # to a warning. + local non-windows = [ set.difference $(all-os) : cygwin windows ] ; + compile-link-flags shared/$(non-windows) : -fPIC ; } -rule set-threading-options ( targets * : sources * : properties * ) { - local threading = [ feature.get-values threading : $(properties) ] ; - if $(threading) = multi - { - local target-os = [ feature.get-values target-os : $(properties) ] ; - local host-os = [ feature.get-values host-os : $(properties) ] ; - local toolset = [ feature.get-values toolset : $(properties) ] ; - local option ; - local libs ; - - if $(toolset) = clang && $(target-os) = windows - { - option = -pthread ; - } + # Handle address-model + compile-link-flags aix/32 : -maix32 ; + compile-link-flags aix/64 : -maix64 ; - switch $(target-os) - { - case android : # No threading options, everything is in already. - case windows : option ?= -mthreads ; - case cygwin : option ?= -mthreads ; - case solaris : option ?= -pthreads ; libs = rt ; - case beos : # No threading options. - case haiku : # No threading options. - case *bsd : option ?= -pthread ; # There is no -lrt on BSD. - case sgi : # gcc on IRIX does not support multi-threading. - case darwin : # No threading options. - case vxworks : # No threading options. - case * : option ?= -pthread ; libs = rt ; - } - if $(option) - { - OPTIONS on $(targets) += $(option) ; - } - if $(libs) - { - FINDLIBS-SA on $(targets) += $(libs) ; - } - } -} + compile-link-flags hpux/32 : -milp32 ; + compile-link-flags hpux/64 : -mlp64 ; -local rule zero-pad ( numbers * ) -{ - local result ; - for local n in $(numbers) - { - switch $(n) - { - case ???? : result += $(n) ; - case ??? : result += 0$(n) ; - case ?? : result += 00$(n) ; - case ? : result += 000$(n) ; - } - } - return $(result) ; + local generic-os = [ set.difference $(all-os) : aix hpux ] ; + local arch = power sparc x86 ; + compile-link-flags $(generic-os)/$(arch)/32 : -m32 ; + compile-link-flags $(generic-os)/$(arch)/64 : -m64 ; } -rule set-cxxstd-options ( targets * : sources * : properties * : action ) { - local *targets = [ $(action).targets ] ; - local *sources = [ $(action).sources ] ; - local target-type = [ $(*targets[1]).type ] ; - local source-type = [ $(*sources[1]).type ] ; - local toolset = [ feature.get-values toolset : $(properties) ] ; - local version = [ zero-pad [ on $(targets[1]) return $(VERSION) ] ] ; - version = $(version[1]).$(version[2]) ; - local cxxstd = [ feature.get-values cxxstd : $(properties) ] ; - local cxxstd-dialect = [ feature.get-values cxxstd-dialect : $(properties) ] ; - cxxstd-dialect ?= iso ; - switch $(cxxstd-dialect) - { - case gnu : cxxstd-dialect = gnu++ ; - case iso : cxxstd-dialect = c++ ; - case * : - errors.warning Unknown cxxstd-dialect $(cxxstd-dialect:E=?) .. using - ISO dialect instead. ; - cxxstd-dialect = c++ ; - } - local option ; - if $(cxxstd) = latest + # Handle threading + local rule threading-flags ( * ) { - if $(toolset) = gcc - { - if $(version) >= 0008.0000 { option = 2a ; } - else if $(version) >= 0005.0001 { option = 1z ; } - else if $(version) >= 0004.0008 { option = 1y ; } - else if $(version) >= 0004.0007 { option = 11 ; } - else if $(version) >= 0003.0003 { option = 98 ; } - } - if $(toolset) = clang + compile-link-flags multi/$(1) : $(2) ; + if $(3) { - if $(version) >= 0003.0005 { option = 1z ; } - if $(version) >= 0003.0004 { option = 14 ; } - if $(version) >= 0003.0003 { option = 11 ; } - option ?= 03 ; + toolset.flags gcc.link FINDLIBS-SA multi/$(1) : $(3) ; } } - else - { - option = $(cxxstd) ; - } - if $(source-type) in CPP || $(target-type) in CPP_PCH EXE SHARED_LIB - { - OPTIONS on $(targets) += -std=$(cxxstd-dialect)$(option) ; - } -} -### -### Compiling generators and actions. -### + threading-flags windows : -mthreads ; + threading-flags cygwin : -mthreads ; + threading-flags solaris : -pthreads : rt ; -class gcc-c-compiling-generator : C-compiling-generator -{ - rule action-class ( ) - { - return gcc-c-compile-action ; - } + local bsd = [ MATCH ^(.*bsd)$ : $(all-os) ] ; + threading-flags $(bsd) : -pthread ; + + local no-threading = android beos haiku sgi darwin vxworks ; + local threading-generic-os = [ set.difference $(all-os) : $(no-threading) $(bsd) windows cygwin solaris ] ; + threading-flags $(threading-generic-os) : -pthread : rt ; } -class gcc-c-compile-action : compile-action { - import gcc ; - - rule execute ( action-name targets + : sources * : properties * ) + local rule cxxstd-flags ( * ) { - gcc.set-threading-options $(targets) : $(sources) : $(properties) ; - gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; - gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; - gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) : $(__name__) ; - compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + toolset.flags gcc.compile.c++ OPTIONS $(1) : $(2) ; + toolset.flags gcc.link OPTIONS $(1) : $(2) ; } -} - -local rule register-gcc-c-compiler ( id : source-types + : target-types + : requirements * - : optional-properties * ) -{ - generators.register [ new gcc-c-compiling-generator $(id) : $(source-types) : - $(target-types) : $(requirements) : $(optional-properties) ] ; -} - -register-gcc-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : gcc ; -register-gcc-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : gcc ; -register-gcc-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ; -register-gcc-c-compiler gcc.compile.c : C : OBJ : gcc ; -register-gcc-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; -class gcc-fortran-compiling-generator : fortran-compiling-generator -{ - rule action-class ( ) + local cxxstd = [ feature.values ] ; + local dialects = [ feature.values ] ; + .cxxstd-dialects = [ set.difference $(dialects) : gnu iso ] ; + # C++ latest needs to be set up on a per-toolset basis + for local std in [ set.difference $(cxxstd) : latest ] { - return gcc-fortran-compile-action ; + cxxstd-flags $(std)/iso : -std=c++$(std) ; + cxxstd-flags $(std)/gnu : -std=gnu++$(std) ; + # If we see this it's probably a mistake, but + # toolset.flags has no way to set up diagnostics. + cxxstd-flags $(std)/$(.cxxstd-dialects) : -std=c++$(std) ; } -} -class gcc-fortran-compile-action : compile-action -{ - import gcc ; - - rule execute ( action-name targets + : sources * : properties * ) + local rule version-ge ( lhs : rhs ) + { + lhs = [ regex.split $(lhs) "[.]" ] ; + rhs = [ regex.split $(rhs) "[.]" ] ; + return [ sequence.compare $(rhs) : $(lhs) : numbers.less ] ; + } + # Version specific flags + local rule init-cxxstd-flags ( condition * : version ) { - gcc.set-threading-options $(targets) : $(sources) : $(properties) ; - gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; - gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; - gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) : $(__name__) ; - compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; + local std ; + if [ version-ge $(version) : 8.0 ] { std = 2a ; } + else if [ version-ge $(version) : 5.1 ] { std = 1z ; } + else if [ version-ge $(version) : 4.8 ] { std = 1y ; } + else if [ version-ge $(version) : 4.7 ] { std = 11 ; } + else if [ version-ge $(version) : 3.3 ] { std = 98 ; } + if $(std) + { + cxxstd-flags $(condition)/latest/iso : -std=c++$(std) ; + cxxstd-flags $(condition)/latest/gnu : -std=gnu++$(std) ; + cxxstd-flags $(condition)/latest/$(.cxxstd-dialects) : -std=c++$(std) ; + } } } -generators.register [ new gcc-fortran-compiling-generator +generators.register-c-compiler gcc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : gcc ; +generators.register-c-compiler gcc.compile.c.preprocess : C : PREPROCESSED_C : gcc ; +generators.register-c-compiler gcc.compile.c++ : CPP : OBJ : gcc ; +generators.register-c-compiler gcc.compile.c : C : OBJ : gcc ; +generators.register-c-compiler gcc.compile.asm : ASM : OBJ : gcc ; + +generators.register [ new fortran-compiling-generator gcc.compile.fortran : FORTRAN FORTRAN90 : OBJ : gcc ] ; rule compile.c++.preprocess ( targets * : sources * : properties * ) @@ -675,7 +563,7 @@ class gcc-pch-generator : pch-generator { local location = [ $(project).project-module ] ; import errors : user-error : errors.user-error ; - errors.user-error "in" $(location): pch target name '$(name)' should + errors.user-error "in" "$(location):" pch target name '$(name)' should be the same as the base name of header file '$(header-name)' ; } @@ -685,8 +573,8 @@ class gcc-pch-generator : pch-generator # Return result of base class and pch-file property as # usage-requirements. return - [ property-set.create $(pch-file) -Winvalid-pch ] - $(pch-file) + [ $(pch-file[1]).add-raw $(pch-file[2-]) -Winvalid-pch ] + $(pch-file[2-]) ; } @@ -699,25 +587,6 @@ class gcc-pch-generator : pch-generator return [ generator.generated-targets $(sources) : $(property-set) : $(project) $(name) ] ; } - - rule action-class ( ) - { - return gcc-pch-compile-action ; - } -} - -class gcc-pch-compile-action : compile-action -{ - import gcc ; - - rule execute ( action-name targets + : sources * : properties * ) - { - gcc.set-threading-options $(targets) : $(sources) : $(properties) ; - gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; - gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; - gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) : $(__name__) ; - compile-action.execute $(action-name) $(targets) : $(sources) : $(properties) ; - } } # Note: the 'H' source type will catch both '.h' header and '.hpp' header. The @@ -774,6 +643,10 @@ toolset.flags gcc.compile OPTIONS on : -pg ; toolset.flags gcc.compile.c++ OPTIONS off : -fno-rtti ; toolset.flags gcc.compile.c++ OPTIONS off : -fno-exceptions ; +# configure Dinkum STL to match compiler options +toolset.flags gcc.compile.c++ DEFINES off/vxworks : _NO_RTTI ; +toolset.flags gcc.compile.c++ DEFINES off/vxworks : _NO_EX=1 ; + ### ### User free feature options. ### @@ -829,8 +702,8 @@ class gcc-linking-generator : unix-linking-generator } if $(reason) { - ECHO warning: $(reason) ; - ECHO warning: It is suggested to use 'static' together + ECHO "warning:" $(reason) ; + ECHO "warning:" It is suggested to use 'static' together with 'static'. ; } else @@ -839,26 +712,6 @@ class gcc-linking-generator : unix-linking-generator $(property-set) : $(sources) ] ; } } - - rule action-class ( ) - { - return gcc-link-action ; - } -} - -class gcc-link-action : action -{ - import gcc ; - - rule execute ( action-name targets + : sources * : properties * ) - { - gcc.set-threading-options $(targets) : $(sources) : $(properties) ; - gcc.set-fpic-options $(targets) : $(sources) : $(properties) ; - gcc.set-address-model-options $(targets) : $(sources) : $(properties) ; - gcc.set-cxxstd-options $(targets) : $(sources) : $(properties) : $(__name__) ; - gcc.set-link-options $(action-name) $(targets) : $(sources) : $(properties) ; - action.execute $(action-name) $(targets) : $(sources) : $(properties) ; - } } # The set of permissible input types is different on mingw. So, define two sets @@ -927,230 +780,163 @@ toolset.flags gcc.link LIBRARIES ; toolset.flags gcc.link.dll .IMPLIB-COMMAND windows : "-Wl,--out-implib," ; toolset.flags gcc.link.dll .IMPLIB-COMMAND cygwin : "-Wl,--out-implib," ; -# Now, the vendor specific flags. -# The parameter linker can be either aix, darwin, gnu, hpux, osf or sun. -rule init-link-flags ( toolset subtool condition ) +# target specific link flags { - ## Need to define the linker-type feature once for each toolset module. - if ! [ feature.valid ] - { - feature.subfeature toolset $(toolset) : linker-type : - gnu aix darwin hpux osf sun : propagated link-incompatible ; - } - ## The specification to add the linker-type is per toolset "instance". - toolset.add-requirements - $(condition),aix:aix - $(condition),darwin:darwin - $(condition),hpux:hpux - $(condition),osf:osf - $(condition),solaris:sun - ; -} + # aix -rule set-link-options ( action-name targets + : sources * : properties * ) -{ - local toolset = [ feature.get-values : $(properties) ] ; - local linker-type = [ feature.get-values : $(properties) ] ; - local target-os = [ feature.get-values : $(properties) ] ; + # On AIX we *have* to use the native linker. + # + # Using -brtl, the AIX linker will look for libraries with both the .a + # and .so extensions, such as libfoo.a and libfoo.so. Without -brtl, the + # AIX linker looks only for libfoo.a. Note that libfoo.a is an archived + # file that may contain shared objects and is different from static libs + # as on Linux. + # + # The -bnoipath strips the prepending (relative) path of libraries from + # the loader section in the target library or executable. Hence, during + # load-time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded + # -blibpath (*similar* to -lrpath/-lrpath-link) is searched. Without + # this option, the prepending (relative) path + library name is + # hard-coded in the loader section, causing *only* this path to be + # searched during load-time. Note that the AIX linker does not have an + # -soname equivalent, this is as close as it gets. + # + # The -bbigtoc option instrcuts the linker to create a TOC bigger than 64k. + # This is neccesary for some submodules such as math, but it does make running + # the tests a tad slower. + # + # The above options are definately for AIX 5.x, and most likely also for + # AIX 4.x and AIX 6.x. For details about the AIX linker see: + # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf + # + toolset.flags gcc.link OPTIONS aix : -Wl,-brtl -Wl,-bnoipath -Wl,-bbigtoc ; - switch $(linker-type:G=) - { - case aix : - - # On AIX we *have* to use the native linker. - # - # Using -brtl, the AIX linker will look for libraries with both the .a - # and .so extensions, such as libfoo.a and libfoo.so. Without -brtl, the - # AIX linker looks only for libfoo.a. Note that libfoo.a is an archived - # file that may contain shared objects and is different from static libs - # as on Linux. - # - # The -bnoipath strips the prepending (relative) path of libraries from - # the loader section in the target library or executable. Hence, during - # load-time LIBPATH (identical to LD_LIBRARY_PATH) or a hard-coded - # -blibpath (*similar* to -lrpath/-lrpath-link) is searched. Without - # this option, the prepending (relative) path + library name is - # hard-coded in the loader section, causing *only* this path to be - # searched during load-time. Note that the AIX linker does not have an - # -soname equivalent, this is as close as it gets. - # - # The -bbigtoc option instrcuts the linker to create a TOC bigger than 64k. - # This is neccesary for some submodules such as math, but it does make running - # the tests a tad slower. - # - # The above options are definately for AIX 5.x, and most likely also for - # AIX 4.x and AIX 6.x. For details about the AIX linker see: - # http://download.boulder.ibm.com/ibmdl/pub/software/dw/aix/es-aix_ll.pdf - # - - OPTIONS on $(targets) += -Wl,-brtl -Wl,-bnoipath -Wl,-bbigtoc ; - - # See note [1] - if static in $(properties) - { - OPTIONS on $(targets) += -static ; - } + # See note [1] + toolset.flags gcc.link OPTIONS aix/static : -static ; - case darwin : + # darwin - # On Darwin, the -s option to ld does not work unless we pass -static, - # and passing -static unconditionally is a bad idea. So, do not pass -s - # at all and darwin.jam will use a separate 'strip' invocation. - RPATH on $(targets) += - [ feature.get-values : $(properties) ] ; - # This does not support -R. - RPATH_OPTION on $(targets) += -rpath ; - # -rpath-link is not supported at all. + # On Darwin, the -s option to ld does not work unless we pass -static, + # and passing -static unconditionally is a bad idea. So, do not pass -s + # at all and darwin.jam will use a separate 'strip' invocation. + toolset.flags gcc.link RPATH darwin : ; + # This does not support -R. + toolset.flags gcc.link RPATH_OPTION darwin : -rpath ; + # -rpath-link is not supported at all. - # See note [1] - if static in $(properties) - { - OPTIONS on $(targets) += -static ; - } + # See note [1] + toolset.flags gcc.link OPTIONS darwin/static : -static ; - case vxworks : - # On VxWorks we want to reflect what ever special flags have been set in the - # environment for the CPU we are targeting in the cross build - toolset.flags $(toolset).link OPTIONS $(condition)/on : -Wl,--strip-all : unchecked ; - toolset.flags $(toolset).link OPTIONS $(condition)/static : [ os.environ LDFLAGS_STATIC ] : unchecked ; - toolset.flags $(toolset).link.dll OPTIONS $(condition) : [ os.environ LDFLAGS_SO ] : unchecked ; - toolset.flags $(toolset).link OPTIONS $(condition)/shared : [ os.environ LDFLAGS_DYNAMIC ] : unchecked ; + # vxworks + # On VxWorks we want to reflect what ever special flags have been set in the + # environment for the CPU we are targeting in the cross build + toolset.flags gcc.link OPTIONS vxworks/on : -Wl,--strip-all ; + toolset.flags gcc.link OPTIONS vxworks/static : [ os.environ LDFLAGS_STATIC ] ; + toolset.flags gcc.link.dll OPTIONS vxworks : [ os.environ LDFLAGS_SO ] ; + toolset.flags gcc.link OPTIONS vxworks/shared : [ os.environ LDFLAGS_DYNAMIC ] ; - case gnu : + # default + + local generic-os = [ set.difference $(all-os) : aix darwin vxworks solaris osf hpux ] ; + # Strip the binary when no debugging is needed. We use --strip-all flag + # as opposed to -s since icc (intel's compiler) is generally + # option-compatible with and inherits from the gcc toolset, but does not + # support -s. + toolset.flags gcc.link OPTIONS $(generic-os)/on : + -Wl,--strip-all ; + toolset.flags gcc.link RPATH $(generic-os) : ; + toolset.flags gcc.link RPATH_OPTION $(generic-os) : -rpath ; + toolset.flags gcc.link RPATH_LINK $(generic-os) : ; + toolset.flags gcc.link START-GROUP $(generic-os) : + -Wl,--start-group ; + toolset.flags gcc.link END-GROUP $(generic-os) : -Wl,--end-group ; + + # gnu ld has the ability to change the search behaviour for libraries + # referenced by the -l switch. These modifiers are -Bstatic and + # -Bdynamic and change search for -l switches that follow them. The + # following list shows the tried variants. Search stops at the first + # variant that has a match. + # + # *nix: -Bstatic -lxxx + # libxxx.a + # + # *nix: -Bdynamic -lxxx + # libxxx.so + # libxxx.a + # + # windows (mingw, cygwin) -Bstatic -lxxx + # libxxx.a + # xxx.lib + # + # windows (mingw, cygwin) -Bdynamic -lxxx + # libxxx.dll.a + # xxx.dll.a + # libxxx.a + # xxx.lib + # cygxxx.dll (*) + # libxxx.dll + # xxx.dll + # libxxx.a + # + # (*) This is for cygwin + # Please note that -Bstatic and -Bdynamic are not a guarantee that a + # static or dynamic lib indeed gets linked in. The switches only change + # search patterns! - # Strip the binary when no debugging is needed. We use --strip-all flag - # as opposed to -s since icc (intel's compiler) is generally - # option-compatible with and inherits from the gcc toolset, but does not - # support -s. - if on in $(properties) - { - OPTIONS on $(targets) += -Wl,--strip-all ; - } - RPATH on $(targets) += - [ feature.get-values : $(properties) ] ; - RPATH_OPTION on $(targets) += -rpath ; - RPATH_LINK on $(targets) += - [ feature.get-values : $(properties) ] ; - START-GROUP on $(targets) += -Wl,--start-group ; - END-GROUP on $(targets) += -Wl,--end-group ; - - # gnu ld has the ability to change the search behaviour for libraries - # referenced by the -l switch. These modifiers are -Bstatic and - # -Bdynamic and change search for -l switches that follow them. The - # following list shows the tried variants. Search stops at the first - # variant that has a match. - # - # *nix: -Bstatic -lxxx - # libxxx.a - # - # *nix: -Bdynamic -lxxx - # libxxx.so - # libxxx.a - # - # windows (mingw, cygwin) -Bstatic -lxxx - # libxxx.a - # xxx.lib - # - # windows (mingw, cygwin) -Bdynamic -lxxx - # libxxx.dll.a - # xxx.dll.a - # libxxx.a - # xxx.lib - # cygxxx.dll (*) - # libxxx.dll - # xxx.dll - # libxxx.a - # - # (*) This is for cygwin - # Please note that -Bstatic and -Bdynamic are not a guarantee that a - # static or dynamic lib indeed gets linked in. The switches only change - # search patterns! - - # On *nix mixing shared libs with static runtime is not a good idea. - if shared in $(properties) - { - FINDLIBS-ST-PFX on $(targets) += -Wl,-Bstatic ; - FINDLIBS-SA-PFX on $(targets) += -Wl,-Bdynamic ; - } + # On *nix mixing shared libs with static runtime is not a good idea. + toolset.flags gcc.link FINDLIBS-ST-PFX $(generic-os)/shared : -Wl,-Bstatic ; + toolset.flags gcc.link FINDLIBS-SA-PFX $(generic-os)/shared : -Wl,-Bdynamic ; - # On windows allow mixing of static and dynamic libs with static - # runtime is not a good idea. - if static in $(properties) && windows in $(properties) - { - FINDLIBS-ST-PFX on $(targets) += -Wl,-Bstatic ; - FINDLIBS-SA-PFX on $(targets) += -Wl,-Bdynamic ; - OPTIONS on $(targets) += -Wl,-Bstatic ; - } + # On windows allow mixing of static and dynamic libs with static + # runtime is not a good idea. + toolset.flags gcc.link FINDLIBS-ST-PFX windows/static : -Wl,-Bstatic ; + toolset.flags gcc.link FINDLIBS-SA-PFX windows/static : -Wl,-Bdynamic ; + toolset.flags gcc.link OPTIONS windows/static : -Wl,-Bstatic ; - HAVE_SONAME on $(targets) += "" ; - SONAME_OPTION on $(targets) += -h ; + toolset.flags gcc.link HAVE_SONAME $(generic-os) : "" ; + toolset.flags gcc.link SONAME_OPTION $(generic-os) : -h ; - # See note [1] - if static in $(properties) - { - OPTIONS on $(targets) += -static ; - } + # See note [1] + toolset.flags gcc.link OPTIONS $(generic-os)/static : -static ; - case hpux : + # hpux - if on in $(properties) - { - OPTIONS on $(targets) += -Wl,-s ; - } - if shared in $(properties) - { - OPTIONS on $(targets) += -fPIC ; - } + toolset.flags gcc.link OPTIONS hpux/on : -Wl,-s ; - HAVE_SONAME on $(targets) += "" ; - SONAME_OPTION on $(targets) += +h ; + toolset.flags gcc.link HAVE_SONAME hpux : "" ; + toolset.flags gcc.link SONAME_OPTION hpux : +h ; - case osf : + # osf - # No --strip-all, just -s. - OPTIONS - osf/$(condition)/on - : -Wl,-s - : unchecked ; - RPATH on $(targets) += [ feature.get-values ] ; - # This does not support -R. - RPATH_OPTION on $(targets) += -rpath ; - # -rpath-link is not supported at all. + # No --strip-all, just -s. + toolset.flags gcc.link OPTIONS osf/on : -Wl,-s ; + toolset.flags gcc.link RPATH osf : ; + # This does not support -R. + toolset.flags gcc.link RPATH_OPTION osf : -rpath ; + # -rpath-link is not supported at all. - # See note [1] - if static in $(properties) - { - OPTIONS on $(targets) += -static ; - } + # See note [1] + toolset.flags gcc.link OPTIONS osf/static : -static ; - case sun : + # sun - if on in $(properties) - { - OPTIONS on $(targets) += -Wl,-s ; - } - RPATH on $(targets) += [ feature.get-values ] ; - # Solaris linker does not have a separate -rpath-link, but allows using - # -L for the same purpose. - LINKPATH on $(targets) += [ feature.get-values ] ; - - # This permits shared libraries with non-PIC code on Solaris. - # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the - # following is not needed. Whether -fPIC should be hardcoded, is a - # separate question. - # AH, 2004/10/16: it is still necessary because some tests link against - # static libraries that were compiled without PIC. - if shared in $(properties) - { - OPTIONS on $(targets) += -mimpure-text ; - } + toolset.flags gcc.link OPTIONS solaris/on : -Wl,-s ; - # See note [1] - if static in $(properties) - { - OPTIONS on $(targets) += -static ; - } - } + toolset.flags gcc.link RPATH solaris : ; + # Solaris linker does not have a separate -rpath-link, but allows using + # -L for the same purpose. + toolset.flags gcc.link LINKPATH solaris : ; + + # This permits shared libraries with non-PIC code on Solaris. + # VP, 2004/09/07: Now that we have -fPIC hardcode in link.dll, the + # following is not needed. Whether -fPIC should be hardcoded, is a + # separate question. + # AH, 2004/10/16: it is still necessary because some tests link against + # static libraries that were compiled without PIC. + toolset.flags gcc.link OPTIONS solaris : -mimpure-text ; + + # See note [1] + toolset.flags gcc.link OPTIONS solaris/static : -static ; # [1] # For static we made sure there are no dynamic libraries in the diff --git a/tools/build/src/tools/generate.jam b/tools/build/src/tools/generate.jam index 6732fa3551..7eaecc8890 100644 --- a/tools/build/src/tools/generate.jam +++ b/tools/build/src/tools/generate.jam @@ -8,6 +8,7 @@ import "class" : new ; import errors ; import feature ; +import param ; import project ; import property ; import property-set ; @@ -94,6 +95,8 @@ class generated-target-class : basic-target rule generate ( name : sources * : requirements * : default-build * : usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; local project = [ project.current ] ; targets.main-target-alternative diff --git a/tools/build/src/tools/generators/archive-generator.jam b/tools/build/src/tools/generators/archive-generator.jam index 88ef165591..1b87218023 100644 --- a/tools/build/src/tools/generators/archive-generator.jam +++ b/tools/build/src/tools/generators/archive-generator.jam @@ -11,6 +11,7 @@ import generators ; # class archive-generator : generator { + import generators ; import property-set ; rule __init__ ( id composing ? : source-types + : target-types + @@ -25,6 +26,8 @@ class archive-generator : generator { sources += [ $(property-set).get ] ; + property-set = [ $(property-set).add-raw link ] ; + local result = [ generator.run $(project) $(name) : $(property-set) : $(sources) ] ; @@ -44,7 +47,7 @@ class archive-generator : generator # will link to the library, but it should not cause any harm. So, return # all LIB sources together with created targets, so that dependants link # to them. - local usage-requirements ; + local usage-requirements = link ; if [ $(property-set).get ] = static { for local t in $(sources) @@ -56,9 +59,7 @@ class archive-generator : generator } } - usage-requirements = [ property-set.create $(usage-requirements) ] ; - - return $(usage-requirements) $(result) ; + return [ generators.add-usage-requirements $(result) : $(usage-requirements) ] ; } } diff --git a/tools/build/src/tools/generators/lib-generator.jam b/tools/build/src/tools/generators/lib-generator.jam index f520b6102d..1e5be998bb 100644 --- a/tools/build/src/tools/generators/lib-generator.jam +++ b/tools/build/src/tools/generators/lib-generator.jam @@ -6,6 +6,7 @@ import "class" : new ; import generators ; +import param ; import project ; import targets ; @@ -52,10 +53,11 @@ class lib-generator : generator { actual-type = STATIC_LIB ; } - property-set = [ $(property-set).add-raw LIB ] ; + property-set = [ $(property-set).add-raw LIB link ] ; # Construct the target. - return [ generators.construct $(project) $(name) : $(actual-type) + local result = [ generators.construct $(project) $(name) : $(actual-type) : $(property-set) : $(sources) ] ; + return [ $(result[1]).add-raw link ] $(result[2-]) ; } } @@ -73,6 +75,8 @@ generators.register [ new lib-generator builtin.lib-generator : : LIB ] ; rule lib ( names + : sources * : requirements * : default-build * : usage-requirements * ) { + param.handle-named-params + sources requirements default-build usage-requirements ; if $(names[2]) { if in $(requirements:G) diff --git a/tools/build/src/tools/generators/linking-generator.jam b/tools/build/src/tools/generators/linking-generator.jam index 2184eea5af..23d0c1e8c5 100644 --- a/tools/build/src/tools/generators/linking-generator.jam +++ b/tools/build/src/tools/generators/linking-generator.jam @@ -35,7 +35,7 @@ class linking-generator : generator sources += [ $(property-set).get ] ; # Add properties for all searched libraries. - local extra ; + local extra = link ; for local s in $(sources) { if [ $(s).type ] = SEARCHED_LIB @@ -55,15 +55,8 @@ class linking-generator : generator { if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ] { - # Unfortunately, we do not have a good way to find the path to a - # file, so use this nasty approach. - # - # TODO: This needs to be done better. One thing that is really - # broken with this is that it does not work correctly with - # projects having multiple source locations. - local p = [ $(s).project ] ; local location = [ path.root [ $(s).name ] - [ $(p).get source-location ] ] ; + [ $(s).path ] ] ; extra-xdll-paths += [ path.parent $(location) ] ; } } @@ -90,11 +83,12 @@ class linking-generator : generator local ur ; if $(result) { - ur = [ extra-usage-requirements $(result) : $(property-set) ] ; - ur = [ $(ur).add - [ property-set.create $(extra-xdll-paths) ] ] ; + ur = [ extra-usage-requirements $(result[2-]) : $(property-set) ] ; + ur = [ $(ur).add-raw + link $(extra-xdll-paths) ] ; + ur = [ $(ur).add $(result[1]) ] ; } - return $(ur) $(result) ; + return $(ur) $(result[2-]) ; } rule extra-usage-requirements ( created-targets * : property-set ) diff --git a/tools/build/src/tools/generators/searched-lib-generator.jam b/tools/build/src/tools/generators/searched-lib-generator.jam index 174d137e3a..b3435daa35 100644 --- a/tools/build/src/tools/generators/searched-lib-generator.jam +++ b/tools/build/src/tools/generators/searched-lib-generator.jam @@ -38,7 +38,7 @@ class searched-lib-generator : generator local search = [ feature.get-values : $(properties) ] ; - local a = [ new null-action $(property-set) ] ; + local a = [ new null-action [ $(property-set).add-raw link ] ] ; local lib-name = [ feature.get-values : $(properties) ] ; lib-name ?= $(name) ; local t = [ new searched-lib-target $(lib-name) : $(project) @@ -47,7 +47,7 @@ class searched-lib-generator : generator # lib png : z : png ; # the 'z' target should be returned, so that apps linking to 'png' # will link to 'z', too. - return [ property-set.create $(search) ] + return [ property-set.create $(search) link ] [ virtual-target.register $(t) ] $(sources) ; } } @@ -86,6 +86,11 @@ class searched-lib-target : abstract-file-target NOTFILE $(target) ; } + rule relevant ( ) + { + return [ property-set.create link ] ; + } + rule path ( ) { } diff --git a/tools/build/src/tools/ifort.jam b/tools/build/src/tools/ifort.jam index eb7c198818..958485928a 100644 --- a/tools/build/src/tools/ifort.jam +++ b/tools/build/src/tools/ifort.jam @@ -19,7 +19,7 @@ flags ifort OPTIONS off : /Od ; flags ifort OPTIONS speed : /O3 ; flags ifort OPTIONS space : /O1 ; -flags ifort OPTIONS on : /debug:full ; +flags ifort OPTIONS on : "/debug:full" ; flags ifort OPTIONS on : /Qprof_gen ; flags ifort.compile FFLAGS off/shared : /MD ; diff --git a/tools/build/src/tools/intel-darwin.jam b/tools/build/src/tools/intel-darwin.jam index 228793eb4d..077f0e2b35 100644 --- a/tools/build/src/tools/intel-darwin.jam +++ b/tools/build/src/tools/intel-darwin.jam @@ -55,8 +55,6 @@ rule init ( version ? : command * : options * ) common.handle-options intel-darwin : $(condition) : $(command) : $(options) ; - gcc.init-link-flags intel-darwin darwin $(condition) ; - # handle # local library-path = [ feature.get-values : $(options) ] ; # flags intel-darwin.link USER_OPTIONS $(condition) : [ feature.get-values : $(options) ] ; @@ -77,7 +75,7 @@ rule init ( version ? : command * : options * ) local lib_path = $(root)/lib $(root:P)/lib/$(bin:B) ; if $(.debug-configuration) { - ECHO notice: using intel libraries :: $(condition) :: $(lib_path) ; + ECHO notice\: using intel libraries "::" $(condition) "::" $(lib_path) ; } flags intel-darwin.link RUN_PATH $(condition) : $(lib_path) ; } @@ -118,6 +116,14 @@ rule init ( version ? : command * : options * ) if $(major) = "9" || ( $(major) = "10" && ( $(minor) = "0" || $(minor) = "1" ) ) { flags intel-darwin.compile DEFINES $(condition) : __WINT_TYPE__=int : unchecked ; } + + # - Ranlib. + local ranlib = [ feature.get-values : $(options) ] ; + toolset.flags intel-darwin.archive .RANLIB $(condition) : $(ranlib[1]) ; + + # - Archive builder. + local archiver = [ feature.get-values : $(options) ] ; + toolset.flags intel-darwin.archive .AR $(condition) : $(archiver[1]) ; } SPACE = " " ; @@ -168,6 +174,7 @@ flags intel-darwin ARFLAGS ; # logic in intel-linux, but that's hardly worth the trouble # as on Linux, 'ar' is always available. .AR = ar ; +.RANLIB = ranlib ; rule archive ( targets * : sources * : properties * ) { @@ -201,7 +208,7 @@ rule archive ( targets * : sources * : properties * ) actions piecemeal archive { "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)" - "ranlib" -cs "$(<)" + "$(.RANLIB)" -cs "$(<)" } flags intel-darwin.link USER_OPTIONS ; diff --git a/tools/build/src/tools/intel-linux.jam b/tools/build/src/tools/intel-linux.jam index c743e52d28..bfa03a14c5 100644 --- a/tools/build/src/tools/intel-linux.jam +++ b/tools/build/src/tools/intel-linux.jam @@ -96,8 +96,6 @@ rule init ( version ? : command * : options * ) : $(command) : $(default_path) ] ; common.handle-options intel-linux : $(condition) : $(command) : $(options) ; - - gcc.init-link-flags intel-linux gnu $(condition) ; local root = [ feature.get-values : $(options) ] ; local bin ; @@ -147,7 +145,7 @@ rule init ( version ? : command * : options * ) local lib_path = $(root)/lib $(root:P)/lib/$(bin:B) ; if $(.debug-configuration) { - ECHO notice: using intel libraries :: $(condition) :: $(lib_path) ; + ECHO notice\: using intel libraries "::" $(condition) "::" $(lib_path) ; } flags intel-linux.link RUN_PATH $(condition) : $(lib_path) ; } diff --git a/tools/build/src/tools/intel-vxworks.jam b/tools/build/src/tools/intel-vxworks.jam index 8d9a3e3a0e..2db9355155 100644 --- a/tools/build/src/tools/intel-vxworks.jam +++ b/tools/build/src/tools/intel-vxworks.jam @@ -54,8 +54,6 @@ rule init ( version ? : command * : options * ) common.handle-options intel-vxworks : $(condition) : $(command) : $(options) ; - gcc.init-link-flags intel-vxworks vxworks $(condition) ; - # handle # local library-path = [ feature.get-values : $(options) ] ; # flags intel-vxworks.link USER_OPTIONS $(condition) : [ feature.get-values : $(options) ] ; @@ -76,7 +74,7 @@ rule init ( version ? : command * : options * ) local lib_path = $(root)/lib $(root:P)/lib/$(bin:B) ; if $(.debug-configuration) { - ECHO notice: using intel libraries :: $(condition) :: $(lib_path) ; + ECHO notice\: using intel libraries "::" $(condition) "::" $(lib_path) ; } flags intel-vxworks.link RUN_PATH $(condition) : $(lib_path) ; } diff --git a/tools/build/src/tools/intel-win.jam b/tools/build/src/tools/intel-win.jam index 6d5aca50ec..16fe1824ba 100644 --- a/tools/build/src/tools/intel-win.jam +++ b/tools/build/src/tools/intel-win.jam @@ -76,7 +76,7 @@ local rule configure ( version ? : command * : options * ) local compatibility = [ feature.get-values : $(options) ] ; # Allow to specify toolset and visual studio backend from commandline .e.g --toolset=intel-14.0-vc10 - local vc_in_version = [ MATCH (vc[0-9]+(\\.[0-9]+)?)$ : $(version) ] ; + local vc_in_version = [ MATCH "(vc[0-9]+(\\.[0-9]+)?)$" : $(version) ] ; vc_in_version = $(vc_in_version[1]) ; if $(compatibility) && $(vc_in_version) { @@ -103,7 +103,7 @@ local rule configure ( version ? : command * : options * ) local msvc_versions = [ feature.values ] ; if ! $(msvc_versions) { - ECHO notice: no msvc versions detected. trying auto detect ; + ECHO notice\: no msvc versions detected. trying auto detect ; toolset.using msvc : all ; msvc_versions = [ feature.values ] ; } @@ -117,7 +117,7 @@ local rule configure ( version ? : command * : options * ) if [ MATCH "($(v))" : $(.iclvars-$(version)-supported-vcs) ] { # Strip trailing .0 from msvc version as intel compiler uses atm only major version for Qvc - local m = [ MATCH ([0-9]+).0$ : $(v) ] ; + local m = [ MATCH "([0-9]+).0$" : $(v) ] ; if $(m) { v = $(m) ; @@ -145,7 +145,7 @@ local rule configure-really ( version ? : command * : options * : compatibility local condition = [ common.check-init-parameters intel-win : version $(version) : compatibility $(compatibility) ] ; - local m = [ MATCH ([0-9]+).* : $(version) ] ; + local m = [ MATCH "([0-9]+).*" : $(version) ] ; local major = $(m[1]) ; if ! $(major) { @@ -234,9 +234,21 @@ local rule configure-really ( version ? : command * : options * : compatibility local setup-call ; if $(major) >= 12 { - local t = [ msvc.maybe-rewrite-setup intel-win : "\"$(setup)\"" : "$(c) $(iclvars_vs_arg)" : $(version) : $(rewrite-setupscript) ] ; - setup-call = "call $(t) > nul " ; cpu-conditions = $(condition)/$(.cpu-arch-$(c)) ; + + if ! $(setup) + { + # No setup script + } + else if $(rewrite-setupscript) = off || [ os.name ] != NT + { + setup-call = "call \"$(setup)\" $(c) $(iclvars_vs_arg)" ; + } + else + { + toolset.flags intel-win .SETUP-SCRIPT $(cpu-conditions) : $(setup) ; + toolset.flags intel-win .SETUP-OPTIONS $(cpu-conditions) : "$(c) $(iclvars_vs_arg)" ; + } } else { @@ -244,15 +256,17 @@ local rule configure-really ( version ? : command * : options * : compatibility cpu-conditions = $(condition) ; } - - if [ os.name ] = NT + if $(setup-call) { - setup-call = $(setup-call)" - " ; - } - else - { - setup-call = "cmd /S /C "$(setup-call)" \"&&\" " ; + if [ os.name ] = NT + { + setup-call = $(setup-call)"\n " ; + } + else + { + setup-call = "cmd /S /C "$(setup-call)" \"&&\" " ; + } + toolset.flags intel-win .SETUP $(cpu-conditions) : $(setup-call) ; } if $(.debug-configuration) @@ -266,13 +280,13 @@ local rule configure-really ( version ? : command * : options * : compatibility local cpu-assembler = $(assembler) ; cpu-assembler ?= $(default-assembler-$(c)) ; - toolset.flags intel-win.compile .CC $(cpu-conditions) : $(setup-call)icl ; - toolset.flags intel-win.link .LD $(cpu-conditions) : $(setup-call)xilink /nologo ; - toolset.flags intel-win.archive .LD $(cpu-conditions) : $(setup-call)xilink /lib /nologo ; - toolset.flags intel-win.link .MT $(cpu-conditions) : $(setup-call)mt -nologo ; - toolset.flags intel-win.compile .ASM $(cpu-conditions) : $(setup-call)$(cpu-assembler) -nologo ; - toolset.flags intel-win.compile .MC $(cpu-conditions) : $(setup-call)mc ; - toolset.flags intel-win.compile .RC $(cpu-conditions) : $(setup-call)rc ; + toolset.flags intel-win.compile .CC $(cpu-conditions) : icl ; + toolset.flags intel-win.link .LD $(cpu-conditions) : xilink /nologo ; + toolset.flags intel-win.archive .LD $(cpu-conditions) : xilink /lib /nologo ; + toolset.flags intel-win.link .MT $(cpu-conditions) : mt -nologo ; + toolset.flags intel-win.compile .ASM $(cpu-conditions) : $(cpu-assembler) -nologo ; + toolset.flags intel-win.compile .MC $(cpu-conditions) : mc ; + toolset.flags intel-win.compile .RC $(cpu-conditions) : rc ; } # Depending on the settings, running of tests require some runtime DLLs. @@ -298,7 +312,7 @@ local rule configure-really ( version ? : command * : options * : compatibility if $(major) > 5 { - C++FLAGS += /Zc:forScope ; # Add support for correct for loop scoping. + C++FLAGS += "/Zc:forScope" ; # Add support for correct for loop scoping. } # Add options recognized only by intel7 and above. @@ -324,7 +338,7 @@ local rule configure-really ( version ? : command * : options * : compatibility if $(major) > 5 { # Add support for wchar_t - C++FLAGS += /Zc:wchar_t + C++FLAGS += "/Zc:wchar_t" # Tell the dinkumware library about it. -D_NATIVE_WCHAR_T_DEFINED ; @@ -372,7 +386,7 @@ local rule get-autodetect-versions local result ; for local v in $(.intel-autodetect-versions) { - local major = [ MATCH ([0-9]+).* : $(v) ] ; # Use only major version + local major = [ MATCH "([0-9]+).*" : $(v) ] ; # Use only major version if [ get-icl-path-from-environment $(major) ] { result += $(v) ; diff --git a/tools/build/src/tools/lex.jam b/tools/build/src/tools/lex.jam index 75d641318c..e85d1d1adf 100644 --- a/tools/build/src/tools/lex.jam +++ b/tools/build/src/tools/lex.jam @@ -5,8 +5,7 @@ import type ; import generators ; import feature ; -import property ; - +import toolset : flags ; feature.feature flex.prefix : : free ; type.register LEX : l ; @@ -18,14 +17,7 @@ rule init ( ) { } -rule lex ( target : source : properties * ) -{ - local r = [ property.select flex.prefix : $(properties) ] ; - if $(r) - { - PREFIX on $(<) = $(r:G=) ; - } -} +flags lex.lex PREFIX ; actions lex { diff --git a/tools/build/src/tools/libjpeg.jam b/tools/build/src/tools/libjpeg.jam index 309b59df61..f267ecb73d 100644 --- a/tools/build/src/tools/libjpeg.jam +++ b/tools/build/src/tools/libjpeg.jam @@ -14,17 +14,20 @@ import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; import property ; import property-set ; header = jpeglib.h ; +# jpeglib.h requires stdio.h to be included first. +header-test = "#include \n#include \n" ; + names = jpeg ; sources = jaricom.c jcapimin.c jcapistd.c jcarith.c jccoefct.c jccolor.c @@ -99,7 +102,10 @@ rule init ( : is-default ? # Default configurations are only used when libjpeg - # has not yet been configured. + # has not yet been configured. This option is + # deprecated. A configuration will be treated + # as a default when none of , , + # , and are present. ) { local caller = [ project.current ] ; @@ -113,24 +119,22 @@ rule init ( project libjpeg ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local source-path = [ property.select : $(options) ] ; - source-path = $(source-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; - local tag = [ property.select : $(options) ] ; - tag = $(tag:G=) ; - local build-name = [ property.select : $(options) ] ; - build-name = $(build-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local source-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + local tag = [ feature.get-values : $(options) ] ; + local build-name = [ feature.get-values : $(options) ] ; condition = [ property-set.create $(requirements) ] ; condition = [ property-set.create [ $(condition).base ] ] ; - local no-build-from-source ; - # Ignore environmental ZLIB_SOURCE if this initialization + if ! $(library-path) && ! $(include-path) && ! $(source-path) && ! $(library-name) + { + is-default = true ; + } + + # Ignore environmental LIBJPEG_SOURCE if this initialization # requested to search for a specific pre-built library. if $(library-path) || $(include-path) || $(library-name) { @@ -140,13 +144,11 @@ rule init ( [ property.select : $(options) ] "and" [ property.select : $(options) ] ; } - else - { - no-build-from-source = true ; - } } - - source-path ?= [ modules.peek : ZLIB_SOURCE ] ; + else + { + source-path ?= [ modules.peek : LIBJPEG_SOURCE ] ; + } if $(.configured.$(condition)) { @@ -163,12 +165,12 @@ rule init ( } return ; } - else if $(source-path) && ! $(no-build-from-source) + else if $(source-path) { build-name ?= jpeg ; library-id = [ CALC $(library-id) + 1 ] ; tag = [ MATCH ^@?(.*)$ : $(tag) ] ; - if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ] + if $(tag) { tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ; } @@ -199,7 +201,6 @@ rule init ( $(source-path) msvc:_CRT_SECURE_NO_DEPRECATE msvc:_SCL_SECURE_NO_DEPRECATE - shared:ZLIB_DLL : : $(source-path) ] ; } @@ -225,6 +226,7 @@ rule init ( local mt = [ new ac-library libjpeg : $(.project) : $(condition) : $(include-path) : $(library-path) : $(library-name) : $(root) ] ; $(mt).set-header $(header) ; + $(mt).set-header-test $(header-test) ; $(mt).set-default-names $(names) ; targets.main-target-alternative $(mt) ; } diff --git a/tools/build/src/tools/libpng.jam b/tools/build/src/tools/libpng.jam index 46e3cc9ae3..43f6817633 100644 --- a/tools/build/src/tools/libpng.jam +++ b/tools/build/src/tools/libpng.jam @@ -14,11 +14,11 @@ import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; import property ; import property-set ; @@ -93,7 +93,10 @@ rule init ( : is-default ? # Default configurations are only used when libpng - # has not yet been configured. + # has not yet been configured. This option is + # deprecated. A configuration will be treated + # as a default when none of , , + # , and are present. ) { local caller = [ project.current ] ; @@ -107,23 +110,21 @@ rule init ( project libpng ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local source-path = [ property.select : $(options) ] ; - source-path = $(source-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; - local tag = [ property.select : $(options) ] ; - tag = $(tag:G=) ; - local build-name = [ property.select : $(options) ] ; - build-name = $(build-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local source-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + local tag = [ feature.get-values : $(options) ] ; + local build-name = [ feature.get-values : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(source-path) && ! $(library-name) + { + is-default = true ; + } condition = [ property-set.create $(requirements) ] ; condition = [ property-set.create [ $(condition).base ] ] ; - local no-build-from-source ; # Ignore environmental LIBPNG_SOURCE if this initialization # requested to search for a specific pre-built library. if $(library-path) || $(include-path) || $(library-name) @@ -134,13 +135,11 @@ rule init ( [ property.select : $(options) ] "and" [ property.select : $(options) ] ; } - else - { - no-build-from-source = true ; - } } - - source-path ?= [ modules.peek : LIBPNG_SOURCE ] ; + else + { + source-path ?= [ modules.peek : LIBPNG_SOURCE ] ; + } if $(.configured.$(condition)) { @@ -157,12 +156,12 @@ rule init ( } return ; } - else if $(source-path) && ! $(no-build-from-source) + else if $(source-path) { build-name ?= png ; library-id = [ CALC $(library-id) + 1 ] ; tag = [ MATCH ^@?(.*)$ : $(tag) ] ; - if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ] + if $(tag) { tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ; } diff --git a/tools/build/src/tools/libtiff.jam b/tools/build/src/tools/libtiff.jam index cbd8ad0151..f315614912 100644 --- a/tools/build/src/tools/libtiff.jam +++ b/tools/build/src/tools/libtiff.jam @@ -14,11 +14,11 @@ import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; import property ; import property-set ; @@ -96,7 +96,10 @@ rule init ( : is-default ? # Default configurations are only used when libtiff - # has not yet been configured. + # has not yet been configured. This option is + # deprecated. A configuration will be treated + # as a default when none of , , + # , and are present. ) { local caller = [ project.current ] ; @@ -110,24 +113,22 @@ rule init ( project libtiff ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local source-path = [ property.select : $(options) ] ; - source-path = $(source-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; - local tag = [ property.select : $(options) ] ; - tag = $(tag:G=) ; - local build-name = [ property.select : $(options) ] ; - build-name = $(build-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local source-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + local tag = [ feature.get-values : $(options) ] ; + local build-name = [ feature.get-values : $(options) ] ; + + if ! $(library-path) && ! $(include-path) && ! $(source-path) && ! $(library-name) + { + is-default = true ; + } condition = [ property-set.create $(requirements) ] ; condition = [ property-set.create [ $(condition).base ] ] ; - local no-build-from-source ; - # Ignore environmental ZLIB_SOURCE if this initialization + # Ignore environmental LIBTIFF_SOURCE if this initialization # requested to search for a specific pre-built library. if $(library-path) || $(include-path) || $(library-name) { @@ -137,13 +138,11 @@ rule init ( [ property.select : $(options) ] "and" [ property.select : $(options) ] ; } - else - { - no-build-from-source = true ; - } } - - source-path ?= [ modules.peek : ZLIB_SOURCE ] ; + else + { + source-path ?= [ modules.peek : LIBTIFF_SOURCE ] ; + } if $(.configured.$(condition)) { @@ -160,12 +159,12 @@ rule init ( } return ; } - else if $(source-path) && ! $(no-build-from-source) + else if $(source-path) { build-name ?= tiff ; library-id = [ CALC $(library-id) + 1 ] ; tag = [ MATCH ^@?(.*)$ : $(tag) ] ; - if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ] + if $(tag) { tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ; } @@ -196,7 +195,6 @@ rule init ( $(source-path) msvc:_CRT_SECURE_NO_DEPRECATE msvc:_SCL_SECURE_NO_DEPRECATE - shared:ZLIB_DLL : : $(source-path) ] ; } diff --git a/tools/build/src/tools/link.jam b/tools/build/src/tools/link.jam index 50ec485c61..3cf6e46f7d 100644 --- a/tools/build/src/tools/link.jam +++ b/tools/build/src/tools/link.jam @@ -34,7 +34,7 @@ actions touch { $(TOUCH) "$(<)" } -rule can-symlink ( project : ps ) +rule can-symlink ( project ) { if ! $(.can-symlink) { @@ -45,7 +45,7 @@ rule can-symlink ( project : ps ) local target = [ new file-target test-symlink : : $(project) : [ new action $(source-target) : link.mklink ] ] ; - if [ configure.try-build $(target) : $(ps) : "symlinks supported" ] + if [ configure.try-build $(target) : [ property-set.empty ] : "symlinks supported" ] { .can-symlink = true ; } @@ -64,7 +64,7 @@ if [ os.name ] = NT { # Test for Windows junctions (mklink /J) -rule can-junction ( project : ps ) +rule can-junction ( project ) { if ! $(.can-junction) { @@ -75,7 +75,7 @@ rule can-junction ( project : ps ) local target = [ new file-target test-junction : : $(project) : [ new action $(source-target) : link.junction ] ] ; - if [ configure.try-build $(target) : $(ps) : "junctions supported" ] + if [ configure.try-build $(target) : [ property-set.empty ] : "junctions supported" ] { .can-junction = true ; } @@ -96,13 +96,13 @@ else .can-junction = false ; -rule can-junction ( project : ps ) +rule can-junction ( project ) { } } -rule can-hardlink ( project : ps ) +rule can-hardlink ( project ) { if ! $(.can-hardlink) { @@ -119,7 +119,7 @@ rule can-hardlink ( project : ps ) : [ new property-set symlink ] ] ] ; - if [ configure.try-build $(target) : $(ps) : "hardlinks supported" ] + if [ configure.try-build $(target) : [ property-set.empty ] : "hardlinks supported" ] { .can-hardlink = true ; } @@ -192,10 +192,10 @@ class symlink-target-class : basic-target # If we have symlinks, don't bother checking # for hardlinks and junctions. - if ! [ link.can-symlink $(self.project) : $(property-set) ] + if ! [ link.can-symlink $(self.project) ] { - link.can-junction $(self.project) : $(property-set) ; - link.can-hardlink $(self.project) : $(property-set) ; + link.can-junction $(self.project) ; + link.can-hardlink $(self.project) ; } if [ $(property-set).get ] diff --git a/tools/build/src/tools/lzma.jam b/tools/build/src/tools/lzma.jam index 2c9c77b6f6..0ceeff1173 100644 --- a/tools/build/src/tools/lzma.jam +++ b/tools/build/src/tools/lzma.jam @@ -9,16 +9,16 @@ # # After 'using lzma', the following targets are available: # -# /lzma//lzam -- The lzma library +# /lzma//lzma -- The lzma library import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; import property ; import property-set ; @@ -33,6 +33,29 @@ if --debug-configuration in [ modules.peek : ARGV ] .debug = true ; } +# Initializes the lzma library. +# +# Options for configuring lzma:: +# +# +# The directory containing the lzma binaries. +# +# Overrides the default library name. +# +# The directory containing the lzma headers. +# +# If none of these options is specified, then the environmental +# variables LZMA_LIBRARY_PATH, LZMA_NAME, and LZMA_INCLUDE will +# be used instead. +# +# Examples:: +# +# # Find lzma in the default system location +# using lzma ; +# # Find lzma in /usr/local +# using lzma : 1.2.7 +# : /usr/local/include /usr/local/lib ; +# rule init ( version ? # (currently ignored) @@ -62,12 +85,9 @@ rule init ( project lzma ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; if ! $(options) { diff --git a/tools/build/src/tools/make.jam b/tools/build/src/tools/make.jam index 40b59faf38..b0784b6209 100644 --- a/tools/build/src/tools/make.jam +++ b/tools/build/src/tools/make.jam @@ -9,6 +9,7 @@ # This module defines the 'make' main target rule. import "class" : new ; +import param ; import project ; import property-set ; import targets ; @@ -17,6 +18,8 @@ import targets ; class make-target-class : basic-target { import "class" : new ; + import indirect ; + import toolset ; import type ; import virtual-target ; @@ -34,10 +37,11 @@ class make-target-class : basic-target # below. local m = [ MATCH ^@(.*) : $(action-name) ] ; - local a = [ new action $(source-targets) : $(m[1]) : $(property-set) ] ; + local relevant = [ toolset.relevant [ indirect.get-rule $(m[1]) ] ] ; + local a = [ new action $(source-targets) : $(m[1]) : [ $(property-set).add $(relevant) ] ] ; local t = [ new file-target $(self.name) exact : [ type.type $(self.name) ] : $(self.project) : $(a) ] ; - return [ property-set.empty ] [ virtual-target.register $(t) ] ; + return $(relevant) [ virtual-target.register $(t) ] ; } } @@ -47,6 +51,8 @@ class make-target-class : basic-target rule make ( target-name : sources * : generating-rule + : requirements * : usage-requirements * ) { + param.handle-named-params + sources generating-rule requirements default-build usage-requirements ; # The '@' sign causes the feature.jam module to qualify rule name with the # module name of current project, if needed. local m = [ MATCH ^(@).* : $(generating-rule) ] ; diff --git a/tools/build/src/tools/mipspro.jam b/tools/build/src/tools/mipspro.jam index 417eaefcf7..9e8c39693a 100644 --- a/tools/build/src/tools/mipspro.jam +++ b/tools/build/src/tools/mipspro.jam @@ -71,8 +71,8 @@ flags mipspro.compile OPTIONS on : -ansiW -diag_suppress 1429 ; # supp flags mipspro.compile OPTIONS all : -fullwarn ; flags mipspro.compile OPTIONS speed : -Ofast ; flags mipspro.compile OPTIONS space : -O2 ; -flags mipspro.compile OPTIONS : -LANG:std ; -flags mipspro.compile.c++ OPTIONS off : -INLINE:none ; +flags mipspro.compile OPTIONS : "-LANG:std" ; +flags mipspro.compile.c++ OPTIONS off : "-INLINE:none" ; flags mipspro.compile.c++ OPTIONS ; flags mipspro.compile DEFINES ; flags mipspro.compile INCLUDES ; diff --git a/tools/build/src/tools/mpi.jam b/tools/build/src/tools/mpi.jam index 1ccc541330..1cb8331ea5 100644 --- a/tools/build/src/tools/mpi.jam +++ b/tools/build/src/tools/mpi.jam @@ -589,12 +589,16 @@ generators.register-standard testing.expect-success : RUN_MPI_OUTPUT : RUN_MPI ; # The number of processes to spawn when executing an MPI test. -feature mpi:processes : : free incidental ; +feature "mpi:processes" : : free incidental ; # The flag settings on testing.capture-output do not # apply to mpi.capture output at the moment. # Redo this explicitly. toolset.flags mpi.capture-output ARGS ; +toolset.uses-features mpi.capture-output : + + ; + rule capture-output ( target : sources * : properties * ) { # Use the standard capture-output rule to run the tests diff --git a/tools/build/src/tools/msvc.jam b/tools/build/src/tools/msvc.jam index f5e56e0c4f..641ea10499 100644 --- a/tools/build/src/tools/msvc.jam +++ b/tools/build/src/tools/msvc.jam @@ -31,11 +31,14 @@ import midl ; import os ; import path ; import pch ; +import project ; import property ; +import property-set ; import rc ; import set ; import toolset ; import type ; +import virtual-target ; type.register MANIFEST : manifest ; @@ -138,7 +141,7 @@ rule init ( # # # Whether to rewrite setup scripts. New scripts will be output in - # TEMP directory and will be used instead of originals in build actions. + # build tree and will be used instead of originals in build actions. # Possible values: # * on - rewrite scripts, if they do not already exist (default) # * always - always rewrite scripts, even if they already exist @@ -219,7 +222,7 @@ rule configure-version-specific ( toolset : version : conditions ) # version 7.* explicitly or if we auto-detected the version ourselves. if ! [ MATCH ^(6\\.) : $(version) ] { - toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ; + toolset.flags $(toolset).compile CFLAGS $(conditions) : "/Zc:forScope" "/Zc:wchar_t" ; toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ; # Explicitly disable the 'function is deprecated' warning. Some msvc @@ -227,7 +230,7 @@ rule configure-version-specific ( toolset : version : conditions ) # with /W0. toolset.flags $(toolset).compile CFLAGS $(conditions)/off : /wd4996 ; - if [ MATCH ^([78]\\.) : $(version) ] + if [ MATCH "^([78]\\.)" : $(version) ] { # 64-bit compatibility warning deprecated since 9.0, see # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx @@ -239,7 +242,7 @@ rule configure-version-specific ( toolset : version : conditions ) # Processor-specific optimization. # - if [ MATCH ^([67]) : $(version) ] + if [ MATCH "^([67])" : $(version) ] { # 8.0 deprecates some of the options. toolset.flags $(toolset).compile CFLAGS $(conditions)/speed $(conditions)/space : /Ogiy /Gs ; @@ -263,19 +266,19 @@ rule configure-version-specific ( toolset : version : conditions ) else { # 8.0 and above adds some more options. - toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/ : /favor:blend ; - toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-em64t) : /favor:EM64T ; - toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-amd64) : /favor:AMD64 ; + toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/ : "/favor:blend" ; + toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-em64t) : "/favor:EM64T" ; + toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/$(.cpu-type-amd64) : "/favor:AMD64" ; # 8.0 and above only has multi-threaded static RTL. toolset.flags $(toolset).compile CFLAGS $(conditions)/off/static/single : /MT ; toolset.flags $(toolset).compile CFLAGS $(conditions)/on/static/single : /MTd ; # Specify target machine type so the linker will not need to guess. - toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : /MACHINE:X64 ; - toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : /MACHINE:X86 ; - toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : /MACHINE:IA64 ; - toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : /MACHINE:ARM ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : "/MACHINE:X64" ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : "/MACHINE:X86" ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : "/MACHINE:IA64" ; + toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-arm) : "/MACHINE:ARM" ; # Make sure that manifest will be generated even if there is no # dependencies to put there. @@ -290,7 +293,7 @@ feature.feature windows-api : desktop store phone : propagated composite link-in feature.compose store : WINAPI_FAMILY=WINAPI_FAMILY_APP _WIN32_WINNT=0x0602 /APPCONTAINER ; feature.compose phone : WINAPI_FAMILY=WINAPI_FAMILY_PHONE_APP _WIN32_WINNT=0x0602 - /APPCONTAINER /NODEFAULTLIB:ole32.lib /NODEFAULTLIB:kernel32.lib WindowsPhoneCore.lib ; + /APPCONTAINER "/NODEFAULTLIB:ole32.lib" "/NODEFAULTLIB:kernel32.lib" WindowsPhoneCore.lib ; feature.set-default windows-api : desktop ; @@ -325,7 +328,7 @@ if [ os.name ] in NT actions archive { if exist "$(<[1])" DEL "$(<[1])" - $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" } } else @@ -333,10 +336,14 @@ else actions archive { $(.RM) "$(<[1])" - $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" } } +rule compile.asm ( targets + : sources * : properties * ) +{ + set-setup-command $(targets) : $(properties) ; +} # For the assembler the following options are turned on by default: # @@ -346,12 +353,13 @@ else # actions compile.asm { - $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)" + $(.SETUP) $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)" } rule compile.c ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; C++FLAGS on $(targets[1]) = ; get-rspline $(targets) : -TC ; compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; @@ -360,6 +368,7 @@ rule compile.c ( targets + : sources * : properties * ) rule compile.c.preprocess ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; C++FLAGS on $(targets[1]) = ; get-rspline $(targets) : -TC ; preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; @@ -368,6 +377,7 @@ rule compile.c.preprocess ( targets + : sources * : properties * ) rule compile.c.pch ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; C++FLAGS on $(targets[1]) = ; get-rspline $(targets[1]) : -TC ; get-rspline $(targets[2]) : -TC ; @@ -405,12 +415,12 @@ toolset.flags msvc YLOPTION : "-Yl" ; # actions compile-c-c++ bind PDB_NAME { - $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER) + $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER) } actions preprocess-c-c++ bind PDB_NAME { - $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)" + $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)" } rule compile-c-c++ ( targets + : sources * ) @@ -437,7 +447,7 @@ rule preprocess-c-c++ ( targets + : sources * ) # syntax highlighting in the messy N-quoted code below. actions compile-c-c++-pch { - $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER) + $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER) } @@ -446,18 +456,20 @@ actions compile-c-c++-pch # given as one of the source parameters. actions compile-c-c++-pch-s { - $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER) + $(.SETUP) $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER) } rule compile.c++ ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; get-rspline $(targets) : -TP ; compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; } rule compile.c++.preprocess ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; get-rspline $(targets) : -TP ; preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ; } @@ -465,6 +477,7 @@ rule compile.c++.preprocess ( targets + : sources * : properties * ) rule compile.c++.pch ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; get-rspline $(targets[1]) : -TP ; get-rspline $(targets[2]) : -TP ; local pch-source = [ on $(<) return $(PCH_SOURCE) ] ; @@ -479,31 +492,46 @@ rule compile.c++.pch ( targets + : sources * : properties * ) } } +rule compile.idl ( targets + : sources * : properties * ) +{ + set-setup-command $(targets) : $(properties) ; +} # See midl.jam for details. # actions compile.idl { - $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")" + $(.SETUP) $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")" $(.TOUCH_FILE) "$(<[4]:W)" $(.TOUCH_FILE) "$(<[5]:W)" } +rule compile.mc ( targets + : sources * : properties * ) +{ + set-setup-command $(targets) : $(properties) ; +} actions compile.mc { - $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)" + $(.SETUP) $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)" } +rule compile.rc ( targets + : sources * : properties * ) +{ + set-setup-command $(targets) : $(properties) ; +} + actions compile.rc { - $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)" + $(.SETUP) $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)" } +toolset.uses-features msvc.link : ; rule link ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; if on in $(properties) { if [ feature.get-values : $(properties) ] @@ -520,7 +548,24 @@ rule link ( targets + : sources * : properties * ) rule link.dll ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ; + local import-lib ; + if ! true in $(properties) + { + import-lib = $(targets[2]) ; + IMPORT_LIB on $(targets) = $(import-lib) ; + } + # On msvc-14.1, the linker might not touch the import library + # if the exports do not change. (Apparently this could also + # happen for incremental linking, which is why we disable it, + # but that no longer seems to be enough). + # Therefore, don't update the import library just because + # it's out-dated. It will be force updated, when the dll + # is updated. Also, make it so that anything that depends + # on it depends on the dll as well. + NOUPDATE $(import-lib) ; + INCLUDES $(import-lib) : $(targets[1]) ; if on in $(properties) { if [ feature.get-values : $(properties) ] @@ -549,44 +594,44 @@ if [ os.name ] in NT { actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE { - $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% } actions manifest { if exist "$(<[1]).manifest" ( - $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1" + $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1" ) } actions manifest.user bind EMBED_MANIFEST_FILE { - $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1" + $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);1" } - actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE + actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE { - $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(IMPORT_LIB:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL% } actions manifest.dll { if exist "$(<[1]).manifest" ( - $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2" + $(.SETUP) $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2" ) } actions manifest.dll.user bind EMBED_MANIFEST_FILE { - $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" + $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" } } else { actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE { - $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" } actions manifest @@ -596,21 +641,21 @@ else fi } - actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE + actions link.dll bind IMPORT_LIB DEF_FILE LIBRARIES_MENTIONED_BY_FILE { - $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" + $(.SETUP) $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(IMPORT_LIB:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")" } actions manifest.dll { if test -e "$(<[1]).manifest"; then - $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2" + $(.SETUP) $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2" fi } actions manifest.dll.user bind EMBED_MANIFEST_FILE { - $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" + $(.SETUP) $(.MT) -manifest "$(EMBED_MANIFEST_FILE)" "-outputresource:$(<[1]);2" } } @@ -623,6 +668,7 @@ else # rule archive ( targets + : sources * : properties * ) { + set-setup-command $(targets) : $(properties) ; PDB_NAME on $(>) = $(<[1]:S=.pdb) ; LOCATE on $(<[1]:S=.pdb) = [ on $(<[1]) return $(LOCATE) ] ; } @@ -677,7 +723,7 @@ class msvc-pch-generator : pch-generator : $(pch-header) ] ; local pch-file ; - for local g in $(generated) + for local g in $(generated[2-]) { if [ type.is-derived [ $(g).type ] PCH ] { @@ -685,8 +731,8 @@ class msvc-pch-generator : pch-generator } } - return [ property-set.create $(pch-header) - $(pch-file) ] $(generated) ; + return [ $(generated[1]).add-raw $(pch-header) + $(pch-file) ] $(generated[2-]) ; } } @@ -737,72 +783,34 @@ local rule auto-detect-toolset-versions ( ) } } -# Helper rule to generate a faster alternative to MSVC setup scripts. -# We used to call MSVC setup scripts directly in every action, however in -# newer MSVC versions (10.0+) they make long-lasting registry queries -# which have a significant impact on build time. -rule maybe-rewrite-setup ( toolset : setup-script : setup-options : version : rewrite-setup ? ) +actions write-setup-script { - local result = $(setup-script)" "$(setup-options) ; - # At the moment we only know how to rewrite scripts with cmd shell. - if ( [ os.name ] in NT ) && ( $(rewrite-setup) != off ) - { - setup-script-id = b2_$(toolset)_$(version)_$(setup-script:B) ; - if $(setup-options)-is-not-empty - { - setup-script-id = $(setup-script-id)_$(setup-options) ; - } - - if $(.$(setup-script-id)) - { - errors.error rewriting setup script for the second time ; - } + @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)" +} - local tmpdir = [ os.environ TEMP ] ; - local replacement = [ path.native $(tmpdir)/$(setup-script-id).cmd ] ; - if ( $(rewrite-setup) = always ) || ( ! [ path.exists $(replacement) ] ) - { - local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ; - local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(setup-script) $(setup-options)>nul && set" ] : "\n" ] ; - local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ; - if $(diff-vars) - { - local target = $(replacement) ; - FILE_CONTENTS on $(target) = "SET "$(diff-vars) ; - ALWAYS $(target) ; - msvc.write-setup-script $(target) ; - UPDATE_NOW $(target) : : ignore-minus-n ; - .$(setup-script-id) = $(replacement) ; - result = "\""$(replacement)"\"" ; - } - } - else - { - result = "\""$(replacement)"\"" ; - } +if [ os.name ] = NT +{ + local rule call-batch-script ( command ) + { + return "call $(command) >nul$(.nl)" ; } - return $(result) ; } - -actions write-setup-script +else { - @($(STDOUT):E=$(FILE_CONTENTS:J=$(.nl))) > "$(<)" + # On cygwin, we need to run both the batch script + # and the following command in the same instance + # of cmd.exe. + local rule call-batch-script ( command ) + { + return "cmd.exe /S /C call $(command) \">nul\" \"&&\" " ; + } } - # Local helper rule to create the vcvars setup command for given architecture # and options. # local rule generate-setup-cmd ( version : command : parent : options * : cpu : global-setup ? : default-global-setup-options : default-setup ) { - local setup-prefix = "call " ; - local setup-suffix = " >nul"$(.nl) ; - if ! [ os.name ] in NT - { - setup-prefix = "cmd.exe /S /C call " ; - setup-suffix = " \">nul\" \"&&\" " ; - } - local setup-options ; local setup = [ feature.get-values : $(options) ] ; @@ -824,7 +832,7 @@ local rule generate-setup-cmd ( version : command : parent : options * : cpu : g { if $(.debug-configuration) { - ECHO 'notice: [generate-setup-cmd] $(version) is 14.1' ; + ECHO 'notice\: "[generate-setup-cmd]" $(version) is 14.1' ; } parent = [ path.native [ path.join $(parent) "..\\..\\..\\..\\..\\Auxiliary\\Build" ] ] ; } @@ -833,19 +841,81 @@ local rule generate-setup-cmd ( version : command : parent : options * : cpu : g } } - # Cygwin to Windows path translation. - setup = "\""$(setup:W)"\"" ; - - # Append setup options to the setup name and add the final setup - # prefix & suffix. - setup-options ?= "" ; - local rewrite = [ feature.get-values : $(options) ] ; - setup = [ maybe-rewrite-setup msvc : $(setup:J=" ") : $(setup-options:J=" ") : $(version) : $(rewrite) ] ; - setup = $(setup-prefix)$(setup)$(setup-suffix) ; - - return $(setup) ; + return $(setup) "$(setup-options:J= )" ; +} + +# Worker for set-setup-command. Usable in a virtual-target.action. +rule adjust-setup-command ( new-setup : setup : properties * ) +{ + local internal = $(new-setup:S=.read) ; + NOTFILE $(internal) ; + local setup-options = [ property.select : $(properties) ] ; + setup-options = $(setup-options:G=:E=) ; + DEPENDS $(internal) : $(setup) ; + DEPENDS $(new-setup) : $(internal) ; + REBUILDS $(new-setup) : $(internal) ; + msvc.read-setup $(internal) : $(setup) ; + msvc.write-setup-script $(new-setup) : $(setup) ; + __ACTION_RULE__ on $(internal) = msvc.rewrite-setup $(setup) $(setup-options) $(new-setup) ; } +# This doesn't actually do anything. It's merely +# used as a trigger for __ACTION_RULE__. +actions quietly read-setup { } + +# Calculates the changes to the environment make by setup-script +# Should be used as a callback for __ACTION_RULE__ +local rule rewrite-setup ( setup-script setup-options new-setup : target : * ) +{ + local setup-path = [ on $(setup-script) return $(LOCATE) $(SEARCH) ] ; + setup-path = $(setup-path[1]) ; + local command = "\"$(setup-script:G=:R=$(setup-path))\" $(setup-options)" ; + local original-vars = [ SPLIT_BY_CHARACTERS [ SHELL set ] : "\n" ] ; + local new-vars = [ SPLIT_BY_CHARACTERS [ SHELL "$(command) >nul && set" ] : "\n" ] ; + local diff-vars = [ set.difference $(new-vars) : $(original-vars) ] ; + if $(diff-vars) + { + FILE_CONTENTS on $(new-setup) = "REM $(command)" "SET "$(diff-vars) ; + } +} + +IMPORT msvc : rewrite-setup : : msvc.rewrite-setup ; + +# Helper rule to generate a faster alternative to MSVC setup scripts. +# We used to call MSVC setup scripts directly in every action, however in +# newer MSVC versions (10.0+) they make long-lasting registry queries +# which have a significant impact on build time. +local rule set-setup-command ( targets * : properties * ) +{ + if ! [ on $(targets) return $(.SETUP) ] + { + local setup-script = [ on $(targets) return $(.SETUP-SCRIPT) ] ; + local setup-options = [ on $(targets) return $(.SETUP-OPTIONS) ] ; + local key = .setup-command-$(setup-script:E=)-$(setup-options:E=) ; + if ! $($(key)) + { + properties = [ feature.expand $(properties) ] ; + properties = [ property.select : $(properties) ] ; + local ps = [ property-set.create $(properties) $(setup-options) ] ; + local original = [ virtual-target.from-file $(setup-script) : [ path.pwd ] : $(.project) ] ; + local action = [ new non-scanning-action $(original) : msvc.adjust-setup-command : $(ps) ] ; + local new-setup = [ virtual-target.register [ new file-target msvc-setup.bat exact : : $(.project) : $(action) ] ] ; + local command = [ $(new-setup).actualize ] ; + local path = [ on $(command) return $(LOCATE) ] ; + local block-update = $(command:S=.nup) ; + NOUPDATE $(block-update) ; + NOTFILE $(block-update) ; + DEPENDS $(block-update) : $(command) ; + if [ on $(targets) return $(.REWRITE-SETUP) ] + { + ALWAYS $(command) ; + } + $(key) = [ call-batch-script "\"$(command:WG=:R=$(path))\" $(setup-options:E=)" ] $(block-update) ; + } + DEPENDS $(targets) : $($(key)[2]) ; + .SETUP on $(targets) = $($(key)[1]) ; + } +} # Worker rule for toolset version configuration. Takes an explicit version id or # nothing in case it should configure the default toolset version (the first @@ -923,7 +993,7 @@ local rule configure-really ( version ? : options * ) if ( ! $(version) || $(version) = "default" ) && ! $(command:D) { ECHO ; - ECHO warning: + ECHO warning\: "Did not find command for MSVC toolset." "If you have Visual Studio 2017 installed you will need to" "specify the full path to the command," @@ -991,8 +1061,8 @@ local rule configure-really ( version ? : options * ) # Generate and register setup command. - local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ; - local below-11.0 = [ MATCH ^([6789]\\.|10\\.) : $(version) ] ; + local below-8.0 = [ MATCH "^([67]\\.)" : $(version) ] ; + local below-11.0 = [ MATCH "^([6789]\\.|10\\.)" : $(version) ] ; local cpu = i386 amd64 ia64 arm ; if $(below-8.0) @@ -1189,29 +1259,49 @@ local rule configure-really ( version ? : options * ) local cpu-assembler = $(assembler) ; cpu-assembler ?= $(default-assembler-$(c)) ; - toolset.flags msvc.compile .RC $(api)/$(cpu-conditions) : $(setup-$(c))$(resource-compiler) ; - toolset.flags msvc.compile .IDL $(api)/$(cpu-conditions) : $(setup-$(c))$(idl-compiler) ; - toolset.flags msvc.compile .MC $(api)/$(cpu-conditions) : $(setup-$(c))$(mc-compiler) ; - toolset.flags msvc.link .MT $(api)/$(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ; - - for api in desktop store phone + for local api in desktop store phone { local setup-script = $(setup-$(c)) ; if $(api) = phone { setup-script = $(setup-phone-$(c)) ; } + + if always in $(options) + { + toolset.flags msvc .REWRITE-SETUP $(api)/$(cpu-conditions) : true ; + } + + if ! $(setup-script) + { + # Should we try to set up some error handling or fallbacks here? + } + else if off in $(options) || [ os.name ] != NT + { + toolset.flags msvc .SETUP $(api)/$(cpu-conditions) : [ call-batch-script "\"$(setup-script[1]:W)\" $(setup-script[2-]:E=)" ] ; + } + else + { + toolset.flags msvc .SETUP-SCRIPT $(api)/$(cpu-conditions) : $(setup-script[1]) ; + toolset.flags msvc .SETUP-OPTIONS $(api)/$(cpu-conditions) : $(setup-script[2-]) ; + } + + toolset.flags msvc.compile .RC $(api)/$(cpu-conditions) : $(resource-compiler) ; + toolset.flags msvc.compile .IDL $(api)/$(cpu-conditions) : $(idl-compiler) ; + toolset.flags msvc.compile .MC $(api)/$(cpu-conditions) : $(mc-compiler) ; + toolset.flags msvc.link .MT $(api)/$(cpu-conditions) : $(manifest-tool) -nologo ; + if $(api) = desktop { - toolset.flags msvc.compile .CC $(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 -nologo ; + toolset.flags msvc.compile .CC $(api)/$(cpu-conditions) : $(compiler) /Zm800 -nologo ; } else { - toolset.flags msvc.compile .CC $(api)/$(cpu-conditions) : $(setup-script)$(compiler) /Zm800 /ZW /EHsc -nologo ; + toolset.flags msvc.compile .CC $(api)/$(cpu-conditions) : $(compiler) /Zm800 /ZW /EHsc -nologo ; } - toolset.flags msvc.compile .ASM $(api)/$(cpu-conditions) : $(setup-script)$(cpu-assembler) -nologo ; - toolset.flags msvc.link .LD $(api)/$(cpu-conditions) : $(setup-script)$(linker) /NOLOGO /INCREMENTAL:NO ; - toolset.flags msvc.archive .LD $(api)/$(cpu-conditions) : $(setup-script)$(linker) /lib /NOLOGO ; + toolset.flags msvc.compile .ASM $(api)/$(cpu-conditions) : $(cpu-assembler) -nologo ; + toolset.flags msvc.link .LD $(api)/$(cpu-conditions) : $(linker) /NOLOGO "/INCREMENTAL:NO" ; + toolset.flags msvc.archive .LD $(api)/$(cpu-conditions) : $(linker) /lib /NOLOGO ; } if $(cc-filter) @@ -1349,8 +1439,8 @@ class msvc-linking-generator : linking-generator if $(result) { - local name-main = [ $(result[0]).name ] ; - local action = [ $(result[0]).action ] ; + local name-main = [ $(result[1]).name ] ; + local action = [ $(result[1]).action ] ; if [ $(property-set).get ] = "on" { @@ -1491,9 +1581,9 @@ local rule register-toolset-really ( ) toolset.flags msvc.compile C++FLAGS on/on/off : /EHa ; toolset.flags msvc.compile C++FLAGS on/on/on : /EHac ; - toolset.flags msvc.compile C++FLAGS 14 : /std:c++14 ; - toolset.flags msvc.compile C++FLAGS 17 : /std:c++17 ; - toolset.flags msvc.compile C++FLAGS latest : /std:c++latest ; + toolset.flags msvc.compile C++FLAGS 14 : "/std:c++14" ; + toolset.flags msvc.compile C++FLAGS 17 : "/std:c++17" ; + toolset.flags msvc.compile C++FLAGS latest : "/std:c++latest" ; # By default 8.0 enables rtti support while prior versions disabled it. We # simply enable or disable it explicitly so we do not have to depend on this @@ -1529,19 +1619,19 @@ local rule register-toolset-really ( ) # Declare flags for linking. { - toolset.flags msvc.link PDB_LINKFLAG on/database : /PDB: ; # not used yet + toolset.flags msvc.link PDB_LINKFLAG on/database : "/PDB:" ; # not used yet toolset.flags msvc.link LINKFLAGS on : /DEBUG ; toolset.flags msvc.link DEF_FILE ; # The linker disables the default optimizations when using /DEBUG so we # have to enable them manually for release builds with debug symbols. - toolset.flags msvc LINKFLAGS on/off : /OPT:REF,ICF ; + toolset.flags msvc LINKFLAGS on/off : "/OPT:REF,ICF" ; - toolset.flags msvc LINKFLAGS console : /subsystem:console ; - toolset.flags msvc LINKFLAGS gui : /subsystem:windows ; - toolset.flags msvc LINKFLAGS wince : /subsystem:windowsce ; - toolset.flags msvc LINKFLAGS native : /subsystem:native ; - toolset.flags msvc LINKFLAGS auto : /subsystem:posix ; + toolset.flags msvc LINKFLAGS console : "/subsystem:console" ; + toolset.flags msvc LINKFLAGS gui : "/subsystem:windows" ; + toolset.flags msvc LINKFLAGS wince : "/subsystem:windowsce" ; + toolset.flags msvc LINKFLAGS native : "/subsystem:native" ; + toolset.flags msvc LINKFLAGS auto : "/subsystem:posix" ; toolset.flags msvc.link OPTIONS ; toolset.flags msvc.link LINKPATH ; @@ -1555,6 +1645,13 @@ local rule register-toolset-really ( ) } toolset.flags msvc.archive AROPTIONS ; + + # Create a project to allow building the setup scripts + project.initialize $(__name__) ; + .project = [ project.current ] ; + project msvc ; + + feature.feature msvc.setup-options : : free ; } @@ -1591,7 +1688,7 @@ local rule register-configuration ( version : path ? ) { if $(.debug-configuration) { - ECHO notice: [msvc-cfg] msvc-$(version) detected, command: + ECHO notice\: "[msvc-cfg]" msvc-$(version) detected, command\: '$(command)' ; } diff --git a/tools/build/src/tools/pgi.jam b/tools/build/src/tools/pgi.jam index 0ea025e7a7..8b13d451bb 100644 --- a/tools/build/src/tools/pgi.jam +++ b/tools/build/src/tools/pgi.jam @@ -40,8 +40,6 @@ rule init ( version ? : command * : options * ) # set link flags flags pgi.link FINDLIBS-ST : [ feature.get-values : $(options) ] : unchecked ; - - gcc.init-link-flags pgi gnu $(condition) ; } # Declare generators diff --git a/tools/build/src/tools/python.jam b/tools/build/src/tools/python.jam index ef5e16ab17..273b28a1e3 100644 --- a/tools/build/src/tools/python.jam +++ b/tools/build/src/tools/python.jam @@ -108,7 +108,7 @@ rule init ( version ? : cmd-or-prefix ? : includes * : libraries ? { if $($(v)) { - debug-message " user-specified "$(v): \"$($(v))\" ; + debug-message " user-specified $(v):" \"$($(v))\" ; } } @@ -155,7 +155,7 @@ local rule is-cygwin-symlink ( path ) if $(dir-listing) { # Escape any special regex characters in the base part of the path. - local base-pat = [ regex.escape $(path:D=) : ].[()*+?|\\$^ : \\ ] ; + local base-pat = [ regex.escape $(path:D=) : "].[()*+?|\\$^" : \\ ] ; # Extract the file's size from the directory listing. local size-of-system-file = [ MATCH "([0-9]+) "$(base-pat) : $(dir-listing) : 1 ] ; @@ -228,7 +228,7 @@ local rule debug-message ( message * ) { if --debug-configuration in [ modules.peek : ARGV ] { - ECHO notice: [python-cfg] $(message) ; + ECHO "notice:" "[python-cfg]" $(message) ; } } @@ -256,8 +256,8 @@ local rule software-registry-value ( path : data ? ) } -.windows-drive-letter-re = ^([A-Za-z]):[\\/](.*) ; -.cygwin-drive-letter-re = ^/cygdrive/([a-z])/(.*) ; +.windows-drive-letter-re = "^([A-Za-z]):[\\/](.*)" ; +.cygwin-drive-letter-re = "^/cygdrive/([a-z])/(.*)" ; .working-directory = [ PWD ] ; .working-drive-letter = [ SUBST $(.working-directory) $(.windows-drive-letter-re) $1 ] ; @@ -284,7 +284,7 @@ local rule cygwin-to-windows-path ( path ) { path = $(path:R="") ; # strip any trailing slash - local drive-letter = [ SUBST $(path) $(.cygwin-drive-letter-re) $1:/$2 ] ; + local drive-letter = [ SUBST $(path) $(.cygwin-drive-letter-re) "$1:/$2" ] ; if $(drive-letter) { path = $(drive-letter) ; @@ -353,7 +353,7 @@ local rule windows-path-to-native ( path ) # local rule guess-windows-path ( path ) { - return [ SUBST $(path) ($(.windows-drive-letter-re)|.*([\\]).*) $1 ] ; + return [ SUBST $(path) "($(.windows-drive-letter-re)|.*([\\]).*)" $1 ] ; } @@ -380,7 +380,7 @@ local rule path-to-native ( paths * ) # local rule split-version ( version ) { - local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ; + local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ; if ! $(major-minor[2]) || $(major-minor[3]) { ECHO "Warning: \"using python\" expects a two part (major, minor) version number; got" $(version) instead ; @@ -459,7 +459,7 @@ local rule probe ( python-cmd ) debug-message ; debug-message If you intend to target a Cygwin build of Python, please ; debug-message replace the path to the link with the path to a real executable ; - debug-message (guessing: \"$(skip-symlink)\") "in" your 'using python' line ; + debug-message "(guessing:" \"$(skip-symlink)\") "in" your 'using python' line ; debug-message "in" user-config.jam or site-config.jam. Do not forget to escape ; debug-message backslashes ; debug-message -------------------------------------------------------------------- ; @@ -495,7 +495,7 @@ local rule probe ( python-cmd ) { # These variables are expected to be declared local in the # caller, so Jam's dynamic scoping will set their values there. - sys.$(s) = [ SUBST $(output) \\<$(s)=([^$(nl)]+) $1 ] ; + sys.$(s) = [ SUBST $(output) "\\<$(s)=([^$(nl)]+)" $1 ] ; } } return $(output) ; @@ -657,6 +657,15 @@ local rule system-library-dependencies ( target-os ) } +# Define a version suffix for libraries depending on Python. +# For example, Boost.Python built for Python 2.7 uses the suffix "27" +rule version-suffix ( version ) +{ + local major-minor = [ split-version $(version) ] ; + local suffix = $(major-minor:J="") ; + return $(suffix) ; +} + # Declare a target to represent Python's library. # local rule declare-libpython-target ( version ? : requirements * ) @@ -676,10 +685,10 @@ local rule declare-libpython-target ( version ? : requirements * ) if ! $(lib-version) { - ECHO *** warning: could not determine Python version, which will ; - ECHO *** warning: probably prevent us from linking with the python ; - ECHO *** warning: library. Consider explicitly passing the version ; - ECHO *** warning: to 'using python'. ; + ECHO *** "warning:" could not determine Python version, which will ; + ECHO *** "warning:" probably prevent us from linking with the python ; + ECHO *** "warning:" library. Consider explicitly passing the version ; + ECHO *** "warning:" to 'using python'. ; } # Declare it. @@ -934,20 +943,7 @@ local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? : # Global, but conditional, requirements to give access to the interpreter # for general utilities, like other toolsets, that run Python scripts. toolset.add-requirements - $(target-requirements:J=,):$(interpreter-cmd) ; - - # We also set a default requirement that assigns the first python configured - # for a particular target OS as the default. This makes it so that we can - # select a python interpreter with only knowledge of the target OS. And hence - # can configure different Pythons based on the target OS only. - local toolset-requirements = [ toolset.requirements ] ; - local toolset-target-os-requirements - = [ property.evaluate-conditionals-in-context - [ $(toolset-requirements).raw ] : $(target-os) ] ; - if ! in $(toolset-target-os-requirements:G) - { - toolset.add-requirements $(target-os):$(version:E=default) ; - } + "$(target-requirements:J=,):$(interpreter-cmd)" ; # Register the right suffix for extensions. register-extension-suffix $(extension-suffix) : $(target-requirements) ; @@ -1028,7 +1024,7 @@ local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? : : : $(target-requirements) : - : $(usage-requirements) -Wl,-bI:$(libraries[1])/python.exp + : $(usage-requirements) "-Wl,-bI:$(libraries[1])/python.exp" ; } else @@ -1048,7 +1044,11 @@ local rule configure ( version ? : cmd-or-prefix ? : includes * : libraries ? : # required properties. rule require-py ( properties * ) { - local py-ext-target = [ $(.project).find python_for_extensions ] ; + local py-ext-target = [ $(.project).find python_for_extensions : no-error ] ; + if ! $(py-ext-target) + { + return no ; + } local property-set = [ property-set.create $(properties) ] ; property-set = [ $(property-set).expand ] ; local py-ext-alternative = [ $(py-ext-target).select-alternatives $(property-set) ] ; @@ -1256,6 +1256,10 @@ local rule pyd-pythonpath ( source ) toolset.flags python.capture-output ARGS ; toolset.flags python.capture-output INPUT_FILES ; +toolset.uses-features python.capture-output : + + ; + rule capture-output ( target : sources * : properties * ) { # Setup up a proper DLL search path. Here, $(sources[1]) is a python module @@ -1268,10 +1272,7 @@ rule capture-output ( target : sources * : properties * ) PYTHONPATH += [ feature.get-values pythonpath : $(properties) ] ; # After test is run, we remove the Python module, but not the Python script. - local targets-to-remove = $(sources[2-]) ; - targets-to-remove ?= none ; - testing.capture-output $(target) : $(sources[1]) : $(properties) : - $(targets-to-remove) ; + testing.capture-output $(target) : $(sources[1]) : $(properties) ; # PYTHONPATH is different; it will be interpreted by whichever Python is # invoked and so must follow path rules for the target os. The only OSes @@ -1288,7 +1289,7 @@ rule capture-output ( target : sources * : properties * ) } local path-separator = [ os.path-separator [ translate-os $(target-os) ] ] ; local set-PYTHONPATH = [ common.variable-setting-command PYTHONPATH : - $(PYTHONPATH:J=$(path-separator)) ] ; + $(PYTHONPATH:E=:J=$(path-separator)) ] ; LAUNCHER on $(target) = $(set-PYTHONPATH) [ on $(target) return \"$(PYTHON)\" ] ; } diff --git a/tools/build/src/tools/qcc.jam b/tools/build/src/tools/qcc.jam index faa3530643..9ed92465fb 100644 --- a/tools/build/src/tools/qcc.jam +++ b/tools/build/src/tools/qcc.jam @@ -21,7 +21,6 @@ import unix ; feature.extend toolset : qcc ; toolset.inherit-generators qcc : unix : unix.link unix.link.dll ; -generators.override builtin.lib-generator : qcc.prebuilt ; toolset.inherit-flags qcc : unix ; toolset.inherit-rules qcc : unix ; @@ -101,7 +100,7 @@ actions compile.c++ actions compile.c { - "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" + "$(CONFIG_COMMAND)" -lang-c $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)" } actions compile.asm diff --git a/tools/build/src/tools/qt3.jam b/tools/build/src/tools/qt3.jam index f82cf0ac33..945ba99b56 100644 --- a/tools/build/src/tools/qt3.jam +++ b/tools/build/src/tools/qt3.jam @@ -65,7 +65,7 @@ rule init ( prefix ? ) # The following generator is used to convert UI files to CPP. It creates # UIC_H from UI, and constructs CPP from UI/UIC_H. In addition, it also # returns UIC_H target, so that it can be mocced. - class qt::uic-cpp-generator : generator + class "qt::uic-cpp-generator" : generator { rule __init__ ( ) { @@ -107,7 +107,7 @@ rule init ( prefix ? ) } } - generators.register [ new qt::uic-cpp-generator ] ; + generators.register [ new "qt::uic-cpp-generator" ] ; # Finally, declare prebuilt target for QT library. local usage-requirements = diff --git a/tools/build/src/tools/qt4.jam b/tools/build/src/tools/qt4.jam index a3aac61b42..4a434d76d1 100644 --- a/tools/build/src/tools/qt4.jam +++ b/tools/build/src/tools/qt4.jam @@ -106,7 +106,7 @@ local rule debug-message ( message * ) { if $(.debug-configuration) = TRUE { - ECHO notice: [qt4-cfg] $(message) ; + ECHO notice\: "[qt4-cfg]" $(message) ; } } @@ -151,7 +151,7 @@ local rule check-version ( bin_prefix ) # local rule split-version ( version ) { - local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ; + local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ; if ! $(major-minor[2]) || $(major-minor[3]) { ECHO "Warning: 'using qt' expects a two part (major, minor) version number; got" $(version) instead ; @@ -180,7 +180,7 @@ rule init ( prefix : full_bin ? : full_inc ? : full_lib ? : version ? : conditio { if $($(v)) { - debug-message " user-specified "$(v): '$($(v))' ; + debug-message " user-specified $(v):" '$($(v))' ; } } diff --git a/tools/build/src/tools/qt5.jam b/tools/build/src/tools/qt5.jam index 464066da87..8125c1f09c 100644 --- a/tools/build/src/tools/qt5.jam +++ b/tools/build/src/tools/qt5.jam @@ -89,7 +89,7 @@ local rule debug-message ( message * ) { if $(.debug-configuration) = TRUE { - ECHO notice: [qt5-cfg] $(message) ; + ECHO notice\: "[qt5-cfg]" $(message) ; } } @@ -134,7 +134,7 @@ local rule check-version ( bin_prefix ) # local rule split-version ( version ) { - local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ; + local major-minor = [ MATCH "^([0-9]+)\.([0-9]+)(.*)$" : $(version) : 1 2 3 ] ; if ! $(major-minor[2]) || $(major-minor[3]) { ECHO "Warning: 'using qt' expects a two part (major, minor) version number; got" $(version) instead ; @@ -165,7 +165,7 @@ rule init ( prefix : version ? : condition * : namespace ? : infix ? : full_bin { if $($(v)) { - debug-message " user-specified "$(v): '$($(v))' ; + debug-message " user-specified $(v):" '$($(v))' ; } } diff --git a/tools/build/src/tools/rc.jam b/tools/build/src/tools/rc.jam index de4071f294..d7534bc6ff 100644 --- a/tools/build/src/tools/rc.jam +++ b/tools/build/src/tools/rc.jam @@ -50,7 +50,7 @@ rule configure ( command ? : condition ? : options * ) flags rc.compile.resource INCLUDES ; if $(.debug-configuration) { - ECHO notice: using rc compiler :: $(condition) :: $(command) ; + ECHO "notice:" using rc compiler "::" $(condition) "::" $(command) ; } } } diff --git a/tools/build/src/tools/sass.jam b/tools/build/src/tools/sass.jam index c4e5cf272c..be56487ff9 100644 --- a/tools/build/src/tools/sass.jam +++ b/tools/build/src/tools/sass.jam @@ -63,7 +63,7 @@ feature is `optional` and is not `propagated` to dependent targets. If no value for this feature is specified, then one is copied from the feature `debug-symbols`. -|# end::doc[] +|# # end::doc[] feature.subfeature sass : line-numbers : on off : optional ; diff --git a/tools/build/src/tools/stage.jam b/tools/build/src/tools/stage.jam index 8d005ae02e..a20482f6d8 100644 --- a/tools/build/src/tools/stage.jam +++ b/tools/build/src/tools/stage.jam @@ -165,7 +165,7 @@ class install-target-class : basic-target if $(ename) { import errors : error : $(__name__) : errors.error ; - errors.error In 'install': property specified with + errors.error In "'install':" property specified with target that requires relinking. ; } else @@ -456,7 +456,7 @@ class installed-shared-lib-generator : generator # 'Z' are numbers, we need to create NNN.XXX and NNN.XXX.YYY # symbolic links. local m = [ MATCH - (.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$ : + "(.*)\\.([0123456789]+)\\.([0123456789]+)\\.([0123456789]+)$" : [ $(copied).name ] ] ; if $(m) { diff --git a/tools/build/src/tools/stlport.jam b/tools/build/src/tools/stlport.jam index ed0947ca56..4a08c8c9b1 100644 --- a/tools/build/src/tools/stlport.jam +++ b/tools/build/src/tools/stlport.jam @@ -89,6 +89,9 @@ class stlport-target-class : basic-target local requirements ; requirements += $(self.version) ; + requirements += runtime-debugging ; + requirements += toolset ; + requirements += runtime-link ; self.requirements = [ property-set.create $(requirements) ] ; } diff --git a/tools/build/src/tools/testing.jam b/tools/build/src/tools/testing.jam index 55576f1368..a6c5cc3d30 100644 --- a/tools/build/src/tools/testing.jam +++ b/tools/build/src/tools/testing.jam @@ -34,12 +34,14 @@ import alias ; +import build-system ; import "class" ; import common ; import errors ; import feature ; import generators ; import os ; +import param ; import path ; import project ; import property ; @@ -116,7 +118,8 @@ rule make-test ( target-type : sources + : requirements * : target-name ? ) # to allow post-processing tools to work. local t = [ targets.create-typed-target [ type.type-from-rule-name $(target-type) ] : $(project) : $(real-name) : $(sources) : - $(requirements) $(real-name)$(.TEST-DIR-SUFFIX) ] ; + $(requirements) $(real-name)$(.TEST-DIR-SUFFIX) + toolset ] ; # The alias to the real target, per period replacement above. if $(real-name) != $(target-name) @@ -138,6 +141,7 @@ rule make-test ( target-type : sources + : requirements * : target-name ? ) # rule compile ( sources + : requirements * : target-name ? ) { + param.handle-named-params sources requirements target-name ; return [ make-test compile : $(sources) : $(requirements) : $(target-name) ] ; } @@ -145,6 +149,7 @@ rule compile ( sources + : requirements * : target-name ? ) rule compile-fail ( sources + : requirements * : target-name ? ) { + param.handle-named-params sources requirements target-name ; return [ make-test compile-fail : $(sources) : $(requirements) : $(target-name) ] ; } @@ -152,12 +157,14 @@ rule compile-fail ( sources + : requirements * : target-name ? ) rule link ( sources + : requirements * : target-name ? ) { + param.handle-named-params sources requirements target-name ; return [ make-test link : $(sources) : $(requirements) : $(target-name) ] ; } rule link-fail ( sources + : requirements * : target-name ? ) { + param.handle-named-params sources requirements target-name ; return [ make-test link-fail : $(sources) : $(requirements) : $(target-name) ] ; } @@ -182,6 +189,8 @@ rule handle-input-files ( input-files * ) rule run ( sources + : args * : input-files * : requirements * : target-name ? : default-build * ) { + param.handle-named-params sources args input-files requirements + target-name default-build ; requirements += $(args:J=" ") ; requirements += [ handle-input-files $(input-files) ] ; return [ make-test run : $(sources) : $(requirements) : $(target-name) ] ; @@ -191,6 +200,8 @@ rule run ( sources + : args * : input-files * : requirements * : target-name ? : rule run-fail ( sources + : args * : input-files * : requirements * : target-name ? : default-build * ) { + param.handle-named-params sources args input-files requirements + target-name default-build ; requirements += $(args:J=" ") ; requirements += [ handle-input-files $(input-files) ] ; return [ make-test run-fail : $(sources) : $(requirements) : $(target-name) @@ -213,6 +224,11 @@ rule dump-tests } } +if ( --dump-tests in [ modules.peek : ARGV ] ) +{ + IMPORT testing : dump-tests : : testing.dump-tests ; + build-system.add-pre-build-hook testing.dump-tests ; +} # Given a project location in normalized form (slashes are forward), compute the # name of the Boost library. @@ -301,20 +317,45 @@ rule dump-test ( target ) # Format them into a single string of quoted strings. test-info = \"$(test-info:J=\"\ \")\" ; - ECHO boost-test($(type)) \"$(name)\" [$(test-info)] ":" + ECHO boost-test($(type)) \"$(name)\" "[$(test-info)]" ":" \"$(source-files)\" ; } } +class testing.expect-failure-generator : generator +{ + rule generated-targets ( sources + : property-set : project name ? ) + { + for local s in $(sources) + { + local a = [ $(s).action ] ; + if $(a) + { + for local t in [ $(a).targets ] + { + $(t).fail-expected ; + } + } + } + return [ generator.generated-targets $(sources) + : $(property-set) : $(project) $(name) ] ; + } +} + +local rule register-fail-expected ( source-type : test-type ) +{ + generators.register [ class.new testing.expect-failure-generator + testing.expect-failure : $(source-type) : $(test-type) ] ; +} # Register generators. Depending on target type, either 'expect-success' or # 'expect-failure' rule will be used. generators.register-standard testing.expect-success : OBJ : COMPILE ; -generators.register-standard testing.expect-failure : OBJ : COMPILE_FAIL ; +register-fail-expected OBJ : COMPILE_FAIL ; generators.register-standard testing.expect-success : RUN_OUTPUT : RUN ; -generators.register-standard testing.expect-failure : RUN_OUTPUT : RUN_FAIL ; -generators.register-standard testing.expect-failure : EXE : LINK_FAIL ; +register-fail-expected RUN_OUTPUT : RUN_FAIL ; generators.register-standard testing.expect-success : EXE : LINK ; +register-fail-expected EXE : LINK_FAIL ; # Generator which runs an EXE and captures output. generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ; @@ -325,6 +366,8 @@ generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ; # http://article.gmane.org/gmane.comp.lib.boost.build/6353). generators.register-standard testing.unit-test : EXE : UNIT_TEST ; +toolset.uses-features testing.expect-success : ; +toolset.uses-features testing.expect-failure : ; # The action rules called by generators. @@ -333,7 +376,7 @@ generators.register-standard testing.unit-test : EXE : UNIT_TEST ; # rule expect-success ( target : dependency + : requirements * ) { - **passed** $(target) : $(dependency) ; + **passed** $(target) : $(dependency) : $(requirements) ; } @@ -345,30 +388,22 @@ rule expect-failure ( target : dependency + : properties * ) local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ; local marker = $(dependency:G=$(grist)*fail) ; (failed-as-expected) $(marker) ; - FAIL_EXPECTED $(dependency) ; LOCATE on $(marker) = [ on $(dependency) return $(LOCATE) ] ; RMOLD $(marker) ; DEPENDS $(marker) : $(dependency) ; DEPENDS $(target) : $(marker) ; - **passed** $(target) : $(marker) ; + **passed** $(target) : $(marker) : $(properties) ; } # The rule/action combination used to report successful passing of a test. # -rule **passed** +rule **passed** ( target : sources * : properties * ) { - remove-test-targets $(<) ; - - # Dump all the tests, if needed. We do it here, since dump should happen - # only after all Jamfiles have been read, and there is no such place - # currently defined (but there should be). - if ! $(.dumped-tests) && ( --dump-tests in [ modules.peek : ARGV ] ) + if [ feature.get-values preserve-test-targets : $(properties) ] = off { - .dumped-tests = true ; - dump-tests ; + remove-test-targets $(<) ; } - # Force deletion of the target, in case any dependencies failed to build. RMOLD $(<) ; } @@ -457,21 +492,20 @@ toolset.flags testing.capture-output ARGS ; toolset.flags testing.capture-output INPUT_FILES ; toolset.flags testing.capture-output LAUNCHER ; -.preserve-test-targets = on ; +toolset.uses-features testing.capture-output : + ; + if --remove-test-targets in [ modules.peek : ARGV ] { - .preserve-test-targets = off ; + feature.set-default preserve-test-targets : off ; } # Runs executable 'sources' and stores stdout in file 'target'. Unless # --preserve-test-targets command line option has been specified, removes the -# executable. The 'target-to-remove' parameter controls what should be removed: -# - if 'none', does not remove anything, ever -# - if empty, removes 'source' -# - if non-empty and not 'none', contains a list of sources to remove. +# executable. # -rule capture-output ( target : source : properties * : targets-to-remove * ) +rule capture-output ( target : source : properties * ) { output-file on $(target) = $(target:S=.output) ; LOCATE on $(target:S=.output) = [ on $(target) return $(LOCATE) ] ; @@ -489,15 +523,6 @@ rule capture-output ( target : source : properties * : targets-to-remove * ) # bug). DEPENDS $(target) : [ on $(target) return $(INPUT_FILES) ] ; - if $(targets-to-remove) = none - { - targets-to-remove = ; - } - else if ! $(targets-to-remove) - { - targets-to-remove = $(source) ; - } - run-path-setup $(target) : $(source) : $(properties) ; DISABLE_TEST_EXECUTION on $(target) = 0 ; @@ -506,16 +531,6 @@ rule capture-output ( target : source : properties * : targets-to-remove * ) DISABLE_TEST_EXECUTION on $(target) = 1 ; } - if [ feature.get-values preserve-test-targets : $(properties) ] = off - || $(.preserve-test-targets) = off - { - rmtemp-sources $(target) : $(targets-to-remove) ; - for local to-remove in $(targets-to-remove) - { - rmtemp-all-sources $(to-remove) ; - } - } - if ! [ feature.get-values testing.launcher : $(properties) ] { ## On VMS set default launcher to MCR @@ -525,42 +540,19 @@ rule capture-output ( target : source : properties * : targets-to-remove * ) .types-to-remove = EXE OBJ ; -local rule remove-test-targets ( targets + ) -{ - if $(.preserve-test-targets) = off - { - rmtemp-all-sources $(target) ; - } -} - -local rule rmtemp-all-sources ( target ) +local rule remove-test-targets ( target ) { - local sources ; local action = [ on $(target) return $(.action) ] ; - if $(action) + local associated-targets = [ virtual-target.traverse [ $(action).targets ] ] ; + local targets-to-remove ; + for local t in [ sequence.unique $(associated-targets) ] { - local action-sources = [ $(action).sources ] ; - for local source in $(action-sources) - { - local source-type = [ $(source).type ] ; - if $(source-type) in $(.types-to-remove) - { - sources += [ $(source).actual-name ] ; - } - else - { - # ECHO IGNORED: $(source) :: $(source-type) ; - } - } - if $(sources) + if [ $(t).type ] in $(.types-to-remove) { - rmtemp-sources $(target) : $(sources) ; - for local source in $(sources) - { - rmtemp-all-sources $(source) ; - } + targets-to-remove += [ $(t).actual-name ] ; } } + rmtemp-sources $(target) : $(targets-to-remove) ; } local rule rmtemp-sources ( target : sources * ) @@ -775,7 +767,7 @@ generators.register-composing testing.time : : TIME ; # with an embedded manifest file by a separate action. rule record-time ( target : source : start end user system clock ) { - local src-string = [$(source:G=:J=",")"] " ; + local src-string = "[$(source:G=:J=,)] " ; USER_TIME on $(target) += $(src-string)$(user) ; SYSTEM_TIME on $(target) += $(src-string)$(system) ; CLOCK_TIME on $(target) += $(src-string)$(clock) ; diff --git a/tools/build/src/tools/types/man.jam b/tools/build/src/tools/types/man.jam index 7dc9cb3534..4fb59a0fef 100644 --- a/tools/build/src/tools/types/man.jam +++ b/tools/build/src/tools/types/man.jam @@ -5,4 +5,4 @@ accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |# -type MANPAGE : man 0 1 1M 2 3 4 5 6 7 8 9 n p x ; +type MANPAGE : man 1M n p x ; diff --git a/tools/build/src/tools/types/xml.jam b/tools/build/src/tools/types/xml.jam index caa67bf5c8..10149ea93b 100644 --- a/tools/build/src/tools/types/xml.jam +++ b/tools/build/src/tools/types/xml.jam @@ -45,5 +45,5 @@ class xinclude-scanner : scanner } } -scanner.register xinclude-scanner : xsl:path ; +scanner.register xinclude-scanner : "xsl:path" ; type.set-scanner XML : xinclude-scanner ; diff --git a/tools/build/src/tools/vmsdecc.jam b/tools/build/src/tools/vmsdecc.jam index 9c159f2882..28f2a9b160 100644 --- a/tools/build/src/tools/vmsdecc.jam +++ b/tools/build/src/tools/vmsdecc.jam @@ -68,7 +68,7 @@ rule init ( version ? : command * : options * ) toolset.flags vmsdecc.link .LD $(condition) : $(linker) ; if $(.debug-configuration) { - ECHO notice: using linker :: $(condition) :: $(linker[1]) ; + ECHO notice\: using linker "::" $(condition) "::" $(linker[1]) ; } local archiver = LIB ; @@ -90,7 +90,7 @@ flags vmsdecc.compile OPTIONS on : /DEBUG ; ## needs PCA link optio flags vmsdecc.compile OPTIONS off : /NOOPT ; flags vmsdecc.compile OPTIONS speed : /OPT=INLINE=SPEED/OPT=NOINLINE ; flags vmsdecc.compile OPTIONS space : /OPT=INLINE=SIZE/OPT=NOINLINE ; -flags vmsdecc.compile OPTIONS off : /NOWARN; +flags vmsdecc.compile OPTIONS off : /NOWARN ; flags vmsdecc.compile OPTIONS on : /WARN ; flags vmsdecc.compile OPTIONS all : /WARN=ENABLE=ALL ; diff --git a/tools/build/src/tools/xsltproc-config.jam b/tools/build/src/tools/xsltproc-config.jam index d1be25fa85..b240fe3af9 100644 --- a/tools/build/src/tools/xsltproc-config.jam +++ b/tools/build/src/tools/xsltproc-config.jam @@ -30,7 +30,7 @@ if $(xsltproc-exe) { if --debug-configuration in [ modules.peek : ARGV ] { - ECHO notice: using xsltproc ":" $(xsltproc-exe) ; + ECHO notice\: using xsltproc ":" $(xsltproc-exe) ; } using xsltproc : $(xsltproc-exe) ; } diff --git a/tools/build/src/tools/xsltproc.jam b/tools/build/src/tools/xsltproc.jam index 56de81f36f..6baf0491af 100644 --- a/tools/build/src/tools/xsltproc.jam +++ b/tools/build/src/tools/xsltproc.jam @@ -6,17 +6,20 @@ # This module defines rules to apply an XSLT stylesheet to an XML file using the # xsltproc driver, part of libxslt. +import "class" : new ; import common ; import feature ; +import generators ; import modules ; import os ; import path ; import regex ; import sequence ; +import toolset ; +import virtual-target ; - -feature.feature xsl:param : : free ; -feature.feature xsl:path : : free ; +feature.feature "xsl:param" : : free ; +feature.feature "xsl:path" : : free ; feature.feature catalog : : free ; @@ -108,42 +111,59 @@ rule .is-cygwin ( xsltproc ) } } - -rule compute-xslt-flags ( target : properties * ) +class xsltproc-action : action { - # Raw flags. - local flags = [ feature.get-values : $(properties) ] ; - - # Translate into command line flags. - for local param in [ feature.get-values : $(properties) ] + rule adjust-properties ( property-set ) { - local namevalue = [ regex.split $(param) "=" ] ; - flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ; + local s = [ $(self.targets[1]).creating-subvariant ] ; + if $(s) + { + return [ $(property-set).add-raw + [ $(s).implicit-includes "xsl:path" : XML ] ] ; + } + else + { + return $(property-set) ; + } } +} - # Translate . - for local path in [ feature.get-values : $(properties) ] +class xsltproc-generator : generator +{ + rule action-class ( ) { - flags += --path \"$(path:G=)\" ; + return xsltproc-action ; } +} - # Take care of implicit dependencies. - local other-deps ; - for local dep in [ feature.get-values : $(properties) - ] +rule register-generator ( id : source-types + : target-types + : requirements * ) +{ + if ! $(id) in $(.known-rules) { - other-deps += [ $(dep:G=).creating-subvariant ] ; + .known-rules += $(id) ; + flags $(id) ; } + generators.register [ new xsltproc-generator $(id) : + $(source-types) : $(target-types) : $(requirements) ] ; +} - local implicit-target-directories ; - for local dep in [ sequence.unique $(other-deps) ] - { - implicit-target-directories += [ $(dep).all-target-directories ] ; - } +IMPORT xsltproc : register-generator : : generators.register-xslt ; + +rule flags ( rulename ) +{ + toolset.uses-features $(rulename) : : unchecked ; + toolset.flags $(rulename) XSL-PATH : : unchecked ; + toolset.flags $(rulename) FLAGS : : unchecked ; +} - for local dir in $(implicit-target-directories) +rule compute-xslt-flags ( target : properties * ) +{ + local flags ; + # Translate into command line flags. + for local param in [ feature.get-values : $(properties) ] { - flags += --path \"$(dir:T)\" ; + local namevalue = [ regex.split $(param) "=" ] ; + flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ; } return $(flags) ; @@ -186,25 +206,27 @@ rule xslt-dir ( target : source stylesheet : properties * : dirname ) $(dirname) : xslt-xsltproc-dir ] ; } +_ = " " ; + actions xslt-xsltproc.windows { - $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:W)" "$(>:W)" + $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:W)" --xinclude -o "$(<)" "$(STYLESHEET:W)" "$(>:W)" } actions xslt-xsltproc bind STYLESHEET { - $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:T)" "$(>:T)" + $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:T)" --xinclude -o "$(<)" "$(STYLESHEET:T)" "$(>:T)" } actions xslt-xsltproc-dir.windows bind STYLESHEET { - $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:W)" "$(>:W)" + $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:W)" --xinclude -o "$(<:D)/" "$(STYLESHEET:W)" "$(>:W)" } actions xslt-xsltproc-dir bind STYLESHEET { - $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:T)" "$(>:T)" + $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --path$(_)"$(XSL-PATH:T)" --xinclude -o "$(<:D)/" "$(STYLESHEET:T)" "$(>:T)" } diff --git a/tools/build/src/tools/zlib.jam b/tools/build/src/tools/zlib.jam index 45dc4767a8..7ac81047d6 100644 --- a/tools/build/src/tools/zlib.jam +++ b/tools/build/src/tools/zlib.jam @@ -14,12 +14,13 @@ import project ; import ac ; import errors ; +import feature ; import "class" : new ; import targets ; import path ; import modules ; -import errors ; import indirect ; +import os ; import property ; import property-set ; @@ -111,18 +112,12 @@ rule init ( project zlib ; } - local library-path = [ property.select : $(options) ] ; - library-path = $(library-path:G=) ; - local include-path = [ property.select : $(options) ] ; - include-path = $(include-path:G=) ; - local source-path = [ property.select : $(options) ] ; - source-path = $(source-path:G=) ; - local library-name = [ property.select : $(options) ] ; - library-name = $(library-name:G=) ; - local tag = [ property.select : $(options) ] ; - tag = $(tag:G=) ; - local build-name = [ property.select : $(options) ] ; - build-name = $(build-name:G=) ; + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local source-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + local tag = [ feature.get-values : $(options) ] ; + local build-name = [ feature.get-values : $(options) ] ; if ! $(library-path) && ! $(include-path) && ! $(source-path) && ! $(library-name) { @@ -132,7 +127,6 @@ rule init ( condition = [ property-set.create $(requirements) ] ; condition = [ property-set.create [ $(condition).base ] ] ; - local no-build-from-source ; # Ignore environmental ZLIB_SOURCE if this initialization # requested to search for a specific pre-built library. if $(library-path) || $(include-path) || $(library-name) @@ -146,7 +140,12 @@ rule init ( } else { - source-path ?= [ modules.peek : ZLIB_SOURCE ] ; + source-path ?= [ os.environ ZLIB_SOURCE ] ; + if $(source-path) + { + source-path = [ path.root [ path.make $(source-path) ] + [ path.pwd ] ] ; + } } if $(.configured.$(condition)) @@ -169,7 +168,7 @@ rule init ( build-name ?= z ; library-id = [ CALC $(library-id) + 1 ] ; tag = [ MATCH ^@?(.*)$ : $(tag) ] ; - if $(tag) && ! [ MATCH ^([^%]*)%([^%]+)$ : $(tag) ] + if $(tag) { tag = [ indirect.make $(tag) : [ $(caller).project-module ] ] ; } diff --git a/tools/build/src/tools/zstd.jam b/tools/build/src/tools/zstd.jam new file mode 100644 index 0000000000..068527f51d --- /dev/null +++ b/tools/build/src/tools/zstd.jam @@ -0,0 +1,98 @@ +# Copyright (c) 2010 Vladimir Prus. +# Copyright (c) 2013 Steven Watanabe +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +# Supports the zstd library +# +# After 'using zstd', the following targets are available: +# +# /zstd//zstd -- The zstd library + +import project ; +import ac ; +import errors ; +import feature ; +import "class" : new ; +import targets ; +import path ; +import modules ; +import indirect ; +import property ; +import property-set ; + +header = zstd.h ; +names = zstd ; + +library-id = 0 ; + +if --debug-configuration in [ modules.peek : ARGV ] +{ + .debug = true ; +} + +rule init ( + version ? + # (currently ignored) + + : options * + # A list of the options to use + + : requirements * + # The requirements for the target + ) +{ + local caller = [ project.current ] ; + + if ! $(.initialized) + { + .initialized = true ; + + project.initialize $(__name__) ; + .project = [ project.current ] ; + project zstd ; + } + + local library-path = [ feature.get-values : $(options) ] ; + local include-path = [ feature.get-values : $(options) ] ; + local library-name = [ feature.get-values : $(options) ] ; + + condition = [ property-set.create $(requirements) ] ; + condition = [ property-set.create [ $(condition).base ] ] ; + + if $(.configured.$(condition)) + { + if ! $(options) + { + if $(.debug) + { + ECHO "notice: [zstd] zstd is already configured" ; + } + } + else + { + errors.user-error "zstd is already configured" ; + } + return ; + } + else + { + if $(.debug) + { + ECHO "notice: [zstd] Using pre-installed library" ; + if $(condition) + { + ECHO "notice: [zstd] Condition" [ $(condition).raw ] ; + } + } + + local mt = [ new ac-library zstd : $(.project) : $(condition) : + $(include-path) : $(library-path) : $(library-name) ] ; + $(mt).set-header $(header) ; + $(mt).set-default-names $(names) ; + targets.main-target-alternative $(mt) ; + } + .configured.$(condition) = true ; +} diff --git a/tools/build/src/util/assert.jam b/tools/build/src/util/assert.jam index 65e880f43b..f6afcdecfd 100644 --- a/tools/build/src/util/assert.jam +++ b/tools/build/src/util/assert.jam @@ -53,7 +53,7 @@ rule equal ( a * : b * ) { if $(a) != $(b) { - errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" + errors.error-skip-frames 3 assertion "failure:" \"$(a)\" "==" \"$(b)\" (ignoring trailing empty strings) ; } } @@ -74,10 +74,10 @@ rule false ( rule-name args * : * ) if $(result) { - errors.error-skip-frames 3 assertion failure: Expected false result from + errors.error-skip-frames 3 assertion "failure:" Expected false result from "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : - $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ] "]" : Got: "[" + $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ] "]" : "Got:" "[" \"$(result)\" "]" ; } } @@ -89,7 +89,7 @@ rule "in" ( element : list * ) { if ! $(element) in $(list) { - errors.error-skip-frames 3 assertion failure: Expected \"$(element)\" in + errors.error-skip-frames 3 assertion "failure:" Expected \"$(element)\" in "[" \"$(list)\" "]" ; } } @@ -101,7 +101,7 @@ rule not-equal ( a * : b * ) { if $(a) = $(b) { - errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" + errors.error-skip-frames 3 assertion "failure:" \"$(a)\" "!=" \"$(b)\" (ignoring trailing empty strings) ; } } @@ -113,7 +113,7 @@ rule not-in ( element : list * ) { if $(element) in $(list) { - errors.error-skip-frames 3 assertion failure: Did not expect + errors.error-skip-frames 3 assertion "failure:" Did not expect \"$(element)\" in "[" \"$(list)\" "]" ; } } @@ -125,7 +125,7 @@ rule not-set-equal ( a * : b * ) { if [ set-equal-test $(a) : $(b) ] { - errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + errors.error-skip-frames 3 assertion "failure:" Expected "[" \"$(a)\" "]" and "[" \"$(b)\" "]" to not be equal as sets ; } } @@ -138,7 +138,7 @@ rule not-exact-equal ( a * : b * ) { if [ exact-equal-test $(a) : $(b) ] { - errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ; + errors.error-skip-frames 3 assertion "failure:" \"$(a)\" "!=" \"$(b)\" ; } } @@ -158,10 +158,10 @@ rule result ( expected * : rule-name args * : * ) if ! [ exact-equal-test $(result) : $(expected) ] { - errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.error-skip-frames 3 assertion "failure:" "[" $(rule-name) [ errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) - : $(18) : $(19) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + : $(18) : $(19) ] "]" : "Expected:" "[" \"$(expected)\" "]" : "Got:" "[" \"$(result)\" "]" ; } } @@ -183,10 +183,10 @@ rule result-set-equal ( expected * : rule-name args * : * ) if ! [ set-equal-test $(result) : $(expected) ] { - errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.error-skip-frames 3 assertion "failure:" "[" $(rule-name) [ errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) - : $(18) : $(19) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + : $(18) : $(19) ] "]" : "Expected:" "[" \"$(expected)\" "]" : "Got:" "[" \"$(result)\" "]" ; } } @@ -198,7 +198,7 @@ rule set-equal ( a * : b * ) { if ! [ set-equal-test $(a) : $(b) ] { - errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + errors.error-skip-frames 3 assertion "failure:" Expected "[" \"$(a)\" "]" and "[" \"$(b)\" "]" to be equal as sets ; } } @@ -219,7 +219,7 @@ rule true ( rule-name args * : * ) if ! $(result) { - errors.error-skip-frames 3 assertion failure: Expected true result from + errors.error-skip-frames 3 assertion "failure:" Expected true result from "[" $(rule-name) [ errors.lol->list $(args) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) : $(10) : $(11) : $(12) : $(13) : $(14) : $(15) : $(16) : $(17) : $(18) : $(19) ] "]" ; @@ -234,7 +234,7 @@ rule exact-equal ( a * : b * ) { if ! [ exact-equal-test $(a) : $(b) ] { - errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" ; + errors.error-skip-frames 3 assertion "failure:" \"$(a)\" "==" \"$(b)\" ; } } @@ -246,7 +246,7 @@ rule variable-not-empty ( name ) local value = [ modules.peek [ CALLER_MODULE ] : $(name) ] ; if ! $(value)-is-not-empty { - errors.error-skip-frames 3 assertion failure: Expected variable + errors.error-skip-frames 3 assertion "failure:" Expected variable \"$(name)\" not to be an empty list ; } } diff --git a/tools/build/src/util/doc.jam b/tools/build/src/util/doc.jam index 4e43912b69..a515bf1752 100644 --- a/tools/build/src/util/doc.jam +++ b/tools/build/src/util/doc.jam @@ -172,7 +172,10 @@ local rule set-class-doc ( module-name ?= * ; $(module-name).$(name).is-class = true ; - $(module-name).$(name).super-name = $(super-name) ; + if $(super-name) + { + $(module-name).$(name).super-name = $(super-name) ; + } $(module-name).$(name).class-rules = [ MATCH "^($(name)[.].*)" : $($(module-name).rules) ] ; $(module-name).$($(module-name).$(name).class-rules).is-class-rule = true ; @@ -292,76 +295,76 @@ local rule print-help-usage ( ) "b2 [ options... ] targets..." ; print.list-start ; - print.list-item -a; + print.list-item -a\; Build all targets, even if they are current. ; - print.list-item -fx; + print.list-item -fx\; Read '"x"' as the Jamfile for building instead of searching for the Boost.Build system. ; - print.list-item -jx; + print.list-item -jx\; Run up to '"x"' commands concurrently. ; - print.list-item -n; + print.list-item -n\; Do not execute build commands. Instead print out the commands as they would be executed if building. ; - print.list-item -ox; + print.list-item -ox\; Output the used build commands to file '"x"'. ; - print.list-item -q; + print.list-item -q\; Quit as soon as a build failure is encountered. Without this option Boost.Jam will continue building as many targets as it can. ; - print.list-item -sx=y; + print.list-item -sx=y\; Sets a Jam variable '"x"' to the value '"y"', overriding any value that variable would have from the environment. ; - print.list-item -tx; + print.list-item -tx\; Rebuild the target '"x"', even if it is up-to-date. ; - print.list-item -v; + print.list-item -v\; Display the version of b2. ; - print.list-item --x; + print.list-item --x\; Any option not explicitly handled by Boost.Build remains available to build scripts using the '"ARGV"' variable. ; - print.list-item --abbreviate-paths; + print.list-item --abbreviate-paths\; Use abbreviated paths for targets. ; - print.list-item --hash; + print.list-item --hash\; Shorten target paths by using an MD5 hash. ; - print.list-item -dconsole; + print.list-item -dconsole\; Run the interactive debugger. Cannot be used with any other option. ; - print.list-item -dn; + print.list-item -dn\; Enables output of diagnostic messages. The debug level '"n"' and all below it are enabled by this option. ; - print.list-item -d+n; + print.list-item -d+n\; Enables output of diagnostic messages. Only the output for debug level '"n"' is enabled. ; print.list-end ; print.section "Debug Levels" Each debug level shows a different set of information. Usually with higher levels producing more verbose information. The following levels - are supported: ; + are supported\: ; print.list-start ; - print.list-item 0; + print.list-item 0\; Turn off all diagnostic output. Only errors are reported. ; - print.list-item 1; + print.list-item 1\; Show the actions taken for building targets, as they are executed. ; - print.list-item 2; + print.list-item 2\; Show "quiet" actions and display all action text, as they are executed. ; - print.list-item 3; + print.list-item 3\; Show dependency analysis, and target/source timestamps/paths. ; - print.list-item 4; + print.list-item 4\; Show arguments of shell invocations. ; - print.list-item 5; + print.list-item 5\; Show rule invocations and variable expansions. ; - print.list-item 6; + print.list-item 6\; Show directory/header file/archive scans, and attempts at binding to targets. ; - print.list-item 7; + print.list-item 7\; Show variable settings. ; - print.list-item 8; + print.list-item 8\; Show variable fetches, variable expansions, and evaluation of '"if"' expressions. ; - print.list-item 9; + print.list-item 9\; Show variable manipulation, scanner tokens, and memory usage. ; - print.list-item 10; + print.list-item 10\; Show execution times for rules. ; - print.list-item 11; + print.list-item 11\; Show parsing progress of Jamfiles. ; - print.list-item 12; + print.list-item 12\; Show graph for target dependencies. ; - print.list-item 13; + print.list-item 13\; Show changes in target status (fate). ; print.list-end ; } @@ -374,7 +377,7 @@ local rule print-help-options ( module-name ) { - local options-to-list = [ MATCH ^[.]option[.](.*) : $($(module-name).variables) ] ; + local options-to-list = [ MATCH "^[.]option[.](.*)" : $($(module-name).variables) ] ; if $(options-to-list) { local option-title = $($(module-name)..option-description.initial) ; @@ -393,7 +396,7 @@ local rule print-help-options ( { def = $($(module-name)..option.$(option).default) ; } - print.list-item $(option): $($(module-name)..option.$(option).docs) + print.list-item $(option)\: $($(module-name)..option.$(option).docs) Default is $(def). ; } print.list-end ; @@ -428,7 +431,7 @@ local rule print-help-module-section ( } if $(show) { - print.list-item $(item): $($(module).$(item).brief) ; + print.list-item $(item)\: $($(module).$(item).brief) ; } } print.list-end ; @@ -453,7 +456,7 @@ local rule print-help-all ( for local module-name in [ sequence.insertion-sort $(documented-modules) ] { # The brief docs for each module. - print.list-item $(module-name): $($(module-name).brief) ; + print.list-item $(module-name)\: $($(module-name).brief) ; } print.list-end ; } @@ -520,12 +523,16 @@ local rule print-help-rules ( signature ?= "" ; print.section "Rule '$(module-name).$(rule-name) ( $(signature) )'" $($(module-name).$(rule-name).docs) ; - if $($(module-name).$(rule-name).args) + if $($(module-name).$(rule-name).args) && + $($(module-name).$(rule-name).args.$($(module-name).$(rule-name).args).docs) { print.list-start ; for local arg-name in $($(module-name).$(rule-name).args) { - print.list-item $(arg-name): $($(module-name).$(rule-name).args.$(arg-name).docs) ; + if $($(module-name).$(rule-name).args.$(arg-name).docs) + { + print.list-item $(arg-name)\: $($(module-name).$(rule-name).args.$(arg-name).docs) ; + } } print.list-end ; } @@ -560,7 +567,7 @@ local rule print-help-classes ( print.list-start ; for local arg-name in $($(module-name).$(class-name).args) { - print.list-item $(arg-name): $($(module-name).$(class-name).args.$(arg-name).docs) ; + print.list-item $(arg-name)\: $($(module-name).$(class-name).args.$(arg-name).docs) ; } print.list-end ; } @@ -650,7 +657,44 @@ local rule print-help-config ( } -ws = " " ; +ws = "\t " ; + +# Extract the text from a single comment +# +local rule extract-one-comment ( + var # The name of the variable to extract from + : start # The initial part after the leading '#' +) +{ + local m = [ MATCH ^(\\|)(.*) : $(start) ] ; + if $(m) + { + start = $(m[2]) ; + local comment ; + while true + { + local end = [ MATCH "(.*)(\\|#)(.*)" : $(start) ] ; + if $(end) + { + comment += $(end[1]) ; + $(var) = $(end[3]) $($(var)[2-]) ; + return $(comment) ; + } + else + { + comment += $(start) ; + $(var) = $($(var)[2-]) ; + } + start = $($(var)[1]) ; + } + } + else + { + $(var) = $($(var)[2-]) ; + if $(start) { return [ MATCH "^[$(ws)]?(.*)$" : $(start) ] ; } + else { return "" ; } + } +} # Extract the text from a block of comments. # @@ -663,9 +707,7 @@ local rule extract-comment ( local l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ; while $(l[1]) && $($(var)) { - if $(l[2]) { comment += [ MATCH "^[$(ws)]?(.*)$" : $(l[2]) ] ; } - else { comment += "" ; } - $(var) = $($(var)[2-]) ; + comment += [ extract-one-comment $(var) : $(l[2]) ] ; line = $($(var)[1]) ; l = [ MATCH "^[$(ws)]*(#)(.*)$" : $(line) ] ; } @@ -873,14 +915,39 @@ local rule scan-variable ( # local rule scan-class ( syntax ? # The syntax text for the class declaration. + : var # The name of the variable to extract from. ) { # [1] = class?, [2] = name, [3] = superclass local class-parts = - [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([^$(ws)]+)[$(ws)]+:*[$(ws)]*([^$(ws);]*)" : $(syntax) ] ; + [ MATCH "^[$(ws)]*([^$(ws)]+)[$(ws)]+([^$(ws)]+)[$(ws)]*:*[$(ws)]*([^$(ws);]*)" : $(syntax) ] ; if $(class-parts[1]) = "class" || $(class-parts[1]) = "class.class" { + # Scan within this class scope. + local scope-level = [ extract-token $(var) ] ; + local scope-name = $(class-parts[2]) ; + while $(scope-level) && $($(var)) + { + local comment-block = [ extract-comment $(var) ] ; + local syntax-block = [ extract-syntax $(var) ] ; + if [ scan-rule $(syntax-block) : $(var) ] + { + } + else if [ MATCH "^(\\{)" : $(syntax-block) ] + { + scope-level += "{" ; + } + else if [ MATCH "^[^\\}]*([\\}])[$(ws)]*$" : $(syntax-block) ] + { + scope-level = $(scope-level[2-]) ; + } + } + + # This has to come after parsing the rules, because + # it looks up the rules for the class from the global list. set-class-doc $(class-parts[2]) $(module-name) : $(class-parts[3]) ; + + return true ; } } @@ -910,13 +977,13 @@ rule scan-module ( syntax-block = [ extract-syntax text ] ; if $(.option.debug) { - ECHO "HELP:" comment block; '$(comment-block)' ; - ECHO "HELP:" syntax block; '$(syntax-block)' ; + ECHO "HELP:" comment block\; '$(comment-block)' ; + ECHO "HELP:" syntax block\; '$(syntax-block)' ; } if [ scan-rule $(syntax-block) : text ] { } else if [ scan-variable $(syntax-block) : text ] { } - else if [ scan-class $(syntax-block) ] { } - else if [ MATCH .*([cC]opyright).* : $(comment-block:J=" ") ] + else if [ scan-class $(syntax-block) : text ] { } + else if [ MATCH ".*([cC]opyright).*" : $(comment-block:J=" ") ] { # mark as the copy for the module. set-module-copyright $(module-name) : $(comment-block) ; @@ -967,9 +1034,7 @@ local rule read-file ( content = [ SHELL "cat \"$(file)\"" ] ; } local lines ; - local nl = " -" ; - local << = "([^$(nl)]*)[$(nl)](.*)" ; + local << = "([^\r\n]*)[\r]?[\n](.*)" ; local line+ = [ MATCH "$(<<)" : "$(content)" ] ; while $(line+) { diff --git a/tools/build/src/util/indirect.jam b/tools/build/src/util/indirect.jam index 40884da96d..095fea95ff 100644 --- a/tools/build/src/util/indirect.jam +++ b/tools/build/src/util/indirect.jam @@ -9,7 +9,7 @@ import numbers ; # The pattern that indirect rules must match: module%rule -.pattern = ^([^%]*)%([^%]+)$ ; +.pattern = "^([^%]*)%([^%]+)$" ; # @@ -31,9 +31,16 @@ local rule indirect-rule ( x ) # rule make ( rulename bound-args * : context ? ) { - context ?= [ CALLER_MODULE ] ; - context ?= "" ; - return $(context)%$(rulename) $(bound-args) ; + if [ MATCH $(.pattern) : $(rulename) ] + { + return $(rulename) $(bound-args) ; + } + else + { + context ?= [ CALLER_MODULE ] ; + context ?= "" ; + return $(context)%$(rulename) $(bound-args) ; + } } @@ -53,13 +60,13 @@ rule make-qualified ( rulename bound-args * : frames ? ) { frames ?= 1 ; # If the rule name includes a Jamfile module, grab it. - local module-context = [ MATCH ^(Jamfile<[^>]*>)\\..* : $(rulename) ] ; + local module-context = [ MATCH "^(Jamfile<[^>]*>)\\..*" : $(rulename) ] ; if ! $(module-context) { # Take the first dot-separated element as module name. This disallows # module names with dots, but allows rule names with dots. - module-context = [ MATCH ^([^.]*)\\..* : $(rulename) ] ; + module-context = [ MATCH "^([^.]*)\\..*" : $(rulename) ] ; } module-context ?= [ CALLER_MODULE $(frames) ] ; return [ make $(rulename) $(bound-args) : $(module-context) ] ; diff --git a/tools/build/src/util/option.jam b/tools/build/src/util/option.jam index f6dc375223..4c837f4e1d 100644 --- a/tools/build/src/util/option.jam +++ b/tools/build/src/util/option.jam @@ -65,7 +65,7 @@ rule process ( ) if $(arg) { - local split = [ MATCH ^(([^-=]+)[^=]*)(=?)(.*)$ : $(arg) ] ; + local split = [ MATCH "^(([^-=]+)[^=]*)(=?)(.*)$" : $(arg) ] ; local full-name = $(split[1]) ; local prefix = $(split[2]) ; local values ; diff --git a/tools/build/src/util/os.jam b/tools/build/src/util/os.jam index bcac5a6967..5c57448145 100644 --- a/tools/build/src/util/os.jam +++ b/tools/build/src/util/os.jam @@ -47,7 +47,7 @@ rule get-constant ( os ? ) # Find the name of the constant being accessed, which is equal to the name # used to invoke us. local bt = [ BACKTRACE 1 ] ; - local rulename = [ MATCH ([^.]*)$ : $(bt[4]) ] ; + local rulename = [ MATCH "([^.]*)$" : $(bt[4]) ] ; return [ constant $(rulename) : $(os) ] ; } @@ -201,8 +201,8 @@ rule __test__ import assert ; if ! ( --quiet in [ modules.peek : ARGV ] ) { - ECHO os: name= [ name ] ; - ECHO os: version= [ version ] ; + ECHO "os:" name= [ name ] ; + ECHO "os:" version= [ version ] ; } assert.true name ; } diff --git a/tools/build/src/util/param.jam b/tools/build/src/util/param.jam new file mode 100644 index 0000000000..9db2e58551 --- /dev/null +++ b/tools/build/src/util/param.jam @@ -0,0 +1,54 @@ +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Named parameters are represented as a list which has the +# argument name as the first element and the value as the +# remaining elements. This function sorts the parameters +# into the correct variables and removes the parameter names. +# +# Example:: +# +# rule exe ( name : sources * : requirements * ) +# { +# param.handle-named-params sources requirements ; +# # At this point $(sources) is test.cpp +# } +# exe test : requirements shared : sources test.cpp ; +# +rule handle-named-params ( parameter-names * ) +{ + module [ CALLER_MODULE ] + { + # Uglify the variable names, because we're executing in an unknown module. + local found-8bef5c096d06a1b0 ; + local tmp-8bef5c096d06a1b0.$(1) ; + for local v-8bef5c096d06a1b0 in $(1) + { + if $($(v-8bef5c096d06a1b0)[1]) && $($(v-8bef5c096d06a1b0)[1]) in $(1) + { + if $(tmp-8bef5c096d06a1b0.$($(v-8bef5c096d06a1b0)[1])) + { + import errors ; + errors.error Parameter '$($(v-8bef5c096d06a1b0)[1])' passed more than once. ; + } + found-8bef5c096d06a1b0 = true ; + tmp-8bef5c096d06a1b0.$($(v-8bef5c096d06a1b0)[1]) = $($(v-8bef5c096d06a1b0)[2-]) ; + } + else if $($(v-8bef5c096d06a1b0))-is-defined + { + if $(found-8bef5c096d06a1b0) + { + import errors ; + errors.error "Positional arguments must appear first." ; + } + tmp-8bef5c096d06a1b0.$(v-8bef5c096d06a1b0) = $($(v-8bef5c096d06a1b0)) ; + } + } + for local v-8bef5c096d06a1b0 in $(1) + { + $(v-8bef5c096d06a1b0) = $(tmp-8bef5c096d06a1b0.$(v-8bef5c096d06a1b0)) ; + } + } +} diff --git a/tools/build/src/util/path.jam b/tools/build/src/util/path.jam index 166c793304..da44f876a4 100644 --- a/tools/build/src/util/path.jam +++ b/tools/build/src/util/path.jam @@ -549,7 +549,7 @@ rule native-CYGWIN ( path ) # rule split-path-VMS ( native ) { - local matches = [ MATCH ([a-zA-Z0-9_-]+:)?(\\[[^\]]*\\])?(.*)?$ : $(native) + local matches = [ MATCH "([a-zA-Z0-9_-]+:)?(\\[[^\]]*\\])?(.*)?$" : $(native) ] ; local device = $(matches[1]) ; local dir = $(matches[2]) ; diff --git a/tools/build/src/util/print.jam b/tools/build/src/util/print.jam index 8a9e5b4c80..b2dc35902b 100644 --- a/tools/build/src/util/print.jam +++ b/tools/build/src/util/print.jam @@ -80,7 +80,7 @@ rule section ( { if $(output-type) = plain { - lines [ split-at-words $(name): ] ; + lines [ split-at-words "$(name):" ] ; lines ; } else if $(output-type) = html @@ -117,11 +117,11 @@ rule section ( { while $(description) && ! [ string.is-whitespace $(description[1]) ] { paragraph += $(description[1]) ; description = $(description[2-]) ; } - if $(paragraph[1]) = :: && ! $(paragraph[2]) + if $(paragraph[1]) = "::" && ! $(paragraph[2]) { pre = " " ; } - if $(paragraph[1]) = :: + if $(paragraph[1]) = "::" { if $(output-type) = plain { @@ -140,10 +140,10 @@ rule section ( local p = [ MATCH "(.*)(::)$" : $(paragraph[-1]) ] ; local pws = [ MATCH "([ ]*)$" : $(p[1]) ] ; p = [ MATCH "(.*)($(pws))($(p[2]))$" : $(paragraph[-1]) ] ; - if $(p[3]) = :: + if $(p[3]) = "::" { pre = [ string.chars [ MATCH "^([$(.whitespace)]*)" : " $(p[1])" ] ] ; - if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) $(p[1]): ; } + if ! $(p[2]) || $(p[2]) = "" { paragraph = $(paragraph[1--2]) "$(p[1]):" ; } else { paragraph = $(paragraph[1--2]) $(p[1]) ; } if $(output-type) = plain { diff --git a/tools/build/src/util/regex.jam b/tools/build/src/util/regex.jam index be8b3cfd12..ef5f632ace 100644 --- a/tools/build/src/util/regex.jam +++ b/tools/build/src/util/regex.jam @@ -98,7 +98,7 @@ rule escape ( string : symbols : escape-symbol ) local m = 1 ; while $(m) { - m = [ MATCH ^([^$(symbols)]*)([$(symbols)])(.*) : $(string) ] ; + m = [ MATCH "^([^$(symbols)]*)([$(symbols)])(.*)" : $(string) ] ; if $(m) { m += "" ; # Supposedly a bug fix; borrowed from regex.split @@ -180,13 +180,13 @@ rule __test__ ( ) : match (.)(.)(.)(.) : abcd ; assert.result ababab cddc - : match ((ab)*)([cd]+) : abababcddc : 1 3 ; + : match "((ab)*)([cd]+)" : abababcddc : 1 3 ; assert.result a.h c.h : transform \"b.h\" : <(.*)> ; assert.result a.h b.h c.h - : transform \"b.h\" : <([^>]*)>|\"([^\"]*)\" : 1 2 ; + : transform \"b.h\" : "<([^>]*)>|\"([^\"]*)\"" : 1 2 ; assert.result "^" : escape "" : "&|()<>^" : "^" ; diff --git a/tools/build/src/util/sequence.jam b/tools/build/src/util/sequence.jam index 97ddfe1539..ddfd069c7d 100644 --- a/tools/build/src/util/sequence.jam +++ b/tools/build/src/util/sequence.jam @@ -156,6 +156,42 @@ rule merge ( s1 * : s2 * : ordered * ) return $(result__) ; } +# Compares two sequences lexicagraphically +# +rule compare ( s1 * : s2 * : ordered * ) +{ + if ! $(ordered) + { + if $(s1) < $(s2) + { + return true ; + } + } + else + { + while true + { + if ! $(s2[1])-is-defined + { + return ; + } + else if ! $(s1[1])-is-defined + { + return true ; + } + else if [ $(ordered) $(s1[1]) $(s2[1]) ] + { + return true ; + } + else if [ $(ordered) $(s2[1]) $(s1[1]) ] + { + return ; + } + s1 = $(s1[2-]) ; + s2 = $(s2[2-]) ; + } + } +} # Join the elements of s into one long string. If joint is supplied, it is used # as a separator. diff --git a/tools/build/src/util/string.jam b/tools/build/src/util/string.jam index a39ed119e2..b7af7c2e49 100644 --- a/tools/build/src/util/string.jam +++ b/tools/build/src/util/string.jam @@ -93,7 +93,7 @@ rule abbreviate ( string ) s2 = $(r:J="") ; # Chop all vowels out of the remainder. - s2 = [ regex.replace $(s2) [AEIOUaeiou] "" ] ; + s2 = [ regex.replace $(s2) "[AEIOUaeiou]" "" ] ; # Shorten remaining consonants to 4 characters. s2 = [ MATCH ^(.?.?.?.?) : $(s2) ] ; diff --git a/tools/build/src/util/utility.jam b/tools/build/src/util/utility.jam index 26981c5480..d2cdb004f0 100644 --- a/tools/build/src/util/utility.jam +++ b/tools/build/src/util/utility.jam @@ -117,7 +117,7 @@ rule ungrist ( names * ) { import errors ; local quoted-names = \"$(names)\" ; - errors.error "in" ungrist $(quoted-names:J=" "): \"$(name)\" is not + errors.error "in" ungrist "$(quoted-names:J= ):" \"$(name)\" is not of the form <.*> ; } result += $(stripped) ; @@ -195,41 +195,41 @@ rule __test__ ( ) { ungrist "" ; } - catch "in" ungrist \"\": \"\" is not of the form <.*> ; + catch "in" ungrist "\"\":" \"\" is not of the form <.*> ; try ; { ungrist foo ; } - catch "in" ungrist \"foo\": \"foo\" is not of the form <.*> ; + catch "in" ungrist "\"foo\":" \"foo\" is not of the form <.*> ; try ; { ungrist ; + catch "in" ungrist "\" ; try ; { ungrist foo> ; } - catch "in" ungrist \"foo>\": \"foo>\" is not of the form <.*> ; + catch "in" ungrist "\"foo>\":" \"foo>\" is not of the form <.*> ; try ; { ungrist foo bar ; } - catch "in" ungrist "\"foo\" \"bar\"": \"foo\" is not of the form <.*> ; + catch "in" ungrist "\"foo\" "\"bar\"":" \"foo\" is not of the form <.*> ; try ; { ungrist foo ; } - catch "in" ungrist "\"foo\" \"\"": \"foo\" is not of the form <.*> ; + catch "in" ungrist "\"foo\" "\"\"":" \"foo\" is not of the form <.*> ; try ; { ungrist bar ; } - catch "in" ungrist "\"\" \"bar\"": \"bar\" is not of the form <.*> ; + catch "in" ungrist "\"\" "\"bar\"":" \"bar\" is not of the form <.*> ; } diff --git a/tools/build/test/BoostBuild.py b/tools/build/test/BoostBuild.py index a6872dcbcf..19b346f77c 100644 --- a/tools/build/test/BoostBuild.py +++ b/tools/build/test/BoostBuild.py @@ -92,13 +92,19 @@ def get_toolset(): cygwin = hasattr(os, "uname") and os.uname()[0].lower().startswith("cygwin") windows = cygwin or os.environ.get("OS", "").lower().startswith("windows") +if cygwin: + default_os = "cygwin" +elif windows: + default_os = "windows" +elif hasattr(os, "uname"): + default_os = os.uname()[0].lower() -def prepare_prefixes_and_suffixes(toolset): - prepare_suffix_map(toolset) - prepare_library_prefix(toolset) +def prepare_prefixes_and_suffixes(toolset, target_os=default_os): + prepare_suffix_map(toolset, target_os) + prepare_library_prefix(toolset, target_os) -def prepare_suffix_map(toolset): +def prepare_suffix_map(toolset, target_os=default_os): """ Set up suffix translation performed by the Boost Build testing framework to accomodate different toolsets generating targets of the same type using @@ -107,11 +113,11 @@ def prepare_suffix_map(toolset): """ global suffixes suffixes = {} - if windows: + if target_os in ["windows", "cygwin"]: if toolset == "gcc": suffixes[".lib"] = ".a" # mingw static libs use suffix ".a". suffixes[".obj"] = ".o" - if cygwin: + if target_os == "cygwin": suffixes[".implib"] = ".lib.a" else: suffixes[".implib"] = ".lib" @@ -122,11 +128,11 @@ def prepare_suffix_map(toolset): suffixes[".obj"] = ".o" suffixes[".implib"] = ".no_implib_files_on_this_platform" - if hasattr(os, "uname") and os.uname()[0] == "Darwin": + if target_os == "darwin": suffixes[".dll"] = ".dylib" -def prepare_library_prefix(toolset): +def prepare_library_prefix(toolset, target_os=default_os): """ Setup whether Boost Build is expected to automatically prepend prefixes to its built library targets. @@ -136,9 +142,9 @@ def prepare_library_prefix(toolset): lib_prefix = "lib" global dll_prefix - if cygwin: + if target_os == "cygwin": dll_prefix = "cyg" - elif windows and toolset != "gcc": + elif target_os == "windows" and toolset != "gcc": dll_prefix = None else: dll_prefix = "lib" @@ -209,11 +215,11 @@ class Tester(TestCmd.TestCmd): def __init__(self, arguments=None, executable="bjam", match=TestCmd.match_exact, boost_build_path=None, translate_suffixes=True, pass_toolset=True, use_test_config=True, - ignore_toolset_requirements=False, workdir="", pass_d0=True, + ignore_toolset_requirements=False, workdir="", pass_d0=False, **keywords): assert arguments.__class__ is not str - self.original_workdir = os.getcwd() + self.original_workdir = os.path.dirname(__file__) if workdir and not os.path.isabs(workdir): raise ("Parameter workdir <%s> must point to an absolute " "directory: " % workdir) @@ -274,8 +280,9 @@ class Tester(TestCmd.TestCmd): # Find where jam_src is located. Try for the debug version if it is # lying around. - dirs = [os.path.join("..", "src", "engine", jam_build_dir + ".debug"), - os.path.join("..", "src", "engine", jam_build_dir)] + srcdir = os.path.join(os.path.dirname(__file__), "..", "src") + dirs = [os.path.join(srcdir, "engine", jam_build_dir + ".debug"), + os.path.join(srcdir, "engine", jam_build_dir)] for d in dirs: if os.path.exists(d): jam_build_dir = d @@ -289,7 +296,8 @@ class Tester(TestCmd.TestCmd): verbosity = [] if "--verbose" in sys.argv: keywords["verbose"] = True - verbosity = ["-d+2"] + verbosity = ["-d2"] + self.verbosity = verbosity if boost_build_path is None: boost_build_path = self.original_workdir + "/.." @@ -300,8 +308,6 @@ class Tester(TestCmd.TestCmd): else: program_list.append(os.path.join(jam_build_dir, executable)) program_list.append('-sBOOST_BUILD_PATH="' + boost_build_path + '"') - if verbosity: - program_list += verbosity if arguments: program_list += arguments @@ -320,6 +326,12 @@ class Tester(TestCmd.TestCmd): # this case. pass + def set_toolset(self, toolset, target_os=default_os): + self.toolset = toolset + self.pass_toolset = True + prepare_prefixes_and_suffixes(toolset, target_os) + + # # Methods that change the working directory's content. # @@ -426,6 +438,7 @@ class Tester(TestCmd.TestCmd): return self.previous_tree, dummy = tree.build_tree(self.workdir) + self.wait_for_time_change_since_last_build() if match is None: match = self.match @@ -444,6 +457,8 @@ class Tester(TestCmd.TestCmd): kw["program"] += self.program if extra_args: kw["program"] += extra_args + if stdout is None and not any(a.startswith("-d") for a in kw["program"]): + kw["program"] += self.verbosity if pass_toolset: kw["program"].append("toolset=" + self.toolset) if use_test_config: @@ -707,6 +722,7 @@ class Tester(TestCmd.TestCmd): self.ignore("*.rsp") # Response files. self.ignore("*.tds") # Borland debug symbols. self.ignore("*.manifest") # MSVC DLL manifests. + self.ignore("bin/standalone/msvc/*/msvc-setup.bat") # Debug builds of bjam built with gcc produce this profiling data. self.ignore("gmon.out") @@ -757,8 +773,8 @@ class Tester(TestCmd.TestCmd): matched = reduce( lambda x, y: x and reduce( lambda a, b: a and b, - y), - matched) + y, True), + matched, True) if not matched: print "Expected:\n" @@ -856,6 +872,22 @@ class Tester(TestCmd.TestCmd): """ self.__wait_for_time_change(path, touch, last_build_time=False) + def wait_for_time_change_since_last_build(self): + """ + Wait for newly assigned file system modification timestamps to + become large enough for the timestamp difference to be + correctly recognized by the Python based testing framework. + Does not care about Jam's timestamp resolution, since we + only need this to detect touched files. + """ + if self.last_build_timestamp: + timestamp_file = "timestamp-3df2f2317e15e4a9" + open(timestamp_file, "wb").close() + self.__wait_for_time_change_impl(timestamp_file, + self.last_build_timestamp, + self.__python_timestamp_resolution(timestamp_file, 0), 0) + os.unlink(timestamp_file) + def __build_timestamp_resolution(self): """ Returns the minimum path modification timestamp resolution supported @@ -1103,7 +1135,12 @@ class Tester(TestCmd.TestCmd): resolution = self.__python_timestamp_resolution(path, build_resolution) assert resolution >= build_resolution + self.__wait_for_time_change_impl(path, start_time, resolution, build_resolution) + if not touch: + os.utime(path, (stats_orig.st_atime, stats_orig.st_mtime)) + + def __wait_for_time_change_impl(self, path, start_time, resolution, build_resolution): # Implementation notes: # * Theoretically time.sleep() API might get interrupted too soon # (never actually encountered). @@ -1160,9 +1197,6 @@ class Tester(TestCmd.TestCmd): break _sleep(max(0.01, start_time - c)) - if not touch: - os.utime(path, (stats_orig.st_atime, stats_orig.st_mtime)) - class List: def __init__(self, s=""): diff --git a/tools/build/test/Jamfile.jam b/tools/build/test/Jamfile.jam new file mode 100644 index 0000000000..7ec0bf3036 --- /dev/null +++ b/tools/build/test/Jamfile.jam @@ -0,0 +1,29 @@ +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import python ; +import testing ; + +if ! [ python.configured ] +{ + using python ; +} + +# Not quite perfect, but good enough for most purposes +local test-files = [ glob *.py ] ; + +local boost-build-files = [ glob + ../src/tools/*.jam + ../src/tools/*/*.jam + ../src/build/*.jam + ../src/util/*.jam + ../src/kernel/*.jam + ../src/options/*.jam + ../src/*.jam ] ; + +testing.make-test run-pyd : test_all.py : + $(test-files) + $(boost-build-files) + ; diff --git a/tools/build/test/MockToolset.py b/tools/build/test/MockToolset.py index 741959e50e..5d396fa026 100755 --- a/tools/build/test/MockToolset.py +++ b/tools/build/test/MockToolset.py @@ -18,6 +18,7 @@ parser.add_option('-o', dest="output_file") parser.add_option('-x', dest="language") parser.add_option('-c', dest="compile", action="store_true") parser.add_option('-I', dest="includes", action="append") +parser.add_option('-D', dest="defines", action="append") parser.add_option('-L', dest="library_path", action="append") parser.add_option('--dll', dest="dll", action="store_true") parser.add_option('--archive', dest="archive", action="store_true") @@ -34,6 +35,8 @@ class MockInfo(object): def source_file(self, name, pattern): self.files[name] = pattern def action(self, command, status=0): + if isinstance(command, str): + command = command.split() self.commands.append((command, status)) def check(self, command): print "Testing command", command @@ -41,7 +44,7 @@ class MockInfo(object): if self.matches(raw, command): return status def matches(self, raw, command): - (expected_options, expected_args) = parser.parse_args(raw.split()) + (expected_options, expected_args) = parser.parse_args(raw) options = command[0] input_files = list(command[1]) if self.verbose: @@ -101,6 +104,16 @@ class MockInfo(object): " != ", map(adjust_path, expected_options.includes) return False + if options.defines is None: + options.defines = [] + if expected_options.defines is None: + expected_options.defines = [] + if options.defines != expected_options.defines: + if self.verbose: + print " Failed to match -I ", options.defines, \ + " != ", expected_options.defines + return False + if options.library_path is None: options.library_path = [] if expected_options.library_path is None: @@ -203,16 +216,18 @@ generators.register-linker mock.link : LIB OBJ : EXE : mock ; generators.register-linker mock.link.dll : LIB OBJ : SHARED_LIB : mock ; generators.register-archiver mock.archive : OBJ : STATIC_LIB : mock ; -toolset.flags mock.compile INCLUDES ; +toolset.flags mock.compile OPTIONS shared : -fPIC ; +toolset.flags mock.compile INCLUDES : ; +toolset.flags mock.compile DEFINES : ; actions compile.c { - $(.config-cmd) mock.py -c -x c -I"$(INCLUDES)" "$(>)" -o "$(<)" + $(.config-cmd) mock.py -c -x c -I"$(INCLUDES)" -D"$(DEFINES)" "$(>)" -o "$(<)" } actions compile.c++ { - $(.config-cmd) mock.py -c -x c++ -I"$(INCLUDES)" "$(>)" -o "$(<)" + $(.config-cmd) mock.py -c -x c++ -I"$(INCLUDES)" -D"$(DEFINES)" "$(>)" -o "$(<)" } toolset.flags mock.link USER_OPTIONS ; diff --git a/tools/build/test/TestToolset.py b/tools/build/test/TestToolset.py new file mode 100644 index 0000000000..92408d38f5 --- /dev/null +++ b/tools/build/test/TestToolset.py @@ -0,0 +1,121 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates a toolset using a mock of the compiler + +import BoostBuild +import os +import re +import sys + +renames = {"debug": "variant=debug", "release": "variant=release"} + +def set_default_target_os(os): + global removed + global default_target_os + default_target_os = os + removed = set() + removed.add("target-os=" + default_target_os) + +def adjust_property(property): + global renames + if property in renames: + return renames[property] + else: + return property + +def adjust_properties(properties): + global removed + return [adjust_property(p) for p in properties if p not in removed] + +def has_property(name, properties): + return name in [re.sub("=.*", "", p) for p in properties] + +def get_property(name, properties): + for m in [re.match("(.*)=(.*)", p) for p in properties]: + if m and m.group(1) == name: + return m.group(2) + +def get_target_os(properties): + return get_property("target-os", properties) or default_target_os + +def expand_properties(properties): + result = properties[:] + if not has_property("variant", properties): + result += ["variant=debug"] + if not has_property("threading", properties): + result += ["threading=single"] + if not has_property("exception-handling", properties): + result += ["exception-handling=on"] + if not has_property("link", properties): + result += ["link=shared"] + if not has_property("rtti", properties): + result += ["rtti=on"] + if not has_property("runtime-link", properties): + result += ["runtime-link=shared"] + if not has_property("strip", properties): + result += ["strip=off"] + if not has_property("target-os", properties): + result += ["target-os=" + default_target_os] + return result + +def compute_path(properties, target_type): + path = "" + if "variant=release" in properties: + path += "/release" + else: + path += "/debug" + if has_property("address-model", properties): + path += "/address-model-" + get_property("address-model", properties) + if has_property("architecture", properties): + path += "/architecture-" + get_property("architecture", properties) + if "cxxstd=latest" in properties: + path += "/cxxstd-latest-iso" + if "exception-handling=off" in properties: + path += "/exception-handling-off" + if "link=static" in properties: + path += "/link-static" + if "rtti=off" in properties: + path += "/rtti-off" + if "runtime-link=static" in properties and target_type in ["exe"]: + path += "/runtime-link-static" + if "strip=on" in properties and target_type in ["dll", "exe", "obj2"]: + path += "/strip-on" + if get_target_os(properties) != default_target_os: + path += "/target-os-" + get_target_os(properties) + if "threading=multi" in properties: + path += "/threading-multi" + return path + +def test_toolset(toolset, version, property_sets): + t = BoostBuild.Tester() + + t.set_tree("toolset-mock") + + # Build necessary tools + t.run_build_system(["-sPYTHON_CMD=%s" % sys.executable], subdir="src") + set_default_target_os(t.read("src/bin/target-os.txt").strip()) + + for properties in property_sets: + t.set_toolset(toolset + "-" + version, get_target_os(properties)) + properties = adjust_properties(properties) + def path(t): + return toolset.split("-")[0] + "-*" + version + compute_path(properties, t) + os.environ["B2_PROPERTIES"] = " ".join(expand_properties(properties)) + t.run_build_system(["--user-config="] + properties) + t.expect_addition("bin/%s/lib.obj" % (path("obj"))) + if "link=static" not in properties: + t.expect_addition("bin/%s/l1.dll" % (path("dll"))) + else: + t.expect_addition("bin/%s/l1.lib" % (path("lib"))) + t.expect_addition("bin/%s/main.obj" % (path("obj2"))) + t.expect_addition("bin/%s/test.exe" % (path("exe"))) + t.expect_nothing_more() + t.rm("bin") + + t.cleanup() diff --git a/tools/build/test/alias.py b/tools/build/test/alias.py index 53371f4e65..132e4c3905 100644 --- a/tools/build/test/alias.py +++ b/tools/build/test/alias.py @@ -99,9 +99,7 @@ int main() {} # ############################################################################### -# We do not pass the '-d0' option to Boost Build here to get more detailed -# information in case of failure. -t = BoostBuild.Tester(pass_d0=False, use_test_config=False) +t = BoostBuild.Tester(use_test_config=False) test_alias_rule(t) test_alias_source_usage_requirements(t) diff --git a/tools/build/test/alternatives.py b/tools/build/test/alternatives.py index e8f9220ff1..7a52427d20 100644 --- a/tools/build/test/alternatives.py +++ b/tools/build/test/alternatives.py @@ -88,7 +88,7 @@ exe a : a_empty.cpp ; exe a : a.cpp ; """) t.run_build_system(["--no-error-backtrace"], status=None) -t.fail_test(string.find(t.stdout(), "No best alternative") == -1) +t.expect_output_lines("error: No best alternative for ./a") # Another ambiguity test: two matches properties in one alternative are neither # better nor worse than a single one in another alternative. @@ -98,7 +98,8 @@ exe a : a.cpp : on ; """) t.run_build_system(["--no-error-backtrace"], status=None) -t.fail_test(string.find(t.stdout(), "No best alternative") == -1) +t.expect_output_lines("error: No best alternative for ./a") +t.rm("bin") # Test that we can have alternative without sources. t.write("jamfile.jam", """\ @@ -108,7 +109,21 @@ feature.extend os : MAGIC ; alias specific-sources : b.cpp : MAGIC ; exe a : a.cpp specific-sources ; """) -t.rm("bin") t.run_build_system() +t.expect_addition("bin/$toolset/debug*/a.exe") +t.rm("bin") + +# Test that subfeatures are expanded in alternatives +# and that unknown subfeatures fail to match instead of +# causing errors. +t.write("jamfile.jam", """\ +import feature : feature subfeature ; +feature X : off on : propagated ; +subfeature X on : version : 1 : propagated ; +exe a : a.cpp : on-1 ; +exe a : a_empty.cpp ; +exe a : a_empty.cpp : on-2 ; +""") +t.run_build_system(["X=on-1"]) t.cleanup() diff --git a/tools/build/test/build_hooks.py b/tools/build/test/build_hooks.py new file mode 100644 index 0000000000..9b8d37af13 --- /dev/null +++ b/tools/build/test/build_hooks.py @@ -0,0 +1,39 @@ +#!/usr/bin/python + +# Copyright (C) Vladimir Prus 2006. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests add-pre-build-hook and add-post-build-hook + +import BoostBuild + +t = BoostBuild.Tester() + +t.write("Jamroot.jam", """ +import build-system ; +build-system.add-pre-build-hook pre-build ; +build-system.add-post-build-hook post-build ; + +rule pre-build ( ) +{ + ECHO "in" pre-build hook ; +} + +rule post-build ( okay ? ) +{ + ECHO "in" post-build hook $(okay) ; +} + +message show : building main targets ; +""") + +t.run_build_system(stdout="""\ +building main targets +in pre-build hook +...found 1 target... +in post-build hook ok +""") + +t.cleanup() diff --git a/tools/build/test/builtin_glob.py b/tools/build/test/builtin_glob.py index 6f55a4d9c1..b68e7eebee 100755 --- a/tools/build/test/builtin_glob.py +++ b/tools/build/test/builtin_glob.py @@ -41,8 +41,8 @@ test_glob([], "[ GLOB . : f*am ]", ["./file.jam"]) test_glob([], "[ GLOB . : fi?e.?am ]", ["./file.jam"]) test_glob([], "[ GLOB . : fi?.jam ]", []) # [abc-fh-j] matches a set of characters -test_glob([], "[ GLOB . : [f][i][l][e].jam ]", ["./file.jam"]) -test_glob([], "[ GLOB . : [fghau][^usdrwe][k-o][^f-s].jam ]", ["./file.jam"]) +test_glob([], '[ GLOB . : "[f][i][l][e].jam" ]', ["./file.jam"]) +test_glob([], '[ GLOB . : "[fghau][^usdrwe][k-o][^f-s].jam" ]', ["./file.jam"]) # \x matches x test_glob([], "[ GLOB . : \\f\\i\\l\\e.jam ]", ["./file.jam"]) diff --git a/tools/build/test/builtin_glob_archive.py b/tools/build/test/builtin_glob_archive.py index 847b14ac70..92faa486bc 100644 --- a/tools/build/test/builtin_glob_archive.py +++ b/tools/build/test/builtin_glob_archive.py @@ -120,7 +120,7 @@ test_glob_archive([archive1], "[ GLOB_ARCHIVE $archive1 : b.* ]", ["$archive1(b$obj)"]) ## glob wildcards:2 -test_glob_archive([archive1], "[ GLOB_ARCHIVE $archive1 : \\b?match[\.]* ]", +test_glob_archive([archive1], '[ GLOB_ARCHIVE $archive1 : "\\b?match[\.]*" ]', ["$archive1(b_match$obj)"]) ## glob wildcards:3 diff --git a/tools/build/test/command_line_properties.py b/tools/build/test/command_line_properties.py new file mode 100644 index 0000000000..ebb186ea45 --- /dev/null +++ b/tools/build/test/command_line_properties.py @@ -0,0 +1,166 @@ +#!/usr/bin/python + +import BoostBuild + +def test_basic(): + '''Tests that feature=value works''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : 1 2 ; + make output.txt : : @run ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=2']) + t.expect_content("bin/*/output.txt", "2") + t.cleanup() + +def test_implicit(): + '''Tests that implicit features can be named without a feature''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : v1 v2 : implicit ; + make output.txt : : @run ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['v2']) + t.expect_content("bin/*/output.txt", "v2") + t.cleanup() + +def test_optional(): + '''Tests that feature= works for optional features''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : 1 2 : optional ; + make output.txt : : @run ; + flags run OPTIONS ; + actions run { echo b $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=']) + t.expect_content("bin/*/output.txt", "b") + t.cleanup() + +def test_free(): + '''Free features named on the command line apply to all targets + everywhere. Free features can contain any characters, even those + that have a special meaning.''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : : free ; + make output1.txt : : @run : output2.txt ; + make output2.txt : : @run ; + explicit output2.txt ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=x,/:-']) + t.expect_content("bin*/output1.txt", "x,/:-") + t.expect_content("bin*/output2.txt", "x,/:-") + t.cleanup() + +def test_subfeature(): + '''Subfeatures should be expressed as feature=value-subvalue''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature subfeature ; + import toolset : flags ; + feature f1 : 1 2 ; + subfeature f1 2 : sub : x y ; + make output.txt : : @run ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=2-y']) + t.expect_content("bin/*/output.txt", "y") + t.cleanup() + +def test_multiple_values(): + '''Multiple values of a feature can be given in a comma-separated list''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : 1 2 3 ; + make output.txt : : @run ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=2,3']) + t.expect_content("bin*/f1-2*/output.txt", "2") + t.expect_content("bin*/f1-3*/output.txt", "3") + t.cleanup() + +def test_multiple_properties(): + '''Multiple properties can be grouped with /''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + feature f1 : 1 2 ; + feature f2 : 3 4 ; + make output.txt : : @run ; + flags run OPTIONS ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=2/f2=4']) + t.expect_content("bin/*/output.txt", "2 4") + t.cleanup() + +def test_cross_product(): + '''If multiple properties are specified on the command line + we expand to every possible maximum set of non-conflicting features. + This test should be run after testing individual components in + isolation.''' + t = BoostBuild.Tester() + t.write('Jamroot.jam', ''' + import feature : feature ; + import toolset : flags ; + # Make features symmetric to make the paths easier to distingush + feature f1 : 11 12 13 14 15 : symmetric ; + feature f2 : 21 22 23 : symmetric ; + feature f3 : v1 v2 v3 v4 : implicit symmetric ; + feature f4 : : free ; + make output.txt : : @run ; + flags run OPTIONS ; + flags run OPTIONS ; + flags run OPTIONS ; + flags run OPTIONS ; + actions run { echo $(OPTIONS) > $(<) } + ''') + t.run_build_system(['f1=12,13/f2=22', 'v2', 'v3', 'f1=14', 'f2=23', + 'f4=xxx', 'f4=yyy', 'v4/f1=15/f4=zzz']) + t.expect_content("bin*/v2*/f1-12/f2-22*/output.txt", "12 22 v2 xxx yyy") + t.expect_addition("bin*/v2*/f1-12/f2-22*/output.txt") + t.expect_content("bin*/v2*/f1-13/f2-22*/output.txt", "13 22 v2 xxx yyy") + t.expect_addition("bin*/v2*/f1-13/f2-22*/output.txt") + t.expect_content("bin*/v2*/f1-14/f2-23*/output.txt", "14 23 v2 xxx yyy") + t.expect_addition("bin*/v2*/f1-14/f2-23*/output.txt") + t.expect_content("bin*/v3*/f1-12/f2-22*/output.txt", "12 22 v3 xxx yyy") + t.expect_addition("bin*/v3*/f1-12/f2-22*/output.txt") + t.expect_content("bin*/v3*/f1-13/f2-22*/output.txt", "13 22 v3 xxx yyy") + t.expect_addition("bin*/v3*/f1-13/f2-22*/output.txt") + t.expect_content("bin*/v3*/f1-14/f2-23*/output.txt", "14 23 v3 xxx yyy") + t.expect_addition("bin*/v3*/f1-14/f2-23*/output.txt") + t.expect_content("bin*/v4*/f1-15/f2-23*/output.txt", "15 23 v4 xxx yyy zzz") + t.expect_addition("bin*/v4*/f1-15/f2-23*/output.txt") + t.expect_nothing_more() + t.cleanup() + +test_basic() +test_implicit() +test_optional() +test_free() +test_subfeature() +test_multiple_values() +test_multiple_properties() +test_cross_product() diff --git a/tools/build/test/conditionals3.py b/tools/build/test/conditionals3.py index 67c04c4293..feffe4900f 100644 --- a/tools/build/test/conditionals3.py +++ b/tools/build/test/conditionals3.py @@ -12,7 +12,7 @@ import BoostBuild t = BoostBuild.Tester(use_test_config=False) t.write("jamroot.jam", """ -exe hello : hello.cpp : debug:CLASS=Foo::Bar ; +exe hello : hello.cpp : debug:"CLASS=Foo::Bar" ; """) t.write("hello.cpp", """ diff --git a/tools/build/test/conditionals_multiple.py b/tools/build/test/conditionals_multiple.py index dd11690811..cb0cfa8c5d 100755 --- a/tools/build/test/conditionals_multiple.py +++ b/tools/build/test/conditionals_multiple.py @@ -165,7 +165,7 @@ feature.feature ccc : 0 1 : incidental ; rule buildRule ( name : targets ? : properties * ) { local ttt = [ feature.get-values toolset : $(properties) ] ; - local vvv = [ feature.get-values toolset-testToolset:version : $(properties) ] ; + local vvv = [ feature.get-values "toolset-testToolset:version" : $(properties) ] ; local aaa = [ feature.get-values aaa : $(properties) ] ; local bbb = [ feature.get-values bbb : $(properties) ] ; local ccc = [ feature.get-values ccc : $(properties) ] ; diff --git a/tools/build/test/configuration.py b/tools/build/test/configuration.py index 724ecd7c93..0a9df6a6c6 100755 --- a/tools/build/test/configuration.py +++ b/tools/build/test/configuration.py @@ -8,6 +8,7 @@ # Test Boost Build configuration file handling. import BoostBuild +import TestCmd import os import os.path @@ -316,6 +317,71 @@ for x in $(names) t.cleanup() +def test_site_config(): + # Ignore user-config, just in case it depends on the user's site-config.jam + t = BoostBuild.Tester(["--user-config="], use_test_config=False, + pass_toolset=0) + # We can immediately exit after we finish loading the config files + t.write("Jamroot", "EXIT Done : 0 ;") + t.write("my-site-config.jam", "ECHO Loaded my-site-config ;") + + t.run_build_system(["--site-config=my-site-config.jam"], + stdout="Loaded my-site-config\nDone\n") + + t.run_build_system(["--ignore-site-config", "--debug-configuration"]) + t.expect_output_lines("""\ +notice: Site configuration files will be ignored due to the +notice: --ignore-site-config command-line option.""") + + t.run_build_system(["--site-config=", "--debug-configuration"]) + t.expect_output_lines("""\ +notice: Site configuration file loading explicitly disabled.""") + + t.cleanup() + +def test_global_config(): + t = BoostBuild.Tester(use_test_config=False, pass_toolset=0) + t.write("my-config.jam", "ECHO Loading my-config ;") + t.write("Jamroot", "EXIT Done : 0 ;") + t.write("project-config.jam", "ECHO bad ;") + t.run_build_system(["--config=my-config.jam", "--debug-configuration"], + match=TestCmd.match_re, stdout= +r"""notice: found boost-build\.jam at .* +notice: loading Boost\.Build from .* +notice: Searching '.*' for all-config configuration file 'my-config\.jam'\. +notice: Loading all-config configuration file 'my-config\.jam' from '.*'\. +Loading my-config +notice: Regular configuration files will be ignored due +notice: to the global configuration being loaded\. +Done +""") + t.run_build_system(["--config=", "--debug-configuration"], + match=TestCmd.match_re, stdout= +r"""notice: found boost-build\.jam at .* +notice: loading Boost\.Build from .* +notice: Configuration file loading explicitly disabled. +Done +""") + t.cleanup() + +def test_project_config(): + t = BoostBuild.Tester(["--user-config=", "--site-config="], + use_test_config=False, pass_toolset=False) + t.write("Jamroot", "EXIT Done : 0 ;") + t.write("project-config.jam", "ECHO Loading Root ;") + t.write("my-project-config.jam", "ECHO Loading explicit ;") + t.write("sub/project-config.jam", "ECHO Loading subdir ;") + t.write("sub/Jamfile", "") + + t.run_build_system(stdout="Loading Root\nDone\n") + t.run_build_system(subdir="sub", stdout="Loading subdir\nDone\n") + t.rm("sub/project-config.jam") + t.run_build_system(subdir="sub", stdout="Loading Root\nDone\n") + t.run_build_system(["--project-config=my-project-config.jam"], + stdout="Loading explicit\nDone\n") + + t.cleanup() + ############################################################################### # # main() @@ -326,3 +392,6 @@ for x in $(names) canSetEmptyEnvironmentVariable = _canSetEmptyEnvironmentVariable() test_user_configuration() +test_site_config() +test_global_config() +test_project_config() diff --git a/tools/build/test/configure.py b/tools/build/test/configure.py new file mode 100644 index 0000000000..85fbbbc869 --- /dev/null +++ b/tools/build/test/configure.py @@ -0,0 +1,219 @@ +#!/usr/bin/python + +# Copyright 2017 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests configure.check-target-builds and friends + +import BoostBuild + +def test_check_target_builds(): + t = BoostBuild.Tester(use_test_config=0) + t.write("Jamroot", """ +import configure ; +obj pass : pass.cpp ; +obj fail : fail.cpp ; +explicit pass fail ; +obj foo : foo.cpp : + [ configure.check-target-builds pass : PASS : FAIL ] ; +obj bar : foo.cpp : + [ configure.check-target-builds fail : FAIL : PASS ] ; +""") + t.write("pass.cpp", "void f() {}\n") + t.write("fail.cpp", "#error fail.cpp\n") + t.write("foo.cpp", """ +#ifndef PASS +#error PASS not defined +#endif +#ifdef FAIL +#error FAIL is defined +#endif +""") + t.run_build_system() + t.expect_output_lines([ + " - pass builds : yes", + " - fail builds : no"]) + t.expect_addition("bin/$toolset/debug*/pass.obj") + t.expect_addition("bin/$toolset/debug*/foo.obj") + t.expect_addition("bin/$toolset/debug*/bar.obj") + t.expect_nothing_more() + + # An up-to-date build should use the cache + t.run_build_system() + t.expect_output_lines([ + " - pass builds : yes (cached)", + " - fail builds : no (cached)"]) + t.expect_nothing_more() + + # -a should re-run everything, including configuration checks + t.run_build_system(["-a"]) + t.expect_output_lines([ + " - pass builds : yes", + " - fail builds : no"]) + t.expect_touch("bin/$toolset/debug*/pass.obj") + t.expect_touch("bin/$toolset/debug*/foo.obj") + t.expect_touch("bin/$toolset/debug*/bar.obj") + t.expect_nothing_more() + + # --reconfigure should re-run configuration checks only + t.run_build_system(["--reconfigure"]) + t.expect_output_lines([ + " - pass builds : yes", + " - fail builds : no"]) + t.expect_touch("bin/$toolset/debug*/pass.obj") + t.expect_nothing_more() + + # -a -n should not rebuild configuration checks + t.run_build_system(["-a", "-n"]) + t.expect_output_lines([ + " - pass builds : yes (cached)", + " - fail builds : no (cached)"]) + t.expect_nothing_more() + + # --clean-all should clear all configuration checks + t.run_build_system(["--clean-all"]) + t.expect_output_lines([ + " - pass builds : yes (cached)", + " - fail builds : no (cached)"]) + t.expect_removal("bin/$toolset/debug*/pass.obj") + t.expect_removal("bin/$toolset/debug*/foo.obj") + t.expect_removal("bin/$toolset/debug*/bar.obj") + t.expect_nothing_more() + + # If configuration checks are absent, then --clean-all + # should create them and then delete them again. This + # currently fails because clean cannot remove targets + # that were created in the same build. + #t.run_build_system(["--clean-all"]) + #t.expect_output_lines([ + # " - pass builds : yes", + # " - fail builds : no"]) + #t.expect_nothing_more() + + # Just verify that we're actually in the initial + # state here. + t.run_build_system() + t.expect_output_lines([ + " - pass builds : yes", + " - fail builds : no"]) + t.expect_addition("bin/$toolset/debug*/pass.obj") + t.expect_addition("bin/$toolset/debug*/foo.obj") + t.expect_addition("bin/$toolset/debug*/bar.obj") + t.expect_nothing_more() + + t.cleanup() + +def test_choose(): + t = BoostBuild.Tester(use_test_config=0) + t.write("Jamroot", """ +import configure ; +obj pass : pass.cpp ; +obj fail : fail.cpp ; +explicit pass fail ; +obj foo : foo.cpp : + [ configure.choose "which one?" : fail FAIL : pass PASS ] ; +""") + t.write("pass.cpp", "void f() {}\n") + t.write("fail.cpp", "#error fail.cpp\n") + t.write("foo.cpp", """ +#ifndef PASS +#error PASS not defined +#endif +#ifdef FAIL +#error FAIL is defined +#endif +""") + t.run_build_system() + t.expect_output_lines([ + " - which one? : pass"]) + t.expect_addition("bin/$toolset/debug*/pass.obj") + t.expect_addition("bin/$toolset/debug*/foo.obj") + t.expect_nothing_more() + + # An up-to-date build should use the cache + t.run_build_system() + t.expect_output_lines([ + " - which one? : pass (cached)"]) + t.expect_nothing_more() + + # -a should re-run everything, including configuration checks + t.run_build_system(["-a"]) + t.expect_output_lines([ + " - which one? : pass"]) + t.expect_touch("bin/$toolset/debug*/pass.obj") + t.expect_touch("bin/$toolset/debug*/foo.obj") + t.expect_nothing_more() + + # --reconfigure should re-run configuration checks only + t.run_build_system(["--reconfigure"]) + t.expect_output_lines([ + " - which one? : pass"]) + t.expect_touch("bin/$toolset/debug*/pass.obj") + t.expect_nothing_more() + + # -a -n should not rebuild configuration checks + t.run_build_system(["-a", "-n"]) + t.expect_output_lines([ + " - which one? : pass (cached)"]) + t.expect_nothing_more() + + # --clean-all should clear all configuration checks + t.run_build_system(["--clean-all"]) + t.expect_output_lines([ + " - which one? : pass (cached)"]) + t.expect_removal("bin/$toolset/debug*/pass.obj") + t.expect_removal("bin/$toolset/debug*/foo.obj") + t.expect_nothing_more() + + # If configuration checks are absent, then --clean-all + # should create them and then delete them again. This + # currently fails because clean cannot remove targets + # that were created in the same build. + #t.run_build_system(["--clean-all"]) + #t.expect_output_lines([ + # " - which one? : pass"]) + #t.expect_nothing_more() + + # Just verify that we're actually in the initial + # state here. + t.run_build_system() + t.expect_output_lines([ + " - which one? : pass"]) + t.expect_addition("bin/$toolset/debug*/pass.obj") + t.expect_addition("bin/$toolset/debug*/foo.obj") + t.expect_nothing_more() + + t.cleanup() + +def test_choose_none(): + """Tests choose when none of the alternatives match.""" + t = BoostBuild.Tester(use_test_config=0) + t.write("Jamroot", """ +import configure ; +obj fail : fail.cpp ; +explicit pass fail ; +obj foo : foo.cpp : + [ configure.choose "which one?" : fail FAIL ] ; +""") + t.write("fail.cpp", "#error fail.cpp\n") + t.write("foo.cpp", """ +#ifdef FAIL +#error FAIL is defined +#endif +""") + t.run_build_system() + t.expect_output_lines([ + " - which one? : none"]) + + # An up-to-date build should use the cache + t.run_build_system() + t.expect_output_lines([ + " - which one? : none (cached)"]) + t.expect_nothing_more() + t.cleanup() + +test_check_target_builds() +test_choose() +test_choose_none() diff --git a/tools/build/test/core_action_output.py b/tools/build/test/core_action_output.py index b26f0e0bd8..7575198637 100755 --- a/tools/build/test/core_action_output.py +++ b/tools/build/test/core_action_output.py @@ -9,7 +9,7 @@ import BoostBuild -t = BoostBuild.Tester(["-d1"], pass_d0=False, pass_toolset=False) +t = BoostBuild.Tester(["-d1"], pass_toolset=False) t.write("file.jam", """\ prefix = "echo \\"" ; @@ -24,7 +24,7 @@ actions go $(prefix)stdout$(suffix) $(prefix)stderr$(suffix) 1>&2 } -ECHO {{{ $(XXX) }}} ; +ECHO "{{{" $(XXX) "}}}" ; ALWAYS all ; go all ; """) diff --git a/tools/build/test/core_arguments.py b/tools/build/test/core_arguments.py index a6e886ff63..7f12782143 100755 --- a/tools/build/test/core_arguments.py +++ b/tools/build/test/core_arguments.py @@ -30,7 +30,7 @@ def test_varargs(t, *args, **kwargs): test(t, "varargs", *args, **kwargs) -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(pass_toolset=0) t.write("echo_args.jam", """\ NOCARE all ; diff --git a/tools/build/test/core_at_file.py b/tools/build/test/core_at_file.py index 1bcdcab559..50fa51220f 100755 --- a/tools/build/test/core_at_file.py +++ b/tools/build/test/core_at_file.py @@ -13,7 +13,7 @@ t = BoostBuild.Tester(["-ffile.jam"], pass_toolset=0) t.write("file.jam", """\ name = n1 n2 ; contents = M1 M2 ; -EXIT file: "@(o$(name) .txt:E= test -D$(contents))" : 0 ; +EXIT "file:" "@(o$(name) .txt:E= test -D$(contents))" : 0 ; """) t.run_build_system() diff --git a/tools/build/test/core_bindrule.py b/tools/build/test/core_bindrule.py index 6ae4ab34c4..f97a31f56f 100755 --- a/tools/build/test/core_bindrule.py +++ b/tools/build/test/core_bindrule.py @@ -8,7 +8,7 @@ import BoostBuild import os -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(["-d1"], pass_toolset=0) t.write("subdir1/file-to-bind", "# This file intentionally left blank") @@ -30,7 +30,7 @@ BINDRULE = bind-rule ; rule bind-rule ( target : path ) { - ECHO found: $(target) at $(path) ; + ECHO "found:" $(target) at $(path) ; } DEPENDS all : fake-target ; diff --git a/tools/build/test/core_d12.py b/tools/build/test/core_d12.py index 5488973d29..370fc4bf12 100644 --- a/tools/build/test/core_d12.py +++ b/tools/build/test/core_d12.py @@ -9,7 +9,7 @@ import BoostBuild -t = BoostBuild.Tester(["-ffile.jam"], pass_d0=False, pass_toolset=0) +t = BoostBuild.Tester(["-ffile.jam"], pass_toolset=0) t.write("file.jam", """\ actions a { } diff --git a/tools/build/test/core_fail_expected.py b/tools/build/test/core_fail_expected.py new file mode 100644 index 0000000000..0865a0b7a0 --- /dev/null +++ b/tools/build/test/core_fail_expected.py @@ -0,0 +1,139 @@ +#!/usr/bin/python + +# Copyright 2017 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild + +def test_basic(): + t = BoostBuild.Tester(pass_toolset=0) + + t.write("file.jam", """\ + actions fail + { + invalid-dd0eeb5899734622 + } + + FAIL_EXPECTED t1 ; + fail t1 ; + + UPDATE t1 ; + """) + + t.run_build_system(["-ffile.jam"]) + t.expect_output_lines("...failed*", False) + t.expect_nothing_more() + + t.cleanup() + +def test_error(): + t = BoostBuild.Tester(pass_toolset=0) + + t.write("file.jam", """\ + actions pass + { + echo okay >$(<) + } + + FAIL_EXPECTED t1 ; + pass t1 ; + + UPDATE t1 ; + """) + + t.run_build_system(["-ffile.jam"], status=1) + t.expect_output_lines("...failed pass t1...") + t.expect_nothing_more() + + t.cleanup() + +def test_multiple_actions(): + """FAIL_EXPECTED targets are considered to pass if the first + updating action fails. Further actions will be skipped.""" + t = BoostBuild.Tester(pass_toolset=0) + + t.write("file.jam", """\ + actions fail + { + invalid-dd0eeb5899734622 + } + + actions pass + { + echo okay >$(<) + } + + FAIL_EXPECTED t1 ; + fail t1 ; + pass t1 ; + + UPDATE t1 ; + """) + + t.run_build_system(["-ffile.jam", "-d1"]) + t.expect_output_lines("...failed*", False) + t.expect_output_lines("pass t1", False) + t.expect_nothing_more() + + t.cleanup() + +def test_quitquick(): + """Tests that FAIL_EXPECTED targets do not cause early exit + on failure.""" + t = BoostBuild.Tester(pass_toolset=0) + + t.write("file.jam", """\ + actions fail + { + invalid-dd0eeb5899734622 + } + + actions pass + { + echo okay >$(<) + } + + FAIL_EXPECTED t1 ; + fail t1 ; + + pass t2 ; + + UPDATE t1 t2 ; + """) + + t.run_build_system(["-ffile.jam", "-q", "-d1"]) + t.expect_output_lines("pass t2") + t.expect_addition("t2") + t.expect_nothing_more() + + t.cleanup() + +def test_quitquick_error(): + """FAIL_EXPECTED targets should cause early exit if they unexpectedly pass.""" + t = BoostBuild.Tester(pass_toolset=0) + + t.write("file.jam", """\ + actions pass + { + echo okay >$(<) + } + + FAIL_EXPECTED t1 ; + pass t1 ; + pass t2 ; + + UPDATE t1 t2 ; + """) + + t.run_build_system(["-ffile.jam", "-q", "-d1"], status=1) + t.expect_output_lines("pass t2", False) + t.expect_nothing_more() + + t.cleanup() + +test_basic() +test_error() +test_multiple_actions() +test_quitquick() +test_quitquick_error() diff --git a/tools/build/test/core_import_module.py b/tools/build/test/core_import_module.py index c5bbd3e638..5903dcd642 100644 --- a/tools/build/test/core_import_module.py +++ b/tools/build/test/core_import_module.py @@ -67,8 +67,7 @@ module c IMPORT_MODULE c : ; c.test ; -actions do-nothing { } -do-nothing all ; +EXIT : 0 ; """) t.run_build_system(["-fcode"], stdout="""\ @@ -77,6 +76,7 @@ R2 L1 A.L1 CTEST + """) t.cleanup() diff --git a/tools/build/test/core_jamshell.py b/tools/build/test/core_jamshell.py index 0344a5792d..5b14213c33 100644 --- a/tools/build/test/core_jamshell.py +++ b/tools/build/test/core_jamshell.py @@ -7,7 +7,7 @@ import BoostBuild import sys -t = BoostBuild.Tester(pass_toolset=False, pass_d0=False) +t = BoostBuild.Tester(pass_toolset=False) t.write("file.jam", """ actions run { diff --git a/tools/build/test/core_multifile_actions.py b/tools/build/test/core_multifile_actions.py index 50bfe83394..a9c7f4790c 100755 --- a/tools/build/test/core_multifile_actions.py +++ b/tools/build/test/core_multifile_actions.py @@ -20,7 +20,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(["-d1"], pass_toolset=0) t.write("file.jam", """ actions update diff --git a/tools/build/test/core_nt_cmd_line.py b/tools/build/test/core_nt_cmd_line.py index 579242d24b..064f86826a 100755 --- a/tools/build/test/core_nt_cmd_line.py +++ b/tools/build/test/core_nt_cmd_line.py @@ -49,7 +49,7 @@ def test_raw_empty(): # get an extra "\r" added in front of it on output. whitespace_out = whitespace_in.replace("\r\n", "\n").replace("\n", "\r\n") - t = BoostBuild.Tester(["-d2", "-d+4"], pass_d0=False, pass_toolset=0, + t = BoostBuild.Tester(["-d2", "-d+4"], pass_toolset=0, use_test_config=False) t.write("file.jam", """\ actions do_empty {%s} @@ -67,7 +67,7 @@ do_empty all ; def test_raw_nt(n=None, error=False): - t = BoostBuild.Tester(["-d1", "-d+4"], pass_d0=False, pass_toolset=0, + t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0, use_test_config=False) cmd_prefix = "%s -c \"print('XXX: " % executable @@ -135,7 +135,7 @@ do_echo all ; def test_raw_to_shell_fallback_nt(): - t = BoostBuild.Tester(["-d1", "-d+4"], pass_d0=False, pass_toolset=0, + t = BoostBuild.Tester(["-d1", "-d+4"], pass_toolset=0, use_test_config=False) cmd_prefix = '%s -c print(' % executable diff --git a/tools/build/test/core_option_d2.py b/tools/build/test/core_option_d2.py index bf809aa85c..8e6b05a455 100755 --- a/tools/build/test/core_option_d2.py +++ b/tools/build/test/core_option_d2.py @@ -7,7 +7,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions .a. diff --git a/tools/build/test/core_option_n.py b/tools/build/test/core_option_n.py index 4dab3bf99e..af3ee0c3eb 100755 --- a/tools/build/test/core_option_n.py +++ b/tools/build/test/core_option_n.py @@ -7,7 +7,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions .a. diff --git a/tools/build/test/core_parallel_actions.py b/tools/build/test/core_parallel_actions.py index 0d44149b74..4f1627c208 100755 --- a/tools/build/test/core_parallel_actions.py +++ b/tools/build/test/core_parallel_actions.py @@ -7,7 +7,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(["-d1"], pass_toolset=0) t.write("sleep.bat", """\ ::@timeout /T %1 /NOBREAK >nul diff --git a/tools/build/test/core_parallel_multifile_actions_1.py b/tools/build/test/core_parallel_multifile_actions_1.py index 8d9448e0c8..4b800a7887 100755 --- a/tools/build/test/core_parallel_multifile_actions_1.py +++ b/tools/build/test/core_parallel_multifile_actions_1.py @@ -17,7 +17,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(["-d1"], pass_toolset=0) t.write("sleep.bat", """\ ::@timeout /T %1 /NOBREAK >nul diff --git a/tools/build/test/core_parallel_multifile_actions_2.py b/tools/build/test/core_parallel_multifile_actions_2.py index ea4034af07..c49e923803 100755 --- a/tools/build/test/core_parallel_multifile_actions_2.py +++ b/tools/build/test/core_parallel_multifile_actions_2.py @@ -20,7 +20,7 @@ import BoostBuild -t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) +t = BoostBuild.Tester(pass_toolset=0) t.write("sleep.bat", """\ ::@timeout /T %1 /NOBREAK >nul diff --git a/tools/build/test/core_scanner.py b/tools/build/test/core_scanner.py new file mode 100644 index 0000000000..af078a00be --- /dev/null +++ b/tools/build/test/core_scanner.py @@ -0,0 +1,36 @@ +#!/usr/bin/python + +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests the parsing of tokens + +import BoostBuild + +t = BoostBuild.Tester(pass_toolset=0) + +t.write("file.jam", """\ +rule test1 ( args * ) +{ + EXIT $(args) : 0 ; +} + +test1 +a # a comment +# another comment +b +c #| a multiline comment |# d +#| another +multiline +comment +|# +e "#f" ; +""") + +t.run_build_system(["-ffile.jam"], stdout="""\ +a b c d e #f +""") + +t.cleanup() diff --git a/tools/build/test/core_typecheck.py b/tools/build/test/core_typecheck.py index 225ea7a4bf..de1bece16e 100644 --- a/tools/build/test/core_typecheck.py +++ b/tools/build/test/core_typecheck.py @@ -13,7 +13,7 @@ t = BoostBuild.Tester(["-ffile.jam"], pass_toolset=0) t.write("file.jam", """ module .typecheck { - rule [path] ( x ) + rule "[path]" ( x ) { if ! [ MATCH "^(::)" : $(x) ] { diff --git a/tools/build/test/core_update_now.py b/tools/build/test/core_update_now.py index 819309a73a..627594bf89 100755 --- a/tools/build/test/core_update_now.py +++ b/tools/build/test/core_update_now.py @@ -9,7 +9,7 @@ import os def basic(): - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions do-print @@ -39,7 +39,7 @@ updating target1 def ignore_minus_n(): - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions do-print @@ -72,7 +72,7 @@ updating target1 def failed_target(): - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions fail @@ -120,7 +120,7 @@ do-print target2 def missing_target(): - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions do-print @@ -155,7 +155,7 @@ def build_once(): effect. """ - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions do-print @@ -199,7 +199,7 @@ def return_status(): Make sure that UPDATE_NOW returns a failure status if the target failed in a previous call to UPDATE_NOW """ - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", """\ actions fail @@ -211,8 +211,8 @@ NOTFILE target1 ; ALWAYS target1 ; fail target1 ; -ECHO update1: [ UPDATE_NOW target1 ] ; -ECHO update2: [ UPDATE_NOW target1 ] ; +ECHO "update1:" [ UPDATE_NOW target1 ] ; +ECHO "update2:" [ UPDATE_NOW target1 ] ; DEPENDS all : target1 ; """) @@ -237,7 +237,7 @@ update2: def save_restore(): """Tests that ignore-minus-n and ignore-minus-q are local to the call to UPDATE_NOW""" - t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) + t = BoostBuild.Tester(pass_toolset=0) t.write("actions.jam", """\ rule fail diff --git a/tools/build/test/core_variables_in_actions.py b/tools/build/test/core_variables_in_actions.py index e3a7177e20..77834f4307 100755 --- a/tools/build/test/core_variables_in_actions.py +++ b/tools/build/test/core_variables_in_actions.py @@ -22,7 +22,7 @@ t.write("file.jam", """\ rule dummy ( i ) { local a = 1 2 3 ; - ECHO From rule: $(a)" seconds" ; + ECHO From "rule:" $(a)" seconds" ; a on $(i) = $(a) ; } diff --git a/tools/build/test/custom_generator.py b/tools/build/test/custom_generator.py index f98a468786..00860f6434 100644 --- a/tools/build/test/custom_generator.py +++ b/tools/build/test/custom_generator.py @@ -61,6 +61,6 @@ t.write("r.rcc", """ """) t.run_build_system() -t.expect_content("bin/$toolset/debug*/r.obj", "rc-object") +t.expect_content("bin/r.obj", "rc-object") t.cleanup() diff --git a/tools/build/test/debugger.py b/tools/build/test/debugger.py index 9edfa84c07..7b696a0fca 100644 --- a/tools/build/test/debugger.py +++ b/tools/build/test/debugger.py @@ -97,6 +97,9 @@ Breakpoint 1, f ( ) at test.jam:8 """) t.cleanup() +# Note: step doesn't need to worry about breakpoints, +# as it always stops at the next line executed. + def test_next(): t = make_tester() t.write("test.jam", """\ @@ -137,6 +140,51 @@ Breakpoint 1, f ( ) at test.jam:7 """) t.cleanup() +def test_next_breakpoint(): + """next should stop if it encounters a breakpoint. + If the normal end point happens to be a breakpoint, + then it should be reported as normal stepping.""" + t = make_tester() + t.write("test.jam", """\ + rule f ( recurse ? ) + { + if $(recurse) { f ; } + a = 1 ; + } + rule g ( ) + { + b = 2 ; + } + f true ; + g ; + """) + run(t, """\ +(b2db) break f +Breakpoint 1 set at f +(b2db) break g +Breakpoint 2 set at g +(b2db) break test.jam:4 +Breakpoint 3 set at test.jam:4 +(b2db) run -ftest.jam +Starting program: {{bjam}} -ftest.jam +Breakpoint 1, f ( true ) at test.jam:3 +3 if $(recurse) { f ; } +(b2db) next +Breakpoint 1, f ( ) at test.jam:3 +3 if $(recurse) { f ; } +(b2db) next +4 a = 1 ; +(b2db) next +4 a = 1 ; +(b2db) next +11 g ; +(b2db) next +Breakpoint 2, g ( ) at test.jam:8 +8 b = 2 ; +(b2db) quit +""") + t.cleanup() + def test_finish(): t = make_tester() t.write("test.jam", """\ @@ -178,7 +226,100 @@ Breakpoint 1, f ( ) at test.jam:3 (b2db) quit """) t.cleanup() - + +def test_finish_breakpoints(): + """finish should stop when it reaches a breakpoint.""" + t = make_tester() + t.write("test.jam", """\ + rule f ( recurse * ) + { + if $(recurse) + { + a = [ f $(recurse[2-]) ] ; + } + } + rule g ( list * ) + { + for local v in $(list) + { + x = $(v) ; + } + } + f 1 2 ; + g 1 2 ; + """) + run(t, """\ +(b2db) break test.jam:5 +Breakpoint 1 set at test.jam:5 +(b2db) break test.jam:12 +Breakpoint 2 set at test.jam:12 +(b2db) run -ftest.jam +Starting program: {{bjam}} -ftest.jam +Breakpoint 1, f ( 1 2 ) at test.jam:5 +5 a = [ f $(recurse[2-]) ] ; +(b2db) finish +Breakpoint 1, f ( 2 ) at test.jam:5 +5 a = [ f $(recurse[2-]) ] ; +(b2db) finish +5 a = [ f $(recurse[2-]) ] ; +(b2db) finish +16 g 1 2 ; +(b2db) finish +Breakpoint 2, g ( 1 2 ) at test.jam:12 +12 x = $(v) ; +(b2db) finish +Breakpoint 2, g ( 1 2 ) at test.jam:12 +12 x = $(v) ; +(b2db) quit +""") + t.cleanup() + +def test_continue_breakpoints(): + """continue should stop when it reaches a breakpoint""" + t = make_tester() + t.write("test.jam", """\ + rule f ( recurse * ) + { + if $(recurse) + { + a = [ f $(recurse[2-]) ] ; + } + } + rule g ( list * ) + { + for local v in $(list) + { + x = $(v) ; + } + } + f 1 2 ; + g 1 2 ; + """) + run(t, """\ +(b2db) break test.jam:5 +Breakpoint 1 set at test.jam:5 +(b2db) break test.jam:12 +Breakpoint 2 set at test.jam:12 +(b2db) run -ftest.jam +Starting program: {{bjam}} -ftest.jam +Breakpoint 1, f ( 1 2 ) at test.jam:5 +5 a = [ f $(recurse[2-]) ] ; +(b2db) continue +Breakpoint 1, f ( 2 ) at test.jam:5 +5 a = [ f $(recurse[2-]) ] ; +(b2db) continue +Breakpoint 1, f ( 1 2 ) at test.jam:5 +5 a = [ f $(recurse[2-]) ] ; +(b2db) continue +Breakpoint 2, g ( 1 2 ) at test.jam:12 +12 x = $(v) ; +(b2db) continue +Breakpoint 2, g ( 1 2 ) at test.jam:12 +12 x = $(v) ; +(b2db) quit +""") + t.cleanup() + def test_breakpoints(): """Tests the interaction between the following commands: break, clear, delete, disable, enable""" @@ -519,7 +660,10 @@ test_run() test_exit_status() test_step() test_next() +test_next_breakpoint() test_finish() +test_finish_breakpoints() +test_continue_breakpoints() test_breakpoints() test_breakpoints_running() test_backtrace() diff --git a/tools/build/test/dependency_property.py b/tools/build/test/dependency_property.py index bcced6ad94..b67539255f 100644 --- a/tools/build/test/dependency_property.py +++ b/tools/build/test/dependency_property.py @@ -8,6 +8,10 @@ # considered different by 'virtual-target.register', but the code which # determined the actual target paths ignored dependency properties so both # targets ended up being in the same location. +# +# This test has flip-flopped several times between passing and failing. +# Currently, the library is only considered relevant for linking and thus +# does not cause a conflict. SJW 20180115 import BoostBuild @@ -29,11 +33,6 @@ __declspec(dllexport) void foo() {} """) -t.run_build_system(["--no-error-backtrace"], status=1) -output = t.stdout() -t.fail_test( - "Tried to build the target twice" not in output and - "Duplicate name of actual target" not in output -) +t.run_build_system(["--no-error-backtrace"], status=0) t.cleanup() diff --git a/tools/build/test/dependency_test.py b/tools/build/test/dependency_test.py index a495affffb..8529557756 100644 --- a/tools/build/test/dependency_test.py +++ b/tools/build/test/dependency_test.py @@ -10,7 +10,7 @@ import BoostBuild def test_basic(): - t = BoostBuild.Tester(["-d3", "-d+12"], pass_d0=False, use_test_config=False) + t = BoostBuild.Tester(["-d3", "-d+12"], use_test_config=False) t.write("a.cpp", """ #include @@ -211,7 +211,7 @@ def test_scanned_includes_with_absolute_paths(): considered when scanning dependencies. """ - t = BoostBuild.Tester(["-d3", "-d+12"], pass_d0=False) + t = BoostBuild.Tester(["-d3", "-d+12"]) t.write("jamroot.jam", """\ path-constant TOP : . ; diff --git a/tools/build/test/direct_request_test.py b/tools/build/test/direct_request_test.py deleted file mode 100644 index 4222769381..0000000000 --- a/tools/build/test/direct_request_test.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/python - -import BoostBuild - -t = BoostBuild.Tester(use_test_config=False) - -# First check some startup. - -t.write("jamroot.jam", "") -t.write("jamfile.jam", """\ -exe a : a.cpp b ; -lib b : b.cpp ; -""") - -t.write("a.cpp", """\ -void -# ifdef _WIN32 -__declspec(dllimport) -# endif -foo(); -int main() { foo(); } -""") - -t.write("b.cpp", """\ -#ifdef MACROS -void -# ifdef _WIN32 -__declspec(dllexport) -# endif -foo() {} -#endif - -# ifdef _WIN32 -int __declspec(dllexport) force_implib_creation; -# endif -""") - -t.run_build_system(["define=MACROS"]) -t.expect_addition("bin/$toolset/debug*/" - * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) - - -# When building a debug version, the 'define' still applies. -t.rm("bin") -t.run_build_system(["debug", "define=MACROS"]) -t.expect_addition("bin/$toolset/debug*/" - * (BoostBuild.List("a.obj b.obj b.dll a.exe"))) - - -# When building a release version, the 'define' still applies. -t.write("jamfile.jam", """\ -exe a : a.cpp b : debug ; -lib b : b.cpp ; -""") -t.rm("bin") -t.run_build_system(["release", "define=MACROS"]) - - -# Regression test: direct build request was not working when there was more -# than one level of 'build-project'. -t.rm(".") -t.write("jamroot.jam", "") -t.write("jamfile.jam", "build-project a ;") -t.write("a/jamfile.jam", "build-project b ;") -t.write("a/b/jamfile.jam", "") -t.run_build_system(["release"]) - -t.cleanup() diff --git a/tools/build/test/dll_path.py b/tools/build/test/dll_path.py index e71b704b96..6282fae9f3 100644 --- a/tools/build/test/dll_path.py +++ b/tools/build/test/dll_path.py @@ -143,4 +143,21 @@ es2 = t.adjust_name("b/bin/$toolset/debug*") t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es1); t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es2); +t.rm("bin/$toolset/debug*/mp.pathlist") + +# Now run the same checks with pre-built libraries +adll = t.glob_file("a/bin/$toolset/debug*/a.dll") +bdll = t.glob_file("b/bin/$toolset/debug*/b.dll") +t.write("b/jamfile.jam", """ +local bdll = %s ; +# Make sure that it is found even with multiple source-locations +project : source-location c $(bdll:D) ; +lib b : ../a//a : $(bdll:D=) ; +""" % bdll.replace("\\", "\\\\")) +t.run_build_system(["hardcode-dll-paths=true"]) +t.expect_addition("bin/$toolset/debug*/mp.pathlist") + +t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es1) +t.expect_content_lines("bin/$toolset/debug*/mp.pathlist", "*" + es2) + t.cleanup() diff --git a/tools/build/test/example_make.py b/tools/build/test/example_make.py index e65158ec20..d72423cb28 100644 --- a/tools/build/test/example_make.py +++ b/tools/build/test/example_make.py @@ -13,5 +13,5 @@ import sys t = BoostBuild.Tester(['example.python.interpreter=%s' % sys.executable]) t.set_tree("../example/make") t.run_build_system() -t.expect_addition(["bin/$toolset/debug*/main.cpp"]) +t.expect_addition(["bin/main.cpp"]) t.cleanup() diff --git a/tools/build/test/expansion.py b/tools/build/test/expansion.py index c5bd30379c..ed8690312a 100644 --- a/tools/build/test/expansion.py +++ b/tools/build/test/expansion.py @@ -16,7 +16,7 @@ int main() {} """) t.write("b.cpp", """ -#ifdef CF_1 +#if defined(CF_1) && !defined(CF_IS_OFF) int main() {} #endif """) @@ -27,6 +27,36 @@ int main() {} #endif """) +t.write("d.cpp", """ +#ifndef CF_IS_OFF +int main() {} +#endif +""") + +t.write("e.cpp", """ +#if !defined(CF_IS_OFF) && defined(CF_2) && !defined(CF_1) +int main() {} +#endif +""") + +t.write("f.cpp", """ +#if defined(CF_1) +int main() {} +#endif +""") + +t.write("g.cpp", """ +#if defined(FOPT_2) +int main() {} +#endif +""") + +t.write("h.cpp", """ +#if defined(CX_2) +int main() {} +#endif +""") + t.write("jamfile.jam", """ # See if default value of composite feature 'cf' will be expanded to # CF_IS_OFF. @@ -38,14 +68,45 @@ exe b : b.cpp : on-1 ; # See if conditional requirements are recursively expanded. exe c : c.cpp : $toolset:release release:FOO ; + +# Composites specified in the default build should not +# be expanded if they are overridden in the the requirements. +exe d : d.cpp : on : off ; + +# Overriding a feature should clear subfeatures and +# apply default values of subfeatures. +exe e : e.cpp : always : on-1 ; + +# Subfeatures should not be changed if the parent feature doesn't change +exe f : f.cpp : on : on-1 ; + +# If a subfeature is not specific to the value of the parent feature, +# then changing the parent value should not clear the subfeature. +exe g : g.cpp : off : on-2 ; + +# If the default value of a composite feature adds an optional +# feature which has a subfeature with a default, then that +# default should be added. +exe h : h.cpp ; """) t.write("jamroot.jam", """ import feature ; -feature.feature cf : off on : composite incidental ; +feature.feature cf : off on always : composite incidental ; feature.compose off : CF_IS_OFF ; feature.subfeature cf on : version : 1 2 : composite optional incidental ; feature.compose 1 : CF_1 ; +feature.subfeature cf always : version : 1 2 : composite incidental ; +feature.compose 1 : CF_2 ; +feature.feature fopt : on off : optional incidental ; +feature.subfeature fopt : version : 1 2 : composite incidental ; +feature.compose 2 : FOPT_2 ; + +feature.feature cx1 : on : composite incidental ; +feature.feature cx2 : on : optional incidental ; +feature.subfeature cx2 on : sub : 1 : composite incidental ; +feature.compose on : on ; +feature.compose 1 : CX_2 ; """) t.expand_toolset("jamfile.jam") @@ -53,7 +114,12 @@ t.expand_toolset("jamfile.jam") t.run_build_system() t.expect_addition(["bin/$toolset/debug*/a.exe", "bin/$toolset/debug*/b.exe", - "bin/$toolset/release*/c.exe"]) + "bin/$toolset/release*/c.exe", + "bin/$toolset/debug*/d.exe", + "bin/$toolset/debug*/e.exe", + "bin/$toolset/debug*/f.exe", + "bin/$toolset/debug*/g.exe", + "bin/$toolset/debug*/h.exe"]) t.rm("bin") diff --git a/tools/build/test/feature_implicit_dependency.py b/tools/build/test/feature_implicit_dependency.py new file mode 100644 index 0000000000..0b40da1bf2 --- /dev/null +++ b/tools/build/test/feature_implicit_dependency.py @@ -0,0 +1,113 @@ +#!/usr/bin/python + +# Copyright (c) Steven Watanabe 2018. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests that a single main target can be used for +# implicit dependencies of multiple different types. + +import BoostBuild + +t = BoostBuild.Tester(pass_toolset=False) + +t.write("input.sss", "") + +t.write("Jamroot.jam", """ +import type ; +import common ; +import generators ; +import "class" : new ; +import feature : feature ; +import toolset : flags ; + +type.register AAA : aaa ; +type.register BBB : bbb ; +type.register CCC : ccc ; +type.register DDD : ddd ; +type.register SSS : sss ; + +feature aaa-path : : free path ; +feature bbb-path : : free path ; + +class aaa-action : action +{ + rule adjust-properties ( property-set ) + { + local s = [ $(self.targets[1]).creating-subvariant ] ; + return [ $(property-set).add-raw + [ $(s).implicit-includes aaa-path : AAA ] ] ; + } +} + +class aaa-generator : generator +{ + rule action-class ( ) + { + return aaa-action ; + } +} + +class bbb-action : action +{ + rule adjust-properties ( property-set ) + { + local s = [ $(self.targets[1]).creating-subvariant ] ; + return [ $(property-set).add-raw + [ $(s).implicit-includes bbb-path : BBB ] ] ; + } +} + +class bbb-generator : generator +{ + rule action-class ( ) + { + return bbb-action ; + } +} + +generators.register-standard common.copy : SSS : AAA ; +generators.register-standard common.copy : SSS : BBB ; + +# Produce two targets from a single source +rule make-aaa-bbb ( project name ? : property-set : sources * ) +{ + local result ; + local aaa = [ generators.construct $(project) $(name) : AAA : + [ $(property-set).add-raw a-loc ] : $(sources) ] ; + local bbb = [ generators.construct $(project) $(name) : BBB : + [ $(property-set).add-raw b-loc ] : $(sources) ] ; + return [ $(aaa[1]).add $(bbb[1]) ] $(aaa[2-]) $(bbb[2-]) ; +} + +generate input : input.sss : @make-aaa-bbb ; +explicit input ; + +flags make-ccc AAAPATH : ; +rule make-ccc ( target : sources * : properties * ) +{ + ECHO aaa path\: [ on $(target) return $(AAAPATH) ] ; + common.copy $(target) : $(sources) ; +} + +flags make-ddd BBBPATH : ; +rule make-ddd ( target : sources * : properties * ) +{ + ECHO bbb path\: [ on $(target) return $(BBBPATH) ] ; + common.copy $(target) : $(sources) ; +} + +generators.register [ new aaa-generator $(__name__).make-ccc : SSS : CCC ] ; +generators.register [ new bbb-generator $(__name__).make-ddd : SSS : DDD ] ; + +# This should have bin/a-loc +ccc output-c : input.sss : input ; +# This should have bin/b-loc +ddd output-d : input.sss : input ; +""") + +t.run_build_system() +t.expect_output_lines(["aaa path: bin/a-loc", "bbb path: bin/b-loc"]) + +t.cleanup() diff --git a/tools/build/test/feature_relevant.py b/tools/build/test/feature_relevant.py new file mode 100644 index 0000000000..4e7a0c4516 --- /dev/null +++ b/tools/build/test/feature_relevant.py @@ -0,0 +1,142 @@ +#!/usr/bin/python + +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests the feature + +import BoostBuild + +t = BoostBuild.Tester(use_test_config=False) + +t.write("xxx.jam", """ +import type ; +import feature : feature ; +import toolset : flags ; +import generators ; +type.register XXX : xxx ; +type.register YYY : yyy ; +feature xxxflags : : free ; +generators.register-standard xxx.run : YYY : XXX ; +# xxxflags is relevant because it is used by flags +flags xxx.run OPTIONS : ; +actions run +{ + echo okay > $(<) +} +""") + +t.write("zzz.jam", """ +import xxx ; +import type ; +import feature : feature ; +import generators ; +type.register ZZZ : zzz ; +feature zzz.enabled : off on : propagated ; +# zzz.enabled is relevant because it is used in the generator's +# requirements +generators.register-standard zzz.run : XXX : ZZZ : on ; +actions run +{ + echo okay > $(<) +} +""") + +t.write("aaa.jam", """ +import zzz ; +import type ; +import feature : feature ; +import generators ; +import toolset : flags ; +type.register AAA : aaa ; +feature aaaflags : : free ; +generators.register-standard aaa.run : ZZZ : AAA ; +flags aaa.run OPTIONS : ; +actions run +{ + echo okay > $(<) +} +""") + +t.write("Jamroot.jam", """ +import xxx ; +import zzz ; +import aaa ; +import feature : feature ; + +# f1 is relevant, because it is composite and is relevant +feature f1 : n y : composite propagated ; +feature.compose y : -no1 ; +# f2 is relevant, because it is used in a conditional +feature f2 : n y : propagated ; +# f3 is relevant, because it is used to choose the target alternative +feature f3 : n y : propagated ; +# f4 is relevant, because it is marked as such explicitly +feature f4 : n y : propagated ; +# f5 is relevant because of the conditional usage-requirements +feature f5 : n y : propagated ; +# f6 is relevant because the indirect conditional indicates so +feature f6 : n y : propagated ; +# f7 is relevant because the icond7 says so +feature f7 : n y : propagated ; + +# The same as f[n], except not propagated +feature g1 : n y : composite ; +feature.compose y : -no1 ; +feature g2 : n y ; +feature g3 : n y ; +feature g4 : n y ; +feature g5 : n y ; +feature g6 : n y ; +feature g7 : n y ; + +project : default-build + y y y y y y y + y y y y y y y on ; + +rule icond6 ( properties * ) +{ + local result ; + if y in $(properties) || y in $(properties) + { + result += -yes6 ; + } + return $(result) + xxxflags:f6 + xxxflags:g6 ; +} + +rule icond7 ( properties * ) +{ + local result ; + if y in $(properties) || y in $(properties) + { + result += -yes7 ; + } + return $(result) + aaaflags:f7 + aaaflags:g7 ; +} + +zzz out : in.yyy + : y:-no2 y:-no2 f4 g4 + @icond6 + : + : y:-yes5 y:-yes5 @icond7 + ; +alias out : : n ; +alias out : : n ; +# Features that are relevant for out are also relevant for check-propagate +aaa check-propagate : out ; +""") + +t.write("in.yyy", "") + +t.run_build_system() +t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f6-y/g1-y/g2-y/g3-y/g4-y/g6-y/out.xxx") +t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f6-y/g1-y/g2-y/g3-y/g4-y/g6-y/zzz.enabled-on/out.zzz") +t.expect_addition("bin/f1-y/f2-y/f3-y/f4-y/f5-y/f6-y/f7-y/zzz.enabled-on/check-propagate.aaa") + +t.cleanup() diff --git a/tools/build/test/feature_suppress_import_lib.py b/tools/build/test/feature_suppress_import_lib.py new file mode 100644 index 0000000000..8dc6667275 --- /dev/null +++ b/tools/build/test/feature_suppress_import_lib.py @@ -0,0 +1,33 @@ +#!/usr/bin/python + +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests the suppress-import-lib feature + +# This used to cause the pdb and the import lib to get mixed up +# if there are any exports. + +import BoostBuild + +t = BoostBuild.Tester(use_test_config=False) + +t.write("Jamroot.jam", """ +lib l : l.cpp : true ; +""") + +t.write("l.cpp", """ +void +#ifdef _WIN32 +__declspec(dllexport) +#endif +f() {} +""") + +t.run_build_system() +t.expect_addition("bin/$toolset/debug*/l.obj") +t.expect_addition("bin/$toolset/debug*/l.dll") + +t.cleanup() diff --git a/tools/build/test/file_types.py b/tools/build/test/file_types.py new file mode 100644 index 0000000000..e6d9bf8407 --- /dev/null +++ b/tools/build/test/file_types.py @@ -0,0 +1,44 @@ +#!/usr/bin/python +# +# Copyright 2018 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests the mapping of various suffixes +# In particular, .so[.version] needs to +# be mapped as a SHARED_LIB. + +import BoostBuild + +t = BoostBuild.Tester() + +t.write("Jamroot.jam", """\ +import type : type ; +ECHO [ type source.c ] ; +ECHO [ type source.cc ] ; +ECHO [ type source.cxx ] ; +ECHO [ type source.cpp ] ; +ECHO [ type source.o ] ; +ECHO [ type source.obj ] ; +ECHO [ type boost_system.lib ] ; +ECHO [ type boost_system.so ] ; +ECHO [ type boost_system.dll ] ; +EXIT [ type boost_system.so.1.66.0 ] : 0 ; +""") + +t.run_build_system(stdout="""\ +C +CPP +CPP +CPP +OBJ +OBJ +STATIC_LIB +SHARED_LIB +SHARED_LIB +SHARED_LIB +""") + +t.cleanup() diff --git a/tools/build/test/flags.py b/tools/build/test/flags.py new file mode 100644 index 0000000000..bdb2b6b7dc --- /dev/null +++ b/tools/build/test/flags.py @@ -0,0 +1,74 @@ +#!/usr/bin/python + +# Copyright (C) Steven Watanabe 2018 +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Tests the check-has-flag rule + +import BoostBuild + +t = BoostBuild.Tester(use_test_config=False) + +# We need an object file before we can run the actual test. +t.write('input.cpp', 'void f() {}\n') +t.write('Jamroot.jam', 'obj input : input.cpp ;') +t.run_build_system() + +linker_input = t.glob_file('bin/$toolset/debug*/input.obj') + +# Check every possible result of pass or fail. +t.write('Jamroot.jam', ''' +import flags ; +import modules ; +OBJECT_FILE = [ modules.peek : OBJECT_FILE ] ; +obj fail_cpp : test.cpp : [ check-has-flag --illegal-flag-cpp + : ERROR : OK ] ; +obj pass_cpp : test.cpp : [ check-has-flag -DMACRO_CPP + : OK : ERROR ] ; +obj fail_c : test.cpp : [ check-has-flag --illegal-flag-c + : ERROR : OK ] ; +obj pass_c : test.cpp : [ check-has-flag -DMACRO_C + : OK : ERROR ] ; +obj fail_link : test.cpp : [ check-has-flag --illegal-flag-link + : ERROR : OK ] ; +# The only thing that we can be certain the linker +# will accept is the name of an object file. +obj pass_link : test.cpp : [ check-has-flag $(OBJECT_FILE) + : OK : ERROR ] ; +''') + +t.write('test.cpp', ''' +#ifdef ERROR +#error ERROR defined +#endif +#ifndef OK +#error ERROR not defined +#endif +''') + +# Don't check the status immediately, so that we have a chance +# to print config.log. Also, we need a minimum of d2 to make +# sure that we always see the commands and output. +t.run_build_system(['-sOBJECT_FILE=' + linker_input, '-d2'], status=None) + +if t.status != 0: + log_file = t.read('bin/config.log') + BoostBuild.annotation("config.log", log_file) + t.fail_test(True) + +t.expect_output_lines([' - has --illegal-flag-cpp : no', + ' - has -DMACRO_CPP : yes', + ' - has --illegal-flag-c : no', + ' - has -DMACRO_C : yes', + ' - has --illegal-flag-link : no', + ' - has *bin*/input.* : yes']) +t.expect_addition('bin/$toolset/debug*/fail_cpp.obj') +t.expect_addition('bin/$toolset/debug*/pass_cpp.obj') +t.expect_addition('bin/$toolset/debug*/fail_c.obj') +t.expect_addition('bin/$toolset/debug*/pass_c.obj') +t.expect_addition('bin/$toolset/debug*/fail_link.obj') +t.expect_addition('bin/$toolset/debug*/pass_link.obj') + +t.cleanup() diff --git a/tools/build/test/free_features_request.py b/tools/build/test/free_features_request.py deleted file mode 100644 index c6bb4e9d63..0000000000 --- a/tools/build/test/free_features_request.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) Vladimir Prus 2007. -# Distributed under the Boost Software License, Version 1.0. (See -# accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# Tests that a free feature specified on the command line applies to all -# targets ever built. - -import BoostBuild - -t = BoostBuild.Tester(use_test_config=False) - -t.write("jamroot.jam", """\ -exe hello : hello.cpp foo ; -lib foo : foo.cpp ; -""") - -t.write("hello.cpp", """\ -extern void foo(); -#ifdef FOO -int main() { foo(); } -#endif -""") - -t.write("foo.cpp", """\ -#ifdef FOO -#ifdef _WIN32 -__declspec(dllexport) -#endif -void foo() {} -#endif -""") - -# If FOO is not defined when compiling the 'foo' target, we will get a link -# error at this point. -t.run_build_system(["hello", "define=FOO"]) - -t.expect_addition("bin/$toolset/debug*/hello.exe") - -t.cleanup() diff --git a/tools/build/test/gcc_runtime.py b/tools/build/test/gcc_runtime.py index 28b6410a52..76c95e1af1 100644 --- a/tools/build/test/gcc_runtime.py +++ b/tools/build/test/gcc_runtime.py @@ -20,9 +20,8 @@ t.expect_output_lines("warning: On gcc, DLLs can not be built with " t.expect_nothing_more() t.run_build_system(["link=static", "runtime-link=static"]) -binFolder = "bin/$toolset/debug*/link-static/runtime-link-static" -t.expect_addition("%s/hello.obj" % binFolder) -t.expect_addition("%s/hello.lib" % binFolder) +t.expect_addition("bin/$toolset/debug*/link-static/hello.obj") +t.expect_addition("bin/$toolset/debug*/link-static/hello.lib") t.expect_nothing_more() t.cleanup() diff --git a/tools/build/test/generator_selection.py b/tools/build/test/generator_selection.py index 64f9cc7b3c..1ecca7100a 100755 --- a/tools/build/test/generator_selection.py +++ b/tools/build/test/generator_selection.py @@ -87,9 +87,9 @@ my-obj other-obj : source.extension ; t.run_build_system() t.expect_output_lines("Generating a CPP file...") - t.expect_addition("bin/$toolset/debug*/dummy.my_obj") - t.expect_addition("Other/bin/$toolset/debug*/other-obj.cpp") - t.expect_addition("Other/bin/$toolset/debug*/other-obj.my_obj") + t.expect_addition("bin/dummy.my_obj") + t.expect_addition("Other/bin/other-obj.cpp") + t.expect_addition("Other/bin/other-obj.my_obj") t.expect_nothing_more() t.cleanup() @@ -139,8 +139,8 @@ yyy other : source.xxx2 ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug*/dummy.yyy") - t.expect_addition("Other/bin/$toolset/debug*/other.yyy") + t.expect_addition("bin/dummy.yyy") + t.expect_addition("Other/bin/other.yyy") t.expect_nothing_more() t.cleanup() diff --git a/tools/build/test/generators_test.py b/tools/build/test/generators_test.py index d666d46c24..f612a25eb3 100644 --- a/tools/build/test/generators_test.py +++ b/tools/build/test/generators_test.py @@ -12,7 +12,7 @@ import re def test_basic(): - t = BoostBuild.Tester(pass_d0=False) + t = BoostBuild.Tester() __write_appender(t, "appender.jam") t.write("a.cpp", "") t.write("b.cxx", "") @@ -110,7 +110,7 @@ type.register NM_EXE : : MY_EXE ; appender.register marked-to-target-cpp : CPP_MARKED : NM.TARGET.CPP ; appender.register cpp-to-marked-positions : CPP : CPP_MARKED POSITIONS ; -class nm::target::cpp-obj-generator : generator +class "nm::target::cpp-obj-generator" : generator { rule __init__ ( id ) { @@ -137,7 +137,7 @@ class nm::target::cpp-obj-generator : generator } } } -generators.register [ new nm::target::cpp-obj-generator target-obj ] ; +generators.register [ new "nm::target::cpp-obj-generator" target-obj ] ; generators.override target-obj : all ; @@ -215,17 +215,17 @@ nm-exe e : e.cpp ; """) t.run_build_system() - t.expect_addition("bin/$toolset/debug*/" * BoostBuild.List("a.my_exe " + t.expect_addition("bin/" * BoostBuild.List("a.my_exe " "a.my_obj b.my_obj c.tui_h c.cpp c.my_obj d_parser.whl d_lexer.dlp " "d_parser.cpp d_lexer.cpp d_lexer.my_obj d_parser.lr0 d_parser.h " "d_parser.my_obj d_parser_symbols.h x.c x.my_obj y.x1 y.x2 y.cpp " "y.my_obj e.marked_cpp e.positions e.target_cpp e.my_obj e.my_exe " "f.my_exe obj_1.my_obj obj_2.my_obj")) - t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.my_obj " + t.expect_addition("lib/bin/" * BoostBuild.List("c.my_obj " "auxilliary.my_lib")) t.expect_nothing_more() - folder = "bin/$toolset/debug*" + folder = "bin" t.expect_content_lines("%s/obj_1.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/obj_2.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/a.my_obj" % folder, " Sources: 'a.cpp'") @@ -285,7 +285,7 @@ appender.register ccc-to-ddd composing : CCC : DDD ; ddd _xxx : _xxx._a ; """ - t = BoostBuild.Tester(pass_d0=False) + t = BoostBuild.Tester() __write_appender(t, "appender.jam") t.write("_xxx._a", "") @@ -311,7 +311,7 @@ ddd _xxx : _xxx._a ; def suffix(rename): if rename: return "_x" return "" - name = "bin/$toolset/debug*/_xxx" + name = "bin/_xxx" e = t.expect_addition e("%s%s._b1" % (name, suffix(rename1))) e("%s%s._b2" % (name, suffix(rename2))) @@ -406,7 +406,7 @@ rule appender ( targets + : sources + : properties * ) local appender-run = $(appender-runs) ; if $(targets[2])-defined { - appender-run += [$(target-index)/$(target-count)] ; + appender-run += "[$(target-index)/$(target-count)]" ; } append $(targets) : $(appender-run:J=" ") $(t) $(sources) ; } diff --git a/tools/build/test/inline.py b/tools/build/test/inline.py index d0ce91ae89..03d91a5d0e 100644 --- a/tools/build/test/inline.py +++ b/tools/build/test/inline.py @@ -21,12 +21,11 @@ int main() {} t.write("helper.cpp", "void helper() {}\n") t.run_build_system() -t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") -t.rm("bin/$toolset/debug/link-static/a__helper.lib") -t.rm("bin/$toolset/debug/link-static/*/a__helper.lib") +t.expect_addition("bin/$toolset/debug*/a__helper.lib") +t.rm("bin/$toolset/debug*/a__helper.lib") t.run_build_system(["a__helper"]) -t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") +t.expect_addition("bin/$toolset/debug*/a__helper.lib") t.rm("bin") @@ -41,8 +40,8 @@ exe a2 : a.cpp [ lib helper : helper.cpp ] ; t.run_build_system() t.expect_addition("bin/$toolset/debug/link-static*/a.exe") -t.expect_addition("bin/$toolset/debug/link-static*/a__helper.lib") -t.expect_addition("bin/$toolset/debug/link-static*/a2__helper.lib") +t.expect_addition("bin/$toolset/debug*/a__helper.lib") +t.expect_addition("bin/$toolset/debug*/a2__helper.lib") # Check that the 'alias' target does not change the name of inline targets, and @@ -58,6 +57,6 @@ t.run_build_system() t.expect_nothing_more() t.run_build_system(["a"]) -t.expect_addition("bin/$toolset/debug/link-static*/helper.lib") +t.expect_addition("bin/$toolset/debug*/helper.lib") t.cleanup() diff --git a/tools/build/test/lib_zlib.py b/tools/build/test/lib_zlib.py new file mode 100755 index 0000000000..04d32ba702 --- /dev/null +++ b/tools/build/test/lib_zlib.py @@ -0,0 +1,184 @@ +#!/usr/bin/python + +# Copyright (C) 2013 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild +import MockToolset + +t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0) + +MockToolset.create(t) + +# Build from source +t.write("zlib/zlib.h", 'zlib') +t.write("zlib/deflate.c", 'deflate') + +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib : : $(here)/zlib ; +alias zlib : /zlib//zlib : : static shared ; +""") + +MockToolset.set_expected(t, ''' +source_file('deflate.c', 'deflate') +action('-c -x c -I./zlib -o $deflate.o $deflate.c') +action('-c -x c -I./zlib -DZLIB_DLL -o $deflate-shared.o $deflate.c') +action('--dll $deflate-shared.o -o $deflate.so') +action('--archive $deflate.o -o $deflate.a') +''') + +t.run_build_system() +t.expect_addition('bin/standalone/zlib/mock/debug/z.dll') +t.expect_addition('bin/standalone/zlib/mock/debug/link-static/z.lib') + +# Build from source specified in the environment +t.rm('bin') +t.rm('zlib') + +t.write("zlib root/zlib.h", 'zlib') +t.write("zlib root/deflate.c", 'deflate') + +t.write("Jamroot.jam", """ +using zlib ; +alias zlib : /zlib//zlib : : static shared ; +""") + +MockToolset.set_expected(t, ''' +source_file('deflate.c', 'deflate') +action(['-c', '-x', 'c', '-I./zlib root', '-o', '$deflate.o', '$deflate.c']) +action(['-c', '-x', 'c', '-I./zlib root', '-DZLIB_DLL', '-o', '$deflate-shared.o', '$deflate.c']) +action('--dll $deflate-shared.o -o $deflate.so') +action('--archive $deflate.o -o $deflate.a') +''') +t.run_build_system(['-sZLIB_SOURCE=zlib root']) +t.expect_addition('bin/standalone/zlib/mock/debug/z.dll') +t.expect_addition('bin/standalone/zlib/mock/debug/link-static/z.lib') + + +t.rm('zlib root') + +# Generic definitions that aren't configuration specific +common_stuff = ''' +source_file('test.cpp', 'test.cpp') +source_file('main.cpp', 'int main() {}') +source_file('zlib.h.cpp', '#include \\n') +action('-c -x c++ $main.cpp -o $main.o') +''' +t.write('test.cpp', 'test.cpp') + +# Default initialization - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib ; +exe test : test.cpp /zlib//zlib : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --static-lib=z -o $config.exe') +action('-c -x c++ $zlib.h.cpp -o $zlib.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --static-lib=z -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Default initialization - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib ; +exe test : test.cpp /zlib//zlib : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --shared-lib=z -o $config.exe') +action('-c -x c++ $zlib.h.cpp -o $zlib.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --shared-lib=z -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib : : myzlib $(here)/zlib $(here)/zlib ; +exe test : test.cpp /zlib//zlib : : static shared ; +""") + +t.write('zlib/zlib.h', 'zlib') + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zlib --static-lib=myzlib -o $config.exe') +action('-c -x c++ $test.cpp -I./zlib -o $test.o') +action('$test.o -L./zlib --static-lib=myzlib -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib : : myzlib $(here)/zlib $(here)/zlib ; +exe test : test.cpp /zlib//zlib : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zlib --shared-lib=myzlib -o $config.exe') +action('-c -x c++ $test.cpp -I./zlib -o $test.o') +action('$test.o -L./zlib --shared-lib=myzlib -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - both static and shared libraries +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zlib : : myzlib $(here)/zlib $(here)/zlib ; +exe test : test.cpp /zlib//zlib + : shared:SHARED : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zlib --static-lib=myzlib -o $config.exe') +action('$main.o -L./zlib --shared-lib=myzlib -o $config.exe') +action('-c -x c++ $test.cpp -I./zlib -o $test-static.o') +action('-c -x c++ $test.cpp -I./zlib -DSHARED -o $test-shared.o') +action('$test-static.o -L./zlib --static-lib=myzlib -o $test') +action('$test-shared.o -L./zlib --shared-lib=myzlib -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization from the environment +t.rm('bin') +t.write('Jamroot.jam', """ +using zlib ; +exe test : test.cpp /zlib//zlib + : : static shared ; +""") +t.write('zlib root/zlib.h', 'zlib') +MockToolset.set_expected(t, common_stuff + ''' +action(['$main.o', '-L./zlib root', '--shared-lib=myzlib', '-o', '$config.exe']) +action(['-c', '-x', 'c++', '$test.cpp', '-I./zlib root', '-o', '$test.o']) +action(['$test.o', '-L./zlib root', '--shared-lib=myzlib', '-o', '$test']) +''') +t.run_build_system(['-sZLIB_INCLUDE=zlib root', + '-sZLIB_LIBRARY_PATH=zlib root', + '-sZLIB_NAME=myzlib']) +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +t.cleanup() diff --git a/tools/build/test/libjpeg.py b/tools/build/test/libjpeg.py index dcf81c9b0a..d98c5da90f 100755 --- a/tools/build/test/libjpeg.py +++ b/tools/build/test/libjpeg.py @@ -13,8 +13,8 @@ t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user MockToolset.create(t) # Build from source -t.write("libjpeg/jpeg.h", 'libjpeg') -t.write("libjpeg/jpeg.c", 'jpeg') +t.write("libjpeg/jpeglib.h", 'libjpeg') +t.write("libjpeg/jerror.c", 'jpeg') t.write("Jamroot.jam", """ path-constant here : . ; @@ -39,7 +39,7 @@ t.rm('libjpeg') common_stuff = ''' source_file('test.cpp', 'test.cpp') source_file('main.cpp', 'int main() {}') -source_file('jpeg.h.cpp', '#include ') +source_file('jpeg.h.cpp', '#include \\n#include \\n') action('-c -x c++ $main.cpp -o $main.o') ''' t.write('test.cpp', 'test.cpp') @@ -88,7 +88,7 @@ using libjpeg : : mylibjpeg $(here)/libjpeg $(here)/libjp exe test : test.cpp /libjpeg//libjpeg : : static shared ; """) -t.write('libjpeg/jpeg.h', 'libjpeg') +t.write('libjpeg/jpeglib.h', 'libjpeg') MockToolset.set_expected(t, common_stuff + ''' action('$main.o -L./libjpeg --static-lib=mylibjpeg -o $config.exe') diff --git a/tools/build/test/liblzma.py b/tools/build/test/liblzma.py new file mode 100755 index 0000000000..6bc767fbb6 --- /dev/null +++ b/tools/build/test/liblzma.py @@ -0,0 +1,118 @@ +#!/usr/bin/python + +# Copy-paste-modify from zlib.py +# Copyright (C) 2013 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild +import MockToolset + +t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0) + +MockToolset.create(t) + +# Generic definitions that aren't configuration specific +common_stuff = ''' +source_file('test.cpp', 'test.cpp') +source_file('main.cpp', 'int main() {}') +source_file('lzma.h.cpp', '#include \\n') +action('-c -x c++ $main.cpp -o $main.o') +''' +t.write('test.cpp', 'test.cpp') + +# Default initialization - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using lzma ; +exe test : test.cpp /lzma//lzma : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --static-lib=lzma -o $config.exe') +action('-c -x c++ $lzma.h.cpp -o $lzma.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --static-lib=lzma -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Default initialization - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using lzma ; +exe test : test.cpp /lzma//lzma : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --shared-lib=lzma -o $config.exe') +action('-c -x c++ $lzma.h.cpp -o $lzma.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --shared-lib=lzma -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using lzma : : mylzma $(here)/lzma $(here)/lzma ; +exe test : test.cpp /lzma//lzma : : static shared ; +""") + +t.write('lzma/lzma.h', 'lzma') + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./lzma --static-lib=mylzma -o $config.exe') +action('-c -x c++ $test.cpp -I./lzma -o $test.o') +action('$test.o -L./lzma --static-lib=mylzma -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using lzma : : mylzma $(here)/lzma $(here)/lzma ; +exe test : test.cpp /lzma//lzma : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./lzma --shared-lib=mylzma -o $config.exe') +action('-c -x c++ $test.cpp -I./lzma -o $test.o') +action('$test.o -L./lzma --shared-lib=mylzma -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - both static and shared libraries +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using lzma : : mylzma $(here)/lzma $(here)/lzma ; +exe test : test.cpp /lzma//lzma + : shared:SHARED : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./lzma --static-lib=mylzma -o $config.exe') +action('$main.o -L./lzma --shared-lib=mylzma -o $config.exe') +action('-c -x c++ $test.cpp -I./lzma -o $test-static.o') +action('-c -x c++ $test.cpp -I./lzma -DSHARED -o $test-shared.o') +action('$test-static.o -L./lzma --static-lib=mylzma -o $test') +action('$test-shared.o -L./lzma --shared-lib=mylzma -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +t.cleanup() diff --git a/tools/build/test/libzstd.py b/tools/build/test/libzstd.py new file mode 100755 index 0000000000..c582c6ad96 --- /dev/null +++ b/tools/build/test/libzstd.py @@ -0,0 +1,118 @@ +#!/usr/bin/python + +# Copy-paste-modify from zlib.py +# Copyright (C) 2013 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild +import MockToolset + +t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0) + +MockToolset.create(t) + +# Generic definitions that aren't configuration specific +common_stuff = ''' +source_file('test.cpp', 'test.cpp') +source_file('main.cpp', 'int main() {}') +source_file('zstd.h.cpp', '#include \\n') +action('-c -x c++ $main.cpp -o $main.o') +''' +t.write('test.cpp', 'test.cpp') + +# Default initialization - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zstd ; +exe test : test.cpp /zstd//zstd : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --static-lib=zstd -o $config.exe') +action('-c -x c++ $zstd.h.cpp -o $zstd.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --static-lib=zstd -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Default initialization - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zstd ; +exe test : test.cpp /zstd//zstd : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o --shared-lib=zstd -o $config.exe') +action('-c -x c++ $zstd.h.cpp -o $zstd.h.o') +action('-c -x c++ $test.cpp -o $test.o') +action('$test.o --shared-lib=zstd -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - static library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zstd : : myzstd $(here)/zstd $(here)/zstd ; +exe test : test.cpp /zstd//zstd : : static shared ; +""") + +t.write('zstd/zstd.h', 'zstd') + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zstd --static-lib=myzstd -o $config.exe') +action('-c -x c++ $test.cpp -I./zstd -o $test.o') +action('$test.o -L./zstd --static-lib=myzstd -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - shared library +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zstd : : myzstd $(here)/zstd $(here)/zstd ; +exe test : test.cpp /zstd//zstd : : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zstd --shared-lib=myzstd -o $config.exe') +action('-c -x c++ $test.cpp -I./zstd -o $test.o') +action('$test.o -L./zstd --shared-lib=myzstd -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +# Initialization in explicit location - both static and shared libraries +t.rm('bin') +t.write("Jamroot.jam", """ +path-constant here : . ; +using zstd : : myzstd $(here)/zstd $(here)/zstd ; +exe test : test.cpp /zstd//zstd + : shared:SHARED : static shared ; +""") + +MockToolset.set_expected(t, common_stuff + ''' +action('$main.o -L./zstd --static-lib=myzstd -o $config.exe') +action('$main.o -L./zstd --shared-lib=myzstd -o $config.exe') +action('-c -x c++ $test.cpp -I./zstd -o $test-static.o') +action('-c -x c++ $test.cpp -I./zstd -DSHARED -o $test-shared.o') +action('$test-static.o -L./zstd --static-lib=myzstd -o $test') +action('$test-shared.o -L./zstd --shared-lib=myzstd -o $test') +''') +t.run_build_system() +t.expect_addition('bin/mock/debug/test.exe') +t.expect_addition('bin/mock/debug/link-static/test.exe') + +t.cleanup() diff --git a/tools/build/test/link.py b/tools/build/test/link.py index 4f83e1b09a..e0524ef0e0 100755 --- a/tools/build/test/link.py +++ b/tools/build/test/link.py @@ -279,8 +279,8 @@ def test_update_file_link(params1, params2): .has-files = [ glob include/file1.h ] ; rule can-link ( properties * ) { - if ( ! [ link.can-symlink $(.project) : [ property-set.empty ] ] ) && - ( ! [ link.can-hardlink $(.project) : [ property-set.empty ] ] ) + if ( ! [ link.can-symlink $(.project) ] ) && + ( ! [ link.can-hardlink $(.project) ] ) { ECHO links unsupported ; } diff --git a/tools/build/test/make_rule.py b/tools/build/test/make_rule.py index 4a2e09ad99..ab994376e1 100644 --- a/tools/build/test/make_rule.py +++ b/tools/build/test/make_rule.py @@ -28,8 +28,8 @@ make foo.bar : : creator : 12345678 ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug*/foo.bar") -t.fail_test(string.find(t.read("bin/$toolset/debug*/foo.bar"), "12345678") == -1) +t.expect_addition("bin/foo.bar") +t.fail_test(string.find(t.read("bin/foo.bar"), "12345678") == -1) # Regression test. Make sure that if a main target is requested two times, and diff --git a/tools/build/test/message.py b/tools/build/test/message.py index 5b4f7da810..30edced4d7 100755 --- a/tools/build/test/message.py +++ b/tools/build/test/message.py @@ -10,7 +10,7 @@ import BoostBuild # Create a temporary working directory. -t = BoostBuild.Tester(use_test_config=False) +t = BoostBuild.Tester(["-d0"], use_test_config=False) t.write("Jamroot.jam", """ project diff --git a/tools/build/test/param.py b/tools/build/test/param.py new file mode 100644 index 0000000000..14b3d7d946 --- /dev/null +++ b/tools/build/test/param.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild + +t = BoostBuild.Tester(pass_toolset=0) + +t.write("Jamroot.jam", """\ +import param ; +import assert ; +import errors : try catch ; +rule test1 ( ) +{ + param.handle-named-params ; +} +test1 ; +rule test2 ( sources * ) +{ + param.handle-named-params sources ; + return $(sources) ; +} +assert.result : test2 ; +assert.result test1.cpp test2.cpp : test2 test1.cpp test2.cpp ; +assert.result test1.cpp test2.cpp : test2 sources test1.cpp test2.cpp ; +rule test3 ( sources * : requirements * ) +{ + param.handle-named-params sources requirements ; + return $(sources) -- $(requirements) ; +} +assert.result -- : test3 ; +assert.result -- shared : test3 : shared ; +assert.result test1.cpp -- shared : test3 test1.cpp : shared ; +assert.result test1.cpp -- shared + : test3 test1.cpp : requirements shared ; +assert.result test1.cpp -- shared + : test3 sources test1.cpp : requirements shared ; +assert.result test1.cpp -- shared + : test3 requirements shared : sources test1.cpp ; +assert.result -- : test3 sources ; +assert.result -- : test3 requirements ; +assert.result -- shared : test3 requirements shared ; +try ; +{ + test3 sources test1.cpp : sources test2.cpp ; +} +catch Parameter 'sources' passed more than once. ; +try ; +{ + test3 sources test1.cpp : shared ; +} +catch "Positional arguments must appear first." ; +EXIT : 0 ; +""") + +t.run_build_system() + +t.cleanup() diff --git a/tools/build/test/path_features.py b/tools/build/test/path_features.py index f8a3f7caa9..5b23150bea 100644 --- a/tools/build/test/path_features.py +++ b/tools/build/test/path_features.py @@ -96,11 +96,20 @@ int main() { return OK; } def test_paths_set_by_indirect_conditionals(): - t = BoostBuild.Tester(pass_d0=False, use_test_config=False) + t = BoostBuild.Tester(use_test_config=False) header = "child_dir/folder_to_include/some_header.h" - t.write("jamroot.jam", "build-project child_dir ;") + t.write("jamroot.jam", """ +build-project child_dir ; +rule attach-include-parent ( properties * ) +{ + return another_folder ; +} +# requirements inherited from a parent project will bind paths +# relative to the project that actually names the rule. +project : requirements @attach-include-parent ; +""") t.write("child_dir/jamfile.jam", """\ import remote/remote ; @@ -121,9 +130,11 @@ rule attach-include-remote ( properties * ) """) t.write("child_dir/x.cpp", """\ #include +#include int main() {} """) t.write(header, "int some_func();\n") + t.write("another_folder/header2.h", "int f2();\n") t.write("child_dir/folder_to_include/jamfile.jam", "") expected_x1 = "child_dir/bin/$toolset/debug*/x1.obj" @@ -139,7 +150,7 @@ int main() {} t.expect_touch(expected_x2) t.touch(header) - t.run_build_system(["..", "-d2"], subdir="child_dir/folder_to_include") + t.run_build_system([".."], subdir="child_dir/folder_to_include") t.expect_touch(expected_x1) t.expect_touch(expected_x2) @@ -149,4 +160,4 @@ int main() {} test_basic() test_absolute_paths() test_ordered_paths() -test_paths_set_by_indirect_conditionals() \ No newline at end of file +test_paths_set_by_indirect_conditionals() diff --git a/tools/build/test/project-test3/jamroot.jam b/tools/build/test/project-test3/jamroot.jam index 3d4dfa19aa..d7cd490eb0 100644 --- a/tools/build/test/project-test3/jamroot.jam +++ b/tools/build/test/project-test3/jamroot.jam @@ -6,6 +6,7 @@ import os ; import gcc ; import property ; +import toolset ; rule properties-as-path ( properties * ) { @@ -21,6 +22,9 @@ rule properties-as-path ( properties * ) [ property.remove incidental : $(r) ] ] ; } +toolset.flags yfc-compile KNOWN-PROPERTIES : ; +toolset.flags yfc-link KNOWN-PROPERTIES : ; + rule yfc-compile ( target : sources * : property-set * ) { PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ; diff --git a/tools/build/test/project-test4/jamroot.jam b/tools/build/test/project-test4/jamroot.jam index fbbe0abf11..d8cf571ae1 100644 --- a/tools/build/test/project-test4/jamroot.jam +++ b/tools/build/test/project-test4/jamroot.jam @@ -5,6 +5,7 @@ import os ; import gcc ; import property ; +import toolset ; rule properties-as-path ( properties * ) { @@ -21,6 +22,10 @@ rule properties-as-path ( properties * ) } +toolset.flags yfc-compile KNOWN-PROPERTIES : ; +toolset.flags yfc-link KNOWN-PROPERTIES : ; + + rule yfc-compile ( target : sources * : property-set * ) { PROPERTIES on $(target) = [ properties-as-path $(property-set) ] ; @@ -60,4 +65,4 @@ if [ os.name ] = VMS } } -IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ; +#IMPORT $(__name__) : yfc-compile yfc-link : : yfc-compile yfc-link ; diff --git a/tools/build/test/project_id.py b/tools/build/test/project_id.py index 7f4070e07a..6477f59575 100755 --- a/tools/build/test/project_id.py +++ b/tools/build/test/project_id.py @@ -98,7 +98,7 @@ project /project-a3 ; """) t.run_build_system() - t.expect_addition("bin/$toolset/b%d._b" % x for x in range(1, 8)) + t.expect_addition("bin/b%d._b" % x for x in range(1, 8)) t.expect_nothing_more() t.cleanup() @@ -280,7 +280,7 @@ bbb b-invalid-target : /foo//invalid ; """) t.run_build_system(["b1", "b2"]) - t.expect_addition("bin/$toolset/debug*/b%d._b" % x for x in range(1, 3)) + t.expect_addition("bin/b%d._b" % x for x in range(1, 3)) t.expect_nothing_more() t.run_build_system(["b-invalid"], status=1) diff --git a/tools/build/test/project_root_rule.py b/tools/build/test/project_root_rule.py index 956c8953bd..503b3cad21 100644 --- a/tools/build/test/project_root_rule.py +++ b/tools/build/test/project_root_rule.py @@ -29,6 +29,6 @@ my-lib foo ; t.run_build_system(subdir="sub") -t.expect_addition("sub/bin/$toolset/debug/link-static*/foo.lib") +t.expect_addition("sub/bin/$toolset/debug*/foo.lib") t.cleanup() diff --git a/tools/build/test/project_test3.py b/tools/build/test/project_test3.py index 82b238f68d..ddd24e8481 100644 --- a/tools/build/test/project_test3.py +++ b/tools/build/test/project_test3.py @@ -24,7 +24,7 @@ t.run_build_system() t.expect_addition("bin/$toolset/debug*/a.obj") t.expect_content("bin/$toolset/debug*/a.obj", """\ -$toolset/debug +$toolset/debug* a.cpp """) @@ -39,43 +39,43 @@ t.expect_content("bin/$toolset/debug*/a.exe", t.expect_addition("lib/bin/$toolset/debug*/b.obj") t.expect_content("lib/bin/$toolset/debug*/b.obj", """\ -$toolset/debug +$toolset/debug* lib/b.cpp """) t.expect_addition("lib/bin/$toolset/debug*/m.exe") t.expect_content("lib/bin/$toolset/debug*/m.exe", """\ -$toolset/debug +$toolset/debug* lib/bin/$toolset/debug*/b.obj lib2/bin/$toolset/debug*/c.obj """) t.expect_addition("lib2/bin/$toolset/debug*/c.obj") t.expect_content("lib2/bin/$toolset/debug*/c.obj", """\ -$toolset/debug +$toolset/debug* lib2/c.cpp """) t.expect_addition("lib2/bin/$toolset/debug*/d.obj") t.expect_content("lib2/bin/$toolset/debug*/d.obj", """\ -$toolset/debug +$toolset/debug* lib2/d.cpp """) t.expect_addition("lib2/bin/$toolset/debug*/l.exe") t.expect_content("lib2/bin/$toolset/debug*/l.exe", """\ -$toolset/debug +$toolset/debug* lib2/bin/$toolset/debug*/c.obj bin/$toolset/debug*/a.obj """) t.expect_addition("lib2/helper/bin/$toolset/debug*/e.obj") t.expect_content("lib2/helper/bin/$toolset/debug*/e.obj", """\ -$toolset/debug +$toolset/debug* lib2/helper/e.cpp """) t.expect_addition("lib3/bin/$toolset/debug*/f.obj") t.expect_content("lib3/bin/$toolset/debug*/f.obj", """\ -$toolset/debug +$toolset/debug* lib3/f.cpp lib2/helper/bin/$toolset/debug*/e.obj """) diff --git a/tools/build/test/project_test4.py b/tools/build/test/project_test4.py index ee12c4d910..30aabaccea 100644 --- a/tools/build/test/project_test4.py +++ b/tools/build/test/project_test4.py @@ -16,13 +16,13 @@ t.run_build_system() t.expect_addition("bin/$toolset/debug*/a.obj") t.expect_content("bin/$toolset/debug*/a.obj", -"""$toolset/debug*/include-everything +"""$toolset/debug*/include-everything* a.cpp """) t.expect_addition("bin/$toolset/debug*/a.exe") t.expect_content("bin/$toolset/debug*/a.exe", -"$toolset/debug*/include-everything\n" + +"$toolset/debug*/include-everything*\n" + "bin/$toolset/debug*/a.obj lib/bin/$toolset/debug/optimization-speed*/b.obj\n" ) diff --git a/tools/build/test/rebuilds.py b/tools/build/test/rebuilds.py index 89ad4d84f7..8242e3ec03 100644 --- a/tools/build/test/rebuilds.py +++ b/tools/build/test/rebuilds.py @@ -21,7 +21,7 @@ def wait_for_bar(t): t.wait_for_time_change("bar", touch=False) -t = BoostBuild.Tester(["-ffile.jam", "-d+3", "-d+12", "-d+13"], pass_d0=False, +t = BoostBuild.Tester(["-ffile.jam", "-d+3", "-d+12", "-d+13"], pass_toolset=0) t.write("file.jam", """\ diff --git a/tools/build/test/regression.py b/tools/build/test/regression.py deleted file mode 100644 index 071e7ca54c..0000000000 --- a/tools/build/test/regression.py +++ /dev/null @@ -1,113 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) Vladimir Prus 2003. -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# Test for the regression testing framework. - -import BoostBuild - -# Create a temporary working directory. -t = BoostBuild.Tester(use_test_config=False) - -t.write("c.cpp", "\n") -t.write("r.cpp", """\ -void helper(); - -#include -int main( int ac, char * av[] ) -{ - helper(); - for ( int i = 1; i < ac; ++i ) - std::cout << av[ i ] << '\\n'; -} -""") -t.write("c-f.cpp", "int\n") -t.write("r-f.cpp", "int main() { return 1; }\n") - -t.write("jamroot.jam", "") -t.write("jamfile.jam", """\ -import testing ; -compile c.cpp ; -compile-fail c-f.cpp ; -run r.cpp libs//helper : foo bar ; -run-fail r-f.cpp ; -""") - -t.write("libs/jamfile.jam", "lib helper : helper.cpp ;") -t.write("libs/helper.cpp", """\ -void -#if defined(_WIN32) -__declspec(dllexport) -#endif -helper() {} -""") - -# First test that when outcomes are expected, all .test files are created. -t.run_build_system(["hardcode-dll-paths=false"], stderr=None, status=None) -t.expect_addition("bin/c.test/$toolset/debug*/c.test") -t.expect_addition("bin/c-f.test/$toolset/debug*/c-f.test") -t.expect_addition("bin/r.test/$toolset/debug*/r.test") -t.expect_addition("bin/r-f.test/$toolset/debug*/r-f.test") - -# Make sure args are handled. -t.expect_content("bin/r.test/$toolset/debug*/r.output", - "foo\nbar\n*\nEXIT STATUS: 0*\n", True) - -# Test that input file is handled as well. -t.write("r.cpp", """\ -#include -#include -int main( int ac, char * av[] ) -{ - for ( int i = 1; i < ac; ++i ) - { - std::ifstream ifs( av[ i ] ); - std::cout << ifs.rdbuf(); - } -} -""") - -t.write("dir/input.txt", "test input") - -t.write("jamfile.jam", """\ -import testing ; -compile c.cpp ; -obj c-obj : c.cpp ; -compile-fail c-f.cpp ; -run r.cpp : : dir/input.txt ; -run-fail r-f.cpp ; -time execution : r ; -time compilation : c-obj ; -""") - -t.run_build_system(["hardcode-dll-paths=false"]) -t.expect_content("bin/r.test/$toolset/debug*/r.output", """\ -test input -EXIT STATUS: 0 -""") - -t.expect_addition('bin/$toolset/debug*/execution.time') -t.expect_addition('bin/$toolset/debug*/compilation.time') - -# Make sure test failures are detected. Reverse expectation and see if .test -# files are created or not. -t.write("jamfile.jam", """\ -import testing ; -compile-fail c.cpp ; -compile c-f.cpp ; -run-fail r.cpp : : dir/input.txt ; -run r-f.cpp ; -""") - -t.touch(BoostBuild.List("c.cpp c-f.cpp r.cpp r-f.cpp")) - -t.run_build_system(["hardcode-dll-paths=false"], stderr=None, status=1) -t.expect_removal("bin/c.test/$toolset/debug*/c.test") -t.expect_removal("bin/c-f.test/$toolset/debug*/c-f.test") -t.expect_removal("bin/r.test/$toolset/debug*/r.test") -t.expect_removal("bin/r-f.test/$toolset/debug*/r-f.test") - -t.cleanup() diff --git a/tools/build/test/remove_requirement.py b/tools/build/test/remove_requirement.py index 8009e0f648..4a825c5a7c 100644 --- a/tools/build/test/remove_requirement.py +++ b/tools/build/test/remove_requirement.py @@ -12,6 +12,8 @@ t = BoostBuild.Tester(use_test_config=False) t.write("jamroot.jam", """ project : requirements multi debug:static ; +# Force link to be relevant +project : requirements shared:TEST_DLL ; build-project sub ; build-project sub2 ; @@ -41,7 +43,7 @@ int main() {} """) t.write("sub3/jamfile.jam", """ -exe hello : hello.cpp : -debug:static ; +exe hello : hello.cpp : "-debug:static" ; """) t.write("sub4/hello.cpp", """ @@ -49,7 +51,7 @@ int main() {} """) t.write("sub4/jamfile.jam", """ -project : requirements -debug:static ; +project : requirements "-debug:static" ; exe hello : hello.cpp ; """) diff --git a/tools/build/test/rescan_header.py b/tools/build/test/rescan_header.py index 37b37c7d41..1257a223c2 100755 --- a/tools/build/test/rescan_header.py +++ b/tools/build/test/rescan_header.py @@ -35,7 +35,7 @@ obj test : test.cpp : header3.h ; """) t.run_build_system(["-j2"]) -t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/header3.h") t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() @@ -72,9 +72,9 @@ obj test : test.cpp : """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug*/header1.h") -t.expect_addition("bin/$toolset/debug*/header2.h") -t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/header1.h") +t.expect_addition("bin/header2.h") +t.expect_addition("bin/header3.h") t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() @@ -122,9 +122,9 @@ obj test : test.cpp : """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug*/header1.h") -t.expect_addition("bin/$toolset/debug*/header2.h") -t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/header1.h") +t.expect_addition("bin/header2.h") +t.expect_addition("bin/header3.h") t.expect_addition("bin/$toolset/debug*/test.obj") t.expect_nothing_more() @@ -184,7 +184,7 @@ exe test : test2.cpp test1.cpp : header3.h ; """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug*/header3.h") +t.expect_addition("bin/header3.h") t.expect_addition("bin/$toolset/debug*/test1.obj") t.expect_addition("bin/$toolset/debug*/test2.obj") t.expect_addition("bin/$toolset/debug*/test.exe") @@ -192,7 +192,7 @@ t.expect_nothing_more() t.touch("header3.in") t.run_build_system(["-j2", "test"]) -t.expect_touch("bin/$toolset/debug*/header3.h") +t.expect_touch("bin/header3.h") t.expect_touch("bin/$toolset/debug*/test1.obj") t.expect_touch("bin/$toolset/debug*/test2.obj") t.expect_touch("bin/$toolset/debug*/test.exe") @@ -256,7 +256,7 @@ exe test : test2.cpp test1.cpp : header2.h . ; """) t.run_build_system(["-j2", "test"]) -t.expect_addition("bin/$toolset/debug*/header2.h") +t.expect_addition("bin/header2.h") t.expect_addition("bin/$toolset/debug*/test1.obj") t.expect_addition("bin/$toolset/debug*/test2.obj") t.expect_addition("bin/$toolset/debug*/test.exe") diff --git a/tools/build/test/source_order.py b/tools/build/test/source_order.py index d3cc2ab206..f21710a8cf 100755 --- a/tools/build/test/source_order.py +++ b/tools/build/test/source_order.py @@ -74,8 +74,8 @@ t.write("file2.c", "") t.write("file3.c", "") t.run_build_system() -t.expect_addition("bin/$toolset/debug*/check.order-test") -t.expect_content("bin/$toolset/debug*/check.order-test", """\ +t.expect_addition("bin/check.order-test") +t.expect_content("bin/check.order-test", """\ file2.c file1.c file3.c diff --git a/tools/build/test/space_in_path.py b/tools/build/test/space_in_path.py index 4cd320c5b4..7f0c041a3a 100755 --- a/tools/build/test/space_in_path.py +++ b/tools/build/test/space_in_path.py @@ -7,15 +7,45 @@ # Test that paths containing spaces are handled correctly by actions. import BoostBuild +import os t = BoostBuild.Tester(use_test_config=False) t.write("has space/jamroot.jam", """\ import testing ; unit-test test : test.cpp ; +actions write-file +{ + @(STDOUT:E=okay) >"$(<)" +} +make test.txt : : @write-file ; """) t.write("has space/test.cpp", "int main() {}\n") -t.run_build_system(["has space"]) +tmpdir = t.workpath("has space") +try: + oldtmp = os.environ["TMP"] +except: + oldtmp = None +try: + oldtmpdir = os.environ["TMPDIR"] +except: + oldtmpdir = None +os.environ["TMP"] = tmpdir; # Windows +os.environ["TMPDIR"] = tmpdir; # *nix + +try: + t.run_build_system(["has space"]) + t.expect_addition("has space/bin/test.txt") + t.expect_addition("has space/bin/$toolset/debug*/test.passed") +finally: + if oldtmp is not None: + os.environ["TMP"] = oldtmp + else: + del os.environ["TMP"] + if oldtmpdir is not None: + os.environ["TMPDIR"] = oldtmpdir + else: + del os.environ["TMPDIR"] t.cleanup() diff --git a/tools/build/test/static_and_shared_library.py b/tools/build/test/static_and_shared_library.py index da010a241f..5b3a6b73a5 100755 --- a/tools/build/test/static_and_shared_library.py +++ b/tools/build/test/static_and_shared_library.py @@ -31,7 +31,7 @@ t.expect_nothing_more() reset() t.run_build_system(["link=static"], subdir="lib") -t.expect_addition("lib/bin/$toolset/debug/link-static*/" * BoostBuild.List( +t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List( "c.obj auxilliary1.lib auxilliary2.lib")) t.expect_nothing_more() diff --git a/tools/build/test/suffix.py b/tools/build/test/suffix.py index b6946a48a8..b31dd17309 100644 --- a/tools/build/test/suffix.py +++ b/tools/build/test/suffix.py @@ -73,6 +73,6 @@ second a : a.cpp ; """) t.run_build_system() -t.expect_addition("bin/$toolset/debug*/a") +t.expect_addition("bin/a") t.cleanup() diff --git a/tools/build/test/tag.py b/tools/build/test/tag.py index 87f537c8c4..adf2fce6f1 100644 --- a/tools/build/test/tag.py +++ b/tools/build/test/tag.py @@ -91,11 +91,11 @@ __declspec (dllexport) void x () {} BoostBuild.List("bin/$toolset/release*/a_rs.exe") + BoostBuild.List("bin/$toolset/release*/b_rs.dll") + BoostBuild.List("c/a_rs.exe") + - BoostBuild.List("bin/$toolset/debug/link-static*/a_dt.exe") + - BoostBuild.List("bin/$toolset/debug/link-static*/b_dt.lib") + + BoostBuild.List("bin/$toolset/debug*/a_dt.exe") + + BoostBuild.List("bin/$toolset/debug*/b_dt.lib") + BoostBuild.List("c/a_dt.exe") + - BoostBuild.List("bin/$toolset/release/link-static*/a_rt.exe") + - BoostBuild.List("bin/$toolset/release/link-static*/b_rt.lib") + + BoostBuild.List("bin/$toolset/release*/a_rt.exe") + + BoostBuild.List("bin/$toolset/release*/b_rt.lib") + BoostBuild.List("c/a_rt.exe")) variants = ["debug", "release", "link=static,shared"] diff --git a/tools/build/test/test_all.py b/tools/build/test/test_all.py index fe97acd1a4..9efddc8610 100644 --- a/tools/build/test/test_all.py +++ b/tools/build/test/test_all.py @@ -96,6 +96,7 @@ def run_tests(critical_tests, other_tests): print("PASSED") else: print("FAILED") + BoostBuild.flush_annotations() else: rs = "succeed" if not passed: @@ -166,6 +167,7 @@ tests = ["absolute_sources", "bad_dirname", "build_dir", "build_file", + "build_hooks", "build_no", "builtin_echo", "builtin_exit", @@ -175,18 +177,21 @@ tests = ["absolute_sources", "c_file", "chain", "clean", + "command_line_properties", "composite", "conditionals", "conditionals2", "conditionals3", "conditionals_multiple", "configuration", + "configure", "copy_time", "core_action_output", "core_action_status", "core_actions_quietly", "core_at_file", "core_bindrule", + "core_fail_expected", "core_jamshell", "core_multifile_actions", "core_nt_cmd_line", @@ -196,6 +201,7 @@ tests = ["absolute_sources", "core_parallel_actions", "core_parallel_multifile_actions_1", "core_parallel_multifile_actions_2", + "core_scanner", "core_source_line_tracking", "core_update_now", "core_variables_in_actions", @@ -208,7 +214,6 @@ tests = ["absolute_sources", # "default_toolset", "dependency_property", "dependency_test", - "direct_request_test", "disambiguation", "dll_path", "double_loading", @@ -219,7 +224,11 @@ tests = ["absolute_sources", "expansion", "explicit", "feature_cxxflags", - "free_features_request", + "feature_implicit_dependency", + "feature_relevant", + "feature_suppress_import_lib", + "file_types", + "flags", "generator_selection", "generators_test", "implicit_dependency", @@ -227,7 +236,11 @@ tests = ["absolute_sources", "inherit_toolset", "inherited_dependency", "inline", + "libjpeg", + "liblzma", + "libzstd", "lib_source_property", + "lib_zlib", "library_chain", "library_property", "link", @@ -240,6 +253,7 @@ tests = ["absolute_sources", "notfile", "ordered_include", "out_of_tree", + "param", "path_features", "prebuilt", "print", @@ -252,7 +266,6 @@ tests = ["absolute_sources", "project_test4", "property_expansion", "rebuilds", - "regression", "relative_sources", "remove_requirement", "rescan_header", @@ -269,10 +282,16 @@ tests = ["absolute_sources", "static_and_shared_library", "suffix", "tag", - "test_result_dumping", "test_rc", - "testing_support", + "testing", "timedata", + "toolset_clang_darwin", + "toolset_clang_linux", + "toolset_clang_vxworks", + "toolset_darwin", + "toolset_defaults", + "toolset_gcc", + "toolset_intel_darwin", "toolset_requirements", "unit_test", "unused", @@ -280,7 +299,6 @@ tests = ["absolute_sources", "using", "wrapper", "wrong_project", - "zlib" ] if os.name == "posix": diff --git a/tools/build/test/test_rc.py b/tools/build/test/test_rc.py index 1ffac15b06..56c02b7ef1 100755 --- a/tools/build/test/test_rc.py +++ b/tools/build/test/test_rc.py @@ -34,7 +34,7 @@ def included_resource_newer_than_rc_script(): # affected by any local (mis)configuration.. t = BoostBuild.Tester(["-d4", "--debug-configuration", "--ignore-site-config", "--user-config=", "toolset=%s" % toolsetName], - pass_d0=False, pass_toolset=False, use_test_config=False, + pass_toolset=False, use_test_config=False, translate_suffixes=False) # Prepare a dummy toolset so we do not get errors in case the default one @@ -113,7 +113,7 @@ set_generated_obj_suffix('cygwin') # Prepare project source files. t.write("jamroot.jam", """\ -ECHO {{{ [ modules.peek : XXX ] [ modules.peek : NOEXEC ] }}} ; +ECHO "{{{" [ modules.peek : XXX ] [ modules.peek : NOEXEC ] "}}}" ; obj xxx : xxx.rc ; """) t.write("xxx.rc", '1 MESSAGETABLE "xxx.bin"\n') diff --git a/tools/build/test/test_result_dumping.py b/tools/build/test/test_result_dumping.py deleted file mode 100755 index bdfc41ee22..0000000000 --- a/tools/build/test/test_result_dumping.py +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/python - -# Copyright 2008 Jurko Gospodnetic -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -# Tests dumping Boost Build based testing results. - -import BoostBuild - - -############################################################################### -# -# Test that dumping Boost Build based testing results works in case test code -# is not located in a folder under the Jamroot folder. -# -############################################################################### - -t = BoostBuild.Tester(["--dump-tests"], use_test_config=False) - -t.write("TestBuild/jamroot.jam", """\ -import testing ; -test-suite testit : [ run ../TestSource/test.cpp ] ; -""") - -t.write("TestSource/test.cpp", "int main() {}\n") - -t.run_build_system(subdir="TestBuild") -t.expect_output_lines('boost-test(RUN) "*/TestBuild/test" : ' - '"../TestSource/test.cpp"') - -t.cleanup() diff --git a/tools/build/test/testing.py b/tools/build/test/testing.py new file mode 100755 index 0000000000..741040123b --- /dev/null +++ b/tools/build/test/testing.py @@ -0,0 +1,535 @@ +#!/usr/bin/python + +# Copyright 2008 Jurko Gospodnetic +# Copyright 2017 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +# Tests different aspects of Boost Builds automated testing support. + +import BoostBuild +import TestCmd + +def test_run(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +run pass.cpp ; +run fail-compile.cpp ; +run fail-link.cpp ; +run fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.run") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") + + t.expect_nothing_more() + + t.cleanup() + +def test_run_fail(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +run-fail pass.cpp ; +run-fail fail-compile.cpp ; +run-fail fail-link.cpp ; +run-fail fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.run") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") + + t.expect_nothing_more() + + t.cleanup() + +def test_run_change(): + """Tests that the test file is removed when a test fails after it + previously passed.""" + + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() { return 1; }\n") + t.write("fail-compile.cpp", "int main() {}\n") + t.write("fail-link.cpp", "int main() {}\n") + t.write("fail-run.cpp", "int main() {}\n") + + t.write("Jamroot.jam", """import testing ; +run-fail pass.cpp ; +run fail-compile.cpp ; +run fail-link.cpp ; +run fail-run.cpp ; +""") + t.run_build_system() + # Sanity check + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") + t.expect_output_lines("...failed*", False) + + # Now make them fail + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + t.run_build_system(status=1) + + t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") + t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + t.expect_removal("bin/fail-link.test/$toolset/debug*/fail-link.test") + t.expect_removal("bin/fail-run.test/$toolset/debug*/fail-run.test") + + t.cleanup() + +def test_run_path(): + """Tests that run can find shared libraries even without + hardcode-dll-paths. Important: The library is in neither the + current working directory, nor any system path, nor the same + directory as the executable, so it should never be found without + help from Boost.Build.""" + t = BoostBuild.Tester(["hardcode-dll-paths=false"], use_test_config=False) + + t.write("l.cpp", """ +void +#if defined(_WIN32) +__declspec(dllexport) +#endif +f() {} +""") + t.write("pass.cpp", "void f(); int main() { f(); }\n") + + t.write("Jamroot.jam", """import testing ; +lib l : l.cpp : shared ; +run pass.cpp l ; +""") + + t.run_build_system() + t.expect_addition("bin/$toolset/debug*/l.obj") + t.expect_addition("bin/$toolset/debug*/l.dll") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.output") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.run") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + + t.cleanup() + +def test_run_args(): + """Tests the handling of args and input-files""" + t = BoostBuild.Tester(use_test_config=False) + t.write("test.cpp", """ +#include +#include +int main(int argc, const char ** argv) +{ + for(int i = 1; i < argc; ++i) + { + if(argv[i][0] == '-') + { + std::cout << argv[i] << std::endl; + } + else + { + std::ifstream ifs(argv[i]); + std::cout << ifs.rdbuf(); + } + } +} +""") + t.write("input1.in", "first input\n") + t.write("input2.in", "second input\n") + t.write("Jamroot.jam", """import testing ; +import common ; +# FIXME: The order actually depends on the lexigraphical +# ordering of the virtual target objects, which is just +# crazy. Switch the order of input1.txt and input2.txt +# to make this fail. Joining the arguments with && might +# work, but might get a bit complicated to implement as +# dependency properties do not currently support &&. +make input1.txt : input1.in : @common.copy ; +make input2.txt : input2.in : @common.copy ; +run test.cpp : -y -a : input1.txt input2.txt ; +""") + t.run_build_system() + t.expect_content("bin/test.test/$toolset/debug*/test.output", """\ +-y +-a +first input +second input + +EXIT STATUS: 0 +""") + t.cleanup() + +def test_link(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +link pass.cpp ; +link fail-compile.cpp ; +link fail-link.cpp ; +link fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.exe") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.exe") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") + + t.expect_nothing_more() + + t.cleanup() + +def test_link_fail(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +link-fail pass.cpp ; +link-fail fail-compile.cpp ; +link-fail fail-link.cpp ; +link-fail fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.exe") + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") + + t.expect_nothing_more() + + t.cleanup() + +def test_link_change(): + """Tests that the test file is removed when a test fails after it + previously passed.""" + + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-compile.cpp", "int main() {}\n") + t.write("fail-link.cpp", "int main() {}\n") + + t.write("Jamroot.jam", """import testing ; +link-fail pass.cpp ; +link fail-compile.cpp ; +link fail-link.cpp ; +""") + t.run_build_system() + # Sanity check + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") + t.expect_output_lines("...failed*", False) + + # Now make them fail + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.run_build_system(status=1) + + t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") + t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + t.expect_removal("bin/fail-link.test/$toolset/debug*/fail-link.test") + + t.cleanup() + +def test_compile(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +compile pass.cpp ; +compile fail-compile.cpp ; +compile fail-link.cpp ; +compile fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/pass.test/$toolset/debug*/pass.obj") + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.obj") + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.obj") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") + + t.expect_nothing_more() + + t.cleanup() + +def test_compile_fail(): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +compile-fail pass.cpp ; +compile-fail fail-compile.cpp ; +compile-fail fail-link.cpp ; +compile-fail fail-run.cpp ; +""") + + t.run_build_system(status=1) + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.obj") + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + + t.expect_nothing_more() + + t.cleanup() + +def test_compile_change(): + """Tests that the test file is removed when a test fails after it + previously passed.""" + + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass.cpp", "#error expected to fail\n") + t.write("fail-compile.cpp", "int main() {}\n") + + t.write("Jamroot.jam", """import testing ; +compile-fail pass.cpp ; +compile fail-compile.cpp ; +""") + t.run_build_system() + # Sanity check + t.expect_addition("bin/pass.test/$toolset/debug*/pass.test") + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + t.expect_output_lines("...failed*", False) + + # Now make them fail + t.write("pass.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.run_build_system(status=1) + + t.expect_removal("bin/pass.test/$toolset/debug*/pass.test") + t.expect_removal("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + + t.cleanup() + +def test_remove_test_targets(option): + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass-compile.cpp", "int main() {}\n") + t.write("pass-link.cpp", "int main() {}\n") + t.write("pass-run.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + t.write("source.cpp", "int f();\n") + + t.write("Jamroot.jam", """import testing ; +obj source.o : source.cpp ; +compile pass-compile.cpp ; +link pass-link.cpp source.o ; +run pass-run.cpp source.o ; +compile-fail fail-compile.cpp ; +link-fail fail-link.cpp ; +run-fail fail-run.cpp ; +""") + + t.run_build_system([option]) + + t.expect_addition("bin/$toolset/debug*/source.obj") + + t.expect_addition("bin/pass-compile.test/$toolset/debug*/pass-compile.test") + + t.expect_addition("bin/pass-link.test/$toolset/debug*/pass-link.test") + + t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.output") + t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.run") + t.expect_addition("bin/pass-run.test/$toolset/debug*/pass-run.test") + + t.expect_addition("bin/fail-compile.test/$toolset/debug*/fail-compile.test") + + t.expect_addition("bin/fail-link.test/$toolset/debug*/fail-link.test") + + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.output") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.run") + t.expect_addition("bin/fail-run.test/$toolset/debug*/fail-run.test") + + t.expect_nothing_more() + + t.cleanup() + +def test_dump_tests(): + """Tests the output of the --dump-tests option""" + t = BoostBuild.Tester(use_test_config=False) + + t.write("pass-compile.cpp", "int main() {}\n") + t.write("pass-link.cpp", "int main() {}\n") + t.write("pass-run.cpp", "int main() {}\n") + t.write("fail-compile.cpp", "#error expected to fail\n") + t.write("fail-link.cpp", "int f();\nint main() { return f(); }\n") + t.write("fail-run.cpp", "int main() { return 1; }\n") + + t.write("Jamroot.jam", """import testing ; +run pass-run.cpp ; +run-fail fail-run.cpp ; +link pass-link.cpp ; +link-fail fail-link.cpp ; +compile pass-compile.cpp ; +compile-fail fail-compile.cpp ; +build-project libs/any/test ; +build-project libs/any/example ; +build-project libs/any ; +build-project tools/bcp/test ; +build-project tools/bcp/example ; +build-project subdir/test ; +build-project status ; +build-project outside/project ; +""") + def write_subdir(dir): + t.write(dir + "/test.cpp", "int main() {}\n") + t.write(dir + "/Jamfile", "run test.cpp ;") + write_subdir("libs/any/test") + write_subdir("libs/any/example") + write_subdir("libs/any") + write_subdir("tools/bcp/test") + write_subdir("tools/bcp/example") + write_subdir("status") + write_subdir("subdir/test") + t.write("outside/other/test.cpp", "int main() {}\n") + t.write("outside/project/Jamroot", "run ../other/test.cpp ;") + t.run_build_system(["--dump-tests", "-n", "-d0"], + match=TestCmd.match_re, stdout= +"""boost-test\(RUN\) ".*/pass-run" : "pass-run\.cpp" +boost-test\(RUN_FAIL\) ".*/fail-run" : "fail-run\.cpp" +boost-test\(LINK\) ".*/pass-link" : "pass-link\.cpp" +boost-test\(LINK_FAIL\) ".*/fail-link" : "fail-link\.cpp" +boost-test\(COMPILE\) ".*/pass-compile" : "pass-compile\.cpp" +boost-test\(COMPILE_FAIL\) ".*/fail-compile" : "fail-compile\.cpp" +boost-test\(RUN\) "any/test" : "libs/any/test\.cpp" +boost-test\(RUN\) "any/test" : "libs/any/test/test\.cpp" +boost-test\(RUN\) "any/test" : "libs/any/example/test\.cpp" +boost-test\(RUN\) "bcp/test" : "tools/bcp/test/test\.cpp" +boost-test\(RUN\) "bcp/test" : "tools/bcp/example/test\.cpp" +boost-test\(RUN\) ".*/subdir/test/test" : "subdir/test/test\.cpp" +boost-test\(RUN\) "test" : "status/test\.cpp" +boost-test\(RUN\) ".*/outside/project/test" : "../other/test.cpp" +""") + t.cleanup() + +################################################################################ +# +# test_files_with_spaces_in_their_name() +# -------------------------------------- +# +################################################################################ + +def test_files_with_spaces_in_their_name(): + """Regression test making sure test result files get created correctly when + testing files with spaces in their name. + """ + + t = BoostBuild.Tester(use_test_config=False) + + t.write("valid source.cpp", "int main() {}\n"); + + t.write("invalid source.cpp", "this is not valid source code"); + + t.write("jamroot.jam", """ +import testing ; +testing.compile "valid source.cpp" ; +testing.compile-fail "invalid source.cpp" ; +""") + + t.run_build_system(status=0) + t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.obj") + t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.test") + t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.obj") + t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.test") + + t.expect_content("bin/valid source.test/$toolset/debug*/valid source.test", \ + "passed" ) + t.expect_content( \ + "bin/invalid source.test/$toolset/debug*/invalid source.test", \ + "passed" ) + t.expect_content( \ + "bin/invalid source.test/$toolset/debug*/invalid source.obj", \ + "failed as expected" ) + + t.cleanup() + + +################################################################################ +# +# main() +# ------ +# +################################################################################ + +test_run() +test_run_fail() +test_run_change() +test_run_path() +test_run_args() +test_link() +test_link_fail() +test_link_change() +test_compile() +test_compile_fail() +test_compile_change() +test_remove_test_targets("--remove-test-targets") +test_remove_test_targets("preserve-test-targets=off") +test_dump_tests() +test_files_with_spaces_in_their_name() diff --git a/tools/build/test/testing_support.py b/tools/build/test/testing_support.py deleted file mode 100755 index c76a1f2a74..0000000000 --- a/tools/build/test/testing_support.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python - -# Copyright 2008 Jurko Gospodnetic -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) - -# Tests different aspects of Boost Builds automated testing support. - -import BoostBuild - - -################################################################################ -# -# test_files_with_spaces_in_their_name() -# -------------------------------------- -# -################################################################################ - -def test_files_with_spaces_in_their_name(): - """Regression test making sure test result files get created correctly when - testing files with spaces in their name. - """ - - t = BoostBuild.Tester(use_test_config=False) - - t.write("valid source.cpp", "int main() {}\n"); - - t.write("invalid source.cpp", "this is not valid source code"); - - t.write("jamroot.jam", """ -import testing ; -testing.compile "valid source.cpp" ; -testing.compile-fail "invalid source.cpp" ; -""") - - t.run_build_system(status=0) - t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.obj") - t.expect_addition("bin/invalid source.test/$toolset/debug*/invalid source.test") - t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.obj") - t.expect_addition("bin/valid source.test/$toolset/debug*/valid source.test") - - t.expect_content("bin/valid source.test/$toolset/debug*/valid source.test", \ - "passed" ) - t.expect_content( \ - "bin/invalid source.test/$toolset/debug*/invalid source.test", \ - "passed" ) - t.expect_content( \ - "bin/invalid source.test/$toolset/debug*/invalid source.obj", \ - "failed as expected" ) - - t.cleanup() - - -################################################################################ -# -# main() -# ------ -# -################################################################################ - -test_files_with_spaces_in_their_name() diff --git a/tools/build/test/toolset-mock/Jamroot.jam b/tools/build/test/toolset-mock/Jamroot.jam new file mode 100644 index 0000000000..fd5f7907b6 --- /dev/null +++ b/tools/build/test/toolset-mock/Jamroot.jam @@ -0,0 +1,8 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +lib l1 : lib.cpp ; +exe test : main.cpp l1 ; diff --git a/tools/build/test/toolset-mock/lib.cpp b/tools/build/test/toolset-mock/lib.cpp new file mode 100644 index 0000000000..1ba30e32d2 --- /dev/null +++ b/tools/build/test/toolset-mock/lib.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2017 Steven Watanabe +// +// Distributed under the Boost Software License Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +int f() {} diff --git a/tools/build/test/toolset-mock/main.cpp b/tools/build/test/toolset-mock/main.cpp new file mode 100644 index 0000000000..0fc8b9a75c --- /dev/null +++ b/tools/build/test/toolset-mock/main.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2017 Steven Watanabe +// +// Distributed under the Boost Software License Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +int main() {} diff --git a/tools/build/test/toolset-mock/project-config.jam b/tools/build/test/toolset-mock/project-config.jam new file mode 100644 index 0000000000..4f30993d04 --- /dev/null +++ b/tools/build/test/toolset-mock/project-config.jam @@ -0,0 +1,40 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import modules ; + +path-constant here : . ; + +using gcc : 4.8.3 : python $(here)/src/gcc-4.8.3-linux.py : : linux ; +using gcc : 4.2.1 : python $(here)/src/gcc-4.2.1-darwin.py : : darwin ; + +# hard-code this to make the test work on other platforms +modules.poke darwin : .host-osx-version : 10.11.0 ; +using darwin : 4.2.1 : python $(here)/src/darwin-4.2.1.py + : $(here)/src/bin/libtool + $(here)/src/bin/strip + : darwin + ; + +using clang-darwin : 3.9.0 : python $(here)/src/clang-3.9.0-darwin.py + : $(here)/src/bin/ar + $(here)/src/bin/ranlib + ; + +using clang-linux : 3.9.0 : python $(here)/src/clang-linux-3.9.0.py + : $(here)/src/bin/ar + $(here)/src/bin/ranlib + ; + +using clang-vxworks : 4.0.1 : python $(here)/src/clang-vxworks-4.0.1.py + : $(here)/src/bin/ld + $(here)/src/bin/ar + ; + +using intel-darwin : 10.2 : python $(here)/src/intel-darwin-10.2.py + : $(here)/src/bin/ar + $(here)/src/bin/ranlib + ; diff --git a/tools/build/test/toolset-mock/src/Jamroot.jam b/tools/build/test/toolset-mock/src/Jamroot.jam new file mode 100644 index 0000000000..c8fc0078bc --- /dev/null +++ b/tools/build/test/toolset-mock/src/Jamroot.jam @@ -0,0 +1,61 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import os ; +import print ; +import regex ; +import feature ; + +.PYTHON = [ os.environ PYTHON_CMD ] ; +path-constant .AR : ar.py ; +path-constant .RANLIB : ranlib.py ; +path-constant .LIBTOOL : libtool.py ; +path-constant .STRIP : strip.py ; +path-constant .LD : ld.py ; + +rule c-escape ( str ) +{ + return [ regex.replace $(str) \\\\ \\\\ ] ; +} + +rule cfg-header ( target : : properties * ) +{ + local PYTHON = [ c-escape $(.PYTHON) ] ; + local AR = [ c-escape $(.AR) ] ; + local RANLIB = [ c-escape $(.RANLIB) ] ; + local LIBTOOL = [ c-escape $(.LIBTOOL) ] ; + local STRIP = [ c-escape $(.STRIP) ] ; + local LD = [ c-escape $(.LD) ] ; + print.output $(target) ; + print.text "#define PYTHON_CMD "\"$(PYTHON)\" : true ; + print.text "#define AR_CMD "\"$(AR)\" : true ; + print.text "#define RANLIB_CMD "\"$(RANLIB)\" : true ; + print.text "#define LIBTOOL_CMD "\"$(LIBTOOL)\" : true ; + print.text "#define STRIP_CMD "\"$(STRIP)\" : true ; + print.text "#define LD_CMD "\"$(LD)\" : true ; +} + +# We can only build one variant at a time and we need to have a fixed path +project : requirements bin ; + +make config.h : : @cfg-header ; + +project : requirements config.h ; + +rule write-target-os ( target : : properties * ) +{ + local target-os = [ feature.defaults ] ; + print.output $(target) ; + print.text $(target-os:G=) : true ; +} + +make target-os.txt : : @write-target-os ; + +exe ar : [ obj ar.obj : mock-program.cpp : PY_SCRIPT=AR_CMD ] ; +exe ranlib : [ obj ranlib.obj : mock-program.cpp : PY_SCRIPT=RANLIB_CMD ] ; +exe libtool : [ obj libtool.obj : mock-program.cpp : PY_SCRIPT=LIBTOOL_CMD ] ; +exe strip : [ obj strip.obj : mock-program.cpp : PY_SCRIPT=STRIP_CMD ] ; +exe ld : [ obj ld.obj : mock-program.cpp : PY_SCRIPT=LD_CMD ] ; diff --git a/tools/build/test/toolset-mock/src/MockProgram.py b/tools/build/test/toolset-mock/src/MockProgram.py new file mode 100644 index 0000000000..ce4723e1ec --- /dev/null +++ b/tools/build/test/toolset-mock/src/MockProgram.py @@ -0,0 +1,260 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import sys +import os +import re + +# Represents a sequence of arguments that must appear +# in a fixed order. +class ordered: + def __init__(self, *args): + self.args = args + def match(self, command_line, pos, outputs): + for p in self.args: + res = try_match(command_line, pos, p, outputs) + if res is None: + return + pos = res + return pos + +# Represents a sequence of arguments that can appear +# in any order. +class unordered: + def __init__(self, *args): + self.args = list(args) + def match(self, command_line, pos, outputs): + unmatched = self.args[:] + while len(unmatched) > 0: + res = try_match_one(command_line, pos, unmatched, outputs) + if res is None: + return + pos = res + return pos + +# Represents a single input file. +# If id is set, then the file must have been created +# by a prior use of output_file. +# If source is set, then the file must be that source file. +class input_file: + def __init__(self, id=None, source=None): + assert((id is None) ^ (source is None)) + self.id = id + self.source = source + def check(self, path): + if path.startswith("-"): + return + if self.id is not None: + try: + with open(path, "r") as f: + data = f.read() + if data == make_file_contents(self.id): + return True + else: + return + except: + return + elif self.source is not None: + if self.source == path: + return True + else: + return + assert(False) + def match(self, command_line, pos, outputs): + if self.check(command_line[pos]): + return pos + 1 + +# Matches an output file. +# If the full pattern is matched, The +# file will be created. +class output_file: + def __init__(self, id): + self.id = id + def match(self, command_line, pos, outputs): + if command_line[pos].startswith("-"): + return + outputs.append((command_line[pos], self.id)) + return pos + 1 + +# Matches the directory containing an input_file +class target_path(object): + def __init__(self, id): + self.tester = input_file(id=id) + def match(self, command_line, pos, outputs): + arg = command_line[pos] + if arg.startswith("-"): + return + try: + for path in os.listdir(arg): + if self.tester.check(os.path.join(arg, path)): + return pos + 1 + except: + return + +# Matches a single argument, which is composed of a prefix and a path +# for example arguments of the form -ofilename. +class arg(object): + def __init__(self, prefix, a): + # The prefix should be a string, a should be target_path or input_file. + self.prefix = prefix + self.a = a + def match(self, command_line, pos, outputs): + s = command_line[pos] + if s.startswith(self.prefix) and try_match([s[len(self.prefix):]], 0, self.a, outputs) == 1: + return pos + 1 + +# Given a file id, returns a string that will be +# written to the file to allow it to be recognized. +def make_file_contents(id): + return id + +# Matches a single pattern from a list. +# If it succeeds, the matching pattern +# is removed from the list. +# Returns the index after the end of the match +def try_match_one(command_line, pos, patterns, outputs): + for p in patterns: + tmp = outputs[:] + res = try_match(command_line, pos, p, tmp) + if res is not None: + outputs[:] = tmp + patterns.remove(p) + return res + +# returns the end of the match if any +def try_match(command_line, pos, pattern, outputs): + if pos == len(command_line): + return + elif type(pattern) is str: + if pattern == command_line[pos]: + return pos + 1 + else: + return pattern.match(command_line, pos, outputs) + +known_patterns = [] +program_name = None + +# Registers a command +# The arguments should be a sequence of: +# str, ordered, unordered, arg, input_file, output_file, target_path +# kwarg: stdout is text that will be printed on success. +def command(*args, **kwargs): + global known_patterns + global program_name + stdout = kwargs.get("stdout", None) + pattern = ordered(*args) + known_patterns += [(pattern, stdout)] + if program_name is None: + program_name = args[0] + else: + assert(program_name == args[0]) + +# Use this to filter the recognized commands, based on the properties +# passed to b2. +def allow_properties(*args): + try: + return all(a in os.environ["B2_PROPERTIES"].split(" ") for a in args) + except KeyError: + return True + +# Use this in the stdout argument of command to print the command +# for running another script. +def script(name): + return os.path.join(os.path.dirname(__file__), "bin", re.sub('\.py$', '', name)) + +def match(command_line): + for (p, stdout) in known_patterns: + outputs = [] + if try_match(command_line, 0, p, outputs) == len(command_line): + return (stdout, outputs) + +# Every mock program should call this after setting up all the commands. +def main(): + command_line = [program_name] + sys.argv[1:] + result = match(command_line) + if result is not None: + (stdout, outputs) = result + if stdout is not None: + print stdout + for (file,id) in outputs: + with open(file, "w") as f: + f.write(make_file_contents(id)) + exit(0) + else: + print command_line + exit(1) + +# file should be the name of a file in the same directory +# as this. Must be called after verify_setup +def verify_file(filename): + global known_files + if filename not in known_files: + known_files.add(filename) + srcdir = os.path.dirname(__file__) + execfile(os.path.join(srcdir, filename), {}) + +def verify_setup(): + """Override the behavior of most module components + in order to detect whether they are being used correctly.""" + global main + global allow_properties + global output_file + global input_file + global target_path + global script + global command + global verify_errors + global output_ids + global input_ids + global known_files + def allow_properties(*args): + return True + def main(): + pass + def output_file(id): + global output_ids + global verify_error + if id in output_ids: + verify_error("duplicate output_file: %s" % id) + output_ids.add(id) + def input_file(id=None, source=None): + if id is not None: + input_ids.add(id) + def target_path(id): + input_ids.add(id) + def script(filename): + verify_file(filename) + def command(*args, **kwargs): + pass + verify_errors = [] + output_ids = set() + input_ids = set() + known_files = set() + +def verify_error(message): + global verify_errors + verify_errors += [message] + +def verify_finalize(): + for id in input_ids: + if not id in output_ids: + verify_error("Input file does not exist: %s" % id) + for error in verify_errors: + print "error: %s" % error + if len(verify_errors) != 0: + return 1 + else: + return 0 + +def verify(): + srcdir = os.path.dirname(__file__) + if srcdir == '': + srcdir = '.' + verify_setup() + for f in os.listdir(srcdir): + if re.match(r"(gcc|clang|darwin|intel)-.*\.py", f): + verify_file(f) + exit(verify_finalize()) diff --git a/tools/build/test/toolset-mock/src/ar.py b/tools/build/test/toolset-mock/src/ar.py new file mode 100644 index 0000000000..853fe1dd8b --- /dev/null +++ b/tools/build/test/toolset-mock/src/ar.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +# +# Copyright 2017-2018 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('ar', 'rc', output_file('bin/gcc-gnu-4.8.3/debug/link-static/libl1.a'), input_file('bin/gcc-gnu-4.8.3/debug/link-static/lib.o')) +command('ar', 'rc', output_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/libl1.a'), input_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/lib.o')) +command('ar', 'rc', output_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/libl1.a'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/libl1.a'), input_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), input_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/libl1.a'), input_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), input_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/lib.o')) +command('ar', 'rc', output_file('bin/clang-linux-3.9.0/debug/link-static/libl1.a'), input_file('bin/clang-linux-3.9.0/debug/link-static/lib.o')) +command('ar', 'rc', output_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/libl1.a'), input_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/lib.o')) +command('ar', 'rcu', output_file('bin/clang-vxworks-4.0.1/debug/link-static/libl1.a'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/lib.o')) +command('ar', 'rcu', output_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/libl1.a'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/lib.o')) + +main() diff --git a/tools/build/test/toolset-mock/src/clang-3.9.0-darwin.py b/tools/build/test/toolset-mock/src/clang-3.9.0-darwin.py new file mode 100644 index 0000000000..d8c2163ab4 --- /dev/null +++ b/tools/build/test/toolset-mock/src/clang-3.9.0-darwin.py @@ -0,0 +1,49 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('clang++', '-print-prog-name=ar', stdout=script('ar.py')) +command('clang++', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +# all builds are multi-threaded for darwin +if allow_properties("variant=debug", "link=shared", "runtime-link=shared"): + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', '@rpath/libl1.dylib', input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/lib.o'), unordered('-g', '-fPIC')) + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/libl1.dylib'), unordered('-g', '-fPIC')) + +if allow_properties("variant=release", "link=shared", "runtime-link=shared"): + command('clang++', '-x', 'c++', unordered('-O3', '-Wno-inline', '-Wall', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/clang-darwin-3.9.0/release/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-v', '-o', output_file('bin/clang-darwin-3.9.0/release/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', '@rpath/libl1.dylib', input_file('bin/clang-darwin-3.9.0/release/target-os-darwin/lib.o'), '-fPIC') + command('clang++', '-x', 'c++', unordered('-O3', '-Wno-inline', '-Wall', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/clang-darwin-3.9.0/release/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-v', '-o', output_file('bin/clang-darwin-3.9.0/release/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/release/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/release/target-os-darwin/libl1.dylib'), '-fPIC') + +if allow_properties("variant=debug", "link=static", "runtime-link=shared"): + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/libl1.a'), '-g') + +if allow_properties("variant=debug", "link=static", "runtime-link=static"): + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), unordered('-g', '-static')) + +if allow_properties("variant=debug", "link=shared", "runtime-link=shared", "architecture=x86", "address-model=32"): + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-fPIC', '-m32'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', '@rpath/libl1.dylib', input_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/lib.o'), unordered('-g', '-march=i686', '-fPIC', '-m32')) + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-fPIC', '-m32'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/debug/x86/target-os-darwin/libl1.dylib'), unordered('-g', '-march=i686', '-fPIC', '-m32')) + +if allow_properties("variant=debug", "link=shared", "runtime-link=shared", "cxxstd=latest"): + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-std=c++1z'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', '@rpath/libl1.dylib', input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/lib.o'), unordered('-g', '-fPIC', '-std=c++1z')) + command('clang++', '-x', 'c++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-std=c++1z'), '-c', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/test'), input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/main.o'), input_file('bin/clang-darwin-3.9.0/debug/target-os-darwin/libl1.dylib'), unordered('-g', '-fPIC', '-std=c++1z')) + +main() diff --git a/tools/build/test/toolset-mock/src/clang-linux-3.9.0.py b/tools/build/test/toolset-mock/src/clang-linux-3.9.0.py new file mode 100644 index 0000000000..242d25624e --- /dev/null +++ b/tools/build/test/toolset-mock/src/clang-linux-3.9.0.py @@ -0,0 +1,48 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('clang++', '-print-prog-name=ar', stdout=script('ar.py')) +command('clang++', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/debug/libl1.so'), '-Wl,-soname', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-g', '-fPIC')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/main.o'), input_file(source='main.cpp')) + command('clang++', '-Wl,-R', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/libl1.so')), '-o', output_file('bin/clang-linux-3.9.0/debug/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/main.o'), input_file('bin/clang-linux-3.9.0/debug/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-g', '-fPIC')) + +if allow_properties('variant=release', 'link=shared', 'threading=single', 'runtime-link=shared', 'strip=on'): + command('clang++', unordered(ordered('-x', 'c++'), '-O3', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG', '-c'), '-o', output_file('bin/clang-linux-3.9.0/release/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/release/libl1.so'), '-Wl,-soname', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/release/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-fPIC', '-Wl,--strip-all')) + command('clang++', unordered(ordered('-x', 'c++'), '-O3', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG', '-c'), '-o', output_file('bin/clang-linux-3.9.0/release/main.o'), input_file(source='main.cpp')) + command('clang++', '-Wl,-R', arg('-Wl,', target_path('bin/clang-linux-3.9.0/release/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/clang-linux-3.9.0/release/libl1.so')), '-o', output_file('bin/clang-linux-3.9.0/release/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/release/main.o'), input_file('bin/clang-linux-3.9.0/release/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-fPIC', '-Wl,--strip-all')) + +if allow_properties('variant=debug', 'link=shared', 'threading=multi', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-pthread', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/threading-multi/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/debug/threading-multi/libl1.so'), '-Wl,-soname', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/threading-multi/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-lrt', '-Wl,--end-group', unordered('-g', '-pthread', '-fPIC')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-pthread', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/threading-multi/main.o'), input_file(source='main.cpp')) + command('clang++', '-Wl,-R', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/threading-multi/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/threading-multi/libl1.so')), '-o', output_file('bin/clang-linux-3.9.0/debug/threading-multi/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/threading-multi/main.o'), input_file('bin/clang-linux-3.9.0/debug/threading-multi/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-lrt', '-Wl,--end-group', unordered('-g', '-pthread', '-fPIC')) + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/link-static/main.o'), input_file('bin/clang-linux-3.9.0/debug/link-static/libl1.a'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', '-g') + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=static'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/main.o'), input_file(source='main.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/main.o'), input_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/libl1.a'), '-Wl,--end-group', unordered('-g', '-static')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared', 'architecture=x86', 'address-model=32'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-m32', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/lib.o'), input_file(source='lib.cpp')) + command('clang++', '-o', output_file('bin/clang-linux-3.9.0/debug/libl1.so'), '-Wl,-soname', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-g', '-march=i686', '-fPIC', '-m32')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-m32', '-fPIC', '-c'), '-o', output_file('bin/clang-linux-3.9.0/debug/main.o'), input_file(source='main.cpp')) + command('clang++', '-Wl,-R', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/clang-linux-3.9.0/debug/libl1.so')), '-o', output_file('bin/clang-linux-3.9.0/debug/test'), '-Wl,--start-group', input_file('bin/clang-linux-3.9.0/debug/main.o'), input_file('bin/clang-linux-3.9.0/debug/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', unordered('-g', '-march=i686', '-fPIC', '-m32')) + +main() diff --git a/tools/build/test/toolset-mock/src/clang-vxworks-4.0.1.py b/tools/build/test/toolset-mock/src/clang-vxworks-4.0.1.py new file mode 100644 index 0000000000..a1fbedb119 --- /dev/null +++ b/tools/build/test/toolset-mock/src/clang-vxworks-4.0.1.py @@ -0,0 +1,42 @@ +#!/usr/bin/python +# +# Copyright 2018 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('clang++', '-print-prog-name=ar', stdout=script('ar.py')) +command('clang++', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=release', 'link=shared', 'threading=single', 'runtime-link=shared', 'strip=on'): + command('clang++', unordered(ordered('-x', 'c++'), '-O3', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/release/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O3', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/release/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=debug', 'link=shared', 'threading=multi', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/threading-multi/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/threading-multi/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=shared'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=static'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared', 'architecture=x86', 'address-model=32'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-m32', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-Wall', '-g', '-march=i686', '-m32', '-fPIC', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/main.o'), input_file(source='main.cpp')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared', 'rtti=off', 'exception-handling=off'): + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-fno-rtti', '-fno-exceptions', '-Wall', '-g', '-fPIC', '-D_NO_RTTI', '-D_NO_EX=1', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/lib.o'), input_file(source='lib.cpp')) + command('clang++', unordered(ordered('-x', 'c++'), '-O0', '-fno-inline', '-fno-rtti', '-fno-exceptions', '-Wall', '-g', '-fPIC', '-D_NO_RTTI', '-D_NO_EX=1', '-c'), '-o', output_file('bin/clang-vxworks-4.0.1/debug/main.o'), input_file(source='main.cpp')) + +main() diff --git a/tools/build/test/toolset-mock/src/darwin-4.2.1.py b/tools/build/test/toolset-mock/src/darwin-4.2.1.py new file mode 100644 index 0000000000..d81359ca5c --- /dev/null +++ b/tools/build/test/toolset-mock/src/darwin-4.2.1.py @@ -0,0 +1,38 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +script("libtool.py") + +command('g++', '-dumpversion', stdout='4.2.1') + +# all builds are multi-threaded for darwin +if allow_properties("variant=debug", "link=shared", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-dynamic', '-gdwarf-2', '-fexceptions', '-fPIC'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', '-dynamiclib', '-Wl,-single_module', '-install_name', 'libl1.dylib', '-o', output_file('bin/darwin-4.2.1/debug/target-os-darwin/libl1.dylib'), input_file('bin/darwin-4.2.1/debug/target-os-darwin/lib.o'), '-headerpad_max_install_names', unordered('-g', '-fPIC')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-dynamic', '-gdwarf-2', '-fexceptions', '-fPIC'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/darwin-4.2.1/debug/target-os-darwin/test'), input_file('bin/darwin-4.2.1/debug/target-os-darwin/main.o'), input_file('bin/darwin-4.2.1/debug/target-os-darwin/libl1.dylib'), unordered('-g', '-fPIC')) + +if allow_properties("variant=release", "link=shared", "runtime-link=shared"): + command('g++', unordered('-O3', '-Wno-inline', '-Wall', '-dynamic', '-gdwarf-2', '-fexceptions', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/darwin-4.2.1/release/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', '-dynamiclib', '-Wl,-single_module', '-install_name', 'libl1.dylib', '-o', output_file('bin/darwin-4.2.1/release/target-os-darwin/libl1.dylib'), input_file('bin/darwin-4.2.1/release/target-os-darwin/lib.o'), '-headerpad_max_install_names', unordered(ordered('-Wl,-dead_strip', '-no_dead_strip_inits_and_terms'), '-fPIC')) + command('g++', unordered('-O3', '-Wno-inline', '-Wall', '-dynamic', '-gdwarf-2', '-fexceptions', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/darwin-4.2.1/release/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/darwin-4.2.1/release/target-os-darwin/test'), input_file('bin/darwin-4.2.1/release/target-os-darwin/main.o'), input_file('bin/darwin-4.2.1/release/target-os-darwin/libl1.dylib'), unordered(ordered('-Wl,-dead_strip', '-no_dead_strip_inits_and_terms'), '-fPIC')) + +if allow_properties("variant=debug", "link=static", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-gdwarf-2', '-fexceptions'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-gdwarf-2', '-fexceptions'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/test'), input_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/main.o'), input_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/libl1.a'), '-g') + +if allow_properties("variant=debug", "link=static", "runtime-link=static"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-gdwarf-2', '-fexceptions'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-gdwarf-2', '-fexceptions'), '-c', '-o', output_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/test'), input_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), unordered('-g', ordered('-nodefaultlibs', '-shared-libgcc', '-lstdc++-static', '-lgcc_eh', '-lgcc', '-lSystem'), '-static')) + +main() diff --git a/tools/build/test/toolset-mock/src/gcc-4.2.1-darwin.py b/tools/build/test/toolset-mock/src/gcc-4.2.1-darwin.py new file mode 100644 index 0000000000..76058c320f --- /dev/null +++ b/tools/build/test/toolset-mock/src/gcc-4.2.1-darwin.py @@ -0,0 +1,37 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('g++', '-print-prog-name=ar', stdout=script('ar.py')) +command('g++', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +# all builds are multi-threaded for darwin +if allow_properties("variant=debug", "link=shared", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', '-o', output_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/libl1.dylib'), '-shared', input_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/lib.o'), unordered('-g', '-fPIC')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-fPIC'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-Wl,-rpath', arg('-Wl,', target_path('bin/gcc-darwin-4.2.1/debug/target-os-darwin/libl1.dylib')), '-o', output_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/test'), input_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/main.o'), input_file('bin/gcc-darwin-4.2.1/debug/target-os-darwin/libl1.dylib'), unordered('-g', '-fPIC')) + +if allow_properties("variant=release", "link=shared", "runtime-link=shared"): + command('g++', unordered('-O3', '-finline-functions', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', '-o', output_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/libl1.dylib'), '-shared', input_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/lib.o'), '-fPIC') + command('g++', unordered('-O3', '-finline-functions', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-Wl,-rpath', arg('-Wl,', target_path('bin/gcc-darwin-4.2.1/release/target-os-darwin/libl1.dylib')), '-o', output_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/test'), input_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/main.o'), input_file('bin/gcc-darwin-4.2.1/release/target-os-darwin/libl1.dylib'), '-fPIC') + +if allow_properties("variant=debug", "link=static", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/test'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/main.o'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/libl1.a'), '-g') + +if allow_properties("variant=debug", "link=static", "runtime-link=static"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/test'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), unordered('-g', '-static')) + +main() diff --git a/tools/build/test/toolset-mock/src/gcc-4.8.3-linux.py b/tools/build/test/toolset-mock/src/gcc-4.8.3-linux.py new file mode 100644 index 0000000000..5604ee5d1a --- /dev/null +++ b/tools/build/test/toolset-mock/src/gcc-4.8.3-linux.py @@ -0,0 +1,50 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('g++', '-print-prog-name=ar', stdout=script('ar.py')) +command('g++', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +if allow_properties("variant=debug", "link=shared", "threading=single", "runtime-link=shared"): + command("g++", unordered("-O0", "-fno-inline", "-Wall", "-g", "-fPIC"), "-c", "-o", output_file("bin/gcc-gnu-4.8.3/debug/lib.o"), input_file(source="lib.cpp")) + command("g++", "-o", output_file("bin/gcc-gnu-4.8.3/debug/libl1.so"), "-Wl,-h", "-Wl,libl1.so", "-shared", "-Wl,--start-group", input_file("bin/gcc-gnu-4.8.3/debug/lib.o"), "-Wl,-Bstatic", "-Wl,-Bdynamic", "-Wl,--end-group", unordered("-g", "-fPIC")) + command("g++", unordered("-O0", "-fno-inline", "-Wall", "-g", "-fPIC"), "-c", "-o", output_file("bin/gcc-gnu-4.8.3/debug/main.o"), input_file(source="main.cpp")) + command("g++", "-Wl,-rpath", arg("-Wl,", target_path("bin/gcc-gnu-4.8.3/debug/libl1.so")), "-Wl,-rpath-link", arg("-Wl,", target_path("bin/gcc-gnu-4.8.3/debug/libl1.so")), "-o", output_file("bin/gcc-gnu-4.8.3/debug/test"), "-Wl,--start-group", input_file("bin/gcc-gnu-4.8.3/debug/main.o"), input_file("bin/gcc-gnu-4.8.3/debug/libl1.so"), "-Wl,-Bstatic", "-Wl,-Bdynamic", "-Wl,--end-group", unordered("-g", "-fPIC")) + +if allow_properties("variant=release", "link=shared", "threading=single", "runtime-link=shared"): + command('g++', unordered('-O3', '-finline-functions', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/release/lib.o'), input_file(source='lib.cpp')) + command('g++', '-o', output_file('bin/gcc-gnu-4.8.3/release/libl1.so'), '-Wl,-h', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/release/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', '-fPIC') + command('g++', unordered('-O3', '-finline-functions', '-Wno-inline', '-Wall', '-fPIC', '-DNDEBUG'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/release/main.o'), input_file(source='main.cpp')) + command('g++', '-Wl,-rpath', arg('-Wl,', target_path('bin/gcc-gnu-4.8.3/release/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/gcc-gnu-4.8.3/release/libl1.so')), '-o', output_file('bin/gcc-gnu-4.8.3/release/test'), '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/release/main.o'), input_file('bin/gcc-gnu-4.8.3/release/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', '-fPIC') + +if allow_properties("variant=debug", "link=shared", "threading=multi", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-pthread', '-fPIC'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/debug/threading-multi/lib.o'), input_file(source='lib.cpp')) + command('g++', '-o', output_file('bin/gcc-gnu-4.8.3/debug/threading-multi/libl1.so'), '-Wl,-h', '-Wl,libl1.so', '-shared', '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/debug/threading-multi/lib.o'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-lrt', '-Wl,--end-group', unordered('-g', '-pthread', '-fPIC')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-pthread', '-fPIC'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/debug/threading-multi/main.o'), input_file(source='main.cpp')) + command('g++', '-Wl,-rpath', arg('-Wl,', target_path('bin/gcc-gnu-4.8.3/debug/threading-multi/libl1.so')), '-Wl,-rpath-link', arg('-Wl,', target_path('bin/gcc-gnu-4.8.3/debug/threading-multi/libl1.so')), '-o', output_file('bin/gcc-gnu-4.8.3/debug/threading-multi/test'), '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/debug/threading-multi/main.o'), input_file('bin/gcc-gnu-4.8.3/debug/threading-multi/libl1.so'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-lrt', '-Wl,--end-group', unordered('-g', '-pthread', '-fPIC')) + +if allow_properties("variant=debug", "link=static", "threading=single", "runtime-link=shared"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g'), '-c', '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/test'), '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/debug/link-static/main.o'), input_file('bin/gcc-gnu-4.8.3/debug/link-static/libl1.a'), '-Wl,-Bstatic', '-Wl,-Bdynamic', '-Wl,--end-group', '-g') + +if allow_properties("variant=debug", "link=static", "threading=single", "runtime-link=static"): + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/lib.o'), input_file(source='lib.cpp')) + command('g++', unordered('-O0', '-fno-inline', '-Wall', '-g', '-c'), '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/main.o'), input_file(source='main.cpp')) + command('g++', '-o', output_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/test'), '-Wl,--start-group', input_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/main.o'), input_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/libl1.a'), '-Wl,--end-group', unordered('-g', '-static')) + + +if allow_properties("variant=debug", "link=shared", "threading=single", "runtime-link=shared"): + command("g++", unordered("-O0", "-fno-inline", "-Wall", "-g", "-fPIC", "-std=c++1y"), "-c", "-o", output_file("bin/gcc-gnu-4.8.3/debug/lib.o"), input_file(source="lib.cpp")) + command("g++", "-o", output_file("bin/gcc-gnu-4.8.3/debug/libl1.so"), "-Wl,-h", "-Wl,libl1.so", "-shared", "-Wl,--start-group", input_file("bin/gcc-gnu-4.8.3/debug/lib.o"), "-Wl,-Bstatic", "-Wl,-Bdynamic", "-Wl,--end-group", unordered("-g", "-fPIC", "-std=c++1y")) + command("g++", unordered("-O0", "-fno-inline", "-Wall", "-g", "-fPIC", "-std=c++1y"), "-c", "-o", output_file("bin/gcc-gnu-4.8.3/debug/main.o"), input_file(source="main.cpp")) + command("g++", "-Wl,-rpath", arg("-Wl,", target_path("bin/gcc-gnu-4.8.3/debug/libl1.so")), "-Wl,-rpath-link", arg("-Wl,", target_path("bin/gcc-gnu-4.8.3/debug/libl1.so")), "-o", output_file("bin/gcc-gnu-4.8.3/debug/test"), "-Wl,--start-group", input_file("bin/gcc-gnu-4.8.3/debug/main.o"), input_file("bin/gcc-gnu-4.8.3/debug/libl1.so"), "-Wl,-Bstatic", "-Wl,-Bdynamic", "-Wl,--end-group", unordered("-g", "-fPIC", "-std=c++1y")) + + +main() diff --git a/tools/build/test/toolset-mock/src/intel-darwin-10.2.py b/tools/build/test/toolset-mock/src/intel-darwin-10.2.py new file mode 100644 index 0000000000..314d6c458d --- /dev/null +++ b/tools/build/test/toolset-mock/src/intel-darwin-10.2.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('icc', '-print-prog-name=ar', stdout=script('ar.py')) +command('icc', '-print-prog-name=ranlib', stdout=script('ranlib.py')) + +# all builds are multi-threaded for darwin +if allow_properties("variant=debug", "link=shared", "runtime-link=shared"): + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0', '-fPIC'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', 'libl1.dylib', input_file('bin/intel-darwin-10.2/debug/target-os-darwin/lib.o'), unordered('-g', ordered('-shared-intel', '-lstdc++', '-lpthread'), '-fPIC')) + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0', '-fPIC'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/target-os-darwin/test'), input_file('bin/intel-darwin-10.2/debug/target-os-darwin/main.o'), input_file('bin/intel-darwin-10.2/debug/target-os-darwin/libl1.dylib'), unordered('-g', ordered('-shared-intel', '-lstdc++', '-lpthread'), '-fPIC')) + +if allow_properties("variant=release", "link=shared", "runtime-link=shared"): + command('icc', '-xc++', unordered('-O3', '-inline-level=2', '-w1', '-vec-report0', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/intel-darwin-10.2/release/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/release/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', 'libl1.dylib', input_file('bin/intel-darwin-10.2/release/target-os-darwin/lib.o'), unordered(ordered('-shared-intel', '-lstdc++', '-lpthread'), '-fPIC')) + command('icc', '-xc++', unordered('-O3', '-inline-level=2', '-w1', '-vec-report0', '-fPIC'), '-DNDEBUG', '-c', '-o', output_file('bin/intel-darwin-10.2/release/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/release/target-os-darwin/test'), input_file('bin/intel-darwin-10.2/release/target-os-darwin/main.o'), input_file('bin/intel-darwin-10.2/release/target-os-darwin/libl1.dylib'), unordered(ordered('-shared-intel', '-lstdc++', '-lpthread'), '-fPIC')) + +if allow_properties("variant=debug", "link=static", "runtime-link=shared"): + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/test'), input_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/main.o'), input_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/libl1.a'), '-g', ordered('-shared-intel', '-lstdc++', '-lpthread')) + +if allow_properties("variant=debug", "link=static", "runtime-link=static"): + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/test'), input_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/main.o'), input_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), unordered('-g', ordered('-static', '-static-intel', '-lstdc++', '-lpthread'), '-static')) + +if allow_properties("variant=debug", "link=shared", "runtime-link=shared", "architecture=x86", "address-model=32"): + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0', '-march=i686', '-fPIC', '-m32'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/lib.o'), input_file(source='lib.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/libl1.dylib'), '-single_module', '-dynamiclib', '-install_name', 'libl1.dylib', input_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/lib.o'), unordered('-g', ordered('-shared-intel', '-lstdc++', '-lpthread'), '-march=i686', '-fPIC', '-m32')) + command('icc', '-xc++', unordered('-O0', '-inline-level=0', '-w1', '-g', '-vec-report0', '-march=i686', '-fPIC', '-m32'), '-c', '-o', output_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/main.o'), input_file(source='main.cpp')) + command('icc', '-o', output_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/test'), input_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/main.o'), input_file('bin/intel-darwin-10.2/debug/x86/target-os-darwin/libl1.dylib'), unordered('-g', ordered('-shared-intel', '-lstdc++', '-lpthread'), '-march=i686', '-fPIC', '-m32')) + +main() diff --git a/tools/build/test/toolset-mock/src/ld.py b/tools/build/test/toolset-mock/src/ld.py new file mode 100644 index 0000000000..2b644e5012 --- /dev/null +++ b/tools/build/test/toolset-mock/src/ld.py @@ -0,0 +1,33 @@ +#!/usr/bin/python +# +# Copyright 2018 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared'): + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/libl1.so'), input_file('bin/clang-vxworks-4.0.1/debug/lib.o'), unordered('-g', '-fPIC'), '-fpic', '-shared', '-non-static') + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/test'), input_file('bin/clang-vxworks-4.0.1/debug/main.o'), input_file('bin/clang-vxworks-4.0.1/debug/libl1.so'), unordered('-g', '-fPIC')) + +if allow_properties('variant=release', 'link=shared', 'threading=single', 'runtime-link=shared', 'strip=on'): + command('ld', '-t', '-o', output_file('bin/clang-vxworks-4.0.1/release/libl1.so'), input_file('bin/clang-vxworks-4.0.1/release/lib.o'), unordered('-fPIC', '-Wl,--strip-all'), '-fpic', '-shared', '-non-static') + command('ld', '-t', '-o', output_file('bin/clang-vxworks-4.0.1/release/test'), input_file('bin/clang-vxworks-4.0.1/release/main.o'), input_file('bin/clang-vxworks-4.0.1/release/libl1.so'), unordered('-fPIC', '-Wl,--strip-all')) + +if allow_properties('variant=debug', 'link=shared', 'threading=multi', 'runtime-link=shared'): + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/threading-multi/libl1.so'), input_file('bin/clang-vxworks-4.0.1/debug/threading-multi/lib.o'), unordered('-g', '-fPIC'), '-fpic', '-shared', '-non-static') + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/threading-multi/test'), input_file('bin/clang-vxworks-4.0.1/debug/threading-multi/main.o'), input_file('bin/clang-vxworks-4.0.1/debug/threading-multi/libl1.so'), unordered('-g', '-fPIC')) + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=shared'): + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/test'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/main.o'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/libl1.a'), '-g') + +if allow_properties('variant=debug', 'link=static', 'threading=single', 'runtime-link=static'): + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/test'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/main.o'), input_file('bin/clang-vxworks-4.0.1/debug/link-static/runtime-link-static/libl1.a'), unordered('-g')) + +if allow_properties('variant=debug', 'link=shared', 'threading=single', 'runtime-link=shared', 'architecture=x86', 'address-model=32'): + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/libl1.so'), input_file('bin/clang-vxworks-4.0.1/debug/lib.o'), unordered('-g', '-march=i686', '-fPIC', '-m32'), '-fpic', '-shared', '-non-static') + command('ld', '-o', output_file('bin/clang-vxworks-4.0.1/debug/test'), input_file('bin/clang-vxworks-4.0.1/debug/main.o'), input_file('bin/clang-vxworks-4.0.1/debug/libl1.so'), unordered('-g', '-march=i686', '-fPIC', '-m32')) + +main() diff --git a/tools/build/test/toolset-mock/src/libtool.py b/tools/build/test/toolset-mock/src/libtool.py new file mode 100644 index 0000000000..9f58dc96d7 --- /dev/null +++ b/tools/build/test/toolset-mock/src/libtool.py @@ -0,0 +1,14 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('libtool', '-static', '-o', output_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/libl1.a'), input_file('bin/darwin-4.2.1/debug/link-static/target-os-darwin/lib.o')) +command('libtool', '-static', '-o', output_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/libl1.a'), input_file('bin/darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/lib.o')) + +main() diff --git a/tools/build/test/toolset-mock/src/mock-program.cpp b/tools/build/test/toolset-mock/src/mock-program.cpp new file mode 100644 index 0000000000..62dd4b8a44 --- /dev/null +++ b/tools/build/test/toolset-mock/src/mock-program.cpp @@ -0,0 +1,42 @@ +// mock-program.cpp +// +// Copyright (c) 2017 Steven Watanabe +// +// Distributed under the Boost Software License Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +// This program does nothing except to exec a python script + +#include +#include +#include +#include "config.h" + +#if defined(_WIN32) + #include + #define execv _execv +#else + #include +#endif + +#ifndef PY_SCRIPT +#error PY_SCRIPT must be defined to the absolute path to the script to run +#endif + +#ifndef PYTHON_CMD +#error PYTHON_CMD must be defined to the absolute path to the python interpreter +#endif + +int main(int argc, char ** argv) +{ + std::vector args; + char python_cmd[] = PYTHON_CMD; + char script[] = PY_SCRIPT; + args.push_back(python_cmd); + args.push_back(script); + args.insert(args.end(), argv + 1, argv + argc); + args.push_back(NULL); + execv(python_cmd, &args[0]); + perror("exec"); +} diff --git a/tools/build/test/toolset-mock/src/project-config.jam b/tools/build/test/toolset-mock/src/project-config.jam new file mode 100644 index 0000000000..73dcf42df7 --- /dev/null +++ b/tools/build/test/toolset-mock/src/project-config.jam @@ -0,0 +1,5 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) diff --git a/tools/build/test/toolset-mock/src/ranlib.py b/tools/build/test/toolset-mock/src/ranlib.py new file mode 100644 index 0000000000..4abe21ed0f --- /dev/null +++ b/tools/build/test/toolset-mock/src/ranlib.py @@ -0,0 +1,22 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('ranlib', input_file('bin/gcc-gnu-4.8.3/debug/link-static/libl1.a')) +command('ranlib', input_file('bin/gcc-gnu-4.8.3/debug/link-static/runtime-link-static/libl1.a')) +command('ranlib', input_file('bin/gcc-darwin-4.2.1/debug/link-static/target-os-darwin/libl1.a')) +command('ranlib', input_file('bin/gcc-darwin-4.2.1/debug/link-static/runtime-link-static/target-os-darwin/libl1.a')) +command('ranlib', input_file('bin/clang-darwin-3.9.0/debug/link-static/target-os-darwin/libl1.a')) +command('ranlib', input_file('bin/clang-darwin-3.9.0/debug/link-static/runtime-link-static/target-os-darwin/libl1.a')) +command('ranlib', '-cs', input_file('bin/intel-darwin-10.2/debug/link-static/target-os-darwin/libl1.a')) +command('ranlib', '-cs', input_file('bin/intel-darwin-10.2/debug/link-static/runtime-link-static/target-os-darwin/libl1.a')) +command('ranlib', input_file('bin/clang-linux-3.9.0/debug/link-static/libl1.a')) +command('ranlib', input_file('bin/clang-linux-3.9.0/debug/link-static/runtime-link-static/libl1.a')) + +main() diff --git a/tools/build/test/toolset-mock/src/strip.py b/tools/build/test/toolset-mock/src/strip.py new file mode 100644 index 0000000000..6245588bf5 --- /dev/null +++ b/tools/build/test/toolset-mock/src/strip.py @@ -0,0 +1,13 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +command('strip', '-S', '-x', input_file('bin/darwin-4.2.1/release/target-os-darwin/test')) + +main() diff --git a/tools/build/test/toolset-mock/src/verify.py b/tools/build/test/toolset-mock/src/verify.py new file mode 100644 index 0000000000..6e5e0ea7ba --- /dev/null +++ b/tools/build/test/toolset-mock/src/verify.py @@ -0,0 +1,9 @@ +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +from MockProgram import * + +verify() diff --git a/tools/build/test/toolset_clang_darwin.py b/tools/build/test/toolset_clang_darwin.py new file mode 100644 index 0000000000..53c7c07cb8 --- /dev/null +++ b/tools/build/test/toolset_clang_darwin.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the clang-darwin toolset using a mock of clang + +from TestToolset import test_toolset + +test_toolset("clang-darwin", "3.9.0", [ + ["target-os=darwin"], + ["target-os=darwin", "release", "strip=on", "linkflags=-v"], + ["target-os=darwin", "threading=multi"], + ["target-os=darwin", "link=static"], + ["target-os=darwin", "link=static", "runtime-link=static"], + ["target-os=darwin", "architecture=x86", "address-model=32"], + ["target-os=darwin", "cxxstd=latest"]]) diff --git a/tools/build/test/toolset_clang_linux.py b/tools/build/test/toolset_clang_linux.py new file mode 100644 index 0000000000..2fbf84b6d0 --- /dev/null +++ b/tools/build/test/toolset_clang_linux.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the clang_linux toolset using a mock of clang + +from TestToolset import test_toolset + +test_toolset("clang-linux", "3.9.0", [ + ["target-os=linux"], + ["target-os=linux", "release", "strip=on"], + ["target-os=linux", "threading=multi"], + ["target-os=linux", "link=static"], + ["target-os=linux", "link=static", "runtime-link=static"], + ["target-os=linux", "architecture=x86", "address-model=32"]]) diff --git a/tools/build/test/toolset_clang_vxworks.py b/tools/build/test/toolset_clang_vxworks.py new file mode 100644 index 0000000000..efdc127595 --- /dev/null +++ b/tools/build/test/toolset_clang_vxworks.py @@ -0,0 +1,20 @@ +#!/usr/bin/python +# +# Copyright 2018 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the clang_vxworks toolset using a mock of clang + +from TestToolset import test_toolset + +test_toolset("clang-vxworks", "4.0.1", [ + ["target-os=vxworks"], + ["target-os=vxworks", "release", "strip=on", "linkflags=-t"], + ["target-os=vxworks", "threading=multi"], + ["target-os=vxworks", "link=static"], + ["target-os=vxworks", "link=static", "runtime-link=static"], + ["target-os=vxworks", "architecture=x86", "address-model=32"], + ["target-os=vxworks", "rtti=off", "exception-handling=off"]]) diff --git a/tools/build/test/toolset_darwin.py b/tools/build/test/toolset_darwin.py new file mode 100644 index 0000000000..58ecc8d2bf --- /dev/null +++ b/tools/build/test/toolset_darwin.py @@ -0,0 +1,21 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the darwin toolset using a mock of gcc + +from TestToolset import test_toolset + +test_toolset("darwin", "4.2.1", [ + ["target-os=darwin"], + ["target-os=darwin", "release", "strip=on"], + ["target-os=darwin", "threading=multi"], + ["target-os=darwin", "link=static"], + ["target-os=darwin", "link=static", "runtime-link=static"], +# Address-model handling is quite broken +# ["target-os=darwin", "architecture=x86", "address-model=32"] +]) diff --git a/tools/build/test/toolset_defaults.py b/tools/build/test/toolset_defaults.py new file mode 100644 index 0000000000..6d76c10fda --- /dev/null +++ b/tools/build/test/toolset_defaults.py @@ -0,0 +1,60 @@ +#!/usr/bin/python + +# Copyright 2018 Steven Watanabe +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +# Test the handling of toolset.add-defaults + +import BoostBuild + +t = BoostBuild.Tester(pass_toolset=0, ignore_toolset_requirements=False) + +t.write('jamroot.jam', ''' +import toolset ; +import errors ; +import feature : feature ; +import set ; + +feature f1 : a b ; +feature f2 : c d ; +feature f3 : e f ; +feature f4 : g h ; +feature f5 : i j ; +feature f6 : k l m ; + +rule test-rule ( properties * ) +{ + if a in $(properties) + { + return d ; + } +} + +toolset.add-defaults + @test-rule + e:h + i:l +; + +rule check-requirements ( target : sources * : properties * ) +{ + local expected = d h m ; + local unexpected = c g k l ; + local missing = [ set.difference $(expected) : $(properties) ] ; + if $(missing) + { + errors.error $(missing) not present ; + } + local extra = [ set.intersection $(unexpected) : $(properties) ] ; + if $(extra) + { + errors.error $(extra) present ; + } +} +make test : : @check-requirements : m ; +''') + +t.run_build_system() + +t.cleanup() diff --git a/tools/build/test/toolset_gcc.py b/tools/build/test/toolset_gcc.py new file mode 100644 index 0000000000..d3d65fcf92 --- /dev/null +++ b/tools/build/test/toolset_gcc.py @@ -0,0 +1,26 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the gcc toolset using a mock of gcc + +from TestToolset import test_toolset + +test_toolset("gcc", "4.8.3", [ + ["target-os=linux"], + ["target-os=linux", "release"], + ["target-os=linux", "threading=multi"], + ["target-os=linux", "link=static"], + ["target-os=linux", "link=static", "runtime-link=static"], + ["target-os=linux", "cxxstd=latest"]]) + +test_toolset("gcc", "4.2.1", [ + ["target-os=darwin"], + ["target-os=darwin", "release"], + ["target-os=darwin", "threading=multi"], + ["target-os=darwin", "link=static"], + ["target-os=darwin", "link=static", "runtime-link=static"]]) diff --git a/tools/build/test/toolset_intel_darwin.py b/tools/build/test/toolset_intel_darwin.py new file mode 100644 index 0000000000..db04449009 --- /dev/null +++ b/tools/build/test/toolset_intel_darwin.py @@ -0,0 +1,19 @@ +#!/usr/bin/python +# +# Copyright 2017 Steven Watanabe +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# validates the intel-darwin toolset using a mock of icc + +from TestToolset import test_toolset + +test_toolset("intel-darwin", "10.2", [ + ["target-os=darwin"], + ["target-os=darwin", "release", "strip=on"], + ["target-os=darwin", "threading=multi"], + ["target-os=darwin", "link=static"], + ["target-os=darwin", "link=static", "runtime-link=static"], + ["target-os=darwin", "architecture=x86", "address-model=32"]]) diff --git a/tools/build/test/zlib.py b/tools/build/test/zlib.py deleted file mode 100755 index 0bb8269adf..0000000000 --- a/tools/build/test/zlib.py +++ /dev/null @@ -1,119 +0,0 @@ -#!/usr/bin/python - -# Copyright (C) 2013 Steven Watanabe -# Distributed under the Boost Software License, Version 1.0. -# (See accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) - -import BoostBuild -import MockToolset - -t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0) - -MockToolset.create(t) - -# Build from source -t.write("zlib/zlib.h", 'zlib') -t.write("zlib/deflate.c", 'deflate') - -t.write("Jamroot.jam", """ -path-constant here : . ; -using zlib : : $(here)/zlib ; -alias zlib : /zlib//zlib : : static shared ; -""") - -MockToolset.set_expected(t, ''' -source_file('deflate.c', 'deflate') -action('-c -x c -I./zlib -o $deflate.o $deflate.c') -action('--dll $deflate.o -o $deflate.so') -action('--archive $deflate.o -o $deflate.a') -''') - -t.run_build_system() -t.expect_addition('bin/standalone/zlib/mock/debug/z.dll') -t.expect_addition('bin/standalone/zlib/mock/debug/link-static/z.lib') - -t.rm('zlib') - -# Generic definitions that aren't configuration specific -common_stuff = ''' -source_file('test.cpp', 'test.cpp') -source_file('main.cpp', 'int main() {}') -source_file('zlib.h.cpp', '#include \\n') -action('-c -x c++ $main.cpp -o $main.o') -''' -t.write('test.cpp', 'test.cpp') - -# Default initialization - static library -t.rm('bin') -t.write("Jamroot.jam", """ -path-constant here : . ; -using zlib ; -exe test : test.cpp /zlib//zlib : : static shared ; -""") - -MockToolset.set_expected(t, common_stuff + ''' -action('$main.o --static-lib=z -o $config.exe') -action('-c -x c++ $zlib.h.cpp -o $zlib.h.o') -action('-c -x c++ $test.cpp -o $test.o') -action('$test.o --static-lib=z -o $test') -''') -t.run_build_system() -t.expect_addition('bin/mock/debug/test.exe') -t.expect_addition('bin/mock/debug/link-static/test.exe') - -# Default initialization - shared library -t.rm('bin') -t.write("Jamroot.jam", """ -path-constant here : . ; -using zlib ; -exe test : test.cpp /zlib//zlib : : static shared ; -""") - -MockToolset.set_expected(t, common_stuff + ''' -action('$main.o --shared-lib=z -o $config.exe') -action('-c -x c++ $zlib.h.cpp -o $zlib.h.o') -action('-c -x c++ $test.cpp -o $test.o') -action('$test.o --shared-lib=z -o $test') -''') -t.run_build_system() -t.expect_addition('bin/mock/debug/test.exe') -t.expect_addition('bin/mock/debug/link-static/test.exe') - -# Initialization in explicit location - static library -t.rm('bin') -t.write("Jamroot.jam", """ -path-constant here : . ; -using zlib : : myzlib $(here)/zlib $(here)/zlib ; -exe test : test.cpp /zlib//zlib : : static shared ; -""") - -t.write('zlib/zlib.h', 'zlib') - -MockToolset.set_expected(t, common_stuff + ''' -action('$main.o -L./zlib --static-lib=myzlib -o $config.exe') -action('-c -x c++ $test.cpp -I./zlib -o $test.o') -action('$test.o -L./zlib --static-lib=myzlib -o $test') -''') -t.run_build_system() -t.expect_addition('bin/mock/debug/test.exe') -t.expect_addition('bin/mock/debug/link-static/test.exe') - -# Initialization in explicit location - shared library -t.rm('bin') -t.write("Jamroot.jam", """ -path-constant here : . ; -using zlib : : myzlib $(here)/zlib $(here)/zlib ; -exe test : test.cpp /zlib//zlib : : static shared ; -""") - -MockToolset.set_expected(t, common_stuff + ''' -action('$main.o -L./zlib --shared-lib=myzlib -o $config.exe') -action('-c -x c++ $test.cpp -I./zlib -o $test.o') -action('$test.o -L./zlib --shared-lib=myzlib -o $test') -''') -t.run_build_system() -t.expect_addition('bin/mock/debug/test.exe') -t.expect_addition('bin/mock/debug/link-static/test.exe') - -t.cleanup() diff --git a/tools/check_build/README.md b/tools/check_build/README.md new file mode 100644 index 0000000000..bb5f25575c --- /dev/null +++ b/tools/check_build/README.md @@ -0,0 +1,3 @@ +# check_build + +A utility submodule that, for each buildable Boost library, creates a test that builds the library. diff --git a/tools/check_build/test/Jamfile b/tools/check_build/test/Jamfile new file mode 100644 index 0000000000..5468393a8d --- /dev/null +++ b/tools/check_build/test/Jamfile @@ -0,0 +1,96 @@ +# Copyright 2017 Peter Dimov +# +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + +import modules ; +import sequence ; +import set ; +import project ; +import virtual-target ; +import testing ; +import ac ; + +if "--debug-check-build" in [ modules.peek : ARGV ] +{ + .info-enabled = 1 ; +} + +local rule .info ( messages * ) +{ + if $(.info-enabled) + { + ECHO info: $(messages) ; + } +} + +local all-libraries = [ MATCH .*libs/(.*)/build/.* : + [ glob ../../../libs/*/build/Jamfile.v2 ] + [ glob ../../../libs/*/build/Jamfile ] ] ; + +all-libraries = [ sequence.unique $(all-libraries) ] ; + +# The function_types library has a Jamfile, but it's used for maintenance +# purposes, there's no library to build and install. + +all-libraries = [ set.difference $(all-libraries) : function_types ] ; + +#ECHO all-libraries: $(all-libraries) ; + +rule alias-sources-impl ( project name : property-set : sources * ) +{ + local target-graph ; + + for local s in $(sources) + { + target-graph += [ virtual-target.traverse $(s) : include-sources : include-roots ] ; + } + + # Remove targets created by the main target + + local result ; + + for local t in $(target-graph) + { + if [ $(t).root ] && ! ( $(t) in $(sources) ) + { + result += $(t) ; + } + } + + .info $(name): ; + + for local t in $(result) + { + .info " " [ $(t).name ] ; + } + + return $(result) ; +} + +path-constant ROOT : ../../.. ; + +for local lib in $(all-libraries) +{ + local path = [ NORMALIZE_PATH /$(ROOT)/libs/$(lib)/build ] ; + local project = [ project.load $(path) ] ; + local pt = [ project.target $(project) ] ; + local mt = [ $(pt).main-target stage ] ; + + if $(mt) + { + generate library-$(lib) : $(path)//stage : @alias-sources-impl ; + } + else + { + .info library-$(lib): ; + .info " (no stage target, using '$(path)')" ; + + alias library-$(lib) : $(path) ; + } +} + +for local lib in $(all-libraries) +{ + run main.cpp : : : [ ac.check-library library-$(lib) : library-$(lib) : no ] : $(lib) ; +} diff --git a/tools/check_build/test/main.cpp b/tools/check_build/test/main.cpp new file mode 100644 index 0000000000..5047a34e39 --- /dev/null +++ b/tools/check_build/test/main.cpp @@ -0,0 +1,3 @@ +int main() +{ +} diff --git a/tools/quickbook/Jamfile.v2 b/tools/quickbook/Jamfile.v2 index b6ef149be2..8b1b641d4d 100644 --- a/tools/quickbook/Jamfile.v2 +++ b/tools/quickbook/Jamfile.v2 @@ -9,6 +9,17 @@ # http://www.boost.org/LICENSE_1_0.txt) #============================================================================== +project quickbook + : requirements + gcc:300 + darwin:300 + gcc:-g0 + darwin:-g0 + msvc:/wd4709 + all + 0x + ; + import boostcpp ; import path ; import option ; diff --git a/tools/quickbook/_clang-format b/tools/quickbook/_clang-format new file mode 100644 index 0000000000..f92d007b84 --- /dev/null +++ b/tools/quickbook/_clang-format @@ -0,0 +1,57 @@ + +# Copyright 2017 Daniel James. +# Distributed under the Boost Software License, Version 1.0. (See accompanying +# file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +# Using clang format 4.0 +# http://llvm.org/releases/4.0.0/tools/clang/docs/ClangFormatStyleOptions.html + +BasedOnStyle: LLVM + +# Basic settings +ColumnLimit: 80 +NamespaceIndentation: All +ContinuationIndentWidth: 4 +IndentWidth: 4 +UseTab: Never +Language: Cpp +Standard: Cpp03 + +# Code layout +AlignAfterOpenBracket: AlwaysBreak +AlignTrailingComments: true +AllowShortBlocksOnASingleLine: true +AllowShortFunctionsOnASingleLine: true +AllowShortIfStatementsOnASingleLine: true +BinPackParameters: false +BreakBeforeBraces: Custom +ConstructorInitializerAllOnOneLineOrOnePerLine: true +BreakConstructorInitializersBeforeComma: true +BraceWrapping: + AfterNamespace: true + AfterClass: true + AfterStruct: true + AfterUnion: true + AfterEnum: true + AfterFunction: true + AfterControlStatement: false + BeforeCatch: false + BeforeElse: true +PointerAlignment: Left + +PenaltyReturnTypeOnItsOwnLine: 1000 + +# Include order + +IncludeCategories: + - Regex: '^$' + Priority: 10 + - Regex: '^$' + Priority: 30 + - Regex: '^<.*>$' + Priority: 20 + - Regex: '^".*"$' + Priority: 40 + +# Boost specific stuff +ForEachMacros: [ BOOST_FOREACH ] diff --git a/tools/quickbook/build/warning-check b/tools/quickbook/build/warning-check index be9fd411ea..064d499324 100755 --- a/tools/quickbook/build/warning-check +++ b/tools/quickbook/build/warning-check @@ -12,7 +12,7 @@ failure=0 for filename in *.cpp do set -x - if ! $CXX -c -O0 -isystem $BOOST_ROOT $filename -o $tmpfile \ + if ! $CXX -c -O0 --std=c++11 -isystem $BOOST_ROOT $filename -o $tmpfile \ -pedantic -Wstrict-aliasing -fstrict-aliasing \ -Werror -Wall -Wextra \ -Wunused-parameter -Wshadow \ diff --git a/tools/quickbook/doc/Jamfile.v2 b/tools/quickbook/doc/Jamfile.v2 index 80ad7c75ff..1803491bd3 100644 --- a/tools/quickbook/doc/Jamfile.v2 +++ b/tools/quickbook/doc/Jamfile.v2 @@ -46,6 +46,10 @@ boostbook fully-standalone html.stylesheet=boostbook.css img.src.path=images/ boost.graphics.root=images/ + boost.mobile=1 + # Use an invalid nav.layout value so it displays the header + # image, but with no navigation. + nav.layout=hackhackhack ; explicit fully-standalone ; diff --git a/tools/quickbook/doc/change_log.qbk b/tools/quickbook/doc/change_log.qbk index 286e5260e5..d094b78317 100644 --- a/tools/quickbook/doc/change_log.qbk +++ b/tools/quickbook/doc/change_log.qbk @@ -69,7 +69,7 @@ * __cond__. Ala C++ #ifdef. * Searching of included and imported files in an extensible search path with `--include-path` (`-I`) option. - + [heading:version_1_5 Version 1.5 - Boost 1.41.0 to 1.42.0] * Support multiple copyright entrys in document info. @@ -364,3 +364,9 @@ Boost 1.46.1: * Minor improvements to some warning and error messages. * Stopped normalizing paths in dependency lists. * Fix xmlbase when it's the same directory as the existing xinclude base. + +[heading Version 1.7.1 - Boost 1.67] + +* Now uses C++11, no longer tested with C++03 compilers. +* Fix parsing escaped docbook with the new version of Spirit. +* Reformatted code with clang-format. diff --git a/tools/quickbook/src/Jamfile.v2 b/tools/quickbook/src/Jamfile.v2 index b943174b88..dbd262b2a0 100644 --- a/tools/quickbook/src/Jamfile.v2 +++ b/tools/quickbook/src/Jamfile.v2 @@ -8,16 +8,6 @@ # http://www.boost.org/LICENSE_1_0.txt) #============================================================================== -project quickbook - : requirements - gcc:300 - darwin:300 - gcc:-g0 - darwin:-g0 - msvc:/wd4709 - all - ; - lib shell32 ; exe quickbook diff --git a/tools/quickbook/src/actions.cpp b/tools/quickbook/src/actions.cpp index 408f2a1b19..f13e45126a 100644 --- a/tools/quickbook/src/actions.cpp +++ b/tools/quickbook/src/actions.cpp @@ -8,80 +8,79 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include +#include "actions.hpp" #include -#include #include +#include #include +#include +#include #include #include -#include -#include +#include #include -#include #include -#include -#include "quickbook.hpp" -#include "actions.hpp" -#include "syntax_highlight.hpp" -#include "utils.hpp" +#include +#include +#include "block_tags.hpp" +#include "document_state.hpp" #include "files.hpp" +#include "grammar.hpp" #include "markups.hpp" +#include "path.hpp" +#include "phrase_tags.hpp" +#include "quickbook.hpp" #include "state.hpp" #include "state_save.hpp" -#include "grammar.hpp" #include "stream.hpp" -#include "block_tags.hpp" -#include "phrase_tags.hpp" -#include "document_state.hpp" -#include "path.hpp" +#include "syntax_highlight.hpp" +#include "utils.hpp" namespace quickbook { - namespace { + namespace + { void write_anchors(quickbook::state& state, collector& tgt) { if (state.source_mode_next) { - detail::outwarn(state.source_mode_next_pos.get_file(), + detail::outwarn( + state.source_mode_next_pos.get_file(), state.source_mode_next_pos.get_position()) - << "Temporary source mode unsupported here." - << std::endl; + << "Temporary source mode unsupported here." << std::endl; state.source_mode_next = 0; } - for(quickbook::state::string_list::iterator - it = state.anchors.begin(), - end = state.anchors.end(); - it != end; ++it) - { + for (quickbook::state::string_list::iterator + it = state.anchors.begin(), + end = state.anchors.end(); + it != end; ++it) { tgt << ""; } - + state.anchors.clear(); } - - std::string add_anchor(quickbook::state& state, - quickbook::string_view id, - id_category::categories category = - id_category::explicit_anchor_id) + + std::string add_anchor( + quickbook::state& state, + quickbook::string_view id, + id_category::categories category = id_category::explicit_anchor_id) { std::string placeholder = state.document.add_anchor(id, category); state.anchors.push_back(placeholder); return placeholder; } - std::string get_attribute_value(quickbook::state& state, - quickbook::value const& value) + std::string get_attribute_value( + quickbook::state& state, quickbook::value const& value) { - std::string x = value.is_encoded() ? - value.get_encoded() : value.get_quickbook().to_s(); + std::string x = value.is_encoded() ? value.get_encoded() + : value.get_quickbook().to_s(); if (x.empty()) { detail::outerr(value.get_file(), value.get_position()) - << "Empty attribute value." - << std::endl; + << "Empty attribute value." << std::endl; ++state.error_count; x = "xxx"; } @@ -89,30 +88,33 @@ namespace quickbook return x; } - std::string validate_id(quickbook::state& state, - quickbook::value const& id_value) + std::string validate_id( + quickbook::state& state, quickbook::value const& id_value) { bool valid = true; std::string id = get_attribute_value(state, id_value); // Special case since I use dollar ids for id placeholders. - if (id[0] == '$') { valid = false; id[0] = '_'; } + if (id[0] == '$') { + valid = false; + id[0] = '_'; + } if (qbk_version_n >= 107u) { char const* allowed_punctuation = "_.-"; - BOOST_FOREACH(char c, id) { + BOOST_FOREACH (char c, id) { if (!std::isalnum(c) && - !std::strchr(allowed_punctuation, c)) + !std::strchr(allowed_punctuation, c)) valid = false; } } if (!valid) { detail::outerr(id_value.get_file(), id_value.get_position()) - << "Invalid id: " - << (id_value.is_encoded() ? id_value.get_encoded() : - id_value.get_quickbook().to_s()) + << "Invalid id: " << (id_value.is_encoded() + ? id_value.get_encoded() + : id_value.get_quickbook().to_s()) << std::endl; ++state.error_count; } @@ -121,11 +123,13 @@ namespace quickbook } } - bool quickbook_range::in_range() const { + bool quickbook_range::in_range() const + { return qbk_version_n >= lower && qbk_version_n < upper; } - bool quickbook_strict::is_strict_checking() const { + bool quickbook_strict::is_strict_checking() const + { return state.strict_mode; } @@ -152,16 +156,15 @@ namespace quickbook void next_source_mode_action(quickbook::state&, value); void code_action(quickbook::state&, value); void do_template_action(quickbook::state&, value, string_iterator); - + void element_action::operator()(parse_iterator first, parse_iterator) const { value_consumer values = state.values.release(); - if(!values.check() || !state.conditional) return; + if (!values.check() || !state.conditional) return; value v = values.consume(); values.finish(); - - switch(v.get_tag()) - { + + switch (v.get_tag()) { case block_tags::ordered_list: case block_tags::itemized_list: return list_action(state, v); @@ -186,13 +189,13 @@ namespace quickbook case block_tags::note: case block_tags::tip: case block_tags::block: - return block_action(state,v); + return block_action(state, v); case block_tags::hr: - return block_empty_action(state,v); + return block_empty_action(state, v); case block_tags::macro_definition: - return macro_definition_action(state,v); + return macro_definition_action(state, v); case block_tags::template_definition: - return template_body_action(state,v); + return template_body_action(state, v); case block_tags::variable_list: return variable_list_action(state, v); case block_tags::table: @@ -253,33 +256,34 @@ namespace quickbook { write_anchors(state, state.phrase); - if(*first == '\\') - { + if (*first == '\\') { detail::outwarn(state.current_file, first.base()) //<< "in column:" << pos.column << ", " - << "'\\n' is deprecated, pleases use '[br]' instead" << ".\n"; + << "'\\n' is deprecated, pleases use '[br]' instead" + << ".\n"; } - if(!state.warned_about_breaks) - { + if (!state.warned_about_breaks) { detail::outwarn(state.current_file, first.base()) << "line breaks generate invalid boostbook " "(will only note first occurrence).\n"; state.warned_about_breaks = true; } - + state.phrase << detail::get_markup(phrase_tags::break_mark).pre; } - void error_message_action::operator()(parse_iterator first, parse_iterator last) const + void error_message_action::operator()( + parse_iterator first, parse_iterator last) const { file_position const pos = state.current_file->position_of(first.base()); std::string value(first, last); std::string formatted_message = message; boost::replace_all(formatted_message, "%s", value); - boost::replace_all(formatted_message, "%c", + boost::replace_all( + formatted_message, "%c", boost::lexical_cast(pos.column)); detail::outerr(state.current_file->path, pos.line) @@ -287,7 +291,8 @@ namespace quickbook ++state.error_count; } - void error_action::operator()(parse_iterator first, parse_iterator /*last*/) const + void error_action::operator()( + parse_iterator first, parse_iterator /*last*/) const { file_position const pos = state.current_file->position_of(first.base()); @@ -303,7 +308,8 @@ namespace quickbook detail::markup markup = detail::get_markup(block.get_tag()); value_consumer values = block; - state.out << markup.pre << values.consume().get_encoded() << markup.post; + state.out << markup.pre << values.consume().get_encoded() + << markup.post; values.finish(); } @@ -322,7 +328,8 @@ namespace quickbook detail::markup markup = detail::get_markup(phrase.get_tag()); value_consumer values = phrase; - state.phrase << markup.pre << values.consume().get_encoded() << markup.post; + state.phrase << markup.pre << values.consume().get_encoded() + << markup.post; values.finish(); } @@ -335,14 +342,10 @@ namespace quickbook value phrase = values.consume(); values.finish(); - state.phrase - << "" - << phrase.get_encoded() - << ""; + state.phrase << "" << phrase.get_encoded() << ""; } void footnote_action(quickbook::state& state, value phrase) @@ -350,12 +353,10 @@ namespace quickbook write_anchors(state, state.phrase); value_consumer values = phrase; - state.phrase - << "" - << values.consume().get_encoded() - << ""; + state.phrase << "" << values.consume().get_encoded() + << ""; values.finish(); } @@ -372,16 +373,16 @@ namespace quickbook std::string str; state.phrase.swap(str); - std::string::const_iterator - pos = str.begin(), - end = str.end(); + std::string::const_iterator pos = str.begin(), end = str.end(); - while(pos != end && cl::space_p.test(*pos)) ++pos; + while (pos != end && cl::space_p.test(*pos)) + ++pos; - if(pos != end) { - detail::markup markup = state.in_list ? - detail::get_markup(block_tags::paragraph_in_list) : - detail::get_markup(block_tags::paragraph); + if (pos != end) { + detail::markup markup = + state.in_list + ? detail::get_markup(block_tags::paragraph_in_list) + : detail::get_markup(block_tags::paragraph); state.out << markup.pre << str; write_anchors(state, state.out); state.out << markup.post; @@ -397,13 +398,17 @@ namespace quickbook { write_anchors(state, state.phrase); } - - namespace { - void write_bridgehead(quickbook::state& state, int level, - std::string const& str, std::string const& id, bool self_link) + + namespace + { + void write_bridgehead( + quickbook::state& state, + int level, + std::string const& str, + std::string const& id, + bool self_link) { - if (self_link && !id.empty()) - { + if (self_link && !id.empty()) { state.out << ""; state.out << ""; } - else - { + else { state.out << ""; state.out << str; state.out << ""; @@ -436,46 +440,43 @@ namespace quickbook int level; - if (generic) - { + if (generic) { level = state.document.section_level() + 1; - // We need to use a heading which is one greater - // than the current. - if (level > 6 ) // The max is h6, clip it if it goes - level = 6; // further than that + // We need to use a heading which is one greater + // than the current. + if (level > 6) // The max is h6, clip it if it goes + level = 6; // further than that } - else - { + else { level = heading_list.get_tag() - block_tags::heading1 + 1; } write_anchors(state, state.out); - if (!element_id.empty()) - { + if (!element_id.empty()) { // Use an explicit id. std::string anchor = state.document.add_id( - validate_id(state, element_id), - id_category::explicit_id); + validate_id(state, element_id), id_category::explicit_id); - write_bridgehead(state, level, - content.get_encoded(), anchor, self_linked_headers); + write_bridgehead( + state, level, content.get_encoded(), anchor, + self_linked_headers); } - else if (state.document.compatibility_version() >= 106u) - { + else if (state.document.compatibility_version() >= 106u) { // Generate ids for 1.6+ std::string anchor = state.document.add_id( detail::make_identifier(content.get_quickbook()), id_category::generated_heading); - write_bridgehead(state, level, - content.get_encoded(), anchor, self_linked_headers); + write_bridgehead( + state, level, content.get_encoded(), anchor, + self_linked_headers); } - else - { - // Generate ids that are compatible with older versions of quickbook. + else { + // Generate ids that are compatible with older versions of + // quickbook. // Older versions of quickbook used the generated boostbook, but // we only have an intermediate version which can contain id @@ -487,22 +488,23 @@ namespace quickbook // the content, it's just used to generate this id. std::string id = detail::make_identifier( - state.document.replace_placeholders_with_unresolved_ids( - content.get_encoded())); + state.document.replace_placeholders_with_unresolved_ids( + content.get_encoded())); if (generic || state.document.compatibility_version() >= 103) { std::string anchor = state.document.add_id(id, id_category::generated_heading); - write_bridgehead(state, level, - content.get_encoded(), anchor, self_linked_headers); + write_bridgehead( + state, level, content.get_encoded(), anchor, + self_linked_headers); } else { - std::string anchor = - state.document.old_style_id(id, id_category::generated_heading); + std::string anchor = state.document.old_style_id( + id, id_category::generated_heading); - write_bridgehead(state, level, - content.get_encoded(), anchor, false); + write_bridgehead( + state, level, content.get_encoded(), anchor, false); } } } @@ -511,13 +513,14 @@ namespace quickbook { write_anchors(state, state.phrase); - int tag = - mark == '*' ? phrase_tags::bold : - mark == '/' ? phrase_tags::italic : - mark == '_' ? phrase_tags::underline : - mark == '=' ? phrase_tags::teletype : - 0; - + int tag = mark == '*' + ? phrase_tags::bold + : mark == '/' + ? phrase_tags::italic + : mark == '_' + ? phrase_tags::underline + : mark == '=' ? phrase_tags::teletype : 0; + assert(tag != 0); detail::markup markup = detail::get_markup(tag); @@ -536,8 +539,7 @@ namespace quickbook saved_conditional = state.conditional; - if (saved_conditional) - { + if (saved_conditional) { bool positive = values.consume().get_quickbook().empty(); quickbook::string_view macro1 = values.consume().get_quickbook(); std::string macro(macro1.begin(), macro1.end()); @@ -553,11 +555,10 @@ namespace quickbook return true; } - + void cond_phrase_push::cleanup() { - if (saved_conditional && !state.conditional) - { + if (saved_conditional && !state.conditional) { state.pop_output(); state.anchors.swap(anchors); } @@ -609,14 +610,13 @@ namespace quickbook namespace { - bool parse_template(value const&, quickbook::state& state, - bool is_attribute_template = false); + bool parse_template( + value const&, + quickbook::state& state, + bool is_attribute_template = false); } - void state::start_callouts() - { - ++callout_depth; - } + void state::start_callouts() { ++callout_depth; } std::string state::add_callout(value v) { @@ -646,8 +646,7 @@ namespace quickbook if (!c.check()) return block; block += ""; - while (c.check()) - { + while (c.check()) { std::string callout_id1 = c.consume().get_encoded(); std::string callout_id2 = c.consume().get_encoded(); value callout_body = c.consume(); @@ -660,28 +659,28 @@ namespace quickbook bool r = parse_template(callout_body, *this); - if(!r) - { - detail::outerr(callout_body.get_file(), callout_body.get_position()) + if (!r) { + detail::outerr( + callout_body.get_file(), callout_body.get_position()) << "Expanding callout." << std::endl - << "------------------begin------------------" << std::endl - << callout_body.get_quickbook() + << "------------------begin------------------" << std::endl - << "------------------end--------------------" << std::endl - ; + << callout_body.get_quickbook() << std::endl + << "------------------end--------------------" + << std::endl; ++error_count; } out.swap(callout_value); } - + block += ""; block += callout_value; block += ""; } block += ""; - + return block; } @@ -693,8 +692,7 @@ namespace quickbook state.out << markup.pre; - BOOST_FOREACH(value item, list) - { + BOOST_FOREACH (value item, list) { state.out << ""; state.out << item.get_encoded(); state.out << ""; @@ -717,30 +715,25 @@ namespace quickbook { write_anchors(state, state.phrase); - if (str == quickbook_get_date) - { + if (str == quickbook_get_date) { char strdate[64]; strftime(strdate, sizeof(strdate), "%Y-%b-%d", current_time); state.phrase << strdate; } - else if (str == quickbook_get_time) - { + else if (str == quickbook_get_time) { char strdate[64]; strftime(strdate, sizeof(strdate), "%I:%M:%S %p", current_time); state.phrase << strdate; } - else - { + else { state.phrase << str; } } - void raw_char_action::operator()(char ch) const - { - state.phrase << ch; - } + void raw_char_action::operator()(char ch) const { state.phrase << ch; } - void raw_char_action::operator()(parse_iterator first, parse_iterator last) const + void raw_char_action::operator()( + parse_iterator first, parse_iterator last) const { while (first != last) state.phrase << *first++; @@ -767,12 +760,14 @@ namespace quickbook quickbook::string_view code_value = values.consume().get_quickbook(); values.finish(); - bool inline_code = code_tag == code_tags::inline_code || + bool inline_code = + code_tag == code_tags::inline_code || (code_tag == code_tags::inline_code_block && qbk_version_n < 106u); bool block = code_tag != code_tags::inline_code; - source_mode_type source_mode = state.source_mode_next ? - state.source_mode_next : state.current_source_mode().source_mode; + source_mode_type source_mode = + state.source_mode_next ? state.source_mode_next + : state.current_source_mode().source_mode; state.source_mode_next = 0; if (inline_code) { @@ -837,7 +832,8 @@ namespace quickbook detail::print_char(ch, state.phrase.get()); } - void plain_char_action::operator()(parse_iterator first, parse_iterator last) const + void plain_char_action::operator()( + parse_iterator first, parse_iterator last) const { write_anchors(state, state.phrase); @@ -845,23 +841,24 @@ namespace quickbook detail::print_char(*first++, state.phrase.get()); } - void escape_unicode_action::operator()(parse_iterator first, parse_iterator last) const + void escape_unicode_action::operator()( + parse_iterator first, parse_iterator last) const { write_anchors(state, state.phrase); - while(first != last && *first == '0') ++first; + while (first != last && *first == '0') + ++first; // Just ignore \u0000 // Maybe I should issue a warning? - if(first == last) return; - + if (first == last) return; + std::string hex_digits(first, last); - - if(hex_digits.size() == 2 && *first > '0' && *first <= '7') { + + if (hex_digits.size() == 2 && *first > '0' && *first <= '7') { using namespace std; detail::print_char( - (char) strtol(hex_digits.c_str(), 0, 16), - state.phrase.get()); + (char)strtol(hex_digits.c_str(), 0, 16), state.phrase.get()); } else { state.phrase << "&#x" << hex_digits << ";"; @@ -870,16 +867,13 @@ namespace quickbook void write_plain_text(std::ostream& out, value const& v) { - if (v.is_encoded()) - { + if (v.is_encoded()) { detail::print_string(v.get_encoded(), out); } else { quickbook::string_view value = v.get_quickbook(); - for(string_iterator - first = value.begin(), last = value.end(); - first != last; ++first) - { + for (string_iterator first = value.begin(), last = value.end(); + first != last; ++first) { if (*first == '\\' && ++first == last) break; detail::print_char(*first, out); } @@ -898,45 +892,43 @@ namespace quickbook value_consumer values = image; attributes["fileref"] = values.consume(); - BOOST_FOREACH(value pair_, values) - { + BOOST_FOREACH (value pair_, values) { value_consumer pair = pair_; value name = pair.consume(); value value = pair.consume(); - std::string name_str(name.get_quickbook().begin(), - name.get_quickbook().end()); + std::string name_str( + name.get_quickbook().begin(), name.get_quickbook().end()); pair.finish(); - if(!attributes.insert(std::make_pair(name_str, value)).second) - { + if (!attributes.insert(std::make_pair(name_str, value)).second) { detail::outwarn(name.get_file(), name.get_position()) - << "Duplicate image attribute: " - << name.get_quickbook() + << "Duplicate image attribute: " << name.get_quickbook() << std::endl; } } - + values.finish(); // Find the file basename and extension. // // Not using Boost.Filesystem because I want to stay in UTF-8. // Need to think about uri encoding. - - std::string fileref = attributes["fileref"].is_encoded() ? - attributes["fileref"].get_encoded() : - attributes["fileref"].get_quickbook().to_s(); + + std::string fileref = + attributes["fileref"].is_encoded() + ? attributes["fileref"].get_encoded() + : attributes["fileref"].get_quickbook().to_s(); // Check for windows paths, then convert. // A bit crude, but there you go. - if(fileref.find('\\') != std::string::npos) - { - (qbk_version_n >= 106u ? - detail::outerr(attributes["fileref"].get_file(), attributes["fileref"].get_position()) : - detail::outwarn(attributes["fileref"].get_file(), attributes["fileref"].get_position())) - << "Image path isn't portable: '" - << fileref - << "'" + if (fileref.find('\\') != std::string::npos) { + (qbk_version_n >= 106u ? detail::outerr( + attributes["fileref"].get_file(), + attributes["fileref"].get_position()) + : detail::outwarn( + attributes["fileref"].get_file(), + attributes["fileref"].get_position())) + << "Image path isn't portable: '" << fileref << "'" << std::endl; if (qbk_version_n >= 106u) ++state.error_count; } @@ -952,13 +944,10 @@ namespace quickbook std::string stem, extension; pos = fileref.rfind('/'); - stem = pos == std::string::npos ? - fileref : - fileref.substr(pos + 1); + stem = pos == std::string::npos ? fileref : fileref.substr(pos + 1); pos = stem.rfind('.'); - if (pos != std::string::npos) - { + if (pos != std::string::npos) { extension = stem.substr(pos + 1); stem = stem.substr(0, pos); } @@ -967,90 +956,86 @@ namespace quickbook // Or if there isn't one, use the stem of the file name. attribute_map::iterator alt_pos = attributes.find("alt"); - quickbook::value alt_text = - alt_pos != attributes.end() ? alt_pos->second : - qbk_version_n < 106u ? encoded_value(stem) : - quickbook::value(); + quickbook::value alt_text = alt_pos != attributes.end() + ? alt_pos->second + : qbk_version_n < 106u + ? encoded_value(stem) + : quickbook::value(); attributes.erase("alt"); - if(extension == "svg") - { - // - // SVG's need special handling: - // - // 1) We must set the "format" attribute, otherwise - // HTML generation produces code that will not display - // the image at all. - // 2) We need to set the "contentwidth" and "contentdepth" - // attributes, otherwise the image will be displayed inside - // a tiny box with scrollbars (Firefox), or else cropped to - // fit in a tiny box (IE7). - // - - attributes.insert(attribute_map::value_type("format", - encoded_value("SVG"))); - - // - // Image paths are relative to the html subdirectory: - // - fs::path img = detail::generic_to_path(fileref); - if (!img.has_root_directory()) - img = quickbook::image_location / img; // relative path - - // - // Now load the SVG file: - // - std::string svg_text; - if (state.dependencies.add_dependency(img)) { - fs::ifstream fs(img); - std::stringstream buffer; - buffer << fs.rdbuf(); - svg_text = buffer.str(); - } - - // - // Extract the svg header from the file: - // - std::string::size_type a, b; - a = svg_text.find("', a); - svg_text = (a == std::string::npos) ? "" : svg_text.substr(a, b - a); - // - // Now locate the "width" and "height" attributes - // and borrow their values: - // - a = svg_text.find("width"); - a = svg_text.find('=', a); - a = svg_text.find('\"', a); - b = svg_text.find('\"', a + 1); - if(a != std::string::npos) - { - attributes.insert(std::make_pair( - "contentwidth", encoded_value(std::string( - boost::next(svg_text.begin(), a + 1), - boost::next(svg_text.begin(), b))) - )); - } - a = svg_text.find("height"); - a = svg_text.find('=', a); - a = svg_text.find('\"', a); - b = svg_text.find('\"', a + 1); - if(a != std::string::npos) - { - attributes.insert(std::make_pair( - "contentdepth", encoded_value(std::string( - boost::next(svg_text.begin(), a + 1), - boost::next(svg_text.begin(), b))) - )); - } + if (extension == "svg") { + // + // SVG's need special handling: + // + // 1) We must set the "format" attribute, otherwise + // HTML generation produces code that will not display + // the image at all. + // 2) We need to set the "contentwidth" and "contentdepth" + // attributes, otherwise the image will be displayed inside + // a tiny box with scrollbars (Firefox), or else cropped to + // fit in a tiny box (IE7). + // + + attributes.insert( + attribute_map::value_type("format", encoded_value("SVG"))); + + // + // Image paths are relative to the html subdirectory: + // + fs::path img = detail::generic_to_path(fileref); + if (!img.has_root_directory()) + img = quickbook::image_location / img; // relative path + + // + // Now load the SVG file: + // + std::string svg_text; + if (state.dependencies.add_dependency(img)) { + fs::ifstream fs(img); + std::stringstream buffer; + buffer << fs.rdbuf(); + svg_text = buffer.str(); + } + + // + // Extract the svg header from the file: + // + std::string::size_type a, b; + a = svg_text.find("', a); + svg_text = + (a == std::string::npos) ? "" : svg_text.substr(a, b - a); + // + // Now locate the "width" and "height" attributes + // and borrow their values: + // + a = svg_text.find("width"); + a = svg_text.find('=', a); + a = svg_text.find('\"', a); + b = svg_text.find('\"', a + 1); + if (a != std::string::npos) { + attributes.insert(std::make_pair( + "contentwidth", encoded_value(std::string( + boost::next(svg_text.begin(), a + 1), + boost::next(svg_text.begin(), b))))); + } + a = svg_text.find("height"); + a = svg_text.find('=', a); + a = svg_text.find('\"', a); + b = svg_text.find('\"', a + 1); + if (a != std::string::npos) { + attributes.insert(std::make_pair( + "contentdepth", encoded_value(std::string( + boost::next(svg_text.begin(), a + 1), + boost::next(svg_text.begin(), b))))); + } } state.phrase << ""; state.phrase << ""; } - void macro_definition_action(quickbook::state& state, quickbook::value macro_definition) + void macro_definition_action( + quickbook::state& state, quickbook::value macro_definition) { value_consumer values = macro_definition; std::string macro_id = values.consume().get_quickbook().to_s(); @@ -1082,8 +1068,7 @@ namespace quickbook boost::spirit::classic::find(state.macro, macro_id.c_str()); quickbook::ignore_variable(&existing_macro); - if (existing_macro) - { + if (existing_macro) { if (qbk_version_n < 106) return; // Do this if you're using spirit's TST. @@ -1092,33 +1077,29 @@ namespace quickbook // return; } - state.macro.add( - macro_id.begin() - , macro_id.end() - , phrase); + state.macro.add(macro_id.begin(), macro_id.end(), phrase); } - void template_body_action(quickbook::state& state, quickbook::value template_definition) + void template_body_action( + quickbook::state& state, quickbook::value template_definition) { value_consumer values = template_definition; std::string identifier = values.consume().get_quickbook().to_s(); std::vector template_values; - BOOST_FOREACH(value const& p, values.consume()) { + BOOST_FOREACH (value const& p, values.consume()) { template_values.push_back(p.get_quickbook().to_s()); } - BOOST_ASSERT(values.check(template_tags::block) || values.check(template_tags::phrase)); + BOOST_ASSERT( + values.check(template_tags::block) || + values.check(template_tags::phrase)); value body = values.consume(); BOOST_ASSERT(!values.check()); - - if (!state.templates.add( - template_symbol( - identifier, - template_values, - body, - &state.templates.top_scope()))) - { + + if (!state.templates.add(template_symbol( + identifier, template_values, body, + &state.templates.top_scope()))) { detail::outwarn(body.get_file(), body.get_position()) << "Template Redefinition: " << identifier << std::endl; ++state.error_count; @@ -1127,13 +1108,12 @@ namespace quickbook namespace { - string_iterator find_first_seperator(string_iterator begin, string_iterator end) + string_iterator find_first_seperator( + string_iterator begin, string_iterator end) { - if(qbk_version_n < 105) { - for(;begin != end; ++begin) - { - switch(*begin) - { + if (qbk_version_n < 105) { + for (; begin != end; ++begin) { + switch (*begin) { case ' ': case '\t': case '\n': @@ -1147,15 +1127,13 @@ namespace quickbook else { unsigned int depth = 0; - for(;begin != end; ++begin) - { - switch(*begin) - { + for (; begin != end; ++begin) { + switch (*begin) { case '[': ++depth; break; case '\\': - if(++begin == end) return begin; + if (++begin == end) return begin; break; case ']': if (depth > 0) --depth; @@ -1170,18 +1148,17 @@ namespace quickbook } } } - + return begin; } - - std::pair find_seperator(string_iterator begin, string_iterator end) + + std::pair find_seperator( + string_iterator begin, string_iterator end) { string_iterator first = begin = find_first_seperator(begin, end); - for(;begin != end; ++begin) - { - switch(*begin) - { + for (; begin != end; ++begin) { + switch (*begin) { case ' ': case '\t': case '\n': @@ -1191,15 +1168,15 @@ namespace quickbook return std::make_pair(first, begin); } } - + return std::make_pair(first, begin); } - + void break_arguments( - std::vector& args - , std::vector const& params - , fs::path const& /* filename */ - ) + std::vector& args, + std::vector const& params, + fs::path const& /* filename */ + ) { // Quickbook 1.4-: If there aren't enough parameters seperated by // '..' then seperate the last parameter using @@ -1208,11 +1185,9 @@ namespace quickbook // then use whitespace to separate them // (2 = template name + argument). - if (qbk_version_n < 105 ? args.size() : args.size() == 1) - { - - while (args.size() < params.size()) - { + if (qbk_version_n < 105 ? args.size() : args.size() == 1) { + + while (args.size() < params.size()) { // Try to break the last argument at the first space found // and push it into the back of args. Do this // recursively until we have all the expected number of @@ -1221,55 +1196,52 @@ namespace quickbook value last_arg = args.back(); string_iterator begin = last_arg.get_quickbook().begin(); string_iterator end = last_arg.get_quickbook().end(); - + std::pair pos = find_seperator(begin, end); if (pos.second == end) break; - value new_arg( - qbk_value(last_arg.get_file(), - pos.second, end, template_tags::phrase)); + value new_arg(qbk_value( + last_arg.get_file(), pos.second, end, + template_tags::phrase)); - args.back() = qbk_value(last_arg.get_file(), - begin, pos.first, last_arg.get_tag()); + args.back() = qbk_value( + last_arg.get_file(), begin, pos.first, + last_arg.get_tag()); args.push_back(new_arg); } } } - std::pair::const_iterator> - get_arguments( - std::vector const& args - , std::vector const& params - , template_scope const& scope - , string_iterator first - , quickbook::state& state - ) + std::pair::const_iterator> get_arguments( + std::vector const& args, + std::vector const& params, + template_scope const& scope, + string_iterator first, + quickbook::state& state) { std::vector::const_iterator arg = args.begin(); std::vector::const_iterator tpl = params.begin(); std::vector empty_params; // Store each of the argument passed in as local templates: - while (arg != args.end()) - { + while (arg != args.end()) { if (!state.templates.add( - template_symbol(*tpl, empty_params, *arg, &scope))) - { + template_symbol(*tpl, empty_params, *arg, &scope))) { detail::outerr(state.current_file, first) << "Duplicate Symbol Found" << std::endl; ++state.error_count; return std::make_pair(false, tpl); } - ++arg; ++tpl; + ++arg; + ++tpl; } return std::make_pair(true, tpl); } - + bool parse_template( - value const& content - , quickbook::state& state - , bool is_attribute_template - ) + value const& content, + quickbook::state& state, + bool is_attribute_template) { file_ptr saved_current_file = state.current_file; @@ -1279,13 +1251,14 @@ namespace quickbook parse_iterator first(source.begin()); parse_iterator last(source.end()); - bool r = cl::parse(first, last, - is_attribute_template ? - state.grammar().attribute_template_body : - content.get_tag() == template_tags::phrase ? - state.grammar().inline_phrase : - state.grammar().block_start - ).full; + bool r = cl::parse( + first, last, + is_attribute_template + ? state.grammar().attribute_template_body + : content.get_tag() == template_tags::phrase + ? state.grammar().inline_phrase + : state.grammar().block_start) + .full; boost::swap(state.current_file, saved_current_file); @@ -1293,11 +1266,12 @@ namespace quickbook } } - void call_template(quickbook::state& state, - template_symbol const* symbol, - std::vector const& args, - string_iterator first, - bool is_attribute_template = false) + void call_template( + quickbook::state& state, + template_symbol const* symbol, + std::vector const& args, + string_iterator first, + bool is_attribute_template = false) { bool is_block = symbol->content.get_tag() != template_tags::phrase; assert(!(is_attribute_template && is_block)); @@ -1310,9 +1284,9 @@ namespace quickbook // If this template contains already encoded text, then just // write it out, without going through any of the rigamarole. - if (symbol->content.is_encoded()) - { - (is_block ? state.out : state.phrase) << symbol->content.get_encoded(); + if (symbol->content.is_encoded()) { + (is_block ? state.out : state.phrase) + << symbol->content.get_encoded(); return; } @@ -1333,8 +1307,7 @@ namespace quickbook qbk_version_n = symbol->content.get_file()->version(); ++state.template_depth; - if (state.template_depth > state.max_template_depth) - { + if (state.template_depth > state.max_template_depth) { detail::outerr(state.current_file, first) << "Infinite loop detected" << std::endl; ++state.error_count; @@ -1352,8 +1325,7 @@ namespace quickbook boost::tie(get_arg_result, tpl) = get_arguments(args, symbol->params, call_scope, first, state); - if (!get_arg_result) - { + if (!get_arg_result) { return; } @@ -1365,11 +1337,10 @@ namespace quickbook state.phrase.swap(save_phrase); } - if (!parse_template(symbol->content, state, is_attribute_template)) - { + if (!parse_template( + symbol->content, state, is_attribute_template)) { detail::outerr(state.current_file, first) - << "Expanding " - << (is_block ? "block" : "phrase") + << "Expanding " << (is_block ? "block" : "phrase") << " template: " << symbol->identifier << "\n\n" << "------------------begin------------------\n" << symbol->content.get_quickbook() @@ -1379,11 +1350,9 @@ namespace quickbook return; } - if (state.document.section_level() != state.min_section_level) - { + if (state.document.section_level() != state.min_section_level) { detail::outerr(state.current_file, first) - << "Mismatched sections in template " - << symbol->identifier + << "Mismatched sections in template " << symbol->identifier << std::endl; ++state.error_count; return; @@ -1393,7 +1362,7 @@ namespace quickbook state.out.swap(save_block); state.phrase.swap(save_phrase); - if(is_block || !save_block.empty()) { + if (is_block || !save_block.empty()) { paragraph_action(); state.out << save_block; state.phrase << save_phrase; @@ -1403,25 +1372,23 @@ namespace quickbook state.phrase << save_phrase; } } - else - { + else { if (is_block) paragraph_action(); } } } - void call_code_snippet(quickbook::state& state, - template_symbol const* symbol, - string_iterator first) + void call_code_snippet( + quickbook::state& state, + template_symbol const* symbol, + string_iterator first) { assert(symbol->params.size() == 0); std::vector args; // Create a fake symbol for call_template template_symbol t( - symbol->identifier, - symbol->params, - symbol->content, + symbol->identifier, symbol->params, symbol->content, symbol->lexical_parent); state.start_callouts(); @@ -1429,8 +1396,8 @@ namespace quickbook state.out << state.end_callouts(); } - void do_template_action(quickbook::state& state, value template_list, - string_iterator first) + void do_template_action( + quickbook::state& state, value template_list, string_iterator first) { bool const is_attribute_template = template_list.get_tag() == template_tags::attribute_template; @@ -1439,17 +1406,17 @@ namespace quickbook value_consumer values = template_list; bool template_escape = values.check(template_tags::escape); - if(template_escape) values.consume(); + if (template_escape) values.consume(); - std::string identifier = values.consume(template_tags::identifier).get_quickbook().to_s(); + std::string identifier = + values.consume(template_tags::identifier).get_quickbook().to_s(); std::vector args; - BOOST_FOREACH(value arg, values) - { + BOOST_FOREACH (value arg, values) { args.push_back(arg); } - + values.finish(); template_symbol const* symbol = state.templates.find(identifier); @@ -1457,22 +1424,17 @@ namespace quickbook // Deal with escaped templates. - if (template_escape) - { - if (!args.empty()) - { + if (template_escape) { + if (!args.empty()) { detail::outerr(state.current_file, first) - << "Arguments for escaped template." - <content.is_encoded()) - { + if (symbol->content.is_encoded()) { state.phrase << symbol->content.get_encoded(); } - else - { + else { state.phrase << symbol->content.get_quickbook(); /* @@ -1500,8 +1462,7 @@ namespace quickbook // Check that attribute templates are phrase templates if (is_attribute_template && - symbol->content.get_tag() != template_tags::phrase) - { + symbol->content.get_tag() != template_tags::phrase) { detail::outerr(state.current_file, first) << "Only phrase templates can be used in attribute values." << std::endl; @@ -1513,23 +1474,19 @@ namespace quickbook /////////////////////////////////// // Initialise the arguments - switch(symbol->content.get_tag()) - { + switch (symbol->content.get_tag()) { case template_tags::block: case template_tags::phrase: // Break the arguments for a template break_arguments(args, symbol->params, state.current_file->path); - if (args.size() != symbol->params.size()) - { + if (args.size() != symbol->params.size()) { detail::outerr(state.current_file, first) << "Invalid number of arguments passed. Expecting: " << symbol->params.size() - << " argument(s), got: " - << args.size() - << " argument(s) instead." - << std::endl; + << " argument(s), got: " << args.size() + << " argument(s) instead." << std::endl; ++state.error_count; return; @@ -1540,11 +1497,9 @@ namespace quickbook case template_tags::snippet: - if (!args.empty()) - { + if (!args.empty()) { detail::outerr(state.current_file, first) - << "Arguments for code snippet." - <"; @@ -1599,7 +1554,8 @@ namespace quickbook write_anchors(state, state.out); value_consumer values = variable_list; - std::string title = values.consume(table_tags::title).get_quickbook().to_s(); + std::string title = + values.consume(table_tags::title).get_quickbook().to_s(); state.out << "\n"; @@ -1607,18 +1563,19 @@ namespace quickbook detail::print_string(title, state.out.get()); state.out << "\n"; - BOOST_FOREACH(value_consumer entry, values) { + BOOST_FOREACH (value_consumer entry, values) { state.out << ""; - - if(entry.check()) { + + if (entry.check()) { state.out << ""; state.out << entry.consume().get_encoded(); state.out << ""; } - - if(entry.check()) { + + if (entry.check()) { state.out << ""; - BOOST_FOREACH(value phrase, entry) state.out << phrase.get_encoded(); + BOOST_FOREACH (value phrase, entry) + state.out << phrase.get_encoded(); state.out << ""; } @@ -1626,7 +1583,7 @@ namespace quickbook } state.out << "\n"; - + values.finish(); } @@ -1637,21 +1594,24 @@ namespace quickbook value_consumer values = table; std::string element_id; - if(values.check(general_tags::element_id)) { + if (values.check(general_tags::element_id)) { element_id = validate_id(state, values.consume()); } value title = values.consume(table_tags::title); bool has_title = !title.empty(); - + std::string table_id; if (!element_id.empty()) { - table_id = state.document.add_id(element_id, id_category::explicit_id); + table_id = + state.document.add_id(element_id, id_category::explicit_id); } else if (has_title) { if (state.document.compatibility_version() >= 105) { - table_id = state.document.add_id(detail::make_identifier(title.get_quickbook()), id_category::generated); + table_id = state.document.add_id( + detail::make_identifier(title.get_quickbook()), + id_category::generated); } else { table_id = state.document.add_id("t", id_category::numbered); @@ -1664,17 +1624,15 @@ namespace quickbook int span_count = 0; value_consumer lookahead = values; - BOOST_FOREACH(value row, lookahead) { + BOOST_FOREACH (value row, lookahead) { ++row_count; span_count = boost::distance(row); } lookahead.finish(); - if (has_title) - { + if (has_title) { state.out << "\n"; state.out << ""; if (qbk_version_n < 106u) { @@ -1685,52 +1643,49 @@ namespace quickbook } state.out << ""; } - else - { + else { state.out << "\n"; } state.out << "\n"; - if (row_count > 1) - { - state.out << "" << ""; - BOOST_FOREACH(value cell, values.consume()) { + if (row_count > 1) { + state.out << "" + << ""; + BOOST_FOREACH (value cell, values.consume()) { state.out << "" << cell.get_encoded() << ""; } - state.out << "\n" << "\n"; + state.out << "\n" + << "\n"; } state.out << "\n"; - BOOST_FOREACH(value row, values) { + BOOST_FOREACH (value row, values) { state.out << ""; - BOOST_FOREACH(value cell, row) { + BOOST_FOREACH (value cell, row) { state.out << "" << cell.get_encoded() << ""; } state.out << "\n"; } - + values.finish(); state.out << "\n" - << "\n"; + << "\n"; - if (has_title) - { + if (has_title) { state.out << "
\n"; } - else - { + else { state.out << "\n"; } } void begin_section_action(quickbook::state& state, value begin_section_list) - { + { value_consumer values = begin_section_list; value element_id = values.optional_consume(general_tags::element_id); @@ -1739,12 +1694,11 @@ namespace quickbook std::string full_id = state.document.begin_section( element_id, - element_id.empty() ? - detail::make_identifier(content.get_quickbook()) : - validate_id(state, element_id), - element_id.empty() ? - id_category::generated_section : - id_category::explicit_section_id, + element_id.empty() + ? detail::make_identifier(content.get_quickbook()) + : validate_id(state, element_id), + element_id.empty() ? id_category::generated_section + : id_category::explicit_section_id, state.current_source_mode()); state.out << "\n
\n"; @@ -1756,12 +1710,11 @@ namespace quickbook write_anchors(state, state.out); - if (self_linked_headers && state.document.compatibility_version() >= 103) - { + if (self_linked_headers && + state.document.compatibility_version() >= 103) { state.out << quickbook::detail::linkify(title, full_id); } - else - { + else { state.out << title; } @@ -1769,7 +1722,8 @@ namespace quickbook } } - void end_section_action(quickbook::state& state, value end_section_list, string_iterator first) + void end_section_action( + quickbook::state& state, value end_section_list, string_iterator first) { value_consumer values = end_section_list; value element_id = values.optional_consume(general_tags::element_id); @@ -1777,19 +1731,18 @@ namespace quickbook write_anchors(state, state.out); - if (state.document.section_level() <= state.min_section_level) - { + if (state.document.section_level() <= state.min_section_level) { file_position const pos = state.current_file->position_of(first); detail::outerr(state.current_file->path, pos.line) << "Mismatched [endsect] near column " << pos.column << ".\n"; ++state.error_count; - + return; } - if (!element_id.empty() && !(element_id == state.document.explicit_id())) - { + if (!element_id.empty() && + !(element_id == state.document.explicit_id())) { file_position const pos = state.current_file->position_of(first); value section_element_id = state.document.explicit_id(); @@ -1799,14 +1752,13 @@ namespace quickbook << element_id.get_quickbook() << "' in section with no explicit id, near column " << pos.column << ".\n"; - } else { + } + else { detail::outerr(state.current_file->path, pos.line) << "Endsect has incorrect id '" - << element_id.get_quickbook() - << "', expected '" + << element_id.get_quickbook() << "', expected '" << state.document.explicit_id().get_quickbook() - << "', near column " - << pos.column << ".\n"; + << "', near column " << pos.column << ".\n"; } ++state.error_count; } @@ -1814,8 +1766,9 @@ namespace quickbook state.out << "
"; state.document.end_section(); } - - void element_id_warning_action::operator()(parse_iterator first, parse_iterator) const + + void element_id_warning_action::operator()( + parse_iterator first, parse_iterator) const { detail::outwarn(state.current_file, first.base()) << "Empty id.\n"; } @@ -1828,27 +1781,29 @@ namespace quickbook path_parameter x = check_xinclude_path(values.consume(), state); values.finish(); - if (x.type == path_parameter::path) - { + if (x.type == path_parameter::path) { quickbook_path path = resolve_xinclude_path(x.value, state, true); state.out << "\n\n"; } } - void load_quickbook(quickbook::state& state, - quickbook_path const& path, - value::tag_type load_type, - value const& include_doc_id = value()) + void load_quickbook( + quickbook::state& state, + quickbook_path const& path, + value::tag_type load_type, + value const& include_doc_id = value()) { - assert(load_type == block_tags::include || + assert( + load_type == block_tags::include || load_type == block_tags::import); // Check this before qbk_version_n gets changed by the inner file. bool keep_inner_source_mode = (qbk_version_n < 106); - + { // When importing, state doesn't scope templates and macros so that // they're added to the existing scope. It might be better to add @@ -1857,10 +1812,12 @@ namespace quickbook // // For old versions of quickbook, templates aren't scoped by the // file. - state_save save(state, - load_type == block_tags::import ? state_save::scope_output : - qbk_version_n >= 106u ? state_save::scope_callables : - state_save::scope_macros); + state_save save( + state, + load_type == block_tags::import + ? state_save::scope_output + : qbk_version_n >= 106u ? state_save::scope_callables + : state_save::scope_macros); state.current_file = load(path.file_path); // Throws load_error state.current_path = path; @@ -1868,7 +1825,7 @@ namespace quickbook // update the __FILENAME__ macro state.update_filename_macro(); - + // parse the file quickbook::parse_file(state, include_doc_id, true); @@ -1880,13 +1837,15 @@ namespace quickbook state.update_filename_macro(); } - void load_source_file(quickbook::state& state, - quickbook_path const& path, - value::tag_type load_type, - string_iterator first, - value const& /* include_doc_id */ = value()) + void load_source_file( + quickbook::state& state, + quickbook_path const& path, + value::tag_type load_type, + string_iterator first, + value const& /* include_doc_id */ = value()) { - assert(load_type == block_tags::include || + assert( + load_type == block_tags::include || load_type == block_tags::import); std::string ext = path.file_path.extension().generic_string(); @@ -1895,34 +1854,28 @@ namespace quickbook state.error_count += load_snippets(path.file_path, storage, ext, load_type); - if (load_type == block_tags::include) - { + if (load_type == block_tags::include) { state.templates.push(); } - BOOST_FOREACH(template_symbol& ts, storage) - { + BOOST_FOREACH (template_symbol& ts, storage) { std::string tname = ts.identifier; - if (tname != "!") - { + if (tname != "!") { ts.lexical_parent = &state.templates.top_scope(); - if (!state.templates.add(ts)) - { - detail::outerr(ts.content.get_file(), ts.content.get_position()) + if (!state.templates.add(ts)) { + detail::outerr( + ts.content.get_file(), ts.content.get_position()) << "Template Redefinition: " << tname << std::endl; ++state.error_count; } } } - if (load_type == block_tags::include) - { - BOOST_FOREACH(template_symbol& ts, storage) - { + if (load_type == block_tags::include) { + BOOST_FOREACH (template_symbol& ts, storage) { std::string tname = ts.identifier; - if (tname == "!") - { + if (tname == "!") { ts.lexical_parent = &state.templates.top_scope(); call_code_snippet(state, &ts, first); } @@ -1932,56 +1885,55 @@ namespace quickbook } } - void include_action(quickbook::state& state, value include, string_iterator first) + void include_action( + quickbook::state& state, value include, string_iterator first) { write_anchors(state, state.out); value_consumer values = include; - value include_doc_id = values.optional_consume(general_tags::include_id); + value include_doc_id = + values.optional_consume(general_tags::include_id); path_parameter parameter = check_path(values.consume(), state); values.finish(); std::set search = include_search(parameter, state, first); - BOOST_FOREACH(quickbook_path const& path, search) - { + BOOST_FOREACH (quickbook_path const& path, search) { try { - if (qbk_version_n >= 106) - { - if (state.imported && include.get_tag() == block_tags::include) + if (qbk_version_n >= 106) { + if (state.imported && + include.get_tag() == block_tags::include) return; - std::string ext = path.file_path.extension().generic_string(); + std::string ext = + path.file_path.extension().generic_string(); - if (ext == ".qbk" || ext == ".quickbook") - { - load_quickbook(state, path, include.get_tag(), include_doc_id); + if (ext == ".qbk" || ext == ".quickbook") { + load_quickbook( + state, path, include.get_tag(), include_doc_id); } - else - { - load_source_file(state, path, include.get_tag(), first, include_doc_id); + else { + load_source_file( + state, path, include.get_tag(), first, + include_doc_id); } } - else - { - if (include.get_tag() == block_tags::include) - { - load_quickbook(state, path, include.get_tag(), include_doc_id); + else { + if (include.get_tag() == block_tags::include) { + load_quickbook( + state, path, include.get_tag(), include_doc_id); } - else - { - load_source_file(state, path, include.get_tag(), first, include_doc_id); + else { + load_source_file( + state, path, include.get_tag(), first, + include_doc_id); } } - } - catch (load_error& e) { + } catch (load_error& e) { ++state.error_count; detail::outerr(state.current_file, first) - << "Loading file " - << path.file_path - << ": " - << e.what() + << "Loading file " << path.file_path << ": " << e.what() << std::endl; } } @@ -1996,19 +1948,18 @@ namespace quickbook return true; } - void to_value_scoped_action::success(parse_iterator first, parse_iterator last) + void to_value_scoped_action::success( + parse_iterator first, parse_iterator last) { std::string value; - if (!state.out.str().empty()) - { + if (!state.out.str().empty()) { paragraph_action para(state); para(); // For paragraphs before the template call. write_anchors(state, state.out); state.out.swap(value); } - else - { + else { write_anchors(state, state.phrase); state.phrase.swap(value); } @@ -2016,8 +1967,7 @@ namespace quickbook state.values.builder.insert(encoded_qbk_value( state.current_file, first.base(), last.base(), value, tag)); } - - + void to_value_scoped_action::cleanup() { state.pop_output(); diff --git a/tools/quickbook/src/actions.hpp b/tools/quickbook/src/actions.hpp index 513fcfdfc7..7039094ddd 100644 --- a/tools/quickbook/src/actions.hpp +++ b/tools/quickbook/src/actions.hpp @@ -12,51 +12,59 @@ #include #include +#include #include "fwd.hpp" +#include "iterator.hpp" +#include "scoped.hpp" #include "utils.hpp" #include "values.hpp" -#include "scoped.hpp" -#include "iterator.hpp" -#include namespace quickbook { namespace cl = boost::spirit::classic; // Match if quickbook version is within range - struct quickbook_range : cl::parser { + struct quickbook_range : cl::parser + { explicit quickbook_range(unsigned lower_, unsigned upper_) - : lower(lower_), upper(upper_) {} + : lower(lower_), upper(upper_) + { + } bool in_range() const; - + template - typename cl::parser_result::type - parse(ScannerT const& scan) const + typename cl::parser_result::type parse( + ScannerT const& scan) const { return in_range() ? scan.empty_match() : scan.no_match(); } unsigned lower, upper; }; - - inline quickbook_range qbk_ver(unsigned lower, unsigned upper = 999u) { + + inline quickbook_range qbk_ver(unsigned lower, unsigned upper = 999u) + { return quickbook_range(lower, upper); } // Match if in strict mode. - struct quickbook_strict : cl::parser { - explicit quickbook_strict(quickbook::state& state_, bool positive_ = true) - : state(state_), positive(positive_) {} + struct quickbook_strict : cl::parser + { + explicit quickbook_strict( + quickbook::state& state_, bool positive_ = true) + : state(state_), positive(positive_) + { + } bool is_strict_checking() const; template - typename cl::parser_result::type - parse(ScannerT const& scan) const + typename cl::parser_result::type parse( + ScannerT const& scan) const { - return is_strict_checking() == positive ? - scan.empty_match() : scan.no_match(); + return is_strict_checking() == positive ? scan.empty_match() + : scan.no_match(); } quickbook_strict operator~() const @@ -68,22 +76,28 @@ namespace quickbook bool positive; }; - inline quickbook_strict qbk_strict(quickbook::state& state, unsigned lower = 999u) { + inline quickbook_strict qbk_strict( + quickbook::state& state, unsigned lower = 999u) + { return quickbook_strict(state, lower); } // Throws load_error - int load_snippets(fs::path const& file, std::vector& storage, - std::string const& extension, value::tag_type load_type); + int load_snippets( + fs::path const& file, + std::vector& storage, + std::string const& extension, + value::tag_type load_type); struct error_message_action { // Prints an error message to std::cerr - explicit error_message_action(quickbook::state& state_, std::string const& message_) - : state(state_) - , message(message_) - {} + explicit error_message_action( + quickbook::state& state_, std::string const& message_) + : state(state_), message(message_) + { + } void operator()(parse_iterator, parse_iterator) const; @@ -95,8 +109,7 @@ namespace quickbook { // Prints an error message to std::cerr - explicit error_action(quickbook::state& state_) - : state(state_) {} + explicit error_action(quickbook::state& state_) : state(state_) {} void operator()(parse_iterator first, parse_iterator last) const; @@ -110,8 +123,7 @@ namespace quickbook struct element_action { - explicit element_action(quickbook::state& state_) - : state(state_) {} + explicit element_action(quickbook::state& state_) : state(state_) {} void operator()(parse_iterator, parse_iterator) const; @@ -123,8 +135,7 @@ namespace quickbook // implicit paragraphs // doesn't output the paragraph if it's only whitespace. - explicit paragraph_action(quickbook::state& state_) - : state(state_) {} + explicit paragraph_action(quickbook::state& state_) : state(state_) {} void operator()() const; void operator()(parse_iterator, parse_iterator) const { (*this)(); } @@ -137,8 +148,9 @@ namespace quickbook // implicit paragraphs // doesn't output the paragraph if it's only whitespace. - explicit explicit_list_action(quickbook::state& state_) - : state(state_) {} + explicit explicit_list_action(quickbook::state& state_) : state(state_) + { + } void operator()() const; void operator()(parse_iterator, parse_iterator) const { (*this)(); } @@ -148,8 +160,7 @@ namespace quickbook struct phrase_end_action { - explicit phrase_end_action(quickbook::state& state_) - : state(state_) {} + explicit phrase_end_action(quickbook::state& state_) : state(state_) {} void operator()() const; void operator()(parse_iterator, parse_iterator) const { (*this)(); } @@ -161,8 +172,9 @@ namespace quickbook { // Handles simple text formats - explicit simple_phrase_action(quickbook::state& state_) - : state(state_) {} + explicit simple_phrase_action(quickbook::state& state_) : state(state_) + { + } void operator()(char) const; @@ -171,8 +183,7 @@ namespace quickbook struct cond_phrase_push : scoped_action_base { - cond_phrase_push(quickbook::state& x) - : state(x) {} + cond_phrase_push(quickbook::state& x) : state(x) {} bool start(); void cleanup(); @@ -216,10 +227,12 @@ namespace quickbook quickbook::state& state; }; - + struct escape_unicode_action { - explicit escape_unicode_action(quickbook::state& state_) : state(state_) {} + explicit escape_unicode_action(quickbook::state& state_) : state(state_) + { + } void operator()(parse_iterator first, parse_iterator last) const; @@ -235,24 +248,29 @@ namespace quickbook quickbook::state& state; }; - struct element_id_warning_action - { + struct element_id_warning_action + { explicit element_id_warning_action(quickbook::state& state_) - : state(state_) {} + : state(state_) + { + } void operator()(parse_iterator first, parse_iterator last) const; quickbook::state& state; - }; + }; // Returns the doc_type, or an empty string if there isn't one. - std::string pre(quickbook::state& state, parse_iterator pos, value include_doc_id, bool nested_file); + std::string pre( + quickbook::state& state, + parse_iterator pos, + value include_doc_id, + bool nested_file); void post(quickbook::state& state, std::string const& doc_type); struct to_value_scoped_action : scoped_action_base { - to_value_scoped_action(quickbook::state& state_) - : state(state_) {} + to_value_scoped_action(quickbook::state& state_) : state(state_) {} bool start(value::tag_type = value::default_tag); void success(parse_iterator, parse_iterator); @@ -267,29 +285,30 @@ namespace quickbook // // Action for calling a member function taking two parse iterators. - template - struct member_action + template struct member_action { - typedef void(T::*member_function)(parse_iterator, parse_iterator); + typedef void (T::*member_function)(parse_iterator, parse_iterator); T& l; member_function mf; explicit member_action(T& l_, member_function mf_) : l(l_), mf(mf_) {} - void operator()(parse_iterator first, parse_iterator last) const { + void operator()(parse_iterator first, parse_iterator last) const + { (l.*mf)(first, last); } }; // member_action1 // - // Action for calling a member function taking two parse iterators and a value. + // Action for calling a member function taking two parse iterators and a + // value. - template - struct member_action1 + template struct member_action1 { - typedef void(T::*member_function)(parse_iterator, parse_iterator, Arg1); + typedef void (T::*member_function)( + parse_iterator, parse_iterator, Arg1); T& l; member_function mf; @@ -301,61 +320,59 @@ namespace quickbook member_action1 a; Arg1 value; - explicit impl(member_action1& a_, Arg1 value_) : - a(a_), value(value_) - {} + explicit impl(member_action1& a_, Arg1 value_) + : a(a_), value(value_) + { + } - void operator()(parse_iterator first, parse_iterator last) const { + void operator()(parse_iterator first, parse_iterator last) const + { (a.l.*a.mf)(first, last, value); } }; - impl operator()(Arg1 a1) { - return impl(*this, a1); - } + impl operator()(Arg1 a1) { return impl(*this, a1); } }; // member_action_value // // Action for calling a unary member function. - template - struct member_action_value + template struct member_action_value { - typedef void(T::*member_function)(Value); + typedef void (T::*member_function)(Value); T& l; member_function mf; - explicit member_action_value(T& l_, member_function mf_) : l(l_), mf(mf_) {} - - void operator()(Value v) const { - (l.*mf)(v); + explicit member_action_value(T& l_, member_function mf_) + : l(l_), mf(mf_) + { } + + void operator()(Value v) const { (l.*mf)(v); } }; // member_action_value // // Action for calling a unary member function with a fixed value. - template - struct member_action_fixed_value + template struct member_action_fixed_value { - typedef void(T::*member_function)(Value); + typedef void (T::*member_function)(Value); T& l; member_function mf; Value v; - explicit member_action_fixed_value(T& l_, member_function mf_, Value v_) : l(l_), mf(mf_), v(v_) {} - - void operator()() const { - (l.*mf)(v); + explicit member_action_fixed_value(T& l_, member_function mf_, Value v_) + : l(l_), mf(mf_), v(v_) + { } - void operator()(parse_iterator, parse_iterator) const { - (l.*mf)(v); - } + void operator()() const { (l.*mf)(v); } + + void operator()(parse_iterator, parse_iterator) const { (l.*mf)(v); } }; } diff --git a/tools/quickbook/src/block_element_grammar.cpp b/tools/quickbook/src/block_element_grammar.cpp index 331e43e63c..b17581d82b 100644 --- a/tools/quickbook/src/block_element_grammar.cpp +++ b/tools/quickbook/src/block_element_grammar.cpp @@ -8,17 +8,17 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "utils.hpp" -#include "state.hpp" -#include "actions.hpp" -#include "grammar_impl.hpp" -#include "block_tags.hpp" -#include "template_tags.hpp" #include -#include #include -#include +#include #include +#include +#include "actions.hpp" +#include "block_tags.hpp" +#include "grammar_impl.hpp" +#include "state.hpp" +#include "template_tags.hpp" +#include "utils.hpp" namespace quickbook { @@ -27,22 +27,18 @@ namespace quickbook struct block_element_grammar_local { - cl::rule - heading, inner_block, inner_phrase, def_macro, - table, table_title, table_row, variablelist, - varlistentry, varlistterm, list, cell, - preformatted, begin_section, end_section, - xinclude, include, include_filename, - template_, template_id, template_formal_arg, - template_body, identifier, import, - element_id, - same_line; + cl::rule heading, inner_block, inner_phrase, def_macro, table, + table_title, table_row, variablelist, varlistentry, varlistterm, + list, cell, preformatted, begin_section, end_section, xinclude, + include, include_filename, template_, template_id, + template_formal_arg, template_body, identifier, import, element_id, + same_line; }; void quickbook_grammar::impl::init_block_elements() { - block_element_grammar_local& local = cleanup_.add( - new block_element_grammar_local); + block_element_grammar_local& local = + cleanup_.add(new block_element_grammar_local); // Actions error_action error(state); @@ -51,6 +47,8 @@ namespace quickbook explicit_list_action explicit_list(state); scoped_parser to_value(state); + // clang-format off + local.element_id = !( ':' >> ( qbk_ver(107u) @@ -331,5 +329,7 @@ namespace quickbook paragraph_phrase ] ; + + // clang-format on } } diff --git a/tools/quickbook/src/block_tags.hpp b/tools/quickbook/src/block_tags.hpp index 3049b57c51..88d8917157 100644 --- a/tools/quickbook/src/block_tags.hpp +++ b/tools/quickbook/src/block_tags.hpp @@ -13,6 +13,8 @@ namespace quickbook { + // clang-format off + QUICKBOOK_VALUE_TAGS(block_tags, 0x200, (begin_section)(end_section) (generic_heading) @@ -35,6 +37,7 @@ namespace quickbook (element_id)(include_id)(list_indent)(list_mark) ) + // clang-format on } #endif diff --git a/tools/quickbook/src/cleanup.hpp b/tools/quickbook/src/cleanup.hpp index 9e952b7cab..41ca4da72d 100644 --- a/tools/quickbook/src/cleanup.hpp +++ b/tools/quickbook/src/cleanup.hpp @@ -30,14 +30,17 @@ namespace quickbook // should be okay for an object to depend on something that was previously // added. - namespace detail { struct cleanup_node; } + namespace detail + { + struct cleanup_node; + } struct cleanup { cleanup() : first_(0) {} ~cleanup(); template T& add(T*); - private: + private: detail::cleanup_node* first_; cleanup& operator=(cleanup const&); @@ -46,38 +49,42 @@ namespace quickbook namespace detail { - template - void delete_impl(void* ptr) { + template void delete_impl(void* ptr) + { delete static_cast(ptr); } - + struct cleanup_node { void* ptr_; void (*del_)(void*); cleanup_node* next_; - + cleanup_node() : ptr_(0), del_(0), next_(0) {} cleanup_node(void* ptr, void (*del)(void* x)) - : ptr_(ptr), del_(del), next_(0) {} - ~cleanup_node() { - if(ptr_) del_(ptr_); + : ptr_(ptr), del_(del), next_(0) + { } - - void move_assign(cleanup_node& n) { + ~cleanup_node() + { + if (ptr_) del_(ptr_); + } + + void move_assign(cleanup_node& n) + { ptr_ = n.ptr_; del_ = n.del_; n.ptr_ = 0; n.del_ = 0; } - private: + + private: cleanup_node(cleanup_node const&); cleanup_node& operator=(cleanup_node const&); }; } - - template - T& cleanup::add(T* ptr) + + template T& cleanup::add(T* ptr) { detail::cleanup_node n(ptr, &detail::delete_impl); detail::cleanup_node* n2 = new detail::cleanup_node(); @@ -87,8 +94,9 @@ namespace quickbook return *ptr; } - inline cleanup::~cleanup() { - while(first_) { + inline cleanup::~cleanup() + { + while (first_) { detail::cleanup_node* to_delete = first_; first_ = first_->next_; delete to_delete; diff --git a/tools/quickbook/src/code_snippet.cpp b/tools/quickbook/src/code_snippet.cpp index 39a88d6307..03b7cdf2e8 100644 --- a/tools/quickbook/src/code_snippet.cpp +++ b/tools/quickbook/src/code_snippet.cpp @@ -7,18 +7,18 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include +#include +#include #include #include -#include -#include -#include "block_tags.hpp" -#include "template_stack.hpp" +#include #include "actions.hpp" -#include "state.hpp" -#include "values.hpp" +#include "block_tags.hpp" #include "files.hpp" +#include "state.hpp" #include "stream.hpp" +#include "template_stack.hpp" +#include "values.hpp" namespace quickbook { @@ -26,9 +26,10 @@ namespace quickbook struct code_snippet_actions { - code_snippet_actions(std::vector& storage_, - file_ptr source_file_, - char const* source_type_) + code_snippet_actions( + std::vector& storage_, + file_ptr source_file_, + char const* source_type_) : last_code_pos(source_file_->source().begin()) , in_code(false) , snippet_stack() @@ -49,26 +50,22 @@ namespace quickbook void end_snippet(string_iterator first, string_iterator last); void end_snippet_impl(string_iterator); void end_file(string_iterator, string_iterator); - + void append_code(string_iterator first, string_iterator last); void close_code(); struct snippet_data { - snippet_data(std::string const& id_) - : id(id_) - , start_code(false) - {} - + snippet_data(std::string const& id_) : id(id_), start_code(false) {} + std::string id; bool start_code; string_iterator source_pos; mapped_file_builder::pos_type start_pos; boost::shared_ptr next; }; - - void push_snippet_data(std::string const& id, - string_iterator pos) + + void push_snippet_data(std::string const& id, string_iterator pos) { boost::shared_ptr new_snippet(new snippet_data(id)); new_snippet->next = snippet_stack; @@ -101,18 +98,18 @@ namespace quickbook : cl::grammar { typedef code_snippet_actions actions_type; - - python_code_snippet_grammar(actions_type & actions_) - : actions(actions_) - {} - template - struct definition + python_code_snippet_grammar(actions_type& actions_) : actions(actions_) + { + } + + template struct definition { typedef code_snippet_actions actions_type; - + definition(python_code_snippet_grammar const& self) { + // clang-format off start_ = (*code_elements) [boost::bind(&actions_type::end_file, &self.actions, _1, _2)] ; @@ -190,33 +187,31 @@ namespace quickbook "\"\"\"" ) ; + + // clang-format on } - cl::rule - start_, identifier, code_elements, start_snippet, end_snippet, - escaped_comment, pass_thru_comment, ignore; + cl::rule start_, identifier, code_elements, start_snippet, + end_snippet, escaped_comment, pass_thru_comment, ignore; - cl::rule const& - start() const { return start_; } + cl::rule const& start() const { return start_; } }; actions_type& actions; - }; + }; - struct cpp_code_snippet_grammar - : cl::grammar + struct cpp_code_snippet_grammar : cl::grammar { typedef code_snippet_actions actions_type; - - cpp_code_snippet_grammar(actions_type & actions_) - : actions(actions_) - {} - template - struct definition + cpp_code_snippet_grammar(actions_type& actions_) : actions(actions_) {} + + template struct definition { definition(cpp_code_snippet_grammar const& self) { + // clang-format off + start_ = (*code_elements) [boost::bind(&actions_type::end_file, &self.actions, _1, _2)] ; @@ -321,56 +316,62 @@ namespace quickbook "*/" ) ; + + // clang-format on } - cl::rule - start_, identifier, code_elements, start_snippet, end_snippet, - escaped_comment, pass_thru_comment, ignore; + cl::rule start_, identifier, code_elements, start_snippet, + end_snippet, escaped_comment, pass_thru_comment, ignore; - cl::rule const& - start() const { return start_; } + cl::rule const& start() const { return start_; } }; actions_type& actions; }; int load_snippets( - fs::path const& filename - , std::vector& storage // snippets are stored in a - // vector of template_symbols - , std::string const& extension - , value::tag_type load_type) + fs::path const& filename, + std::vector& storage // snippets are stored in a + // vector of template_symbols + , + std::string const& extension, + value::tag_type load_type) { - assert(load_type == block_tags::include || + assert( + load_type == block_tags::include || load_type == block_tags::import); bool is_python = extension == ".py" || extension == ".jam"; - code_snippet_actions a(storage, load(filename, qbk_version_n), is_python ? "[python]" : "[c++]"); + code_snippet_actions a( + storage, load(filename, qbk_version_n), + is_python ? "[python]" : "[c++]"); string_iterator first(a.source_file->source().begin()); string_iterator last(a.source_file->source().end()); cl::parse_info info; - if(is_python) { - info = boost::spirit::classic::parse(first, last, python_code_snippet_grammar(a)); + if (is_python) { + info = boost::spirit::classic::parse( + first, last, python_code_snippet_grammar(a)); } else { - info = boost::spirit::classic::parse(first, last, cpp_code_snippet_grammar(a)); + info = boost::spirit::classic::parse( + first, last, cpp_code_snippet_grammar(a)); } assert(info.full); return a.error_count; } - void code_snippet_actions::append_code(string_iterator first, string_iterator last) + void code_snippet_actions::append_code( + string_iterator first, string_iterator last) { assert(last_code_pos <= first); - if(snippet_stack) { + if (snippet_stack) { if (last_code_pos != first) { - if (!in_code) - { + if (!in_code) { content.add_at_pos("\n\n", last_code_pos); content.add_at_pos(source_type, last_code_pos); content.add_at_pos("```\n", last_code_pos); @@ -378,19 +379,19 @@ namespace quickbook in_code = true; } - content.add(quickbook::string_view(last_code_pos, first - last_code_pos)); + content.add(quickbook::string_view( + last_code_pos, first - last_code_pos)); } } - + last_code_pos = last; } - + void code_snippet_actions::close_code() { if (!snippet_stack) return; - - if (in_code) - { + + if (in_code) { content.add_at_pos("\n```\n\n", last_code_pos); in_code = false; } @@ -402,13 +403,13 @@ namespace quickbook mark_end = last; } - void code_snippet_actions::pass_thru(string_iterator first, string_iterator last) + void code_snippet_actions::pass_thru( + string_iterator first, string_iterator last) { - if(!snippet_stack) return; + if (!snippet_stack) return; append_code(first, last); - if (!in_code) - { + if (!in_code) { content.add_at_pos("\n\n", first); content.add_at_pos(source_type, first); content.add_at_pos("```\n", first); @@ -418,58 +419,57 @@ namespace quickbook content.add(quickbook::string_view(mark_begin, mark_end - mark_begin)); } - void code_snippet_actions::escaped_comment(string_iterator first, string_iterator last) + void code_snippet_actions::escaped_comment( + string_iterator first, string_iterator last) { append_code(first, last); close_code(); - if (mark_begin != mark_end) - { - if (!snippet_stack) - { + if (mark_begin != mark_end) { + if (!snippet_stack) { start_snippet_impl("!", first); } - + snippet_data& snippet = *snippet_stack; content.add_at_pos("\n", mark_begin); - content.unindent_and_add(quickbook::string_view(mark_begin, mark_end - mark_begin)); + content.unindent_and_add( + quickbook::string_view(mark_begin, mark_end - mark_begin)); - if (snippet.id == "!") - { + if (snippet.id == "!") { end_snippet_impl(last); } } } - void code_snippet_actions::start_snippet(string_iterator first, string_iterator last) + void code_snippet_actions::start_snippet( + string_iterator first, string_iterator last) { append_code(first, last); start_snippet_impl(std::string(mark_begin, mark_end), first); } - void code_snippet_actions::end_snippet(string_iterator first, string_iterator last) + void code_snippet_actions::end_snippet( + string_iterator first, string_iterator last) { append_code(first, last); - if(!snippet_stack) { + if (!snippet_stack) { if (qbk_version_n >= 106u) { detail::outerr(source_file, first) - << "Mismatched end snippet." - << std::endl; + << "Mismatched end snippet." << std::endl; ++error_count; } else { detail::outwarn(source_file, first) - << "Mismatched end snippet." - << std::endl; + << "Mismatched end snippet." << std::endl; } return; } end_snippet_impl(first); } - + void code_snippet_actions::end_file(string_iterator, string_iterator pos) { append_code(pos, pos); @@ -478,26 +478,22 @@ namespace quickbook while (snippet_stack) { if (qbk_version_n >= 106u) { detail::outerr(source_file->path) - << "Unclosed snippet '" - << snippet_stack->id - << "'" + << "Unclosed snippet '" << snippet_stack->id << "'" << std::endl; ++error_count; } else { detail::outwarn(source_file->path) - << "Unclosed snippet '" - << snippet_stack->id - << "'" + << "Unclosed snippet '" << snippet_stack->id << "'" << std::endl; } - + end_snippet_impl(pos); } } - void code_snippet_actions::start_snippet_impl(std::string const& id, - string_iterator position) + void code_snippet_actions::start_snippet_impl( + std::string const& id, string_iterator position) { push_snippet_data(id, position); } @@ -524,8 +520,10 @@ namespace quickbook file_ptr body = f.release(); - storage.push_back(template_symbol(snippet->id, params, - qbk_value(body, body->source().begin(), body->source().end(), + storage.push_back(template_symbol( + snippet->id, params, + qbk_value( + body, body->source().begin(), body->source().end(), template_tags::snippet))); } } diff --git a/tools/quickbook/src/collector.cpp b/tools/quickbook/src/collector.cpp index fb2daec901..31324ab32f 100644 --- a/tools/quickbook/src/collector.cpp +++ b/tools/quickbook/src/collector.cpp @@ -13,48 +13,40 @@ namespace quickbook { string_stream::string_stream() : buffer_ptr(new std::string()) - , stream_ptr(new ostream(boost::iostreams::back_inserter(*buffer_ptr.get()))) - {} + , stream_ptr( + new ostream(boost::iostreams::back_inserter(*buffer_ptr.get()))) + { + } string_stream::string_stream(string_stream const& other) - : buffer_ptr(other.buffer_ptr) - , stream_ptr(other.stream_ptr) - {} - - string_stream& - string_stream::operator=(string_stream const& other) + : buffer_ptr(other.buffer_ptr), stream_ptr(other.stream_ptr) + { + } + + string_stream& string_stream::operator=(string_stream const& other) { buffer_ptr = other.buffer_ptr; stream_ptr = other.stream_ptr; return *this; } - - collector::collector() - : main(default_) - , top(default_) - { - } - collector::collector(string_stream& out) - : main(out) - , top(out) - { - } - + collector::collector() : main(default_), top(default_) {} + + collector::collector(string_stream& out) : main(out), top(out) {} + collector::~collector() { - BOOST_ASSERT(streams.empty()); // assert there are no more pushes than pops!!! + BOOST_ASSERT( + streams.empty()); // assert there are no more pushes than pops!!! } - - void - collector::push() + + void collector::push() { streams.push(string_stream()); top = boost::ref(streams.top()); } - - void - collector::pop() + + void collector::pop() { BOOST_ASSERT(!streams.empty()); streams.pop(); diff --git a/tools/quickbook/src/collector.hpp b/tools/quickbook/src/collector.hpp index a3b98e2702..eb2772c84b 100644 --- a/tools/quickbook/src/collector.hpp +++ b/tools/quickbook/src/collector.hpp @@ -9,13 +9,13 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_COLLECTOR_HPP) #define BOOST_SPIRIT_QUICKBOOK_COLLECTOR_HPP -#include #include -#include -#include -#include +#include #include #include +#include +#include +#include namespace quickbook { @@ -32,16 +32,10 @@ namespace quickbook stream_ptr->flush(); return *buffer_ptr.get(); } - - std::ostream& get() const - { - return *stream_ptr.get(); - } - - void clear() - { - buffer_ptr->clear(); - } + + std::ostream& get() const { return *stream_ptr.get(); } + + void clear() { buffer_ptr->clear(); } void swap(std::string& other) { @@ -55,8 +49,7 @@ namespace quickbook *buffer_ptr.get() += other; } - private: - + private: boost::shared_ptr buffer_ptr; boost::shared_ptr stream_ptr; }; @@ -66,53 +59,35 @@ namespace quickbook collector(); collector(string_stream& out); ~collector(); - + void push(); void pop(); - std::ostream& get() const - { - return top.get().get(); - } - - std::string const& str() const - { - return top.get().str(); - } - - void clear() - { - top.get().clear(); - } - - void swap(std::string& other) - { - top.get().swap(other); - } + std::ostream& get() const { return top.get().get(); } - void append(std::string const& other) - { - top.get().append(other); - } + std::string const& str() const { return top.get().str(); } - private: + void clear() { top.get().clear(); } + void swap(std::string& other) { top.get().swap(other); } + + void append(std::string const& other) { top.get().append(other); } + + private: std::stack streams; boost::reference_wrapper main; boost::reference_wrapper top; string_stream default_; }; - + template - inline collector& - operator<<(collector& out, T const& val) + inline collector& operator<<(collector& out, T const& val) { out.get() << val; return out; } - inline collector& - operator<<(collector& out, std::string const& val) + inline collector& operator<<(collector& out, std::string const& val) { out.append(val); return out; @@ -120,4 +95,3 @@ namespace quickbook } #endif // BOOST_SPIRIT_QUICKBOOK_COLLECTOR_HPP - diff --git a/tools/quickbook/src/dependency_tracker.cpp b/tools/quickbook/src/dependency_tracker.cpp index 787452ee44..6ef932cad7 100644 --- a/tools/quickbook/src/dependency_tracker.cpp +++ b/tools/quickbook/src/dependency_tracker.cpp @@ -7,29 +7,25 @@ =============================================================================*/ #include "dependency_tracker.hpp" -#include "path.hpp" -#include #include +#include #include +#include "path.hpp" namespace quickbook { static char const* control_escapes[16] = { - "\\000", "\\001", "\\002", "\\003", - "\\004", "\\005", "\\006", "\\a", - "\\b", "\\t", "\\n", "\\v", - "\\f", "\\r", "\\016", "\\017" - }; + "\\000", "\\001", "\\002", "\\003", "\\004", "\\005", "\\006", "\\a", + "\\b", "\\t", "\\n", "\\v", "\\f", "\\r", "\\016", "\\017"}; static std::string escaped_path(std::string const& generic) { std::string result; result.reserve(generic.size()); - BOOST_FOREACH(char c, generic) - { + BOOST_FOREACH (char c, generic) { if (c >= 0 && c < 16) { - result += control_escapes[(unsigned int) c]; + result += control_escapes[(unsigned int)c]; } else if (c == '\\') { result += "\\\\"; @@ -45,8 +41,8 @@ namespace quickbook return result; } - static std::string get_path(fs::path const& path, - dependency_tracker::flags f) + static std::string get_path( + fs::path const& path, dependency_tracker::flags f) { std::string generic = quickbook::detail::path_to_generic(path); @@ -57,29 +53,35 @@ namespace quickbook return generic; } - dependency_tracker::dependency_tracker() : - dependencies(), glob_dependencies(), - last_glob(glob_dependencies.end()) {} + dependency_tracker::dependency_tracker() + : dependencies() + , glob_dependencies() + , last_glob(glob_dependencies.end()) + { + } - bool dependency_tracker::add_dependency(fs::path const& f) { + bool dependency_tracker::add_dependency(fs::path const& f) + { bool found = fs::exists(fs::status(f)); dependencies[f] |= found; return found; } - void dependency_tracker::add_glob(fs::path const& f) { + void dependency_tracker::add_glob(fs::path const& f) + { std::pair r = glob_dependencies.insert( - std::make_pair(f, glob_list::mapped_type())); + std::make_pair(f, glob_list::mapped_type())); last_glob = r.first; } - void dependency_tracker::add_glob_match(fs::path const& f) { + void dependency_tracker::add_glob_match(fs::path const& f) + { assert(last_glob != glob_dependencies.end()); last_glob->second.insert(f); } - void dependency_tracker::write_dependencies(fs::path const& file_out, - flags f) + void dependency_tracker::write_dependencies( + fs::path const& file_out, flags f) { fs::ofstream out(file_out); @@ -93,23 +95,18 @@ namespace quickbook write_dependencies(out, f); } - void dependency_tracker::write_dependencies(std::ostream& out, - flags f) + void dependency_tracker::write_dependencies(std::ostream& out, flags f) { if (f & checked) { - BOOST_FOREACH(dependency_list::value_type const& d, dependencies) - { - out << (d.second ? "+ " : "- ") - << get_path(d.first, f) << std::endl; + BOOST_FOREACH (dependency_list::value_type const& d, dependencies) { + out << (d.second ? "+ " : "- ") << get_path(d.first, f) + << std::endl; } - BOOST_FOREACH(glob_list::value_type const& g, glob_dependencies) - { - out << "g " - << get_path(g.first, f) << std::endl; + BOOST_FOREACH (glob_list::value_type const& g, glob_dependencies) { + out << "g " << get_path(g.first, f) << std::endl; - BOOST_FOREACH(fs::path const& p, g.second) - { + BOOST_FOREACH (fs::path const& p, g.second) { out << "+ " << get_path(p, f) << std::endl; } } @@ -117,23 +114,19 @@ namespace quickbook else { std::set paths; - BOOST_FOREACH(dependency_list::value_type const& d, dependencies) - { + BOOST_FOREACH (dependency_list::value_type const& d, dependencies) { if (d.second) { paths.insert(get_path(d.first, f)); } } - BOOST_FOREACH(glob_list::value_type const& g, glob_dependencies) - { - BOOST_FOREACH(fs::path const& p, g.second) - { + BOOST_FOREACH (glob_list::value_type const& g, glob_dependencies) { + BOOST_FOREACH (fs::path const& p, g.second) { paths.insert(get_path(p, f)); } } - BOOST_FOREACH(std::string const& p, paths) - { + BOOST_FOREACH (std::string const& p, paths) { out << p << std::endl; } } diff --git a/tools/quickbook/src/dependency_tracker.hpp b/tools/quickbook/src/dependency_tracker.hpp index 2da44f5c03..b0a3764fa4 100644 --- a/tools/quickbook/src/dependency_tracker.hpp +++ b/tools/quickbook/src/dependency_tracker.hpp @@ -9,18 +9,18 @@ #if !defined(QUICKBOOK_DEPENDENCY_TRACKER_HPP) #define QUICKBOOK_DEPENDENCY_TRACKER_HPP +#include #include #include -#include #include namespace quickbook { namespace fs = boost::filesystem; - struct dependency_tracker { - private: - + struct dependency_tracker + { + private: typedef std::map dependency_list; typedef std::map > glob_list; @@ -28,9 +28,9 @@ namespace quickbook glob_list glob_dependencies; glob_list::iterator last_glob; - public: - - enum flags { + public: + enum flags + { default_ = 0, checked = 1, escaped = 2 diff --git a/tools/quickbook/src/doc_info_actions.cpp b/tools/quickbook/src/doc_info_actions.cpp index 320f770363..d9cbc75513 100644 --- a/tools/quickbook/src/doc_info_actions.cpp +++ b/tools/quickbook/src/doc_info_actions.cpp @@ -9,23 +9,24 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include -#include #include -#include +#include #include -#include "quickbook.hpp" -#include "utils.hpp" -#include "files.hpp" -#include "stream.hpp" -#include "state.hpp" +#include #include "doc_info_tags.hpp" #include "document_state.hpp" +#include "files.hpp" #include "path.hpp" +#include "quickbook.hpp" +#include "state.hpp" +#include "stream.hpp" +#include "utils.hpp" namespace quickbook { - static void write_document_title(collector& out, value const& title, value const& version); - + static void write_document_title( + collector& out, value const& title, value const& version); + static std::string doc_info_output(value const& p, unsigned version) { if (qbk_version_n < version) { @@ -40,8 +41,8 @@ namespace quickbook char const* doc_info_attribute_name(value::tag_type tag) { - return doc_attributes::is_tag(tag) ? doc_attributes::name(tag) : - doc_info_attributes::name(tag); + return doc_attributes::is_tag(tag) ? doc_attributes::name(tag) + : doc_info_attributes::name(tag); } // Each docinfo attribute is stored in a value list, these are then stored @@ -49,29 +50,33 @@ namespace quickbook // values for an attribute tag. // Expecting at most one attribute, with several values in the list. - value consume_list(value_consumer& c, value::tag_type tag, - std::vector* duplicates) + value consume_list( + value_consumer& c, + value::tag_type tag, + std::vector* duplicates) { value p; int count = 0; - while(c.check(tag)) { + while (c.check(tag)) { p = c.consume(); ++count; } - if(count > 1) duplicates->push_back(doc_info_attribute_name(tag)); + if (count > 1) duplicates->push_back(doc_info_attribute_name(tag)); return p; } // Expecting at most one attribute, with a single value, so extract that // immediately. - value consume_value_in_list(value_consumer& c, value::tag_type tag, - std::vector* duplicates) + value consume_value_in_list( + value_consumer& c, + value::tag_type tag, + std::vector* duplicates) { value l = consume_list(c, tag, duplicates); - if(l.empty()) return l; + if (l.empty()) return l; assert(l.is_list()); value_consumer c2 = l; @@ -82,60 +87,67 @@ namespace quickbook } // Any number of attributes, so stuff them into a vector. - std::vector consume_multiple_values(value_consumer& c, value::tag_type tag) + std::vector consume_multiple_values( + value_consumer& c, value::tag_type tag) { std::vector values; - - while(c.check(tag)) { + + while (c.check(tag)) { values.push_back(c.consume()); } - + return values; } - enum version_state { version_unknown, version_stable, version_dev }; - version_state classify_version(unsigned v) { - return v < 100u ? version_unknown : - v <= 107u ? version_stable : - //v <= 107u ? version_dev : - version_unknown; + enum version_state + { + version_unknown, + version_stable, + version_dev + }; + version_state classify_version(unsigned v) + { + return v < 100u ? version_unknown + : v <= 107u ? version_stable : + // v <= 107u ? version_dev : + version_unknown; } - unsigned get_version(quickbook::state& state, bool using_docinfo, - value version) + unsigned get_version( + quickbook::state& state, bool using_docinfo, value version) { unsigned result = 0; - + if (!version.empty()) { value_consumer version_values(version); - bool before_docinfo = version_values.optional_consume( - doc_info_tags::before_docinfo).check(); + bool before_docinfo = + version_values.optional_consume(doc_info_tags::before_docinfo) + .check(); int major_verison = version_values.consume().get_int(); int minor_verison = version_values.consume().get_int(); version_values.finish(); - + if (before_docinfo || using_docinfo) { - result = ((unsigned) major_verison * 100) + - (unsigned) minor_verison; - - if (classify_version(result) == version_unknown) - { + result = + ((unsigned)major_verison * 100) + (unsigned)minor_verison; + + if (classify_version(result) == version_unknown) { detail::outerr(state.current_file->path) - << "Unknown version: " - << major_verison - << "." - << minor_verison - << std::endl; + << "Unknown version: " << major_verison << "." + << minor_verison << std::endl; ++state.error_count; } } } - + return result; } - std::string pre(quickbook::state& state, parse_iterator pos, - value include_doc_id, bool nested_file) + std::string pre( + quickbook::state& state, + parse_iterator pos, + value include_doc_id, + bool nested_file) { // The doc_info in the file has been parsed. Here's what we'll do // *before* anything else. @@ -147,32 +159,30 @@ namespace quickbook // Skip over invalid attributes - while (values.check(value::default_tag)) values.consume(); + while (values.check(value::default_tag)) + values.consume(); bool use_doc_info = false; std::string doc_type; value doc_title; - if (values.check(doc_info_tags::type)) - { - doc_type = values.consume(doc_info_tags::type).get_quickbook().to_s(); + if (values.check(doc_info_tags::type)) { + doc_type = + values.consume(doc_info_tags::type).get_quickbook().to_s(); doc_title = values.consume(doc_info_tags::title); use_doc_info = !nested_file || qbk_version_n >= 106u; } - else - { - if (!nested_file) - { + else { + if (!nested_file) { detail::outerr(state.current_file, pos.base()) - << "No doc_info block." - << std::endl; + << "No doc_info block." << std::endl; ++state.error_count; // Create a fake document info block in order to continue. doc_type = "article"; - doc_title = qbk_value(state.current_file, - pos.base(), pos.base(), + doc_title = qbk_value( + state.current_file, pos.base(), pos.base(), doc_info_tags::type); use_doc_info = true; } @@ -180,56 +190,67 @@ namespace quickbook std::vector duplicates; - std::vector escaped_attributes = consume_multiple_values(values, doc_info_tags::escaped_attribute); + std::vector escaped_attributes = + consume_multiple_values(values, doc_info_tags::escaped_attribute); - value qbk_version = consume_list(values, doc_attributes::qbk_version, &duplicates); - value compatibility_mode = consume_list(values, doc_attributes::compatibility_mode, &duplicates); + value qbk_version = + consume_list(values, doc_attributes::qbk_version, &duplicates); + value compatibility_mode = consume_list( + values, doc_attributes::compatibility_mode, &duplicates); consume_multiple_values(values, doc_attributes::source_mode); - value id = consume_value_in_list(values, doc_info_attributes::id, &duplicates); - value dirname = consume_value_in_list(values, doc_info_attributes::dirname, &duplicates); - value last_revision = consume_value_in_list(values, doc_info_attributes::last_revision, &duplicates); - value purpose = consume_value_in_list(values, doc_info_attributes::purpose, &duplicates); - std::vector categories = consume_multiple_values(values, doc_info_attributes::category); - value lang = consume_value_in_list(values, doc_info_attributes::lang, &duplicates); - value version = consume_value_in_list(values, doc_info_attributes::version, &duplicates); - std::vector authors = consume_multiple_values(values, doc_info_attributes::authors); - std::vector copyrights = consume_multiple_values(values, doc_info_attributes::copyright); - value license = consume_value_in_list(values, doc_info_attributes::license, &duplicates); - std::vector biblioids = consume_multiple_values(values, doc_info_attributes::biblioid); - value xmlbase = consume_value_in_list(values, doc_info_attributes::xmlbase, &duplicates); + value id = + consume_value_in_list(values, doc_info_attributes::id, &duplicates); + value dirname = consume_value_in_list( + values, doc_info_attributes::dirname, &duplicates); + value last_revision = consume_value_in_list( + values, doc_info_attributes::last_revision, &duplicates); + value purpose = consume_value_in_list( + values, doc_info_attributes::purpose, &duplicates); + std::vector categories = + consume_multiple_values(values, doc_info_attributes::category); + value lang = consume_value_in_list( + values, doc_info_attributes::lang, &duplicates); + value version = consume_value_in_list( + values, doc_info_attributes::version, &duplicates); + std::vector authors = + consume_multiple_values(values, doc_info_attributes::authors); + std::vector copyrights = + consume_multiple_values(values, doc_info_attributes::copyright); + value license = consume_value_in_list( + values, doc_info_attributes::license, &duplicates); + std::vector biblioids = + consume_multiple_values(values, doc_info_attributes::biblioid); + value xmlbase = consume_value_in_list( + values, doc_info_attributes::xmlbase, &duplicates); values.finish(); - if(!duplicates.empty()) - { + if (!duplicates.empty()) { detail::outwarn(state.current_file->path) - << (duplicates.size() > 1 ? - "Duplicate attributes" : "Duplicate attribute") - << ":" << boost::algorithm::join(duplicates, ", ") - << "\n" - ; + << (duplicates.size() > 1 ? "Duplicate attributes" + : "Duplicate attribute") + << ":" << boost::algorithm::join(duplicates, ", ") << "\n"; } std::string include_doc_id_, id_; if (!include_doc_id.empty()) include_doc_id_ = include_doc_id.get_quickbook().to_s(); - if (!id.empty()) - id_ = id.get_quickbook().to_s(); + if (!id.empty()) id_ = id.get_quickbook().to_s(); // Quickbook version unsigned new_version = get_version(state, use_doc_info, qbk_version); - if (new_version != qbk_version_n) - { - if (classify_version(new_version) == version_dev) - { + if (new_version != qbk_version_n) { + if (classify_version(new_version) == version_dev) { detail::outwarn(state.current_file->path) - << "Quickbook " << (new_version / 100) << "." << (new_version % 100) + << "Quickbook " << (new_version / 100) << "." + << (new_version % 100) << " is still under development and is " - "likely to change in the future." << std::endl; + "likely to change in the future." + << std::endl; } } @@ -241,7 +262,8 @@ namespace quickbook qbk_version_n = 101; detail::outwarn(state.current_file, pos.base()) << "Quickbook version undefined. " - "Version 1.1 is assumed" << std::endl; + "Version 1.1 is assumed" + << std::endl; } state.current_file->version(qbk_version_n); @@ -252,22 +274,21 @@ namespace quickbook get_version(state, use_doc_info, compatibility_mode); if (!compatibility_version) { - compatibility_version = use_doc_info ? - qbk_version_n : state.document.compatibility_version(); + compatibility_version = + use_doc_info ? qbk_version_n + : state.document.compatibility_version(); } // Start file, finish here if not generating document info. - if (!use_doc_info) - { - state.document.start_file(compatibility_version, include_doc_id_, id_, - doc_title); + if (!use_doc_info) { + state.document.start_file( + compatibility_version, include_doc_id_, id_, doc_title); return ""; } - std::string id_placeholder = - state.document.start_file_with_docinfo( - compatibility_version, include_doc_id_, id_, doc_title); + std::string id_placeholder = state.document.start_file_with_docinfo( + compatibility_version, include_doc_id_, id_, doc_title); // Make sure we really did have a document info block. @@ -277,26 +298,20 @@ namespace quickbook std::string xmlbase_value; - if (!xmlbase.empty()) - { + if (!xmlbase.empty()) { path_parameter x = check_xinclude_path(xmlbase, state); - if (x.type == path_parameter::path) - { + if (x.type == path_parameter::path) { quickbook_path path = resolve_xinclude_path(x.value, state); - if (!fs::is_directory(path.file_path)) - { + if (!fs::is_directory(path.file_path)) { detail::outerr(xmlbase.get_file(), xmlbase.get_position()) - << "xmlbase \"" - << xmlbase.get_quickbook() - << "\" isn't a directory." - << std::endl; + << "xmlbase \"" << xmlbase.get_quickbook() + << "\" isn't a directory." << std::endl; ++state.error_count; } - else - { + else { xmlbase_value = dir_path_to_url(path.abstract_file_path); state.xinclude_base = path.file_path; } @@ -305,64 +320,50 @@ namespace quickbook // Warn about invalid fields - if (doc_type != "library") - { + if (doc_type != "library") { std::vector invalid_attributes; - if (!purpose.empty()) - invalid_attributes.push_back("purpose"); + if (!purpose.empty()) invalid_attributes.push_back("purpose"); - if (!categories.empty()) - invalid_attributes.push_back("category"); + if (!categories.empty()) invalid_attributes.push_back("category"); - if (!dirname.empty()) - invalid_attributes.push_back("dirname"); + if (!dirname.empty()) invalid_attributes.push_back("dirname"); - if(!invalid_attributes.empty()) - { + if (!invalid_attributes.empty()) { detail::outwarn(state.current_file->path) - << (invalid_attributes.size() > 1 ? - "Invalid attributes" : "Invalid attribute") + << (invalid_attributes.size() > 1 ? "Invalid attributes" + : "Invalid attribute") << " for '" << doc_type << " document info': " - << boost::algorithm::join(invalid_attributes, ", ") - << "\n" - ; + << boost::algorithm::join(invalid_attributes, ", ") << "\n"; } } // Write out header - if (!nested_file) - { + if (!nested_file) { state.out << "\n" - << "\n" - ; + << "\n"; } state.out << '<' << doc_type << "\n" - << " id=\"" - << id_placeholder - << "\"\n"; + << " id=\"" << id_placeholder << "\"\n"; - if(!lang.empty()) - { - state.out << " lang=\"" - << doc_info_output(lang, 106) - << "\"\n"; + if (!lang.empty()) { + state.out << " lang=\"" << doc_info_output(lang, 106) << "\"\n"; } - if(doc_type == "library" && !doc_title.empty()) - { - state.out << " name=\"" << doc_info_output(doc_title, 106) << "\"\n"; + if (doc_type == "library" && !doc_title.empty()) { + state.out << " name=\"" << doc_info_output(doc_title, 106) + << "\"\n"; } // Set defaults for dirname + last_revision - if (!dirname.empty() || doc_type == "library") - { + if (!dirname.empty() || doc_type == "library") { state.out << " dirname=\""; if (!dirname.empty()) { state.out << doc_info_output(dirname, 106); @@ -384,54 +385,46 @@ namespace quickbook } state.out << " last-revision=\""; - if (!last_revision.empty()) - { + if (!last_revision.empty()) { state.out << doc_info_output(last_revision, 106); } - else - { + else { // default value for last-revision is now char strdate[64]; strftime( strdate, sizeof(strdate), - (debug_mode ? - "DEBUG MODE Date: %Y/%m/%d %H:%M:%S $" : - "$" /* prevent CVS substitution */ "Date: %Y/%m/%d %H:%M:%S $"), - current_gm_time - ); + (debug_mode ? "DEBUG MODE Date: %Y/%m/%d %H:%M:%S $" + : "$" /* prevent CVS substitution */ + "Date: %Y/%m/%d %H:%M:%S $"), + current_gm_time); state.out << strdate; } state.out << "\" \n"; - if (!xmlbase.empty()) - { - state.out << " xml:base=\"" - << xmlbase_value - << "\"\n"; + if (!xmlbase.empty()) { + state.out << " xml:base=\"" << xmlbase_value << "\"\n"; } state.out << " xmlns:xi=\"http://www.w3.org/2001/XInclude\">\n"; std::ostringstream tmp; - if(!authors.empty()) - { + if (!authors.empty()) { tmp << " \n"; - BOOST_FOREACH(value_consumer author_values, authors) - { + BOOST_FOREACH (value_consumer author_values, authors) { while (author_values.check()) { - value surname = author_values.consume(doc_info_tags::author_surname); - value first = author_values.consume(doc_info_tags::author_first); - + value surname = + author_values.consume(doc_info_tags::author_surname); + value first = + author_values.consume(doc_info_tags::author_first); + tmp << " \n" - << " " - << doc_info_output(first, 106) + << " " << doc_info_output(first, 106) << "\n" - << " " - << doc_info_output(surname, 106) + << " " << doc_info_output(surname, 106) << "\n" << " \n"; } @@ -439,48 +432,44 @@ namespace quickbook tmp << " \n"; } - BOOST_FOREACH(value_consumer copyright, copyrights) - { - while(copyright.check()) - { - tmp << "\n" << " \n"; - - while(copyright.check(doc_info_tags::copyright_year)) - { + BOOST_FOREACH (value_consumer copyright, copyrights) { + while (copyright.check()) { + tmp << "\n" + << " \n"; + + while (copyright.check(doc_info_tags::copyright_year)) { value year_start_value = copyright.consume(); int year_start = year_start_value.get_int(); int year_end = - copyright.check(doc_info_tags::copyright_year_end) ? - copyright.consume().get_int() : - year_start; - + copyright.check(doc_info_tags::copyright_year_end) + ? copyright.consume().get_int() + : year_start; + if (year_end < year_start) { ++state.error_count; - - detail::outerr(state.current_file, copyright.begin()->get_position()) - << "Invalid year range: " - << year_start - << "-" - << year_end - << "." - << std::endl; + + detail::outerr( + state.current_file, + copyright.begin()->get_position()) + << "Invalid year range: " << year_start << "-" + << year_end << "." << std::endl; } - - for(; year_start <= year_end; ++year_start) + + for (; year_start <= year_end; ++year_start) tmp << " " << year_start << "\n"; } - + tmp << " " - << doc_info_output(copyright.consume(doc_info_tags::copyright_name), 106) + << doc_info_output( + copyright.consume(doc_info_tags::copyright_name), + 106) << "\n" << " \n" - << "\n" - ; + << "\n"; } } - if (!license.empty()) - { + if (!license.empty()) { tmp << " \n" @@ -488,69 +477,54 @@ namespace quickbook << " " << doc_info_output(license, 103) << "\n" << "
\n" << " \n" - << "\n" - ; + << "\n"; } - if (!purpose.empty()) - { + if (!purpose.empty()) { tmp << " <" << doc_type << "purpose>\n" - << " " << doc_info_output(purpose, 103) - << " \n" - << "\n" - ; + << " " << doc_info_output(purpose, 103) << " \n" + << "\n"; } - BOOST_FOREACH(value_consumer category_values, categories) { + BOOST_FOREACH (value_consumer category_values, categories) { value category = category_values.optional_consume(); - if(!category.empty()) { + if (!category.empty()) { tmp << " <" << doc_type << "category name=\"category:" - << doc_info_output(category, 106) - << "\">\n" - << "\n" - ; + << doc_info_output(category, 106) << "\">\n" + << "\n"; } category_values.finish(); } - BOOST_FOREACH(value_consumer biblioid, biblioids) - { + BOOST_FOREACH (value_consumer biblioid, biblioids) { value class_ = biblioid.consume(doc_info_tags::biblioid_class); value value_ = biblioid.consume(doc_info_tags::biblioid_value); - - tmp << " " - << doc_info_output(value_, 106) - << "" - << "\n" - ; + + tmp << " " + << doc_info_output(value_, 106) << "" + << "\n"; biblioid.finish(); } - BOOST_FOREACH(value escaped, escaped_attributes) - { - tmp << "" - << escaped.get_quickbook() - << "" - ; + BOOST_FOREACH (value escaped, escaped_attributes) { + tmp << "" << escaped.get_quickbook() + << ""; } - if(doc_type != "library") { + if (doc_type != "library") { write_document_title(state.out, doc_title, version); } std::string docinfo = tmp.str(); - if(!docinfo.empty()) - { + if (!docinfo.empty()) { state.out << " <" << doc_type << "info>\n" - << docinfo - << " \n" - << "\n" - ; + << docinfo << " \n" + << "\n"; } - if(doc_type == "library") { + if (doc_type == "library") { write_document_title(state.out, doc_title, version); } @@ -566,16 +540,18 @@ namespace quickbook if (!doc_type.empty() && state.document.section_level() > 1) { if (state.strict_mode) { detail::outerr(state.current_file->path) - << "Missing [endsect] detected at end of file (strict mode)." + << "Missing [endsect] detected at end of file (strict " + "mode)." << std::endl; ++state.error_count; - } else { + } + else { detail::outwarn(state.current_file->path) << "Missing [endsect] detected at end of file." << std::endl; } - while(state.document.section_level() > 1) { + while (state.document.section_level() > 1) { state.out << ""; state.document.end_section(); } @@ -585,16 +561,15 @@ namespace quickbook if (!doc_type.empty()) state.out << "\n\n\n"; } - static void write_document_title(collector& out, value const& title, value const& version) + static void write_document_title( + collector& out, value const& title, value const& version) { - if (!title.empty()) - { - out << " " - << doc_info_output(title, 106); + if (!title.empty()) { + out << " <title>" << doc_info_output(title, 106); if (!version.empty()) { out << ' ' << doc_info_output(version, 106); } - out<< "\n\n\n"; + out << "\n\n\n"; } } } diff --git a/tools/quickbook/src/doc_info_grammar.cpp b/tools/quickbook/src/doc_info_grammar.cpp index c36d2622ef..6e2c5db914 100644 --- a/tools/quickbook/src/doc_info_grammar.cpp +++ b/tools/quickbook/src/doc_info_grammar.cpp @@ -10,18 +10,18 @@ #include #include +#include #include #include -#include -#include #include -#include +#include #include -#include "grammar_impl.hpp" -#include "state.hpp" +#include #include "actions.hpp" #include "doc_info_tags.hpp" +#include "grammar_impl.hpp" #include "phrase_tags.hpp" +#include "state.hpp" namespace quickbook { @@ -31,7 +31,8 @@ namespace quickbook { attribute_info(value::tag_type t, cl::rule* r) : tag(t), rule(r) - {} + { + } value::tag_type tag; cl::rule* rule; @@ -41,77 +42,69 @@ namespace quickbook { struct assign_attribute_type { - assign_attribute_type(doc_info_grammar_local& l_) - : l(l_) - {} + assign_attribute_type(doc_info_grammar_local& l_) : l(l_) {} - void operator()(value::tag_type& t) const { + void operator()(value::tag_type& t) const + { l.attribute_rule = *l.attribute_rules[t]; l.attribute_tag = t; } - + doc_info_grammar_local& l; }; - + struct fallback_attribute_type { - fallback_attribute_type(doc_info_grammar_local& l_) - : l(l_) - {} + fallback_attribute_type(doc_info_grammar_local& l_) : l(l_) {} - void operator()(parse_iterator, parse_iterator) const { + void operator()(parse_iterator, parse_iterator) const + { l.attribute_rule = l.doc_fallback; l.attribute_tag = value::default_tag; } - + doc_info_grammar_local& l; }; - cl::rule - doc_info_block, doc_attribute, doc_info_attribute, - doc_info_escaped_attributes, - doc_title, doc_simple, doc_phrase, doc_fallback, - doc_authors, doc_author, - doc_copyright, doc_copyright_holder, - doc_source_mode, doc_biblioid, doc_compatibility_mode, - quickbook_version, macro, char_; + cl::rule doc_info_block, doc_attribute, doc_info_attribute, + doc_info_escaped_attributes, doc_title, doc_simple, doc_phrase, + doc_fallback, doc_authors, doc_author, doc_copyright, + doc_copyright_holder, doc_source_mode, doc_biblioid, + doc_compatibility_mode, quickbook_version, macro, char_; cl::uint_parser doc_copyright_year; cl::symbols<> doc_types; cl::symbols doc_info_attributes; cl::symbols doc_attributes; - std::map* > attribute_rules; + std::map*> attribute_rules; value::tag_type attribute_tag; cl::rule attribute_rule; assign_attribute_type assign_attribute; fallback_attribute_type fallback_attribute; doc_info_grammar_local() - : assign_attribute(*this) - , fallback_attribute(*this) - {} + : assign_attribute(*this), fallback_attribute(*this) + { + } bool source_mode_unset; }; void quickbook_grammar::impl::init_doc_info() { - doc_info_grammar_local& local = cleanup_.add( - new doc_info_grammar_local); + doc_info_grammar_local& local = + cleanup_.add(new doc_info_grammar_local); - typedef cl::uint_parser uint2_t; + typedef cl::uint_parser uint2_t; - local.doc_types = - "book", "article", "library", "chapter", "part" - , "appendix", "preface", "qandadiv", "qandaset" - , "reference", "set" - ; + local.doc_types = "book", "article", "library", "chapter", "part", + "appendix", "preface", "qandadiv", "qandaset", "reference", "set"; - BOOST_FOREACH(value::tag_type t, doc_attributes::tags()) { + BOOST_FOREACH (value::tag_type t, doc_attributes::tags()) { local.doc_attributes.add(doc_attributes::name(t), t); local.doc_info_attributes.add(doc_attributes::name(t), t); } - BOOST_FOREACH(value::tag_type t, doc_info_attributes::tags()) { + BOOST_FOREACH (value::tag_type t, doc_info_attributes::tags()) { local.doc_info_attributes.add(doc_info_attributes::name(t), t); } @@ -120,11 +113,14 @@ namespace quickbook plain_char_action plain_char(state); do_macro_action do_macro(state); scoped_parser to_value(state); - member_action_value change_source_mode( - state, &state::change_source_mode); - member_action_fixed_value default_source_mode( - state, &state::change_source_mode, source_mode_tags::cpp); - + member_action_value + change_source_mode(state, &state::change_source_mode); + member_action_fixed_value + default_source_mode( + state, &state::change_source_mode, source_mode_tags::cpp); + + // clang-format off + doc_info_details = cl::eps_p [ph::var(local.source_mode_unset) = true] >> *( space @@ -321,5 +317,7 @@ namespace quickbook ) >> state.macro [do_macro] ; + + // clang-format on } } diff --git a/tools/quickbook/src/doc_info_tags.hpp b/tools/quickbook/src/doc_info_tags.hpp index ccc69186cb..2f20c4a079 100644 --- a/tools/quickbook/src/doc_info_tags.hpp +++ b/tools/quickbook/src/doc_info_tags.hpp @@ -13,6 +13,8 @@ namespace quickbook { + // clang-format off + QUICKBOOK_VALUE_TAGS(doc_info_tags, 0x400, (before_docinfo) (type) @@ -44,6 +46,8 @@ namespace quickbook ((biblioid)("biblioid")) ((xmlbase)("xmlbase")) ) + + // clang-format on } #endif diff --git a/tools/quickbook/src/document_state.cpp b/tools/quickbook/src/document_state.cpp index 4f1210810b..69a9984bc9 100644 --- a/tools/quickbook/src/document_state.cpp +++ b/tools/quickbook/src/document_state.cpp @@ -6,12 +6,12 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "document_state_impl.hpp" -#include "utils.hpp" -#include +#include #include +#include #include -#include +#include "document_state_impl.hpp" +#include "utils.hpp" namespace quickbook { @@ -31,28 +31,36 @@ namespace quickbook std::string const doc_id_1_1; // Constructor for files that aren't the root of a document. - explicit file_info(boost::shared_ptr const& parent_, - unsigned compatibility_version_, - quickbook::string_view doc_id_1_1_, - id_placeholder const* override_id_) : - parent(parent_), document(parent->document), - compatibility_version(compatibility_version_), - depth(parent->depth + 1), - override_depth(override_id_ ? depth : parent->override_depth), - override_id(override_id_ ? override_id_ : parent->override_id), - doc_id_1_1(doc_id_1_1_.to_s()) - {} + explicit file_info( + boost::shared_ptr const& parent_, + unsigned compatibility_version_, + quickbook::string_view doc_id_1_1_, + id_placeholder const* override_id_) + : parent(parent_) + , document(parent->document) + , compatibility_version(compatibility_version_) + , depth(parent->depth + 1) + , override_depth(override_id_ ? depth : parent->override_depth) + , override_id(override_id_ ? override_id_ : parent->override_id) + , doc_id_1_1(doc_id_1_1_.to_s()) + { + } // Constructor for files that are the root of a document. - explicit file_info(boost::shared_ptr const& parent_, - boost::shared_ptr const& document_, - unsigned compatibility_version_, - quickbook::string_view doc_id_1_1_) : - parent(parent_), document(document_), - compatibility_version(compatibility_version_), - depth(0), override_depth(0), override_id(0), - doc_id_1_1(doc_id_1_1_.to_s()) - {} + explicit file_info( + boost::shared_ptr const& parent_, + boost::shared_ptr const& document_, + unsigned compatibility_version_, + quickbook::string_view doc_id_1_1_) + : parent(parent_) + , document(document_) + , compatibility_version(compatibility_version_) + , depth(0) + , override_depth(0) + , override_id(0) + , doc_id_1_1(doc_id_1_1_.to_s()) + { + } }; struct doc_info @@ -78,69 +86,68 @@ namespace quickbook id_placeholder const* const placeholder_1_6; source_mode_info const source_mode; - explicit section_info(boost::shared_ptr const& parent_, - file_info const* current_file_, - value const& explicit_id_, - quickbook::string_view id_1_1_, - id_placeholder const* placeholder_1_6_, - source_mode_info const& source_mode_) : - parent(parent_), - compatibility_version(current_file_->compatibility_version), - file_depth(current_file_->depth), - level(parent ? parent->level + 1 : 1), - explicit_id(explicit_id_), - id_1_1(id_1_1_.to_s()), - placeholder_1_6(placeholder_1_6_), - source_mode(source_mode_) {} + explicit section_info( + boost::shared_ptr const& parent_, + file_info const* current_file_, + value const& explicit_id_, + quickbook::string_view id_1_1_, + id_placeholder const* placeholder_1_6_, + source_mode_info const& source_mode_) + : parent(parent_) + , compatibility_version(current_file_->compatibility_version) + , file_depth(current_file_->depth) + , level(parent ? parent->level + 1 : 1) + , explicit_id(explicit_id_) + , id_1_1(id_1_1_.to_s()) + , placeholder_1_6(placeholder_1_6_) + , source_mode(source_mode_) + { + } }; // // document_state // - document_state::document_state() - : state(new document_state_impl) - { - } + document_state::document_state() : state(new document_state_impl) {} document_state::~document_state() {} void document_state::start_file( - unsigned compatibility_version_, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title_) + unsigned compatibility_version_, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title_) { - state->start_file(compatibility_version_, false, include_doc_id, id, title_); + state->start_file( + compatibility_version_, false, include_doc_id, id, title_); } std::string document_state::start_file_with_docinfo( - unsigned compatibility_version_, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title_) + unsigned compatibility_version_, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title_) { - return state->start_file(compatibility_version_, true, include_doc_id, - id, title_)->to_string(); + return state + ->start_file( + compatibility_version_, true, include_doc_id, id, title_) + ->to_string(); } - void document_state::end_file() - { - state->end_file(); - } + void document_state::end_file() { state->end_file(); } std::string document_state::begin_section( - value const& explicit_id_, quickbook::string_view id, - id_category category, source_mode_info const& source_mode) + value const& explicit_id_, + quickbook::string_view id, + id_category category, + source_mode_info const& source_mode) { return state->begin_section(explicit_id_, id, category, source_mode) ->to_string(); } - void document_state::end_section() - { - return state->end_section(); - } + void document_state::end_section() { return state->end_section(); } int document_state::section_level() const { @@ -154,33 +161,37 @@ namespace quickbook source_mode_info document_state::section_source_mode() const { - return state->current_file ? - state->current_file->document->current_section->source_mode : - source_mode_info(); + return state->current_file + ? state->current_file->document->current_section->source_mode + : source_mode_info(); } - std::string document_state::old_style_id(quickbook::string_view id, id_category category) + std::string document_state::old_style_id( + quickbook::string_view id, id_category category) { return state->old_style_id(id, category)->to_string(); } - std::string document_state::add_id(quickbook::string_view id, id_category category) + std::string document_state::add_id( + quickbook::string_view id, id_category category) { return state->add_id(id, category)->to_string(); } - std::string document_state::add_anchor(quickbook::string_view id, id_category category) + std::string document_state::add_anchor( + quickbook::string_view id, id_category category) { return state->add_placeholder(id, category)->to_string(); } std::string document_state::replace_placeholders_with_unresolved_ids( - quickbook::string_view xml) const + quickbook::string_view xml) const { return replace_ids(*state, xml); } - std::string document_state::replace_placeholders(quickbook::string_view xml) const + std::string document_state::replace_placeholders( + quickbook::string_view xml) const { assert(!state->current_file); std::vector ids = generate_ids(*state, xml); @@ -197,17 +208,18 @@ namespace quickbook // id_placeholder::id_placeholder( - std::size_t index_, - quickbook::string_view id_, - id_category category_, - id_placeholder const* parent_) - : index(index_), - id(id_.begin(), id_.end()), - unresolved_id(parent_ ? parent_->unresolved_id + '.' + id : id), - parent(parent_), - category(category_), - num_dots(boost::range::count(id, '.') + - (parent_ ? parent_->num_dots + 1 : 0)) + std::size_t index_, + quickbook::string_view id_, + id_category category_, + id_placeholder const* parent_) + : index(index_) + , id(id_.begin(), id_.end()) + , unresolved_id(parent_ ? parent_->unresolved_id + '.' + id : id) + , parent(parent_) + , category(category_) + , num_dots( + boost::range::count(id, '.') + + (parent_ ? parent_->num_dots + 1 : 0)) { } @@ -221,40 +233,42 @@ namespace quickbook // id_placeholder const* document_state_impl::add_placeholder( - quickbook::string_view id, id_category category, - id_placeholder const* parent) + quickbook::string_view id, + id_category category, + id_placeholder const* parent) { - placeholders.push_back(id_placeholder( - placeholders.size(), id, category, parent)); + placeholders.push_back( + id_placeholder(placeholders.size(), id, category, parent)); return &placeholders.back(); } - id_placeholder const* document_state_impl::get_placeholder(quickbook::string_view value) const + id_placeholder const* document_state_impl::get_placeholder( + quickbook::string_view value) const { // If this isn't a placeholder id. - if (value.size() <= 1 || *value.begin() != '$') - return 0; + if (value.size() <= 1 || *value.begin() != '$') return 0; - unsigned index = boost::lexical_cast(std::string( - value.begin() + 1, value.end())); + unsigned index = boost::lexical_cast( + std::string(value.begin() + 1, value.end())); return &placeholders.at(index); } id_placeholder const* document_state_impl::get_id_placeholder( - boost::shared_ptr const& section) const + boost::shared_ptr const& section) const { - return !section ? 0 : - section->file_depth < current_file->override_depth ? - current_file->override_id : section->placeholder_1_6; + return !section ? 0 + : section->file_depth < current_file->override_depth + ? current_file->override_id + : section->placeholder_1_6; } id_placeholder const* document_state_impl::start_file( - unsigned compatibility_version, - bool document_root, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title) + unsigned compatibility_version, + bool document_root, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title) { boost::shared_ptr parent = current_file; assert(parent || document_root); @@ -268,10 +282,8 @@ namespace quickbook quickbook::string_view initial_doc_id; - if (document_root || - compatibility_version >= 106u || - parent->compatibility_version >= 106u) - { + if (document_root || compatibility_version >= 106u || + parent->compatibility_version >= 106u) { initial_doc_id = !include_doc_id.empty() ? include_doc_id : id; } else { @@ -288,8 +300,10 @@ namespace quickbook if (title.check()) document->last_title_1_1 = title.get_quickbook().to_s(); - doc_id_1_1 = !initial_doc_id.empty() ? initial_doc_id.to_s() : - detail::make_identifier(document->last_title_1_1); + doc_id_1_1 = + !initial_doc_id.empty() + ? initial_doc_id.to_s() + : detail::make_identifier(document->last_title_1_1); } else if (parent) { doc_id_1_1 = parent->doc_id_1_1; @@ -298,29 +312,33 @@ namespace quickbook if (document_root) { // Create new file - current_file = boost::make_shared(parent, - document, compatibility_version, doc_id_1_1); + current_file = boost::make_shared( + parent, document, compatibility_version, doc_id_1_1); // Create a section for the new document. source_mode_info default_source_mode; if (!initial_doc_id.empty()) { - return create_new_section(empty_value(), id, - id_category::explicit_section_id, default_source_mode); + return create_new_section( + empty_value(), id, id_category::explicit_section_id, + default_source_mode); } else if (!title.empty()) { - return create_new_section(empty_value(), + return create_new_section( + empty_value(), detail::make_identifier(title.get_quickbook()), id_category::generated_doc, default_source_mode); } else if (compatibility_version >= 106u) { - return create_new_section(empty_value(), "doc", - id_category::numbered, default_source_mode); + return create_new_section( + empty_value(), "doc", id_category::numbered, + default_source_mode); } else { - return create_new_section(empty_value(), "", - id_category::generated_doc, default_source_mode); + return create_new_section( + empty_value(), "", id_category::generated_doc, + default_source_mode); } } else { @@ -335,19 +353,18 @@ namespace quickbook id_placeholder const* override_id = 0; - if (!initial_doc_id.empty() && compatibility_version >= 106u) - { + if (!initial_doc_id.empty() && compatibility_version >= 106u) { boost::shared_ptr null_section; - override_id = add_id_to_section(initial_doc_id, - id_category::explicit_section_id, null_section); + override_id = add_id_to_section( + initial_doc_id, id_category::explicit_section_id, + null_section); } // Create new file - current_file = - boost::make_shared(parent, compatibility_version, - doc_id_1_1, override_id); + current_file = boost::make_shared( + parent, compatibility_version, doc_id_1_1, override_id); return 0; } @@ -359,17 +376,16 @@ namespace quickbook } id_placeholder const* document_state_impl::add_id( - quickbook::string_view id, - id_category category) + quickbook::string_view id, id_category category) { - return add_id_to_section(id, category, - current_file->document->current_section); + return add_id_to_section( + id, category, current_file->document->current_section); } id_placeholder const* document_state_impl::add_id_to_section( - quickbook::string_view id, - id_category category, - boost::shared_ptr const& section) + quickbook::string_view id, + id_category category, + boost::shared_ptr const& section) { std::string id_part(id.begin(), id.end()); @@ -377,21 +393,20 @@ namespace quickbook // adding to section according to section compatibility version. if (current_file->compatibility_version >= 106u && - category.c < id_category::explicit_id) { + category.c < id_category::explicit_id) { id_part = normalize_id(id); } id_placeholder const* placeholder_1_6 = get_id_placeholder(section); - if(!section || section->compatibility_version >= 106u) { + if (!section || section->compatibility_version >= 106u) { return add_placeholder(id_part, category, placeholder_1_6); } else { std::string const& qualified_id = section->id_1_1; std::string new_id; - if (!placeholder_1_6) - new_id = current_file->doc_id_1_1; + if (!placeholder_1_6) new_id = current_file->doc_id_1_1; if (!new_id.empty() && !qualified_id.empty()) new_id += '.'; new_id += qualified_id; if (!new_id.empty() && !id_part.empty()) new_id += '.'; @@ -402,30 +417,31 @@ namespace quickbook } id_placeholder const* document_state_impl::old_style_id( - quickbook::string_view id, - id_category category) + quickbook::string_view id, id_category category) { - return current_file->compatibility_version < 103u ? - add_placeholder( - current_file->document->section_id_1_1 + "." + id.to_s(), category) : - add_id(id, category); + return current_file->compatibility_version < 103u + ? add_placeholder( + current_file->document->section_id_1_1 + "." + + id.to_s(), + category) + : add_id(id, category); } id_placeholder const* document_state_impl::begin_section( - value const& explicit_id, - quickbook::string_view id, - id_category category, - source_mode_info const& source_mode) + value const& explicit_id, + quickbook::string_view id, + id_category category, + source_mode_info const& source_mode) { current_file->document->section_id_1_1 = id.to_s(); return create_new_section(explicit_id, id, category, source_mode); } id_placeholder const* document_state_impl::create_new_section( - value const& explicit_id, - quickbook::string_view id, - id_category category, - source_mode_info const& source_mode) + value const& explicit_id, + quickbook::string_view id, + id_category category, + source_mode_info const& source_mode) { boost::shared_ptr parent = current_file->document->current_section; @@ -437,8 +453,7 @@ namespace quickbook if (parent && current_file->compatibility_version < 106u) { id_1_1 = parent->id_1_1; - if (!id_1_1.empty() && !id.empty()) - id_1_1 += "."; + if (!id_1_1.empty() && !id.empty()) id_1_1 += "."; id_1_1.append(id.begin(), id.end()); } @@ -470,9 +485,9 @@ namespace quickbook } current_file->document->current_section = - boost::make_shared(parent, - current_file.get(), explicit_id, id_1_1, placeholder_1_6, - source_mode); + boost::make_shared( + parent, current_file.get(), explicit_id, id_1_1, + placeholder_1_6, source_mode); return p; } diff --git a/tools/quickbook/src/document_state.hpp b/tools/quickbook/src/document_state.hpp index 6623d6e01b..a2e056a535 100644 --- a/tools/quickbook/src/document_state.hpp +++ b/tools/quickbook/src/document_state.hpp @@ -9,11 +9,11 @@ #if !defined(BOOST_QUICKBOOK_DOCUMENT_STATE_HPP) #define BOOST_QUICKBOOK_DOCUMENT_STATE_HPP +#include #include #include "string_view.hpp" -#include -#include "values.hpp" #include "syntax_highlight.hpp" +#include "values.hpp" namespace quickbook { @@ -26,12 +26,12 @@ namespace quickbook enum categories { default_category = 0, - numbered, // Just used to avoid random docbook ids - generated, // Generated ids for other elements. - generated_heading, // Generated ids for headings. - generated_section, // Generated ids for sections. - generated_doc, // Generated ids for document. - explicit_id, // Explicitly given by user + numbered, // Just used to avoid random docbook ids + generated, // Generated ids for other elements. + generated_heading, // Generated ids for headings. + generated_section, // Generated ids for sections. + generated_doc, // Generated ids for document. + explicit_id, // Explicitly given by user explicit_section_id, explicit_anchor_id }; @@ -53,21 +53,24 @@ namespace quickbook ~document_state(); std::string start_file_with_docinfo( - unsigned compatibility_version, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title); + unsigned compatibility_version, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title); void start_file( - unsigned compatibility_version, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title); + unsigned compatibility_version, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title); void end_file(); - std::string begin_section(value const&, - quickbook::string_view, id_category, source_mode_info const&); + std::string begin_section( + value const&, + quickbook::string_view, + id_category, + source_mode_info const&); void end_section(); int section_level() const; value const& explicit_id() const; @@ -78,11 +81,12 @@ namespace quickbook std::string add_anchor(quickbook::string_view, id_category); std::string replace_placeholders_with_unresolved_ids( - quickbook::string_view) const; + quickbook::string_view) const; std::string replace_placeholders(quickbook::string_view) const; unsigned compatibility_version() const; - private: + + private: boost::scoped_ptr state; }; } diff --git a/tools/quickbook/src/document_state_impl.hpp b/tools/quickbook/src/document_state_impl.hpp index 8b428e2cb5..e9107d68e0 100644 --- a/tools/quickbook/src/document_state_impl.hpp +++ b/tools/quickbook/src/document_state_impl.hpp @@ -9,14 +9,14 @@ #if !defined(BOOST_QUICKBOOK_DOCUMENT_STATE_IMPL_HPP) #define BOOST_QUICKBOOK_DOCUMENT_STATE_IMPL_HPP -#include "document_state.hpp" -#include "phrase_tags.hpp" -#include "utils.hpp" -#include "string_view.hpp" -#include #include #include #include +#include +#include "document_state.hpp" +#include "phrase_tags.hpp" +#include "string_view.hpp" +#include "utils.hpp" namespace quickbook { @@ -30,24 +30,27 @@ namespace quickbook struct id_placeholder { - std::size_t index; // The index in document_state_impl::placeholders. - // Use for the dollar identifiers in - // intermediate xml. - std::string id; // The node id. + std::size_t index; // The index in document_state_impl::placeholders. + // Use for the dollar identifiers in + // intermediate xml. + std::string id; // The node id. std::string unresolved_id; - // The id that would be generated - // without any duplicate handling. - // Used for generating old style header anchors. + // The id that would be generated + // without any duplicate handling. + // Used for generating old style header anchors. id_placeholder const* parent; - // Placeholder of the parent id. + // Placeholder of the parent id. id_category category; std::ptrdiff_t num_dots; // Number of dots in the id. - // Normally equal to the section level - // but not when an explicit id contains - // dots. + // Normally equal to the section level + // but not when an explicit id contains + // dots. - id_placeholder(std::size_t index, quickbook::string_view id, - id_category category, id_placeholder const* parent_); + id_placeholder( + std::size_t index, + quickbook::string_view id, + id_category category, + id_placeholder const* parent_); std::string to_string() const; }; @@ -69,53 +72,56 @@ namespace quickbook // Placeholder methods - id_placeholder const* add_placeholder(quickbook::string_view, id_category, + id_placeholder const* add_placeholder( + quickbook::string_view, + id_category, id_placeholder const* parent = 0); id_placeholder const* get_placeholder(quickbook::string_view) const; id_placeholder const* get_id_placeholder( - boost::shared_ptr const& section) const; + boost::shared_ptr const& section) const; // Events id_placeholder const* start_file( - unsigned compatibility_version, - bool document_root, - quickbook::string_view include_doc_id, - quickbook::string_view id, - value const& title); + unsigned compatibility_version, + bool document_root, + quickbook::string_view include_doc_id, + quickbook::string_view id, + value const& title); void end_file(); id_placeholder const* add_id( - quickbook::string_view id, - id_category category); + quickbook::string_view id, id_category category); id_placeholder const* old_style_id( - quickbook::string_view id, - id_category category); + quickbook::string_view id, id_category category); id_placeholder const* begin_section( - value const& explicit_id, - quickbook::string_view id, - id_category category, - source_mode_info const&); + value const& explicit_id, + quickbook::string_view id, + id_category category, + source_mode_info const&); void end_section(); - private: + private: id_placeholder const* add_id_to_section( - quickbook::string_view id, - id_category category, - boost::shared_ptr const& section); + quickbook::string_view id, + id_category category, + boost::shared_ptr const& section); id_placeholder const* create_new_section( - value const& explicit_id, - quickbook::string_view id, - id_category category, - source_mode_info const&); + value const& explicit_id, + quickbook::string_view id, + id_category category, + source_mode_info const&); }; - std::string replace_ids(document_state_impl const& state, quickbook::string_view xml, - std::vector const* = 0); - std::vector generate_ids(document_state_impl const&, quickbook::string_view); + std::string replace_ids( + document_state_impl const& state, + quickbook::string_view xml, + std::vector const* = 0); + std::vector generate_ids( + document_state_impl const&, quickbook::string_view); std::string normalize_id(quickbook::string_view src_id); std::string normalize_id(quickbook::string_view src_id, std::size_t); @@ -135,7 +141,8 @@ namespace quickbook std::vector id_attributes; - struct callback { + struct callback + { virtual void start(quickbook::string_view) {} virtual void id_value(quickbook::string_view) {} virtual void finish(quickbook::string_view) {} diff --git a/tools/quickbook/src/files.cpp b/tools/quickbook/src/files.cpp index 0ee2811351..05de07737d 100644 --- a/tools/quickbook/src/files.cpp +++ b/tools/quickbook/src/files.cpp @@ -8,14 +8,14 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "files.hpp" -#include -#include -#include -#include -#include #include #include #include +#include +#include +#include +#include +#include namespace quickbook { @@ -30,43 +30,49 @@ namespace quickbook // probably broken. template - bool check_bom(InputIterator& begin, InputIterator end, - OutputIterator out, char const* chars, int length) + bool check_bom( + InputIterator& begin, + InputIterator end, + OutputIterator out, + char const* chars, + int length) { char const* ptr = chars; - while(begin != end && *begin == *ptr) { + while (begin != end && *begin == *ptr) { ++begin; ++ptr; --length; - if(length == 0) return true; + if (length == 0) return true; } // Failed to match, so write the skipped characters to storage: - while(chars != ptr) *out++ = *chars++; + while (chars != ptr) + *out++ = *chars++; return false; } template - std::string read_bom(InputIterator& begin, InputIterator end, - OutputIterator out) + std::string read_bom( + InputIterator& begin, InputIterator end, OutputIterator out) { - if(begin == end) return ""; + if (begin == end) return ""; - const char* utf8 = "\xef\xbb\xbf" ; + const char* utf8 = "\xef\xbb\xbf"; const char* utf32be = "\0\0\xfe\xff"; const char* utf32le = "\xff\xfe\0\0"; unsigned char c = *begin; - switch(c) - { + switch (c) { case 0xEF: { // UTF-8 return check_bom(begin, end, out, utf8, 3) ? "UTF-8" : ""; } case 0xFF: // UTF-16/UTF-32 little endian - return !check_bom(begin, end, out, utf32le, 2) ? "" : - check_bom(begin, end, out, utf32le + 2, 2) ? "UTF-32" : "UTF-16"; + return !check_bom(begin, end, out, utf32le, 2) + ? "" + : check_bom(begin, end, out, utf32le + 2, 2) ? "UTF-32" + : "UTF-16"; case 0: // UTF-32 big endian return check_bom(begin, end, out, utf32be, 4) ? "UTF-32" : ""; case 0xFE: // UTF-16 big endian @@ -80,20 +86,18 @@ namespace quickbook // newlines. template - void normalize(InputIterator begin, InputIterator end, - OutputIterator out) + void normalize(InputIterator begin, InputIterator end, OutputIterator out) { std::string encoding = read_bom(begin, end, out); - if(encoding != "UTF-8" && encoding != "") - throw load_error(encoding + - " is not supported. Please use UTF-8."); + if (encoding != "UTF-8" && encoding != "") + throw load_error(encoding + " is not supported. Please use UTF-8."); - while(begin != end) { - if(*begin == '\r') { + while (begin != end) { + if (*begin == '\r') { *out++ = '\n'; ++begin; - if(begin != end && *begin == '\n') ++begin; + if (begin != end && *begin == '\n') ++begin; } else { *out++ = *begin++; @@ -103,27 +107,23 @@ namespace quickbook file_ptr load(fs::path const& filename, unsigned qbk_version) { - boost::unordered_map::iterator pos - = files.find(filename); + boost::unordered_map::iterator pos = + files.find(filename); - if (pos == files.end()) - { + if (pos == files.end()) { fs::ifstream in(filename, std::ios_base::in); - if (!in) - throw load_error("Could not open input file."); + if (!in) throw load_error("Could not open input file."); // Turn off white space skipping on the stream in.unsetf(std::ios::skipws); std::string source; normalize( - std::istream_iterator(in), - std::istream_iterator(), + std::istream_iterator(in), std::istream_iterator(), std::back_inserter(source)); - if (in.bad()) - throw load_error("Error reading input file."); + if (in.bad()) throw load_error("Error reading input file."); bool inserted; @@ -142,34 +142,28 @@ namespace quickbook } file_position relative_position( - string_iterator begin, - string_iterator iterator) + string_iterator begin, string_iterator iterator) { file_position pos; string_iterator line_begin = begin; - while (begin != iterator) - { - if (*begin == '\r') - { + while (begin != iterator) { + if (*begin == '\r') { ++begin; ++pos.line; line_begin = begin; } - else if (*begin == '\n') - { + else if (*begin == '\n') { ++begin; ++pos.line; line_begin = begin; if (begin == iterator) break; - if (*begin == '\r') - { + if (*begin == '\r') { ++begin; line_begin = begin; } } - else - { + else { ++begin; } } @@ -187,40 +181,44 @@ namespace quickbook struct mapped_file_section { - enum section_types { + enum section_types + { normal, empty, indented }; - + std::string::size_type original_pos; std::string::size_type our_pos; section_types section_type; explicit mapped_file_section( - std::string::size_type original_pos_, - std::string::size_type our_pos_, - section_types section_type_ = normal) : - original_pos(original_pos_), our_pos(our_pos_), - section_type(section_type_) {} + std::string::size_type original_pos_, + std::string::size_type our_pos_, + section_types section_type_ = normal) + : original_pos(original_pos_) + , our_pos(our_pos_) + , section_type(section_type_) + { + } }; struct mapped_section_original_cmp { - bool operator()(mapped_file_section const& x, - mapped_file_section const& y) + bool operator()( + mapped_file_section const& x, mapped_file_section const& y) { return x.original_pos < y.original_pos; } - bool operator()(mapped_file_section const& x, - std::string::size_type const& y) + bool operator()( + mapped_file_section const& x, std::string::size_type const& y) { return x.original_pos < y; } - bool operator()(std::string::size_type const& x, - mapped_file_section const& y) + bool operator()( + std::string::size_type const& x, mapped_file_section const& y) { return x < y.original_pos; } @@ -228,51 +226,53 @@ namespace quickbook struct mapped_section_pos_cmp { - bool operator()(mapped_file_section const& x, - mapped_file_section const& y) + bool operator()( + mapped_file_section const& x, mapped_file_section const& y) { return x.our_pos < y.our_pos; } - bool operator()(mapped_file_section const& x, - std::string::size_type const& y) + bool operator()( + mapped_file_section const& x, std::string::size_type const& y) { return x.our_pos < y; } - bool operator()(std::string::size_type const& x, - mapped_file_section const& y) + bool operator()( + std::string::size_type const& x, mapped_file_section const& y) { return x < y.our_pos; } }; - + struct mapped_file : file { - explicit mapped_file(file_ptr original_) : - file(*original_, std::string()), - original(original_), mapped_sections() - {} + explicit mapped_file(file_ptr original_) + : file(*original_, std::string()) + , original(original_) + , mapped_sections() + { + } file_ptr original; std::vector mapped_sections; - - void add_empty_mapped_file_section(string_iterator pos) { + + void add_empty_mapped_file_section(string_iterator pos) + { std::string::size_type original_pos = pos - original->source().begin(); - + if (mapped_sections.empty() || - mapped_sections.back().section_type != - mapped_file_section::empty || - mapped_sections.back().original_pos != original_pos) - { + mapped_sections.back().section_type != + mapped_file_section::empty || + mapped_sections.back().original_pos != original_pos) { mapped_sections.push_back(mapped_file_section( - original_pos, source().size(), - mapped_file_section::empty)); + original_pos, source().size(), mapped_file_section::empty)); } } - void add_mapped_file_section(string_iterator pos) { + void add_mapped_file_section(string_iterator pos) + { mapped_sections.push_back(mapped_file_section( pos - original->source().begin(), source().size())); } @@ -289,68 +289,67 @@ namespace quickbook std::string::size_type pos) const { switch (section->section_type) { - case mapped_file_section::normal: - return pos - section->our_pos + section->original_pos; - - case mapped_file_section::empty: - return section->original_pos; - - case mapped_file_section::indented: { - // Will contain the start of the current line. - quickbook::string_view::size_type our_line = section->our_pos; - - // Will contain the number of lines in the block before - // the current line. - unsigned newline_count = 0; - - for(quickbook::string_view::size_type i = section->our_pos; - i != pos; ++i) - { - if (source()[i] == '\n') { - our_line = i + 1; - ++newline_count; - } - } + case mapped_file_section::normal: + return pos - section->our_pos + section->original_pos; - // The start of the line in the original source. - quickbook::string_view::size_type original_line = - section->original_pos; - - while(newline_count > 0) { - if (original->source()[original_line] == '\n') - --newline_count; - ++original_line; - } + case mapped_file_section::empty: + return section->original_pos; - // The start of line content (i.e. after indentation). - our_line = skip_indentation(source(), our_line); + case mapped_file_section::indented: { + // Will contain the start of the current line. + quickbook::string_view::size_type our_line = section->our_pos; - // The position is in the middle of indentation, so - // just return the start of the whitespace, which should - // be good enough. - if (our_line > pos) return original_line; + // Will contain the number of lines in the block before + // the current line. + unsigned newline_count = 0; - original_line = - skip_indentation(original->source(), original_line); + for (quickbook::string_view::size_type i = section->our_pos; + i != pos; ++i) { + if (source()[i] == '\n') { + our_line = i + 1; + ++newline_count; + } + } - // Confirm that we are actually in the same position. - assert(original->source()[original_line] == - source()[our_line]); + // The start of the line in the original source. + quickbook::string_view::size_type original_line = + section->original_pos; - // Calculate the position - return original_line + (pos - our_line); + while (newline_count > 0) { + if (original->source()[original_line] == '\n') + --newline_count; + ++original_line; } - default: - assert(false); - return section->original_pos; + + // The start of line content (i.e. after indentation). + our_line = skip_indentation(source(), our_line); + + // The position is in the middle of indentation, so + // just return the start of the whitespace, which should + // be good enough. + if (our_line > pos) return original_line; + + original_line = + skip_indentation(original->source(), original_line); + + // Confirm that we are actually in the same position. + assert(original->source()[original_line] == source()[our_line]); + + // Calculate the position + return original_line + (pos - our_line); + } + default: + assert(false); + return section->original_pos; } } - + std::vector::const_iterator find_section( string_iterator pos) const { std::vector::const_iterator section = - boost::upper_bound(mapped_sections, + boost::upper_bound( + mapped_sections, std::string::size_type(pos - source().begin()), mapped_section_pos_cmp()); assert(section != mapped_sections.begin()); @@ -361,18 +360,18 @@ namespace quickbook virtual file_position position_of(string_iterator) const; - private: - + private: static std::string::size_type skip_indentation( - quickbook::string_view src, std::string::size_type i) + quickbook::string_view src, std::string::size_type i) { - while (i != src.size() && (src[i] == ' ' || src[i] == '\t')) ++i; + while (i != src.size() && (src[i] == ' ' || src[i] == '\t')) + ++i; return i; } - }; - namespace { + namespace + { std::list mapped_files; } @@ -380,7 +379,7 @@ namespace quickbook { mapped_file_builder_data() { reset(); } void reset() { new_file.reset(); } - + boost::intrusive_ptr new_file; }; @@ -404,11 +403,8 @@ namespace quickbook return r; } - void mapped_file_builder::clear() - { - data->reset(); - } - + void mapped_file_builder::clear() { data->reset(); } + bool mapped_file_builder::empty() const { return data->new_file->source().empty(); @@ -418,7 +414,7 @@ namespace quickbook { return data->new_file->source().size(); } - + void mapped_file_builder::add_at_pos(quickbook::string_view x, iterator pos) { data->new_file->add_empty_mapped_file_section(pos); @@ -436,48 +432,46 @@ namespace quickbook add(x, 0, x.data->new_file->source_.size()); } - void mapped_file_builder::add(mapped_file_builder const& x, - pos_type begin, pos_type end) + void mapped_file_builder::add( + mapped_file_builder const& x, pos_type begin, pos_type end) { assert(data->new_file->original == x.data->new_file->original); assert(begin <= x.data->new_file->source_.size()); assert(end <= x.data->new_file->source_.size()); - if (begin != end) - { + if (begin != end) { std::vector::const_iterator i = x.data->new_file->find_section( x.data->new_file->source().begin() + begin); - + std::string::size_type size = data->new_file->source_.size(); - + data->new_file->mapped_sections.push_back(mapped_file_section( - x.data->new_file->to_original_pos(i, begin), - size, i->section_type)); - + x.data->new_file->to_original_pos(i, begin), size, + i->section_type)); + for (++i; i != x.data->new_file->mapped_sections.end() && - i->our_pos < end; ++i) - { + i->our_pos < end; + ++i) { data->new_file->mapped_sections.push_back(mapped_file_section( i->original_pos, i->our_pos - begin + size, i->section_type)); } - + data->new_file->source_.append( x.data->new_file->source_.begin() + begin, - x.data->new_file->source_.begin() + end); + x.data->new_file->source_.begin() + end); } } - quickbook::string_view::size_type indentation_count(quickbook::string_view x) + quickbook::string_view::size_type indentation_count( + quickbook::string_view x) { unsigned count = 0; - for(string_iterator begin = x.begin(), end = x.end(); - begin != end; ++begin) - { - switch(*begin) - { + for (string_iterator begin = x.begin(), end = x.end(); begin != end; + ++begin) { + switch (*begin) { case ' ': ++count; break; @@ -500,7 +494,8 @@ namespace quickbook std::string const program(x.begin(), x.end()); // Erase leading blank lines and newlines: - std::string::size_type text_start = program.find_first_not_of(" \t\r\n"); + std::string::size_type text_start = + program.find_first_not_of(" \t\r\n"); if (text_start == std::string::npos) return; text_start = program.find_last_of("\r\n", text_start); @@ -509,7 +504,8 @@ namespace quickbook assert(text_start < program.size()); // Get the first line indentation - std::string::size_type indent = program.find_first_not_of(" \t", text_start) - text_start; + std::string::size_type indent = + program.find_first_not_of(" \t", text_start) - text_start; quickbook::string_view::size_type full_indent = indentation_count( quickbook::string_view(&program[text_start], indent)); @@ -517,8 +513,8 @@ namespace quickbook // Calculate the minimum indent from the rest of the lines // Detecting a mix of spaces and tabs. - while (std::string::npos != (pos = program.find_first_of("\r\n", pos))) - { + while (std::string::npos != + (pos = program.find_first_of("\r\n", pos))) { pos = program.find_first_not_of("\r\n", pos); if (std::string::npos == pos) break; @@ -528,9 +524,10 @@ namespace quickbook char ch = program[n]; if (ch == '\r' || ch == '\n') continue; // ignore empty lines - indent = (std::min)(indent, n-pos); - full_indent = (std::min)(full_indent, indentation_count( - quickbook::string_view(&program[pos], n-pos))); + indent = (std::min)(indent, n - pos); + full_indent = (std::min)( + full_indent, indentation_count(quickbook::string_view( + &program[pos], n - pos))); } // Detect if indentation is mixed. @@ -538,13 +535,13 @@ namespace quickbook quickbook::string_view first_indent(&program[text_start], indent); pos = text_start; - while (std::string::npos != (pos = program.find_first_of("\r\n", pos))) - { + while (std::string::npos != + (pos = program.find_first_of("\r\n", pos))) { pos = program.find_first_not_of("\r\n", pos); if (std::string::npos == pos) break; std::string::size_type n = program.find_first_not_of(" \t", pos); - if (n == std::string::npos || n-pos < indent) continue; + if (n == std::string::npos || n - pos < indent) continue; if (quickbook::string_view(&program[pos], indent) != first_indent) { mixed_indentation = true; @@ -558,20 +555,21 @@ namespace quickbook pos = text_start; do { - if (std::string::npos == (pos = program.find_first_not_of("\r\n", pos))) + if (std::string::npos == + (pos = program.find_first_not_of("\r\n", pos))) break; - unindented_program.append(program.begin() + copy_start, program.begin() + pos); + unindented_program.append( + program.begin() + copy_start, program.begin() + pos); copy_start = pos; // Find the end of the indentation. std::string::size_type next = program.find_first_not_of(" \t", pos); if (next == std::string::npos) next = program.size(); - if (mixed_indentation) - { - string_view::size_type length = indentation_count(quickbook::string_view( - &program[pos], next - pos)); + if (mixed_indentation) { + string_view::size_type length = indentation_count( + quickbook::string_view(&program[pos], next - pos)); if (length > full_indent) { std::string new_indentation(length - full_indent, ' '); @@ -580,14 +578,13 @@ namespace quickbook copy_start = next; } - else - { + else { copy_start = (std::min)(pos + indent, next); } pos = next; } while (std::string::npos != - (pos = program.find_first_of("\r\n", pos))); + (pos = program.find_first_of("\r\n", pos))); unindented_program.append(program.begin() + copy_start, program.end()); @@ -597,7 +594,8 @@ namespace quickbook file_position mapped_file::position_of(string_iterator pos) const { - return original->position_of(original->source().begin() + + return original->position_of( + original->source().begin() + to_original_pos(find_section(pos), pos - source().begin())); } } diff --git a/tools/quickbook/src/files.hpp b/tools/quickbook/src/files.hpp index 647d6af233..115974e918 100644 --- a/tools/quickbook/src/files.hpp +++ b/tools/quickbook/src/files.hpp @@ -11,15 +11,16 @@ #if !defined(BOOST_QUICKBOOK_FILES_HPP) #define BOOST_QUICKBOOK_FILES_HPP +#include +#include +#include #include #include #include #include "string_view.hpp" -#include -#include -#include -namespace quickbook { +namespace quickbook +{ namespace fs = boost::filesystem; @@ -29,60 +30,71 @@ namespace quickbook { struct file_position { file_position() : line(1), column(1) {} - file_position(std::ptrdiff_t l, std::ptrdiff_t c) : line(l), column(c) {} + file_position(std::ptrdiff_t l, std::ptrdiff_t c) : line(l), column(c) + { + } std::ptrdiff_t line; std::ptrdiff_t column; - + bool operator==(file_position const& other) const { return line == other.line && column == other.column; } - + friend std::ostream& operator<<(std::ostream&, file_position const&); }; struct file { - private: + private: // Non copyable file& operator=(file const&); file(file const&); - public: + + public: fs::path const path; std::string source_; bool is_code_snippets; - private: + + private: unsigned qbk_version; unsigned ref_count; - public: + + public: quickbook::string_view source() const { return source_; } - file(fs::path const& path_, quickbook::string_view source_view, - unsigned qbk_version_) : - path(path_), - source_(source_view.begin(), source_view.end()), - is_code_snippets(false), - qbk_version(qbk_version_), - ref_count(0) - {} - - explicit file(file const& f, quickbook::string_view s) : - path(f.path), source_(s.begin(), s.end()), - is_code_snippets(f.is_code_snippets), - qbk_version(f.qbk_version), ref_count(0) - {} - - virtual ~file() { - assert(!ref_count); + file( + fs::path const& path_, + quickbook::string_view source_view, + unsigned qbk_version_) + : path(path_) + , source_(source_view.begin(), source_view.end()) + , is_code_snippets(false) + , qbk_version(qbk_version_) + , ref_count(0) + { + } + + explicit file(file const& f, quickbook::string_view s) + : path(f.path) + , source_(s.begin(), s.end()) + , is_code_snippets(f.is_code_snippets) + , qbk_version(f.qbk_version) + , ref_count(0) + { } - unsigned version() const { + virtual ~file() { assert(!ref_count); } + + unsigned version() const + { assert(qbk_version); return qbk_version; } - void version(unsigned v) { + void version(unsigned v) + { // Check that either version hasn't been set, or it was // previously set to the same version (because the same // file has been loaded twice). @@ -95,17 +107,17 @@ namespace quickbook { friend void intrusive_ptr_add_ref(file* ptr) { ++ptr->ref_count; } friend void intrusive_ptr_release(file* ptr) - { if(--ptr->ref_count == 0) delete ptr; } + { + if (--ptr->ref_count == 0) delete ptr; + } }; // If version isn't supplied then it must be set later. - file_ptr load(fs::path const& filename, - unsigned qbk_version = 0); + file_ptr load(fs::path const& filename, unsigned qbk_version = 0); struct load_error : std::runtime_error { - explicit load_error(std::string const& arg) - : std::runtime_error(arg) {} + explicit load_error(std::string const& arg) : std::runtime_error(arg) {} }; // Interface for creating fake files which are mapped to @@ -133,7 +145,8 @@ namespace quickbook { void add(mapped_file_builder const&); void add(mapped_file_builder const&, pos_type, pos_type); void unindent_and_add(quickbook::string_view); - private: + + private: mapped_file_builder_data* data; mapped_file_builder(mapped_file_builder const&); diff --git a/tools/quickbook/src/fwd.hpp b/tools/quickbook/src/fwd.hpp index dbf7246962..f079aa5bcf 100644 --- a/tools/quickbook/src/fwd.hpp +++ b/tools/quickbook/src/fwd.hpp @@ -25,7 +25,7 @@ namespace quickbook typedef boost::intrusive_ptr file_ptr; typedef unsigned source_mode_type; - inline void ignore_variable(void const*) {} + inline void ignore_variable(void const*) {} } #endif diff --git a/tools/quickbook/src/glob.cpp b/tools/quickbook/src/glob.cpp index ff332e10a8..224b9ce48d 100644 --- a/tools/quickbook/src/glob.cpp +++ b/tools/quickbook/src/glob.cpp @@ -16,10 +16,13 @@ namespace quickbook void check_glob_range(glob_iterator&, glob_iterator); void check_glob_escape(glob_iterator&, glob_iterator); - bool match_section(glob_iterator& pattern_begin, glob_iterator pattern_end, - glob_iterator& filename_begin, glob_iterator& filename_end); - bool match_range(glob_iterator& pattern_begin, glob_iterator pattern_end, - char x); + bool match_section( + glob_iterator& pattern_begin, + glob_iterator pattern_end, + glob_iterator& filename_begin, + glob_iterator& filename_end); + bool match_range( + glob_iterator& pattern_begin, glob_iterator pattern_end, char x); // Is pattern a glob or a plain file name? // Throws glob_error if pattern is an invalid glob. @@ -32,38 +35,37 @@ namespace quickbook glob_iterator end = pattern.end(); while (begin != end) { - if (*begin < 32 || (*begin & 0x80)) - is_ascii = false; + if (*begin < 32 || (*begin & 0x80)) is_ascii = false; - switch(*begin) { - case '\\': - check_glob_escape(begin, end); - break; + switch (*begin) { + case '\\': + check_glob_escape(begin, end); + break; - case '[': - check_glob_range(begin, end); - is_glob = true; - break; + case '[': + check_glob_range(begin, end); + is_glob = true; + break; - case ']': - throw glob_error("uneven square brackets"); + case ']': + throw glob_error("uneven square brackets"); - case '?': - is_glob = true; - ++begin; - break; + case '?': + is_glob = true; + ++begin; + break; - case '*': - is_glob = true; - ++begin; + case '*': + is_glob = true; + ++begin; - if (begin != end && *begin == '*') { - throw glob_error("'**' not supported"); - } - break; + if (begin != end && *begin == '*') { + throw glob_error("'**' not supported"); + } + break; - default: - ++begin; + default: + ++begin; } } @@ -78,32 +80,31 @@ namespace quickbook assert(begin != end && *begin == '['); ++begin; - if (*begin == ']') - throw glob_error("empty range"); + if (*begin == ']') throw glob_error("empty range"); while (begin != end) { switch (*begin) { - case '\\': - ++begin; + case '\\': + ++begin; - if (begin == end) { - throw glob_error("trailing escape"); - } - else if (*begin == '\\' || *begin == '/') { - throw glob_error("contains escaped slash"); - } + if (begin == end) { + throw glob_error("trailing escape"); + } + else if (*begin == '\\' || *begin == '/') { + throw glob_error("contains escaped slash"); + } - ++begin; - break; - case '[': - throw glob_error("nested square brackets"); - case ']': - ++begin; - return; - case '/': - throw glob_error("slash in square brackets"); - default: - ++begin; + ++begin; + break; + case '[': + throw glob_error("nested square brackets"); + case ']': + ++begin; + return; + case '/': + throw glob_error("slash in square brackets"); + default: + ++begin; } } @@ -129,8 +130,9 @@ namespace quickbook // Does filename match pattern? // Might throw glob_error if pattern is an invalid glob, // but should call check_glob first to validate the glob. - bool glob(quickbook::string_view const& pattern, - quickbook::string_view const& filename) + bool glob( + quickbook::string_view const& pattern, + quickbook::string_view const& filename) { // If there wasn't this special case then '*' would match an // empty string. @@ -151,11 +153,14 @@ namespace quickbook if (pattern_it == pattern_end) return true; - if (*pattern_it == '*') { throw glob_error("'**' not supported"); } + if (*pattern_it == '*') { + throw glob_error("'**' not supported"); + } for (;;) { if (filename_it == filename_end) return false; - if (match_section(pattern_it, pattern_end, filename_it, filename_end)) + if (match_section( + pattern_it, pattern_end, filename_it, filename_end)) break; ++filename_it; } @@ -164,8 +169,11 @@ namespace quickbook return filename_it == filename_end; } - bool match_section(glob_iterator& pattern_begin, glob_iterator pattern_end, - glob_iterator& filename_begin, glob_iterator& filename_end) + bool match_section( + glob_iterator& pattern_begin, + glob_iterator pattern_end, + glob_iterator& filename_begin, + glob_iterator& filename_end) { glob_iterator pattern_it = pattern_begin; glob_iterator filename_it = filename_begin; @@ -173,33 +181,34 @@ namespace quickbook while (pattern_it != pattern_end && *pattern_it != '*') { if (filename_it == filename_end) return false; - switch(*pattern_it) { - case '*': - assert(false); - throw new glob_error("Internal error"); - case '[': - if (!match_range(pattern_it, pattern_end, *filename_it)) - return false; - ++filename_it; - break; - case ']': - throw glob_error("uneven square brackets"); - case '?': - ++pattern_it; - ++filename_it; - break; - case '\\': - ++pattern_it; - if (pattern_it == pattern_end) { - throw glob_error("trailing escape"); - } else if (*pattern_it == '\\' || *pattern_it == '/') { - throw glob_error("contains escaped slash"); - } - BOOST_FALLTHROUGH; - default: - if (*pattern_it != *filename_it) return false; - ++pattern_it; - ++filename_it; + switch (*pattern_it) { + case '*': + assert(false); + throw new glob_error("Internal error"); + case '[': + if (!match_range(pattern_it, pattern_end, *filename_it)) + return false; + ++filename_it; + break; + case ']': + throw glob_error("uneven square brackets"); + case '?': + ++pattern_it; + ++filename_it; + break; + case '\\': + ++pattern_it; + if (pattern_it == pattern_end) { + throw glob_error("trailing escape"); + } + else if (*pattern_it == '\\' || *pattern_it == '/') { + throw glob_error("contains escaped slash"); + } + BOOST_FALLTHROUGH; + default: + if (*pattern_it != *filename_it) return false; + ++pattern_it; + ++filename_it; } } @@ -211,8 +220,8 @@ namespace quickbook return true; } - bool match_range(glob_iterator& pattern_begin, glob_iterator pattern_end, - char x) + bool match_range( + glob_iterator& pattern_begin, glob_iterator pattern_end, char x) { assert(pattern_begin != pattern_end && *pattern_begin == '['); ++pattern_begin; @@ -229,7 +238,8 @@ namespace quickbook if (pattern_begin == pattern_end) { throw glob_error("uneven square brackets"); } - } else if (*pattern_begin == ']') { + } + else if (*pattern_begin == ']') { throw glob_error("empty range"); } @@ -254,7 +264,8 @@ namespace quickbook if (pattern_begin == pattern_end) { throw glob_error("uneven square brackets"); } - } else if (first == '/') { + } + else if (first == '/') { throw glob_error("slash in square brackets"); } @@ -286,7 +297,8 @@ namespace quickbook if (pattern_begin == pattern_end) { throw glob_error("uneven square brackets"); } - } else if (second == '/') { + } + else if (second == '/') { throw glob_error("slash in square brackets"); } @@ -297,8 +309,7 @@ namespace quickbook return invert_match != matched; } - std::size_t find_glob_char(quickbook::string_view pattern, - std::size_t pos) + std::size_t find_glob_char(quickbook::string_view pattern, std::size_t pos) { // Weird style is because quickbook::string_view's find_first_of // doesn't take a position argument. diff --git a/tools/quickbook/src/glob.hpp b/tools/quickbook/src/glob.hpp index 5b79c07b2b..63fe42c6ea 100644 --- a/tools/quickbook/src/glob.hpp +++ b/tools/quickbook/src/glob.hpp @@ -6,25 +6,24 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "string_view.hpp" #include +#include "string_view.hpp" namespace quickbook { struct glob_error : std::runtime_error { - explicit glob_error(char const* error) : - std::runtime_error(error) {} + explicit glob_error(char const* error) : std::runtime_error(error) {} }; // Is this path a glob? Throws glob_error if glob is invalid. bool check_glob(quickbook::string_view); // pre: glob is valid (call check_glob first on user data). - bool glob(quickbook::string_view const& pattern, - quickbook::string_view const& filename); + bool glob( + quickbook::string_view const& pattern, + quickbook::string_view const& filename); - std::size_t find_glob_char(quickbook::string_view, - std::size_t start = 0); + std::size_t find_glob_char(quickbook::string_view, std::size_t start = 0); std::string glob_unescape(quickbook::string_view); } diff --git a/tools/quickbook/src/grammar.cpp b/tools/quickbook/src/grammar.cpp index 54ed64aa06..24a3e96ad6 100644 --- a/tools/quickbook/src/grammar.cpp +++ b/tools/quickbook/src/grammar.cpp @@ -13,25 +13,21 @@ namespace quickbook { - quickbook_grammar::quickbook_grammar(quickbook::state& s) + quickbook_grammar::quickbook_grammar(quickbook::state& s) : impl_(new impl(s)) , command_line_macro(impl_->command_line, "command_line_macro") , inline_phrase(impl_->inline_phrase, "inline_phrase") , phrase_start(impl_->phrase_start, "phrase") , block_start(impl_->block_start, "block") - , attribute_template_body(impl_->attribute_template_body, - "attribute_template_body") + , attribute_template_body( + impl_->attribute_template_body, "attribute_template_body") , doc_info(impl_->doc_info_details, "doc_info") { } - - quickbook_grammar::~quickbook_grammar() - { - } - quickbook_grammar::impl::impl(quickbook::state& s) - : state(s) - , cleanup_() + quickbook_grammar::~quickbook_grammar() {} + + quickbook_grammar::impl::impl(quickbook::state& s) : state(s), cleanup_() { init_main(); init_block_elements(); diff --git a/tools/quickbook/src/grammar.hpp b/tools/quickbook/src/grammar.hpp index b472d5a3fc..17fea7d448 100644 --- a/tools/quickbook/src/grammar.hpp +++ b/tools/quickbook/src/grammar.hpp @@ -22,23 +22,30 @@ namespace quickbook // spirit implementation detail, but since classic is no longer under // development, it won't change. And spirit 2 won't require such a hack. - typedef cl::scanner > scanner; + typedef cl::scanner< + parse_iterator, + cl::scanner_policies< + cl::iteration_policy, + cl::match_policy, + cl::action_policy> > + scanner; template struct Scanner_must_be_the_quickbook_scanner_typedef; - template <> - struct Scanner_must_be_the_quickbook_scanner_typedef {}; + template <> struct Scanner_must_be_the_quickbook_scanner_typedef + { + }; - struct grammar - : public cl::grammar + struct grammar : public cl::grammar { grammar(cl::rule const& start_rule_, char const* /* name */) - : start_rule(start_rule_) {} + : start_rule(start_rule_) + { + } template - struct definition : - Scanner_must_be_the_quickbook_scanner_typedef + struct definition + : Scanner_must_be_the_quickbook_scanner_typedef { definition(grammar const& self) : start_rule(self.start_rule) {} cl::rule const& start() const { return start_rule; } @@ -50,13 +57,13 @@ namespace quickbook struct quickbook_grammar { - public: + public: struct impl; - private: + private: boost::scoped_ptr impl_; - public: + public: grammar command_line_macro; grammar inline_phrase; grammar phrase_start; diff --git a/tools/quickbook/src/grammar_impl.hpp b/tools/quickbook/src/grammar_impl.hpp index e0baaadba8..74c50155c1 100644 --- a/tools/quickbook/src/grammar_impl.hpp +++ b/tools/quickbook/src/grammar_impl.hpp @@ -11,10 +11,10 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_GRAMMARS_IMPL_HPP) #define BOOST_SPIRIT_QUICKBOOK_GRAMMARS_IMPL_HPP -#include "grammar.hpp" +#include #include "cleanup.hpp" +#include "grammar.hpp" #include "values.hpp" -#include namespace quickbook { @@ -32,7 +32,8 @@ namespace quickbook // - whether they end a paragraph // - how following newlines are interpreted by the grammar. // - and possibly other things..... - enum type_enum { + enum type_enum + { // Used when there's no element. nothing = 0, @@ -43,9 +44,9 @@ namespace quickbook // but not nested. conditional_or_block = 2, - // Block elements that can be nested in other elements. + // Block elements that can be nested in other elements. nested_block = 4, - + // Phrase elements. phrase = 8, @@ -65,17 +66,18 @@ namespace quickbook // Masks to determine which context elements can be used in (in_*), and // whether they are consided to be a block element (is_*). - enum context { + enum context + { // At the top level we allow everything. in_top_level = phrase | maybe_block | nested_block | - conditional_or_block | section_block, + conditional_or_block | section_block, // In conditional phrases and list blocks we everything but section // elements. - in_conditional = phrase | maybe_block | nested_block | - conditional_or_block, - in_list_block = phrase | maybe_block | nested_block | - conditional_or_block, + in_conditional = + phrase | maybe_block | nested_block | conditional_or_block, + in_list_block = + phrase | maybe_block | nested_block | conditional_or_block, // In nested blocks we allow a more limited range of elements. in_nested_block = phrase | maybe_block | nested_block, @@ -86,21 +88,22 @@ namespace quickbook // At the start of a block these are all block elements. is_contextual_block = maybe_block | nested_block | - conditional_or_block | section_block, + conditional_or_block | section_block, // These are all block elements in all other contexts. is_block = nested_block | conditional_or_block | section_block }; - element_info() - : type(nothing), rule(), tag(0) {} + element_info() : type(nothing), rule(), tag(0) {} element_info( - type_enum t, - cl::rule* r, - value::tag_type tag_ = value::default_tag, - unsigned int v = 0) - : type(t), rule(r), tag(tag_), qbk_version(v) {} + type_enum t, + cl::rule* r, + value::tag_type tag_ = value::default_tag, + unsigned int v = 0) + : type(t), rule(r), tag(tag_), qbk_version(v) + { + } type_enum type; cl::rule* rule; @@ -137,25 +140,24 @@ namespace quickbook // the end of an itendifier. cl::rule space; // Space/tab/newline/comment (possibly empty) cl::rule blank; // Space/tab/comment (possibly empty) - cl::rule eol; // blank >> eol + cl::rule eol; // blank >> eol cl::rule phrase_end; // End of phrase text, context sensitive cl::rule comment; cl::rule line_comment; cl::rule macro_identifier; - // Element Symbols + // Element Symbols cl::symbols elements; // Source mode cl::symbols source_modes; - + // Doc Info cl::rule doc_info_details; - - impl(quickbook::state&); - private: + impl(quickbook::state&); + private: void init_main(); void init_block_elements(); void init_phrase_elements(); diff --git a/tools/quickbook/src/id_generation.cpp b/tools/quickbook/src/id_generation.cpp index 80df0ad4eb..f640d19009 100644 --- a/tools/quickbook/src/id_generation.cpp +++ b/tools/quickbook/src/id_generation.cpp @@ -7,14 +7,15 @@ =============================================================================*/ #include -#include "document_state_impl.hpp" -#include -#include -#include #include +#include +#include #include +#include +#include "document_state_impl.hpp" -namespace quickbook { +namespace quickbook +{ // // The maximum size of a generated part of an id. // @@ -24,13 +25,16 @@ namespace quickbook { static const std::size_t max_size = 32; typedef std::vector placeholder_index; - placeholder_index index_placeholders(document_state_impl const&, quickbook::string_view); + placeholder_index index_placeholders( + document_state_impl const&, quickbook::string_view); void generate_id_block( - placeholder_index::iterator, placeholder_index::iterator, - std::vector& generated_ids); + placeholder_index::iterator, + placeholder_index::iterator, + std::vector& generated_ids); - std::vector generate_ids(document_state_impl const& state, quickbook::string_view xml) + std::vector generate_ids( + document_state_impl const& state, quickbook::string_view xml) { std::vector generated_ids(state.placeholders.size()); @@ -49,7 +53,8 @@ namespace quickbook { // // So find the group of placeholders with the same number of dots. iterator group_begin = it, group_end = it; - while (group_end != end && (*group_end)->num_dots == (*it)->num_dots) + while (group_end != end && + (*group_end)->num_dots == (*it)->num_dots) ++group_end; generate_id_block(group_begin, group_end, generated_ids); @@ -77,12 +82,15 @@ namespace quickbook { bool x_explicit = x->category.c >= id_category::explicit_id; bool y_explicit = y->category.c >= id_category::explicit_id; - return - x->num_dots < y->num_dots ? true : - x->num_dots > y->num_dots ? false : - x_explicit > y_explicit ? true : - x_explicit < y_explicit ? false : - order[x->index] < order[y->index]; + return x->num_dots < y->num_dots + ? true + : x->num_dots > y->num_dots + ? false + : x_explicit > y_explicit + ? true + : x_explicit < y_explicit + ? false + : order[x->index] < order[y->index]; } }; @@ -92,12 +100,11 @@ namespace quickbook { std::vector& order; unsigned count; - get_placeholder_order_callback(document_state_impl const& state_, - std::vector& order_) - : state(state_), - order(order_), - count(0) - {} + get_placeholder_order_callback( + document_state_impl const& state_, std::vector& order_) + : state(state_), order(order_), count(0) + { + } void id_value(quickbook::string_view value) { @@ -114,8 +121,7 @@ namespace quickbook { }; placeholder_index index_placeholders( - document_state_impl const& state, - quickbook::string_view xml) + document_state_impl const& state, quickbook::string_view xml) { // The order that the placeholder appear in the xml source. std::vector order(state.placeholders.size()); @@ -126,7 +132,7 @@ namespace quickbook { placeholder_index sorted_placeholders; sorted_placeholders.reserve(state.placeholders.size()); - BOOST_FOREACH(id_placeholder const& p, state.placeholders) + BOOST_FOREACH (id_placeholder const& p, state.placeholders) if (order[p.index]) sorted_placeholders.push_back(&p); boost::sort(sorted_placeholders, placeholder_compare(order)); @@ -143,26 +149,30 @@ namespace quickbook { chosen_id_map chosen_ids; std::vector& generated_ids; - explicit generate_id_block_type(std::vector& generated_ids_) : - generated_ids(generated_ids_) {} + explicit generate_id_block_type( + std::vector& generated_ids_) + : generated_ids(generated_ids_) + { + } - void generate(placeholder_index::iterator begin, - placeholder_index::iterator end); + void generate( + placeholder_index::iterator begin, placeholder_index::iterator end); std::string resolve_id(id_placeholder const*); std::string generate_id(id_placeholder const*, std::string const&); }; - void generate_id_block(placeholder_index::iterator begin, - placeholder_index::iterator end, - std::vector& generated_ids) + void generate_id_block( + placeholder_index::iterator begin, + placeholder_index::iterator end, + std::vector& generated_ids) { generate_id_block_type impl(generated_ids); impl.generate(begin, end); } - void generate_id_block_type::generate(placeholder_index::iterator begin, - placeholder_index::iterator end) + void generate_id_block_type::generate( + placeholder_index::iterator begin, placeholder_index::iterator end) { std::vector resolved_ids; @@ -170,18 +180,15 @@ namespace quickbook { resolved_ids.push_back(resolve_id(*i)); unsigned index = 0; - for (placeholder_index::iterator i = begin; i != end; ++i, ++index) - { - generated_ids[(**i).index] = - generate_id(*i, resolved_ids[index]); + for (placeholder_index::iterator i = begin; i != end; ++i, ++index) { + generated_ids[(**i).index] = generate_id(*i, resolved_ids[index]); } } std::string generate_id_block_type::resolve_id(id_placeholder const* p) { - std::string id = p->parent ? - generated_ids[p->parent->index] + "." + p->id : - p->id; + std::string id = + p->parent ? generated_ids[p->parent->index] + "." + p->id : p->id; if (p->category.c > id_category::numbered) { // Reserve the id if it isn't already reserved. @@ -189,19 +196,17 @@ namespace quickbook { // If it was reserved by a placeholder with a lower category, // then overwrite it. - if (p->category.c > pos->second->category.c) - pos->second = p; + if (p->category.c > pos->second->category.c) pos->second = p; } return id; } - std::string generate_id_block_type::generate_id(id_placeholder const* p, - std::string const& resolved_id) + std::string generate_id_block_type::generate_id( + id_placeholder const* p, std::string const& resolved_id) { if (p->category.c > id_category::numbered && - chosen_ids.at(resolved_id) == p) - { + chosen_ids.at(resolved_id) == p) { return resolved_id; } @@ -217,8 +222,8 @@ namespace quickbook { } else { parent_id = resolved_id.substr(0, child_start + 1); - base_id = normalize_id(resolved_id.substr(child_start + 1), - max_size - 1); + base_id = + normalize_id(resolved_id.substr(child_start + 1), max_size - 1); } // Since we're adding digits, don't want an id that ends in @@ -232,7 +237,7 @@ namespace quickbook { ++length; } else { - while (length > 0 && std::isdigit(base_id[length -1])) + while (length > 0 && std::isdigit(base_id[length - 1])) --length; base_id.erase(length); } @@ -240,10 +245,8 @@ namespace quickbook { unsigned count = 0; - for (;;) - { - std::string postfix = - boost::lexical_cast(count++); + for (;;) { + std::string postfix = boost::lexical_cast(count++); if ((base_id.size() + postfix.size()) > max_size) { // The id is now too long, so reduce the length and @@ -256,7 +259,7 @@ namespace quickbook { --length; // Trim any trailing digits. - while (length > 0 && std::isdigit(base_id[length -1])) + while (length > 0 && std::isdigit(base_id[length - 1])) --length; base_id.erase(length); @@ -287,25 +290,20 @@ namespace quickbook { string_iterator source_pos; std::string result; - replace_ids_callback(document_state_impl const& state_, - std::vector const* ids_) - : state(state_), - ids(ids_), - source_pos(), - result() - {} - - void start(quickbook::string_view xml) + replace_ids_callback( + document_state_impl const& state_, + std::vector const* ids_) + : state(state_), ids(ids_), source_pos(), result() { - source_pos = xml.begin(); } + void start(quickbook::string_view xml) { source_pos = xml.begin(); } + void id_value(quickbook::string_view value) { - if (id_placeholder const* p = state.get_placeholder(value)) - { - quickbook::string_view id = ids ? - (*ids)[p->index] : p->unresolved_id; + if (id_placeholder const* p = state.get_placeholder(value)) { + quickbook::string_view id = + ids ? (*ids)[p->index] : p->unresolved_id; result.append(source_pos, value.begin()); result.append(id.begin(), id.end()); @@ -320,8 +318,10 @@ namespace quickbook { } }; - std::string replace_ids(document_state_impl const& state, quickbook::string_view xml, - std::vector const* ids) + std::string replace_ids( + document_state_impl const& state, + quickbook::string_view xml, + std::vector const* ids) { xml_processor processor; replace_ids_callback callback(state, ids); @@ -359,7 +359,7 @@ namespace quickbook { if (id[src] == '_') { do { ++src; - } while(src < id.length() && id[src] == '_'); + } while (src < id.length() && id[src] == '_'); if (src < id.length()) id[dst++] = '_'; } diff --git a/tools/quickbook/src/id_xml.cpp b/tools/quickbook/src/id_xml.cpp index e220f66210..a3ddb28bf2 100644 --- a/tools/quickbook/src/id_xml.cpp +++ b/tools/quickbook/src/id_xml.cpp @@ -6,28 +6,23 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ +#include #include "document_state_impl.hpp" #include "utils.hpp" -#include namespace quickbook { namespace { - char const* id_attributes_[] = - { - "id", - "linkend", - "linkends", - "arearefs" - }; + char const* id_attributes_[] = {"id", "linkend", "linkends", + "arearefs"}; } xml_processor::xml_processor() { - static std::size_t const n_id_attributes = sizeof(id_attributes_)/sizeof(char const*); - for (int i = 0; i != n_id_attributes; ++i) - { + static std::size_t const n_id_attributes = + sizeof(id_attributes_) / sizeof(char const*); + for (int i = 0; i != n_id_attributes; ++i) { id_attributes.push_back(id_attributes_[i]); } @@ -37,26 +32,26 @@ namespace quickbook template bool read(Iterator& it, Iterator end, char const* text) { - for(Iterator it2 = it;; ++it2, ++text) { + for (Iterator it2 = it;; ++it2, ++text) { if (!*text) { it = it2; return true; } - if (it2 == end || *it2 != *text) - return false; + if (it2 == end || *it2 != *text) return false; } } template void read_past(Iterator& it, Iterator end, char const* text) { - while (it != end && !read(it, end, text)) ++it; + while (it != end && !read(it, end, text)) + ++it; } bool find_char(char const* text, char c) { - for(;*text; ++text) + for (; *text; ++text) if (c == *text) return true; return false; } @@ -64,13 +59,15 @@ namespace quickbook template void read_some_of(Iterator& it, Iterator end, char const* text) { - while(it != end && find_char(text, *it)) ++it; + while (it != end && find_char(text, *it)) + ++it; } template void read_to_one_of(Iterator& it, Iterator end, char const* text) { - while(it != end && !find_char(text, *it)) ++it; + while (it != end && !find_char(text, *it)) + ++it; } void xml_processor::parse(quickbook::string_view source, callback& c) @@ -81,19 +78,16 @@ namespace quickbook iterator it = source.begin(), end = source.end(); - for(;;) - { + for (;;) { read_past(it, end, "<"); if (it == end) break; - if (read(it, end, "!--quickbook-escape-prefix-->")) - { + if (read(it, end, "!--quickbook-escape-prefix-->")) { read_past(it, end, ""); continue; } - switch(*it) - { + switch (*it) { case '?': ++it; read_past(it, end, "?>"); @@ -107,10 +101,8 @@ namespace quickbook break; default: - if ((*it >= 'a' && *it <= 'z') || - (*it >= 'A' && *it <= 'Z') || - *it == '_' || *it == ':') - { + if ((*it >= 'a' && *it <= 'z') || (*it >= 'A' && *it <= 'Z') || + *it == '_' || *it == ':') { read_to_one_of(it, end, " \t\n\r>"); for (;;) { @@ -118,7 +110,8 @@ namespace quickbook iterator name_start = it; read_to_one_of(it, end, "= \t\n\r>"); if (it == end || *it == '>') break; - quickbook::string_view name(name_start, it - name_start); + quickbook::string_view name( + name_start, it - name_start); ++it; read_some_of(it, end, "= \t\n\r"); @@ -131,18 +124,17 @@ namespace quickbook it = std::find(it, end, delim); if (it == end) break; - quickbook::string_view value(value_start, it - value_start); + quickbook::string_view value( + value_start, it - value_start); ++it; - if (boost::find(id_attributes, name.to_s()) - != id_attributes.end()) - { + if (boost::find(id_attributes, name.to_s()) != + id_attributes.end()) { c.id_value(value); } } } - else - { + else { read_past(it, end, ">"); } } @@ -151,8 +143,10 @@ namespace quickbook c.finish(source); } - namespace detail { - std::string linkify(quickbook::string_view source, quickbook::string_view linkend) + namespace detail + { + std::string linkify( + quickbook::string_view source, quickbook::string_view linkend) { typedef string_iterator iterator; @@ -160,13 +154,11 @@ namespace quickbook bool contains_link = false; - for(;!contains_link;) - { + for (; !contains_link;) { read_past(it, end, "<"); if (it == end) break; - switch(*it) - { + switch (*it) { case '?': ++it; read_past(it, end, "?>"); @@ -175,20 +167,23 @@ namespace quickbook case '!': if (read(it, end, "!--")) { read_past(it, end, "-->"); - } else { + } + else { read_past(it, end, ">"); } break; default: if ((*it >= 'a' && *it <= 'z') || - (*it >= 'A' && *it <= 'Z') || - *it == '_' || *it == ':') - { + (*it >= 'A' && *it <= 'Z') || *it == '_' || + *it == ':') { iterator tag_name_start = it; read_to_one_of(it, end, " \t\n\r>"); - quickbook::string_view tag_name(tag_name_start, it - tag_name_start); - if (tag_name == "link") { contains_link = true; } + quickbook::string_view tag_name( + tag_name_start, it - tag_name_start); + if (tag_name == "link") { + contains_link = true; + } for (;;) { read_to_one_of(it, end, "\"'\n\r>"); @@ -202,8 +197,7 @@ namespace quickbook } } } - else - { + else { read_past(it, end, ">"); } } @@ -217,7 +211,8 @@ namespace quickbook result += "\">"; result.append(source.begin(), source.end()); result += ""; - } else { + } + else { result.append(source.begin(), source.end()); } diff --git a/tools/quickbook/src/include_paths.cpp b/tools/quickbook/src/include_paths.cpp index c598555b37..32d6d8a571 100644 --- a/tools/quickbook/src/include_paths.cpp +++ b/tools/quickbook/src/include_paths.cpp @@ -9,17 +9,17 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "stream.hpp" -#include "glob.hpp" #include "include_paths.hpp" +#include +#include +#include +#include +#include "glob.hpp" #include "path.hpp" +#include "quickbook.hpp" // For the include_path global (yuck) #include "state.hpp" +#include "stream.hpp" #include "utils.hpp" -#include "quickbook.hpp" // For the include_path global (yuck) -#include -#include -#include -#include namespace quickbook { @@ -31,8 +31,7 @@ namespace quickbook { if (qbk_version_n >= 107u) { std::string path_text = path.get_encoded(); - if (path_text.empty()) - { + if (path_text.empty()) { detail::outerr(path.get_file(), path.get_position()) << "Empty path argument" << "std::endl"; @@ -45,13 +44,12 @@ namespace quickbook return path_parameter(path_text, path_parameter::glob); } else { - return path_parameter(glob_unescape(path_text), - path_parameter::path); + return path_parameter( + glob_unescape(path_text), path_parameter::path); } - } catch(glob_error& e) { + } catch (glob_error& e) { detail::outerr(path.get_file(), path.get_position()) - << "Invalid path (" << e.what() << "): " - << path_text + << "Invalid path (" << e.what() << "): " << path_text << std::endl; ++state.error_count; return path_parameter(path_text, path_parameter::invalid); @@ -64,14 +62,13 @@ namespace quickbook // // Counter-intuitively: encoded == plain text here. - std::string path_text = qbk_version_n >= 106u || path.is_encoded() ? - path.get_encoded() : path.get_quickbook().to_s(); + std::string path_text = qbk_version_n >= 106u || path.is_encoded() + ? path.get_encoded() + : path.get_quickbook().to_s(); - if (path_text.empty()) - { + if (path_text.empty()) { detail::outerr(path.get_file(), path.get_position()) - << "Empty path argument" - << std::endl; + << "Empty path argument" << std::endl; ++state.error_count; return path_parameter(path_text, path_parameter::invalid); } @@ -79,8 +76,7 @@ namespace quickbook // Check for windows paths, an error in quickbook 1.6 // In quickbook 1.7 backslash is used as an escape character // for glob characters. - if (path_text.find('\\') != std::string::npos) - { + if (path_text.find('\\') != std::string::npos) { quickbook::detail::ostream* err; if (qbk_version_n >= 106u) { @@ -88,13 +84,12 @@ namespace quickbook ++state.error_count; } else { - err = &detail::outwarn(path.get_file(), path.get_position()); + err = + &detail::outwarn(path.get_file(), path.get_position()); } - *err << "Path isn't portable: '" - << path_text - << "'" - << std::endl; + *err << "Path isn't portable: '" << path_text << "'" + << std::endl; boost::replace(path_text, '\\', '/'); } @@ -109,8 +104,7 @@ namespace quickbook if (parameter.type == path_parameter::glob) { detail::outerr(p.get_file(), p.get_position()) - << "Glob used for xml path." - << std::endl; + << "Glob used for xml path." << std::endl; ++state.error_count; parameter.type = path_parameter::invalid; } @@ -122,18 +116,18 @@ namespace quickbook // Search include path // - void include_search_glob(std::set & result, + void include_search_glob( + std::set& result, quickbook_path const& location, - std::string path, quickbook::state& state) + std::string path, + quickbook::state& state) { std::size_t glob_pos = find_glob_char(path); - if (glob_pos == std::string::npos) - { + if (glob_pos == std::string::npos) { quickbook_path complete_path = location / glob_unescape(path); - if (fs::exists(complete_path.file_path)) - { + if (fs::exists(complete_path.file_path)) { state.dependencies.add_glob_match(complete_path.file_path); result.insert(complete_path); } @@ -155,17 +149,16 @@ namespace quickbook if (next != std::string::npos) ++next; quickbook::string_view glob( - path.data() + glob_begin, - glob_end - glob_begin); + path.data() + glob_begin, glob_end - glob_begin); - fs::path base_dir = new_location.file_path.empty() ? - fs::path(".") : new_location.file_path; + fs::path base_dir = new_location.file_path.empty() + ? fs::path(".") + : new_location.file_path; if (!fs::is_directory(base_dir)) return; // Walk through the dir for matches. - for (fs::directory_iterator dir_i(base_dir), dir_e; - dir_i != dir_e; ++dir_i) - { + for (fs::directory_iterator dir_i(base_dir), dir_e; dir_i != dir_e; + ++dir_i) { fs::path f = dir_i->path().filename(); std::string generic_path = detail::path_to_generic(f); @@ -173,34 +166,33 @@ namespace quickbook if (!quickbook::glob(glob, generic_path)) continue; // If it's a file we add it to the results. - if (next == std::string::npos) - { - if (fs::is_regular_file(dir_i->status())) - { + if (next == std::string::npos) { + if (fs::is_regular_file(dir_i->status())) { quickbook_path r = new_location / generic_path; state.dependencies.add_glob_match(r.file_path); result.insert(r); } } // If it's a matching dir, we recurse looking for more files. - else - { - if (!fs::is_regular_file(dir_i->status())) - { - include_search_glob(result, new_location / generic_path, - path.substr(next), state); + else { + if (!fs::is_regular_file(dir_i->status())) { + include_search_glob( + result, new_location / generic_path, path.substr(next), + state); } } } } - std::set include_search(path_parameter const& parameter, - quickbook::state& state, string_iterator pos) + std::set include_search( + path_parameter const& parameter, + quickbook::state& state, + string_iterator pos) { std::set result; switch (parameter.type) { - case path_parameter::glob: + case path_parameter::glob: // If the path has some glob match characters // we do a discovery of all the matches.. { @@ -208,78 +200,70 @@ namespace quickbook // Search for the current dir accumulating to the result. state.dependencies.add_glob(current / parameter.value); - include_search_glob(result, state.current_path.parent_path(), - parameter.value, state); + include_search_glob( + result, state.current_path.parent_path(), parameter.value, + state); // Search the include path dirs accumulating to the result. unsigned count = 0; - BOOST_FOREACH(fs::path dir, include_path) - { + BOOST_FOREACH (fs::path dir, include_path) { ++count; state.dependencies.add_glob(dir / parameter.value); - include_search_glob(result, - quickbook_path(dir, count, fs::path()), - parameter.value, state); + include_search_glob( + result, quickbook_path(dir, count, fs::path()), + parameter.value, state); } // Done. return result; } - case path_parameter::path: - { - fs::path path = detail::generic_to_path(parameter.value); - - // If the path is relative, try and resolve it. - if (!path.has_root_directory() && !path.has_root_name()) - { - quickbook_path path2 = - state.current_path.parent_path() / parameter.value; - - // See if it can be found locally first. - if (state.dependencies.add_dependency(path2.file_path)) - { - result.insert(path2); - return result; - } + case path_parameter::path: { + fs::path path = detail::generic_to_path(parameter.value); - // Search in each of the include path locations. - unsigned count = 0; - BOOST_FOREACH(fs::path full, include_path) - { - ++count; - full /= path; - - if (state.dependencies.add_dependency(full)) - { - result.insert(quickbook_path(full, count, path)); - return result; - } - } + // If the path is relative, try and resolve it. + if (!path.has_root_directory() && !path.has_root_name()) { + quickbook_path path2 = + state.current_path.parent_path() / parameter.value; + + // See if it can be found locally first. + if (state.dependencies.add_dependency(path2.file_path)) { + result.insert(path2); + return result; } - else - { - if (state.dependencies.add_dependency(path)) { - result.insert(quickbook_path(path, 0, path)); + + // Search in each of the include path locations. + unsigned count = 0; + BOOST_FOREACH (fs::path full, include_path) { + ++count; + full /= path; + + if (state.dependencies.add_dependency(full)) { + result.insert(quickbook_path(full, count, path)); return result; } } + } + else { + if (state.dependencies.add_dependency(path)) { + result.insert(quickbook_path(path, 0, path)); + return result; + } + } - detail::outerr(state.current_file, pos) - << "Unable to find file: " - << parameter.value - << std::endl; - ++state.error_count; + detail::outerr(state.current_file, pos) + << "Unable to find file: " << parameter.value << std::endl; + ++state.error_count; - return result; - } + return result; + } - case path_parameter::invalid: - return result; + case path_parameter::invalid: + return result; - default: - assert(0); - return result; + default: + assert(0); + return result; } } @@ -287,7 +271,8 @@ namespace quickbook // quickbook_path // - void swap(quickbook_path& x, quickbook_path& y) { + void swap(quickbook_path& x, quickbook_path& y) + { boost::swap(x.file_path, y.file_path); boost::swap(x.include_path_offset, y.include_path_offset); boost::swap(x.abstract_file_path, y.abstract_file_path); @@ -295,12 +280,11 @@ namespace quickbook bool quickbook_path::operator<(quickbook_path const& other) const { - return - abstract_file_path != other.abstract_file_path ? - abstract_file_path < other.abstract_file_path : - include_path_offset != other.include_path_offset ? - include_path_offset < other.include_path_offset : - file_path < other.file_path; + return abstract_file_path != other.abstract_file_path + ? abstract_file_path < other.abstract_file_path + : include_path_offset != other.include_path_offset + ? include_path_offset < other.include_path_offset + : file_path < other.file_path; } quickbook_path quickbook_path::operator/(quickbook::string_view x) const @@ -318,17 +302,19 @@ namespace quickbook quickbook_path quickbook_path::parent_path() const { - return quickbook_path(file_path.parent_path(), include_path_offset, - abstract_file_path.parent_path()); + return quickbook_path( + file_path.parent_path(), include_path_offset, + abstract_file_path.parent_path()); } - quickbook_path resolve_xinclude_path(std::string const& x, quickbook::state& state, bool is_file) { + quickbook_path resolve_xinclude_path( + std::string const& x, quickbook::state& state, bool is_file) + { fs::path path = detail::generic_to_path(x); fs::path full_path = path; // If the path is relative - if (!path.has_root_directory()) - { + if (!path.has_root_directory()) { // Resolve the path from the current file full_path = state.current_file->path.parent_path() / path; diff --git a/tools/quickbook/src/include_paths.hpp b/tools/quickbook/src/include_paths.hpp index 20c39c5e3c..a986ed1e26 100644 --- a/tools/quickbook/src/include_paths.hpp +++ b/tools/quickbook/src/include_paths.hpp @@ -15,23 +15,31 @@ // Classes and functions for dealing with the values from include, import and // xinclude elements. -#include "fwd.hpp" -#include "values.hpp" #include #include #include +#include "fwd.hpp" +#include "values.hpp" namespace quickbook { - struct path_parameter { + struct path_parameter + { // Will possibly add 'url' to this list later: - enum path_type { invalid, path, glob }; + enum path_type + { + invalid, + path, + glob + }; std::string value; path_type type; - path_parameter(std::string const& value_, path_type type_) : - value(value_), type(type_) {} + path_parameter(std::string const& value_, path_type type_) + : value(value_), type(type_) + { + } }; path_parameter check_path(value const& path, quickbook::state& state); @@ -40,7 +48,9 @@ namespace quickbook struct quickbook_path { quickbook_path(fs::path const& x, unsigned offset, fs::path const& y) - : file_path(x), include_path_offset(offset), abstract_file_path(y) {} + : file_path(x), include_path_offset(offset), abstract_file_path(y) + { + } friend void swap(quickbook_path&, quickbook_path&); @@ -62,10 +72,11 @@ namespace quickbook fs::path abstract_file_path; }; - std::set include_search(path_parameter const&, - quickbook::state& state, string_iterator pos); + std::set include_search( + path_parameter const&, quickbook::state& state, string_iterator pos); - quickbook_path resolve_xinclude_path(std::string const&, quickbook::state&, bool is_file = false); + quickbook_path resolve_xinclude_path( + std::string const&, quickbook::state&, bool is_file = false); } #endif diff --git a/tools/quickbook/src/iterator.hpp b/tools/quickbook/src/iterator.hpp index 9b138e4248..9cdeeb7d29 100644 --- a/tools/quickbook/src/iterator.hpp +++ b/tools/quickbook/src/iterator.hpp @@ -9,10 +9,10 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_ITERATOR_HPP) #define BOOST_SPIRIT_QUICKBOOK_ITERATOR_HPP -#include +#include #include +#include #include -#include #include "string_view.hpp" namespace quickbook @@ -20,38 +20,33 @@ namespace quickbook template struct lookback_iterator : boost::forward_iterator_helper< - lookback_iterator, - typename boost::iterator_value::type, - typename boost::iterator_difference::type, - typename boost::iterator_pointer::type, - typename boost::iterator_reference::type - > + lookback_iterator, + typename boost::iterator_value::type, + typename boost::iterator_difference::type, + typename boost::iterator_pointer::type, + typename boost::iterator_reference::type> { lookback_iterator() {} - explicit lookback_iterator(Iterator i) - : original_(i), base_(i) {} - + explicit lookback_iterator(Iterator i) : original_(i), base_(i) {} + friend bool operator==( - lookback_iterator const& x, - lookback_iterator const& y) + lookback_iterator const& x, lookback_iterator const& y) { return x.base_ == y.base_; } - + lookback_iterator& operator++() { ++base_; return *this; } - + typename boost::iterator_reference::type operator*() const { return *base_; } - - Iterator base() const { - return base_; - } + + Iterator base() const { return base_; } typedef boost::iterator_range > lookback_range; @@ -60,8 +55,8 @@ namespace quickbook { return lookback_range(base_, original_); } - - private: + + private: Iterator original_; Iterator base_; }; diff --git a/tools/quickbook/src/main_grammar.cpp b/tools/quickbook/src/main_grammar.cpp index 4da18e12a2..a7835297fd 100644 --- a/tools/quickbook/src/main_grammar.cpp +++ b/tools/quickbook/src/main_grammar.cpp @@ -8,38 +8,40 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "grammar_impl.hpp" -#include "state.hpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "actions.hpp" -#include "utils.hpp" -#include "template_tags.hpp" #include "block_tags.hpp" -#include "phrase_tags.hpp" +#include "grammar_impl.hpp" #include "parsers.hpp" +#include "phrase_tags.hpp" #include "scoped.hpp" +#include "state.hpp" #include "stream.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "template_tags.hpp" +#include "utils.hpp" namespace quickbook { namespace cl = boost::spirit::classic; - struct list_stack_item { + struct list_stack_item + { // Is this the root of the context // (e.g. top, template, table cell etc.) - enum list_item_type { - syntactic_list, // In a list marked up '*' or '#' - top_level, // At the top level of a parse - // (might be a template body) - nested_block // Nested in a block element. + enum list_item_type + { + syntactic_list, // In a list marked up '*' or '#' + top_level, // At the top level of a parse + // (might be a template body) + nested_block // Nested in a block element. } type; unsigned int indent; // Indent of list marker @@ -51,20 +53,31 @@ namespace quickbook // // |indent // * List item - // |indent2 - - explicit list_stack_item(list_item_type r) : - type(r), indent(0), indent2(0), mark('\0') {} + // |indent2 - explicit list_stack_item(char mark_, unsigned int indent_, unsigned int indent2_) : - type(syntactic_list), indent(indent_), indent2(indent2_), mark(mark_) - {} + explicit list_stack_item(list_item_type r) + : type(r), indent(0), indent2(0), mark('\0') + { + } + explicit list_stack_item( + char mark_, unsigned int indent_, unsigned int indent2_) + : type(syntactic_list) + , indent(indent_) + , indent2(indent2_) + , mark(mark_) + { + } }; - struct block_types { - enum values { - none, code, list, paragraph + struct block_types + { + enum values + { + none, + code, + list, + paragraph }; }; @@ -74,39 +87,34 @@ namespace quickbook // Local actions void start_blocks_impl(parse_iterator first, parse_iterator last); - void start_nested_blocks_impl(parse_iterator first, parse_iterator last); + void start_nested_blocks_impl( + parse_iterator first, parse_iterator last); void end_blocks_impl(parse_iterator first, parse_iterator last); void check_indentation_impl(parse_iterator first, parse_iterator last); void check_code_block_impl(parse_iterator first, parse_iterator last); void plain_block(string_iterator first, string_iterator last); - void list_block(string_iterator first, string_iterator mark_pos, - string_iterator last); + void list_block( + string_iterator first, + string_iterator mark_pos, + string_iterator last); void clear_stack(); //////////////////////////////////////////////////////////////////////// // Local members - cl::rule - template_phrase, top_level, indent_check, - paragraph_separator, inside_paragraph, - code, code_line, blank_line, hr, - inline_code, skip_inline_code, - template_, attribute_template, template_body, - code_block, skip_code_block, macro, - template_args, - template_args_1_4, template_arg_1_4, - template_inner_arg_1_4, brackets_1_4, - template_args_1_5, template_arg_1_5, template_arg_1_5_content, - template_inner_arg_1_5, brackets_1_5, - template_args_1_6, template_arg_1_6, template_arg_1_6_content, - break_, - command_line_macro_identifier, - dummy_block, line_dummy_block, square_brackets, error_brackets, - skip_escape - ; - - struct block_context_closure : cl::closure + cl::rule template_phrase, top_level, indent_check, + paragraph_separator, inside_paragraph, code, code_line, blank_line, + hr, inline_code, skip_inline_code, template_, attribute_template, + template_body, code_block, skip_code_block, macro, template_args, + template_args_1_4, template_arg_1_4, template_inner_arg_1_4, + brackets_1_4, template_args_1_5, template_arg_1_5, + template_arg_1_5_content, template_inner_arg_1_5, brackets_1_5, + template_args_1_6, template_arg_1_6, template_arg_1_6_content, + break_, command_line_macro_identifier, dummy_block, + line_dummy_block, square_brackets, error_brackets, skip_escape; + + struct block_context_closure + : cl::closure { // Mask used to determine whether or not an element is a block // element. @@ -117,7 +125,8 @@ namespace quickbook cl::rule paragraph; cl::rule list; - cl::rule syntactic_block_item; + cl::rule + syntactic_block_item; cl::rule common; cl::rule element; @@ -126,7 +135,7 @@ namespace quickbook unsigned int list_indent; bool no_eols; element_info::context context; - char mark; // Simple markup's deliminator + char mark; // Simple markup's deliminator bool still_in_block; // Inside a syntatic block // transitory state @@ -147,22 +156,24 @@ namespace quickbook , context(element_info::in_top_level) , mark('\0') , state_(state) - {} + { + } }; - struct process_element_impl : scoped_action_base { - process_element_impl(main_grammar_local& l_) : - l(l_), pushed_source_mode_(false), element_context_error_(false) {} + struct process_element_impl : scoped_action_base + { + process_element_impl(main_grammar_local& l_) + : l(l_), pushed_source_mode_(false), element_context_error_(false) + { + } bool start() { // This element doesn't exist in the current language version. - if (qbk_version_n < l.info.qbk_version) - return false; + if (qbk_version_n < l.info.qbk_version) return false; // The element is not allowed in this context. - if (!(l.info.type & l.context)) - { + if (!(l.info.type & l.context)) { if (qbk_version_n < 107u) { return false; } @@ -174,8 +185,7 @@ namespace quickbook info_ = l.info; if (info_.type != element_info::phrase && - info_.type != element_info::maybe_block) - { + info_.type != element_info::maybe_block) { paragraph_action para(l.state_); para(); } @@ -183,8 +193,7 @@ namespace quickbook assert(l.state_.values.builder.empty()); if (l.state_.source_mode_next && - info_.type != element_info::maybe_block) - { + info_.type != element_info::maybe_block) { l.state_.push_tagged_source_mode(l.state_.source_mode_next); pushed_source_mode_ = true; l.state_.source_mode_next = 0; @@ -197,16 +206,16 @@ namespace quickbook bool result(ResultT r, ScannerT const& scan) { if (element_context_error_) { - error_message_action error(l.state_, - "Element not allowed in this context."); + error_message_action error( + l.state_, "Element not allowed in this context."); error(scan.first, scan.first); return true; } else if (r) { return true; } - else if (qbk_version_n < 107u && - info_.type & element_info::in_phrase) { + else if ( + qbk_version_n < 107u && info_.type & element_info::in_phrase) { // Old versions of quickbook had a soft fail // for unparsed phrase elements. return false; @@ -219,12 +228,15 @@ namespace quickbook } } - void success(parse_iterator, parse_iterator) { l.element_type = info_.type; } + void success(parse_iterator, parse_iterator) + { + l.element_type = info_.type; + } void failure() { l.element_type = element_info::nothing; } - void cleanup() { - if (pushed_source_mode_) - l.state_.pop_tagged_source_mode(); + void cleanup() + { + if (pushed_source_mode_) l.state_.pop_tagged_source_mode(); } main_grammar_local& l; @@ -235,17 +247,21 @@ namespace quickbook struct scoped_paragraph : scoped_action_base { - scoped_paragraph(quickbook::state& state_) : - state(state_), pushed(false) {} + scoped_paragraph(quickbook::state& state_) + : state(state_), pushed(false) + { + } - bool start() { + bool start() + { state.push_tagged_source_mode(state.source_mode_next); pushed = true; state.source_mode_next = 0; return true; } - void cleanup() { + void cleanup() + { if (pushed) state.pop_tagged_source_mode(); } @@ -253,15 +269,16 @@ namespace quickbook bool pushed; }; - struct in_list_impl { + struct in_list_impl + { main_grammar_local& l; - explicit in_list_impl(main_grammar_local& l_) : - l(l_) {} + explicit in_list_impl(main_grammar_local& l_) : l(l_) {} - bool operator()() const { + bool operator()() const + { return !l.list_stack.empty() && - l.list_stack.top().type == list_stack_item::syntactic_list; + l.list_stack.top().type == list_stack_item::syntactic_list; } }; @@ -271,18 +288,19 @@ namespace quickbook typedef M T::*member_ptr; explicit set_scoped_value_impl(T& l_, member_ptr ptr_) - : l(l_), ptr(ptr_), saved_value() {} + : l(l_), ptr(ptr_), saved_value() + { + } - bool start(M const& value) { + bool start(M const& value) + { saved_value = l.*ptr; l.*ptr = value; return true; } - void cleanup() { - l.*ptr = saved_value; - } + void cleanup() { l.*ptr = saved_value; } T& l; member_ptr ptr; @@ -294,8 +312,10 @@ namespace quickbook { typedef set_scoped_value_impl impl; - set_scoped_value(T& l, typename impl::member_ptr ptr) : - scoped_parser(impl(l, ptr)) {} + set_scoped_value(T& l, typename impl::member_ptr ptr) + : scoped_parser(impl(l, ptr)) + { + } }; //////////////////////////////////////////////////////////////////////////// @@ -303,8 +323,7 @@ namespace quickbook void quickbook_grammar::impl::init_main() { - main_grammar_local& local = cleanup_.add( - new main_grammar_local(state)); + main_grammar_local& local = cleanup_.add(new main_grammar_local(state)); // Global Actions quickbook::element_action element_action(state); @@ -333,22 +352,24 @@ namespace quickbook in_list_impl in_list(local); set_scoped_value scoped_no_eols( - local, &main_grammar_local::no_eols); - set_scoped_value scoped_context( - local, &main_grammar_local::context); + local, &main_grammar_local::no_eols); + set_scoped_value + scoped_context(local, &main_grammar_local::context); set_scoped_value scoped_still_in_block( - local, &main_grammar_local::still_in_block); - - member_action check_indentation(local, - &main_grammar_local::check_indentation_impl); - member_action check_code_block(local, - &main_grammar_local::check_code_block_impl); - member_action start_blocks(local, - &main_grammar_local::start_blocks_impl); - member_action start_nested_blocks(local, - &main_grammar_local::start_nested_blocks_impl); - member_action end_blocks(local, - &main_grammar_local::end_blocks_impl); + local, &main_grammar_local::still_in_block); + + member_action check_indentation( + local, &main_grammar_local::check_indentation_impl); + member_action check_code_block( + local, &main_grammar_local::check_code_block_impl); + member_action start_blocks( + local, &main_grammar_local::start_blocks_impl); + member_action start_nested_blocks( + local, &main_grammar_local::start_nested_blocks_impl); + member_action end_blocks( + local, &main_grammar_local::end_blocks_impl); + + // clang-format off // phrase/phrase_start is used for an entirely self-contained // phrase. For example, any remaining anchors are written out @@ -1087,17 +1108,17 @@ namespace quickbook | qbk_ver(0, 106u) >> +(cl::anychar_p - (cl::space_p | ']')) ; + + // clang-format on } //////////////////////////////////////////////////////////////////////////// // Indentation Handling - template - int indent_length(Iterator first, Iterator end) + template int indent_length(Iterator first, Iterator end) { int length = 0; - for(; first != end; ++first) - { + for (; first != end; ++first) { if (*first == '\t') { // hardcoded tab to 4 for now length = length + 4 - (length % 4); @@ -1115,7 +1136,8 @@ namespace quickbook list_stack.push(list_stack_item(list_stack_item::top_level)); } - void main_grammar_local::start_nested_blocks_impl(parse_iterator, parse_iterator) + void main_grammar_local::start_nested_blocks_impl( + parse_iterator, parse_iterator) { // If this nested block is part of a list, then tell the // output state. @@ -1131,13 +1153,13 @@ namespace quickbook list_stack.pop(); } - void main_grammar_local::check_indentation_impl(parse_iterator first_, parse_iterator last_) + void main_grammar_local::check_indentation_impl( + parse_iterator first_, parse_iterator last_) { string_iterator first = first_.base(); string_iterator last = last_.base(); string_iterator mark_pos = boost::find_first_of( - boost::make_iterator_range(first, last), - boost::as_literal("#*")); + boost::make_iterator_range(first, last), boost::as_literal("#*")); if (mark_pos == last) { plain_block(first, last); @@ -1147,15 +1169,18 @@ namespace quickbook } } - void main_grammar_local::check_code_block_impl(parse_iterator first, parse_iterator last) + void main_grammar_local::check_code_block_impl( + parse_iterator first, parse_iterator last) { unsigned int new_indent = indent_length(first.base(), last.base()); - block_type = (new_indent > list_stack.top().indent2) ? - block_types::code : block_types::none; + block_type = (new_indent > list_stack.top().indent2) + ? block_types::code + : block_types::none; } - void main_grammar_local::plain_block(string_iterator first, string_iterator last) + void main_grammar_local::plain_block( + string_iterator first, string_iterator last) { if (qbk_version_n >= 106u) { unsigned int new_indent = indent_length(first, last); @@ -1169,18 +1194,17 @@ namespace quickbook } } else { - while (list_stack.top().type == list_stack_item::syntactic_list - && new_indent < list_stack.top().indent) - { + while (list_stack.top().type == + list_stack_item::syntactic_list && + new_indent < list_stack.top().indent) { state_.end_list_item(); state_.end_list(list_stack.top().mark); list_stack.pop(); list_indent = list_stack.top().indent; } - if (list_stack.top().type == list_stack_item::syntactic_list - && new_indent == list_stack.top().indent) - { + if (list_stack.top().type == list_stack_item::syntactic_list && + new_indent == list_stack.top().indent) { // If the paragraph is aligned with the list item's marker, // then end the current list item if that's aligned (or to // the left of) the parent's paragraph. @@ -1198,13 +1222,14 @@ namespace quickbook // * Level 2 // // Back to Level 1 - + list_stack_item save = list_stack.top(); list_stack.pop(); - assert(list_stack.top().type != list_stack_item::syntactic_list ? - new_indent >= list_stack.top().indent : - new_indent > list_stack.top().indent); + assert( + list_stack.top().type != list_stack_item::syntactic_list + ? new_indent >= list_stack.top().indent + : new_indent > list_stack.top().indent); if (new_indent <= list_stack.top().indent2) { state_.end_list_item(); @@ -1220,7 +1245,7 @@ namespace quickbook } if (qbk_version_n == 106u && - list_stack.top().type == list_stack_item::syntactic_list) { + list_stack.top().type == list_stack_item::syntactic_list) { detail::outerr(state_.current_file, first) << "Paragraphs in lists aren't supported in quickbook 1.6." << std::endl; @@ -1231,29 +1256,30 @@ namespace quickbook clear_stack(); if (list_stack.top().type != list_stack_item::nested_block && - last != first) + last != first) block_type = block_types::code; else block_type = block_types::paragraph; } } - void main_grammar_local::list_block(string_iterator first, string_iterator mark_pos, - string_iterator last) + void main_grammar_local::list_block( + string_iterator first, string_iterator mark_pos, string_iterator last) { unsigned int new_indent = indent_length(first, mark_pos); unsigned int new_indent2 = indent_length(first, last); char list_mark = *mark_pos; if (list_stack.top().type == list_stack_item::top_level && - new_indent > 0) { + new_indent > 0) { block_type = block_types::code; return; } if (list_stack.top().type != list_stack_item::syntactic_list || - new_indent > list_indent) { - list_stack.push(list_stack_item(list_mark, new_indent, new_indent2)); + new_indent > list_indent) { + list_stack.push( + list_stack_item(list_mark, new_indent, new_indent2)); state_.start_list(list_mark); } else if (new_indent == list_indent) { @@ -1262,9 +1288,8 @@ namespace quickbook else { // This should never reach root, since the first list // has indentation 0. - while(list_stack.top().type == list_stack_item::syntactic_list && - new_indent < list_stack.top().indent) - { + while (list_stack.top().type == list_stack_item::syntactic_list && + new_indent < list_stack.top().indent) { state_.end_list_item(); state_.end_list(list_stack.top().mark); list_stack.pop(); @@ -1275,8 +1300,7 @@ namespace quickbook list_indent = new_indent; - if (list_mark != list_stack.top().mark) - { + if (list_mark != list_stack.top().mark) { detail::outerr(state_.current_file, first) << "Illegal change of list style.\n"; detail::outwarn(state_.current_file, first) diff --git a/tools/quickbook/src/markups.cpp b/tools/quickbook/src/markups.cpp index f077943a0f..df8cd3c6ca 100644 --- a/tools/quickbook/src/markups.cpp +++ b/tools/quickbook/src/markups.cpp @@ -8,13 +8,13 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "quickbook.hpp" #include "markups.hpp" +#include +#include +#include #include "block_tags.hpp" #include "phrase_tags.hpp" -#include -#include -#include +#include "quickbook.hpp" namespace quickbook { @@ -25,55 +25,59 @@ namespace quickbook void initialise_markups() { markup init_markups[] = { - { block_tags::paragraph, "\n", "\n" }, - { block_tags::paragraph_in_list, "\n", "\n" }, - { block_tags::blurb, "\n", "\n" }, - { block_tags::blockquote, "
", "
" }, - { block_tags::preformatted, "", "" }, - { block_tags::warning, "", "" }, - { block_tags::caution, "", "" }, - { block_tags::important, "", "" }, - { block_tags::note, "", "" }, - { block_tags::tip, "", "" }, - { block_tags::block, "", "" }, - { block_tags::ordered_list, "", "" }, - { block_tags::itemized_list, "", "" }, - { block_tags::hr, "", 0 }, - { phrase_tags::url, "" }, - { phrase_tags::link, "" }, - { phrase_tags::funcref, "" }, - { phrase_tags::classref, "" }, - { phrase_tags::memberref, "" }, - { phrase_tags::enumref, "" }, - { phrase_tags::macroref, "" }, - { phrase_tags::headerref, "" }, - { phrase_tags::conceptref, "" }, - { phrase_tags::globalref, "" }, - { phrase_tags::bold, "", "" }, - { phrase_tags::italic, "", "" }, - { phrase_tags::underline, "", "" }, - { phrase_tags::teletype, "", "" }, - { phrase_tags::strikethrough, "", "" }, - { phrase_tags::quote, "", "" }, - { phrase_tags::replaceable, "", "" }, - { phrase_tags::escape, "", "" }, - { phrase_tags::break_mark, "\n", 0 } - }; + {block_tags::paragraph, "\n", "\n"}, + {block_tags::paragraph_in_list, "\n", "\n"}, + {block_tags::blurb, "\n", + "\n"}, + {block_tags::blockquote, "
", "
"}, + {block_tags::preformatted, "", + ""}, + {block_tags::warning, "", ""}, + {block_tags::caution, "", ""}, + {block_tags::important, "", ""}, + {block_tags::note, "", ""}, + {block_tags::tip, "", ""}, + {block_tags::block, "", ""}, + {block_tags::ordered_list, "", ""}, + {block_tags::itemized_list, "", + ""}, + {block_tags::hr, "", 0}, + {phrase_tags::url, ""}, + {phrase_tags::link, ""}, + {phrase_tags::funcref, ""}, + {phrase_tags::classref, ""}, + {phrase_tags::memberref, ""}, + {phrase_tags::enumref, ""}, + {phrase_tags::macroref, ""}, + {phrase_tags::headerref, ""}, + {phrase_tags::conceptref, ""}, + {phrase_tags::globalref, ""}, + {phrase_tags::bold, "", ""}, + {phrase_tags::italic, "", ""}, + {phrase_tags::underline, "", + ""}, + {phrase_tags::teletype, "", ""}, + {phrase_tags::strikethrough, + "", ""}, + {phrase_tags::quote, "", ""}, + {phrase_tags::replaceable, "", ""}, + {phrase_tags::escape, "", + ""}, + {phrase_tags::break_mark, "\n", 0}}; - BOOST_FOREACH(markup m, init_markups) - { + BOOST_FOREACH (markup m, init_markups) { markups[m.tag] = m; } } - markup const& get_markup(value::tag_type t) - { - return markups[t]; - } + markup const& get_markup(value::tag_type t) { return markups[t]; } std::ostream& operator<<(std::ostream& out, markup const& m) { - return out<<"{"< -#include #include "native_text.hpp" +#include +#include #include "utils.hpp" #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS -#include #include +#include #endif -namespace quickbook { -namespace detail { +namespace quickbook +{ + namespace detail + { // This is used for converting paths to UTF-8 on cygin. -// Might be better not to use a windows +// Might be better not to use a windows #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS - std::string to_utf8(std::wstring const& x) - { - int buffer_count = WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0); - - if (!buffer_count) - throw conversion_error("Error converting wide string to utf-8."); + std::string to_utf8(std::wstring const& x) + { + int buffer_count = + WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, 0, 0, 0, 0); - boost::scoped_ptr buffer(new char[buffer_count]); + if (!buffer_count) + throw conversion_error( + "Error converting wide string to utf-8."); - if (!WideCharToMultiByte(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, 0)) - throw conversion_error("Error converting wide string to utf-8."); - - return std::string(buffer.get()); - } + boost::scoped_array buffer(new char[buffer_count]); - std::wstring from_utf8(quickbook::string_view text) - { - std::string x(text.begin(), text.end()); - int buffer_count = MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0); - - if (!buffer_count) - throw conversion_error("Error converting utf-8 to wide string."); + if (!WideCharToMultiByte( + CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count, 0, + 0)) + throw conversion_error( + "Error converting wide string to utf-8."); - boost::scoped_ptr buffer(new wchar_t[buffer_count]); + return std::string(buffer.get()); + } - if (!MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count)) - throw conversion_error("Error converting utf-8 to wide string."); + std::wstring from_utf8(quickbook::string_view text) + { + std::string x(text.begin(), text.end()); + int buffer_count = + MultiByteToWideChar(CP_UTF8, 0, x.c_str(), -1, 0, 0); - return std::wstring(buffer.get()); - } + if (!buffer_count) + throw conversion_error( + "Error converting utf-8 to wide string."); + + boost::scoped_array buffer(new wchar_t[buffer_count]); + + if (!MultiByteToWideChar( + CP_UTF8, 0, x.c_str(), -1, buffer.get(), buffer_count)) + throw conversion_error( + "Error converting utf-8 to wide string."); + + return std::wstring(buffer.get()); + } #endif -}} + } +} diff --git a/tools/quickbook/src/native_text.hpp b/tools/quickbook/src/native_text.hpp index e138c3a6e3..33047e4a21 100644 --- a/tools/quickbook/src/native_text.hpp +++ b/tools/quickbook/src/native_text.hpp @@ -11,22 +11,22 @@ #if !defined(BOOST_QUICKBOOK_DETAIL_NATIVE_TEXT_HPP) #define BOOST_QUICKBOOK_DETAIL_NATIVE_TEXT_HPP -#include -#include #include -#include "string_view.hpp" +#include +#include #include "fwd.hpp" +#include "string_view.hpp" #if defined(__cygwin__) || defined(__CYGWIN__) -# define QUICKBOOK_CYGWIN_PATHS 1 +#define QUICKBOOK_CYGWIN_PATHS 1 #elif defined(_WIN32) -# define QUICKBOOK_WIDE_PATHS 1 - // Wide streams work okay for me with older versions of Visual C++, - // but I've had reports of problems. My guess is that it's an - // incompatibility with later versions of windows. -# if defined(BOOST_MSVC) && BOOST_MSVC >= 1700 -# define QUICKBOOK_WIDE_STREAMS 1 -# endif +#define QUICKBOOK_WIDE_PATHS 1 +// Wide streams work okay for me with older versions of Visual C++, +// but I've had reports of problems. My guess is that it's an +// incompatibility with later versions of windows. +#if defined(BOOST_MSVC) && BOOST_MSVC >= 1700 +#define QUICKBOOK_WIDE_STREAMS 1 +#endif #endif #if !defined(QUICKBOOK_WIDE_PATHS) diff --git a/tools/quickbook/src/parsers.hpp b/tools/quickbook/src/parsers.hpp index 1c785d4b90..ac15d6471c 100644 --- a/tools/quickbook/src/parsers.hpp +++ b/tools/quickbook/src/parsers.hpp @@ -8,21 +8,22 @@ =============================================================================*/ // Some custom parsers for use in quickbook. - + #ifndef BOOST_QUICKBOOK_PARSERS_HPP #define BOOST_QUICKBOOK_PARSERS_HPP #include #include +#include #include #include -#include #include "fwd.hpp" #include "iterator.hpp" -namespace quickbook { +namespace quickbook +{ namespace cl = boost::spirit::classic; - + /////////////////////////////////////////////////////////////////////////// // // scoped_parser @@ -38,53 +39,57 @@ namespace quickbook { template struct scoped_parser_impl - : public cl::unary< ParserT, cl::parser< scoped_parser_impl > > + : public cl::unary< + ParserT, + cl::parser > > { typedef scoped_parser_impl self_t; - typedef cl::unary< ParserT, cl::parser< scoped_parser_impl > > base_t; + typedef cl::unary< + ParserT, + cl::parser > > + base_t; - template - struct result { typedef cl::match<> type; }; + template struct result + { + typedef cl::match<> type; + }; scoped_parser_impl( - Impl const& impl, - Arguments const& arguments, - ParserT const &p) - : base_t(p) - , impl_(impl) - , arguments_(arguments) - {} + Impl const& impl, Arguments const& arguments, ParserT const& p) + : base_t(p), impl_(impl), arguments_(arguments) + { + } struct scoped { - explicit scoped(Impl const& impl) - : impl_(impl) - , in_progress_(false) - {} - + explicit scoped(Impl const& impl) : impl_(impl), in_progress_(false) + { + } + typedef phoenix::tuple_index<0> t0; typedef phoenix::tuple_index<1> t1; - + bool start(phoenix::tuple<> const&) { in_progress_ = impl_.start(); return in_progress_; } - - template - bool start(phoenix::tuple const& x) + + template bool start(phoenix::tuple const& x) { - in_progress_ = phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()])(); + in_progress_ = + phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()])(); return in_progress_; } template bool start(phoenix::tuple const& x) { - in_progress_ = phoenix::bind(&Impl::start)(phoenix::var(impl_), x[t0()], x[t1()])(); + in_progress_ = phoenix::bind(&Impl::start)( + phoenix::var(impl_), x[t0()], x[t1()])(); return in_progress_; } - + void success(parse_iterator f, parse_iterator l) { in_progress_ = false; @@ -102,23 +107,22 @@ namespace quickbook { if (in_progress_) impl_.failure(); impl_.cleanup(); } - + Impl impl_; bool in_progress_; }; - + template - typename result::type parse(ScannerT const &scan) const + typename result::type parse(ScannerT const& scan) const { typedef typename ScannerT::iterator_t iterator_t; iterator_t save = scan.first; scoped scope(impl_); - if (!scope.start(arguments_)) - return scan.no_match(); + if (!scope.start(arguments_)) return scan.no_match(); - typename cl::parser_result::type r - = this->subject().parse(scan); + typename cl::parser_result::type r = + this->subject().parse(scan); bool success = scope.impl_.result(r, scan); @@ -126,10 +130,13 @@ namespace quickbook { scope.success(save, scan.first); if (r) { - return scan.create_match(r.length(), cl::nil_t(), save, scan.first); + return scan.create_match( + r.length(), cl::nil_t(), save, scan.first); } else { - return scan.create_match(scan.first.base() - save.base(), cl::nil_t(), save, scan.first); + return scan.create_match( + scan.first.base() - save.base(), cl::nil_t(), save, + scan.first); } } else { @@ -137,61 +144,56 @@ namespace quickbook { return scan.no_match(); } } - + Impl impl_; Arguments arguments_; }; - template - struct scoped_parser_gen - { + template struct scoped_parser_gen + { explicit scoped_parser_gen(Impl impl, Arguments const& arguments) - : impl_(impl), arguments_(arguments) {} + : impl_(impl), arguments_(arguments) + { + } - template - scoped_parser_impl - < + template + scoped_parser_impl< Impl, Arguments, - typename cl::as_parser::type - > - operator[](ParserT const &p) const + typename cl::as_parser::type> + operator[](ParserT const& p) const { typedef cl::as_parser as_parser_t; typedef typename as_parser_t::type parser_t; - return scoped_parser_impl - (impl_, arguments_, p); + return scoped_parser_impl( + impl_, arguments_, p); } Impl impl_; Arguments arguments_; }; - template - struct scoped_parser + template struct scoped_parser { - scoped_parser(Impl const& impl) - : impl_(impl) {} - - scoped_parser_gen > - operator()() const + scoped_parser(Impl const& impl) : impl_(impl) {} + + scoped_parser_gen > operator()() const { typedef phoenix::tuple<> tuple; return scoped_parser_gen(impl_, tuple()); } template - scoped_parser_gen > - operator()(Arg1 x1) const + scoped_parser_gen > operator()(Arg1 x1) const { typedef phoenix::tuple tuple; return scoped_parser_gen(impl_, tuple(x1)); } - + template - scoped_parser_gen > - operator()(Arg1 x1, Arg2 x2) const + scoped_parser_gen > operator()( + Arg1 x1, Arg2 x2) const { typedef phoenix::tuple tuple; return scoped_parser_gen(impl_, tuple(x1, x2)); @@ -199,7 +201,7 @@ namespace quickbook { Impl impl_; - private: + private: scoped_parser& operator=(scoped_parser const&); }; @@ -216,37 +218,37 @@ namespace quickbook { template struct lookback_parser - : public cl::unary< ParserT, cl::parser< lookback_parser > > + : public cl::unary > > { typedef lookback_parser self_t; - typedef cl::unary< ParserT, cl::parser< lookback_parser > > base_t; + typedef cl::unary > > + base_t; - template - struct result + template struct result { typedef typename cl::parser_result::type type; }; - lookback_parser(ParserT const& p) - : base_t(p) - {} + lookback_parser(ParserT const& p) : base_t(p) {} template - typename result::type parse(ScannerT const &scan) const + typename result::type parse(ScannerT const& scan) const { - typedef typename ScannerT::iterator_t::lookback_range::iterator iterator_t; - typedef cl::scanner scanner_t; + typedef typename ScannerT::iterator_t::lookback_range::iterator + iterator_t; + typedef cl::scanner + scanner_t; iterator_t begin = scan.first.lookback().begin(); scanner_t lookback_scan(begin, scan.first.lookback().end(), scan); - + if (this->subject().parse(lookback_scan)) return scan.empty_match(); else return scan.no_match(); } }; - + struct lookback_gen { template @@ -255,9 +257,9 @@ namespace quickbook { return lookback_parser(p); } }; - + lookback_gen const lookback = lookback_gen(); - + /////////////////////////////////////////////////////////////////////////// // // UTF-8 code point @@ -273,8 +275,7 @@ namespace quickbook { { typedef u8_codepoint_parser self_t; - template - struct result + template struct result { typedef cl::match<> type; }; @@ -291,13 +292,13 @@ namespace quickbook { do { ++scan.first; } while (!scan.at_end() && - ((unsigned char) *scan.first & 0xc0) == 0x80); + ((unsigned char)*scan.first & 0xc0) == 0x80); - return scan.create_match(scan.first.base() - save.base(), - cl::nil_t(), save, scan.first); + return scan.create_match( + scan.first.base() - save.base(), cl::nil_t(), save, scan.first); } }; - + u8_codepoint_parser const u8_codepoint_p = u8_codepoint_parser(); } diff --git a/tools/quickbook/src/path.cpp b/tools/quickbook/src/path.cpp index b6b7ce639f..5abec4e615 100644 --- a/tools/quickbook/src/path.cpp +++ b/tools/quickbook/src/path.cpp @@ -10,18 +10,18 @@ =============================================================================*/ #include "path.hpp" +#include +#include +#include +#include #include "glob.hpp" #include "include_paths.hpp" #include "state.hpp" #include "utils.hpp" -#include -#include -#include -#include #if QUICKBOOK_CYGWIN_PATHS -#include #include +#include #endif namespace quickbook @@ -35,8 +35,7 @@ namespace quickbook std::vector parts; - BOOST_FOREACH(fs::path const& part, path) - { + BOOST_FOREACH (fs::path const& part, path) { if (part.empty() || part == ".") { } else if (part == "..") { @@ -51,42 +50,39 @@ namespace quickbook } // The relative path from base to path - fs::path path_difference(fs::path const& base, fs::path const& path, bool is_file) + fs::path path_difference( + fs::path const& base, fs::path const& path, bool is_file) { - fs::path - absolute_base = fs::absolute(base), - absolute_path = fs::absolute(path); + fs::path absolute_base = fs::absolute(base), + absolute_path = fs::absolute(path); // Remove '.', '..' and empty parts from the remaining path - std::vector - base_parts = remove_dots_from_path(absolute_base.relative_path()), - path_parts = remove_dots_from_path(absolute_path.relative_path()); + std::vector base_parts = remove_dots_from_path( + absolute_base.relative_path()), + path_parts = remove_dots_from_path( + absolute_path.relative_path()); - std::vector::iterator - base_it = base_parts.begin(), - base_end = base_parts.end(), - path_it = path_parts.begin(), - path_end = path_parts.end(); + std::vector::iterator base_it = base_parts.begin(), + base_end = base_parts.end(), + path_it = path_parts.begin(), + path_end = path_parts.end(); // Build up the two paths in these variables, checking for the first // difference. - fs::path - base_tmp = absolute_base.root_path(), - path_tmp = absolute_path.root_path(); + fs::path base_tmp = absolute_base.root_path(), + path_tmp = absolute_path.root_path(); fs::path result; // If they have different roots then there's no relative path so // just build an absolute path. - if (!fs::equivalent(base_tmp, path_tmp)) - { + if (!fs::equivalent(base_tmp, path_tmp)) { result = path_tmp; } - else - { + else { // Find the point at which the paths differ - for(; base_it != base_end && path_it != path_end; ++base_it, ++path_it) - { + for (; base_it != base_end && path_it != path_end; + ++base_it, ++path_it) { base_tmp /= *base_it; path_tmp /= *path_it; if (*base_it != *path_it) { @@ -97,19 +93,23 @@ namespace quickbook } } - if (is_file && path_it == path_end && path_it != path_parts.begin()) { + if (is_file && path_it == path_end && + path_it != path_parts.begin()) { --path_it; result = ".."; - } else if (base_it == base_end && path_it == path_end) { - result = "."; + } + else if (base_it == base_end && path_it == path_end) { + result = "."; } // Build a relative path to that point - for(; base_it != base_end; ++base_it) result /= ".."; + for (; base_it != base_end; ++base_it) + result /= ".."; } // Build the rest of our path - for(; path_it != path_end; ++path_it) result /= *path_it; + for (; path_it != path_end; ++path_it) + result /= *path_it; return result; } @@ -124,7 +124,9 @@ namespace quickbook std::string file_path_to_url_impl(fs::path const& x, bool is_dir) { fs::path::const_iterator it = x.begin(), end = x.end(); - if (it == end) { return is_dir ? "./" : ""; } + if (it == end) { + return is_dir ? "./" : ""; + } std::string result; bool sep = false; @@ -141,7 +143,8 @@ namespace quickbook sep = false; ++it; } - } else { + } + else { result = "file:///"; } @@ -149,35 +152,39 @@ namespace quickbook if (it != end) { part = detail::path_to_generic(*it); if (part.size() >= 2 && part[part.size() - 1] == ':') { - result += detail::escape_uri(part.substr(0, part.size()- 1)); + result += + detail::escape_uri(part.substr(0, part.size() - 1)); result += ':'; sep = false; ++it; } } - } else if (x.has_root_directory()) { + } + else if (x.has_root_directory()) { result = "file://"; sep = true; - } else if (*it == ".") { + } + else if (*it == ".") { result = "."; sep = true; ++it; } - for (;it != end; ++it) - { + for (; it != end; ++it) { part = detail::path_to_generic(*it); if (part == "/") { result += "/"; sep = false; - } else if (part == ".") { + } + else if (part == ".") { // If the path has a trailing slash, write it out, // even if is_dir is false. if (sep) { result += "/"; sep = false; } - } else { + } + else { if (sep) { result += "/"; } @@ -193,7 +200,8 @@ namespace quickbook return result; } - std::string file_path_to_url(fs::path const& x) { + std::string file_path_to_url(fs::path const& x) + { return file_path_to_url_impl(x, false); } @@ -202,7 +210,8 @@ namespace quickbook return file_path_to_url_impl(x, true); } - namespace detail { + namespace detail + { #if QUICKBOOK_WIDE_PATHS std::string command_line_to_utf8(command_line_string const& x) { @@ -245,13 +254,15 @@ namespace quickbook ssize_t size = cygwin_conv_path(flags, path.c_str(), NULL, 0); if (size < 0) - throw conversion_error("Error converting cygwin path to windows."); + throw conversion_error( + "Error converting cygwin path to windows."); boost::scoped_array result(new char[size]); void* ptr = result.get(); - if(cygwin_conv_path(flags, path.c_str(), ptr, size)) - throw conversion_error("Error converting cygwin path to windows."); + if (cygwin_conv_path(flags, path.c_str(), ptr, size)) + throw conversion_error( + "Error converting cygwin path to windows."); return fs::path(static_cast(ptr)); } @@ -260,15 +271,19 @@ namespace quickbook { cygwin_conv_path_t flags = CCP_WIN_W_TO_POSIX | CCP_RELATIVE; - ssize_t size = cygwin_conv_path(flags, path.native().c_str(), NULL, 0); + ssize_t size = + cygwin_conv_path(flags, path.native().c_str(), NULL, 0); if (size < 0) - throw conversion_error("Error converting windows path to cygwin."); + throw conversion_error( + "Error converting windows path to cygwin."); boost::scoped_array result(new char[size]); - if(cygwin_conv_path(flags, path.native().c_str(), result.get(), size)) - throw conversion_error("Error converting windows path to cygwin."); + if (cygwin_conv_path( + flags, path.native().c_str(), result.get(), size)) + throw conversion_error( + "Error converting windows path to cygwin."); return std::string(result.get()); } diff --git a/tools/quickbook/src/path.hpp b/tools/quickbook/src/path.hpp index acb22c123e..64771d4b4d 100644 --- a/tools/quickbook/src/path.hpp +++ b/tools/quickbook/src/path.hpp @@ -20,24 +20,26 @@ namespace quickbook namespace fs = boost::filesystem; // The relative path from base to path - fs::path path_difference(fs::path const& base, fs::path const& path, bool is_file = false); + fs::path path_difference( + fs::path const& base, fs::path const& path, bool is_file = false); // Convert a Boost.Filesystem path to a URL. std::string file_path_to_url(fs::path const&); std::string dir_path_to_url(fs::path const&); - namespace detail { - // 'generic': Paths in quickbook source and the generated boostbook. - // Always UTF-8. - // 'command_line': - // Paths (or other parameters) from the command line and - // possibly other sources in the future. Wide strings on - // normal windows, UTF-8 for cygwin and other platforms - // (hopefully). - // 'path': Stored as a boost::filesystem::path. Since - // Boost.Filesystem doesn't support cygwin, this - // is always wide on windows. UTF-8 on other - // platforms (again, hopefully). + namespace detail + { +// 'generic': Paths in quickbook source and the generated boostbook. +// Always UTF-8. +// 'command_line': +// Paths (or other parameters) from the command line and +// possibly other sources in the future. Wide strings on +// normal windows, UTF-8 for cygwin and other platforms +// (hopefully). +// 'path': Stored as a boost::filesystem::path. Since +// Boost.Filesystem doesn't support cygwin, this +// is always wide on windows. UTF-8 on other +// platforms (again, hopefully). #if QUICKBOOK_WIDE_PATHS typedef std::wstring command_line_string; diff --git a/tools/quickbook/src/phrase_element_grammar.cpp b/tools/quickbook/src/phrase_element_grammar.cpp index 39624d4a96..aa0b04ca16 100644 --- a/tools/quickbook/src/phrase_element_grammar.cpp +++ b/tools/quickbook/src/phrase_element_grammar.cpp @@ -8,18 +8,18 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "grammar_impl.hpp" -#include "state.hpp" -#include "actions.hpp" -#include "utils.hpp" -#include "phrase_tags.hpp" -#include +#include #include #include +#include #include -#include #include -#include +#include +#include "actions.hpp" +#include "grammar_impl.hpp" +#include "phrase_tags.hpp" +#include "state.hpp" +#include "utils.hpp" namespace quickbook { @@ -27,22 +27,22 @@ namespace quickbook struct phrase_element_grammar_local { - cl::rule - image, anchor, link, empty, cond_phrase, inner_phrase, - role, source_mode - ; + cl::rule image, anchor, link, empty, cond_phrase, inner_phrase, + role, source_mode; }; void quickbook_grammar::impl::init_phrase_elements() { - phrase_element_grammar_local& local = cleanup_.add( - new phrase_element_grammar_local); + phrase_element_grammar_local& local = + cleanup_.add(new phrase_element_grammar_local); error_action error(state); raw_char_action raw_char(state); scoped_parser scoped_cond_phrase(state); scoped_parser to_value(state); + // clang-format off + elements.add ("?", element_info(element_info::phrase, &local.cond_phrase)) ; @@ -205,5 +205,7 @@ namespace quickbook blank >> to_value() [ paragraph_phrase ] ; + + // clang-format on } } diff --git a/tools/quickbook/src/phrase_tags.hpp b/tools/quickbook/src/phrase_tags.hpp index f4bba91653..e94c0935c5 100644 --- a/tools/quickbook/src/phrase_tags.hpp +++ b/tools/quickbook/src/phrase_tags.hpp @@ -13,6 +13,8 @@ namespace quickbook { + // clang-format off + QUICKBOOK_VALUE_TAGS(phrase_tags, 0x500, (image) (url)(link)(anchor) @@ -37,6 +39,8 @@ namespace quickbook (inline_code_block) (next_source_mode) ) + + // clang-format on } #endif diff --git a/tools/quickbook/src/post_process.cpp b/tools/quickbook/src/post_process.cpp index 12344a3dc0..25a1a24d73 100644 --- a/tools/quickbook/src/post_process.cpp +++ b/tools/quickbook/src/post_process.cpp @@ -7,11 +7,11 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "post_process.hpp" -#include -#include +#include #include #include -#include +#include +#include namespace quickbook { @@ -21,8 +21,14 @@ namespace quickbook struct printer { printer(std::string& out_, int& current_indent_, int linewidth_) - : prev(0), out(out_), current_indent(current_indent_) , column(0) - , in_string(false), linewidth(linewidth_) {} + : prev(0) + , out(out_) + , current_indent(current_indent_) + , column(0) + , in_string(false) + , linewidth(linewidth_) + { + } void indent() { @@ -34,7 +40,7 @@ namespace quickbook void trim_spaces() { - out.erase(out.find_last_not_of(' ')+1); // trim trailing spaces + out.erase(out.find_last_not_of(' ') + 1); // trim trailing spaces } void break_line() @@ -46,10 +52,9 @@ namespace quickbook bool line_is_empty() const { - for (iter_type i = out.end()-(column-current_indent); i != out.end(); ++i) - { - if (*i != ' ') - return false; + for (iter_type i = out.end() - (column - current_indent); + i != out.end(); ++i) { + if (*i != ' ') return false; } return true; } @@ -57,27 +62,23 @@ namespace quickbook void align_indent() { // make sure we are at the proper indent position - if (column != current_indent) - { - if (column > current_indent) - { - if (line_is_empty()) - { - // trim just enough trailing spaces down to current_indent position - out.erase(out.end()-(column-current_indent), out.end()); + if (column != current_indent) { + if (column > current_indent) { + if (line_is_empty()) { + // trim just enough trailing spaces down to + // current_indent position + out.erase( + out.end() - (column - current_indent), out.end()); column = current_indent; } - else - { + else { // nope, line is not empty. do a hard CR break_line(); } } - else - { + else { // will this happen? (i.e. column <= current_indent) - while (column != current_indent) - { + while (column != current_indent) { out += ' '; ++column; } @@ -101,38 +102,31 @@ namespace quickbook // Strings will occur only in tag attributes. Normal content // will have " instead. We shall deal only with tag // attributes here. - if (ch == '"') - in_string = !in_string; // don't break strings! + if (ch == '"') in_string = !in_string; // don't break strings! - if (!in_string && std::isspace(static_cast(ch))) - { + if (!in_string && std::isspace(static_cast(ch))) { // we can break spaces if they are not inside strings - if (!std::isspace(static_cast(prev))) - { - if (column >= linewidth) - { + if (!std::isspace(static_cast(prev))) { + if (column >= linewidth) { break_line(); - if (column == 0 && ch == ' ') - { + if (column == 0 && ch == ' ') { ++column; out += ' '; } } - else - { + else { ++column; out += ' '; } } } - else - { + else { // we can break tag boundaries and stuff after // delimiters if they are not inside strings // and *only-if* the preceding char is a space - if (!in_string - && column >= linewidth - && (ch == '<' && std::isspace(static_cast(prev)))) + if (!in_string && column >= linewidth && + (ch == '<' && + std::isspace(static_cast(prev)))) break_line(); out += ch; ++column; @@ -141,29 +135,26 @@ namespace quickbook prev = ch; } - void - print(iter_type f, iter_type l) + void print(iter_type f, iter_type l) { for (iter_type i = f; i != l; ++i) print(*i); } - void - print_tag(iter_type f, iter_type l, bool is_flow_tag) + void print_tag(iter_type f, iter_type l, bool is_flow_tag) { - if (is_flow_tag) - { + if (is_flow_tag) { print(f, l); } - else - { + else { // This is not a flow tag, so, we're going to do a // carriage return anyway. Let us remove extra right // spaces. std::string str(f, l); BOOST_ASSERT(f != l); // this should not happen iter_type i = str.end(); - while (i != str.begin() && std::isspace(static_cast(*(i-1)))) + while (i != str.begin() && + std::isspace(static_cast(*(i - 1)))) --i; print(str.begin(), i); } @@ -176,73 +167,40 @@ namespace quickbook bool in_string; int linewidth; - private: + private: printer& operator=(printer const&); }; - char const* block_tags_[] = - { - "author" - , "blockquote" - , "bridgehead" - , "callout" - , "calloutlist" - , "caution" - , "copyright" - , "entry" - , "important" - , "informaltable" - , "itemizedlist" - , "legalnotice" - , "listitem" - , "note" - , "orderedlist" - , "para" - , "row" - , "section" - , "simpara" - , "table" - , "tbody" - , "textobject" - , "tgroup" - , "thead" - , "tip" - , "variablelist" - , "varlistentry" - , "warning" - , "xml" - , "xi:include" - }; + char const* block_tags_[] = { + "author", "blockquote", "bridgehead", "callout", + "calloutlist", "caution", "copyright", "entry", + "important", "informaltable", "itemizedlist", "legalnotice", + "listitem", "note", "orderedlist", "para", + "row", "section", "simpara", "table", + "tbody", "textobject", "tgroup", "thead", + "tip", "variablelist", "varlistentry", "warning", + "xml", "xi:include"}; - char const* doc_types_[] = - { - "book" - , "article" - , "library" - , "chapter" - , "part" - , "appendix" - , "preface" - , "qandadiv" - , "qandaset" - , "reference" - , "set" - }; + char const* doc_types_[] = {"book", "article", "library", "chapter", + "part", "appendix", "preface", "qandadiv", + "qandaset", "reference", "set"}; struct tidy_compiler { tidy_compiler(std::string& out_, int linewidth_) - : out(out_), current_indent(0), printer_(out, current_indent, linewidth_) + : out(out_) + , current_indent(0) + , printer_(out, current_indent, linewidth_) { - static std::size_t const n_block_tags = sizeof(block_tags_)/sizeof(char const*); - for (std::size_t i = 0; i != n_block_tags; ++i) - { + static std::size_t const n_block_tags = + sizeof(block_tags_) / sizeof(char const*); + for (std::size_t i = 0; i != n_block_tags; ++i) { block_tags.insert(block_tags_[i]); } - static std::size_t const n_doc_types = sizeof(doc_types_)/sizeof(char const*); - for (std::size_t i = 0; i != n_doc_types; ++i) - { + static std::size_t const n_doc_types = + sizeof(doc_types_) / sizeof(char const*); + for (std::size_t i = 0; i != n_doc_types; ++i) { block_tags.insert(doc_types_[i]); block_tags.insert(doc_types_[i] + std::string("info")); block_tags.insert(doc_types_[i] + std::string("purpose")); @@ -261,20 +219,23 @@ namespace quickbook printer printer_; std::string current_tag; - private: + private: tidy_compiler& operator=(tidy_compiler const&); }; struct tidy_grammar : cl::grammar { tidy_grammar(tidy_compiler& state_, int indent_) - : state(state_), indent(indent_) {} + : state(state_), indent(indent_) + { + } - template - struct definition + template struct definition { definition(tidy_grammar const& self) { + // clang-format off + tag = (cl::lexeme_d[+(cl::alpha_p | '_' | ':')]) [boost::bind(&tidy_grammar::do_tag, &self, _1, _2)]; code = @@ -323,14 +284,14 @@ namespace quickbook ; tidy = +markup; + + // clang-format on } - cl::rule const& - start() { return tidy; } + cl::rule const& start() { return tidy; } - cl::rule - tidy, tag, start_tag, start_end_tag, - content, end_tag, markup, code, escape; + cl::rule tidy, tag, start_tag, start_end_tag, content, + end_tag, markup, code, escape; }; void do_escape_post(iter_type f, iter_type l) const @@ -341,39 +302,37 @@ namespace quickbook void do_escape(iter_type f, iter_type l) const { - while (f != l && std::isspace(*f)) + while (f != l && std::isspace(*f)) { ++f; - for (iter_type i = f; i != l; ++i) + } + while (f != l && std::isspace(*(l - 1))) { + --l; + } + for (iter_type i = f; i != l; ++i) { state.out += *i; + } } void do_code(iter_type f, iter_type l) const { state.printer_.trim_spaces(); - if (state.out[state.out.size() - 1] != '\n') - state.out += '\n'; + if (state.out[state.out.size() - 1] != '\n') state.out += '\n'; // print the string taking care of line // ending CR/LF platform issues - for (iter_type i = f; i != l; ++i) - { - if (*i == '\n') - { + for (iter_type i = f; i != l; ++i) { + if (*i == '\n') { state.printer_.trim_spaces(); state.out += '\n'; ++i; - if (i != l && *i != '\r') - state.out += *i; + if (i != l && *i != '\r') state.out += *i; } - else if (*i == '\r') - { + else if (*i == '\r') { state.printer_.trim_spaces(); state.out += '\n'; ++i; - if (i != l && *i != '\n') - state.out += *i; + if (i != l && *i != '\n') state.out += *i; } - else - { + else { state.out += *i; } } @@ -389,22 +348,18 @@ namespace quickbook void do_start_end_tag(iter_type f, iter_type l) const { bool is_flow_tag = state.is_flow_tag(state.current_tag); - if (!is_flow_tag) - state.printer_.align_indent(); + if (!is_flow_tag) state.printer_.align_indent(); state.printer_.print_tag(f, l, is_flow_tag); - if (!is_flow_tag) - state.printer_.break_line(); + if (!is_flow_tag) state.printer_.break_line(); } void do_start_tag(iter_type f, iter_type l) const { state.tags.push(state.current_tag); bool is_flow_tag = state.is_flow_tag(state.current_tag); - if (!is_flow_tag) - state.printer_.align_indent(); + if (!is_flow_tag) state.printer_.align_indent(); state.printer_.print_tag(f, l, is_flow_tag); - if (!is_flow_tag) - { + if (!is_flow_tag) { state.current_indent += indent; state.printer_.break_line(); } @@ -419,48 +374,39 @@ namespace quickbook { if (state.tags.empty()) throw quickbook::post_process_failure("Mismatched tags."); - + bool is_flow_tag = state.is_flow_tag(state.tags.top()); - if (!is_flow_tag) - { + if (!is_flow_tag) { state.current_indent -= indent; state.printer_.align_indent(); } state.printer_.print_tag(f, l, is_flow_tag); - if (!is_flow_tag) - state.printer_.break_line(); + if (!is_flow_tag) state.printer_.break_line(); state.tags.pop(); } tidy_compiler& state; int indent; - private: + private: tidy_grammar& operator=(tidy_grammar const&); }; - std::string post_process( - std::string const& in - , int indent - , int linewidth) + std::string post_process(std::string const& in, int indent, int linewidth) { - if (indent == -1) - indent = 2; // set default to 2 - if (linewidth == -1) - linewidth = 80; // set default to 80 + if (indent == -1) indent = 2; // set default to 2 + if (linewidth == -1) linewidth = 80; // set default to 80 std::string tidy; tidy_compiler state(tidy, linewidth); tidy_grammar g(state, indent); - cl::parse_info r = parse(in.begin(), in.end(), g, cl::space_p); - if (r.full) - { + cl::parse_info r = + parse(in.begin(), in.end(), g, cl::space_p); + if (r.full) { return tidy; } - else - { + else { throw quickbook::post_process_failure("Post Processing Failed."); } } } - diff --git a/tools/quickbook/src/post_process.hpp b/tools/quickbook/src/post_process.hpp index 81f282b7a6..572138f321 100644 --- a/tools/quickbook/src/post_process.hpp +++ b/tools/quickbook/src/post_process.hpp @@ -9,23 +9,22 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP) #define BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP -#include #include +#include namespace quickbook { std::string post_process( - std::string const& in - , int indent = -1 - , int linewidth = -1); + std::string const& in, int indent = -1, int linewidth = -1); struct post_process_failure : public std::runtime_error { - public: + public: explicit post_process_failure(std::string const& error) - : std::runtime_error(error) {} + : std::runtime_error(error) + { + } }; } #endif // BOOST_SPIRIT_QUICKBOOK_POST_PROCESS_HPP - diff --git a/tools/quickbook/src/quickbook.cpp b/tools/quickbook/src/quickbook.cpp index 11a7c704f8..7c6c3b45cc 100644 --- a/tools/quickbook/src/quickbook.cpp +++ b/tools/quickbook/src/quickbook.cpp @@ -7,30 +7,30 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "grammar.hpp" #include "quickbook.hpp" -#include "state.hpp" -#include "actions.hpp" -#include "post_process.hpp" -#include "utils.hpp" -#include "files.hpp" -#include "stream.hpp" -#include "path.hpp" -#include "document_state.hpp" -#include -#include -#include +#include +#include #include +#include +#include +#include +#include #include #include #include -#include -#include -#include +#include "actions.hpp" +#include "document_state.hpp" +#include "files.hpp" +#include "grammar.hpp" +#include "path.hpp" +#include "post_process.hpp" +#include "state.hpp" +#include "stream.hpp" +#include "utils.hpp" +#include #include #include -#include #if defined(_WIN32) #include @@ -38,19 +38,19 @@ #endif #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) -#pragma warning(disable:4355) +#pragma warning(disable : 4355) #endif -#define QUICKBOOK_VERSION "Quickbook Version 1.7.0" +#define QUICKBOOK_VERSION "Quickbook Version 1.7.1" namespace quickbook { namespace cl = boost::spirit::classic; namespace fs = boost::filesystem; - tm* current_time; // the current time + tm* current_time; // the current time tm* current_gm_time; // the current UTC time - bool debug_mode; // for quickbook developers only + bool debug_mode; // for quickbook developers only bool self_linked_headers; std::vector include_path; std::vector preset_defines; @@ -58,11 +58,10 @@ namespace quickbook static void set_macros(quickbook::state& state) { - for(std::vector::const_iterator - it = preset_defines.begin(), - end = preset_defines.end(); - it != end; ++it) - { + for (std::vector::const_iterator + it = preset_defines.begin(), + end = preset_defines.end(); + it != end; ++it) { quickbook::string_view val(*it); parse_iterator first(val.begin()); parse_iterator last(val.end()); @@ -71,11 +70,8 @@ namespace quickbook cl::parse(first, last, state.grammar().command_line_macro); if (!info.full) { - detail::outerr() - << "Error parsing command line definition: '" - << *it - << "'" - << std::endl; + detail::outerr() << "Error parsing command line definition: '" + << *it << "'" << std::endl; ++state.error_count; } } @@ -86,25 +82,29 @@ namespace quickbook // Parse a file // /////////////////////////////////////////////////////////////////////////// - void parse_file(quickbook::state& state, value include_doc_id, bool nested_file) + void parse_file( + quickbook::state& state, value include_doc_id, bool nested_file) { parse_iterator first(state.current_file->source().begin()); parse_iterator last(state.current_file->source().end()); - cl::parse_info info = cl::parse(first, last, state.grammar().doc_info); + cl::parse_info info = + cl::parse(first, last, state.grammar().doc_info); assert(info.hit); - if (!state.error_count) - { - std::string doc_type = pre(state, info.stop, include_doc_id, nested_file); + if (!state.error_count) { + std::string doc_type = + pre(state, info.stop, include_doc_id, nested_file); - info = cl::parse(info.hit ? info.stop : first, last, state.grammar().block_start); + info = cl::parse( + info.hit ? info.stop : first, last, + state.grammar().block_start); post(state, doc_type); - if (!info.full) - { - file_position const& pos = state.current_file->position_of(info.stop.base()); + if (!info.full) { + file_position const& pos = + state.current_file->position_of(info.stop.base()); detail::outerr(state.current_file->path, pos.line) << "Syntax Error near column " << pos.column << ".\n"; ++state.error_count; @@ -114,13 +114,14 @@ namespace quickbook struct parse_document_options { - parse_document_options() : - indent(-1), - linewidth(-1), - pretty_print(true), - strict_mode(false), - deps_out_flags(quickbook::dependency_tracker::default_) - {} + parse_document_options() + : indent(-1) + , linewidth(-1) + , pretty_print(true) + , strict_mode(false) + , deps_out_flags(quickbook::dependency_tracker::default_) + { + } int indent; int linewidth; @@ -132,11 +133,10 @@ namespace quickbook fs::path xinclude_base; }; - static int - parse_document( - fs::path const& filein_ - , fs::path const& fileout_ - , parse_document_options const& options_) + static int parse_document( + fs::path const& filein_, + fs::path const& fileout_, + parse_document_options const& options_) { string_stream buffer; document_state output; @@ -144,7 +144,8 @@ namespace quickbook int result = 0; try { - quickbook::state state(filein_, options_.xinclude_base, buffer, output); + quickbook::state state( + filein_, options_.xinclude_base, buffer, output); state.strict_mode = options_.strict_mode; set_macros(state); @@ -154,7 +155,7 @@ namespace quickbook parse_file(state); - if(state.error_count) { + if (state.error_count) { detail::outerr() << "Error count: " << state.error_count << ".\n"; } @@ -162,70 +163,55 @@ namespace quickbook result = state.error_count ? 1 : 0; - if (!options_.deps_out.empty()) - { - state.dependencies.write_dependencies(options_.deps_out, - options_.deps_out_flags); + if (!options_.deps_out.empty()) { + state.dependencies.write_dependencies( + options_.deps_out, options_.deps_out_flags); } - if (!options_.locations_out.empty()) - { + if (!options_.locations_out.empty()) { fs::ofstream out(options_.locations_out); - state.dependencies.write_dependencies(options_.locations_out, - dependency_tracker::checked); + state.dependencies.write_dependencies( + options_.locations_out, dependency_tracker::checked); } - } - catch (load_error& e) { + } catch (load_error& e) { detail::outerr(filein_) << e.what() << std::endl; result = 1; - } - catch (std::runtime_error& e) { + } catch (std::runtime_error& e) { detail::outerr() << e.what() << std::endl; result = 1; } - if (!fileout_.empty() && result == 0) - { + if (!fileout_.empty() && result == 0) { std::string stage2 = output.replace_placeholders(buffer.str()); fs::ofstream fileout(fileout_); if (fileout.fail()) { ::quickbook::detail::outerr() - << "Error opening output file " - << fileout_ - << std::endl; + << "Error opening output file " << fileout_ << std::endl; return 1; } - if (options_.pretty_print) - { - try - { - fileout << post_process(stage2, options_.indent, - options_.linewidth); - } - catch (quickbook::post_process_failure&) - { + if (options_.pretty_print) { + try { + fileout << post_process( + stage2, options_.indent, options_.linewidth); + } catch (quickbook::post_process_failure&) { // fallback! ::quickbook::detail::outerr() - << "Post Processing Failed." - << std::endl; + << "Post Processing Failed." << std::endl; fileout << stage2; return 1; } } - else - { + else { fileout << stage2; } if (fileout.fail()) { ::quickbook::detail::outerr() - << "Error writing to output file " - << fileout_ - << std::endl; + << "Error writing to output file " << fileout_ << std::endl; return 1; } @@ -240,11 +226,9 @@ namespace quickbook // Main program // /////////////////////////////////////////////////////////////////////////// -int -main(int argc, char* argv[]) +int main(int argc, char* argv[]) { - try - { + try { namespace fs = boost::filesystem; namespace po = boost::program_options; @@ -256,13 +240,14 @@ main(int argc, char* argv[]) using boost::program_options::command_line_parser; using boost::program_options::notify; using boost::program_options::positional_options_description; - + using namespace quickbook; using quickbook::detail::command_line_string; - // First thing, the filesystem should record the current working directory. + // First thing, the filesystem should record the current working + // directory. fs::initial_path(); - + // Various initialisation methods quickbook::detail::initialise_output(); quickbook::detail::initialise_markups(); @@ -279,6 +264,8 @@ main(int argc, char* argv[]) #define PO_VALUE po::value #endif + // clang-format off + desc.add_options() ("help", "produce help message") ("version", "print version string") @@ -316,6 +303,8 @@ main(int argc, char* argv[]) "write the deps file in this format.") ; + // clang-format on + all.add(desc).add(hidden); positional_options_description p; @@ -331,9 +320,9 @@ main(int argc, char* argv[]) int wide_argc; LPWSTR* wide_argv = CommandLineToArgvW(GetCommandLineW(), &wide_argc); - if (!wide_argv) - { - quickbook::detail::outerr() << "Error getting argument values." << std::endl; + if (!wide_argv) { + quickbook::detail::outerr() + << "Error getting argument values." << std::endl; return 1; } @@ -341,14 +330,14 @@ main(int argc, char* argv[]) wcommand_line_parser(wide_argc, wide_argv) .options(all) .positional(p) - .run(), vm); + .run(), + vm); LocalFree(wide_argv); #else - store(command_line_parser(argc, argv) - .options(all) - .positional(p) - .run(), vm); + store( + command_line_parser(argc, argv).options(all).positional(p).run(), + vm); #endif notify(vm); @@ -359,8 +348,7 @@ main(int argc, char* argv[]) bool expect_errors = vm.count("expect-errors"); int error_count = 0; - if (vm.count("help")) - { + if (vm.count("help")) { std::ostringstream description_text; description_text << desc; @@ -369,37 +357,29 @@ main(int argc, char* argv[]) return 0; } - if (vm.count("version")) - { + if (vm.count("version")) { std::string boost_version = BOOST_LIB_VERSION; boost::replace(boost_version, '_', '.'); - - quickbook::detail::out() - << QUICKBOOK_VERSION - << " (Boost " - << boost_version - << ")" - << std::endl; + + quickbook::detail::out() << QUICKBOOK_VERSION << " (Boost " + << boost_version << ")" << std::endl; return 0; } quickbook::detail::set_ms_errors(vm.count("ms-errors")); - if (vm.count("no-pretty-print")) - options.pretty_print = false; + if (vm.count("no-pretty-print")) options.pretty_print = false; options.strict_mode = !!vm.count("strict"); quickbook::self_linked_headers = !vm.count("no-self-linked-headers"); - if (vm.count("indent")) - options.indent = vm["indent"].as(); + if (vm.count("indent")) options.indent = vm["indent"].as(); if (vm.count("linewidth")) options.linewidth = vm["linewidth"].as(); - if (vm.count("debug")) - { + if (vm.count("debug")) { static tm timeinfo; timeinfo.tm_year = 2000 - 1900; timeinfo.tm_mon = 12 - 1; @@ -413,8 +393,7 @@ main(int argc, char* argv[]) quickbook::current_gm_time = &timeinfo; quickbook::debug_mode = true; } - else - { + else { time_t t = std::time(0); static tm lt = *localtime(&t); static tm gmt = *gmtime(&t); @@ -422,10 +401,9 @@ main(int argc, char* argv[]) quickbook::current_gm_time = &gmt; quickbook::debug_mode = false; } - + quickbook::include_path.clear(); - if (vm.count("include-path")) - { + if (vm.count("include-path")) { boost::transform( vm["include-path"].as >(), std::back_inserter(quickbook::include_path), @@ -433,57 +411,49 @@ main(int argc, char* argv[]) } quickbook::preset_defines.clear(); - if (vm.count("define")) - { + if (vm.count("define")) { boost::transform( vm["define"].as >(), std::back_inserter(quickbook::preset_defines), quickbook::detail::command_line_to_utf8); } - if (vm.count("input-file")) - { + if (vm.count("input-file")) { fs::path filein = quickbook::detail::command_line_to_path( vm["input-file"].as()); fs::path fileout; if (!fs::exists(filein)) { quickbook::detail::outerr() - << "file not found: " - << filein - << std::endl; + << "file not found: " << filein << std::endl; ++error_count; } bool default_output = true; - if (vm.count("no-output")) - { + if (vm.count("no-output")) { default_output = false; } - if (vm.count("output-deps")) - { - options.deps_out = - quickbook::detail::command_line_to_path( - vm["output-deps"].as()); + if (vm.count("output-deps")) { + options.deps_out = quickbook::detail::command_line_to_path( + vm["output-deps"].as()); default_output = false; } - if (vm.count("output-deps-format")) - { + if (vm.count("output-deps-format")) { std::string format_flags = quickbook::detail::command_line_to_utf8( vm["output-deps-format"].as()); std::vector flag_names; - boost::algorithm::split(flag_names, format_flags, - boost::algorithm::is_any_of(", "), - boost::algorithm::token_compress_on); + boost::algorithm::split( + flag_names, format_flags, boost::algorithm::is_any_of(", "), + boost::algorithm::token_compress_on); unsigned flags = 0; - BOOST_FOREACH(std::string const& flag, flag_names) { + BOOST_FOREACH (std::string const& flag, flag_names) { if (flag == "checked") { flags |= quickbook::dependency_tracker::checked; } @@ -492,9 +462,8 @@ main(int argc, char* argv[]) } else if (!flag.empty()) { quickbook::detail::outerr() - << "Unknown dependency format flag: " - << flag - <()); + if (vm.count("output-checked-locations")) { + options.locations_out = quickbook::detail::command_line_to_path( + vm["output-checked-locations"].as()); default_output = false; } - if (vm.count("output-file")) - { + if (vm.count("output-file")) { fileout = quickbook::detail::command_line_to_path( vm["output-file"].as()); fs::path parent = fileout.parent_path(); - if (!parent.empty() && !fs::is_directory(parent)) - { + if (!parent.empty() && !fs::is_directory(parent)) { quickbook::detail::outerr() << "parent directory not found for output file" << std::endl; ++error_count; } } - else if (default_output) - { + else if (default_output) { fileout = filein; fileout.replace_extension(".xml"); } - if (vm.count("xinclude-base")) - { - options.xinclude_base = - quickbook::detail::command_line_to_path( - vm["xinclude-base"].as()); + if (vm.count("xinclude-base")) { + options.xinclude_base = quickbook::detail::command_line_to_path( + vm["xinclude-base"].as()); // I'm not sure if this error check is necessary. // There might be valid reasons to use a path that doesn't // exist yet, or a path that just generates valid relative // paths. - if (!fs::is_directory(options.xinclude_base)) - { + if (!fs::is_directory(options.xinclude_base)) { quickbook::detail::outerr() - << "xinclude-base is not a directory" - << std::endl; + << "xinclude-base is not a directory" << std::endl; ++error_count; } } - else - { + else { options.xinclude_base = fileout.parent_path(); if (options.xinclude_base.empty()) { options.xinclude_base = "."; } - // If fileout was implicitly created from filein, then it should be in filein's directory. - // If fileout was explicitly specified, then it's already been checked. + // If fileout was implicitly created from filein, then it should + // be in filein's directory. + // If fileout was explicitly specified, then it's already been + // checked. assert(error_count || fs::is_directory(options.xinclude_base)); } - if (vm.count("image-location")) - { - quickbook::image_location = quickbook::detail::command_line_to_path( - vm["image-location"].as()); + if (vm.count("image-location")) { + quickbook::image_location = + quickbook::detail::command_line_to_path( + vm["image-location"].as()); } - else - { + else { quickbook::image_location = filein.parent_path() / "html"; } if (!error_count) { if (!fileout.empty()) { - quickbook::detail::out() << "Generating Output File: " - << fileout - << std::endl; + quickbook::detail::out() + << "Generating Output File: " << fileout << std::endl; } - error_count += quickbook::parse_document( - filein, fileout, options); + error_count += + quickbook::parse_document(filein, fileout, options); } - if (expect_errors) - { - if (!error_count) quickbook::detail::outerr() << "No errors detected for --expect-errors." << std::endl; + if (expect_errors) { + if (!error_count) + quickbook::detail::outerr() + << "No errors detected for --expect-errors." + << std::endl; return !error_count; } - else - { + else { return error_count; } } - else - { + else { std::ostringstream description_text; description_text << desc; - + quickbook::detail::outerr() << "No filename given\n\n" - << description_text.str() << std::endl; + << description_text.str() << std::endl; return 1; - } + } } - catch(std::exception& e) - { + catch (std::exception& e) { quickbook::detail::outerr() << e.what() << "\n"; return 1; } - catch(...) - { + catch (...) { quickbook::detail::outerr() << "Exception of unknown type caught\n"; return 1; } diff --git a/tools/quickbook/src/quickbook.hpp b/tools/quickbook/src/quickbook.hpp index 27d07a4125..584f81e998 100644 --- a/tools/quickbook/src/quickbook.hpp +++ b/tools/quickbook/src/quickbook.hpp @@ -12,9 +12,9 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP) #define BOOST_SPIRIT_QUICKBOOK_QUICKBOOK_HPP +#include #include #include -#include #include #include "fwd.hpp" #include "values.hpp" @@ -23,7 +23,7 @@ namespace quickbook { namespace fs = boost::filesystem; - extern tm* current_time; // the current time + extern tm* current_time; // the current time extern tm* current_gm_time; // the current UTC time extern bool debug_mode; extern bool self_linked_headers; @@ -31,9 +31,10 @@ namespace quickbook extern std::vector preset_defines; extern fs::path image_location; - void parse_file(quickbook::state& state, - value include_doc_id = value(), - bool nested_file = false); + void parse_file( + quickbook::state& state, + value include_doc_id = value(), + bool nested_file = false); // Some initialisation methods // // Declared here to avoid including other headers diff --git a/tools/quickbook/src/scoped.hpp b/tools/quickbook/src/scoped.hpp index 387f1e40dd..483b05f48e 100644 --- a/tools/quickbook/src/scoped.hpp +++ b/tools/quickbook/src/scoped.hpp @@ -11,16 +11,16 @@ #include -namespace quickbook { +namespace quickbook +{ struct scoped_action_base { bool start() { return true; } - template - void success(Iterator, Iterator) {} + template void success(Iterator, Iterator) {} void failure() {} void cleanup() {} - + template bool result(ResultT r, ScannerT const&) { diff --git a/tools/quickbook/src/state.cpp b/tools/quickbook/src/state.cpp index f0047f3b5f..314f2fc4f0 100644 --- a/tools/quickbook/src/state.cpp +++ b/tools/quickbook/src/state.cpp @@ -9,17 +9,17 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ #include "state.hpp" -#include "state_save.hpp" +#include #include "document_state.hpp" -#include "quickbook.hpp" #include "grammar.hpp" #include "path.hpp" -#include "utils.hpp" #include "phrase_tags.hpp" -#include +#include "quickbook.hpp" +#include "state_save.hpp" +#include "utils.hpp" #if (defined(BOOST_MSVC) && (BOOST_MSVC <= 1310)) -#pragma warning(disable:4355) +#pragma warning(disable : 4355) #endif namespace quickbook @@ -29,8 +29,11 @@ namespace quickbook unsigned qbk_version_n = 0; // qbk_major_version * 100 + qbk_minor_version - state::state(fs::path const& filein_, fs::path const& xinclude_base_, - string_stream& out_, document_state& document_) + state::state( + fs::path const& filein_, + fs::path const& xinclude_base_, + string_stream& out_, + document_state& document_) : grammar_() , order_pos(0) @@ -67,77 +70,78 @@ namespace quickbook , values(¤t_file) { // add the predefined macros - macro.add - ("__DATE__", std::string(quickbook_get_date)) - ("__TIME__", std::string(quickbook_get_time)) - ("__FILENAME__", std::string()) - ; + macro.add("__DATE__", std::string(quickbook_get_date))( + "__TIME__", + std::string(quickbook_get_time))("__FILENAME__", std::string()); update_filename_macro(); - boost::scoped_ptr g( - new quickbook_grammar(*this)); + boost::scoped_ptr g(new quickbook_grammar(*this)); grammar_.swap(g); } - quickbook_grammar& state::grammar() const { - return *grammar_; - } + quickbook_grammar& state::grammar() const { return *grammar_; } - void state::update_filename_macro() { - *boost::spirit::classic::find(macro, "__FILENAME__") - = detail::encode_string( - detail::path_to_generic(current_path.abstract_file_path)); - } - - unsigned state::get_new_order_pos() { - return ++order_pos; + void state::update_filename_macro() + { + *boost::spirit::classic::find(macro, "__FILENAME__") = + detail::encode_string( + detail::path_to_generic(current_path.abstract_file_path)); } - void state::push_output() { + unsigned state::get_new_order_pos() { return ++order_pos; } + + void state::push_output() + { out.push(); phrase.push(); in_list_save.push(in_list); } - void state::pop_output() { + void state::pop_output() + { phrase.pop(); out.pop(); in_list = in_list_save.top(); in_list_save.pop(); } - source_mode_info state::tagged_source_mode() const { + source_mode_info state::tagged_source_mode() const + { source_mode_info result; - BOOST_FOREACH(source_mode_info const& s, tagged_source_mode_stack) { + BOOST_FOREACH (source_mode_info const& s, tagged_source_mode_stack) { result.update(s); } return result; } - source_mode_info state::current_source_mode() const { + source_mode_info state::current_source_mode() const + { source_mode_info result = source_mode; result.update(document.section_source_mode()); - BOOST_FOREACH(source_mode_info const& s, tagged_source_mode_stack) { + BOOST_FOREACH (source_mode_info const& s, tagged_source_mode_stack) { result.update(s); } return result; } - void state::change_source_mode(source_mode_type s) { + void state::change_source_mode(source_mode_type s) + { source_mode = source_mode_info(s, get_new_order_pos()); } - void state::push_tagged_source_mode(source_mode_type s) { + void state::push_tagged_source_mode(source_mode_type s) + { tagged_source_mode_stack.push_back( source_mode_info(s, s ? get_new_order_pos() : 0)); } - void state::pop_tagged_source_mode() { + void state::pop_tagged_source_mode() + { assert(!tagged_source_mode_stack.empty()); tagged_source_mode_stack.pop_back(); } diff --git a/tools/quickbook/src/state.hpp b/tools/quickbook/src/state.hpp index 5bd5bb6157..022d262d77 100644 --- a/tools/quickbook/src/state.hpp +++ b/tools/quickbook/src/state.hpp @@ -12,14 +12,14 @@ #include #include -#include "parsers.hpp" -#include "values_parse.hpp" #include "collector.hpp" -#include "template_stack.hpp" -#include "symbols.hpp" #include "dependency_tracker.hpp" -#include "syntax_highlight.hpp" #include "include_paths.hpp" +#include "parsers.hpp" +#include "symbols.hpp" +#include "syntax_highlight.hpp" +#include "template_stack.hpp" +#include "values_parse.hpp" namespace quickbook { @@ -28,65 +28,67 @@ namespace quickbook struct state { - state(fs::path const& filein_, fs::path const& xinclude_base, string_stream& out_, - document_state&); + state( + fs::path const& filein_, + fs::path const& xinclude_base, + string_stream& out_, + document_state&); - private: + private: boost::scoped_ptr grammar_; - public: - /////////////////////////////////////////////////////////////////////////// - // State - /////////////////////////////////////////////////////////////////////////// + public: + /////////////////////////////////////////////////////////////////////////// + // State + /////////////////////////////////////////////////////////////////////////// typedef std::vector string_list; static int const max_template_depth = 100; - // global state - unsigned order_pos; - fs::path xinclude_base; - template_stack templates; - int error_count; - string_list anchors; - bool warned_about_breaks; - bool conditional; - document_state& document; - value_builder callouts; // callouts are global as - int callout_depth; // they don't nest. - dependency_tracker dependencies; - bool explicit_list; // set when using a list - bool strict_mode; - - // state saved for files and templates. - bool imported; - string_symbols macro; - source_mode_info source_mode; - source_mode_type source_mode_next; - value source_mode_next_pos; - std::vector - tagged_source_mode_stack; - file_ptr current_file; - quickbook_path current_path; - - // state saved for templates. - int template_depth; - int min_section_level; - - // output state - scoped by templates and grammar - bool in_list; // generating a list - std::stack in_list_save; // save the in_list state - collector out; // main output stream - collector phrase; // phrase output stream - - // values state - scoped by everything. - value_parser values; // parsed values + // global state + unsigned order_pos; + fs::path xinclude_base; + template_stack templates; + int error_count; + string_list anchors; + bool warned_about_breaks; + bool conditional; + document_state& document; + value_builder callouts; // callouts are global as + int callout_depth; // they don't nest. + dependency_tracker dependencies; + bool explicit_list; // set when using a list + bool strict_mode; + + // state saved for files and templates. + bool imported; + string_symbols macro; + source_mode_info source_mode; + source_mode_type source_mode_next; + value source_mode_next_pos; + std::vector tagged_source_mode_stack; + file_ptr current_file; + quickbook_path current_path; + + // state saved for templates. + int template_depth; + int min_section_level; + + // output state - scoped by templates and grammar + bool in_list; // generating a list + std::stack in_list_save; // save the in_list state + collector out; // main output stream + collector phrase; // phrase output stream + + // values state - scoped by everything. + value_parser values; // parsed values quickbook_grammar& grammar() const; - /////////////////////////////////////////////////////////////////////////// - // actions - /////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////// + // actions + /////////////////////////////////////////////////////////////////////////// void update_filename_macro(); @@ -111,7 +113,8 @@ namespace quickbook void pop_tagged_source_mode(); }; - extern unsigned qbk_version_n; // qbk_major_version * 100 + qbk_minor_version + extern unsigned + qbk_version_n; // qbk_major_version * 100 + qbk_minor_version extern char const* quickbook_get_date; extern char const* quickbook_get_time; } diff --git a/tools/quickbook/src/state_save.hpp b/tools/quickbook/src/state_save.hpp index 8cae8cd1b2..8f76badde0 100644 --- a/tools/quickbook/src/state_save.hpp +++ b/tools/quickbook/src/state_save.hpp @@ -20,7 +20,8 @@ namespace quickbook struct state_save { - enum scope_flags { + enum scope_flags + { scope_none = 0, scope_macros = 1, scope_templates = 2, @@ -44,7 +45,8 @@ namespace quickbook string_symbols macro; int template_depth; int min_section_level; - private: + + private: state_save(state_save const&); state_save& operator=(state_save const&); }; diff --git a/tools/quickbook/src/stream.cpp b/tools/quickbook/src/stream.cpp index 05241d0823..9aab9c8721 100644 --- a/tools/quickbook/src/stream.cpp +++ b/tools/quickbook/src/stream.cpp @@ -7,196 +7,208 @@ =============================================================================*/ #include "stream.hpp" -#include "path.hpp" #include "files.hpp" +#include "path.hpp" #if QUICKBOOK_WIDE_PATHS || QUICKBOOK_WIDE_STREAMS -#include #include +#include #endif -namespace quickbook { -namespace detail { - namespace { - bool ms_errors = false; - } +namespace quickbook +{ + namespace detail + { + namespace + { + bool ms_errors = false; + } - void set_ms_errors(bool x) { - ms_errors = x; - } + void set_ms_errors(bool x) { ms_errors = x; } #if QUICKBOOK_WIDE_STREAMS - void initialise_output() - { - if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT); - if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT); - } - - void write_utf8(ostream::base_ostream& out, quickbook::string_view x) - { - out << from_utf8(x); - } + void initialise_output() + { + if (_isatty(_fileno(stdout))) _setmode(_fileno(stdout), _O_U16TEXT); + if (_isatty(_fileno(stderr))) _setmode(_fileno(stderr), _O_U16TEXT); + } - ostream& out() - { - static ostream x(std::wcout); - return x; - } + void write_utf8(ostream::base_ostream& out, quickbook::string_view x) + { + out << from_utf8(x); + } - namespace - { - inline ostream& error_stream() + ostream& out() { - static ostream x(std::wcerr); + static ostream x(std::wcout); return x; } - } -#else + namespace + { + inline ostream& error_stream() + { + static ostream x(std::wcerr); + return x; + } + } - void initialise_output() - { - } +#else - void write_utf8(ostream::base_ostream& out, quickbook::string_view x) - { - out << x; - } + void initialise_output() {} - ostream& out() - { - static ostream x(std::cout); - return x; - } + void write_utf8(ostream::base_ostream& out, quickbook::string_view x) + { + out << x; + } - namespace - { - inline ostream& error_stream() + ostream& out() { - static ostream x(std::clog); + static ostream x(std::cout); return x; } - } + + namespace + { + inline ostream& error_stream() + { + static ostream x(std::clog); + return x; + } + } #endif - ostream& outerr() - { - return error_stream() << "Error: "; - } + ostream& outerr() { return error_stream() << "Error: "; } - ostream& outerr(fs::path const& file, std::ptrdiff_t line) - { - if (line >= 0) + ostream& outerr(fs::path const& file, std::ptrdiff_t line) { - if (ms_errors) - return error_stream() << path_to_stream(file) << "(" << line << "): error: "; - else - return error_stream() << path_to_stream(file) << ":" << line << ": error: "; + if (line >= 0) { + if (ms_errors) + return error_stream() << path_to_stream(file) << "(" << line + << "): error: "; + else + return error_stream() << path_to_stream(file) << ":" << line + << ": error: "; + } + else { + return error_stream() << path_to_stream(file) << ": error: "; + } } - else + + ostream& outerr(file_ptr const& f, string_iterator pos) { - return error_stream() << path_to_stream(file) << ": error: "; + return outerr(f->path, f->position_of(pos).line); } - } - - ostream& outerr(file_ptr const& f, string_iterator pos) - { - return outerr(f->path, f->position_of(pos).line); - } - ostream& outwarn(fs::path const& file, std::ptrdiff_t line) - { - if (line >= 0) + ostream& outwarn(fs::path const& file, std::ptrdiff_t line) { - if (ms_errors) - return error_stream() << path_to_stream(file) << "(" << line << "): warning: "; - else - return error_stream() << path_to_stream(file) << ":" << line << ": warning: "; + if (line >= 0) { + if (ms_errors) + return error_stream() << path_to_stream(file) << "(" << line + << "): warning: "; + else + return error_stream() << path_to_stream(file) << ":" << line + << ": warning: "; + } + else { + return error_stream() << path_to_stream(file) << ": warning: "; + } } - else + + ostream& outwarn(file_ptr const& f, string_iterator pos) { - return error_stream() << path_to_stream(file) << ": warning: "; + return outwarn(f->path, f->position_of(pos).line); } - } - - ostream& outwarn(file_ptr const& f, string_iterator pos) - { - return outwarn(f->path, f->position_of(pos).line); - } - ostream& ostream::operator<<(char c) { - assert(c && !(c & 0x80)); - base << c; - return *this; - } + ostream& ostream::operator<<(char c) + { + assert(c && !(c & 0x80)); + base << c; + return *this; + } - inline bool check_ascii(char const* x) { - for(;*x;++x) if(*x & 0x80) return false; - return true; - } + inline bool check_ascii(char const* x) + { + for (; *x; ++x) + if (*x & 0x80) return false; + return true; + } - ostream& ostream::operator<<(char const* x) { - assert(check_ascii(x)); - base << x; - return *this; - } + ostream& ostream::operator<<(char const* x) + { + assert(check_ascii(x)); + base << x; + return *this; + } - ostream& ostream::operator<<(std::string const& x) { - write_utf8(base, x); - return *this; - } + ostream& ostream::operator<<(std::string const& x) + { + write_utf8(base, x); + return *this; + } - ostream& ostream::operator<<(quickbook::string_view x) { - write_utf8(base, x); - return *this; - } + ostream& ostream::operator<<(quickbook::string_view x) + { + write_utf8(base, x); + return *this; + } - ostream& ostream::operator<<(int x) { - base << x; - return *this; - } + ostream& ostream::operator<<(int x) + { + base << x; + return *this; + } - ostream& ostream::operator<<(unsigned int x) { - base << x; - return *this; - } + ostream& ostream::operator<<(unsigned int x) + { + base << x; + return *this; + } - ostream& ostream::operator<<(long x) { - base << x; - return *this; - } + ostream& ostream::operator<<(long x) + { + base << x; + return *this; + } - ostream& ostream::operator<<(unsigned long x) { - base << x; - return *this; - } + ostream& ostream::operator<<(unsigned long x) + { + base << x; + return *this; + } #if !defined(BOOST_NO_LONG_LONG) - ostream& ostream::operator<<(boost::long_long_type x) { - base << x; - return *this; - } + ostream& ostream::operator<<(boost::long_long_type x) + { + base << x; + return *this; + } - ostream& ostream::operator<<(boost::ulong_long_type x) { - base << x; - return *this; - } + ostream& ostream::operator<<(boost::ulong_long_type x) + { + base << x; + return *this; + } #endif - ostream& ostream::operator<<(fs::path const& x) { - base << path_to_stream(x); - return *this; - } + ostream& ostream::operator<<(fs::path const& x) + { + base << path_to_stream(x); + return *this; + } - ostream& ostream::operator<<(base_ostream& (*x)(base_ostream&)) { - base << x; - return *this; - } + ostream& ostream::operator<<(base_ostream& (*x)(base_ostream&)) + { + base << x; + return *this; + } - ostream& ostream::operator<<(base_ios& (*x)(base_ios&)) { - base << x; - return *this; + ostream& ostream::operator<<(base_ios& (*x)(base_ios&)) + { + base << x; + return *this; + } } -}} +} diff --git a/tools/quickbook/src/stream.hpp b/tools/quickbook/src/stream.hpp index 380711bd7f..48d789710e 100644 --- a/tools/quickbook/src/stream.hpp +++ b/tools/quickbook/src/stream.hpp @@ -11,9 +11,9 @@ #if !defined(BOOST_QUICKBOOK_DETAIL_STREAM_HPP) #define BOOST_QUICKBOOK_DETAIL_STREAM_HPP -#include "native_text.hpp" -#include #include +#include +#include "native_text.hpp" namespace quickbook { diff --git a/tools/quickbook/src/string_view.hpp b/tools/quickbook/src/string_view.hpp index ef5afe8bf2..c0574ae1a3 100644 --- a/tools/quickbook/src/string_view.hpp +++ b/tools/quickbook/src/string_view.hpp @@ -11,12 +11,14 @@ #include -namespace quickbook { +namespace quickbook +{ // boost::string_view now can't be constructed from an rvalue std::string, // which is something that quickbook does in several places, so this wraps // it to allow that. - struct string_view : boost::string_view { + struct string_view : boost::string_view + { typedef boost::string_view base; string_view() : base() {} diff --git a/tools/quickbook/src/symbols.hpp b/tools/quickbook/src/symbols.hpp index a514f37747..1d16c35cf7 100644 --- a/tools/quickbook/src/symbols.hpp +++ b/tools/quickbook/src/symbols.hpp @@ -12,58 +12,58 @@ /////////////////////////////////////////////////////////////////////////////// -#include #include #include +#include /////////////////////////////////////////////////////////////////////////////// namespace quickbook { -/////////////////////////////////////////////////////////////////////////////// -// -// tst class -// -// This it the Ternary Search Tree from -// adapted to be cheap -// to copy. -// -// Ternary Search Tree implementation. The data structure is faster than -// hashing for many typical search problems especially when the search -// interface is iterator based. Searching for a string of length k in a -// ternary search tree with n strings will require at most O(log n+k) -// character comparisons. TSTs are many times faster than hash tables -// for unsuccessful searches since mismatches are discovered earlier -// after examining only a few characters. Hash tables always examine an -// entire key when searching. -// -// For details see http://www.cs.princeton.edu/~rs/strings/. -// -// *** This is a low level class and is -// not meant for public consumption *** -// -/////////////////////////////////////////////////////////////////////////////// - - template - struct tst_node + /////////////////////////////////////////////////////////////////////////////// + // + // tst class + // + // This it the Ternary Search Tree from + // adapted to be cheap + // to copy. + // + // Ternary Search Tree implementation. The data structure is faster + // than + // hashing for many typical search problems especially when the search + // interface is iterator based. Searching for a string of length k in a + // ternary search tree with n strings will require at most O(log n+k) + // character comparisons. TSTs are many times faster than hash tables + // for unsuccessful searches since mismatches are discovered earlier + // after examining only a few characters. Hash tables always examine an + // entire key when searching. + // + // For details see http://www.cs.princeton.edu/~rs/strings/. + // + // *** This is a low level class and is + // not meant for public consumption *** + // + /////////////////////////////////////////////////////////////////////////////// + + template struct tst_node { tst_node(CharT value_) - : reference_count(0) - , left() - , middle() - , right() - , data() - , value(value_) + : reference_count(0) + , left() + , middle() + , right() + , data() + , value(value_) { } - + tst_node(tst_node const& other) - : reference_count(0) - , left(other.left) - , middle(other.middle) - , right(other.right) - , data(other.data ? new T(*other.data) : 0) - , value(other.value) + : reference_count(0) + , left(other.left) + , middle(other.middle) + , right(other.right) + , data(other.data ? new T(*other.data) : 0) + , value(other.value) { } @@ -76,39 +76,38 @@ namespace quickbook boost::intrusive_ptr right; boost::scoped_ptr data; CharT value; - private: + + private: tst_node& operator=(tst_node const&); }; template void intrusive_ptr_add_ref(tst_node* ptr) - { ++ptr->reference_count; } + { + ++ptr->reference_count; + } template void intrusive_ptr_release(tst_node* ptr) - { if(--ptr->reference_count == 0) delete ptr; } - + { + if (--ptr->reference_count == 0) delete ptr; + } /////////////////////////////////////////////////////////////////////////// - template - class tst + template class tst { typedef tst_node node_t; typedef boost::intrusive_ptr node_ptr; node_ptr root; - public: - + public: struct search_info { - T* data; + T* data; std::size_t length; }; - void swap(tst& other) - { - root.swap(other.root); - } + void swap(tst& other) { root.swap(other.root); } // Adds symbol to ternary search tree. // If it already exists, then replace it with new value. @@ -117,35 +116,29 @@ namespace quickbook template T* add(IteratorT first, IteratorT const& last, T const& data) { - assert (first != last); + assert(first != last); node_ptr* np = &root; CharT ch = *first; - for(;;) - { - if (!*np) - { + for (;;) { + if (!*np) { *np = new node_t(ch); } - else if ((*np)->reference_count > 1) - { + else if ((*np)->reference_count > 1) { *np = new node_t(**np); } - if (ch < (*np)->value) - { + if (ch < (*np)->value) { np = &(*np)->left; } - else if (ch == (*np)->value) - { + else if (ch == (*np)->value) { ++first; if (first == last) break; ch = *first; np = &(*np)->middle; } - else - { + else { np = &(*np)->right; } } @@ -154,23 +147,22 @@ namespace quickbook boost::swap((*np)->data, new_data); return (*np)->data.get(); } - + template search_info find(ScannerT const& scan) const { - search_info result = { 0, 0 }; + search_info result = {0, 0}; if (scan.at_end()) { return result; } typedef typename ScannerT::iterator_t iterator_t; - node_ptr np = root; - CharT ch = *scan; - iterator_t latest = scan.first; + node_ptr np = root; + CharT ch = *scan; + iterator_t latest = scan.first; std::size_t length = 0; - while (np) - { + while (np) { if (ch < np->value) // => go left! { np = np->left; @@ -181,8 +173,7 @@ namespace quickbook ++length; // Found a potential match. - if (np->data.get()) - { + if (np->data.get()) { result.data = np->data.get(); result.length = length; latest = scan.first; @@ -203,11 +194,9 @@ namespace quickbook } }; - typedef boost::spirit::classic::symbols< - std::string, - char, - quickbook::tst - > string_symbols; + typedef boost::spirit::classic:: + symbols > + string_symbols; } // namespace quickbook #endif diff --git a/tools/quickbook/src/syntax_highlight.cpp b/tools/quickbook/src/syntax_highlight.cpp index bbdcb5186d..f6a6d3e827 100644 --- a/tools/quickbook/src/syntax_highlight.cpp +++ b/tools/quickbook/src/syntax_highlight.cpp @@ -7,22 +7,22 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include -#include +#include "syntax_highlight.hpp" #include -#include +#include +#include #include -#include "grammar.hpp" -#include "state.hpp" +#include #include "actions.hpp" -#include "syntax_highlight.hpp" -#include "utils.hpp" #include "files.hpp" -#include "stream.hpp" +#include "grammar.hpp" #include "phrase_tags.hpp" +#include "state.hpp" +#include "stream.hpp" +#include "utils.hpp" namespace quickbook -{ +{ namespace cl = boost::spirit::classic; // Syntax Highlight Actions @@ -36,13 +36,15 @@ namespace quickbook bool support_callouts; quickbook::string_view marked_text; - syntax_highlight_actions(quickbook::state& state_, bool is_block_) : - state(state_), - do_macro_impl(state_), - support_callouts(is_block_ && (qbk_version_n >= 107u || - state.current_file->is_code_snippets)), - marked_text() - {} + syntax_highlight_actions(quickbook::state& state_, bool is_block_) + : state(state_) + , do_macro_impl(state_) + , support_callouts( + is_block_ && (qbk_version_n >= 107u || + state.current_file->is_code_snippets)) + , marked_text() + { + } void span(parse_iterator, parse_iterator, char const*); void span_start(parse_iterator, parse_iterator, char const*); @@ -57,8 +59,8 @@ namespace quickbook void callout(parse_iterator, parse_iterator); }; - void syntax_highlight_actions::span(parse_iterator first, - parse_iterator last, char const* name) + void syntax_highlight_actions::span( + parse_iterator first, parse_iterator last, char const* name) { state.phrase << ""; while (first != last) @@ -66,31 +68,30 @@ namespace quickbook state.phrase << ""; } - void syntax_highlight_actions::span_start(parse_iterator first, - parse_iterator last, char const* name) + void syntax_highlight_actions::span_start( + parse_iterator first, parse_iterator last, char const* name) { state.phrase << ""; while (first != last) detail::print_char(*first++, state.phrase.get()); } - void syntax_highlight_actions::span_end(parse_iterator first, - parse_iterator last) + void syntax_highlight_actions::span_end( + parse_iterator first, parse_iterator last) { while (first != last) detail::print_char(*first++, state.phrase.get()); state.phrase << ""; } - void syntax_highlight_actions::unexpected_char(parse_iterator first, - parse_iterator last) + void syntax_highlight_actions::unexpected_char( + parse_iterator first, parse_iterator last) { file_position const pos = state.current_file->position_of(first.base()); detail::outwarn(state.current_file->path, pos.line) - << "in column:" << pos.column - << ", unexpected character: " << std::string(first.base(), last.base()) - << "\n"; + << "in column:" << pos.column << ", unexpected character: " + << std::string(first.base(), last.base()) << "\n"; // print out an unexpected character state.phrase << ""; @@ -99,21 +100,21 @@ namespace quickbook state.phrase << ""; } - void syntax_highlight_actions::plain_char(parse_iterator first, - parse_iterator last) + void syntax_highlight_actions::plain_char( + parse_iterator first, parse_iterator last) { while (first != last) detail::print_char(*first++, state.phrase.get()); } - void syntax_highlight_actions::pre_escape_back(parse_iterator, - parse_iterator) + void syntax_highlight_actions::pre_escape_back( + parse_iterator, parse_iterator) { state.push_output(); // save the stream } - void syntax_highlight_actions::post_escape_back(parse_iterator, - parse_iterator) + void syntax_highlight_actions::post_escape_back( + parse_iterator, parse_iterator) { std::string tmp; state.phrase.swap(tmp); @@ -126,16 +127,17 @@ namespace quickbook do_macro_impl(v); } - void syntax_highlight_actions::mark_text(parse_iterator first, - parse_iterator last) + void syntax_highlight_actions::mark_text( + parse_iterator first, parse_iterator last) { - marked_text = quickbook::string_view(first.base(), last.base() - first.base()); + marked_text = + quickbook::string_view(first.base(), last.base() - first.base()); } void syntax_highlight_actions::callout(parse_iterator, parse_iterator) { - state.phrase << state.add_callout(qbk_value(state.current_file, - marked_text.begin(), marked_text.end())); + state.phrase << state.add_callout(qbk_value( + state.current_file, marked_text.begin(), marked_text.end())); marked_text.clear(); } @@ -147,6 +149,8 @@ namespace quickbook keywords_holder() { + // clang-format off + cpp = "alignas", "alignof", "and_eq", "and", "asm", "auto", "bitand", "bitor", "bool", "break", "case", "catch", @@ -182,10 +186,13 @@ namespace quickbook "as", "None" ; + + // clang-format on } }; - namespace { + namespace + { keywords_holder keywords; } @@ -193,14 +200,17 @@ namespace quickbook struct cpp_highlight : public cl::grammar { explicit cpp_highlight(syntax_highlight_actions& actions_) - : actions(actions_) {} + : actions(actions_) + { + } - template - struct definition + template struct definition { definition(cpp_highlight const& self) : g(self.actions.state.grammar()) { + // clang-format off + member_action1 span(self.actions, &syntax_highlight_actions::span), span_start(self.actions, &syntax_highlight_actions::span_start); @@ -339,19 +349,18 @@ namespace quickbook identifier = (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; + + // clang-format on } - cl::rule - program, line_start, rest_of_line, macro, preprocessor, - inline_callout, line_callout, comment, - special, string_, - char_, number, identifier, keyword, escape, - string_char; + cl::rule program, line_start, rest_of_line, macro, + preprocessor, inline_callout, line_callout, comment, special, + string_, char_, number, identifier, keyword, escape, + string_char; quickbook_grammar& g; - cl::rule const& - start() const { return program; } + cl::rule const& start() const { return program; } }; syntax_highlight_actions& actions; @@ -363,14 +372,17 @@ namespace quickbook struct python_highlight : public cl::grammar { explicit python_highlight(syntax_highlight_actions& actions_) - : actions(actions_) {} + : actions(actions_) + { + } - template - struct definition + template struct definition { definition(python_highlight const& self) : g(self.actions.state.grammar()) { + // clang-format off + member_action1 span(self.actions, &syntax_highlight_actions::span), span_start(self.actions, &syntax_highlight_actions::span_start); @@ -496,18 +508,17 @@ namespace quickbook identifier = (cl::alpha_p | '_') >> *(cl::alnum_p | '_') ; + + // clang-format on } - cl::rule - program, macro, inline_callout, line_callout, - comment, special, string_, string_prefix, - short_string, long_string, number, identifier, keyword, - escape, string_char; + cl::rule program, macro, inline_callout, line_callout, + comment, special, string_, string_prefix, short_string, + long_string, number, identifier, keyword, escape, string_char; quickbook_grammar& g; - cl::rule const& - start() const { return program; } + cl::rule const& start() const { return program; } }; syntax_highlight_actions& actions; @@ -517,22 +528,30 @@ namespace quickbook struct teletype_highlight : public cl::grammar { teletype_highlight(syntax_highlight_actions& actions_) - : actions(actions_) {} + : actions(actions_) + { + } - template - struct definition + template struct definition { definition(teletype_highlight const& self) : g(self.actions.state.grammar()) { - member_action - plain_char(self.actions, &syntax_highlight_actions::plain_char), - pre_escape_back(self.actions, &syntax_highlight_actions::pre_escape_back), - post_escape_back(self.actions, &syntax_highlight_actions::post_escape_back); - member_action_value + member_action plain_char( + self.actions, &syntax_highlight_actions::plain_char), + pre_escape_back( + self.actions, + &syntax_highlight_actions::pre_escape_back), + post_escape_back( + self.actions, + &syntax_highlight_actions::post_escape_back); + member_action_value< + syntax_highlight_actions, std::string const&> do_macro(self.actions, &syntax_highlight_actions::do_macro); error_action error(self.actions.state); + // clang-format off + program = *( macro @@ -567,14 +586,15 @@ namespace quickbook ) ) [post_escape_back] ; + + // clang-format on } cl::rule program, macro, escape; quickbook_grammar& g; - cl::rule const& - start() const { return program; } + cl::rule const& start() const { return program; } }; syntax_highlight_actions& actions; @@ -590,25 +610,24 @@ namespace quickbook syntax_highlight_actions syn_actions(state, is_block); // print the code with syntax coloring - switch(source_mode) - { - case source_mode_tags::cpp: { - cpp_highlight cpp_p(syn_actions); - boost::spirit::classic::parse(first, last, cpp_p); - break; - } - case source_mode_tags::python: { - python_highlight python_p(syn_actions); - boost::spirit::classic::parse(first, last, python_p); - break; - } - case source_mode_tags::teletype: { - teletype_highlight teletype_p(syn_actions); - boost::spirit::classic::parse(first, last, teletype_p); - break; - } - default: - BOOST_ASSERT(0); + switch (source_mode) { + case source_mode_tags::cpp: { + cpp_highlight cpp_p(syn_actions); + boost::spirit::classic::parse(first, last, cpp_p); + break; + } + case source_mode_tags::python: { + python_highlight python_p(syn_actions); + boost::spirit::classic::parse(first, last, python_p); + break; + } + case source_mode_tags::teletype: { + teletype_highlight teletype_p(syn_actions); + boost::spirit::classic::parse(first, last, teletype_p); + break; + } + default: + BOOST_ASSERT(0); } } } diff --git a/tools/quickbook/src/syntax_highlight.hpp b/tools/quickbook/src/syntax_highlight.hpp index f42103710c..74e1ab7e81 100644 --- a/tools/quickbook/src/syntax_highlight.hpp +++ b/tools/quickbook/src/syntax_highlight.hpp @@ -9,10 +9,10 @@ #if !defined(BOOST_QUICKBOOK_SYNTAX_HIGHLIGHT_HPP) #define BOOST_QUICKBOOK_SYNTAX_HIGHLIGHT_HPP +#include #include "fwd.hpp" -#include "phrase_tags.hpp" #include "iterator.hpp" -#include +#include "phrase_tags.hpp" namespace quickbook { @@ -22,35 +22,38 @@ namespace quickbook // The source mode is stored in a few places, so the order needs to also be // stored to work out which is the current source mode. - struct source_mode_info { + struct source_mode_info + { source_mode_type source_mode; unsigned order; source_mode_info() : source_mode(source_mode_tags::cpp), order(0) {} - source_mode_info(source_mode_type source_mode_, unsigned order_) : - source_mode(source_mode_), - order(order_) {} + source_mode_info(source_mode_type source_mode_, unsigned order_) + : source_mode(source_mode_), order(order_) + { + } - void update(source_mode_info const& x) { + void update(source_mode_info const& x) + { if (x.order > order) { source_mode = x.source_mode; order = x.order; } } - void swap(source_mode_info& x) { + void swap(source_mode_info& x) + { boost::swap(source_mode, x.source_mode); boost::swap(order, x.order); } }; - inline void swap(source_mode_info& x, source_mode_info& y) { - x.swap(y); - } + inline void swap(source_mode_info& x, source_mode_info& y) { x.swap(y); } void syntax_highlight( - parse_iterator first, parse_iterator last, + parse_iterator first, + parse_iterator last, quickbook::state& state, source_mode_type source_mode, bool is_block); diff --git a/tools/quickbook/src/template_stack.cpp b/tools/quickbook/src/template_stack.cpp index 901d12a5db..404780974e 100644 --- a/tools/quickbook/src/template_stack.cpp +++ b/tools/quickbook/src/template_stack.cpp @@ -7,8 +7,8 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include #include "template_stack.hpp" +#include #include "files.hpp" #ifdef BOOST_MSVC @@ -18,42 +18,44 @@ namespace quickbook { template_symbol::template_symbol( - std::string const& identifier_, - std::vector const& params_, - value const& content_, - template_scope const* lexical_parent_) - : identifier(identifier_) - , params(params_) - , content(content_) - , lexical_parent(lexical_parent_) + std::string const& identifier_, + std::vector const& params_, + value const& content_, + template_scope const* lexical_parent_) + : identifier(identifier_) + , params(params_) + , content(content_) + , lexical_parent(lexical_parent_) { - assert(content.get_tag() == template_tags::block || + assert( + content.get_tag() == template_tags::block || content.get_tag() == template_tags::phrase || content.get_tag() == template_tags::snippet); } template_stack::template_stack() - : scope(template_stack::parser(*this)) - , scopes() - , parent_1_4(0) + : scope(template_stack::parser(*this)), scopes(), parent_1_4(0) { scopes.push_front(template_scope()); parent_1_4 = &scopes.front(); } - + template_symbol* template_stack::find(std::string const& symbol) const { - for (template_scope const* i = &*scopes.begin(); i; i = i->parent_scope) - { - if (template_symbol* ts = boost::spirit::classic::find(i->symbols, symbol.c_str())) + for (template_scope const* i = &*scopes.begin(); i; + i = i->parent_scope) { + if (template_symbol* ts = + boost::spirit::classic::find(i->symbols, symbol.c_str())) return ts; } return 0; } - template_symbol* template_stack::find_top_scope(std::string const& symbol) const + template_symbol* template_stack::find_top_scope( + std::string const& symbol) const { - return boost::spirit::classic::find(scopes.front().symbols, symbol.c_str()); + return boost::spirit::classic::find( + scopes.front().symbols, symbol.c_str()); } template_symbols const& template_stack::top() const @@ -67,22 +69,22 @@ namespace quickbook BOOST_ASSERT(!scopes.empty()); return scopes.front(); } - + bool template_stack::add(template_symbol const& ts) { BOOST_ASSERT(!scopes.empty()); BOOST_ASSERT(ts.lexical_parent); - + if (this->find_top_scope(ts.identifier)) { return false; } - - boost::spirit::classic::add(scopes.front().symbols, - ts.identifier.c_str(), ts); + + boost::spirit::classic::add( + scopes.front().symbols, ts.identifier.c_str(), ts); return true; } - + void template_stack::push() { template_scope const& old_front = scopes.front(); @@ -104,16 +106,12 @@ namespace quickbook // current scope (the dynamic scope). // Quickbook 1.5+: Use the scope the template was defined in // (the static scope). - if (symbol->content.get_file()->version() >= 105u) - { + if (symbol->content.get_file()->version() >= 105u) { parent_1_4 = scopes.front().parent_1_4; scopes.front().parent_scope = symbol->lexical_parent; } - else - { + else { scopes.front().parent_scope = scopes.front().parent_1_4; } } } - - diff --git a/tools/quickbook/src/template_stack.hpp b/tools/quickbook/src/template_stack.hpp index 7cb1edd29c..9ad2251ca4 100644 --- a/tools/quickbook/src/template_stack.hpp +++ b/tools/quickbook/src/template_stack.hpp @@ -9,19 +9,19 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP) #define BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP -#include +#include #include +#include #include -#include -#include #include +#include +#include #include #include -#include -#include +#include #include "fwd.hpp" -#include "values.hpp" #include "template_tags.hpp" +#include "values.hpp" namespace quickbook { @@ -32,10 +32,10 @@ namespace quickbook struct template_symbol { template_symbol( - std::string const& identifier, - std::vector const& params, - value const& content, - template_scope const* parent = 0); + std::string const& identifier, + std::vector const& params, + value const& content, + template_scope const* parent = 0); std::string identifier; std::vector params; @@ -45,7 +45,7 @@ namespace quickbook }; typedef boost::spirit::classic::symbols template_symbols; - + // template scope // // 1.4-: parent_scope is the previous scope on the dynamic @@ -57,7 +57,7 @@ namespace quickbook // correct lookup chain for that version of quickboook. // // symbols contains the templates defined in this scope. - + struct template_scope { template_scope() : parent_scope(), parent_1_4() {} @@ -74,31 +74,27 @@ namespace quickbook { typedef boost::spirit::classic::nil_t result_t; - parser(template_stack& ts_) - : ts(ts_) {} + parser(template_stack& ts_) : ts(ts_) {} template - std::ptrdiff_t - operator()(Scanner const& scan, result_t) const + std::ptrdiff_t operator()(Scanner const& scan, result_t) const { // search all scopes for the longest matching symbol. typename Scanner::iterator_t f = scan.first; std::ptrdiff_t len = -1; - for (template_scope const* i = &*ts.scopes.begin(); i; i = i->parent_scope) - { + for (template_scope const* i = &*ts.scopes.begin(); i; + i = i->parent_scope) { boost::spirit::classic::match<> m = i->symbols.parse(scan); - if (m.length() > len) - len = m.length(); + if (m.length() > len) len = m.length(); scan.first = f; } - if (len >= 0) - scan.first = boost::next(f, len); + if (len >= 0) scan.first = boost::next(f, len); return len; } template_stack& ts; - private: + private: parser& operator=(parser const&); }; @@ -108,7 +104,8 @@ namespace quickbook template_symbols const& top() const; template_scope const& top_scope() const; // Add the given template symbol to the current scope. - // If it doesn't have a scope, sets the symbol's scope to the current scope. + // If it doesn't have a scope, sets the symbol's scope to the current + // scope. bool add(template_symbol const&); void push(); void pop(); @@ -117,8 +114,7 @@ namespace quickbook boost::spirit::classic::functor_parser scope; - private: - + private: friend struct parser; deque scopes; template_scope const* parent_1_4; @@ -128,4 +124,3 @@ namespace quickbook } #endif // BOOST_SPIRIT_QUICKBOOK_TEMPLATE_STACK_HPP - diff --git a/tools/quickbook/src/template_tags.hpp b/tools/quickbook/src/template_tags.hpp index d895707bc9..006200cbd3 100644 --- a/tools/quickbook/src/template_tags.hpp +++ b/tools/quickbook/src/template_tags.hpp @@ -13,6 +13,8 @@ namespace quickbook { + // clang-format off + QUICKBOOK_VALUE_TAGS(template_tags, 0x100, (template_) (attribute_template) @@ -22,6 +24,8 @@ namespace quickbook (phrase) (snippet) ) + + // clang-format on } #endif diff --git a/tools/quickbook/src/utils.cpp b/tools/quickbook/src/utils.cpp index a601245978..f2f155768b 100644 --- a/tools/quickbook/src/utils.cpp +++ b/tools/quickbook/src/utils.cpp @@ -13,104 +13,122 @@ #include #include -namespace quickbook { namespace detail +namespace quickbook { - std::string encode_string(quickbook::string_view str) + namespace detail { - std::string result; - result.reserve(str.size()); - - for (string_iterator it = str.begin(); - it != str.end(); ++it) + std::string encode_string(quickbook::string_view str) { - switch (*it) - { - case '<': result += "<"; break; - case '>': result += ">"; break; - case '&': result += "&"; break; - case '"': result += """; break; - default: result += *it; break; + std::string result; + result.reserve(str.size()); + + for (string_iterator it = str.begin(); it != str.end(); ++it) { + switch (*it) { + case '<': + result += "<"; + break; + case '>': + result += ">"; + break; + case '&': + result += "&"; + break; + case '"': + result += """; + break; + default: + result += *it; + break; + } } - } - return result; - } + return result; + } - void print_char(char ch, std::ostream& out) - { - switch (ch) + void print_char(char ch, std::ostream& out) { - case '<': out << "<"; break; - case '>': out << ">"; break; - case '&': out << "&"; break; - case '"': out << """; break; - default: out << ch; break; - // note ' is not included. see the curse of apos: - // http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos + switch (ch) { + case '<': + out << "<"; + break; + case '>': + out << ">"; + break; + case '&': + out << "&"; + break; + case '"': + out << """; + break; + default: + out << ch; + break; + // note ' is not included. see the curse of apos: + // http://fishbowl.pastiche.org/2003/07/01/the_curse_of_apos + } } - } - void print_string(quickbook::string_view str, std::ostream& out) - { - for (string_iterator cur = str.begin(); - cur != str.end(); ++cur) + void print_string(quickbook::string_view str, std::ostream& out) { - print_char(*cur, out); + for (string_iterator cur = str.begin(); cur != str.end(); ++cur) { + print_char(*cur, out); + } } - } - std::string make_identifier(quickbook::string_view text) - { - std::string id(text.begin(), text.end()); - for (std::string::iterator i = id.begin(); i != id.end(); ++i) { - if (!std::isalnum(static_cast(*i))) { - *i = '_'; - } - else { - *i = static_cast(std::tolower(static_cast(*i))); + std::string make_identifier(quickbook::string_view text) + { + std::string id(text.begin(), text.end()); + for (std::string::iterator i = id.begin(); i != id.end(); ++i) { + if (!std::isalnum(static_cast(*i))) { + *i = '_'; + } + else { + *i = static_cast( + std::tolower(static_cast(*i))); + } } - } - return id; - } + return id; + } - static std::string escape_uri_impl(quickbook::string_view uri_param, char const* mark) - { - // Extra capital characters for validating percent escapes. - static char const hex[] = "0123456789abcdefABCDEF"; + static std::string escape_uri_impl( + quickbook::string_view uri_param, char const* mark) + { + // Extra capital characters for validating percent escapes. + static char const hex[] = "0123456789abcdefABCDEF"; - std::string uri; - uri.reserve(uri_param.size()); + std::string uri; + uri.reserve(uri_param.size()); - for (std::string::size_type n = 0; n < uri_param.size(); ++n) - { - if (static_cast(uri_param[n]) > 127 || + for (std::string::size_type n = 0; n < uri_param.size(); ++n) { + if (static_cast(uri_param[n]) > 127 || (!std::isalnum(static_cast(uri_param[n])) && !std::strchr(mark, uri_param[n])) || - (uri_param[n] == '%' && !(n + 2 < uri_param.size() && - std::strchr(hex, uri_param[n+1]) && - std::strchr(hex, uri_param[n+2])))) - { - char escape[] = { '%', hex[uri_param[n] / 16], hex[uri_param[n] % 16], '\0' }; - uri += escape; + (uri_param[n] == '%' && + !(n + 2 < uri_param.size() && + std::strchr(hex, uri_param[n + 1]) && + std::strchr(hex, uri_param[n + 2])))) { + char escape[] = {'%', hex[uri_param[n] / 16], + hex[uri_param[n] % 16], '\0'}; + uri += escape; + } + else { + uri += uri_param[n]; + } } - else - { - uri += uri_param[n]; - } - } - return uri; - } + return uri; + } - std::string escape_uri(quickbook::string_view uri_param) - { - std::string uri(uri_param.begin(), uri_param.end()); - return escape_uri_impl(uri_param, "-_.!~*'()?\\/"); - } + std::string escape_uri(quickbook::string_view uri_param) + { + std::string uri(uri_param.begin(), uri_param.end()); + return escape_uri_impl(uri_param, "-_.!~*'()?\\/"); + } - std::string partially_escape_uri(quickbook::string_view uri_param) - { - return escape_uri_impl(uri_param, "-_.!~*'()?\\/:&=#%+"); + std::string partially_escape_uri(quickbook::string_view uri_param) + { + return escape_uri_impl(uri_param, "-_.!~*'()?\\/:&=#%+"); + } } -}} +} diff --git a/tools/quickbook/src/utils.hpp b/tools/quickbook/src/utils.hpp index 53cd71f13f..98dd1b4b66 100644 --- a/tools/quickbook/src/utils.hpp +++ b/tools/quickbook/src/utils.hpp @@ -10,25 +10,29 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_UTILS_HPP) #define BOOST_SPIRIT_QUICKBOOK_UTILS_HPP -#include #include +#include #include "string_view.hpp" -namespace quickbook { namespace detail { - std::string encode_string(quickbook::string_view); - void print_char(char ch, std::ostream& out); - void print_string(quickbook::string_view str, std::ostream& out); - std::string make_identifier(quickbook::string_view); +namespace quickbook +{ + namespace detail + { + std::string encode_string(quickbook::string_view); + void print_char(char ch, std::ostream& out); + void print_string(quickbook::string_view str, std::ostream& out); + std::string make_identifier(quickbook::string_view); - // URI escape string - std::string escape_uri(quickbook::string_view); + // URI escape string + std::string escape_uri(quickbook::string_view); - // URI escape string, leaving characters generally used in URIs. - std::string partially_escape_uri(quickbook::string_view); + // URI escape string, leaving characters generally used in URIs. + std::string partially_escape_uri(quickbook::string_view); - // Defined in id_xml.cpp. Just because. - std::string linkify(quickbook::string_view source, quickbook::string_view linkend); -}} + // Defined in id_xml.cpp. Just because. + std::string linkify( + quickbook::string_view source, quickbook::string_view linkend); + } +} #endif // BOOST_SPIRIT_QUICKBOOK_UTILS_HPP - diff --git a/tools/quickbook/src/value_tags.hpp b/tools/quickbook/src/value_tags.hpp index 42a5313fa2..69f90f08b2 100644 --- a/tools/quickbook/src/value_tags.hpp +++ b/tools/quickbook/src/value_tags.hpp @@ -9,71 +9,82 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_VALUES_TAGS_HPP) #define BOOST_SPIRIT_QUICKBOOK_VALUES_TAGS_HPP -#include +#include +#include #include #include -#include +#include #include -#include -#define QUICKBOOK_VALUE_TAGS(tags_name, start_index, values) \ - struct tags_name { \ - enum tags_name##_enum { \ - previous_index = start_index - 1, \ - BOOST_PP_SEQ_ENUM(values), \ - end_index \ - }; \ - \ - static char const* name(int value) { \ - switch(value) {\ - case 0: \ - return "null"; \ - BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_CASE, _, values) \ - default: \ - assert(false); return ""; \ - }; \ - } \ - \ - typedef boost::integer_range range_type; \ - static range_type tags() { return boost::irange(start_index, (int) end_index); } \ - static bool is_tag(int value) { \ - return value >= start_index && value < (int) end_index; \ - } \ +#define QUICKBOOK_VALUE_TAGS(tags_name, start_index, values) \ + struct tags_name \ + { \ + enum tags_name##_enum{previous_index = start_index - 1, \ + BOOST_PP_SEQ_ENUM(values), end_index}; \ + \ + static char const* name(int value) \ + { \ + switch (value) { \ + case 0: \ + return "null"; \ + BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_CASE, _, values) \ + default: \ + assert(false); \ + return ""; \ + }; \ + } \ + \ + typedef boost::integer_range range_type; \ + static range_type tags() \ + { \ + return boost::irange(start_index, (int)end_index); \ + } \ + static bool is_tag(int value) \ + { \ + return value >= start_index && value < (int)end_index; \ + } \ }; -#define QUICKBOOK_VALUE_CASE(r, _, value) \ - case value: return BOOST_PP_STRINGIZE(value); +#define QUICKBOOK_VALUE_CASE(r, _, value) \ + case value: \ + return BOOST_PP_STRINGIZE(value); -#define QUICKBOOK_VALUE_NAMED_TAGS(tags_name, start_index, values) \ - struct tags_name { \ - enum tags_name##_enum { \ - previous_index = start_index - 1 \ - BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_NAMED_ENUM, _, values), \ - end_index \ - }; \ - \ - static char const* name(int value) { \ - switch(value) {\ - case 0: \ - return "null"; \ - BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_NAMED_CASE, _, values) \ - default: \ - assert(false); return ""; \ - }; \ - } \ - \ - typedef boost::integer_range range_type; \ - static range_type tags() { return boost::irange(start_index, (int) end_index); } \ - static bool is_tag(int value) { \ - return value >= start_index && value < (int) end_index; \ - } \ +#define QUICKBOOK_VALUE_NAMED_TAGS(tags_name, start_index, values) \ + struct tags_name \ + { \ + enum tags_name##_enum{previous_index = \ + start_index - \ + 1 BOOST_PP_SEQ_FOR_EACH( \ + QUICKBOOK_VALUE_NAMED_ENUM, _, values), \ + end_index}; \ + \ + static char const* name(int value) \ + { \ + switch (value) { \ + case 0: \ + return "null"; \ + BOOST_PP_SEQ_FOR_EACH(QUICKBOOK_VALUE_NAMED_CASE, _, values) \ + default: \ + assert(false); \ + return ""; \ + }; \ + } \ + \ + typedef boost::integer_range range_type; \ + static range_type tags() \ + { \ + return boost::irange(start_index, (int)end_index); \ + } \ + static bool is_tag(int value) \ + { \ + return value >= start_index && value < (int)end_index; \ + } \ }; -#define QUICKBOOK_VALUE_NAMED_ENUM(r, _, value) \ - , BOOST_PP_SEQ_ELEM(0, value) - -#define QUICKBOOK_VALUE_NAMED_CASE(r, _, value) \ - case BOOST_PP_SEQ_ELEM(0, value): return BOOST_PP_SEQ_ELEM(1, value); +#define QUICKBOOK_VALUE_NAMED_ENUM(r, _, value) , BOOST_PP_SEQ_ELEM(0, value) +#define QUICKBOOK_VALUE_NAMED_CASE(r, _, value) \ + case BOOST_PP_SEQ_ELEM(0, value): \ + return BOOST_PP_SEQ_ELEM(1, value); #endif diff --git a/tools/quickbook/src/values.cpp b/tools/quickbook/src/values.cpp index 8a049e3c1e..6e2c3ec916 100644 --- a/tools/quickbook/src/values.cpp +++ b/tools/quickbook/src/values.cpp @@ -7,50 +7,48 @@ =============================================================================*/ #include "values.hpp" -#include "files.hpp" #include #include +#include "files.hpp" -#define UNDEFINED_ERROR() \ - throw value_undefined_method( \ - std::string(BOOST_CURRENT_FUNCTION) +\ - " not defined for " + \ - this->type_name() + \ - " values." \ - ); +#define UNDEFINED_ERROR() \ + throw value_undefined_method( \ + std::string(BOOST_CURRENT_FUNCTION) + " not defined for " + \ + this->type_name() + " values."); namespace quickbook { //////////////////////////////////////////////////////////////////////////// // Value Error - + struct value_undefined_method : value_error { value_undefined_method(std::string const&); }; - - value_error::value_error(std::string const& x) - : std::logic_error(x) {} + + value_error::value_error(std::string const& x) : std::logic_error(x) {} value_undefined_method::value_undefined_method(std::string const& x) - : value_error(x) {} + : value_error(x) + { + } //////////////////////////////////////////////////////////////////////////// // Node namespace detail { - value_node::value_node(tag_type t) - : ref_count_(0), tag_(t), next_() { - } - - value_node::~value_node() { - } - + value_node::value_node(tag_type t) : ref_count_(0), tag_(t), next_() {} + + value_node::~value_node() {} + file_ptr value_node::get_file() const { UNDEFINED_ERROR(); } string_iterator value_node::get_position() const { UNDEFINED_ERROR(); } int value_node::get_int() const { UNDEFINED_ERROR(); } - quickbook::string_view value_node::get_quickbook() const { UNDEFINED_ERROR(); } + quickbook::string_view value_node::get_quickbook() const + { + UNDEFINED_ERROR(); + } std::string value_node::get_encoded() const { UNDEFINED_ERROR(); } value_node* value_node::get_list() const { UNDEFINED_ERROR(); } @@ -71,9 +69,9 @@ namespace quickbook struct value_list_end_impl : public value_node { static value_list_end_impl instance; - private: - value_list_end_impl() - : value_node(value::default_tag) + + private: + value_list_end_impl() : value_node(value::default_tag) { intrusive_ptr_add_ref(&instance); next_ = this; @@ -83,7 +81,9 @@ namespace quickbook virtual value_node* clone() const { UNDEFINED_ERROR(); } virtual bool equals(value_node* other) const - { return this == other; } + { + return this == other; + } bool empty() const { UNDEFINED_ERROR(); } bool check() const { UNDEFINED_ERROR(); } @@ -93,7 +93,7 @@ namespace quickbook value_list_end_impl value_list_end_impl::instance; } - + //////////////////////////////////////////////////////////////////////////// // Empty/nil values // @@ -106,34 +106,35 @@ namespace quickbook { static value_node* new_(value::tag_type t); - protected: - explicit empty_value_impl(value::tag_type t) - : value_node(t) {} + protected: + explicit empty_value_impl(value::tag_type t) : value_node(t) {} - private: + private: char const* type_name() const { return "empty"; } - + virtual value_node* clone() const - { return new empty_value_impl(tag_); } + { + return new empty_value_impl(tag_); + } - virtual bool empty() const - { return true; } + virtual bool empty() const { return true; } - virtual bool check() const - { return false; } + virtual bool check() const { return false; } virtual bool equals(value_node* other) const - { return !other->check(); } - + { + return !other->check(); + } + friend value quickbook::empty_value(value::tag_type); }; - + struct value_nil_impl : public empty_value_impl { static value_nil_impl instance; - private: - value_nil_impl() - : empty_value_impl(value::default_tag) + + private: + value_nil_impl() : empty_value_impl(value::default_tag) { intrusive_ptr_add_ref(&instance); next_ = &value_list_end_impl::instance; @@ -142,7 +143,8 @@ namespace quickbook value_nil_impl value_nil_impl::instance; - value_node* empty_value_impl::new_(value::tag_type t) { + value_node* empty_value_impl::new_(value::tag_type t) + { // The return value from this function is always placed in an // intrusive_ptr which will manage the memory correctly. // Note that value_nil_impl increments its reference count @@ -166,8 +168,7 @@ namespace quickbook namespace detail { - value_counted::value_counted() - : value_base(&value_nil_impl::instance) + value_counted::value_counted() : value_base(&value_nil_impl::instance) { // Even though empty is not on the heap, its reference // counter needs to be incremented so that the destructor @@ -175,53 +176,35 @@ namespace quickbook intrusive_ptr_add_ref(value_); } - - value_counted::value_counted(value_counted const& x) - : value_base(x) + + value_counted::value_counted(value_counted const& x) : value_base(x) { intrusive_ptr_add_ref(value_); } - - value_counted::value_counted(value_base const& x) - : value_base(x) + + value_counted::value_counted(value_base const& x) : value_base(x) { intrusive_ptr_add_ref(value_); } - - value_counted::value_counted(value_node* x) - : value_base(x) + + value_counted::value_counted(value_node* x) : value_base(x) { intrusive_ptr_add_ref(value_); } - - value_counted::~value_counted() - { - intrusive_ptr_release(value_); - } + + value_counted::~value_counted() { intrusive_ptr_release(value_); } } - + //////////////////////////////////////////////////////////////////////////// // value - value::value() - : detail::value_counted() - { - } + value::value() : detail::value_counted() {} - value::value(value const& x) - : detail::value_counted(x) - { - } + value::value(value const& x) : detail::value_counted(x) {} - value::value(detail::value_base const& x) - : detail::value_counted(x) - { - } + value::value(detail::value_base const& x) : detail::value_counted(x) {} - value::value(detail::value_node* x) - : detail::value_counted(x) - { - } + value::value(detail::value_node* x) : detail::value_counted(x) {} value& value::operator=(value x) { @@ -236,9 +219,10 @@ namespace quickbook { struct int_value_impl : public value_node { - public: + public: explicit int_value_impl(int, value::tag_type); - private: + + private: char const* type_name() const { return "integer"; } virtual value_node* clone() const; virtual int get_int() const; @@ -251,40 +235,31 @@ namespace quickbook }; int_value_impl::int_value_impl(int v, value::tag_type t) - : value_node(t) - , value_(v) - {} + : value_node(t), value_(v) + { + } value_node* int_value_impl::clone() const { return new int_value_impl(value_, tag_); } - int int_value_impl::get_int() const - { - return value_; - } + int int_value_impl::get_int() const { return value_; } std::string int_value_impl::get_encoded() const { return boost::lexical_cast(value_); } - bool int_value_impl::empty() const - { - return false; - } + bool int_value_impl::empty() const { return false; } - bool int_value_impl::is_encoded() const - { - return true; - } + bool int_value_impl::is_encoded() const { return true; } - bool int_value_impl::equals(value_node* other) const { + bool int_value_impl::equals(value_node* other) const + { try { return value_ == other->get_int(); - } - catch(value_undefined_method&) { + } catch (value_undefined_method&) { return false; } } @@ -302,9 +277,10 @@ namespace quickbook { struct encoded_value_impl : public value_node { - public: + public: explicit encoded_value_impl(std::string const&, value::tag_type); - private: + + private: char const* type_name() const { return "encoded text"; } virtual ~encoded_value_impl(); @@ -316,16 +292,17 @@ namespace quickbook std::string value_; }; - + struct qbk_value_impl : public value_node { - public: + public: explicit qbk_value_impl( - file_ptr const&, - string_iterator begin, - string_iterator end, - value::tag_type); - private: + file_ptr const&, + string_iterator begin, + string_iterator end, + value::tag_type); + + private: char const* type_name() const { return "quickbook"; } virtual ~qbk_value_impl(); @@ -340,16 +317,22 @@ namespace quickbook string_iterator begin_; string_iterator end_; }; - + struct encoded_qbk_value_impl : public value_node { - private: - char const* type_name() const { return "encoded text with quickbook reference"; } + private: + char const* type_name() const + { + return "encoded text with quickbook reference"; + } + + encoded_qbk_value_impl( + file_ptr const&, + string_iterator, + string_iterator, + std::string const&, + value::tag_type); - encoded_qbk_value_impl(file_ptr const&, - string_iterator, string_iterator, - std::string const&, value::tag_type); - virtual ~encoded_qbk_value_impl(); virtual value_node* clone() const; virtual file_ptr get_file() const; @@ -364,152 +347,154 @@ namespace quickbook string_iterator begin_; string_iterator end_; std::string encoded_value_; - + friend quickbook::value quickbook::encoded_qbk_value( - file_ptr const&, string_iterator, string_iterator, - std::string const&, quickbook::value::tag_type); + file_ptr const&, + string_iterator, + string_iterator, + std::string const&, + quickbook::value::tag_type); }; // encoded_value_impl - + encoded_value_impl::encoded_value_impl( - std::string const& val, - value::tag_type tag - ) + std::string const& val, value::tag_type tag) : value_node(tag), value_(val) { } - - encoded_value_impl::~encoded_value_impl() - { - } + + encoded_value_impl::~encoded_value_impl() {} value_node* encoded_value_impl::clone() const { return new encoded_value_impl(value_, tag_); } - - std::string encoded_value_impl::get_encoded() const - { return value_; } - bool encoded_value_impl::empty() const - { return value_.empty(); } + std::string encoded_value_impl::get_encoded() const { return value_; } + + bool encoded_value_impl::empty() const { return value_.empty(); } - bool encoded_value_impl::is_encoded() const - { return true; } + bool encoded_value_impl::is_encoded() const { return true; } - bool encoded_value_impl::equals(value_node* other) const { + bool encoded_value_impl::equals(value_node* other) const + { try { return value_ == other->get_encoded(); - } - catch(value_undefined_method&) { + } catch (value_undefined_method&) { return false; } } // qbk_value_impl - + qbk_value_impl::qbk_value_impl( - file_ptr const& f, - string_iterator begin, - string_iterator end, - value::tag_type tag - ) : value_node(tag), file_(f), begin_(begin), end_(end) + file_ptr const& f, + string_iterator begin, + string_iterator end, + value::tag_type tag) + : value_node(tag), file_(f), begin_(begin), end_(end) { } - - qbk_value_impl::~qbk_value_impl() - { - } - + + qbk_value_impl::~qbk_value_impl() {} + value_node* qbk_value_impl::clone() const { return new qbk_value_impl(file_, begin_, end_, tag_); } - file_ptr qbk_value_impl::get_file() const - { return file_; } + file_ptr qbk_value_impl::get_file() const { return file_; } - string_iterator qbk_value_impl::get_position() const - { return begin_; } + string_iterator qbk_value_impl::get_position() const { return begin_; } quickbook::string_view qbk_value_impl::get_quickbook() const - { return quickbook::string_view(begin_, end_ - begin_); } + { + return quickbook::string_view(begin_, end_ - begin_); + } - bool qbk_value_impl::empty() const - { return begin_ == end_; } - - bool qbk_value_impl::equals(value_node* other) const { + bool qbk_value_impl::empty() const { return begin_ == end_; } + + bool qbk_value_impl::equals(value_node* other) const + { try { return this->get_quickbook() == other->get_quickbook(); - } - catch(value_undefined_method&) { + } catch (value_undefined_method&) { return false; } } // encoded_qbk_value_impl - + encoded_qbk_value_impl::encoded_qbk_value_impl( - file_ptr const& f, - string_iterator begin, - string_iterator end, - std::string const& encoded, - value::tag_type tag) + file_ptr const& f, + string_iterator begin, + string_iterator end, + std::string const& encoded, + value::tag_type tag) : value_node(tag) , file_(f) , begin_(begin) , end_(end) , encoded_value_(encoded) - - { - } - - encoded_qbk_value_impl::~encoded_qbk_value_impl() + { } + encoded_qbk_value_impl::~encoded_qbk_value_impl() {} + value_node* encoded_qbk_value_impl::clone() const { return new encoded_qbk_value_impl( - file_, begin_, end_, encoded_value_, tag_); + file_, begin_, end_, encoded_value_, tag_); } - file_ptr encoded_qbk_value_impl::get_file() const - { return file_; } + file_ptr encoded_qbk_value_impl::get_file() const { return file_; } string_iterator encoded_qbk_value_impl::get_position() const - { return begin_; } + { + return begin_; + } quickbook::string_view encoded_qbk_value_impl::get_quickbook() const - { return quickbook::string_view(begin_, end_ - begin_); } + { + return quickbook::string_view(begin_, end_ - begin_); + } std::string encoded_qbk_value_impl::get_encoded() const - { return encoded_value_; } + { + return encoded_value_; + } // Should this test the quickbook, the boostbook or both? bool encoded_qbk_value_impl::empty() const - { return encoded_value_.empty(); } + { + return encoded_value_.empty(); + } - bool encoded_qbk_value_impl::is_encoded() const - { return true; } + bool encoded_qbk_value_impl::is_encoded() const { return true; } - bool encoded_qbk_value_impl::equals(value_node* other) const { + bool encoded_qbk_value_impl::equals(value_node* other) const + { try { return this->get_quickbook() == other->get_quickbook(); + } catch (value_undefined_method&) { } - catch(value_undefined_method&) {} try { return this->get_encoded() == other->get_encoded(); + } catch (value_undefined_method&) { } - catch(value_undefined_method&) {} return false; } } - value qbk_value(file_ptr const& f, string_iterator x, string_iterator y, value::tag_type t) + value qbk_value( + file_ptr const& f, + string_iterator x, + string_iterator y, + value::tag_type t) { return value(new detail::qbk_value_impl(f, x, y, t)); } @@ -520,125 +505,130 @@ namespace quickbook } value encoded_qbk_value( - file_ptr const& f, string_iterator x, string_iterator y, - std::string const& z, value::tag_type t) + file_ptr const& f, + string_iterator x, + string_iterator y, + std::string const& z, + value::tag_type t) { - return value(new detail::encoded_qbk_value_impl(f,x,y,z,t)); + return value(new detail::encoded_qbk_value_impl(f, x, y, z, t)); } ////////////////////////////////////////////////////////////////////////// // List methods - + namespace detail { - namespace { - value_node** list_ref_back(value_node**); - void list_ref(value_node*); - void list_unref(value_node*); - value_node** merge_sort(value_node**); - value_node** merge_sort(value_node**, int); - value_node** merge(value_node**, value_node**, value_node**); - void rotate(value_node**, value_node**, value_node**); - - value_node** list_ref_back(value_node** back) - { - while(*back != &value_list_end_impl::instance) { - intrusive_ptr_add_ref(*back); - back = &(*back)->next_; + namespace + { + value_node** list_ref_back(value_node**); + void list_ref(value_node*); + void list_unref(value_node*); + value_node** merge_sort(value_node**); + value_node** merge_sort(value_node**, int); + value_node** merge(value_node**, value_node**, value_node**); + void rotate(value_node**, value_node**, value_node**); + + value_node** list_ref_back(value_node** back) + { + while (*back != &value_list_end_impl::instance) { + intrusive_ptr_add_ref(*back); + back = &(*back)->next_; + } + + return back; } - - return back; - } - void list_ref(value_node* ptr) - { - while(ptr != &value_list_end_impl::instance) { - intrusive_ptr_add_ref(ptr); - ptr = ptr->next_; + void list_ref(value_node* ptr) + { + while (ptr != &value_list_end_impl::instance) { + intrusive_ptr_add_ref(ptr); + ptr = ptr->next_; + } } - } - void list_unref(value_node* ptr) - { - while(ptr != &value_list_end_impl::instance) { - value_node* next = ptr->next_; - intrusive_ptr_release(ptr); - ptr = next; + void list_unref(value_node* ptr) + { + while (ptr != &value_list_end_impl::instance) { + value_node* next = ptr->next_; + intrusive_ptr_release(ptr); + ptr = next; + } } - } - value_node** merge_sort(value_node** l) - { - if(*l == &value_list_end_impl::instance) - return l; - else - return merge_sort(l, 9999); - } + value_node** merge_sort(value_node** l) + { + if (*l == &value_list_end_impl::instance) + return l; + else + return merge_sort(l, 9999); + } - value_node** merge_sort(value_node** l, int recurse_limit) - { - value_node** p = &(*l)->next_; - for(int count = 0; - count < recurse_limit && *p != &value_list_end_impl::instance; - ++count) + value_node** merge_sort(value_node** l, int recurse_limit) { - p = merge(l, p, merge_sort(p, count)); + value_node** p = &(*l)->next_; + for (int count = 0; count < recurse_limit && + *p != &value_list_end_impl::instance; + ++count) { + p = merge(l, p, merge_sort(p, count)); + } + return p; } - return p; - } - - value_node** merge( + + value_node** merge( value_node** first, value_node** second, value_node** third) - { - for(;;) { - for(;;) { - if(first == second) return third; - if((*second)->tag_ < (*first)->tag_) break; + { + for (;;) { + for (;;) { + if (first == second) return third; + if ((*second)->tag_ < (*first)->tag_) break; + first = &(*first)->next_; + } + + rotate(first, second, third); first = &(*first)->next_; - } - - rotate(first, second, third); - first = &(*first)->next_; - - // Since the two ranges were just swapped, the order is now: - // first...third...second - // - // Also, that since the second section of the list was - // originally before the first, if the heads are equal - // we need to swap to maintain the order. - - for(;;) { - if(first == third) return second; - if((*third)->tag_ <= (*first)->tag_) break; + + // Since the two ranges were just swapped, the order is now: + // first...third...second + // + // Also, that since the second section of the list was + // originally before the first, if the heads are equal + // we need to swap to maintain the order. + + for (;;) { + if (first == third) return second; + if ((*third)->tag_ <= (*first)->tag_) break; + first = &(*first)->next_; + } + + rotate(first, third, second); first = &(*first)->next_; } - - rotate(first, third, second); - first = &(*first)->next_; } - } - void rotate(value_node** first, value_node** second, value_node** third) - { - value_node* tmp = *first; - *first = *second; - *second = *third; - *third = tmp; - //if(*second != &value_list_end_impl::instance) back = second; + void rotate( + value_node** first, value_node** second, value_node** third) + { + value_node* tmp = *first; + *first = *second; + *second = *third; + *third = tmp; + // if(*second != &value_list_end_impl::instance) back = second; + } } } - } ////////////////////////////////////////////////////////////////////////// // Lists - + namespace detail { struct value_list_impl : public value_node { value_list_impl(value::tag_type); value_list_impl(value_list_builder&, value::tag_type); - private: + + private: value_list_impl(value_list_impl const&); char const* type_name() const { return "list"; } @@ -650,16 +640,17 @@ namespace quickbook virtual bool is_list() const; virtual value_node* get_list() const; - + value_node* head_; }; - + value_list_impl::value_list_impl(value::tag_type tag) : value_node(tag), head_(&value_list_end_impl::instance) - {} - - value_list_impl::value_list_impl(value_list_builder& builder, - value::tag_type tag) + { + } + + value_list_impl::value_list_impl( + value_list_builder& builder, value::tag_type tag) : value_node(tag), head_(builder.release()) { } @@ -669,11 +660,8 @@ namespace quickbook { list_ref(head_); } - - value_list_impl::~value_list_impl() - { - list_unref(head_); - } + + value_list_impl::~value_list_impl() { list_unref(head_); } value_node* value_list_impl::clone() const { @@ -684,82 +672,75 @@ namespace quickbook { return head_ == &value_list_end_impl::instance; } - - bool value_list_impl::is_list() const - { - return true; - } - - value_node* value_list_impl::get_list() const - { - return head_; - } - bool value_list_impl::equals(value_node* other) const { + bool value_list_impl::is_list() const { return true; } + + value_node* value_list_impl::get_list() const { return head_; } + + bool value_list_impl::equals(value_node* other) const + { value_node* x1; try { - x1 = other->get_list(); - } - catch(value_undefined_method&) { + x1 = other->get_list(); + } catch (value_undefined_method&) { return false; } - for(value_node *x2 = head_; x1 != x2; x1 = x1->next_, x2 = x2->next_) - { - if (x2 == &value_list_end_impl::instance || - !x1->equals(x2)) return false; + for (value_node *x2 = head_; x1 != x2; + x1 = x1->next_, x2 = x2->next_) { + if (x2 == &value_list_end_impl::instance || !x1->equals(x2)) + return false; } - + return true; } } ////////////////////////////////////////////////////////////////////////// // List builder - + namespace detail { // value_list_builder - + value_list_builder::value_list_builder() - : head_(&value_list_end_impl::instance) - , back_(&head_) - {} + : head_(&value_list_end_impl::instance), back_(&head_) + { + } value_list_builder::value_list_builder(value_node* ptr) - : head_(ptr) - , back_(list_ref_back(&head_)) - {} - - value_list_builder::~value_list_builder() + : head_(ptr), back_(list_ref_back(&head_)) { - list_unref(head_); } - void value_list_builder::swap(value_list_builder& other) { + value_list_builder::~value_list_builder() { list_unref(head_); } + + void value_list_builder::swap(value_list_builder& other) + { std::swap(head_, other.head_); std::swap(back_, other.back_); - if(back_ == &other.head_) back_ = &head_; - if(other.back_ == &head_) other.back_ = &other.head_; + if (back_ == &other.head_) back_ = &head_; + if (other.back_ == &head_) other.back_ = &other.head_; } - value_node* value_list_builder::release() { + value_node* value_list_builder::release() + { value_node* r = head_; head_ = &value_list_end_impl::instance; back_ = &head_; return r; } - + void value_list_builder::append(value_node* item) { - if(item->next_) item = item->clone(); + if (item->next_) item = item->clone(); intrusive_ptr_add_ref(item); item->next_ = *back_; *back_ = item; back_ = &item->next_; } - + void value_list_builder::sort() { back_ = merge_sort(&head_); @@ -774,79 +755,75 @@ namespace quickbook ////////////////////////////////////////////////////////////////////////// // Value builder - + value_builder::value_builder() - : current() - , list_tag(value::default_tag) - , saved() + : current(), list_tag(value::default_tag), saved() { } - - void value_builder::swap(value_builder& other) { + + void value_builder::swap(value_builder& other) + { current.swap(other.current); std::swap(list_tag, other.list_tag); saved.swap(other.saved); } - - void value_builder::save() { + + void value_builder::save() + { boost::scoped_ptr store(new value_builder); swap(*store); saved.swap(store); } - void value_builder::restore() { + void value_builder::restore() + { boost::scoped_ptr store; store.swap(saved); swap(*store); } - value value_builder::release() { + value value_builder::release() + { return value(new detail::value_list_impl(current, list_tag)); } - void value_builder::insert(value const& item) { + void value_builder::insert(value const& item) + { current.append(item.value_); } - void value_builder::extend(value const& list) { + void value_builder::extend(value const& list) + { for (value::iterator begin = list.begin(), end = list.end(); - begin != end; ++begin) - { + begin != end; ++begin) { insert(*begin); } } - void value_builder::start_list(value::tag_type tag) { + void value_builder::start_list(value::tag_type tag) + { save(); list_tag = tag; } - void value_builder::finish_list() { + void value_builder::finish_list() + { value list = release(); restore(); insert(list); } - void value_builder::clear_list() { - restore(); - } + void value_builder::clear_list() { restore(); } - void value_builder::sort_list() - { - current.sort(); - } + void value_builder::sort_list() { current.sort(); } - bool value_builder::empty() const - { - return current.empty(); - } + bool value_builder::empty() const { return current.empty(); } //////////////////////////////////////////////////////////////////////////// // Iterator namespace detail { - value::iterator::iterator() - : ptr_(&value_list_end_impl::instance) {} + value::iterator::iterator() : ptr_(&value_list_end_impl::instance) {} } } diff --git a/tools/quickbook/src/values.hpp b/tools/quickbook/src/values.hpp index 7bcca415e7..3ba75ffe57 100644 --- a/tools/quickbook/src/values.hpp +++ b/tools/quickbook/src/values.hpp @@ -11,16 +11,16 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_VALUES_HPP) #define BOOST_SPIRIT_QUICKBOOK_VALUES_HPP -#include -#include #include #include -#include -#include +#include +#include #include -#include "string_view.hpp" -#include "fwd.hpp" +#include +#include #include "files.hpp" +#include "fwd.hpp" +#include "string_view.hpp" namespace quickbook { @@ -32,21 +32,21 @@ namespace quickbook { //////////////////////////////////////////////////////////////////////// // Node - + struct value_node { - private: + private: value_node(value_node const&); value_node& operator=(value_node const&); - public: + public: typedef int tag_type; - protected: + protected: explicit value_node(tag_type); virtual ~value_node(); - public: + public: virtual char const* type_name() const = 0; virtual value_node* clone() const = 0; @@ -63,15 +63,19 @@ namespace quickbook virtual bool equals(value_node*) const; virtual value_node* get_list() const; - + int ref_count_; const tag_type tag_; value_node* next_; friend void intrusive_ptr_add_ref(value_node* ptr) - { ++ptr->ref_count_; } + { + ++ptr->ref_count_; + } friend void intrusive_ptr_release(value_node* ptr) - { if(--ptr->ref_count_ == 0) delete ptr; } + { + if (--ptr->ref_count_ == 0) delete ptr; + } }; //////////////////////////////////////////////////////////////////////// @@ -79,19 +83,21 @@ namespace quickbook // // This defines most of the public methods for value. // 'begin' and 'end' are defined with the iterators later. - + struct value_base { - public: + public: struct iterator; typedef iterator const_iterator; typedef value_node::tag_type tag_type; - enum { default_tag = 0 }; + enum + { + default_tag = 0 + }; - protected: - explicit value_base(value_node* base) - : value_(base) + protected: + explicit value_base(value_node* base) : value_(base) { assert(value_); } @@ -99,7 +105,8 @@ namespace quickbook ~value_base() {} void swap(value_base& x) { std::swap(value_, x.value_); } - public: + + public: bool check() const { return value_->check(); } bool empty() const { return value_->empty(); } bool is_encoded() const { return value_->is_encoded(); } @@ -110,63 +117,76 @@ namespace quickbook // Item accessors tag_type get_tag() const { return value_->tag_; } - file_ptr get_file() const - { return value_->get_file(); } + file_ptr get_file() const { return value_->get_file(); } string_iterator get_position() const - { return value_->get_position(); } + { + return value_->get_position(); + } quickbook::string_view get_quickbook() const - { return value_->get_quickbook(); } - std::string get_encoded() const - { return value_->get_encoded(); } - int get_int() const - { return value_->get_int(); } + { + return value_->get_quickbook(); + } + std::string get_encoded() const { return value_->get_encoded(); } + int get_int() const { return value_->get_int(); } // Equality is pretty inefficient. Not really designed for anything // more than testing purposes. friend bool operator==(value_base const& x, value_base const& y) - { return x.value_->equals(y.value_); } + { + return x.value_->equals(y.value_); + } - protected: + protected: value_node* value_; // value_builder needs to access 'value_' to get the node // from a value. friend struct quickbook::value_builder; }; - + //////////////////////////////////////////////////////////////////////// // Reference and proxy values for use in iterators struct value_ref : public value_base { - public: + public: explicit value_ref(value_node* base) : value_base(base) {} }; - + struct value_proxy : public value_base { - public: + public: explicit value_proxy(value_node* base) : value_base(base) {} value_proxy* operator->() { return this; } value_ref operator*() const { return value_ref(value_); } }; - + //////////////////////////////////////////////////////////////////////// // Iterators - struct value_base::iterator - : public boost::forward_iterator_helper< - iterator, value, int, value_proxy, value_ref> + struct value_base::iterator : public boost::forward_iterator_helper< + iterator, + value, + int, + value_proxy, + value_ref> { - public: + public: iterator(); explicit iterator(value_node* p) : ptr_(p) {} friend bool operator==(iterator x, iterator y) - { return x.ptr_ == y.ptr_; } - iterator& operator++() { ptr_ = ptr_->next_; return *this; } + { + return x.ptr_ == y.ptr_; + } + iterator& operator++() + { + ptr_ = ptr_->next_; + return *this; + } value_ref operator*() const { return value_ref(ptr_); } value_proxy operator->() const { return value_proxy(ptr_); } - private: + + private: value_node* ptr_; }; @@ -186,7 +206,8 @@ namespace quickbook struct value_counted : public value_base { value_counted& operator=(value_counted const&); - protected: + + protected: value_counted(); value_counted(value_counted const&); value_counted(value_base const&); @@ -200,10 +221,12 @@ namespace quickbook // Values are immutable, so this class is used to build a list of // value nodes before constructing the value. - struct value_list_builder { + struct value_list_builder + { value_list_builder(value_list_builder const&); value_list_builder& operator=(value_list_builder const&); - public: + + public: value_list_builder(); value_list_builder(value_node*); ~value_list_builder(); @@ -214,12 +237,13 @@ namespace quickbook void sort(); bool empty() const; - private: + + private: value_node* head_; value_node** back_; }; } - + //////////////////////////////////////////////////////////////////////////// // Value // @@ -227,7 +251,7 @@ namespace quickbook struct value : public detail::value_counted { - public: + public: value(); value(value const&); value(detail::value_base const&); @@ -235,7 +259,7 @@ namespace quickbook value& operator=(value); void swap(value& x) { detail::value_counted::swap(x); } }; - + // Empty value empty_value(value::tag_type = value::default_tag); @@ -245,28 +269,36 @@ namespace quickbook // String types // Quickbook strings contain a reference to the original quickbook source. - value qbk_value(file_ptr const&, string_iterator, string_iterator, - value::tag_type = value::default_tag); + value qbk_value( + file_ptr const&, + string_iterator, + string_iterator, + value::tag_type = value::default_tag); // Encoded strings are either plain text or boostbook. - value encoded_value(std::string const&, - value::tag_type = value::default_tag); + value encoded_value( + std::string const&, value::tag_type = value::default_tag); // An encoded quickbook string is an encoded string that contains a // reference to the quickbook source it was generated from. - value encoded_qbk_value(file_ptr const&, string_iterator, string_iterator, - std::string const&, value::tag_type = value::default_tag); + value encoded_qbk_value( + file_ptr const&, + string_iterator, + string_iterator, + std::string const&, + value::tag_type = value::default_tag); //////////////////////////////////////////////////////////////////////////// // Value Builder // // Used to incrementally build a valueeter tree. - struct value_builder { - public: + struct value_builder + { + public: value_builder(); void swap(value_builder& b); - + void save(); void restore(); @@ -282,7 +314,7 @@ namespace quickbook bool empty() const; - private: + private: detail::value_list_builder current; value::tag_type list_tag; boost::scoped_ptr saved; @@ -291,10 +323,10 @@ namespace quickbook //////////////////////////////////////////////////////////////////////////// // Value Error // - + struct value_error : public std::logic_error { - public: + public: explicit value_error(std::string const&); }; @@ -303,41 +335,46 @@ namespace quickbook // // Convenience class for unpacking value values. - struct value_consumer { - public: - struct iterator - : public boost::input_iterator_helper::type, - boost::iterator_difference::type, - boost::iterator_pointer::type, - boost::iterator_reference::type> + struct value_consumer + { + public: + struct iterator : public boost::input_iterator_helper< + iterator, + boost::iterator_value::type, + boost::iterator_difference::type, + boost::iterator_pointer::type, + boost::iterator_reference::type> { - public: + public: iterator(); explicit iterator(value::iterator* p) : ptr_(p) {} friend bool operator==(iterator x, iterator y) - { return *x.ptr_ == *y.ptr_; } - iterator& operator++() { ++*ptr_; return *this; } + { + return *x.ptr_ == *y.ptr_; + } + iterator& operator++() + { + ++*ptr_; + return *this; + } reference operator*() const { return **ptr_; } pointer operator->() const { return ptr_->operator->(); } - private: + + private: value::iterator* ptr_; }; typedef iterator const_iterator; typedef iterator::reference reference; - + value_consumer(value const& x) - : list_(x) - , pos_(x.begin()) - , end_(x.end()) - {} + : list_(x), pos_(x.begin()), end_(x.end()) + { + } - value_consumer(reference x) - : list_(x) - , pos_(x.begin()) - , end_(x.end()) - {} + value_consumer(reference x) : list_(x), pos_(x.begin()), end_(x.end()) + { + } reference consume() { @@ -353,7 +390,7 @@ namespace quickbook value optional_consume() { - if(check()) { + if (check()) { return *pos_++; } else { @@ -363,7 +400,7 @@ namespace quickbook value optional_consume(value::tag_type t) { - if(check(t)) { + if (check(t)) { return *pos_++; } else { @@ -371,38 +408,33 @@ namespace quickbook } } - bool check() const - { - return pos_ != end_; - } + bool check() const { return pos_ != end_; } bool check(value::tag_type t) const { return pos_ != end_ && t == pos_->get_tag(); } - + void finish() const { - if (pos_ != end_) - throw value_error("Not all values handled."); + if (pos_ != end_) throw value_error("Not all values handled."); } iterator begin() { return iterator(&pos_); } iterator end() { return iterator(&end_); } - private: - void assert_check() const - { - if (pos_ == end_) - throw value_error("Attempt to read past end of value list."); - } + private: + void assert_check() const + { + if (pos_ == end_) + throw value_error("Attempt to read past end of value list."); + } - void assert_check(value::tag_type t) const - { - assert_check(); - if (t != pos_->get_tag()) - throw value_error("Incorrect value tag."); - } + void assert_check(value::tag_type t) const + { + assert_check(); + if (t != pos_->get_tag()) throw value_error("Incorrect value tag."); + } value list_; value::iterator pos_, end_; diff --git a/tools/quickbook/src/values_parse.hpp b/tools/quickbook/src/values_parse.hpp index 00d69ee3dd..ee9cb2be7c 100644 --- a/tools/quickbook/src/values_parse.hpp +++ b/tools/quickbook/src/values_parse.hpp @@ -9,19 +9,22 @@ #if !defined(BOOST_SPIRIT_QUICKBOOK_VALUES_PARSE_HPP) #define BOOST_SPIRIT_QUICKBOOK_VALUES_PARSE_HPP -#include "values.hpp" +#include #include "parsers.hpp" #include "scoped.hpp" -#include +#include "values.hpp" #include -namespace quickbook { +namespace quickbook +{ namespace ph = phoenix; struct value_builder_save : scoped_action_base { - explicit value_builder_save(value_builder& builder_) : builder(builder_) {} + explicit value_builder_save(value_builder& builder_) : builder(builder_) + { + } bool start() { @@ -33,13 +36,15 @@ namespace quickbook { value_builder& builder; - private: + private: value_builder_save& operator=(value_builder_save const&); }; struct value_builder_list : scoped_action_base { - explicit value_builder_list(value_builder& builder_) : builder(builder_) {} + explicit value_builder_list(value_builder& builder_) : builder(builder_) + { + } bool start(value::tag_type tag = value::default_tag) { @@ -52,28 +57,37 @@ namespace quickbook { value_builder& builder; - private: + private: value_builder_list& operator=(value_builder_list const&); }; struct value_entry { - template - struct result { + template < + typename Arg1, + typename Arg2 = void, + typename Arg3 = void, + typename Arg4 = void> + struct result + { typedef void type; }; explicit value_entry(value_builder& builder_, file_ptr* current_file_) - : builder(builder_), current_file(current_file_) {} - - void operator()(parse_iterator begin, parse_iterator end, - value::tag_type tag = value::default_tag) const + : builder(builder_), current_file(current_file_) { - builder.insert(qbk_value(*current_file, begin.base(), end.base(), tag)); } - void operator()(int v, + void operator()( + parse_iterator begin, + parse_iterator end, value::tag_type tag = value::default_tag) const + { + builder.insert( + qbk_value(*current_file, begin.base(), end.base(), tag)); + } + + void operator()(int v, value::tag_type tag = value::default_tag) const { builder.insert(int_value(v, tag)); } @@ -81,24 +95,21 @@ namespace quickbook { value_builder& builder; file_ptr* current_file; - private: + private: value_entry& operator=(value_entry const&); }; struct value_sort { typedef void result_type; - - explicit value_sort(value_builder& builder_) - : builder(builder_) {} - void operator()() const { - builder.sort_list(); - } + explicit value_sort(value_builder& builder_) : builder(builder_) {} + + void operator()() const { builder.sort_list(); } value_builder& builder; - private: + private: value_sort& operator=(value_sort const&); }; @@ -110,8 +121,9 @@ namespace quickbook { , list(value_builder_list(builder)) , entry(value_entry(builder, current_file)) , sort(value_sort(builder)) - {} - + { + } + value release() { return builder.release(); } value_builder builder; diff --git a/tools/quickbook/test/callouts.cpp b/tools/quickbook/test/callouts.cpp index 82981e7159..8506a93f1b 100644 --- a/tools/quickbook/test/callouts.cpp +++ b/tools/quickbook/test/callouts.cpp @@ -3,6 +3,8 @@ // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or move at http://www.boost.org/LICENSE_1_0.txt) +// clang-format off + /*< This shouldn't be used. >*/ //[ example1 diff --git a/tools/quickbook/test/quickbook-testing.jam b/tools/quickbook/test/quickbook-testing.jam index 614facec5d..5133532a92 100644 --- a/tools/quickbook/test/quickbook-testing.jam +++ b/tools/quickbook/test/quickbook-testing.jam @@ -45,7 +45,7 @@ rule quickbook-test ( target-name : input ? : reference-output ? : requirements local boost-root = [ modules.peek : BOOST_ROOT ] ; - local t = + local t1 = [ targets.create-typed-target QUICKBOOK_OUTPUT : $(project) : $(target-name).boostbook @@ -53,23 +53,26 @@ rule quickbook-test ( target-name : input ? : reference-output ? : requirements : $(requirements) $(target-name).test $(boost-root)/tools/quickbook/src//quickbook - ] + ] ; + local t2 = [ targets.create-typed-target RUN : $(project) : $(target-name) - : $(boost-root)/tools/quickbook/test/src//line-compare-tool + : $(boost-root)/tools/quickbook/test/src/text_diff.cpp : $(requirements) - $(target-name).test + $(target-name).test2 $(reference-output) $(target-name).boostbook on ] ; - modules.poke testing : .all-tests : \$\(all-tests\) $(t) ; + local all-tests = [ modules.peek testing : .all-tests ] ; + all-tests += $(t2) ; + modules.poke testing : .all-tests : $(all-tests) ; - return $(t) ; + return $(t1) $(t2) ; } rule quickbook-fail-test ( target-name : input ? : requirements * ) @@ -92,7 +95,9 @@ rule quickbook-fail-test ( target-name : input ? : requirements * ) ] ; - modules.poke testing : .all-tests : \$\(all-tests\) $(t) ; + local all-tests = [ modules.peek testing : .all-tests ] ; + all-tests += $(t) ; + modules.poke testing : .all-tests : $(all-tests) ; return $(t) ; } @@ -118,7 +123,9 @@ rule quickbook-error-test ( target-name : input ? : requirements * ) ] ; - modules.poke testing : .all-tests : \$\(all-tests\) $(t) ; + local all-tests = [ modules.peek testing : .all-tests ] ; + all-tests += $(t) ; + modules.poke testing : .all-tests : $(all-tests) ; return $(t) ; } diff --git a/tools/quickbook/test/snippets/pass_thru.cpp b/tools/quickbook/test/snippets/pass_thru.cpp index 4d729d3599..c5c120a174 100644 --- a/tools/quickbook/test/snippets/pass_thru.cpp +++ b/tools/quickbook/test/snippets/pass_thru.cpp @@ -1,3 +1,5 @@ +// clang-format off + //[foo_cpp_copyright /*============================================================================= Copyright (c) 2011 Daniel James diff --git a/tools/quickbook/test/snippets/unbalanced_snippet2.cpp b/tools/quickbook/test/snippets/unbalanced_snippet2.cpp index 238b976357..b2fcb247b7 100644 --- a/tools/quickbook/test/snippets/unbalanced_snippet2.cpp +++ b/tools/quickbook/test/snippets/unbalanced_snippet2.cpp @@ -7,4 +7,3 @@ License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ - diff --git a/tools/quickbook/test/src/Jamfile.v2 b/tools/quickbook/test/src/Jamfile.v2 deleted file mode 100644 index f90ba25d71..0000000000 --- a/tools/quickbook/test/src/Jamfile.v2 +++ /dev/null @@ -1,9 +0,0 @@ -# -# Copyright (c) 2011 Daniel James -# -# Distributed under the Boost Software License, Version 1.0. (See -# accompanying file LICENSE_1_0.txt or copy at -# http://www.boost.org/LICENSE_1_0.txt) -# - -exe line-compare-tool : text_diff.cpp ; diff --git a/tools/quickbook/test/src/text_diff.cpp b/tools/quickbook/test/src/text_diff.cpp index 1617f9cd52..cee521173b 100644 --- a/tools/quickbook/test/src/text_diff.cpp +++ b/tools/quickbook/test/src/text_diff.cpp @@ -6,21 +6,21 @@ // http://www.boost.org/LICENSE_1_0.txt) // +#include #include #include #include -#include #include -#include #include +#include namespace spirit = boost::spirit::classic; typedef std::istream_iterator iterator; typedef spirit::scanner scanner; -int main(int argc, char * argv[]) +int main(int argc, char* argv[]) { std::vector args; bool usage_error = false; @@ -30,17 +30,18 @@ int main(int argc, char * argv[]) if (strcmp(argv[i], "--strict") == 0) { // Ignore --strict because the build file accidentally // uses it. Why yes, this is a horrible hack. - } else { + } + else { std::cerr << "ERROR: Invalid flag: " << argv[i] << std::endl; usage_error = true; } - } else { + } + else { args.push_back(argv[i]); } } - if (!usage_error && args.size() != 2) - { + if (!usage_error && args.size() != 2) { std::cerr << "ERROR: Wrong number of arguments." << std::endl; usage_error = true; } @@ -50,12 +51,10 @@ int main(int argc, char * argv[]) return 1; } - std::ifstream - file1(args[0], std::ios_base::binary | std::ios_base::in), + std::ifstream file1(args[0], std::ios_base::binary | std::ios_base::in), file2(args[1], std::ios_base::binary | std::ios_base::in); - if (!file1 || !file2) - { + if (!file1 || !file2) { std::cerr << "ERROR: Unable to open one or both files." << std::endl; return 2; } @@ -63,24 +62,17 @@ int main(int argc, char * argv[]) file1.unsetf(std::ios_base::skipws); file2.unsetf(std::ios_base::skipws); - iterator - iter_file1(file1), - iter_file2(file2); + iterator iter_file1(file1), iter_file2(file2); - scanner - scan1(iter_file1, iterator()), - scan2(iter_file2, iterator()); + scanner scan1(iter_file1, iterator()), scan2(iter_file2, iterator()); std::size_t line = 1, column = 1; - while (!scan1.at_end() && !scan2.at_end()) - { - if (spirit::eol_p.parse(scan1)) - { - if (!spirit::eol_p.parse(scan2)) - { - std::cout << "Files differ at line " << line << ", column " << - column << '.' << std::endl; + while (!scan1.at_end() && !scan2.at_end()) { + if (spirit::eol_p.parse(scan1)) { + if (!spirit::eol_p.parse(scan2)) { + std::cout << "Files differ at line " << line << ", column " + << column << '.' << std::endl; return 3; } @@ -88,18 +80,16 @@ int main(int argc, char * argv[]) continue; } - if (*scan1 != *scan2) - { - std::cout << "Files differ at line " << line << ", column " << - column << '.' << std::endl; + if (*scan1 != *scan2) { + std::cout << "Files differ at line " << line << ", column " + << column << '.' << std::endl; return 4; } ++scan1, ++scan2, ++column; } - if (scan1.at_end() != scan2.at_end()) - { + if (scan1.at_end() != scan2.at_end()) { std::cout << "Files differ in length." << std::endl; return 5; } diff --git a/tools/quickbook/test/stub.cpp b/tools/quickbook/test/stub.cpp index 358f291e3f..ef0f03432d 100644 --- a/tools/quickbook/test/stub.cpp +++ b/tools/quickbook/test/stub.cpp @@ -7,6 +7,8 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ +// clang-format off + /*` This should appear when =stub.cpp= is included. */ #include diff --git a/tools/quickbook/test/unit/cleanup_test.cpp b/tools/quickbook/test/unit/cleanup_test.cpp index 93e98c5e2e..4952c991a4 100644 --- a/tools/quickbook/test/unit/cleanup_test.cpp +++ b/tools/quickbook/test/unit/cleanup_test.cpp @@ -7,31 +7,36 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "cleanup.hpp" -#include #include +#include +#include "cleanup.hpp" -struct counted { +struct counted +{ static int count; static std::vector destroyed; - static void reset() { + static void reset() + { count = 0; destroyed.clear(); } int value; - counted(int v) : value(v) { + counted(int v) : value(v) + { BOOST_TEST(value != -1); ++count; } - counted(counted const& x) : value(x.value) { + counted(counted const& x) : value(x.value) + { BOOST_TEST(value != -1); ++count; } - ~counted() { + ~counted() + { BOOST_TEST(value != -1); destroyed.push_back(value); value = -1; @@ -43,7 +48,8 @@ struct counted { int counted::count = 0; std::vector counted::destroyed; -int main() { +int main() +{ counted::reset(); { quickbook::cleanup c; diff --git a/tools/quickbook/test/unit/glob_test.cpp b/tools/quickbook/test/unit/glob_test.cpp index bbae3786f4..27d2611b35 100644 --- a/tools/quickbook/test/unit/glob_test.cpp +++ b/tools/quickbook/test/unit/glob_test.cpp @@ -6,10 +6,11 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "glob.hpp" #include +#include "glob.hpp" -void glob_tests() { +void glob_tests() +{ BOOST_TEST(quickbook::glob("", "")); BOOST_TEST(!quickbook::glob("*", "")); diff --git a/tools/quickbook/test/unit/path_test.cpp b/tools/quickbook/test/unit/path_test.cpp index 0d05e41ea2..734769ef6e 100644 --- a/tools/quickbook/test/unit/path_test.cpp +++ b/tools/quickbook/test/unit/path_test.cpp @@ -6,12 +6,13 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "path.hpp" #include #include #include +#include "path.hpp" -void file_path_to_url_tests() { +void file_path_to_url_tests() +{ using boost::filesystem::path; using quickbook::file_path_to_url; @@ -22,28 +23,37 @@ void file_path_to_url_tests() { BOOST_TEST_EQ(std::string("a/b/"), file_path_to_url(path("a/b/"))); BOOST_TEST_EQ(std::string("./a/b"), file_path_to_url(path("./a/./././b"))); BOOST_TEST_EQ(std::string("../a/b"), file_path_to_url(path("../a/b"))); - BOOST_TEST_EQ(std::string("A%20B%2bC%2520"), file_path_to_url(path("A B+C%20"))); + BOOST_TEST_EQ( + std::string("A%20B%2bC%2520"), file_path_to_url(path("A B+C%20"))); BOOST_TEST_EQ(std::string("file:///"), file_path_to_url(path("/"))); BOOST_TEST_EQ(std::string("file:///a/b"), file_path_to_url(path("/a/b"))); BOOST_TEST_EQ(std::string("file:///a/b/"), file_path_to_url(path("/a/b/"))); - BOOST_TEST_EQ(std::string("file://hello/a/b"), file_path_to_url(path("//hello/a/b"))); + BOOST_TEST_EQ( + std::string("file://hello/a/b"), file_path_to_url(path("//hello/a/b"))); #if BOOST_OS_WINDOWS || BOOST_OS_CYGWIN // Should this be file:///c:/x ? - BOOST_TEST_EQ(std::string("file://?/a:/x"), file_path_to_url(path("\\\\?\\a:\\x"))); + BOOST_TEST_EQ( + std::string("file://?/a:/x"), file_path_to_url(path("\\\\?\\a:\\x"))); BOOST_TEST_EQ(std::string("file:///a"), file_path_to_url(path("\\a"))); BOOST_TEST_EQ(std::string("file:///c:/"), file_path_to_url(path("c:\\"))); - BOOST_TEST_EQ(std::string("file:///c:/foo/bar"), file_path_to_url(path("c:\\foo\\bar"))); - BOOST_TEST_EQ(std::string("file://localhost/c:/foo/bar"), file_path_to_url(path("\\\\localhost\\c:\\foo\\bar"))); + BOOST_TEST_EQ( + std::string("file:///c:/foo/bar"), + file_path_to_url(path("c:\\foo\\bar"))); + BOOST_TEST_EQ( + std::string("file://localhost/c:/foo/bar"), + file_path_to_url(path("\\\\localhost\\c:\\foo\\bar"))); // Really not sure what to do with these examples. // Maybe an error? BOOST_TEST_EQ(std::string("file:///c:"), file_path_to_url(path("c:"))); - BOOST_TEST_EQ(std::string("file:///c:foo/bar"), file_path_to_url(path("c:foo\\bar"))); + BOOST_TEST_EQ( + std::string("file:///c:foo/bar"), file_path_to_url(path("c:foo\\bar"))); #endif } -void dir_path_to_url_tests() { +void dir_path_to_url_tests() +{ using boost::filesystem::path; using quickbook::dir_path_to_url; @@ -54,29 +64,37 @@ void dir_path_to_url_tests() { BOOST_TEST_EQ(std::string("a/b/"), dir_path_to_url(path("a/b/"))); BOOST_TEST_EQ(std::string("./a/b/"), dir_path_to_url(path("./a/./././b"))); BOOST_TEST_EQ(std::string("../a/b/"), dir_path_to_url(path("../a/b"))); - BOOST_TEST_EQ(std::string("A%20B%2bC%2520/"), dir_path_to_url(path("A B+C%20"))); + BOOST_TEST_EQ( + std::string("A%20B%2bC%2520/"), dir_path_to_url(path("A B+C%20"))); BOOST_TEST_EQ(std::string("file:///"), dir_path_to_url(path("/"))); BOOST_TEST_EQ(std::string("file:///a/b/"), dir_path_to_url(path("/a/b"))); BOOST_TEST_EQ(std::string("file:///a/b/"), dir_path_to_url(path("/a/b/"))); - BOOST_TEST_EQ(std::string("file://hello/a/b/"), dir_path_to_url(path("//hello/a/b"))); + BOOST_TEST_EQ( + std::string("file://hello/a/b/"), dir_path_to_url(path("//hello/a/b"))); #if BOOST_OS_WINDOWS || BOOST_OS_CYGWIN // Should this be file:///c:/x/ ? - BOOST_TEST_EQ(std::string("file://?/a:/x/"), dir_path_to_url(path("\\\\?\\a:\\x"))); + BOOST_TEST_EQ( + std::string("file://?/a:/x/"), dir_path_to_url(path("\\\\?\\a:\\x"))); BOOST_TEST_EQ(std::string("file:///a/"), dir_path_to_url(path("\\a"))); BOOST_TEST_EQ(std::string("file:///c:/"), dir_path_to_url(path("c:\\"))); - BOOST_TEST_EQ(std::string("file:///c:/foo/bar/"), dir_path_to_url(path("c:\\foo\\bar"))); - BOOST_TEST_EQ(std::string("file://localhost/c:/foo/bar/"), dir_path_to_url(path("\\\\localhost\\c:\\foo\\bar"))); + BOOST_TEST_EQ( + std::string("file:///c:/foo/bar/"), + dir_path_to_url(path("c:\\foo\\bar"))); + BOOST_TEST_EQ( + std::string("file://localhost/c:/foo/bar/"), + dir_path_to_url(path("\\\\localhost\\c:\\foo\\bar"))); // Really not sure what to do with these examples. // Maybe an error? BOOST_TEST_EQ(std::string("file:///c:"), dir_path_to_url(path("c:"))); - BOOST_TEST_EQ(std::string("file:///c:foo/bar/"), dir_path_to_url(path("c:foo\\bar"))); + BOOST_TEST_EQ( + std::string("file:///c:foo/bar/"), dir_path_to_url(path("c:foo\\bar"))); #endif - } -void path_difference_tests() { +void path_difference_tests() +{ using boost::filesystem::current_path; using boost::filesystem::path; using quickbook::path_difference; @@ -86,19 +104,31 @@ void path_difference_tests() { BOOST_TEST(path(".") == path_difference(path("a/../b"), path("b"))); BOOST_TEST(path(".") == path_difference(current_path(), current_path())); BOOST_TEST(path("..") == path_difference(path("a"), path(""))); - BOOST_TEST(path("..") == path_difference(current_path()/"a", current_path())); + BOOST_TEST( + path("..") == path_difference(current_path() / "a", current_path())); BOOST_TEST(path("a") == path_difference(path(""), path("a"))); - BOOST_TEST(path("a") == path_difference(current_path(), current_path()/"a")); + BOOST_TEST( + path("a") == path_difference(current_path(), current_path() / "a")); BOOST_TEST(path("b") == path_difference(path("a"), path("a/b"))); - BOOST_TEST(path("b") == path_difference(current_path()/"a", current_path()/"a"/"b")); + BOOST_TEST( + path("b") == + path_difference(current_path() / "a", current_path() / "a" / "b")); BOOST_TEST(path("../a/b") == path_difference(path("c"), path("a/b"))); - BOOST_TEST(path("../a/b") == path_difference(current_path()/"c", current_path()/"a"/"b")); + BOOST_TEST( + path("../a/b") == + path_difference(current_path() / "c", current_path() / "a" / "b")); BOOST_TEST(path("..") == path_difference(path(""), path(".."))); - BOOST_TEST(path("..") == path_difference(current_path(), current_path().parent_path())); + BOOST_TEST( + path("..") == + path_difference(current_path(), current_path().parent_path())); BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b"))); BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("a/b"))); - BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("d/f/../../a/b"))); - BOOST_TEST(path("../../x/a/b") == path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"))); + BOOST_TEST( + path("b") == + path_difference(path("b/c/../../a"), path("d/f/../../a/b"))); + BOOST_TEST( + path("../../x/a/b") == + path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"))); // path_difference to a file, try to include the filename in the result, // although not always possible. Maybe nonsense calls should be an error? @@ -108,29 +138,50 @@ void path_difference_tests() { // always called with the full path, but it'd be nice to get this right. // Or maybe just add the pre-condition to path_difference? std::cout << path_difference(path(""), path(""), true) << std::endl; - //BOOST_TEST(path(".") == path_difference(path(""), path(""), true)); + // BOOST_TEST(path(".") == path_difference(path(""), path(""), true)); BOOST_TEST(path("../a") == path_difference(path("a"), path("a"), true)); - BOOST_TEST(path("../../a") == path_difference(path("a/b"), path("a"), true)); - BOOST_TEST(path("../b") == path_difference(path("a/../b"), path("b"), true)); - BOOST_TEST(".."/current_path().filename() == path_difference(current_path(), current_path(), true)); - //BOOST_TEST(path("..") == path_difference(path("a"), path(""), true)); - BOOST_TEST("../.."/current_path().filename() == path_difference(current_path()/"a", current_path(), true)); + BOOST_TEST( + path("../../a") == path_difference(path("a/b"), path("a"), true)); + BOOST_TEST( + path("../b") == path_difference(path("a/../b"), path("b"), true)); + BOOST_TEST( + ".." / current_path().filename() == + path_difference(current_path(), current_path(), true)); + // BOOST_TEST(path("..") == path_difference(path("a"), path(""), true)); + BOOST_TEST( + "../.." / current_path().filename() == + path_difference(current_path() / "a", current_path(), true)); BOOST_TEST(path("a") == path_difference(path(""), path("a"), true)); - BOOST_TEST(path("a") == path_difference(current_path(), current_path()/"a", true)); + BOOST_TEST( + path("a") == + path_difference(current_path(), current_path() / "a", true)); BOOST_TEST(path("b") == path_difference(path("a"), path("a/b"), true)); - BOOST_TEST(path("b") == path_difference(current_path()/"a", current_path()/"a"/"b", true)); + BOOST_TEST( + path("b") == + path_difference( + current_path() / "a", current_path() / "a" / "b", true)); BOOST_TEST(path("../a/b") == path_difference(path("c"), path("a/b"), true)); - BOOST_TEST(path("../a/b") == path_difference(current_path()/"c", current_path()/"a"/"b", true)); - //BOOST_TEST(path("..") == path_difference(path(""), path(".."), true)); - BOOST_TEST("../.."/current_path().parent_path().filename() == + BOOST_TEST( + path("../a/b") == + path_difference( + current_path() / "c", current_path() / "a" / "b", true)); + // BOOST_TEST(path("..") == path_difference(path(""), path(".."), true)); + BOOST_TEST( + "../.." / current_path().parent_path().filename() == path_difference(current_path(), current_path().parent_path(), true)); BOOST_TEST(path("b") == path_difference(path("a/c/.."), path("a/b"), true)); - BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("a/b"), true)); - BOOST_TEST(path("b") == path_difference(path("b/c/../../a"), path("d/f/../../a/b"), true)); - BOOST_TEST(path("../../x/a/b") == path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"), true)); + BOOST_TEST( + path("b") == path_difference(path("b/c/../../a"), path("a/b"), true)); + BOOST_TEST( + path("b") == + path_difference(path("b/c/../../a"), path("d/f/../../a/b"), true)); + BOOST_TEST( + path("../../x/a/b") == + path_difference(path("b/c/../../a"), path("d/f/../../../x/a/b"), true)); } -int main() { +int main() +{ file_path_to_url_tests(); dir_path_to_url_tests(); path_difference_tests(); diff --git a/tools/quickbook/test/unit/post_process_test.cpp b/tools/quickbook/test/unit/post_process_test.cpp index 737d233c25..e7681c72da 100644 --- a/tools/quickbook/test/unit/post_process_test.cpp +++ b/tools/quickbook/test/unit/post_process_test.cpp @@ -6,25 +6,22 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "post_process.hpp" #include +#include "post_process.hpp" -#define EXPECT_EXCEPTION(test, msg) \ - try { \ - test; \ - BOOST_ERROR(msg); \ - } \ - catch(quickbook::post_process_failure&) { \ +#define EXPECT_EXCEPTION(test, msg) \ + try { \ + test; \ + BOOST_ERROR(msg); \ + } catch (quickbook::post_process_failure&) { \ } int main() { EXPECT_EXCEPTION( - quickbook::post_process(""), - "Succeeded with unbalanced tag"); + quickbook::post_process(""), "Succeeded with unbalanced tag"); EXPECT_EXCEPTION( - quickbook::post_process("<"), - "Succeeded with badly formed tag"); + quickbook::post_process("<"), "Succeeded with badly formed tag"); return boost::report_errors(); } diff --git a/tools/quickbook/test/unit/source_map_test.cpp b/tools/quickbook/test/unit/source_map_test.cpp index bca63855e0..6248ac1f66 100644 --- a/tools/quickbook/test/unit/source_map_test.cpp +++ b/tools/quickbook/test/unit/source_map_test.cpp @@ -6,46 +6,52 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "fwd.hpp" -#include "files.hpp" -#include "string_view.hpp" #include #include +#include "files.hpp" +#include "fwd.hpp" +#include "string_view.hpp" void simple_map_tests() { quickbook::string_view source("First Line\nSecond Line"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); quickbook::string_iterator line1 = fake_file->source().begin(); - quickbook::string_iterator line1_end = boost::find(fake_file->source(), '\n'); + quickbook::string_iterator line1_end = + boost::find(fake_file->source(), '\n'); quickbook::string_iterator line2 = line1_end + 1; quickbook::string_iterator line2_end = fake_file->source().end(); quickbook::mapped_file_builder builder; - + { // Empty test builder.start(fake_file); BOOST_TEST(builder.empty()); quickbook::file_ptr f1 = builder.release(); BOOST_TEST(f1->source().empty()); } - + { // Add full text builder.start(fake_file); builder.add(quickbook::string_view(line1, line2_end - line1)); quickbook::file_ptr f1 = builder.release(); BOOST_TEST_EQ(f1->source(), source); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(1,3)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line1_end - line1)), - quickbook::file_position(1,line1_end - line1 + 1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2 - line1)), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(1, 3)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line1_end - line1)), + quickbook::file_position(1, line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2 - line1)), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), fake_file->position_of(fake_file->source().end())); } @@ -53,14 +59,18 @@ void simple_map_tests() builder.start(fake_file); builder.add(quickbook::string_view(line1, line1_end - line1)); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), + BOOST_TEST_EQ( + f1->source(), quickbook::string_view(source.begin(), line1_end - line1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(1,3)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(1,line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(1, 3)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(1, line1_end - line1 + 1)); } { // Add second line @@ -68,12 +78,15 @@ void simple_map_tests() builder.add(quickbook::string_view(line2, line2_end - line2)); quickbook::file_ptr f1 = builder.release(); BOOST_TEST_EQ(f1->source(), quickbook::string_view("Second Line")); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(2,3)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(2,line2_end - line2 + 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(2, 3)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(2, line2_end - line2 + 1)); } { // Out of order @@ -82,21 +95,27 @@ void simple_map_tests() builder.add(quickbook::string_view(line1_end, 1)); builder.add(quickbook::string_view(line1, line1_end - line1)); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Second Line\nFirst Line")); - - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(2,3)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2 - 1)), - quickbook::file_position(2,line2_end - line2)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2)), - quickbook::file_position(1,(line1_end - line1 + 1))); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2 + 1)), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(1,line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Second Line\nFirst Line")); + + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(2, 3)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2 - 1)), + quickbook::file_position(2, line2_end - line2)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2)), + quickbook::file_position(1, (line1_end - line1 + 1))); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2 + 1)), + quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(1, line1_end - line1 + 1)); } { // Repeated text @@ -105,84 +124,100 @@ void simple_map_tests() builder.add(quickbook::string_view(line1_end, 1)); builder.add(quickbook::string_view(line2, line2_end - line2)); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Second Line\nSecond Line")); - - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(2,3)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2 - 1)), - quickbook::file_position(2,line2_end - line2)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2)), - quickbook::file_position(1,(line1_end - line1 + 1))); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + (line2_end - line2 + 1)), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(2,line2_end - line2 + 1)); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Second Line\nSecond Line")); + + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(2, 3)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2 - 1)), + quickbook::file_position(2, line2_end - line2)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2)), + quickbook::file_position(1, (line1_end - line1 + 1))); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + (line2_end - line2 + 1)), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(2, line2_end - line2 + 1)); } - { // Generated text builder.start(fake_file); builder.add_at_pos("------\n", line1); builder.add(quickbook::string_view(line1, line1_end - line1)); builder.add_at_pos("\n------\n", line1_end); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("------\nFirst Line\n------\n")); - + quickbook::string_iterator newline = boost::find(f1->source(), '\n'); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 2), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(newline), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(newline + 1), - quickbook::file_position(1,1)); - BOOST_TEST_EQ(f1->position_of(newline + 2), - quickbook::file_position(1,2)); - BOOST_TEST_EQ(f1->position_of(newline + (line1_end - line1)), - quickbook::file_position(1,line1_end - line1)); - BOOST_TEST_EQ(f1->position_of(newline + (line1_end - line1 + 1)), - quickbook::file_position(1,line1_end - line1 + 1)); - BOOST_TEST_EQ(f1->position_of(newline + (line1_end - line1 + 2)), - quickbook::file_position(1,line1_end - line1 + 1)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(1,line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 2), + quickbook::file_position(1, 1)); + BOOST_TEST_EQ(f1->position_of(newline), quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(newline + 1), quickbook::file_position(1, 1)); + BOOST_TEST_EQ( + f1->position_of(newline + 2), quickbook::file_position(1, 2)); + BOOST_TEST_EQ( + f1->position_of(newline + (line1_end - line1)), + quickbook::file_position(1, line1_end - line1)); + BOOST_TEST_EQ( + f1->position_of(newline + (line1_end - line1 + 1)), + quickbook::file_position(1, line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->position_of(newline + (line1_end - line1 + 2)), + quickbook::file_position(1, line1_end - line1 + 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(1, line1_end - line1 + 1)); } } void indented_map_tests() { - quickbook::string_view source( - " Code line1\n" - " Code line2\n"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::string_view source(" Code line1\n" + " Code line2\n"); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); quickbook::mapped_file_builder builder; - + { builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\nCode line2\n")); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 1), - quickbook::file_position(1,5)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 5), - quickbook::file_position(1,9)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 10), - quickbook::file_position(1,14)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 11), - quickbook::file_position(2,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(3,1)); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\nCode line2\n")); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 1), + quickbook::file_position(1, 5)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 5), + quickbook::file_position(1, 9)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 10), + quickbook::file_position(1, 14)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 11), + quickbook::file_position(2, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(3, 1)); } { @@ -195,20 +230,26 @@ void indented_map_tests() } quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\nCode line2\n")); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 1), - quickbook::file_position(1,5)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 5), - quickbook::file_position(1,9)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 10), - quickbook::file_position(1,14)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 11), - quickbook::file_position(2,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(3,1)); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\nCode line2\n")); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 1), + quickbook::file_position(1, 5)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 5), + quickbook::file_position(1, 9)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 10), + quickbook::file_position(1, 14)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 11), + quickbook::file_position(2, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(3, 1)); } { @@ -217,52 +258,64 @@ void indented_map_tests() fake_file->source().begin() + 3, fake_file->source().end() - (fake_file->source().begin() + 3))); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\n Code line2\n")); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 1), - quickbook::file_position(1,5)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 5), - quickbook::file_position(1,9)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 10), - quickbook::file_position(1,14)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 11), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().end()), - quickbook::file_position(3,1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 1), + quickbook::file_position(1, 5)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 5), + quickbook::file_position(1, 9)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 10), + quickbook::file_position(1, 14)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 11), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().end()), + quickbook::file_position(3, 1)); } } void indented_map_tests2() { - quickbook::string_view source( - " Code line1\n" - "\n" - " Code line2\n"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::string_view source(" Code line1\n" + "\n" + " Code line2\n"); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); quickbook::mapped_file_builder builder; - + { builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n\nCode line2\n")); - BOOST_TEST_EQ(f1->position_of(f1->source().begin()), - quickbook::file_position(1,4)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 1), - quickbook::file_position(1,5)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 5), - quickbook::file_position(1,9)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 10), - quickbook::file_position(1,14)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 11), - quickbook::file_position(2,1)); - BOOST_TEST_EQ(f1->position_of(f1->source().begin() + 12), - quickbook::file_position(3,4)); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\n\nCode line2\n")); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin()), + quickbook::file_position(1, 4)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 1), + quickbook::file_position(1, 5)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 5), + quickbook::file_position(1, 9)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 10), + quickbook::file_position(1, 14)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 11), + quickbook::file_position(2, 1)); + BOOST_TEST_EQ( + f1->position_of(f1->source().begin() + 12), + quickbook::file_position(3, 4)); } } @@ -272,35 +325,33 @@ void indented_map_leading_blanks_test() { quickbook::string_view source("\n\n Code line1\n"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n")); + BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n")); } { quickbook::string_view source(" \n \n Code line1\n"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n")); + BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n")); } { quickbook::string_view source(" Code line1\n \n Code line2"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n\nCode line2")); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\n\nCode line2")); } } @@ -310,37 +361,34 @@ void indented_map_trailing_blanks_test() { quickbook::string_view source("\n\n Code line1\n "); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n")); + BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n")); } { quickbook::string_view source(" \n \n Code line1\n "); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n ")); + BOOST_TEST_EQ(f1->source(), quickbook::string_view("Code line1\n ")); } { quickbook::string_view source(" Code line1\n \n Code line2\n "); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line1\n\nCode line2\n")); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line1\n\nCode line2\n")); } - } void indented_map_mixed_test() @@ -348,40 +396,42 @@ void indented_map_mixed_test() quickbook::mapped_file_builder builder; { - quickbook::string_view source("\tCode line 1\n Code line 2\n\t Code line 3\n \tCode line 4"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::string_view source("\tCode line 1\n Code line 2\n\t " + "Code line 3\n \tCode line 4"); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line 1\nCode line 2\n Code line 3\n Code line 4")); + BOOST_TEST_EQ( + f1->source(), + quickbook::string_view( + "Code line 1\nCode line 2\n Code line 3\n Code line 4")); } { quickbook::string_view source(" Code line 1\n\tCode line 2"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line 1\n Code line 2")); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line 1\n Code line 2")); } { quickbook::string_view source(" Code line 1\n \tCode line 2"); - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); builder.start(fake_file); builder.unindent_and_add(fake_file->source()); quickbook::file_ptr f1 = builder.release(); - BOOST_TEST_EQ(f1->source(), - quickbook::string_view("Code line 1\n\tCode line 2")); + BOOST_TEST_EQ( + f1->source(), quickbook::string_view("Code line 1\n\tCode line 2")); } } - int main() { simple_map_tests(); diff --git a/tools/quickbook/test/unit/symbols_find_null.cpp b/tools/quickbook/test/unit/symbols_find_null.cpp index 4f3ca6cc37..0be8ab1e58 100644 --- a/tools/quickbook/test/unit/symbols_find_null.cpp +++ b/tools/quickbook/test/unit/symbols_find_null.cpp @@ -12,22 +12,23 @@ #include "symbols.hpp" typedef char char_type; -typedef char const * iterator; +typedef char const* iterator; char_type data_[] = "whatever"; iterator begin = data_; -iterator end = data_ - + sizeof(data_)/sizeof(char_type); // Yes, this is an intentional bug ;) +iterator end = + data_ + + sizeof(data_) / sizeof(char_type); // Yes, this is an intentional bug ;) int main() { typedef BOOST_SPIRIT_CLASSIC_NS::scanner<> scanner; - typedef quickbook::tst symbols; + typedef quickbook::tst symbols; symbols symbols_; - symbols_.add(begin, end - 1, (void*) boost::addressof(symbols_)); + symbols_.add(begin, end - 1, (void*)boost::addressof(symbols_)); // The symbol table parser should not choke on input containing the null // character. diff --git a/tools/quickbook/test/unit/symbols_tests.cpp b/tools/quickbook/test/unit/symbols_tests.cpp index dbf3f68ac1..41f37b5e77 100644 --- a/tools/quickbook/test/unit/symbols_tests.cpp +++ b/tools/quickbook/test/unit/symbols_tests.cpp @@ -12,7 +12,6 @@ #include #include #include -#include #include #include "symbols.hpp" @@ -22,12 +21,9 @@ using namespace BOOST_SPIRIT_CLASSIC_NS; /////////////////////////////////////////////////////////////////////////////// -template -bool -equal(IteratorT p, IteratorT q) +template bool equal(IteratorT p, IteratorT q) { - while (*p && *p == *q) - { + while (*p && *p == *q) { ++p; ++q; } @@ -35,85 +31,71 @@ equal(IteratorT p, IteratorT q) } template -void -docheck -( - SymbolsT const &sym, - CharT const *candidate, - bool hit, - CharT const *result, - int length -) +void docheck( + SymbolsT const& sym, + CharT const* candidate, + bool hit, + CharT const* result, + int length) { parse_info info = parse(candidate, sym); #define correctly_matched hit == info.hit #define correct_match_length unsigned(length) == info.length -#define correct_tail equal(candidate + (hit?1:0)*length, result) +#define correct_tail equal(candidate + (hit ? 1 : 0) * length, result) BOOST_TEST(correctly_matched); - if (hit) - { + if (hit) { BOOST_TEST(correct_match_length); BOOST_TEST(correct_tail); } - else - { + else { BOOST_TEST(correct_tail); } } -template -struct store_action +template struct store_action { - store_action(T const &v) : value(v) {} - void operator()(T &v) const { v = value; } -private: + store_action(T const& v) : value(v) {} + void operator()(T& v) const { v = value; } + + private: T const value; }; -template -store_action -store(T const &v) -{ - return v; -} +template store_action store(T const& v) { return v; } -template -struct check_action +template struct check_action { - check_action(T const &v) : value(v) {} + check_action(T const& v) : value(v) {} + +#define correct_value_stored (v == value) + void operator()(T const& v) const { BOOST_TEST(correct_value_stored); } -#define correct_value_stored (v==value) - void operator()(T const &v) const { BOOST_TEST(correct_value_stored); } -private: + private: T const value; }; -template -check_action -docheck(T const &v) -{ - return v; -} +template check_action docheck(T const& v) { return v; } -static void -default_constructible() -{ // this actually a compile time test +static void default_constructible() +{ // this actually a compile time test symbols > ns1; symbols > ws1; symbols > ns2; symbols > ws2; - (void)ns1; (void)ws1; (void)ns2; (void)ws2; + (void)ns1; + (void)ws1; + (void)ns2; + (void)ws2; } typedef symbols > nsymbols; typedef symbols > wsymbols; -static void -narrow_match_tests() +static void narrow_match_tests() { nsymbols sym; sym = "pineapple", "orange", "banana", "applepie", "apple"; @@ -142,8 +124,7 @@ narrow_match_tests() docheck(sym, "applepix", true, "pix", 5); } -static void -narrow_copy_ctor_tests() +static void narrow_copy_ctor_tests() { nsymbols sym; sym = "pineapple", "orange", "banana", "applepie", "apple"; @@ -154,8 +135,7 @@ narrow_copy_ctor_tests() docheck(sym2, "bananarama", true, "rama", 6); } -static void -narrow_assigment_operator_tests() +static void narrow_assigment_operator_tests() { nsymbols sym; sym = "pineapple", "orange", "banana", "applepie", "apple"; @@ -168,8 +148,7 @@ narrow_assigment_operator_tests() docheck(sym2, "bananarama", true, "rama", 6); } -static void -narrow_swap_tests() +static void narrow_swap_tests() { nsymbols sym, sym2; sym = "pineapple", "orange", "banana", "applepie", "apple"; @@ -184,13 +163,12 @@ narrow_swap_tests() docheck(sym, "cauliflour", false, "cauliflour", -1); } -static void -narrow_value_tests() -{ // also tests the add member functions +static void narrow_value_tests() +{ // also tests the add member functions nsymbols sym; sym = "orange", "banana"; - sym.add("pineapple",1234); + sym.add("pineapple", 1234); sym.add("lemon"); parse("orange", sym[store(12345)]); @@ -200,19 +178,18 @@ narrow_value_tests() parse("lemon", sym[docheck(int())]); } -static void -narrow_free_functions_tests() +static void narrow_free_functions_tests() { nsymbols sym; -#define add_returned_non_null_value (res!=0) -#define add_returned_null (res==0) -#define find_returned_non_null_value (res!=0) -#define find_returned_null (res==0) +#define add_returned_non_null_value (res != 0) +#define add_returned_null (res == 0) +#define find_returned_non_null_value (res != 0) +#define find_returned_null (res == 0) - int *res = add(sym,"pineapple"); + int* res = add(sym, "pineapple"); BOOST_TEST(add_returned_non_null_value); - res = add(sym,"pineapple"); + res = add(sym, "pineapple"); BOOST_TEST(add_returned_null); res = find(sym, "pineapple"); @@ -221,8 +198,7 @@ narrow_free_functions_tests() BOOST_TEST(find_returned_null); } -static void -wide_match_tests() +static void wide_match_tests() { wsymbols sym; sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple"; @@ -251,8 +227,7 @@ wide_match_tests() docheck(sym, L"applepix", true, L"pix", 5); } -static void -wide_copy_ctor_tests() +static void wide_copy_ctor_tests() { wsymbols sym; sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple"; @@ -263,8 +238,7 @@ wide_copy_ctor_tests() docheck(sym2, L"bananarama", true, L"rama", 6); } -static void -wide_assigment_operator_tests() +static void wide_assigment_operator_tests() { wsymbols sym; sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple"; @@ -277,8 +251,7 @@ wide_assigment_operator_tests() docheck(sym2, L"bananarama", true, L"rama", 6); } -static void -wide_swap_tests() +static void wide_swap_tests() { wsymbols sym, sym2; sym = L"pineapple", L"orange", L"banana", L"applepie", L"apple"; @@ -293,13 +266,12 @@ wide_swap_tests() docheck(sym, L"cauliflour", false, L"cauliflour", -1); } -static void -wide_value_tests() -{ // also tests the add member functions +static void wide_value_tests() +{ // also tests the add member functions wsymbols sym; sym = L"orange", L"banana"; - sym.add(L"pineapple",1234); + sym.add(L"pineapple", 1234); sym.add(L"lemon"); parse(L"orange", sym[store(12345)]); @@ -309,14 +281,13 @@ wide_value_tests() parse(L"lemon", sym[docheck(int())]); } -static void -wide_free_functions_tests() +static void wide_free_functions_tests() { wsymbols sym; - int *res = add(sym,L"pineapple"); + int* res = add(sym, L"pineapple"); BOOST_TEST(add_returned_non_null_value); - res = add(sym,L"pineapple"); + res = add(sym, L"pineapple"); BOOST_TEST(add_returned_null); res = find(sym, L"pineapple"); @@ -325,8 +296,7 @@ wide_free_functions_tests() BOOST_TEST(find_returned_null); } -static -void free_add_find_functions_tests() +static void free_add_find_functions_tests() { nsymbols sym; BOOST_TEST(*add(sym, "a", 0) == 0); @@ -343,18 +313,17 @@ void free_add_find_functions_tests() struct check_parse_value { - explicit check_parse_value(int value) : value_(value){} - + explicit check_parse_value(int value) : value_(value) {} + void operator()(int value) const { BOOST_TEST(value == value_); } - + int value_; }; // My version is different to the original, if there's an existing value // it replaces it with the new one. -static -void duplicate_add_tests() +static void duplicate_add_tests() { char const* foo1 = "foo"; char const* foo2 = foo1 + 3; @@ -364,7 +333,7 @@ void duplicate_add_tests() nsymbols sym2 = sym; sym.add(foo1, foo2, 2); sym2.add(foo1, foo2, 3); - + BOOST_TEST(find(sym, "foo") && *find(sym, "foo") == 2); BOOST_TEST(find(sym2, "foo") && *find(sym2, "foo") == 3); @@ -383,8 +352,7 @@ void duplicate_add_tests() BOOST_TEST(info.hit && info.length == 3); } -int -main() +int main() { default_constructible(); narrow_match_tests(); diff --git a/tools/quickbook/test/unit/utils_test.cpp b/tools/quickbook/test/unit/utils_test.cpp index ce56f2f293..15e081bc98 100644 --- a/tools/quickbook/test/unit/utils_test.cpp +++ b/tools/quickbook/test/unit/utils_test.cpp @@ -7,29 +7,35 @@ http://www.boost.org/LICENSE_1_0.txt) =============================================================================*/ -#include "utils.hpp" #include +#include "utils.hpp" #include -void linkify_test() { +void linkify_test() +{ using quickbook::detail::linkify; BOOST_TEST(linkify("abc", "link") == "abc"); - BOOST_TEST(linkify("abc", "link") == + BOOST_TEST( + linkify("abc", "link") == "abc"); - BOOST_TEST(linkify("abc def", "link") == + BOOST_TEST( + linkify("abc def", "link") == "abc def"); - BOOST_TEST(linkify("abc def", "link") == + BOOST_TEST( + linkify("abc def", "link") == "abc def"); } -void encode_string_test() { +void encode_string_test() +{ using quickbook::detail::encode_string; BOOST_TEST_EQ(std::string("<A&B>"), encode_string("")); } -void escape_uri_test() { +void escape_uri_test() +{ using quickbook::detail::escape_uri; using quickbook::detail::partially_escape_uri; @@ -37,7 +43,8 @@ void escape_uri_test() { BOOST_TEST_EQ(std::string("%20%25%25"), partially_escape_uri("%20%25%")); } -int main() { +int main() +{ linkify_test(); encode_string_test(); escape_uri_test(); diff --git a/tools/quickbook/test/unit/values_test.cpp b/tools/quickbook/test/unit/values_test.cpp index 6c1bc6a3c7..d0036d4289 100644 --- a/tools/quickbook/test/unit/values_test.cpp +++ b/tools/quickbook/test/unit/values_test.cpp @@ -9,11 +9,11 @@ // Some very light testing for quickbook::value and friends. // Just for a few issues that came up during development. +#include #include #include -#include -#include "values.hpp" #include "files.hpp" +#include "values.hpp" void empty_tests() { @@ -28,12 +28,10 @@ void qbk_tests() std::string source = "Source"; quickbook::value q; { - quickbook::file_ptr fake_file = new quickbook::file( - "(fake file)", source, 105u); + quickbook::file_ptr fake_file = + new quickbook::file("(fake file)", source, 105u); q = quickbook::qbk_value( - fake_file, - fake_file->source().begin(), - fake_file->source().end()); + fake_file, fake_file->source().begin(), fake_file->source().end()); } BOOST_TEST_EQ(q.get_quickbook(), quickbook::string_view(source)); } @@ -46,12 +44,16 @@ void sort_test() b.insert(quickbook::encoded_value("c", 5)); b.insert(quickbook::encoded_value("d", 8)); b.sort_list(); - + quickbook::value_consumer c = b.release(); - BOOST_TEST(c.check(2)); BOOST_TEST_EQ(c.consume(2).get_encoded(), "b"); - BOOST_TEST(c.check(5)); c.consume(5); - BOOST_TEST(c.check(8)); c.consume(8); - BOOST_TEST(c.check(10)); c.consume(10); + BOOST_TEST(c.check(2)); + BOOST_TEST_EQ(c.consume(2).get_encoded(), "b"); + BOOST_TEST(c.check(5)); + c.consume(5); + BOOST_TEST(c.check(8)); + c.consume(8); + BOOST_TEST(c.check(10)); + c.consume(10); BOOST_TEST(!c.check()); } @@ -92,7 +94,7 @@ void equality_tests() quickbook::value_builder builder; quickbook::value nil; - + // 0: nil distinct_values.push_back(nil); @@ -103,12 +105,12 @@ void equality_tests() builder.insert(nil); distinct_values.push_back(builder.release()); - for(std::size_t i = 0; i < distinct_values.size(); ++i) { - for(std::size_t j = 0; j < distinct_values.size(); ++j) { + for (std::size_t i = 0; i < distinct_values.size(); ++i) { + for (std::size_t j = 0; j < distinct_values.size(); ++j) { if ((i == j) != (distinct_values[i] == distinct_values[j])) { BOOST_ERROR("Value mismatch."); - BOOST_LIGHTWEIGHT_TEST_OSTREAM - << "\tat " << i << ", " << j << std::endl; + BOOST_LIGHTWEIGHT_TEST_OSTREAM << "\tat " << i << ", " << j + << std::endl; } } } -- cgit v1.2.3