From 3faecf9a00512dcbc8712c4bca9adae72fb64410 Mon Sep 17 00:00:00 2001 From: Kenneth Heafield Date: Sat, 12 May 2012 14:01:52 -0400 Subject: Give in and copy bjam into cdec source code --- jam-files/boost-build/util/__init__.py | 136 +++++ jam-files/boost-build/util/assert.jam | 336 +++++++++++ jam-files/boost-build/util/container.jam | 339 +++++++++++ jam-files/boost-build/util/doc.jam | 997 +++++++++++++++++++++++++++++++ jam-files/boost-build/util/indirect.jam | 115 ++++ jam-files/boost-build/util/indirect.py | 15 + jam-files/boost-build/util/logger.py | 46 ++ jam-files/boost-build/util/numbers.jam | 218 +++++++ jam-files/boost-build/util/option.jam | 109 ++++ jam-files/boost-build/util/option.py | 35 ++ jam-files/boost-build/util/order.jam | 169 ++++++ jam-files/boost-build/util/order.py | 121 ++++ jam-files/boost-build/util/os.jam | 171 ++++++ jam-files/boost-build/util/os_j.py | 19 + jam-files/boost-build/util/path.jam | 934 +++++++++++++++++++++++++++++ jam-files/boost-build/util/path.py | 904 ++++++++++++++++++++++++++++ jam-files/boost-build/util/print.jam | 488 +++++++++++++++ jam-files/boost-build/util/regex.jam | 193 ++++++ jam-files/boost-build/util/regex.py | 25 + jam-files/boost-build/util/sequence.jam | 335 +++++++++++ jam-files/boost-build/util/sequence.py | 50 ++ jam-files/boost-build/util/set.jam | 93 +++ jam-files/boost-build/util/set.py | 42 ++ jam-files/boost-build/util/string.jam | 189 ++++++ jam-files/boost-build/util/utility.jam | 235 ++++++++ jam-files/boost-build/util/utility.py | 155 +++++ 26 files changed, 6469 insertions(+) create mode 100644 jam-files/boost-build/util/__init__.py create mode 100644 jam-files/boost-build/util/assert.jam create mode 100644 jam-files/boost-build/util/container.jam create mode 100644 jam-files/boost-build/util/doc.jam create mode 100644 jam-files/boost-build/util/indirect.jam create mode 100644 jam-files/boost-build/util/indirect.py create mode 100644 jam-files/boost-build/util/logger.py create mode 100644 jam-files/boost-build/util/numbers.jam create mode 100644 jam-files/boost-build/util/option.jam create mode 100644 jam-files/boost-build/util/option.py create mode 100644 jam-files/boost-build/util/order.jam create mode 100644 jam-files/boost-build/util/order.py create mode 100644 jam-files/boost-build/util/os.jam create mode 100644 jam-files/boost-build/util/os_j.py create mode 100644 jam-files/boost-build/util/path.jam create mode 100644 jam-files/boost-build/util/path.py create mode 100644 jam-files/boost-build/util/print.jam create mode 100644 jam-files/boost-build/util/regex.jam create mode 100644 jam-files/boost-build/util/regex.py create mode 100644 jam-files/boost-build/util/sequence.jam create mode 100644 jam-files/boost-build/util/sequence.py create mode 100644 jam-files/boost-build/util/set.jam create mode 100644 jam-files/boost-build/util/set.py create mode 100644 jam-files/boost-build/util/string.jam create mode 100644 jam-files/boost-build/util/utility.jam create mode 100644 jam-files/boost-build/util/utility.py (limited to 'jam-files/boost-build/util') diff --git a/jam-files/boost-build/util/__init__.py b/jam-files/boost-build/util/__init__.py new file mode 100644 index 00000000..f80fe70e --- /dev/null +++ b/jam-files/boost-build/util/__init__.py @@ -0,0 +1,136 @@ + +import bjam +import re +import types + +# Decorator the specifies bjam-side prototype for a Python function +def bjam_signature(s): + + def wrap(f): + f.bjam_signature = s + return f + + return wrap + +def metatarget(f): + + f.bjam_signature = (["name"], ["sources", "*"], ["requirements", "*"], + ["default_build", "*"], ["usage_requirements", "*"]) + return f + +class cached(object): + + def __init__(self, function): + self.function = function + self.cache = {} + + def __call__(self, *args): + try: + return self.cache[args] + except KeyError: + v = self.function(*args) + self.cache[args] = v + return v + + def __get__(self, instance, type): + return types.MethodType(self, instance, type) + +def unquote(s): + if s and s[0] == '"' and s[-1] == '"': + return s[1:-1] + else: + return s + +_extract_jamfile_and_rule = re.compile("(Jamfile<.*>)%(.*)") + +def qualify_jam_action(action_name, context_module): + + if action_name.startswith("###"): + # Callable exported from Python. Don't touch + return action_name + elif _extract_jamfile_and_rule.match(action_name): + # Rule is already in indirect format + return action_name + else: + ix = action_name.find('.') + if ix != -1 and action_name[:ix] == context_module: + return context_module + '%' + action_name[ix+1:] + + return context_module + '%' + action_name + + +def set_jam_action(name, *args): + + m = _extract_jamfile_and_rule.match(name) + if m: + args = ("set-update-action-in-module", m.group(1), m.group(2)) + args + else: + args = ("set-update-action", name) + args + + return bjam.call(*args) + + +def call_jam_function(name, *args): + + m = _extract_jamfile_and_rule.match(name) + if m: + args = ("call-in-module", m.group(1), m.group(2)) + args + return bjam.call(*args) + else: + return bjam.call(*((name,) + args)) + +__value_id = 0 +__python_to_jam = {} +__jam_to_python = {} + +def value_to_jam(value, methods=False): + """Makes a token to refer to a Python value inside Jam language code. + + The token is merely a string that can be passed around in Jam code and + eventually passed back. For example, we might want to pass PropertySet + instance to a tag function and it might eventually call back + to virtual_target.add_suffix_and_prefix, passing the same instance. + + For values that are classes, we'll also make class methods callable + from Jam. + + Note that this is necessary to make a bit more of existing Jamfiles work. + This trick should not be used to much, or else the performance benefits of + Python port will be eaten. + """ + + global __value_id + + r = __python_to_jam.get(value, None) + if r: + return r + + exported_name = '###_' + str(__value_id) + __value_id = __value_id + 1 + __python_to_jam[value] = exported_name + __jam_to_python[exported_name] = value + + if methods and type(value) == types.InstanceType: + for field_name in dir(value): + field = getattr(value, field_name) + if callable(field) and not field_name.startswith("__"): + bjam.import_rule("", exported_name + "." + field_name, field) + + return exported_name + +def record_jam_to_value_mapping(jam_value, python_value): + __jam_to_python[jam_value] = python_value + +def jam_to_value_maybe(jam_value): + + if type(jam_value) == type(""): + return __jam_to_python.get(jam_value, jam_value) + else: + return jam_value + +def stem(filename): + i = filename.find('.') + if i != -1: + return filename[0:i] + else: + return filename diff --git a/jam-files/boost-build/util/assert.jam b/jam-files/boost-build/util/assert.jam new file mode 100644 index 00000000..abedad52 --- /dev/null +++ b/jam-files/boost-build/util/assert.jam @@ -0,0 +1,336 @@ +# Copyright 2001, 2002, 2003 Dave Abrahams +# Copyright 2006 Rene Rivera +# Copyright 2002, 2003 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) + +import errors ; +import modules ; + + +################################################################################ +# +# Private implementation details. +# +################################################################################ + +# Rule added as a replacement for the regular Jam = operator but which does not +# ignore trailing empty string elements. +# +local rule exact-equal-test ( lhs * : rhs * ) +{ + local lhs_extended = $(lhs) xxx ; + local rhs_extended = $(rhs) xxx ; + if $(lhs_extended) = $(rhs_extended) + { + return true ; + } +} + + +# Two lists are considered set-equal if they contain the same elements, ignoring +# duplicates and ordering. +# +local rule set-equal-test ( set1 * : set2 * ) +{ + if ( $(set1) in $(set2) ) && ( $(set2) in $(set1) ) + { + return true ; + } +} + + +################################################################################ +# +# Public interface. +# +################################################################################ + +# Assert the equality of A and B, ignoring trailing empty string elements. +# +rule equal ( a * : b * ) +{ + if $(a) != $(b) + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" + (ignoring trailing empty strings) ; + } +} + + +# Assert that the result of calling RULE-NAME on the given arguments has a false +# logical value (is either an empty list or all empty strings). +# +rule false ( rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) + : $(7) : $(8) : $(9) ] ; + } + + if $(result) + { + 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) ] "]" : Got: "[" \"$(result)\" "]" ; + } +} + + +# Assert that ELEMENT is present in LIST. +# +rule "in" ( element : list * ) +{ + if ! $(element) in $(list) + { + errors.error-skip-frames 3 assertion failure: Expected \"$(element)\" in + "[" \"$(list)\" "]" ; + } +} + + +# Assert the inequality of A and B, ignoring trailing empty string elements. +# +rule not-equal ( a * : b * ) +{ + if $(a) = $(b) + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" + (ignoring trailing empty strings) ; + } +} + + +# Assert that ELEMENT is not present in LIST. +# +rule not-in ( element : list * ) +{ + if $(element) in $(list) + { + errors.error-skip-frames 3 assertion failure: Did not expect + \"$(element)\" in "[" \"$(list)\" "]" ; + } +} + + +# Assert the inequality of A and B as sets. +# +rule not-set-equal ( a * : b * ) +{ + if [ set-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + and "[" \"$(b)\" "]" to not be equal as sets ; + } +} + + +# Assert that A and B are not exactly equal, not ignoring trailing empty string +# elements. +# +rule not-exact-equal ( a * : b * ) +{ + if [ exact-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "!=" \"$(b)\" ; + } +} + + +# Assert that EXPECTED is the result of calling RULE-NAME with the given +# arguments. +# +rule result ( expected * : rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) + : $(8) : $(9) ] ; + } + + if ! [ exact-equal-test $(result) : $(expected) ] + { + errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + \"$(result)\" "]" ; + } +} + + +# Assert that EXPECTED is set-equal (i.e. duplicates and ordering are ignored) +# to the result of calling RULE-NAME with the given arguments. Note that rules +# called this way may accept at most 8 parameters. +# +rule result-set-equal ( expected * : rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(2) : $(3) : $(4) : $(5) : $(6) : $(7) + : $(8) : $(9) ] ; + } + + if ! [ set-equal-test $(result) : $(expected) ] + { + errors.error-skip-frames 3 assertion failure: "[" $(rule-name) [ + errors.lol->list $(args) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : + $(9) ] "]" : Expected: "[" \"$(expected)\" "]" : Got: "[" + \"$(result)\" "]" ; + } +} + + +# Assert the equality of A and B as sets. +# +rule set-equal ( a * : b * ) +{ + if ! [ set-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: Expected "[" \"$(a)\" "]" + and "[" \"$(b)\" "]" to be equal as sets ; + } +} + + +# Assert that the result of calling RULE-NAME on the given arguments has a true +# logical value (is neither an empty list nor all empty strings). +# +rule true ( rule-name args * : * ) +{ + local result ; + module [ CALLER_MODULE ] + { + modules.poke assert : result : [ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) + : $(7) : $(8) : $(9) ] ; + } + + if ! $(result) + { + 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) ] "]" ; + } +} + + +# Assert the exact equality of A and B, not ignoring trailing empty string +# elements. +# +rule exact-equal ( a * : b * ) +{ + if ! [ exact-equal-test $(a) : $(b) ] + { + errors.error-skip-frames 3 assertion failure: \"$(a)\" "==" \"$(b)\" ; + } +} + + +# Assert that the given variable is not an empty list. +# +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 + \"$(name)\" not to be an empty list ; + } +} + + +rule __test__ ( ) +{ + # Helper rule used to avoid test duplication related to different list + # equality test rules. + # + local rule run-equality-test ( equality-assert : ignore-trailing-empty-strings ? ) + { + local not-equality-assert = not-$(equality-assert) ; + + # When the given equality test is expected to ignore trailing empty + # strings some of the test results should be inverted. + local not-equality-assert-i = not-$(equality-assert) ; + if $(ignore-trailing-empty-strings) + { + not-equality-assert-i = $(equality-assert) ; + } + + $(equality-assert) : ; + $(equality-assert) "" "" : "" "" ; + $(not-equality-assert-i) : "" "" ; + $(equality-assert) x : x ; + $(not-equality-assert) : x ; + $(not-equality-assert) "" : x ; + $(not-equality-assert) "" "" : x ; + $(not-equality-assert-i) x : x "" ; + $(equality-assert) x "" : x "" ; + $(not-equality-assert) x : "" x ; + $(equality-assert) "" x : "" x ; + + $(equality-assert) 1 2 3 : 1 2 3 ; + $(not-equality-assert) 1 2 3 : 3 2 1 ; + $(not-equality-assert) 1 2 3 : 1 5 3 ; + $(not-equality-assert) 1 2 3 : 1 "" 3 ; + $(not-equality-assert) 1 2 3 : 1 1 2 3 ; + $(not-equality-assert) 1 2 3 : 1 2 2 3 ; + $(not-equality-assert) 1 2 3 : 5 6 7 ; + + # Extra variables used here just to make sure Boost Jam or Boost Build + # do not handle lists with empty strings differently depending on + # whether they are literals or stored in variables. + + local empty = ; + local empty-strings = "" "" ; + local x-empty-strings = x "" "" ; + local empty-strings-x = "" "" x ; + + $(equality-assert) : $(empty) ; + $(not-equality-assert-i) "" : $(empty) ; + $(not-equality-assert-i) "" "" : $(empty) ; + $(not-equality-assert-i) : $(empty-strings) ; + $(not-equality-assert-i) "" : $(empty-strings) ; + $(equality-assert) "" "" : $(empty-strings) ; + $(equality-assert) $(empty) : $(empty) ; + $(equality-assert) $(empty-strings) : $(empty-strings) ; + $(not-equality-assert-i) $(empty) : $(empty-strings) ; + $(equality-assert) $(x-empty-strings) : $(x-empty-strings) ; + $(equality-assert) $(empty-strings-x) : $(empty-strings-x) ; + $(not-equality-assert) $(empty-strings-x) : $(x-empty-strings) ; + $(not-equality-assert-i) x : $(x-empty-strings) ; + $(not-equality-assert) x : $(empty-strings-x) ; + $(not-equality-assert-i) x : $(x-empty-strings) ; + $(not-equality-assert-i) x "" : $(x-empty-strings) ; + $(equality-assert) x "" "" : $(x-empty-strings) ; + $(not-equality-assert) x : $(empty-strings-x) ; + $(not-equality-assert) "" x : $(empty-strings-x) ; + $(equality-assert) "" "" x : $(empty-strings-x) ; + } + + + # --------------- + # Equality tests. + # --------------- + + run-equality-test equal : ignore-trailing-empty-strings ; + run-equality-test exact-equal ; + + + # ------------------------- + # assert.set-equal() tests. + # ------------------------- + + set-equal : ; + not-set-equal "" "" : ; + set-equal "" "" : "" ; + set-equal "" "" : "" "" ; + set-equal a b c : a b c ; + set-equal a b c : b c a ; + set-equal a b c a : a b c ; + set-equal a b c : a b c a ; + not-set-equal a b c : a b c d ; + not-set-equal a b c d : a b c ; +} diff --git a/jam-files/boost-build/util/container.jam b/jam-files/boost-build/util/container.jam new file mode 100644 index 00000000..dd496393 --- /dev/null +++ b/jam-files/boost-build/util/container.jam @@ -0,0 +1,339 @@ +# Copyright 2003 Dave Abrahams +# Copyright 2002, 2003 Rene Rivera +# Copyright 2002, 2003, 2004 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) + +# Various container classes. + +# Base for container objects. This lets us construct recursive structures. That +# is containers with containers in them, specifically so we can tell literal +# values from node values. +# +class node +{ + rule __init__ ( + value ? # Optional value to set node to initially. + ) + { + self.value = $(value) ; + } + + # Set the value of this node, passing nothing will clear it. + # + rule set ( value * ) + { + self.value = $(value) ; + } + + # Get the value of this node. + # + rule get ( ) + { + return $(self.value) ; + } +} + + +# A simple vector. Interface mimics the C++ std::vector and std::list, with the +# exception that indices are one (1) based to follow Jam standard. +# +# TODO: Possibly add assertion checks. +# +class vector : node +{ + import numbers ; + import utility ; + import sequence ; + + rule __init__ ( + values * # Initial contents of vector. + ) + { + node.__init__ ; + self.value = $(values) ; + } + + # Get the value of the first element. + # + rule front ( ) + { + return $(self.value[1]) ; + } + + # Get the value of the last element. + # + rule back ( ) + { + return $(self.value[-1]) ; + } + + # Get the value of the element at the given index, one based. Access to + # elements of recursive structures is supported directly. Specifying + # additional index values recursively accesses the elements as containers. + # For example: [ $(v).at 1 : 2 ] would retrieve the second element of our + # first element, assuming the first element is a container. + # + rule at ( + index # The element index, one based. + : * # Additional indices to access recursively. + ) + { + local r = $(self.value[$(index)]) ; + if $(2) + { + r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ; + } + return $(r) ; + } + + # Get the value contained in the given element. This has the same + # functionality and interface as "at" but in addition gets the value of the + # referenced element, assuming it is a "node". + # + rule get-at ( + index # The element index, one based. + : * # Additional indices to access recursively. + ) + { + local r = $(self.value[$(index)]) ; + if $(2) + { + r = [ $(r).at $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ] ; + } + return [ $(r).get ] ; + } + + # Insert the given value into the front of the vector pushing the rest of + # the elements back. + # + rule push-front ( + value # Value to become first element. + ) + { + self.value = $(value) $(self.value) ; + } + + # Remove the front element from the vector. Does not return the value. No + # effect if vector is empty. + # + rule pop-front ( ) + { + self.value = $(self.value[2-]) ; + } + + # Add the given value at the end of the vector. + # + rule push-back ( + value # Value to become back element. + ) + { + self.value += $(value) ; + } + + # Remove the back element from the vector. Does not return the value. No + # effect if vector is empty. + # + rule pop-back ( ) + { + self.value = $(self.value[1--2]) ; + } + + # Insert the given value at the given index, one based. The values at and to + # the right of the index are pushed back to make room for the new value. + # If the index is passed the end of the vector the element is added to the + # end. + # + rule insert ( + index # The index to insert at, one based. + : value # The value to insert. + ) + { + local left = $(self.value[1-$(index)]) ; + local right = $(self.value[$(index)-]) ; + if $(right)-is-not-empty + { + left = $(left[1--2]) ; + } + self.value = $(left) $(value) $(right) ; + } + + # Remove one or more elements from the vector. The range is inclusive, and + # not specifying an end is equivalent to the [start, start] range. + # + rule erase ( + start # Index of first element to remove. + end ? # Optional, index of last element to remove. + ) + { + end ?= $(start) ; + local left = $(self.value[1-$(start)]) ; + left = $(left[1--2]) ; + local right = $(self.value[$(end)-]) ; + right = $(right[2-]) ; + self.value = $(left) $(right) ; + } + + # Remove all elements from the vector. + # + rule clear ( ) + { + self.value = ; + } + + # The number of elements in the vector. + # + rule size ( ) + { + return [ sequence.length $(self.value) ] ; + } + + # Returns "true" if there are NO elements in the vector, empty otherwise. + # + rule empty ( ) + { + if ! $(self.value)-is-not-empty + { + return true ; + } + } + + # Returns the textual representation of content. + # + rule str ( ) + { + return "[" [ sequence.transform utility.str : $(self.value) ] "]" ; + } + + # Sorts the vector inplace, calling 'utility.less' for comparisons. + # + rule sort ( ) + { + self.value = [ sequence.insertion-sort $(self.value) : utility.less ] ; + } + + # Returns true if content is equal to the content of other vector. Uses + # 'utility.equal' for comparison. + # + rule equal ( another ) + { + local mismatch ; + local size = [ size ] ; + if $(size) = [ $(another).size ] + { + for local i in [ numbers.range 1 $(size) ] + { + if ! [ utility.equal [ at $(i) ] [ $(another).at $(i) ] ] + { + mismatch = true ; + } + } + } + else + { + mismatch = true ; + } + + if ! $(mismatch) + { + return true ; + } + } +} + + +rule __test__ ( ) +{ + import assert ; + import "class" : new ; + + local v1 = [ new vector ] ; + assert.true $(v1).equal $(v1) ; + assert.true $(v1).empty ; + assert.result 0 : $(v1).size ; + assert.result "[" "]" : $(v1).str ; + $(v1).push-back b ; + $(v1).push-front a ; + assert.result "[" a b "]" : $(v1).str ; + assert.result a : $(v1).front ; + assert.result b : $(v1).back ; + $(v1).insert 2 : d ; + $(v1).insert 2 : c ; + $(v1).insert 4 : f ; + $(v1).insert 4 : e ; + $(v1).pop-back ; + assert.result 5 : $(v1).size ; + assert.result d : $(v1).at 3 ; + $(v1).pop-front ; + assert.result c : $(v1).front ; + assert.false $(v1).empty ; + $(v1).erase 3 4 ; + assert.result 2 : $(v1).size ; + + local v2 = [ new vector q w e r t y ] ; + assert.result 6 : $(v2).size ; + $(v1).push-back $(v2) ; + assert.result 3 : $(v1).size ; + local v2-alias = [ $(v1).back ] ; + assert.result e : $(v2-alias).at 3 ; + $(v1).clear ; + assert.true $(v1).empty ; + assert.false $(v2-alias).empty ; + $(v2).pop-back ; + assert.result t : $(v2-alias).back ; + + local v3 = [ new vector ] ; + $(v3).push-back [ new vector 1 2 3 4 5 ] ; + $(v3).push-back [ new vector a b c ] ; + assert.result "[" "[" 1 2 3 4 5 "]" "[" a b c "]" "]" : $(v3).str ; + $(v3).push-back [ new vector [ new vector x y z ] [ new vector 7 8 9 ] ] ; + assert.result 1 : $(v3).at 1 : 1 ; + assert.result b : $(v3).at 2 : 2 ; + assert.result a b c : $(v3).get-at 2 ; + assert.result 7 8 9 : $(v3).get-at 3 : 2 ; + + local v4 = [ new vector 4 3 6 ] ; + $(v4).sort ; + assert.result 3 4 6 : $(v4).get ; + assert.false $(v4).equal $(v3) ; + + local v5 = [ new vector 3 4 6 ] ; + assert.true $(v4).equal $(v5) ; + # Check that vectors of different sizes are considered non-equal. + $(v5).pop-back ; + assert.false $(v4).equal $(v5) ; + + local v6 = [ new vector [ new vector 1 2 3 ] ] ; + assert.true $(v6).equal [ new vector [ new vector 1 2 3 ] ] ; + + local v7 = [ new vector 111 222 333 ] ; + assert.true $(v7).equal $(v7) ; + $(v7).insert 4 : 444 ; + assert.result 111 222 333 444 : $(v7).get ; + $(v7).insert 999 : xxx ; + assert.result 111 222 333 444 xxx : $(v7).get ; + + local v8 = [ new vector "" "" "" ] ; + assert.true $(v8).equal $(v8) ; + assert.false $(v8).empty ; + assert.result 3 : $(v8).size ; + assert.result "" : $(v8).at 1 ; + assert.result "" : $(v8).at 2 ; + assert.result "" : $(v8).at 3 ; + assert.result : $(v8).at 4 ; + $(v8).insert 2 : 222 ; + assert.result 4 : $(v8).size ; + assert.result "" 222 "" "" : $(v8).get ; + $(v8).insert 999 : "" ; + assert.result 5 : $(v8).size ; + assert.result "" 222 "" "" "" : $(v8).get ; + $(v8).insert 999 : xxx ; + assert.result 6 : $(v8).size ; + assert.result "" 222 "" "" "" xxx : $(v8).get ; + + # Regression test for a bug causing vector.equal to compare only the first + # and the last element in the given vectors. + local v9 = [ new vector 111 xxx 222 ] ; + local v10 = [ new vector 111 yyy 222 ] ; + assert.false $(v9).equal $(v10) ; +} diff --git a/jam-files/boost-build/util/doc.jam b/jam-files/boost-build/util/doc.jam new file mode 100644 index 00000000..a7515588 --- /dev/null +++ b/jam-files/boost-build/util/doc.jam @@ -0,0 +1,997 @@ +# Copyright 2002, 2005 Dave Abrahams +# Copyright 2002, 2003, 2006 Rene Rivera +# Copyright 2003 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) + +# Documentation system, handles --help requests. +# It defines rules that attach documentation to modules, rules, and variables. +# Collects and generates documentation for the various parts of the build +# system. The documentation is collected from comments integrated into the code. + +import modules ; +import print ; +import set ; +import container ; +import "class" ; +import sequence ; +import path ; + + +# The type of output to generate. +# "console" is formated text echoed to the console (the default); +# "text" is formated text appended to the output file; +# "html" is HTML output to the file. +# +help-output = console ; + + +# The file to output documentation to when generating "text" or "html" help. +# This is without extension as the extension is determined by the type of +# output. +# +help-output-file = help ; + +# Whether to include local rules in help output. +# +.option.show-locals ?= ; + +# When showing documentation for a module, whether to also generate +# automatically the detailed docs for each item in the module. +# +.option.detailed ?= ; + +# Generate debug output as the help is generated and modules are parsed. +# +.option.debug ?= ; + +# Enable or disable a documentation option. +# +local rule set-option ( + option # The option name. + : value ? # Enabled (non-empty), or disabled (empty) +) +{ + .option.$(option) = $(value) ; +} + + +# Set the type of output. +# +local rule set-output ( type ) +{ + help-output = $(type) ; +} + + +# Set the output to a file. +# +local rule set-output-file ( file ) +{ + help-output-file = $(file) ; +} + + +# Extracts the brief comment from a complete comment. The brief comment is the +# first sentence. +# +local rule brief-comment ( + docs * # The comment documentation. +) +{ + local d = $(docs:J=" ") ; + local p = [ MATCH ".*([.])$" : $(d) ] ; + if ! $(p) { d = $(d)"." ; } + d = $(d)" " ; + local m = [ MATCH "^([^.]+[.])(.*)" : $(d) ] ; + local brief = $(m[1]) ; + while $(m[2]) && [ MATCH "^([^ ])" : $(m[2]) ] + { + m = [ MATCH "^([^.]+[.])(.*)" : $(m[2]) ] ; + brief += $(m[1]) ; + } + return $(brief:J="") ; +} + + +# Specifies the documentation for the current module. +# +local rule set-module-doc ( + module-name ? # The name of the module to document. + : docs * # The documentation for the module. +) +{ + module-name ?= * ; + + $(module-name).brief = [ brief-comment $(docs) ] ; + $(module-name).docs = $(docs) ; + + if ! $(module-name) in $(documented-modules) + { + documented-modules += $(module-name) ; + } +} + + +# Specifies the documentation for the current module. +# +local rule set-module-copyright ( + module-name ? # The name of the module to document. + : copyright * # The copyright for the module. +) +{ + module-name ?= * ; + + $(module-name).copy-brief = [ brief-comment $(copyright) ] ; + $(module-name).copy-docs = $(docs) ; + + if ! $(module-name) in $(documented-modules) + { + documented-modules += $(module-name) ; + } +} + + +# Specifies the documentation for a rule in the current module. If called in the +# global module, this documents a global rule. +# +local rule set-rule-doc ( + name # The name of the rule. + module-name ? # The name of the module to document. + is-local ? # Whether the rule is local to the module. + : docs * # The documentation for the rule. +) +{ + module-name ?= * ; + + $(module-name).$(name).brief = [ brief-comment $(docs) ] ; + $(module-name).$(name).docs = $(docs) ; + $(module-name).$(name).is-local = $(is-local) ; + + if ! $(name) in $($(module-name).rules) + { + $(module-name).rules += $(name) ; + } +} + + +# Specify a class, will turn a rule into a class. +# +local rule set-class-doc ( + name # The name of the class. + module-name ? # The name of the module to document. + : super-name ? # The super class name. +) +{ + module-name ?= * ; + + $(module-name).$(name).is-class = true ; + $(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 ; + + $(module-name).classes += $(name) ; + $(module-name).class-rules += $($(module-name).$(name).class-rules) ; + $(module-name).rules = + [ set.difference $($(module-name).rules) : + $(name) $($(module-name).$(name).class-rules) ] ; +} + + +# Set the argument call signature of a rule. +# +local rule set-rule-arguments-signature ( + name # The name of the rule. + module-name ? # The name of the module to document. + : signature * # The arguments signature. +) +{ + module-name ?= * ; + + $(module-name).$(name).signature = $(signature) ; +} + + +# Specifies the documentation for an argument of a rule. +# +local rule set-argument-doc ( + name # The name of the argument. + qualifier # Argument syntax qualifier, "*", "+", etc. + rule-name # The name of the rule. + module-name ? # THe optional name of the module. + : docs * # The documentation. +) +{ + module-name ?= * ; + + $(module-name).$(rule-name).args.$(name).qualifier = $(qualifier) ; + $(module-name).$(rule-name).args.$(name).docs = $(docs) ; + + if ! $(name) in $($(module-name).$(rule-name).args) + { + $(module-name).$(rule-name).args += $(name) ; + } +} + + +# Specifies the documentation for a variable in the current module. If called in +# the global module, the global variable is documented. +# +local rule set-variable-doc ( + name # The name of the variable. + default # The default value. + initial # The initial value. + module-name ? # The name of the module to document. + : docs * # The documentation for the variable. +) +{ + module-name ?= * ; + + $(module-name).$(name).brief = [ brief-comment $(docs) ] ; + $(module-name).$(name).default = $(default) ; + $(module-name).$(name).initial = $(initial) ; + $(module-name).$(name).docs = $(docs) ; + + if ! $(name) in $($(module-name).variables) + { + $(module-name).variables += $(name) ; + } +} + + +# Generates a general description of the documentation and help system. +# +local rule print-help-top ( ) +{ + print.section "General command line usage" ; + + print.text " bjam [options] [properties] [targets] + + Options, properties and targets can be specified in any order. + " ; + + print.section "Important Options" ; + + print.list-start ; + print.list-item "--clean Remove targets instead of building" ; + print.list-item "-a Rebuild everything" ; + print.list-item "-n Don't execute the commands, only print them" ; + print.list-item "-d+2 Show commands as they are executed" ; + print.list-item "-d0 Supress all informational messages" ; + print.list-item "-q Stop at first error" ; + print.list-item "--debug-configuration Diagnose configuration" ; + print.list-item "--debug-building Report which targets are built with what properties" ; + print.list-item "--debug-generator Diagnose generator search/execution" ; + print.list-end ; + + print.section "Further Help" + The following options can be used to obtain additional documentation. + ; + + print.list-start ; + print.list-item "--help-options Print more obscure command line options." ; + print.list-item "--help-internal Boost.Build implementation details." ; + print.list-item "--help-doc-options Implementation details doc formatting." ; + print.list-end ; +} + + +# Generate Jam/Boost.Jam command usage information. +# +local rule print-help-usage ( ) +{ + print.section "Boost.Jam Usage" + "bjam [ options... ] targets..." + ; + print.list-start ; + print.list-item -a; + Build all targets, even if they are current. ; + print.list-item -fx; + Read '"x"' as the Jamfile for building instead of searching for the + Boost.Build system. ; + print.list-item -jx; + Run up to '"x"' commands concurrently. ; + 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; + Output the used build commands to file '"x"'. ; + 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; + Sets a Jam variable '"x"' to the value '"y"', overriding any value that + variable would have from the environment. ; + print.list-item -tx; + Rebuild the target '"x"', even if it is up-to-date. ; + print.list-item -v; + Display the version of bjam. ; + print.list-item --x; + Any option not explicitly handled by Boost.Jam remains available to + build scripts using the '"ARGV"' variable. ; + 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; + 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: ; + print.list-start ; + print.list-item 0; + Turn off all diagnostic output. Only errors are reported. ; + print.list-item 1; + Show the actions taken for building targets, as they are executed. ; + print.list-item 2; + Show "quiet" actions and display all action text, as they are executed. ; + print.list-item 3; + Show dependency analysis, and target/source timestamps/paths. ; + print.list-item 4; + Show arguments of shell invocations. ; + print.list-item 5; + Show rule invocations and variable expansions. ; + print.list-item 6; + Show directory/header file/archive scans, and attempts at binding to targets. ; + print.list-item 7; + Show variable settings. ; + print.list-item 8; + Show variable fetches, variable expansions, and evaluation of '"if"' expressions. ; + print.list-item 9; + Show variable manipulation, scanner tokens, and memory usage. ; + print.list-item 10; + Show execution times for rules. ; + print.list-item 11; + Show parsing progress of Jamfiles. ; + print.list-item 12; + Show graph for target dependencies. ; + print.list-item 13; + Show changes in target status (fate). ; + print.list-end ; +} + + +# Generates description of options controlling the help system. This +# automatically reads the options as all variables in the doc module of the form +# ".option.*". +# +local rule print-help-options ( + module-name # The doc module. +) +{ + print.section "Help Options" + These are all the options available for enabling or disabling to control + the help system in various ways. Options can be enabled or disabled with + '"--help-enable-