merge from head
authorMathieu Lacage <mathieu.lacage@sophia.inria.fr>
Thu, 21 Jun 2007 09:40:57 +0200
changeset 896 9abc108e9817
parent 895 b90ba0bcfd36 (current diff)
parent 785 bf8e7773836a (diff)
child 897 3d0c89af9c50
merge from head
.hgtags
SConstruct
src/common/header.h
src/common/packet.cc
src/common/trailer.h
--- a/.hgtags	Wed Jun 13 00:20:53 2007 +0200
+++ b/.hgtags	Thu Jun 21 09:40:57 2007 +0200
@@ -1,3 +1,4 @@
 56928998e05c9c11f5f3aefe79be8d2843e0db88 release ns-3.0.1
 7ac5a4b0969b255c4824c926c2b37ef450136ce9 release ns-3.0.2
 0dc81e76166c56aaae64da48b673b62155943aad packet-history-working
+38099dd26e9467b8f49f8632f22789858149a6e7 release ns-3.0.3
--- a/README	Wed Jun 13 00:20:53 2007 +0200
+++ b/README	Thu Jun 21 09:40:57 2007 +0200
@@ -23,7 +23,7 @@
 process.
 
 Contributing to the ns-3 project is still a very informal
-process because that process depends heavily on the personality
+process because that process depends heavily on the background
 of the people involved, the amount of time they can invest
 and the type of model they want to work on.  
 
@@ -34,7 +34,7 @@
 2) An overview of the ns-3 project
 ----------------------------------
 
-This package contains the latest version of ns-3 which is aims 
+This package contains the latest version of ns-3 which aims 
 at being a replacement for ns-2. Currently, ns-3 provides a 
 number of very simple network simulation models:
   - an ipv4 and udp stack
@@ -93,6 +93,7 @@
 the following platforms:
   - gcc 3.3 and earlier
   - optimized builds on linux x86 gcc 4.0 
+  - cygwin
 
 Other platforms may or may not work: we welcome 
 patches to improve the portability of the code to these
--- a/SConstruct	Wed Jun 13 00:20:53 2007 +0200
+++ b/SConstruct	Thu Jun 21 09:40:57 2007 +0200
@@ -422,6 +422,12 @@
 sample_trace.set_executable()
 sample_trace.add_source('main-trace.cc')
 
+sample_query_interface = build.Ns3Module('sample-query-interface', 'samples')
+ns3.add(sample_query_interface)
+sample_query_interface.add_dep('common')
+sample_query_interface.set_executable()
+sample_query_interface.add_source('main-query-interface.cc')
+
 sample_simu = build.Ns3Module('sample-simulator', 'samples')
 ns3.add(sample_simu)
 sample_simu.set_executable()
--- a/VERSION	Wed Jun 13 00:20:53 2007 +0200
+++ b/VERSION	Thu Jun 21 09:40:57 2007 +0200
@@ -1,1 +1,1 @@
-3.0.2
+3.0.3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/release_steps.txt	Thu Jun 21 09:40:57 2007 +0200
@@ -0,0 +1,19 @@
+Steps in doing an ns-3 release
+
+1. prepare the source files
+   - revise and check in AUTHORS, if needed
+   - revise and check in RELEASE_NOTES
+   - update and check in VERSION to the latest release number
+2. make a new "architecture.pdf" document and place it in the doc/ directory
+3. scons dist
+4. test tarball on release platforms (run-tests and simple-p2p)
+5. tag ns-3-dev with "release ns-3.0.X"
+6. clone the ns-3-dev and place it on the repository
+7. upload "ns-3.0.x.tar.gz" to the releases/ directory on the server
+8. update web page
+   - add link to news.html
+   - update download.html
+   - update roadmap.html
+   - build and update Doxygen directory on the server
+   - update and upload software architecture document (PDF, HTML)
+9. announce to ns-developers, with summary of release notes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/samples/main-query-interface.cc	Thu Jun 21 09:40:57 2007 +0200
@@ -0,0 +1,280 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/*
+ * Copyright (c) 2007 University of Washington
+ * Authors:  Tom Henderson, Craig Dowell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation;
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "ns3/debug.h"
+#include "ns3/object.h"
+#include "ns3/component-manager.h"
+
+using namespace ns3;
+
+//
+// This sample file shows examples of how to use QueryInterface.
+//
+// QueryInterface is a templated method of class Object, defined in 
+// src/core/object.h.  ns-3 objects that derive from class Object
+// can have QueryInterface invoked on them.
+//
+// QueryInterface is a type-safe way to ask an object, at run-time, 
+// "Do you support the interface identified by the given InterfaceId?"  
+// It avoids deprecated techniques of having to downcast pointers to 
+// an object to ask questions about its type.  One or more interfaces
+// may be associated with a given object.
+// 
+// QueryInterface is of most use when working with base class
+// pointers of objects that may be subclassed.  For instance,
+// one may have a pointer to a Node, but not know whether it has
+// an IPv4 stack.  Another example might be to determine whether
+// a Node has an EnergyModel, to which calls to decrement energy
+// from the node's battery might be made.
+//
+
+
+//
+// Object is the base class for ns-3 node-related objects used at 
+// the public API.  Object provides reference counting implementations
+// and the QueryInterface.
+// 
+// A common design paradigm for an ns-3 node object, such as a Queue,
+// is that we provide an abstract base class that inherits from
+// Object.  This class is assigned an interface ID (iid) and 
+// contains the basic API for objects in this class and subclasses.
+// This base class is specialized to provide implementations of
+// the object in question (such as a DropTailQueue).
+// 
+// The design pattern commonly used is known as the "non-virtual
+// public interface" pattern, whereby the public API for this
+// object is a set of public non-virtual functions that forward
+// to private virtual functions.  The forwarding functions can
+// impose pre- and post-conditions on the forwarding call at
+// the base class level.
+// 
+// We'll call this base class "AnInterface" in the example below.
+//
+// 
+class AnInterface : public Object
+{
+public:
+  static const InterfaceId iid;
+  void methodA (void);
+private:
+  virtual void domethodA (void) = 0;
+};
+
+void
+AnInterface::methodA (void)
+{
+  // pre-dispatch asserts
+   NS_DEBUG_UNCOND("AnInterface pre-condition::methodA");
+  domethodA ();
+   NS_DEBUG_UNCOND("AnInterface post-condition::methodA\n");
+  // post-dispatch asserts
+}
+
+//
+// The below assignment assigns the InterfaceId of the class AnInterface,
+// and declares that the parent iid is that of class Object.
+//
+const InterfaceId AnInterface::iid = MakeInterfaceId ("AnInterface", Object::iid);
+
+//
+// AnImplementation is an implementation of the abstract base class
+// defined above. It provides implementation for the virtual functions 
+// in the base class.  It defines one ClassId for each constructor, 
+// and can also provide an interface itself (in this example, 
+// a methodImpl is available)
+// 
+class AnImplementation : public AnInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  AnImplementation ();
+  void methodImpl (void);
+private:
+  virtual void domethodA (void);
+};
+
+void
+AnImplementation::methodImpl (void)
+{
+   NS_DEBUG_UNCOND("AnImplementation::methodImpl\n");
+}
+
+
+AnImplementation::AnImplementation (void)
+{
+  // enable our interface
+  SetInterfaceId (AnImplementation::iid);
+}
+
+void
+AnImplementation::domethodA () 
+{
+   NS_DEBUG_UNCOND("AnImplementation::domethodA");
+}
+
+//
+// The below assignment assigns the InterfaceId of the class AnImplementation,
+// and declares that the parent iid is that of class Object.
+//
+const InterfaceId AnImplementation::iid = 
+  MakeInterfaceId ("AnImplementation", AnInterface::iid);
+
+//
+// The next few lines are used by the component manager.  They
+// state that the component manager can create a new object 
+// AnImplementation and return an interface corresponding to 
+// the AnImplementation iid.
+//
+const ClassId AnImplementation::cid = 
+  MakeClassId<AnImplementation> 
+  ("AnImplementation", AnImplementation::iid);
+
+
+//
+// Extending interfaces
+// ==================
+// What if AnInterface doesn't provide enough API for your
+// object type?
+// - if you aren't concerned about backward compatibility and
+//   don't mind recompiling, you just add new methods to AnInterface
+//   and recompile.
+// - if you want to address backward compatibiliy, or allow part
+//   of the system to use the old interface, you have to do more.
+//   You have to declare a new interface with the new functionality.
+//
+
+class AnExtendedInterface : public AnInterface
+{
+public:
+  static const InterfaceId iid;
+  void methodB (void);
+private:
+  virtual void domethodB (void) = 0;
+};
+
+const InterfaceId AnExtendedInterface::iid = 
+  MakeInterfaceId ("AnExtendedInterface", AnInterface::iid);
+
+//
+// Then you need provide an implementation for the virtual 
+// methods.  If you are providing a new implementation for 
+// everything, the answer is straightforward
+//
+
+class ANewImplementation : public AnExtendedInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  ANewImplementation ();
+  void methodImpl (void);
+private:
+  virtual void domethodA (void) { /* new-implementation-behavior ();  */}
+  virtual void domethodB (void) { /* new-implementation-behavior (); */}
+};
+
+ANewImplementation::ANewImplementation (void)
+{
+  // enable our interface
+  SetInterfaceId (ANewImplementation::iid);
+}
+
+void
+ANewImplementation::methodImpl (void)
+{
+   NS_DEBUG_UNCOND("ANewImplementation::methodImpl\n");
+}
+
+const InterfaceId ANewImplementation::iid = 
+  MakeInterfaceId ("ANewImplementation", AnExtendedInterface::iid);
+
+//
+// If you want to extend an existing implementation, you can use 
+// the existing class to instantiate an implementation of its 
+// methods (hasa) and do the following if you can use stuff from 
+// the existing class.
+//
+
+class AnExtendedImplementation : public AnExtendedInterface
+{
+public:
+  static const InterfaceId iid;
+  static const ClassId cid;
+
+  AnExtendedImplementation ();
+  void methodImpl (void) { /* pImpl->methodImpl (); */ }
+  void methodExtendedImpl (void);
+private:
+  virtual void domethodA (void) { /* new-implementation-behavior (); */}
+  virtual void domethodB (void) { /* new-implementation-behavior (); */}
+  Ptr<AnImplementation> pImpl;
+};
+
+AnExtendedImplementation::AnExtendedImplementation (void)
+{
+  pImpl = Create<AnImplementation> (); 
+  SetInterfaceId (AnExtendedImplementation::iid);
+}
+
+void
+AnExtendedImplementation::methodExtendedImpl (void)
+{
+   NS_DEBUG_UNCOND("AnExtendedImplementation::methodExtendedImpl\n");
+}
+
+const InterfaceId AnExtendedImplementation::iid = 
+  MakeInterfaceId ("AnExtendedImplementation", AnExtendedInterface::iid);
+
+//
+// Inheriting from an existing implementation (isa) and an extended
+// interface is tricky, because of the diamond multiple inheritance
+// problem.  If the pImpl method above is not desirable, it may
+// be that the implementation extension could be aggregated.
+// 
+// The extension will not have access to the base implementation,
+// so this design pattern may be more appropriate if the extension
+// is very modular (e.g., add an EnergyModel to a wireless interface)
+//
+// EXAMPLE NOT YET PROVIDED
+
+int main (int argc, char *argv[])
+{
+
+  Ptr<AnInterface> aBase = ComponentManager::Create<AnImplementation> 
+    (AnImplementation::cid, AnInterface::iid);
+  NS_ASSERT (aBase != 0);
+
+  aBase->methodA ();
+  //aBase->methodImpl (); // XXX won't compile, aBase not right ptr type
+  
+  Ptr<AnImplementation> aBaseImplPtr = 
+    aBase-> QueryInterface<AnImplementation> (AnImplementation::iid);
+  aBaseImplPtr->methodImpl ();
+  aBaseImplPtr->methodA();
+
+  // Test symmetric property of QueryInterface 
+  Ptr<AnInterface> aBase2 = 
+    aBaseImplPtr-> QueryInterface<AnInterface> (AnInterface::iid);
+  aBase2->methodA ();
+
+  return 0;
+}
--- a/src/applications/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/applications/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,6 +1,10 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 
+def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-applications')
+
+
 def build(bld):
     obj = bld.create_obj('cpp', 'shlib')
     obj.name = 'ns3-applications'
--- a/src/common/header.h	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/common/header.h	Thu Jun 21 09:40:57 2007 +0200
@@ -53,6 +53,10 @@
 
   /**
    * \returns the size of the serialized Header.
+   *
+   * This method is used by Packet::AddHeader to reserve
+   * enough room in the packet byte buffer prior to calling
+   * Header::Serialize.
    */
   virtual uint32_t GetSerializedSize (void) const = 0;
 
@@ -67,6 +71,10 @@
    *    deserialize itself. This iterator identifies 
    *    the start of the buffer.
    * \returns the number of bytes read from the buffer
+   *
+   * The value returned is used to trim the packet byte buffer of the 
+   * corresponding amount when this method is invoked from 
+   * Packet::RemoveHeader
    */
   virtual uint32_t DeserializeFrom (Buffer::Iterator start) = 0;
 };
--- a/src/common/packet.cc	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/common/packet.cc	Thu Jun 21 09:40:57 2007 +0200
@@ -144,3 +144,58 @@
 }
 
 }; // namespace ns3
+
+
+
+#ifdef RUN_SELF_TESTS
+
+#include "ns3/test.h"
+#include <string>
+
+namespace ns3 {
+
+class PacketTest: public Test {
+public:
+  virtual bool RunTests (void);
+  PacketTest ();
+};
+
+
+PacketTest::PacketTest ()
+  : Test ("Packet") {}
+
+
+bool
+PacketTest::RunTests (void)
+{
+  bool ok = true;
+
+  Packet pkt1 (reinterpret_cast<const uint8_t*> ("hello"), 5);
+  Packet pkt2 (reinterpret_cast<const uint8_t*> (" world"), 6);
+  Packet packet;
+  packet.AddAtEnd (pkt1);
+  packet.AddAtEnd (pkt2);
+  
+  if (packet.GetSize () != 11)
+    {
+      Failure () << "expected size 11, got " << packet.GetSize () << std::endl;
+      ok = false;
+    }
+
+  std::string msg = std::string (reinterpret_cast<const char *>(packet.PeekData ()),
+                                 packet.GetSize ());
+  if (msg != "hello world")
+    {
+      Failure () << "expected size 'hello world', got " << msg << std::endl;
+      ok = false;
+    }
+
+  return ok;
+}
+
+
+static PacketTest gPacketTest;
+
+}; // namespace ns3
+
+#endif /* RUN_SELF_TESTS */
--- a/src/common/trailer.h	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/common/trailer.h	Thu Jun 21 09:40:57 2007 +0200
@@ -36,6 +36,32 @@
  *   - ns3::Trailer::DeserializeFrom
  *   - ns3::Trailer::GetSerializedSize
  *   - ns3::Trailer::PrintTo
+ *
+ * Note that the SerializeTo and DeserializeFrom methods behave
+ * in a way which might seem surprising to users: the input iterator
+ * really points to the end of the buffer to which and from which
+ * the user is expected to write and read respectively. This means that
+ * if the trailer has a fixed size and if the user wishes to read or
+ * write that trailer from front to back, the user must rewind the 
+ * iterator by hand to go to the start of the trailer. Typical code
+ * looks like this:
+ * \code
+ * void CrcTrailer::SerializeTo (Buffer::Iterator end)
+ * {
+ *   end.Prev (4);
+ *   end.WriteHtonU32 (m_crc);
+ * }
+ * \endcode
+ *
+ * Some users would have expected that the iterator would be rewinded 
+ * to the "start" of the trailer before calling SerializeTo and DeserializeFrom.
+ * However, this behavior was not implemented because it cannot be made to
+ * work reliably for trailers which have a variable size. i.e., if the trailer 
+ * contains options, the code which calls DeserializeFrom cannot rewind
+ * to the start of the trailer because it does not know the real size of the 
+ * trailer. Hence, to make this legitimate use-case work (variable-sized 
+ * trailers), the input iterator to DeserializeFrom and SerializeTo points
+ * to the end of the trailer, and not its start.
  */
 class Trailer : public Chunk {
 public:
@@ -53,6 +79,10 @@
 
   /**
    * \returns the size of the serialized Trailer.
+   *
+   * This method is used by Packet::AddTrailer to reserve
+   * enough room in the packet byte buffer prior to calling
+   * Trailer::Serialize.
    */
   virtual uint32_t GetSerializedSize (void) const = 0;
 
@@ -60,6 +90,9 @@
    * \param end the buffer iterator in which the protocol trailer
    *    must serialize itself. This iterator identifies 
    *    the end of the buffer.
+   *
+   * This iterator must be typically moved with the Buffer::Iterator::Prev
+   * method before writing any byte in the buffer.
    */
   virtual void SerializeTo (Buffer::Iterator end) const = 0;
   /**
@@ -67,6 +100,11 @@
    *    deserialize itself. This iterator identifies 
    *    the end of the buffer.
    * \returns the number of bytes read from the buffer
+   *
+   * This iterator must be typically moved with the Buffer::Iterator::Prev
+   * method before reading any byte in the buffer. The value returned
+   * is used to trim the packet byte buffer of the corresponding
+   * amount when this method is invoked from Packet::RemoveTrailer
    */
   virtual uint32_t DeserializeFrom (Buffer::Iterator end) = 0;
 };
--- a/src/common/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/common/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,5 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-common')
 
 def build(bld):
     common = bld.create_obj('cpp', 'shlib')
--- a/src/core/test.h	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/core/test.h	Thu Jun 21 09:40:57 2007 +0200
@@ -101,6 +101,41 @@
 };
 }; // namespace ns3 
 
+/**
+ * Convenience macro to check that a value returned by a test is what
+ * is expected.  Note: this macro assumes a 'bool result = true'
+ * declaration exists in the test function body, and that the function
+ * returns that value.
+ *
+ * \param got value obtained from the test
+ * \param expected value that the test is expected to return
+ */
+#define NS_TEST_ASSERT_EQUAL(got, expected)             \
+    if ((got) != (expected))                            \
+      {                                                 \
+        Failure () << __FILE__ << ":" <<__LINE__        \
+                   << ": expected " << (expected)       \
+                   << ", got " << (got) << std::endl;   \
+        result = false;                                 \
+      }
+/**
+ * Convenience macro to check an assertion is held during an unit
+ * test.  Note: this macro assumes a 'bool result = true' declaration
+ * exists in the test function body, and that the function returns
+ * that value.
+ *
+ * \param assertion expression that must be true if the test did not fail
+ */
+#define NS_TEST_ASSERT(assertion)                       \
+    if (!(assertion))                                   \
+      {                                                 \
+        Failure () << __FILE__ << ":" <<__LINE__        \
+                   << ": assertion `" << (assertion)    \
+                   << "'failed." << std::endl;          \
+        result = false;                                 \
+      }
+
+
 #endif /* RUN_SELF_TESTS */
 
 #endif /* TEST_H */
--- a/src/core/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/core/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -3,6 +3,8 @@
 
 
 def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-core')
+
     e = conf.create_header_configurator()
     e.mandatory = False
     e.name = 'stdlib.h'
--- a/src/devices/p2p/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/devices/p2p/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,6 +1,10 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 
+def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-p2p')
+
+
 def build(bld):
     p2p = bld.create_obj('cpp', 'shlib')
     p2p.name = 'ns3-p2p'
--- a/src/internet-node/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/internet-node/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,6 +1,10 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 
+def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-internet-node')
+
+
 def build(bld):
     obj = bld.create_obj('cpp', 'shlib')
     obj.name = 'ns3-internet-node'
--- a/src/node/ipv4-address.cc	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/node/ipv4-address.cc	Thu Jun 21 09:40:57 2007 +0200
@@ -215,6 +215,11 @@
 {
   return !a.IsEqual (b);
 }
+bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB)
+{
+  return (addrA.GetHostOrder () < addrB.GetHostOrder ());
+}
+
 size_t Ipv4AddressHash::operator()(Ipv4Address const &x) const 
 { 
   return x.GetHostOrder ();
@@ -230,6 +235,14 @@
   mask.Print (os);
   return os;
 }
+bool operator == (Ipv4Mask const &a, Ipv4Mask const &b)
+{
+  return a.IsEqual (b);
+}
+bool operator != (Ipv4Mask const &a, Ipv4Mask const &b)
+{
+  return !a.IsEqual (b);
+}
 
 
 }; // namespace ns3
--- a/src/node/ipv4-address.h	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/node/ipv4-address.h	Thu Jun 21 09:40:57 2007 +0200
@@ -122,11 +122,15 @@
 
 bool operator == (Ipv4Address const &a, Ipv4Address const &b);
 bool operator != (Ipv4Address const &a, Ipv4Address const &b);
+bool operator < (Ipv4Address const &addrA, Ipv4Address const &addrB);
+
 class Ipv4AddressHash : public std::unary_function<Ipv4Address, size_t> {
 public:
   size_t operator()(Ipv4Address const &x) const;
 };
-bool operator != (Ipv4Address const &a, Ipv4Address const &b);
+
+bool operator == (Ipv4Mask const &a, Ipv4Mask const &b);
+bool operator != (Ipv4Mask const &a, Ipv4Mask const &b);
 
 }; // namespace ns3
 
--- a/src/node/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/node/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,5 +1,8 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
+def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-node')
+
 
 def build(bld):
     node = bld.create_obj('cpp', 'shlib')
--- a/src/simulator/cairo-wideint.c	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/simulator/cairo-wideint.c	Thu Jun 21 09:40:57 2007 +0200
@@ -658,7 +658,7 @@
  * Compute a 32 bit quotient and 64 bit remainder of a 96 bit unsigned
  * dividend and 64 bit divisor.  If the quotient doesn't fit into 32
  * bits then the returned remainder is equal to the divisor, and the
- * qoutient is the largest representable 64 bit integer.  It is an
+ * quotient is the largest representable 64 bit integer.  It is an
  * error to call this function with the high 32 bits of @num being
  * non-zero. */
 cairo_uquorem64_t
@@ -776,7 +776,7 @@
 {
     int			num_neg = _cairo_int128_negative (num);
     int			den_neg = _cairo_int64_negative (den);
-    cairo_int64_t	nonneg_den = den;
+    cairo_uint64_t	nonneg_den;
     cairo_uquorem64_t	uqr;
     cairo_quorem64_t	qr;
 
@@ -784,9 +784,11 @@
 	num = _cairo_int128_negate (num);
     if (den_neg)
 	nonneg_den = _cairo_int64_negate (den);
+    else
+	nonneg_den = den;
 
     uqr = _cairo_uint_96by64_32x64_divrem (num, nonneg_den);
-    if (_cairo_uint64_eq (uqr.rem, nonneg_den)) {
+    if (_cairo_uint64_eq (uqr.rem, _cairo_int64_to_uint64 (nonneg_den))) {
 	/* bail on overflow. */
 	qr.quo = _cairo_uint32s_to_uint64 (0x7FFFFFFF, -1U);;
 	qr.rem = den;
--- a/src/simulator/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/simulator/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -13,6 +13,8 @@
 
 
 def configure(conf):
+    conf.env.append_value('NS3_MODULES', 'ns3-simulator')
+
     if Params.g_options.high_precision_as_double:
         conf.add_define('USE_HIGH_PRECISION_DOUBLE', 1)
         conf.env['USE_HIGH_PRECISION_DOUBLE'] = 1
--- a/src/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/src/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -29,6 +29,7 @@
 
     blddir = os.path.abspath(os.path.join(conf.m_blddir, conf.env.variant()))
     for module in all_modules:
+        conf.sub_config(module)
         conf.env.append_value('NS3_MODULE_PATH', os.path.join(blddir, 'src', module))
 
 
--- a/utils/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/utils/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -1,23 +1,23 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-import sys
-import Params
 
 
 def build(bld):
+    env = bld.env_of_name('default')
 
     def create_ns_prog(name, source):
         obj = bld.create_obj('cpp', 'program')
         obj.target = name
-        obj.uselib_local = "ns3-core ns3-common ns3-simulator"
         obj.source = source
         return obj
 
     unit_tests = create_ns_prog('run-tests', 'run-tests.cc')
     unit_tests.install_var  = 0 # do not install
     unit_tests.unit_test    = 1 # runs on 'waf check'
+    ## link unit test program with all ns3 modules
+    unit_tests.uselib_local = env['NS3_MODULES']
     
-    #if sys.platform != 'win32':
     obj = create_ns_prog('bench-simulator', 'bench-simulator.cc')
+    obj.uselib_local = "ns3-core ns3-common ns3-simulator"
+
     obj = create_ns_prog('replay-simulation', 'replay-simulation.cc')
-    ## bench-packets requires missing header files
-    #obj = create_ns_prog('bench-packets', 'bench-packets.cc')
+    obj.uselib_local = "ns3-core ns3-common ns3-simulator"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/waf.bat	Thu Jun 21 09:40:57 2007 +0200
@@ -0,0 +1,1 @@
+@python -x waf %* & exit /b
--- a/wscript	Wed Jun 13 00:20:53 2007 +0200
+++ b/wscript	Thu Jun 21 09:40:57 2007 +0200
@@ -79,6 +79,7 @@
     conf.setenv(variant_name)
 
     variant_env.append_value('CXXDEFINES', 'RUN_SELF_TESTS')
+    variant_env.append_value('CXXFLAGS', ['-Wall', '-Werror'])
     if 'debug' in Params.g_options.debug_level.lower():
         variant_env.append_value('CXXDEFINES', 'NS3_DEBUG_ENABLE')
         variant_env.append_value('CXXDEFINES', 'NS3_ASSERT_ENABLE')
@@ -141,6 +142,9 @@
     elif sys.platform == 'win32':
         pathvar = 'PATH'
         pathsep = ';'
+    elif sys.platform == 'cygwin':
+        pathvar = 'PATH'
+        pathsep = ':'
     else:
         Params.warning(("Don't know how to configure "
                         "dynamic library path for the platform '%s'") % (sys.platform,))