diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 850888710..d0ddea175 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -9,6 +9,56 @@ http://www.nsnam.org including tutorials: http://www.nsnam.org/tutorials.html Consult the file CHANGES.html for more detailed information about changed API and behavior across ns-3 releases. +Release 3.8 +=========== + +Availability +------------ +This release is not yet available. + +Supported platforms +------------------- +ns-3.8 has been tested on the following platforms: + - linux x86 gcc 4.4.0, 4.3.2, 4.2, 4.1.1, 4.1 and 3.4.6 (debug and optimized) + - linux x86_64 gcc 4.4.0, 4.3.2, 4.2.4, 4.2.3, 4.2.1, 4.1.3, 3.4.6 (debug and optimized) + - MacOS X ppc gcc 4.0.x and 4.2.x (debug and optimized) + - cygwin gcc 3.4.4 (debug only), gcc 4.3.2 (debug and optimized) + +Unofficially supported platform +------------------- +- mingw gcc 3.4.5 (debug only) + +Not all ns-3 options are available on all platforms; consult the +wiki for more information: +http://www.nsnam.org/wiki/index.php/Installation + +New user-visible features +------------------------- + a) + + b) + + c) + +API changes from ns-3.7 +----------------------- +API changes for this release are documented in the file CHANGES.html. + +Bugs fixed +---------- +The following lists many of the bugs that were fixed since ns-3.7, in +many cases referencing the Bugzilla bug number + - bug 747 - Listening TCP socket closes on RST + - bug 788 - OLSR_NEIGH_HOLD_TIME should be 3 times OLSR_REFRESH_INTERVAL + +Known issues +------------ +ns-3 builds have been known to fail on the following platforms: + - gcc 3.3 and earlier + - optimized builds on gcc 3.4.4 and 3.4.5 + - optimized builds on linux x86 gcc 4.0.x + + Release 3.7 =========== diff --git a/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py b/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py index 0cd936720..732ac3e4d 100644 --- a/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py +++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_common.py @@ -222,6 +222,11 @@ def register_Ns3Buffer_methods(root_module, cls): 'void', [param('std::ostream *', 'os'), param('uint32_t', 'size')], is_const=True) + ## buffer.h: uint32_t ns3::Buffer::CopyData(uint8_t * buffer, uint32_t size) const [member function] + cls.add_method('CopyData', + 'uint32_t', + [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], + is_const=True) ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function] cls.add_method('CreateFragment', 'ns3::Buffer', diff --git a/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py b/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py index 4783572d1..d88638c46 100644 --- a/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py +++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_internet_stack.py @@ -59,6 +59,8 @@ def register_types(module): module.add_class('Icmpv6TooBig', parent=root_module['ns3::Icmpv6Header']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionHeader [class] module.add_class('Ipv6ExtensionHeader', parent=root_module['ns3::Header']) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader [class] + module.add_class('Ipv6ExtensionHopByHopHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']]) ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader [class] module.add_class('Ipv6ExtensionRoutingHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) ## ipv6-option-header.h: ns3::Ipv6OptionHeader [class] @@ -101,6 +103,8 @@ def register_types(module): module.add_enum('RxStatus', ['RX_OK', 'RX_CSUM_FAILED', 'RX_ENDPOINT_CLOSED', 'RX_ENDPOINT_UNREACH'], outer_class=root_module['ns3::Ipv4L4Protocol']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionAHHeader [class] module.add_class('Ipv6ExtensionAHHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader [class] + module.add_class('Ipv6ExtensionDestinationHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']]) ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader [class] module.add_class('Ipv6ExtensionESPHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionFragmentHeader [class] @@ -231,6 +235,7 @@ def register_methods(root_module): register_Ns3Icmpv6TimeExceeded_methods(root_module, root_module['ns3::Icmpv6TimeExceeded']) register_Ns3Icmpv6TooBig_methods(root_module, root_module['ns3::Icmpv6TooBig']) register_Ns3Ipv6ExtensionHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHeader']) + register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHopByHopHeader']) register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionRoutingHeader']) register_Ns3Ipv6OptionHeader_methods(root_module, root_module['ns3::Ipv6OptionHeader']) register_Ns3Ipv6OptionHeaderAlignment_methods(root_module, root_module['ns3::Ipv6OptionHeader::Alignment']) @@ -249,6 +254,7 @@ def register_methods(root_module): register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol']) register_Ns3Ipv4L4Protocol_methods(root_module, root_module['ns3::Ipv4L4Protocol']) register_Ns3Ipv6ExtensionAHHeader_methods(root_module, root_module['ns3::Ipv6ExtensionAHHeader']) + register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, root_module['ns3::Ipv6ExtensionDestinationHeader']) register_Ns3Ipv6ExtensionESPHeader_methods(root_module, root_module['ns3::Ipv6ExtensionESPHeader']) register_Ns3Ipv6ExtensionFragmentHeader_methods(root_module, root_module['ns3::Ipv6ExtensionFragmentHeader']) register_Ns3Ipv6ExtensionLooseRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionLooseRoutingHeader']) @@ -1481,6 +1487,43 @@ def register_Ns3Ipv6ExtensionHeader_methods(root_module, cls): [param('uint8_t', 'nextHeader')]) return +def register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, cls): + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader(ns3::Ipv6ExtensionHopByHopHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv6ExtensionHopByHopHeader const &', 'arg0')]) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader() [constructor] + cls.add_constructor([]) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) + ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', + 'void', + [param('std::ostream &', 'os')], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) + return + def register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, cls): ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader(ns3::Ipv6ExtensionRoutingHeader const & arg0) [copy constructor] cls.add_constructor([param('ns3::Ipv6ExtensionRoutingHeader const &', 'arg0')]) @@ -2616,6 +2659,43 @@ def register_Ns3Ipv6ExtensionAHHeader_methods(root_module, cls): is_const=True, is_virtual=True) return +def register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, cls): + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader(ns3::Ipv6ExtensionDestinationHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv6ExtensionDestinationHeader const &', 'arg0')]) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader() [constructor] + cls.add_constructor([]) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) + ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', + 'void', + [param('std::ostream &', 'os')], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) + return + def register_Ns3Ipv6ExtensionESPHeader_methods(root_module, cls): ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader::Ipv6ExtensionESPHeader(ns3::Ipv6ExtensionESPHeader const & arg0) [copy constructor] cls.add_constructor([param('ns3::Ipv6ExtensionESPHeader const &', 'arg0')]) diff --git a/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py b/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py index a772263ea..6689c22e2 100644 --- a/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py +++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_node.py @@ -4723,11 +4723,6 @@ def register_Ns3PbbPacket_methods(root_module, cls): 'int', [], is_const=True) - ## packetbb.h: void ns3::PbbPacket::SerializePacketTlv(ns3::Buffer::Iterator & start) const [member function] - cls.add_method('SerializePacketTlv', - 'void', - [param('ns3::Buffer::Iterator &', 'start')], - is_const=True, visibility='protected') return def register_Ns3PbbTlv_methods(root_module, cls): diff --git a/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py b/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py index cb6915c12..43d9aae49 100644 --- a/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py +++ b/bindings/python/apidefs/gcc-ILP32/ns3_module_stats.py @@ -13,8 +13,12 @@ def register_types(module): module.add_class('DataCollector', parent=root_module['ns3::Object']) ## data-output-interface.h: ns3::DataOutputInterface [class] module.add_class('DataOutputInterface', parent=root_module['ns3::Object']) + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator [class] + module.add_class('MinMaxAvgTotalCalculator', template_parameters=['unsigned int'], parent=[root_module['ns3::DataCalculator'], root_module['ns3::StatisticalSummary']]) ## omnet-data-output.h: ns3::OmnetDataOutput [class] module.add_class('OmnetDataOutput', parent=root_module['ns3::DataOutputInterface']) + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator [class] + module.add_class('PacketSizeMinMaxAvgTotalCalculator', parent=root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >']) ## sqlite-data-output.h: ns3::SqliteDataOutput [class] module.add_class('SqliteDataOutput', parent=root_module['ns3::DataOutputInterface']) ## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator [class] @@ -116,7 +120,9 @@ def register_methods(root_module): register_Ns3DataCalculator_methods(root_module, root_module['ns3::DataCalculator']) register_Ns3DataCollector_methods(root_module, root_module['ns3::DataCollector']) register_Ns3DataOutputInterface_methods(root_module, root_module['ns3::DataOutputInterface']) + register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >']) register_Ns3OmnetDataOutput_methods(root_module, root_module['ns3::OmnetDataOutput']) + register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::PacketSizeMinMaxAvgTotalCalculator']) register_Ns3SqliteDataOutput_methods(root_module, root_module['ns3::SqliteDataOutput']) register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::TimeMinMaxAvgTotalCalculator']) register_Ns3CounterCalculator__Unsigned_int_methods(root_module, root_module['ns3::CounterCalculator< unsigned int >']) @@ -364,6 +370,67 @@ def register_Ns3DataOutputInterface_methods(root_module, cls): visibility='protected', is_virtual=True) return +def register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, cls): + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator::MinMaxAvgTotalCalculator(ns3::MinMaxAvgTotalCalculator const & arg0) [copy constructor] + cls.add_constructor([param('ns3::MinMaxAvgTotalCalculator< unsigned int > const &', 'arg0')]) + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator::MinMaxAvgTotalCalculator() [constructor] + cls.add_constructor([]) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::Output(ns3::DataOutputCallback & callback) const [member function] + cls.add_method('Output', + 'void', + [param('ns3::DataOutputCallback &', 'callback')], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::Update(unsigned int const i) [member function] + cls.add_method('Update', + 'void', + [param('unsigned int const', 'i')]) + ## basic-data-calculators.h: long int ns3::MinMaxAvgTotalCalculator::getCount() const [member function] + cls.add_method('getCount', + 'long int', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMax() const [member function] + cls.add_method('getMax', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMean() const [member function] + cls.add_method('getMean', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMin() const [member function] + cls.add_method('getMin', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getSqrSum() const [member function] + cls.add_method('getSqrSum', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getStddev() const [member function] + cls.add_method('getStddev', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getSum() const [member function] + cls.add_method('getSum', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getVariance() const [member function] + cls.add_method('getVariance', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::DoDispose() [member function] + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) + return + def register_Ns3OmnetDataOutput_methods(root_module, cls): ## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput(ns3::OmnetDataOutput const & arg0) [copy constructor] cls.add_constructor([param('ns3::OmnetDataOutput const &', 'arg0')]) @@ -381,6 +448,26 @@ def register_Ns3OmnetDataOutput_methods(root_module, cls): visibility='protected', is_virtual=True) return +def register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, cls): + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator(ns3::PacketSizeMinMaxAvgTotalCalculator const & arg0) [copy constructor] + cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')]) + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor] + cls.add_constructor([]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr packet, ns3::Mac48Address realto) [member function] + cls.add_method('FrameUpdate', + 'void', + [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr packet) [member function] + cls.add_method('PacketUpdate', + 'void', + [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::DoDispose() [member function] + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) + return + def register_Ns3SqliteDataOutput_methods(root_module, cls): ## sqlite-data-output.h: ns3::SqliteDataOutput::SqliteDataOutput(ns3::SqliteDataOutput const & arg0) [copy constructor] cls.add_constructor([param('ns3::SqliteDataOutput const &', 'arg0')]) diff --git a/bindings/python/apidefs/gcc-LP64/ns3_module_common.py b/bindings/python/apidefs/gcc-LP64/ns3_module_common.py index 0cd936720..732ac3e4d 100644 --- a/bindings/python/apidefs/gcc-LP64/ns3_module_common.py +++ b/bindings/python/apidefs/gcc-LP64/ns3_module_common.py @@ -222,6 +222,11 @@ def register_Ns3Buffer_methods(root_module, cls): 'void', [param('std::ostream *', 'os'), param('uint32_t', 'size')], is_const=True) + ## buffer.h: uint32_t ns3::Buffer::CopyData(uint8_t * buffer, uint32_t size) const [member function] + cls.add_method('CopyData', + 'uint32_t', + [param('uint8_t *', 'buffer'), param('uint32_t', 'size')], + is_const=True) ## buffer.h: ns3::Buffer ns3::Buffer::CreateFragment(uint32_t start, uint32_t length) const [member function] cls.add_method('CreateFragment', 'ns3::Buffer', diff --git a/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py b/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py index 4783572d1..d88638c46 100644 --- a/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py +++ b/bindings/python/apidefs/gcc-LP64/ns3_module_internet_stack.py @@ -59,6 +59,8 @@ def register_types(module): module.add_class('Icmpv6TooBig', parent=root_module['ns3::Icmpv6Header']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionHeader [class] module.add_class('Ipv6ExtensionHeader', parent=root_module['ns3::Header']) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader [class] + module.add_class('Ipv6ExtensionHopByHopHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']]) ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader [class] module.add_class('Ipv6ExtensionRoutingHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) ## ipv6-option-header.h: ns3::Ipv6OptionHeader [class] @@ -101,6 +103,8 @@ def register_types(module): module.add_enum('RxStatus', ['RX_OK', 'RX_CSUM_FAILED', 'RX_ENDPOINT_CLOSED', 'RX_ENDPOINT_UNREACH'], outer_class=root_module['ns3::Ipv4L4Protocol']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionAHHeader [class] module.add_class('Ipv6ExtensionAHHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader [class] + module.add_class('Ipv6ExtensionDestinationHeader', parent=[root_module['ns3::Ipv6ExtensionHeader'], root_module['ns3::OptionField']]) ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader [class] module.add_class('Ipv6ExtensionESPHeader', parent=root_module['ns3::Ipv6ExtensionHeader']) ## ipv6-extension-header.h: ns3::Ipv6ExtensionFragmentHeader [class] @@ -231,6 +235,7 @@ def register_methods(root_module): register_Ns3Icmpv6TimeExceeded_methods(root_module, root_module['ns3::Icmpv6TimeExceeded']) register_Ns3Icmpv6TooBig_methods(root_module, root_module['ns3::Icmpv6TooBig']) register_Ns3Ipv6ExtensionHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHeader']) + register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, root_module['ns3::Ipv6ExtensionHopByHopHeader']) register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionRoutingHeader']) register_Ns3Ipv6OptionHeader_methods(root_module, root_module['ns3::Ipv6OptionHeader']) register_Ns3Ipv6OptionHeaderAlignment_methods(root_module, root_module['ns3::Ipv6OptionHeader::Alignment']) @@ -249,6 +254,7 @@ def register_methods(root_module): register_Ns3Ipv4L3Protocol_methods(root_module, root_module['ns3::Ipv4L3Protocol']) register_Ns3Ipv4L4Protocol_methods(root_module, root_module['ns3::Ipv4L4Protocol']) register_Ns3Ipv6ExtensionAHHeader_methods(root_module, root_module['ns3::Ipv6ExtensionAHHeader']) + register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, root_module['ns3::Ipv6ExtensionDestinationHeader']) register_Ns3Ipv6ExtensionESPHeader_methods(root_module, root_module['ns3::Ipv6ExtensionESPHeader']) register_Ns3Ipv6ExtensionFragmentHeader_methods(root_module, root_module['ns3::Ipv6ExtensionFragmentHeader']) register_Ns3Ipv6ExtensionLooseRoutingHeader_methods(root_module, root_module['ns3::Ipv6ExtensionLooseRoutingHeader']) @@ -1481,6 +1487,43 @@ def register_Ns3Ipv6ExtensionHeader_methods(root_module, cls): [param('uint8_t', 'nextHeader')]) return +def register_Ns3Ipv6ExtensionHopByHopHeader_methods(root_module, cls): + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader(ns3::Ipv6ExtensionHopByHopHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv6ExtensionHopByHopHeader const &', 'arg0')]) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionHopByHopHeader::Ipv6ExtensionHopByHopHeader() [constructor] + cls.add_constructor([]) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) + ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionHopByHopHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionHopByHopHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', + 'void', + [param('std::ostream &', 'os')], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionHopByHopHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) + return + def register_Ns3Ipv6ExtensionRoutingHeader_methods(root_module, cls): ## ipv6-extension-header.h: ns3::Ipv6ExtensionRoutingHeader::Ipv6ExtensionRoutingHeader(ns3::Ipv6ExtensionRoutingHeader const & arg0) [copy constructor] cls.add_constructor([param('ns3::Ipv6ExtensionRoutingHeader const &', 'arg0')]) @@ -2616,6 +2659,43 @@ def register_Ns3Ipv6ExtensionAHHeader_methods(root_module, cls): is_const=True, is_virtual=True) return +def register_Ns3Ipv6ExtensionDestinationHeader_methods(root_module, cls): + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader(ns3::Ipv6ExtensionDestinationHeader const & arg0) [copy constructor] + cls.add_constructor([param('ns3::Ipv6ExtensionDestinationHeader const &', 'arg0')]) + ## ipv6-extension-header.h: ns3::Ipv6ExtensionDestinationHeader::Ipv6ExtensionDestinationHeader() [constructor] + cls.add_constructor([]) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::Deserialize(ns3::Buffer::Iterator start) [member function] + cls.add_method('Deserialize', + 'uint32_t', + [param('ns3::Buffer::Iterator', 'start')], + is_virtual=True) + ## ipv6-extension-header.h: ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetInstanceTypeId() const [member function] + cls.add_method('GetInstanceTypeId', + 'ns3::TypeId', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: uint32_t ns3::Ipv6ExtensionDestinationHeader::GetSerializedSize() const [member function] + cls.add_method('GetSerializedSize', + 'uint32_t', + [], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: static ns3::TypeId ns3::Ipv6ExtensionDestinationHeader::GetTypeId() [member function] + cls.add_method('GetTypeId', + 'ns3::TypeId', + [], + is_static=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Print(std::ostream & os) const [member function] + cls.add_method('Print', + 'void', + [param('std::ostream &', 'os')], + is_const=True, is_virtual=True) + ## ipv6-extension-header.h: void ns3::Ipv6ExtensionDestinationHeader::Serialize(ns3::Buffer::Iterator start) const [member function] + cls.add_method('Serialize', + 'void', + [param('ns3::Buffer::Iterator', 'start')], + is_const=True, is_virtual=True) + return + def register_Ns3Ipv6ExtensionESPHeader_methods(root_module, cls): ## ipv6-extension-header.h: ns3::Ipv6ExtensionESPHeader::Ipv6ExtensionESPHeader(ns3::Ipv6ExtensionESPHeader const & arg0) [copy constructor] cls.add_constructor([param('ns3::Ipv6ExtensionESPHeader const &', 'arg0')]) diff --git a/bindings/python/apidefs/gcc-LP64/ns3_module_node.py b/bindings/python/apidefs/gcc-LP64/ns3_module_node.py index a772263ea..6689c22e2 100644 --- a/bindings/python/apidefs/gcc-LP64/ns3_module_node.py +++ b/bindings/python/apidefs/gcc-LP64/ns3_module_node.py @@ -4723,11 +4723,6 @@ def register_Ns3PbbPacket_methods(root_module, cls): 'int', [], is_const=True) - ## packetbb.h: void ns3::PbbPacket::SerializePacketTlv(ns3::Buffer::Iterator & start) const [member function] - cls.add_method('SerializePacketTlv', - 'void', - [param('ns3::Buffer::Iterator &', 'start')], - is_const=True, visibility='protected') return def register_Ns3PbbTlv_methods(root_module, cls): diff --git a/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py b/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py index cb6915c12..43d9aae49 100644 --- a/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py +++ b/bindings/python/apidefs/gcc-LP64/ns3_module_stats.py @@ -13,8 +13,12 @@ def register_types(module): module.add_class('DataCollector', parent=root_module['ns3::Object']) ## data-output-interface.h: ns3::DataOutputInterface [class] module.add_class('DataOutputInterface', parent=root_module['ns3::Object']) + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator [class] + module.add_class('MinMaxAvgTotalCalculator', template_parameters=['unsigned int'], parent=[root_module['ns3::DataCalculator'], root_module['ns3::StatisticalSummary']]) ## omnet-data-output.h: ns3::OmnetDataOutput [class] module.add_class('OmnetDataOutput', parent=root_module['ns3::DataOutputInterface']) + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator [class] + module.add_class('PacketSizeMinMaxAvgTotalCalculator', parent=root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >']) ## sqlite-data-output.h: ns3::SqliteDataOutput [class] module.add_class('SqliteDataOutput', parent=root_module['ns3::DataOutputInterface']) ## time-data-calculators.h: ns3::TimeMinMaxAvgTotalCalculator [class] @@ -116,7 +120,9 @@ def register_methods(root_module): register_Ns3DataCalculator_methods(root_module, root_module['ns3::DataCalculator']) register_Ns3DataCollector_methods(root_module, root_module['ns3::DataCollector']) register_Ns3DataOutputInterface_methods(root_module, root_module['ns3::DataOutputInterface']) + register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, root_module['ns3::MinMaxAvgTotalCalculator< unsigned int >']) register_Ns3OmnetDataOutput_methods(root_module, root_module['ns3::OmnetDataOutput']) + register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::PacketSizeMinMaxAvgTotalCalculator']) register_Ns3SqliteDataOutput_methods(root_module, root_module['ns3::SqliteDataOutput']) register_Ns3TimeMinMaxAvgTotalCalculator_methods(root_module, root_module['ns3::TimeMinMaxAvgTotalCalculator']) register_Ns3CounterCalculator__Unsigned_int_methods(root_module, root_module['ns3::CounterCalculator< unsigned int >']) @@ -364,6 +370,67 @@ def register_Ns3DataOutputInterface_methods(root_module, cls): visibility='protected', is_virtual=True) return +def register_Ns3MinMaxAvgTotalCalculator__Unsigned_int_methods(root_module, cls): + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator::MinMaxAvgTotalCalculator(ns3::MinMaxAvgTotalCalculator const & arg0) [copy constructor] + cls.add_constructor([param('ns3::MinMaxAvgTotalCalculator< unsigned int > const &', 'arg0')]) + ## basic-data-calculators.h: ns3::MinMaxAvgTotalCalculator::MinMaxAvgTotalCalculator() [constructor] + cls.add_constructor([]) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::Output(ns3::DataOutputCallback & callback) const [member function] + cls.add_method('Output', + 'void', + [param('ns3::DataOutputCallback &', 'callback')], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::Update(unsigned int const i) [member function] + cls.add_method('Update', + 'void', + [param('unsigned int const', 'i')]) + ## basic-data-calculators.h: long int ns3::MinMaxAvgTotalCalculator::getCount() const [member function] + cls.add_method('getCount', + 'long int', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMax() const [member function] + cls.add_method('getMax', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMean() const [member function] + cls.add_method('getMean', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getMin() const [member function] + cls.add_method('getMin', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getSqrSum() const [member function] + cls.add_method('getSqrSum', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getStddev() const [member function] + cls.add_method('getStddev', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getSum() const [member function] + cls.add_method('getSum', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: double ns3::MinMaxAvgTotalCalculator::getVariance() const [member function] + cls.add_method('getVariance', + 'double', + [], + is_const=True, is_virtual=True) + ## basic-data-calculators.h: void ns3::MinMaxAvgTotalCalculator::DoDispose() [member function] + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) + return + def register_Ns3OmnetDataOutput_methods(root_module, cls): ## omnet-data-output.h: ns3::OmnetDataOutput::OmnetDataOutput(ns3::OmnetDataOutput const & arg0) [copy constructor] cls.add_constructor([param('ns3::OmnetDataOutput const &', 'arg0')]) @@ -381,6 +448,26 @@ def register_Ns3OmnetDataOutput_methods(root_module, cls): visibility='protected', is_virtual=True) return +def register_Ns3PacketSizeMinMaxAvgTotalCalculator_methods(root_module, cls): + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator(ns3::PacketSizeMinMaxAvgTotalCalculator const & arg0) [copy constructor] + cls.add_constructor([param('ns3::PacketSizeMinMaxAvgTotalCalculator const &', 'arg0')]) + ## packet-data-calculators.h: ns3::PacketSizeMinMaxAvgTotalCalculator::PacketSizeMinMaxAvgTotalCalculator() [constructor] + cls.add_constructor([]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::FrameUpdate(std::string path, ns3::Ptr packet, ns3::Mac48Address realto) [member function] + cls.add_method('FrameUpdate', + 'void', + [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet'), param('ns3::Mac48Address', 'realto')]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::PacketUpdate(std::string path, ns3::Ptr packet) [member function] + cls.add_method('PacketUpdate', + 'void', + [param('std::string', 'path'), param('ns3::Ptr< ns3::Packet const >', 'packet')]) + ## packet-data-calculators.h: void ns3::PacketSizeMinMaxAvgTotalCalculator::DoDispose() [member function] + cls.add_method('DoDispose', + 'void', + [], + visibility='protected', is_virtual=True) + return + def register_Ns3SqliteDataOutput_methods(root_module, cls): ## sqlite-data-output.h: ns3::SqliteDataOutput::SqliteDataOutput(ns3::SqliteDataOutput const & arg0) [copy constructor] cls.add_constructor([param('ns3::SqliteDataOutput const &', 'arg0')]) diff --git a/bindings/python/wscript b/bindings/python/wscript index 5bb703dea..41e3a6407 100644 --- a/bindings/python/wscript +++ b/bindings/python/wscript @@ -15,7 +15,7 @@ import Build import Utils ## https://launchpad.net/pybindgen/ -REQUIRED_PYBINDGEN_VERSION = (0, 12, 0, 710) +REQUIRED_PYBINDGEN_VERSION = (0, 13, 0, 744) REQUIRED_PYGCCXML_VERSION = (0, 9, 5) @@ -346,7 +346,7 @@ class all_ns3_headers_taskgen(TaskGen.task_gen): all_headers_inputs.append(node) assert all_headers_inputs all_headers_outputs = [self.path.find_or_declare("everything.h")] - task = self.create_task('gen_everything_h', self.env) + task = self.create_task('gen_everything_h', env=self.env) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) diff --git a/src/common/buffer.cc b/src/common/buffer.cc index 7f1ee2f5f..cc1f107d3 100644 --- a/src/common/buffer.cc +++ b/src/common/buffer.cc @@ -726,6 +726,38 @@ Buffer::CopyData(std::ostream *os, uint32_t size) const } } +uint32_t +Buffer::CopyData (uint8_t *buffer, uint32_t size) const +{ + uint32_t originalSize = size; + if (size > 0) + { + uint32_t tmpsize = std::min (m_zeroAreaStart-m_start, size); + memcpy (buffer, (const char*)(m_data->m_data + m_start), tmpsize); + buffer += tmpsize; + if (size > tmpsize) + { + size -= m_zeroAreaStart-m_start; + tmpsize = std::min (m_zeroAreaEnd - m_zeroAreaStart, size); + uint32_t left = tmpsize; + while (left > 0) + { + uint32_t toWrite = std::min (left, g_zeroes.size); + memcpy (buffer, g_zeroes.buffer, toWrite); + left -= toWrite; + buffer += toWrite; + } + if (size > tmpsize) + { + size -= tmpsize; + tmpsize = std::min (m_end - m_zeroAreaEnd, size); + memcpy (buffer, (const char*)(m_data->m_data + m_zeroAreaStart), tmpsize); + } + } + } + return originalSize - size; +} + /****************************************************** * The buffer iterator below. ******************************************************/ diff --git a/src/common/buffer.h b/src/common/buffer.h index 4d542251f..33d32b9d2 100644 --- a/src/common/buffer.h +++ b/src/common/buffer.h @@ -487,6 +487,8 @@ public: */ void CopyData (std::ostream *os, uint32_t size) const; + uint32_t CopyData (uint8_t *buffer, uint32_t size) const; + Buffer (Buffer const &o); Buffer &operator = (Buffer const &o); Buffer (); diff --git a/src/common/packet.cc b/src/common/packet.cc index 244c26e6f..8f48811a7 100644 --- a/src/common/packet.cc +++ b/src/common/packet.cc @@ -350,14 +350,7 @@ Packet::PeekData (void) const uint32_t Packet::CopyData (uint8_t *buffer, uint32_t size) const { - Buffer::Iterator i = m_buffer.Begin (); - uint32_t cur = 0; - while (!i.IsEnd () && cur < size) - { - buffer[cur] = i.ReadU8 (); - cur++; - } - return cur; + return m_buffer.CopyData (buffer, size); } void diff --git a/src/common/packet.h b/src/common/packet.h index 0fdff7efb..cf0883400 100644 --- a/src/common/packet.h +++ b/src/common/packet.h @@ -202,7 +202,6 @@ private: class Packet : public SimpleRefCount { public: - Ptr Copy (void) const; /** * Create an empty packet with a new uid (as returned @@ -346,8 +345,23 @@ public: */ uint32_t CopyData (uint8_t *buffer, uint32_t size) const; + /** + * \param os pointer to output stream in which we want + * to write the packet data. + * \param size the maximum number of bytes we want to write + * in the output stream. + */ void CopyData(std::ostream *os, uint32_t size) const; + /** + * \returns a COW copy of the packet. + * + * The returns packet will behave like an independent copy of + * the original packet, even though they both share the + * same datasets internally. + */ + Ptr Copy (void) const; + /** * A packet is allocated a new uid when it is created * empty or with zero-filled payload. @@ -377,6 +391,14 @@ public: */ void Print (std::ostream &os) const; + /** + * \returns an iterator which points to the first 'item' + * stored in this buffer. Note that this iterator will point + * to an empty array of items if you don't call EnablePrinting + * or EnableChecking before. + * + * \sa EnablePrinting EnableChecking + */ PacketMetadata::ItemIterator BeginItem (void) const; /** diff --git a/src/internet-stack/tcp-socket-impl.cc b/src/internet-stack/tcp-socket-impl.cc index 58ef5cb65..28ae5958c 100644 --- a/src/internet-stack/tcp-socket-impl.cc +++ b/src/internet-stack/tcp-socket-impl.cc @@ -677,16 +677,6 @@ TcpSocketImpl::ForwardUp (Ptr packet, Ipv4Address ipv4, uint16_t port) TcpHeader tcpHeader; packet->RemoveHeader (tcpHeader); - if (tcpHeader.GetFlags () & TcpHeader::RST) - { // Got an RST, just shut everything down - NotifyErrorClose(); - CancelAllTimers(); - m_endPoint->SetDestroyCallback(MakeNullCallback()); - m_tcp->DeAllocate (m_endPoint); - m_endPoint = 0; - return; - } - if (tcpHeader.GetFlags () & TcpHeader::ACK) { Time m = m_rtt->AckSeq (tcpHeader.GetAckNumber () ); @@ -721,14 +711,7 @@ Actions_t TcpSocketImpl::ProcessEvent (Events_t e) // class intended to be a singleton; see simulation-singleton.h SA stateAction = SimulationSingleton::Get ()->Lookup (m_state,e); NS_LOG_LOGIC ("TcpSocketImpl::ProcessEvent stateAction " << stateAction.action); - // debug - if (stateAction.action == RST_TX) - { - NS_LOG_LOGIC ("TcpSocketImpl " << this << " sending RST from state " - << saveState << " event " << e); - SendRST(); - return NO_ACT; - } + bool needCloseNotify = (stateAction.state == CLOSED && m_state != CLOSED && e != TIMEOUT); m_state = stateAction.state; @@ -925,6 +908,12 @@ bool TcpSocketImpl::ProcessPacketAction (Actions_t a, Ptr p, switch (a) { + case RST_TX: + { + NS_LOG_LOGIC ("TcpSocketImpl " << this << " Action RST_TX"); + SendRST(); + return NO_ACT; + } case ACK_TX: NS_LOG_LOGIC ("TcpSocketImpl " << this <<" Action ACK_TX"); if(tcpHeader.GetFlags() & TcpHeader::FIN) diff --git a/src/node/packetbb.h b/src/node/packetbb.h index 6d73df481..f9795e7f4 100644 --- a/src/node/packetbb.h +++ b/src/node/packetbb.h @@ -631,7 +631,6 @@ public: bool operator!= (const PbbPacket &other) const; protected: - void SerializePacketTlv (Buffer::Iterator &start) const; private: PbbTlvBlock m_tlvList; diff --git a/src/routing/global-routing/global-route-manager-impl.cc b/src/routing/global-routing/global-route-manager-impl.cc index 513e004c8..9051a640b 100644 --- a/src/routing/global-routing/global-route-manager-impl.cc +++ b/src/routing/global-routing/global-route-manager-impl.cc @@ -222,53 +222,6 @@ SPFVertex::GetDistanceFromRoot (void) const return m_distanceFromRoot; } -void -SPFVertex::SetOutgoingInterfaceId (int32_t id) -{ - NS_LOG_FUNCTION (id); - - // always maintain only one output interface index when using setter/getter methods - m_rootOif = id; -} - -uint32_t -SPFVertex::GetOutgoingInterfaceId (void) const -{ - NS_LOG_FUNCTION_NOARGS (); - return m_rootOif; -} - -//void -//SPFVertex::MergeOutgoingInterfaceId (const SPFVertex* v) -//{ -// NS_LOG_FUNCTION (v); -// -// NS_LOG_LOGIC ("Before merge, list of root out-going interfaces = " << m_rootOif); -// // combine the two lists first, and then remove any duplicated after -// m_rootOif.insert (m_rootOif.end (), -// v->m_rootOif.begin (), v->m_rootOif.end ()); -// // remove duplication -// m_rootOif.sort (); -// m_rootOif.unique (); -// NS_LOG_LOGIC ("After merge, list of root out-going interfaces = " << m_rootOif); -//} - - void -SPFVertex::SetNextHop (Ipv4Address nextHop) -{ - NS_LOG_FUNCTION (nextHop); - - // always maintain only one nexthop when using setter/getter methods - m_nextHop = nextHop; -} - - Ipv4Address -SPFVertex::GetNextHop (void) const -{ - NS_LOG_FUNCTION_NOARGS (); - return m_nextHop; -} - void SPFVertex::SetParent (SPFVertex* parent) { @@ -1637,11 +1590,6 @@ GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v Ipv4Address tempip = extlsa->GetLinkStateId (); tempip = tempip.CombineMask (tempmask); - NS_LOG_LOGIC (" Node " << node->GetId () << - " add route to " << tempip << - " with mask " << tempmask << - " using next hop " << v->GetNextHop () << - " via interface " << v->GetOutgoingInterfaceId ()); // // Here's why we did all of that work. We're going to add a host route to the // host address found in the m_linkData field of the point-to-point link @@ -1662,20 +1610,28 @@ GlobalRouteManagerImpl::SPFAddASExternal (GlobalRoutingLSA *extlsa, SPFVertex *v } Ptr gr = router->GetRoutingProtocol (); NS_ASSERT (gr); - if (v->GetOutgoingInterfaceId () >= 0) + // walk through all next-hop-IPs and out-going-interfaces for reaching + // the stub network gateway 'v' from the root node + for (uint32_t i = 0; i < v->GetNRootExitDirections (); i++) { - gr->AddASExternalRouteTo (tempip, tempmask, v->GetNextHop (), v->GetOutgoingInterfaceId ()); - NS_LOG_LOGIC ("Node " << node->GetId () << - " add network route to " << tempip << - " using next hop " << v->GetNextHop () << - " via interface " << v->GetOutgoingInterfaceId ()); - } - else - { - NS_LOG_LOGIC ("Node " << node->GetId () << - " NOT able to add network route to " << tempip << - " using next hop " << v->GetNextHop () << - " since outgoing interface id is negative"); + SPFVertex::NodeExit_t exit = v->GetRootExitDirection (i); + Ipv4Address nextHop = exit.first; + int32_t outIf = exit.second; + if (outIf >= 0) + { + gr->AddASExternalRouteTo (tempip, tempmask, nextHop, outIf); + NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () << + " add external network route to " << tempip << + " using next hop " << nextHop << + " via interface " << outIf); + } + else + { + NS_LOG_LOGIC ("(Route " << i << ") Node " << node->GetId () << + " NOT able to add network route to " << tempip << + " using next hop " << nextHop << + " since outgoing interface id is negative"); + } } return; } // if diff --git a/src/routing/global-routing/global-route-manager-impl.h b/src/routing/global-routing/global-route-manager-impl.h index 4befa1d6a..46aebbe52 100644 --- a/src/routing/global-routing/global-route-manager-impl.h +++ b/src/routing/global-routing/global-route-manager-impl.h @@ -255,183 +255,6 @@ public: */ void SetDistanceFromRoot (uint32_t distance); -/** - * \deprecated Use GetRootExitDirection instead - * - * @brief Get the interface ID that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * @internal - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The outgoing interface that we're asking for is the interface - * index on the root node that should be used to start packets along the - * path to "this" vertex. - * - * When initializing the root SPFVertex, the interface ID is determined by - * examining the Global Router Link Records of the Link State Advertisement - * generated by the root node's GlobalRouter. These interfaces are used to - * forward packets off of the root's network down those links. As other - * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Global Router Link Record. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to the interface of that - * first hop. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, the root node is asking, "which of my local interfaces - * should I use to get a packet to the network or host represented by 'this' - * SPFVertex." - * - * @see GlobalRouter - * @see GlobalRoutingLSA - * @see GlobalRoutingLinkRecord - * @returns The interface index to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - uint32_t GetOutgoingInterfaceId (void) const NS_DEPRECATED; - -/** - * \deprecated Use SetRootExitDirection instead - * - * @brief Set the interface ID that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * @internal - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The outgoing interface that we're asking for is the interface - * index on the root node that should be used to start packets along the - * path to "this" vertex. - * - * When initializing the root SPFVertex, the interface ID is determined by - * examining the Global Router Link Records of the Link State Advertisement - * generated by the root node's GlobalRouter. These interfaces are used to - * forward packets off of the root's network down those links. As other - * vertices are discovered which are further away from the root, they will - * be accessible down one of the paths begun by a Global Router Link Record. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to the interface of that - * first hop. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, we are letting the root node know which of its local - * interfaces it should use to get a packet to the network or host represented - * by "this" SPFVertex. - * - * @see GlobalRouter - * @see GlobalRoutingLSA - * @see GlobalRoutingLinkRecord - * @param id The interface index to use when forwarding packets to the host or - * network represented by "this" SPFVertex. - */ - void SetOutgoingInterfaceId (int32_t id) NS_DEPRECATED; - -/** - * \deprecated Use GetRootExitDirection instead - * - * @brief Get the IP address that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * @internal - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The IP address that we're asking for is the address on the - * remote side of a link off of the root node that should be used as the - * destination for packets along the path to "this" vertex. - * - * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Global Router Link Records of the - * Link State Advertisement generated by the root node's GlobalRouter. This - * address is used to forward packets off of the root's network down those - * links. As other vertices / nodes are discovered which are further away - * from the root, they will be accessible down one of the paths via a link - * described by one of these Global Router Link Records. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to a first hop router down - * an interface. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method, the root node is asking, "which router should I send a - * packet to in order to get that packet to the network or host represented - * by 'this' SPFVertex." - * - * @see GlobalRouter - * @see GlobalRoutingLSA - * @see GlobalRoutingLinkRecord - * @returns The IP address to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - Ipv4Address GetNextHop (void) const NS_DEPRECATED; - -/** - * \deprecated Use SetRootExitDirection instead - * - * @brief Set the IP address that should be used to begin forwarding packets - * from the root SPFVertex to "this" SPFVertex. - * @internal - * - * Each router node in the simulation is associated with an SPFVertex object. - * When calculating routes, each of these routers is, in turn, chosen as the - * "root" of the calculation and routes to all of the other routers are - * eventually saved in the routing tables of each of the chosen nodes. - * - * The "Root" vertex is then the SPFVertex representing the router that is - * having its routing tables set. The "this" SPFVertex is the vertex that - * represents the host or network to which a route is being calculated from - * the root. The IP address that we're asking for is the address on the - * remote side of a link off of the root node that should be used as the - * destination for packets along the path to "this" vertex. - * - * When initializing the root SPFVertex, the IP address used when forwarding - * packets is determined by examining the Global Router Link Records of the - * Link State Advertisement generated by the root node's GlobalRouter. This - * address is used to forward packets off of the root's network down those - * links. As other vertices / nodes are discovered which are further away - * from the root, they will be accessible down one of the paths via a link - * described by one of these Global Router Link Records. - * - * To forward packets to these hosts or networks, the root node must begin - * the forwarding process by sending the packets to a first hop router down - * an interface. This means that the first hop address and interface ID must - * be the same for all downstream SPFVertices. We call this "inheriting" - * the interface and next hop. - * - * In this method we are telling the root node which router it should send - * should I send a packet to in order to get that packet to the network or - * host represented by 'this' SPFVertex." - * - * @see GlobalRouter - * @see GlobalRoutingLSA - * @see GlobalRoutingLinkRecord - * @param nextHop The IP address to use when forwarding packets to the host - * or network represented by "this" SPFVertex. - */ - void SetNextHop (Ipv4Address nextHop) NS_DEPRECATED; /** * @brief Set the IP address and outgoing interface index that should be used * to begin forwarding packets from the root SPFVertex to "this" SPFVertex. diff --git a/src/routing/olsr/olsr-routing-protocol.cc b/src/routing/olsr/olsr-routing-protocol.cc index 5c3873703..45d9e91ce 100644 --- a/src/routing/olsr/olsr-routing-protocol.cc +++ b/src/routing/olsr/olsr-routing-protocol.cc @@ -72,7 +72,7 @@ /********** Holding times **********/ /// Neighbor holding time. -#define OLSR_NEIGHB_HOLD_TIME (Scalar (3) * m_helloInterval) +#define OLSR_NEIGHB_HOLD_TIME (Scalar (3) * OLSR_REFRESH_INTERVAL) /// Top holding time. #define OLSR_TOP_HOLD_TIME (Scalar (3) * m_tcInterval) /// Dup holding time. diff --git a/src/test/perf/perf-pcap.cc b/src/test/perf/perf-pcap.cc index 5b9e4896c..4c96c370b 100644 --- a/src/test/perf/perf-pcap.cc +++ b/src/test/perf/perf-pcap.cc @@ -16,6 +16,7 @@ #include #include +#include #include "ns3/simulator-module.h" #include "ns3/node-module.h" @@ -29,38 +30,56 @@ using namespace ns3; bool g_passheader = true; bool g_addheader = true; + +RadiotapHeader g_header; + Time g_t(0.); -static void -WritePacket (Ptr file, Ptr packet) +void +PerfPcapNew (Ptr file, Ptr p, uint32_t n) { if (g_passheader) { - RadiotapHeader header; - header.SetTsft (0); - header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE); - header.SetRate (0); - header.SetChannelFrequencyAndFlags (0, 0); - - file->Write (g_t, header, packet); - return; - } - - if (g_addheader) - { - RadiotapHeader header; - header.SetTsft (0); - header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE); - header.SetRate (0); - header.SetChannelFrequencyAndFlags (0, 0); - - Ptr p = packet->Copy (); - p->AddHeader (header); - file->Write (g_t, p); + for (uint32_t i = 0; i < n; ++i) + { + if (g_passheader) + { + file->Write (g_t, g_header, p); + } + } } else { - file->Write (g_t, packet); + for (uint32_t i = 0; i < n; ++i) + { + if (g_addheader) + { + Ptr pc = p->Copy (); + pc->AddHeader (g_header); + file->Write (g_t, pc); + } + else + { + file->Write (g_t, p); + } + } + } +} + +void +PerfPcapOld (PcapWriter &pcapWriter, Ptr p, uint32_t n) +{ + + for (uint32_t i = 0; i < n; ++i) + { + if (g_addheader) + { + pcapWriter.WriteWifiMonitorPacket (p, 0, 0, 0, true, false, 0., 0.); + } + else + { + pcapWriter.WritePacket (p); + } } } @@ -68,17 +87,19 @@ int main (int argc, char *argv[]) { uint32_t n = 100000; + uint32_t iter = 50; bool oldstyle = false; CommandLine cmd; cmd.AddValue ("addheader", "Add a header to the traces to trigger a deep copy", g_addheader); cmd.AddValue ("passheader", "Pass header as reference instead of adding it", g_passheader); cmd.AddValue ("n", "How many packets to write (defaults to 100000", n); + cmd.AddValue ("iter", "How many times to run the test looking for a min (defaults to 20)", iter); cmd.AddValue ("oldstyle", "run the old style pcap writer stuff if true", oldstyle); cmd.Parse (argc, argv); - uint64_t et; - + uint64_t result = std::numeric_limits::max (); + if (oldstyle) { PcapWriter pcapWriter; @@ -87,50 +108,48 @@ main (int argc, char *argv[]) Ptr p = Create (1024); - //NS_LOG_UNCOND ("timing old style pcap file write of 1K packet"); - //NS_LOG_UNCOND ("g_addheader = " << g_addheader); - //NS_LOG_UNCOND ("g_passheader = " << g_passheader); - //NS_LOG_UNCOND ("n = " << n); - - SystemWallClockMs ms; - ms.Start (); - - for (uint32_t i = 0; i < n; ++i) + // + // This will probably run on a machine doing other things. Run it some + // relatively large number of times and try to find a minimum, which + // will hopefully represent a time when it runs free of interference. + // + for (uint32_t i = 0; i < iter; ++i) { - if (g_addheader) - { - pcapWriter.WriteWifiMonitorPacket (p, 0, 0, 0, true, false, 0., 0.); - } - else - { - pcapWriter.WritePacket (p); - } + SystemWallClockMs ms; + ms.Start (); + PerfPcapOld (pcapWriter, p, n); + uint64_t et = ms.End (); + result = std::min (result, et); + std::cout << "."; std::cout.flush (); } - - et = ms.End (); + std::cout << std::endl; } else { PcapHelper pcapHelper; - Ptr file = pcapHelper.CreateFile ("perf-pcap.pcap", "w", PcapHelper::DLT_IEEE802_11_RADIO); - + Ptr file = pcapHelper.CreateFile ("perf-pcap.pcap", "w", PcapHelper::DLT_IEEE802_11_RADIO); Ptr p = Create (1024); - //NS_LOG_UNCOND ("timing new style pcap file write of 1K packet"); - //NS_LOG_UNCOND ("g_addheader = " << g_addheader); - //NS_LOG_UNCOND ("g_passheader = " << g_passheader); - //NS_LOG_UNCOND ("n = " << n); + g_header.SetTsft (0); + g_header.SetFrameFlags (RadiotapHeader::FRAME_FLAG_SHORT_PREAMBLE); + g_header.SetRate (0); + g_header.SetChannelFrequencyAndFlags (0, 0); - SystemWallClockMs ms; - ms.Start (); - - for (uint32_t i = 0; i < n; ++i) + // + // This will probably run on a machine doing other things. Run it some + // relatively large number of times and try to find a minimum, which + // will hopefully represent a time when it runs free of interference. + // + for (uint32_t i = 0; i < iter; ++i) { - WritePacket (file, p); + SystemWallClockMs ms; + ms.Start (); + PerfPcapNew (file, p, n); + uint64_t et = ms.End (); + result = std::min (result, et); + std::cout << "."; std::cout.flush (); } - - et = ms.End (); + std::cout << std::endl; } - - //NS_LOG_UNCOND ("elapsed time = " << et); + std::cout << "perf-pcap: " << result << "ms" << std::endl; } diff --git a/src/wscript b/src/wscript index 252867421..0815da7d8 100644 --- a/src/wscript +++ b/src/wscript @@ -140,7 +140,7 @@ class ns3header_taskgen(TaskGen.task_gen): raise Utils.WafError("source ns3 header file %s not found" % (filename,)) dst_node = ns3_dir_node.find_or_declare(os.path.basename(filename)) assert dst_node is not None - task = self.create_task('ns3header', self.env) + task = self.create_task('ns3header', env=self.env) task.set_inputs([src_node]) task.set_outputs([dst_node]) @@ -245,7 +245,7 @@ class ns3moduleheader_taskgen(TaskGen.task_gen): module_obj = self.bld.name_to_obj("ns3-" + self.module, self.env) assert module_obj is not None all_headers_outputs = [ns3_dir_node.find_or_declare("%s-module.h" % self.module)] - task = self.create_task('gen_ns3_module_header', self.env) + task = self.create_task('gen_ns3_module_header', env=self.env) task.set_inputs(all_headers_inputs) task.set_outputs(all_headers_outputs) task.module = self.module diff --git a/utils/check-style.py b/utils/check-style.py new file mode 100755 index 000000000..2544e3091 --- /dev/null +++ b/utils/check-style.py @@ -0,0 +1,439 @@ +#!/usr/bin/env python + +import os +import subprocess +import tempfile +import sys +import filecmp +import optparse +import shutil +import difflib +import re + +def hg_modified_files(): + files = os.popen ('hg st -nma') + return [filename.strip() for filename in files] + +def copy_file(filename): + [tmp,pathname] = tempfile.mkstemp() + src = open(filename, 'r') + dst = open(pathname, 'w') + for line in src: + dst.write(line) + dst.close() + src.close() + return pathname + +# generate a temporary configuration file +def uncrustify_config_file(level): + level2 = """ +nl_collapse_empty_body=False +nl_if_brace=Add +nl_brace_else=Add +nl_elseif_brace=Add +nl_else_brace=Add +nl_while_brace=Add +nl_do_brace=Add +nl_for_brace=Add +nl_brace_while=Add +nl_switch_brace=Add +nl_after_case=True +nl_namespace_brace=Remove +nl_after_brace_open=True +nl_class_leave_one_liners=False +nl_enum_leave_one_liners=False +nl_func_leave_one_liners=False +nl_if_leave_one_liners=False +nl_class_colon=Ignore +nl_after_access_spec=1 +nl_after_semicolon=True +pos_class_colon=Lead +pos_class_comma=Trail +pos_bool=Lead +nl_class_init_args=Add +nl_template_class=Add +nl_class_brace=Add +# does not work very well +nl_func_type_name=Ignore +nl_func_scope_name=Ignore +nl_func_type_name_class=Ignore +nl_func_proto_type_name=Ignore +# function\\n( +nl_func_paren=Remove +nl_fdef_brace=Add +nl_struct_brace=Add +nl_enum_brace=Add +nl_union_brace=Add +mod_full_brace_do=Add +mod_full_brace_for=Add +mod_full_brace_if=Add +mod_full_brace_while=Add +mod_full_brace_for=Add +mod_remove_extra_semicolon=True +# max code width +#code_width=128 +#ls_for_split_full=True +#ls_func_split_full=True +""" + level1 = """ +# extra spaces here and there +sp_func_proto_paren=Add +sp_func_def_paren=Add +sp_func_call_paren=Add +sp_brace_typedef=Add +sp_enum_assign=Add +sp_before_sparen=Add +sp_after_semi_for=Add +sp_arith=Add +sp_assign=Add +sp_compare=Add +sp_cmt_cpp_start=Add +sp_func_class_paren=Add +sp_after_type=Add +sp_type_func=Add +sp_angle_paren=Add +""" + level0 = """ +sp_after_semi_for=Ignore +sp_before_sparen=Ignore +sp_type_func=Ignore +sp_after_type=Ignore +nl_class_leave_one_liners=True +nl_enum_leave_one_liners=True +nl_func_leave_one_liners=True +nl_assign_leave_one_liners=True +#nl_collapse_empty_body=False +nl_getset_leave_one_liners=True +nl_if_leave_one_liners=True +nl_fdef_brace=Ignore +# finally, indentation configuration +indent_with_tabs=0 +indent_namespace=false +indent_columns=2 +indent_brace=2 +indent_case_brace=2 +indent_class=true +indent_class_colon=True +# alignment +indent_align_assign=False +align_left_shift=True +# comment reformating disabled +cmt_reflow_mode=1 # do not touch comments at all +cmt_indent_multi=False # really, do not touch them +""" + [tmp,pathname] = tempfile.mkstemp() + dst = open(pathname, 'w') + dst.write(level0) + if level >= 1: + dst.write(level1) + if level >= 2: + dst.write(level2) + dst.close() + return pathname + +class PatchChunkLine: + SRC = 1 + DST = 2 + BOTH = 3 + def __init__(self): + self.__type = 0 + self.__line = '' + def set_src(self,line): + self.__type = self.SRC + self.__line = line + def set_dst(self,line): + self.__type = self.DST + self.__line = line + def set_both(self,line): + self.__type = self.BOTH + self.__line = line + def append_to_line(self, s): + self.__line = self.__line + s + def line(self): + return self.__line + def is_src(self): + return self.__type == self.SRC or self.__type == self.BOTH + def is_dst(self): + return self.__type == self.DST or self.__type == self.BOTH + def write(self, f): + if self.__type == self.SRC: + f.write('-%s\n' % self.__line) + elif self.__type == self.DST: + f.write('+%s\n' % self.__line) + elif self.__type == self.BOTH: + f.write(' %s\n' % self.__line) + else: + raise Exception('invalid patch') + + +class PatchChunk: + def __init__(self, src_pos, dst_pos): + self.__lines = [] + self.__src_pos = int(src_pos) + self.__dst_pos = int(dst_pos) + def src_start(self): + return self.__src_pos + def add_line(self,line): + self.__lines.append(line) + def src(self): + src = [] + for line in self.__lines: + if line.is_src(): + src.append(line) + return src + def dst(self): + dst = [] + for line in self.__lines: + if line.is_dst(): + dst.append(line) + return dst + def src_len(self): + return len(self.src()) + def dst_len(self): + return len(self.dst()) + def write(self,f): + f.write('@@ -%d,%d +%d,%d @@\n' % (self.__src_pos, self.src_len(), + self.__dst_pos, self.dst_len())) + for line in self.__lines: + line.write(f) + +class Patch: + def __init__(self): + self.__src = '' + self.__dst = '' + self.__chunks = [] + def add_chunk(self, chunk): + self.__chunks.append(chunk) + def chunks(self): + return self.__chunks + def set_src(self,src): + self.__src = src + def set_dst(self,dst): + self.__dst = dst + def apply(self,filename): + # XXX: not implemented + return + def write(self,f): + f.write('--- %s\n' % self.__src ) + f.write('+++ %s\n' % self.__dst ) + for chunk in self.__chunks: + chunk.write(f) + +def parse_patchset(generator): + src_file = re.compile('^--- (.*)$') + dst_file = re.compile('^\+\+\+ (.*)$') + chunk_start = re.compile('^@@ -([0-9]+),([0-9]+) \+([0-9]+),([0-9]+) @@') + src = re.compile('^-(.*)$') + dst = re.compile('^\+(.*)$') + both = re.compile('^ (.*)$') + patchset = [] + current_patch = None + for line in generator: + m = src_file.search(line) + if m is not None: + current_patch = Patch() + patchset.append(current_patch) + current_patch.set_src(m.group(1)) + continue + m = dst_file.search(line) + if m is not None: + current_patch.set_dst(m.group(1)) + continue + m = chunk_start.search(line) + if m is not None: + current_chunk = PatchChunk(m.group(1), m.group(3)) + current_patch.add_chunk(current_chunk) + continue + m = src.search(line) + if m is not None: + l = PatchChunkLine() + l.set_src(m.group(1)) + current_chunk.add_line(l) + continue + m = dst.search(line) + if m is not None: + l = PatchChunkLine() + l.set_dst(m.group(1)) + current_chunk.add_line(l) + continue + m = both.search(line) + if m is not None: + l = PatchChunkLine() + l.set_both(m.group(1)) + current_chunk.add_line(l) + continue + raise Exception() + return patchset + +def remove_trailing_whitespace_changes(patch_generator): + whitespace = re.compile('^(.*)([ \t]+)$') + patchset = parse_patchset(patch_generator) + for patch in patchset: + for chunk in patch.chunks(): + src = chunk.src() + dst = chunk.dst() + try: + for i in range(0,len(src)): + s = src[i] + d = dst[i] + m = whitespace.search(s.line()) + if m is not None and m.group(1) == d.line(): + d.append_to_line(m.group(2)) + except: + return patchset + return patchset + + +def indent(source, debug, level): + output = tempfile.mkstemp()[1] + # apply uncrustify + cfg = uncrustify_config_file(level) + if debug: + sys.stderr.write('original file=' + source + '\n') + sys.stderr.write('uncrustify config file=' + cfg + '\n') + sys.stderr.write('temporary file=' + output + '\n') + try: + uncrust = subprocess.Popen(['uncrustify', '-c', cfg, '-f', source, '-o', output], + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE) + (out, err) = uncrust.communicate('') + if debug: + sys.stderr.write(out) + sys.stderr.write(err) + except OSError: + raise Exception ('uncrustify not installed') + # generate a diff file + src = open(source, 'r') + dst = open(output, 'r') + diff = difflib.unified_diff(src.readlines(), dst.readlines(), + fromfile=source, tofile=output) + src.close() + dst.close() + if debug: + initial_diff = tempfile.mkstemp()[1] + sys.stderr.write('initial diff file=' + initial_diff + '\n') + tmp = open(initial_diff, 'w') + tmp.writelines(diff) + tmp.close() + final_diff = tempfile.mkstemp()[1] + if level < 3: + patchset = remove_trailing_whitespace_changes(diff); + dst = open(final_diff, 'w') + if len(patchset) != 0: + patchset[0].write(dst) + dst.close() + else: + dst = open(final_diff, 'w') + dst.writelines(diff) + dst.close() + + + # apply diff file + if debug: + sys.stderr.write('final diff file=' + final_diff + '\n') + shutil.copyfile(source,output) + patch = subprocess.Popen(['patch', '-p1', '-i', final_diff, output], + stdin = subprocess.PIPE, + stdout = subprocess.PIPE, + stderr = subprocess.PIPE) + (out, err) = patch.communicate('') + if debug: + sys.stderr.write(out) + sys.stderr.write(err) + return output + + + +def indent_files(files, diff=False, debug=False, level=0, inplace=False): + output = [] + for f in files: + dst = indent(f, debug=debug, level=level) + output.append([f,dst]) + + # First, copy to inplace + if inplace: + for src,dst in output: + shutil.copyfile(dst,src) + return True + + # now, compare + failed = [] + for src,dst in output: + if filecmp.cmp(src,dst) == 0: + failed.append([src, dst]) + if len(failed) > 0: + if not diff: + print 'Found %u badly indented files:' % len(failed) + for src,dst in failed: + print ' ' + src + else: + for src,dst in failed: + s = open(src, 'r').readlines() + d = open(dst, 'r').readlines() + for line in difflib.unified_diff(s, d, fromfile=src, tofile=dst): + sys.stdout.write(line) + return False + return True + +def run_as_hg_hook(ui, repo, **kwargs): + # hack to work around mercurial < 1.3 bug + from mercurial import lock, error + lock.LockError = error.LockError + # actually do the work + files = hg_modified_files() + if not indent_files(files, inplace=False): + return True + return False + +def run_as_main(): + parser = optparse.OptionParser() + parser.add_option('--debug', action='store_true', dest='debug', default=False, + help='Output some debugging information') + parser.add_option('-l', '--level', type='int', dest='level', default=0, + help="Level of style conformance: higher levels include all lower levels. " + "level=0: re-indent only. level=1: add extra spaces. level=2: insert extra newlines and " + "extra braces around single-line statements. level=3: remove all trailing spaces") + parser.add_option('--check-hg-hook', action='store_true', dest='hg_hook', default=False, + help='Get the list of files to check from mercurial\'s list of modified ' + 'and added files and assume that the script runs as a pretxncommit mercurial hook') + parser.add_option('--check-hg', action='store_true', dest='hg', default=False, + help="Get the list of files to check from mercurial\'s list of modified and added files") + parser.add_option('-f', '--check-file', action='store', dest='file', default='', + help="Check a single file") + parser.add_option('--diff', action='store_true', dest='diff', default=False, + help="Generate a diff on stdout of the indented files") + parser.add_option('-i', '--in-place', action='store_true', dest='in_place', default=False, + help="Indent the input files in-place") + (options,args) = parser.parse_args() + debug = options.debug + if options.hg_hook: + files = hg_modified_files() + if not indent_files(files, debug=options.debug, + level=options.level, + inplace=False): + sys.exit(1) + elif options.hg: + files = hg_modified_files() + indent_files(files, diff=options.diff, + debug=options.debug, + level=options.level, + inplace=options.in_place) + elif options.file != '': + file = options.file + if not os.path.exists(file) or \ + not os.path.isfile(file): + print 'file %s does not exist' % file + sys.exit(1) + indent_files([file], diff=options.diff, + debug=options.debug, + level=options.level, + inplace=options.in_place) + sys.exit(0) + +if __name__ == '__main__': +# try: + run_as_main() +# except Exception, e: +# sys.stderr.write(str(e) + '\n') +# sys.exit(1) diff --git a/waf b/waf index 65ab0a8e3..d99146fa4 100755 Binary files a/waf and b/waf differ