update a lot default tip
authorHajime Tazaki <tazaki@nict.go.jp>
Thu, 20 Jun 2013 09:56:26 +0900
changeset 260fca5307fd86
parent 25 7d5166e0dc25
update a lot
bgp-caida.patch
cradle-bulk.patch
dce-debug.patch
dce-sctp.patch
dce_test_improve.patch
fedora8-nontimerfd.patch
linux-stack-rework.patch
modulize-quagga-mip6.patch
more-test.patch
mpitest.patch
new-tutorial.patch
perf-update.patch
poll-rework.patch
pyscan.patch
python-binding.patch
series
task-mgr-rework.patch
valg.patch
waf-module-find.patch
     1.1 --- a/bgp-caida.patch	Mon Aug 06 20:45:50 2012 +0900
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,177 +0,0 @@
     1.4 -diff -r 137184880c3b example/dce-quagga-bgpd-caida.cc
     1.5 ---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.6 -+++ b/example/dce-quagga-bgpd-caida.cc	Tue Jan 24 17:31:19 2012 +0900
     1.7 -@@ -0,0 +1,159 @@
     1.8 -+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     1.9 -+
    1.10 -+#include "ns3/network-module.h"
    1.11 -+#include "ns3/core-module.h"
    1.12 -+#include "ns3/internet-module.h"
    1.13 -+#include "ns3/dce-module.h"
    1.14 -+#include "ns3/quagga-helper.h"
    1.15 -+#include "ns3/point-to-point-helper.h"
    1.16 -+#include "../helper/ipv4-dce-routing-helper.h"
    1.17 -+#include "ns3/topology-read-module.h"
    1.18 -+#include <sys/resource.h>
    1.19 -+
    1.20 -+using namespace ns3;
    1.21 -+NS_LOG_COMPONENT_DEFINE ("DceQuaggaBgpd");
    1.22 -+
    1.23 -+// Parameters
    1.24 -+uint32_t nNodes = 2;
    1.25 -+uint32_t stopTime = 6000;
    1.26 -+
    1.27 -+static void
    1.28 -+SetRlimit ()
    1.29 -+{
    1.30 -+  int ret;
    1.31 -+  struct rlimit limit;
    1.32 -+  limit.rlim_cur = 1000000;
    1.33 -+  limit.rlim_max = 1000000;
    1.34 -+
    1.35 -+  ret = setrlimit(RLIMIT_NOFILE, &limit);
    1.36 -+  if (ret == -1)
    1.37 -+    {
    1.38 -+       perror ("setrlimit");
    1.39 -+    }
    1.40 -+  return;
    1.41 -+}
    1.42 -+
    1.43 -+static void RunIp (Ptr<Node> node, Time at, std::string str)
    1.44 -+{
    1.45 -+  DceApplicationHelper process;
    1.46 -+  ApplicationContainer apps;
    1.47 -+  process.SetBinary ("ip");
    1.48 -+  process.SetStackSize (1<<16);
    1.49 -+  process.ResetArguments();
    1.50 -+  process.ParseArguments(str.c_str ());
    1.51 -+  apps = process.Install (node);
    1.52 -+  apps.Start (at);
    1.53 -+}
    1.54 -+
    1.55 -+static void AddAddress (Ptr<Node> node, Time at, const char *name, const char *address)
    1.56 -+{
    1.57 -+  std::ostringstream oss;
    1.58 -+  oss << "-f inet addr add " << address << " dev " << name;
    1.59 -+  RunIp (node, at, oss.str ());
    1.60 -+}
    1.61 -+
    1.62 -+int main (int argc, char *argv[]) {
    1.63 -+  // 
    1.64 -+  //  Step 0
    1.65 -+  //  Node Basic Configuration
    1.66 -+  // 
    1.67 -+
    1.68 -+  CommandLine cmd;
    1.69 -+  cmd.AddValue ("stopTime", "Time to stop(seconds)", stopTime);
    1.70 -+  cmd.Parse (argc,argv);
    1.71 -+
    1.72 -+  // 
    1.73 -+  //  Step 1
    1.74 -+  //  Node Basic Configuration
    1.75 -+  // 
    1.76 -+  Ptr<TopologyReader> inFile = 0;
    1.77 -+  TopologyReaderHelper topoHelp;
    1.78 -+  NodeContainer nodes;
    1.79 -+  
    1.80 -+  std::string format ("Caida");
    1.81 -+  std::string input ("./asrel-as2500.txt");
    1.82 -+
    1.83 -+  topoHelp.SetFileName(input);
    1.84 -+  topoHelp.SetFileType(format);
    1.85 -+  inFile = topoHelp.GetTopologyReader();
    1.86 -+
    1.87 -+  if (inFile != 0)
    1.88 -+    {
    1.89 -+      nodes = inFile->Read ();
    1.90 -+    }
    1.91 -+
    1.92 -+  if (nodes.GetN () == 0)
    1.93 -+    {
    1.94 -+      NS_LOG_ERROR ("Problems reading node information the topology file. Failing.");
    1.95 -+      return -1;
    1.96 -+    }
    1.97 -+  if (inFile->LinksSize () == 0)
    1.98 -+    {
    1.99 -+      NS_LOG_ERROR ("Problems reading the topology file. Failing.");
   1.100 -+      return -1;
   1.101 -+    }
   1.102 -+  NS_LOG_INFO ("Caida topology created with " << nodes.GetN () << " nodes and " << 
   1.103 -+               inFile->LinksSize () << " links (from " << input << ")");
   1.104 -+
   1.105 -+  // Address conf In virtual topology
   1.106 -+  PointToPointHelper p2p;
   1.107 -+  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
   1.108 -+  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
   1.109 -+
   1.110 -+  int totlinks = inFile->LinksSize ();
   1.111 -+  NS_LOG_INFO ("creating node containers");
   1.112 -+  NodeContainer nc[totlinks];
   1.113 -+  TopologyReader::ConstLinksIterator iter;
   1.114 -+  int i = 0;
   1.115 -+  for ( iter = inFile->LinksBegin (); iter != inFile->LinksEnd (); iter++, i++ )
   1.116 -+    {
   1.117 -+      nc[i] = NodeContainer (iter->GetFromNode (), iter->GetToNode ());
   1.118 -+    }
   1.119 -+
   1.120 -+  DceManagerHelper processManager;
   1.121 -+  processManager.SetLoader ("ns3::DlmLoaderFactory");
   1.122 -+  processManager.SetTaskManagerAttribute ("FiberManagerType", 
   1.123 -+                                          EnumValue (0));
   1.124 -+  processManager.SetNetworkStack("ns3::LinuxSocketFdFactory",
   1.125 -+                                 "Library", StringValue ("libnet-next-2.6.so"));
   1.126 -+  processManager.Install (nodes);
   1.127 -+  QuaggaHelper quagga;
   1.128 -+  quagga.EnableBgp (nodes);
   1.129 -+
   1.130 -+  NS_LOG_INFO ("creating net device containers");
   1.131 -+  NetDeviceContainer ndc[totlinks];
   1.132 -+  for (int i = 0; i < totlinks; i++)
   1.133 -+    {
   1.134 -+      ndc[i] = p2p.Install (nc[i]);
   1.135 -+
   1.136 -+#if 0
   1.137 -+      // IP address configuration
   1.138 -+      AddAddress (nodes.Get (0), Seconds (0.1), "sim0", "10.0.0.1/24");
   1.139 -+      RunIp (nodes.Get (0), Seconds (0.11), "link set lo up");
   1.140 -+      RunIp (nodes.Get (0), Seconds (0.11), "link set sim0 up");
   1.141 -+
   1.142 -+      AddAddress (nodes.Get (1), Seconds (0.1), "sim0", "10.0.0.2/24");
   1.143 -+      RunIp (nodes.Get (1), Seconds (0.11), "link set lo up");
   1.144 -+      RunIp (nodes.Get (1), Seconds (0.11), "link set sim0 up");
   1.145 -+
   1.146 -+      quagga.BgpAddNeighbor (nodes.Get (0), "10.0.0.2", quagga.GetAsn(nodes.Get (1)));
   1.147 -+      quagga.BgpAddNeighbor (nodes.Get (1), "10.0.0.1", quagga.GetAsn(nodes.Get (0)));
   1.148 -+      quagga.Install (nodes);  
   1.149 -+#endif
   1.150 -+    }
   1.151 -+
   1.152 -+
   1.153 -+  //  p2p.EnablePcapAll ("dce-quagga-bgpd-caida");
   1.154 -+
   1.155 -+  // 
   1.156 -+  // Now It's ready to GO!
   1.157 -+  // 
   1.158 -+  if (stopTime != 0)
   1.159 -+    {
   1.160 -+      Simulator::Stop (Seconds (stopTime));
   1.161 -+    }
   1.162 -+  Simulator::Run ();
   1.163 -+  Simulator::Destroy ();
   1.164 -+
   1.165 -+  return 0;
   1.166 -+}
   1.167 -diff -r 137184880c3b wscript
   1.168 ---- a/wscript	Tue Jan 24 16:33:26 2012 +0900
   1.169 -+++ b/wscript	Tue Jan 24 17:31:19 2012 +0900
   1.170 -@@ -266,6 +266,10 @@
   1.171 -                        target='bin/dce-quagga-ospfd',
   1.172 -                        source=['example/dce-quagga-ospfd.cc'])
   1.173 - 
   1.174 -+    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'visualizer', 'topology-read'],
   1.175 -+                       target='bin/dce-quagga-bgpd-caida',
   1.176 -+                       source=['example/dce-quagga-bgpd-caida.cc'])
   1.177 -+
   1.178 -     module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point'],
   1.179 -                        target='bin/dce-quagga-bgpd',
   1.180 -                        source=['example/dce-quagga-bgpd.cc'])
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/cradle-bulk.patch	Thu Jun 20 09:56:26 2013 +0900
     2.3 @@ -0,0 +1,251 @@
     2.4 +diff --git a/example/dce-cradle-simple.cc b/example/dce-cradle-simple.cc
     2.5 +--- a/example/dce-cradle-simple.cc
     2.6 ++++ b/example/dce-cradle-simple.cc
     2.7 +@@ -34,6 +34,8 @@
     2.8 + std::string m_rate = "100Bps";
     2.9 + bool m_dual = false;
    2.10 + std::string m_ccid = "2";
    2.11 ++bool m_bulk = false;
    2.12 ++
    2.13 + int
    2.14 + main (int argc, char *argv[])
    2.15 + {
    2.16 +@@ -57,6 +59,7 @@
    2.17 +   cmd.AddValue ("rate", "tx rate", m_rate);
    2.18 +   cmd.AddValue ("dual", "dual flow or not (default: uni-directional)", m_dual);
    2.19 +   cmd.AddValue ("ccid", "CCID if dccp (default: 2)", m_ccid);
    2.20 ++  cmd.AddValue ("bulk", "use BulkSendApp instead of OnOffApp", m_bulk);
    2.21 +   cmd.Parse (argc, argv);
    2.22 + 
    2.23 +   NodeContainer nodes;
    2.24 +@@ -89,17 +92,35 @@
    2.25 +   ApplicationContainer apps;
    2.26 +   OnOffHelper onoff = OnOffHelper (proto_sw[m_proto],
    2.27 +                                    InetSocketAddress (interfaces.GetAddress (1), 9));
    2.28 +-  onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
    2.29 +-  onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
    2.30 +-  onoff.SetAttribute ("PacketSize", StringValue ("1024"));
    2.31 +-  onoff.SetAttribute ("DataRate", StringValue (m_rate));
    2.32 +-  apps = onoff.Install (nodes.Get (0));
    2.33 +-  apps.Start (Seconds (4.0));
    2.34 +-  if (m_dual)
    2.35 ++  if (!m_bulk)
    2.36 +     {
    2.37 +-      onoff.SetAttribute ("Remote", AddressValue (InetSocketAddress (interfaces.GetAddress (0), 9)));
    2.38 +-      apps = onoff.Install (nodes.Get (1));
    2.39 +-      apps.Start (Seconds (4.1));
    2.40 ++      onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
    2.41 ++      onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
    2.42 ++      onoff.SetAttribute ("PacketSize", StringValue ("1024"));
    2.43 ++      onoff.SetAttribute ("DataRate", StringValue (m_rate));
    2.44 ++      apps = onoff.Install (nodes.Get (0));
    2.45 ++      apps.Start (Seconds (4.0));
    2.46 ++      if (m_dual)
    2.47 ++        {
    2.48 ++          onoff.SetAttribute ("Remote", AddressValue (InetSocketAddress (interfaces.GetAddress (0), 9)));
    2.49 ++          apps = onoff.Install (nodes.Get (1));
    2.50 ++          apps.Start (Seconds (4.1));
    2.51 ++        }
    2.52 ++    }
    2.53 ++  else
    2.54 ++    {
    2.55 ++      BulkSendHelper bulk (proto_sw[m_proto],
    2.56 ++                           InetSocketAddress (interfaces.GetAddress (1), 9));
    2.57 ++      // Set the amount of data to send in bytes.  Zero is unlimited.
    2.58 ++      bulk.SetAttribute ("MaxBytes", UintegerValue (1024));
    2.59 ++      apps = bulk.Install (nodes.Get (0));
    2.60 ++      apps.Start (Seconds (4.0));
    2.61 ++      if (m_dual)
    2.62 ++        {
    2.63 ++          bulk.SetAttribute ("Remote", AddressValue (InetSocketAddress (interfaces.GetAddress (0), 9)));
    2.64 ++          apps = bulk.Install (nodes.Get (1));
    2.65 ++          apps.Start (Seconds (4.1));
    2.66 ++        }
    2.67 +     }
    2.68 + 
    2.69 +   PacketSinkHelper sink = PacketSinkHelper (proto_sw[m_proto],
    2.70 +diff --git a/example/dce-tcp-ns3-nsc-comparison.cc b/example/dce-tcp-ns3-nsc-comparison.cc
    2.71 +--- a/example/dce-tcp-ns3-nsc-comparison.cc
    2.72 ++++ b/example/dce-tcp-ns3-nsc-comparison.cc
    2.73 +@@ -40,6 +40,7 @@
    2.74 + bool enablePcap = false;
    2.75 + std::string m_pktSize = "1024";
    2.76 + bool m_frag = false;
    2.77 ++bool m_bulk = false;
    2.78 + 
    2.79 + int
    2.80 + main (int argc, char *argv[])
    2.81 +@@ -55,6 +56,7 @@
    2.82 +   cmd.AddValue ("enablePcap", "pcap", enablePcap);
    2.83 +   cmd.AddValue ("pktSize", "packet size", m_pktSize);
    2.84 +   cmd.AddValue ("frag", "fragment", m_frag);
    2.85 ++  cmd.AddValue ("bulk", "use BulkSendApp instead of OnOffApp", m_bulk);
    2.86 +   cmd.Parse (argc, argv);
    2.87 + 
    2.88 +   SeedManager::SetSeed (m_seed);
    2.89 +@@ -91,10 +93,10 @@
    2.90 +     }
    2.91 +   else if (m_stack == "dce-dccp")
    2.92 +     {
    2.93 +-      internetStack.Install (routers);
    2.94 +       dceManager.SetNetworkStack ("ns3::LinuxSocketFdFactory",
    2.95 +                                   "Library", StringValue ("liblinux.so"));
    2.96 +       sock_factory = "ns3::LinuxDccpSocketFactory";
    2.97 ++      stack.Install (routers);
    2.98 +       stack.Install (lefts);
    2.99 +       stack.Install (rights);
   2.100 +     }
   2.101 +@@ -215,17 +217,34 @@
   2.102 +                                    InetSocketAddress (Ipv4Address ("10.2.0.2"), 2000));
   2.103 +   onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
   2.104 +   onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
   2.105 ++  onoff.SetAttribute ("PacketSize", StringValue (m_pktSize));
   2.106 ++  onoff.SetAttribute ("DataRate", StringValue ("1Mbps"));
   2.107 ++
   2.108 ++  BulkSendHelper bulk = BulkSendHelper (sock_factory,
   2.109 ++                                        InetSocketAddress ("10.2.0.2", 2000));
   2.110 ++  // Set the amount of data to send in bytes.  Zero is unlimited.
   2.111 ++  bulk.SetAttribute ("MaxBytes", UintegerValue (0));
   2.112 ++  bulk.SetAttribute ("SendSize", UintegerValue (atoi (m_pktSize.c_str ())));
   2.113 + 
   2.114 +   // Flow 1 - n
   2.115 +   for (uint32_t i = 0; i < m_nNodes; i++)
   2.116 +     {
   2.117 +       std::ostringstream oss;
   2.118 +       oss << "10.2." << i << ".2";
   2.119 +-      onoff.SetAttribute ("Remote", AddressValue (InetSocketAddress (Ipv4Address (oss.str ().c_str ()), 2000)));
   2.120 +-      onoff.SetAttribute ("PacketSize", StringValue (m_pktSize));
   2.121 +-      onoff.SetAttribute ("DataRate", StringValue ("1Mbps"));
   2.122 +-      onoff.SetAttribute ("StartTime", TimeValue (Seconds (startTime)));
   2.123 +-      apps = onoff.Install (lefts.Get (i));
   2.124 ++      if (!m_bulk)
   2.125 ++        {
   2.126 ++          onoff.SetAttribute ("Remote", 
   2.127 ++                              AddressValue (InetSocketAddress (Ipv4Address (oss.str ().c_str ()), 2000)));
   2.128 ++          onoff.SetAttribute ("StartTime", TimeValue (Seconds (startTime)));
   2.129 ++          apps = onoff.Install (lefts.Get (i));
   2.130 ++        }
   2.131 ++      else
   2.132 ++        {
   2.133 ++          bulk.SetAttribute ("Remote", 
   2.134 ++                             AddressValue (InetSocketAddress (Ipv4Address (oss.str ().c_str ()), 2000)));
   2.135 ++          apps = bulk.Install (lefts.Get (i));
   2.136 ++          apps.Start (Seconds (startTime));
   2.137 ++        }
   2.138 +     }
   2.139 + 
   2.140 +   PacketSinkHelper sink = PacketSinkHelper (sock_factory,
   2.141 +diff --git a/example/examples-to-run.py b/example/examples-to-run.py
   2.142 +--- a/example/examples-to-run.py
   2.143 ++++ b/example/examples-to-run.py
   2.144 +@@ -30,8 +30,15 @@
   2.145 +     ("dce-cradle-simple --rate=10kbps --proto=tcp", "True", "True"),
   2.146 +     ("dce-cradle-simple --rate=10kbps --proto=dccp", "True", "True"),
   2.147 +     ("dce-cradle-simple --rate=10kbps --proto=dccp -ccid=3", "True", "True"),
   2.148 ++    ("dce-cradle-simple --bulk=1 --rate=10kbps --proto=tcp", "True", "True"),
   2.149 ++    ("dce-cradle-simple --bulk=1 --rate=10kbps --proto=dccp", "True", "True"),
   2.150 ++    ("dce-cradle-simple --bulk=1 --rate=10kbps --proto=dccp -ccid=3", "True", "True"),
   2.151 +     ("dce-tcp-ns3-nsc-comparison", "True", "True"), 
   2.152 +     ("dce-tcp-ns3-nsc-comparison --stack=dce", "True", "True"),
   2.153 ++    ("dce-tcp-ns3-nsc-comparison --bulk=1", "True", "True"), 
   2.154 ++    ("dce-tcp-ns3-nsc-comparison --stack=dce --bulk=1", "True", "True"),
   2.155 ++    ("dce-tcp-ns3-nsc-comparison --stack=dce-dccp", "True", "True"),
   2.156 ++    ("dce-tcp-ns3-nsc-comparison --stack=dce-dccp --bulk=1", "True", "True"),
   2.157 +     ("dce-ping-mt1 --kernel=1", "True", "True"),
   2.158 +     ("dce-mt2 --kernel=1", "True", "True"),
   2.159 +     ("dce-mt3 --kernel=1", "True", "True"),
   2.160 +diff --git a/model/linux/linux-socket-impl.cc b/model/linux/linux-socket-impl.cc
   2.161 +--- a/model/linux/linux-socket-impl.cc
   2.162 ++++ b/model/linux/linux-socket-impl.cc
   2.163 +@@ -138,11 +138,11 @@
   2.164 +   return tid;
   2.165 + }
   2.166 + 
   2.167 +-bool m_conn_inprogress = false;
   2.168 + LinuxSocketImpl::LinuxSocketImpl ()
   2.169 + {
   2.170 +   NS_LOG_FUNCTION_NOARGS ();
   2.171 +   m_listening = false;
   2.172 ++  m_conn_inprogress = false;
   2.173 +   m_pid = -1;
   2.174 +   SetNs3ToPosixConverter (MakeCallback (&LinuxSocketImpl::Ns3AddressToPosixAddress, this));
   2.175 +   SetPosixToNs3Converter (MakeCallback (&LinuxSocketImpl::PosixAddressToNs3Address, this));
   2.176 +@@ -197,7 +197,27 @@
   2.177 + enum Socket::SocketType
   2.178 + LinuxSocketImpl::GetSocketType (void) const
   2.179 + {
   2.180 +-  return NS3_SOCK_DGRAM;
   2.181 ++  switch (m_socktype)
   2.182 ++    {
   2.183 ++    case SOCK_STREAM:
   2.184 ++    case SOCK_DCCP:
   2.185 ++      {
   2.186 ++        return NS3_SOCK_STREAM;
   2.187 ++        break;
   2.188 ++      }
   2.189 ++    case SOCK_DGRAM:
   2.190 ++      {
   2.191 ++        return NS3_SOCK_DGRAM;
   2.192 ++        break;
   2.193 ++      }
   2.194 ++    case SOCK_RAW:
   2.195 ++      {
   2.196 ++        return NS3_SOCK_RAW;
   2.197 ++        break;
   2.198 ++      }
   2.199 ++    default:
   2.200 ++        break;
   2.201 ++    }
   2.202 + }
   2.203 + 
   2.204 + uint16_t
   2.205 +@@ -514,7 +534,7 @@
   2.206 +       LeaveFakeTask (pid);
   2.207 + 
   2.208 +       // Notify the data
   2.209 +-      mask &= (POLLIN | POLLERR | POLLHUP | POLLRDHUP);
   2.210 ++      mask &= (POLLIN | POLLOUT | POLLERR | POLLHUP | POLLRDHUP);
   2.211 +       if (mask)
   2.212 +         {
   2.213 +           Ptr<LinuxSocketFdFactory> factory = 0;
   2.214 +@@ -577,14 +597,27 @@
   2.215 +                   Current ()->process->manager->Wait ();
   2.216 +                 }
   2.217 + 
   2.218 +-              NS_LOG_INFO ("notify recv");
   2.219 +-              NotifyDataRecv ();
   2.220 ++              else if (mask & POLLIN || mask & POLLERR)
   2.221 ++                {
   2.222 ++                  NS_LOG_INFO ("notify recv");
   2.223 ++                  NotifyDataRecv ();
   2.224 ++                }
   2.225 ++              else if (mask & POLLOUT)
   2.226 ++                {
   2.227 ++                  Simulator::ScheduleWithContext (m_node->GetId (), Seconds (0.0),
   2.228 ++                                                  MakeEvent (&LinuxSocketImpl::NotifySend, this, 0));
   2.229 ++                  NS_LOG_INFO ("wait send for next poll event");
   2.230 ++                  table->Wait (Seconds (0));
   2.231 ++                  NS_LOG_INFO ("awaken");
   2.232 ++                }
   2.233 +             }
   2.234 +         }
   2.235 +       // if not masked
   2.236 +       else
   2.237 +         {
   2.238 ++          NS_LOG_INFO ("wait for next poll event");
   2.239 +           table->Wait (Seconds (0));
   2.240 ++          NS_LOG_INFO ("awaken");
   2.241 +         }
   2.242 + 
   2.243 +       // next loop
   2.244 +diff --git a/model/linux/linux-socket-impl.h b/model/linux/linux-socket-impl.h
   2.245 +--- a/model/linux/linux-socket-impl.h
   2.246 ++++ b/model/linux/linux-socket-impl.h
   2.247 +@@ -109,6 +109,7 @@
   2.248 +   uint16_t m_socktype;
   2.249 +   uint16_t m_protocol;
   2.250 +   bool m_listening;
   2.251 ++  bool m_conn_inprogress;
   2.252 +   uint16_t m_pid;
   2.253 +   EventId m_poll;
   2.254 + 
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/dce-debug.patch	Thu Jun 20 09:56:26 2013 +0900
     3.3 @@ -0,0 +1,11 @@
     3.4 +diff --git a/model/dce-debug.cc b/model/dce-debug.cc
     3.5 +--- a/model/dce-debug.cc
     3.6 ++++ b/model/dce-debug.cc
     3.7 +@@ -27,7 +27,6 @@
     3.8 + uint32_t dce_debug_nodeid (void)
     3.9 + {
    3.10 +   NS_LOG_FUNCTION (Current () << UtilsGetNodeId ());
    3.11 +-  NS_ASSERT (Current () != 0);
    3.12 +   return UtilsGetNodeId ();
    3.13 + }
    3.14 + const char * dce_debug_processname (void)
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/dce-sctp.patch	Thu Jun 20 09:56:26 2013 +0900
     4.3 @@ -0,0 +1,455 @@
     4.4 +diff -r 4f91d96592e9 -r 8bc8c14ee22c example/dce-sctp-simple.cc
     4.5 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.6 ++++ b/example/dce-sctp-simple.cc	Fri Oct 12 10:45:01 2012 +0900
     4.7 +@@ -0,0 +1,80 @@
     4.8 ++#include "ns3/core-module.h"
     4.9 ++#include "ns3/network-module.h"
    4.10 ++#include "ns3/dce-module.h"
    4.11 ++#include "ns3/point-to-point-module.h"
    4.12 ++#include "ns3/internet-module.h"
    4.13 ++#include <fstream>
    4.14 ++
    4.15 ++using namespace ns3;
    4.16 ++
    4.17 ++static void RunIp (Ptr<Node> node, Time at, std::string str)
    4.18 ++{
    4.19 ++  DceApplicationHelper process;
    4.20 ++  ApplicationContainer apps;
    4.21 ++  process.SetBinary ("ip");
    4.22 ++  process.SetStackSize (1<<16);
    4.23 ++  process.ResetArguments();
    4.24 ++  process.ParseArguments(str.c_str ());
    4.25 ++  apps = process.Install (node);
    4.26 ++  apps.Start (at);
    4.27 ++}
    4.28 ++
    4.29 ++int main (int argc, char *argv[])
    4.30 ++{
    4.31 ++  CommandLine cmd;
    4.32 ++  cmd.Parse (argc, argv);
    4.33 ++
    4.34 ++  NodeContainer nodes;
    4.35 ++  nodes.Create (2);
    4.36 ++
    4.37 ++  NetDeviceContainer devices;
    4.38 ++
    4.39 ++  PointToPointHelper p2p;
    4.40 ++  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Gbps"));
    4.41 ++  p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
    4.42 ++  devices = p2p.Install (nodes);
    4.43 ++  p2p.EnablePcapAll ("dce-sctp-simple");
    4.44 ++
    4.45 ++  DceManagerHelper processManager;
    4.46 ++  processManager.SetTaskManagerAttribute ("FiberManagerType",
    4.47 ++                                          StringValue ("UcontextFiberManager"));
    4.48 ++  // processManager.SetLoader ("ns3::DlmLoaderFactory");
    4.49 ++  processManager.SetNetworkStack("ns3::LinuxSocketFdFactory", "Library", StringValue ("liblinux.so"));
    4.50 ++  LinuxStackHelper stack;
    4.51 ++  stack.Install (nodes);
    4.52 ++
    4.53 ++  Ipv4AddressHelper address;
    4.54 ++  address.SetBase ("10.0.0.0", "255.255.255.0");
    4.55 ++  Ipv4InterfaceContainer interfaces = address.Assign (devices);
    4.56 ++
    4.57 ++  processManager.Install (nodes);
    4.58 ++
    4.59 ++
    4.60 ++  for (int n=0; n < 2; n++)
    4.61 ++    {
    4.62 ++      RunIp (nodes.Get (n), Seconds (0.2), "link show");
    4.63 ++      RunIp (nodes.Get (n), Seconds (0.3), "route show table all");
    4.64 ++      RunIp (nodes.Get (n), Seconds (0.4), "addr list");
    4.65 ++    }
    4.66 ++
    4.67 ++  DceApplicationHelper process;
    4.68 ++  ApplicationContainer apps;
    4.69 ++
    4.70 ++  process.SetBinary ("sctp-server");
    4.71 ++  process.ResetArguments ();
    4.72 ++  process.SetStackSize (1<<16);
    4.73 ++  apps = process.Install (nodes.Get (0));
    4.74 ++  apps.Start (Seconds (1.0));
    4.75 ++
    4.76 ++  process.SetBinary ("sctp-client");
    4.77 ++  process.ResetArguments ();
    4.78 ++  process.ParseArguments ("10.0.0.1");
    4.79 ++  apps = process.Install (nodes.Get (1));
    4.80 ++  apps.Start (Seconds (1.5));
    4.81 ++
    4.82 ++  Simulator::Stop (Seconds (2000000.0));
    4.83 ++  Simulator::Run ();
    4.84 ++  Simulator::Destroy ();
    4.85 ++
    4.86 ++  return 0;
    4.87 ++}
    4.88 +diff -r 4f91d96592e9 -r 8bc8c14ee22c example/sctp-client.cc
    4.89 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    4.90 ++++ b/example/sctp-client.cc	Fri Oct 12 10:45:01 2012 +0900
    4.91 +@@ -0,0 +1,89 @@
    4.92 ++// 
    4.93 ++// libstcp1-dev is needed
    4.94 ++// 
    4.95 ++#include <stdio.h>
    4.96 ++#include <stdlib.h>
    4.97 ++#include <string.h>        /* for memset */
    4.98 ++#include <unistd.h>        /* for memset */
    4.99 ++#include <sys/socket.h>
   4.100 ++#include <sys/types.h>
   4.101 ++#include <arpa/inet.h>
   4.102 ++#include <netinet/in.h>
   4.103 ++#include <netinet/sctp.h>
   4.104 ++
   4.105 ++int
   4.106 ++main (int argc, char **argv)
   4.107 ++{
   4.108 ++  int connect_sock, stat, port, slen, i, flags;
   4.109 ++  struct sctp_initmsg initmsg;
   4.110 ++  struct sockaddr_in server_addr;
   4.111 ++  struct sctp_event_subscribe s_events;
   4.112 ++  struct sctp_status s_status;
   4.113 ++  struct sctp_sndrcvinfo s_sndrcvinfo;
   4.114 ++  char buffer[1024];
   4.115 ++
   4.116 ++  port = 3007;
   4.117 ++
   4.118 ++  connect_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
   4.119 ++  memset (&initmsg, 0, sizeof (initmsg));
   4.120 ++  initmsg.sinit_num_ostreams = 3;          // Number of Output Stream
   4.121 ++  initmsg.sinit_max_instreams = 3;      // Number of Input Stream
   4.122 ++  initmsg.sinit_max_attempts = 4;
   4.123 ++  stat = setsockopt (connect_sock, IPPROTO_SCTP, SCTP_INITMSG,
   4.124 ++                     &initmsg, sizeof (initmsg) );
   4.125 ++  if (stat < 0)
   4.126 ++    {
   4.127 ++      perror ("setsockopt error");
   4.128 ++      exit (-1);
   4.129 ++    }
   4.130 ++
   4.131 ++  memset (&server_addr, 0, sizeof (server_addr));
   4.132 ++  server_addr.sin_family = AF_INET;
   4.133 ++  server_addr.sin_port = htons (port);
   4.134 ++  server_addr.sin_addr.s_addr = inet_addr (argv[1]);
   4.135 ++
   4.136 ++  stat = connect (connect_sock, (struct sockaddr *)&server_addr, 
   4.137 ++                  sizeof (server_addr) );
   4.138 ++  if (stat < 0)
   4.139 ++    {
   4.140 ++      perror ("connect error");
   4.141 ++      exit (-1);
   4.142 ++    }
   4.143 ++
   4.144 ++  memset (&s_events, 0, sizeof (s_events));
   4.145 ++  s_events.sctp_data_io_event = 1;
   4.146 ++  stat = setsockopt (connect_sock, SOL_SCTP, SCTP_EVENTS,
   4.147 ++                     (const void *)&s_events, sizeof (s_events));
   4.148 ++  if (stat < 0)
   4.149 ++    {
   4.150 ++      perror ("event error");
   4.151 ++      exit (-1);
   4.152 ++    }
   4.153 ++
   4.154 ++  slen = sizeof (s_status);
   4.155 ++  stat = getsockopt (connect_sock, SOL_SCTP, SCTP_STATUS,
   4.156 ++                     (void *)&s_status, (socklen_t *)&slen );
   4.157 ++
   4.158 ++  printf ("assoc id  = %d\n", s_status.sstat_assoc_id );
   4.159 ++  printf ("state     = %d\n", s_status.sstat_state );
   4.160 ++  printf ("instrms   = %d\n", s_status.sstat_instrms );
   4.161 ++  printf ("outstrms  = %d\n", s_status.sstat_outstrms );
   4.162 ++
   4.163 ++
   4.164 ++  for (i = 0 ; i < 2 ; i++)
   4.165 ++    {
   4.166 ++      stat = sctp_recvmsg (connect_sock, (void *)buffer, sizeof (buffer),
   4.167 ++                           (struct sockaddr *)NULL, 0, &s_sndrcvinfo, &flags );
   4.168 ++      printf ("stat = %d\n", stat);
   4.169 ++      if (stat > 0)
   4.170 ++        {
   4.171 ++          buffer[stat] = 0;
   4.172 ++          printf ("(Stream %d) %s\n", s_sndrcvinfo.sinfo_stream, buffer);
   4.173 ++        }
   4.174 ++    }
   4.175 ++  /* Close our socket and exit */
   4.176 ++  close (connect_sock);
   4.177 ++  return 0;
   4.178 ++}
   4.179 ++
   4.180 ++
   4.181 +diff -r 4f91d96592e9 -r 8bc8c14ee22c example/sctp-client.cc~
   4.182 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   4.183 ++++ b/example/sctp-client.cc~	Fri Oct 12 10:45:01 2012 +0900
   4.184 +@@ -0,0 +1,87 @@
   4.185 ++#include <stdio.h>
   4.186 ++#include <stdlib.h>
   4.187 ++#include <string.h>        /* for memset */
   4.188 ++#include <unistd.h>        /* for memset */
   4.189 ++#include <sys/socket.h>
   4.190 ++#include <sys/types.h>
   4.191 ++#include <arpa/inet.h>
   4.192 ++#include <netinet/in.h>
   4.193 ++#include <netinet/sctp.h>
   4.194 ++
   4.195 ++void my_exit (char *str)
   4.196 ++{
   4.197 ++  perror (str);
   4.198 ++  exit (1);
   4.199 ++}
   4.200 ++
   4.201 ++int main (int argc, char **argv)
   4.202 ++{
   4.203 ++  int connect_sock, stat, port, slen, i, flags;
   4.204 ++  struct sctp_initmsg initmsg;
   4.205 ++  struct sockaddr_in server_addr;
   4.206 ++  struct sctp_event_subscribe s_events;
   4.207 ++  struct sctp_status s_status;
   4.208 ++  struct sctp_sndrcvinfo s_sndrcvinfo;
   4.209 ++  char buffer[1024];
   4.210 ++
   4.211 ++  port = 3007;
   4.212 ++
   4.213 ++  connect_sock = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
   4.214 ++  memset (&initmsg, 0, sizeof(initmsg));
   4.215 ++  initmsg.sinit_num_ostreams = 3;          // Number of Output Stream
   4.216 ++  initmsg.sinit_max_instreams = 3;      // Number of Input Stream
   4.217 ++  initmsg.sinit_max_attempts = 4;
   4.218 ++  stat = setsockopt (connect_sock, IPPROTO_SCTP, SCTP_INITMSG,
   4.219 ++                     &initmsg, sizeof(initmsg) );
   4.220 ++  if (stat < 0)
   4.221 ++    {
   4.222 ++      my_exit ("setsockopt error");
   4.223 ++    }
   4.224 ++
   4.225 ++  memset (&server_addr, 0, sizeof(server_addr));
   4.226 ++  server_addr.sin_family = AF_INET;
   4.227 ++  server_addr.sin_port = htons (port);
   4.228 ++  server_addr.sin_addr.s_addr = inet_addr ("127.0.0.1");
   4.229 ++
   4.230 ++  stat = connect (connect_sock, (struct sockaddr *)&server_addr, sizeof(server_addr) );
   4.231 ++  if (stat < 0)
   4.232 ++    {
   4.233 ++      my_exit ("connect error");
   4.234 ++    }
   4.235 ++
   4.236 ++  memset (&s_events, 0, sizeof(s_events));
   4.237 ++  s_events.sctp_data_io_event = 1;
   4.238 ++  stat = setsockopt (connect_sock, SOL_SCTP, SCTP_EVENTS,
   4.239 ++                     (const void *)&s_events, sizeof(s_events));
   4.240 ++  if (stat < 0)
   4.241 ++    {
   4.242 ++      my_exit ("event error");
   4.243 ++    }
   4.244 ++
   4.245 ++  slen = sizeof(s_status);
   4.246 ++  stat = getsockopt (connect_sock, SOL_SCTP, SCTP_STATUS,
   4.247 ++                     (void *)&s_status, (socklen_t *)&slen );
   4.248 ++
   4.249 ++  printf ("assoc id  = %d\n", s_status.sstat_assoc_id );
   4.250 ++  printf ("state     = %d\n", s_status.sstat_state );
   4.251 ++  printf ("instrms   = %d\n", s_status.sstat_instrms );
   4.252 ++  printf ("outstrms  = %d\n", s_status.sstat_outstrms );
   4.253 ++
   4.254 ++
   4.255 ++  for (i = 0 ; i < 2 ; i++)
   4.256 ++    {
   4.257 ++      stat = sctp_recvmsg (connect_sock, (void *)buffer, sizeof(buffer),
   4.258 ++                           (struct sockaddr *)NULL, 0, &s_sndrcvinfo, &flags );
   4.259 ++      printf ("stat = %d\n", stat);
   4.260 ++      if (stat > 0)
   4.261 ++        {
   4.262 ++          buffer[stat] = 0;
   4.263 ++          printf ("(Stream %d) %s\n", s_sndrcvinfo.sinfo_stream, buffer);
   4.264 ++        }
   4.265 ++    }
   4.266 ++  /* Close our socket and exit */
   4.267 ++  close (connect_sock);
   4.268 ++  return 0;
   4.269 ++}
   4.270 ++
   4.271 ++
   4.272 +diff -r 4f91d96592e9 -r 8bc8c14ee22c example/sctp-server.cc
   4.273 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   4.274 ++++ b/example/sctp-server.cc	Fri Oct 12 10:45:01 2012 +0900
   4.275 +@@ -0,0 +1,78 @@
   4.276 ++// 
   4.277 ++// libstcp1-dev is needed
   4.278 ++// 
   4.279 ++#include <stdio.h>
   4.280 ++#include <stdlib.h>
   4.281 ++#include <string.h>
   4.282 ++#include <unistd.h>
   4.283 ++#include <sys/socket.h>
   4.284 ++#include <sys/types.h>
   4.285 ++#include <arpa/inet.h>
   4.286 ++#include <netinet/in.h>
   4.287 ++#include <netinet/sctp.h>
   4.288 ++
   4.289 ++void
   4.290 ++echo_main (int sock)
   4.291 ++{
   4.292 ++  int stat;
   4.293 ++  char buffer[1024];
   4.294 ++
   4.295 ++  printf ("sock: %d\n", sock);
   4.296 ++
   4.297 ++  // Stream No.0
   4.298 ++  sprintf (buffer, "This is a test of stream 0");
   4.299 ++  stat = sctp_sendmsg (sock, buffer, (size_t)strlen (buffer),
   4.300 ++                       NULL, 0, 0, 0, 0, 0, 0);
   4.301 ++
   4.302 ++  // Stream No.1
   4.303 ++  sprintf (buffer, "This is a test of stream 1");
   4.304 ++  stat = sctp_sendmsg (sock, buffer, (size_t)strlen (buffer),
   4.305 ++                       NULL, 0, 0, 0, 1, 0, 0);
   4.306 ++}
   4.307 ++
   4.308 ++int
   4.309 ++main (int argc, char **argv)
   4.310 ++{
   4.311 ++  int sock_listen, sock_server, stat;
   4.312 ++  struct sockaddr_in server_addr;
   4.313 ++  struct sctp_initmsg s_initmsg;
   4.314 ++  int echo_port;
   4.315 ++
   4.316 ++  echo_port = 3007;
   4.317 ++
   4.318 ++  sock_listen = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
   4.319 ++
   4.320 ++  memset (&server_addr, 0, sizeof(server_addr));
   4.321 ++  server_addr.sin_family = AF_INET;
   4.322 ++  server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
   4.323 ++  server_addr.sin_port = htons (echo_port);
   4.324 ++
   4.325 ++  stat = bind (sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
   4.326 ++
   4.327 ++  // SCTP parameter
   4.328 ++  memset (&s_initmsg, 0, sizeof(s_initmsg));
   4.329 ++  s_initmsg.sinit_num_ostreams = 5;
   4.330 ++  s_initmsg.sinit_max_instreams = 5;
   4.331 ++  s_initmsg.sinit_max_attempts = 5;
   4.332 ++
   4.333 ++  stat = setsockopt (sock_listen, IPPROTO_SCTP, SCTP_INITMSG,
   4.334 ++                     &s_initmsg, sizeof(s_initmsg));
   4.335 ++  if (stat < 0)
   4.336 ++    {
   4.337 ++      perror ("Socket Option error");
   4.338 ++      exit (-1);
   4.339 ++    }
   4.340 ++
   4.341 ++  listen (sock_listen, 5);
   4.342 ++  while (1)
   4.343 ++    {
   4.344 ++      printf ("SCTP server accepting\n");
   4.345 ++      sock_server = accept (sock_listen, (struct sockaddr *)NULL, (socklen_t *)NULL);
   4.346 ++
   4.347 ++      echo_main (sock_server);
   4.348 ++    }
   4.349 ++
   4.350 ++  close (sock_listen);
   4.351 ++  return 0;
   4.352 ++}
   4.353 ++
   4.354 +diff -r 4f91d96592e9 -r 8bc8c14ee22c example/sctp-server.cc~
   4.355 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   4.356 ++++ b/example/sctp-server.cc~	Fri Oct 12 10:45:01 2012 +0900
   4.357 +@@ -0,0 +1,78 @@
   4.358 ++#include <stdio.h>
   4.359 ++#include <stdlib.h>
   4.360 ++#include <string.h>
   4.361 ++#include <sys/socket.h>
   4.362 ++#include <sys/types.h>
   4.363 ++#include <arpa/inet.h>
   4.364 ++#include <netinet/in.h>
   4.365 ++#include <netinet/sctp.h>
   4.366 ++
   4.367 ++void
   4.368 ++echo_main (int sock)
   4.369 ++{
   4.370 ++  int stat;
   4.371 ++  char buffer[1024];
   4.372 ++
   4.373 ++  printf ("sock: %d\n", sock);
   4.374 ++
   4.375 ++  // Stream No.0
   4.376 ++  sprintf (buffer, "This is a test of stream 0");
   4.377 ++  stat = sctp_sendmsg (sock, buffer, (size_t)strlen (buffer),
   4.378 ++                       NULL, 0, 0, 0, 0, 0, 0);
   4.379 ++
   4.380 ++  // Stream No.1
   4.381 ++  sprintf (buffer, "This is a test of stream 1");
   4.382 ++  stat = sctp_sendmsg (sock, buffer, (size_t)strlen (buffer),
   4.383 ++                       NULL, 0, 0, 0, 1, 0, 0);
   4.384 ++}
   4.385 ++
   4.386 ++int
   4.387 ++main (int argc, char **argv)
   4.388 ++{
   4.389 ++  int sock_listen, sock_server, stat;
   4.390 ++  struct sockaddr_in server_addr;
   4.391 ++  struct sctp_initmsg s_initmsg;
   4.392 ++  int echo_port;
   4.393 ++
   4.394 ++  echo_port = 3007;
   4.395 ++
   4.396 ++  sock_listen = socket (AF_INET, SOCK_STREAM, IPPROTO_SCTP);
   4.397 ++
   4.398 ++  memset (&server_addr, 0, sizeof(server_addr));
   4.399 ++  server_addr.sin_family = AF_INET;
   4.400 ++  server_addr.sin_addr.s_addr = htonl (INADDR_ANY);
   4.401 ++  server_addr.sin_port = htons (echo_port);
   4.402 ++
   4.403 ++  // bind() によるソケットとアドレスの関係づけ
   4.404 ++  stat = bind (sock_listen, (struct sockaddr *)&server_addr, sizeof(server_addr));
   4.405 ++
   4.406 ++  // SCTP のパラメータ
   4.407 ++  memset (&s_initmsg, 0, sizeof(s_initmsg)); // 構造体変数のクリア
   4.408 ++  s_initmsg.sinit_num_ostreams = 5;  // 送信ストリーム数
   4.409 ++  s_initmsg.sinit_max_instreams = 5; // 受信可能ストリーム数の最大値
   4.410 ++  s_initmsg.sinit_max_attempts = 5;  // INIT 再送の最大数
   4.411 ++
   4.412 ++  // setsockopt() によるパラメータの設定
   4.413 ++  stat = setsockopt (sock_listen, IPPROTO_SCTP, SCTP_INITMSG,
   4.414 ++                     &s_initmsg, sizeof(s_initmsg));
   4.415 ++  if (stat < 0)
   4.416 ++    {
   4.417 ++      my_exit ("Socket Option error");
   4.418 ++    }
   4.419 ++
   4.420 ++  // listen() による接続要求待機
   4.421 ++  listen (sock_listen, 5);
   4.422 ++  while (1)
   4.423 ++    {
   4.424 ++      printf ("SCTP server accepting\n");
   4.425 ++      // accept() による接続要求の受付
   4.426 ++      sock_server = accept (sock_listen, (struct sockaddr *)NULL, (int *)NULL);
   4.427 ++
   4.428 ++      // クライアント処理を行う関数の呼び出し
   4.429 ++      echo_main (sock_server);
   4.430 ++    }
   4.431 ++
   4.432 ++  close (sock_listen);
   4.433 ++  return 0;
   4.434 ++}
   4.435 ++
   4.436 +diff -r 4f91d96592e9 -r 8bc8c14ee22c wscript
   4.437 +--- a/wscript	Thu Oct 11 12:14:09 2012 +0900
   4.438 ++++ b/wscript	Fri Oct 12 10:45:01 2012 +0900
   4.439 +@@ -232,6 +232,8 @@
   4.440 +                     ['unix-client', []],
   4.441 +                     ['udp-echo-server', []],
   4.442 +                     ['udp-echo-client', []],
   4.443 ++                    ['sctp-server', ['sctp']],
   4.444 ++                    ['sctp-client', ['sctp']],
   4.445 + #                    ['little-cout', []],
   4.446 +                     ]
   4.447 +     for name,lib in dce_examples:
   4.448 +@@ -316,6 +318,10 @@
   4.449 +                        target='bin/dce-linux',
   4.450 +                        source=['example/dce-linux.cc'])
   4.451 + 
   4.452 ++    module.add_example(needed = ['core', 'network', 'dce', 'point-to-point' ],
   4.453 ++                       target='bin/dce-sctp-simple',
   4.454 ++                       source=['example/dce-sctp-simple.cc'])
   4.455 ++
   4.456 + # Add a script to build system 
   4.457 + def build_a_script(bld, name, needed = [], **kw):
   4.458 +     external = [i for i in needed if not i == name]
     5.1 --- a/dce_test_improve.patch	Mon Aug 06 20:45:50 2012 +0900
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,104 +0,0 @@
     5.4 -improve test-case to cover pthread/ucontext, dlm/cooja, with vdl/no-vdl
     5.5 -
     5.6 -diff -r 9c972df8a320 test/dce-manager-test.cc
     5.7 ---- a/test/dce-manager-test.cc	Mon Jul 09 17:35:31 2012 +0200
     5.8 -+++ b/test/dce-manager-test.cc	Tue Jul 10 00:56:45 2012 +0900
     5.9 -@@ -25,7 +25,8 @@
    5.10 - class DceManagerTestCase : public TestCase
    5.11 - {
    5.12 - public:
    5.13 --  DceManagerTestCase (std::string filename, Time maxDuration, std::string stdinFilename, bool useNet, bool useK);
    5.14 -+  DceManagerTestCase (std::string filename, Time maxDuration, std::string stdinFilename, 
    5.15 -+                      bool useNet, bool useK);
    5.16 - private:
    5.17 -   virtual void DoRun (void);
    5.18 -   static void Finished (int *pstatus, uint16_t pid, int status);
    5.19 -@@ -37,9 +38,16 @@
    5.20 -   bool m_useNet;
    5.21 - };
    5.22 - 
    5.23 --DceManagerTestCase::DceManagerTestCase (std::string filename, Time maxDuration, std::string stdin, bool useNet, bool useK)
    5.24 --  : TestCase ("Check that process \"" + filename + "\" completes correctly."),
    5.25 --    m_filename (filename), m_stdinFilename ( stdin), m_maxDuration ( maxDuration ), m_useKernel (useK), m_useNet (useNet)
    5.26 -+DceManagerTestCase::DceManagerTestCase (std::string filename, Time maxDuration, 
    5.27 -+                                        std::string stdin, bool useNet, bool useK)
    5.28 -+  : TestCase ("Check that process \"" + filename +
    5.29 -+              (useK ? " (kernel" : " (ns3)") + 
    5.30 -+              "\" completes correctly."),
    5.31 -+    m_filename (filename), 
    5.32 -+    m_stdinFilename (stdin),
    5.33 -+    m_maxDuration (maxDuration),
    5.34 -+    m_useKernel (useK),
    5.35 -+    m_useNet (useNet)
    5.36 - {
    5.37 - //  mtrace ();
    5.38 - }
    5.39 -@@ -83,7 +91,6 @@
    5.40 -           apps = dce.Install (nodes.Get (0));
    5.41 -           apps.Start (Seconds (3.0));
    5.42 - 
    5.43 --          //dceManager.SetTaskManagerAttribute( "FiberManagerType", StringValue ( "UcontextFiberManager" ) );
    5.44 -         } else
    5.45 -         {
    5.46 -           dceManager.Install (nodes);
    5.47 -@@ -164,7 +171,7 @@
    5.48 -       {  "test-random", 0, "", false },
    5.49 -       {  "test-local-socket", 0, "", false },
    5.50 -       {  "test-poll", 3200, "", true },
    5.51 --      //      {  "test-tcp-socket", 320, "", true },
    5.52 -+      {  "test-tcp-socket", 320, "", true },
    5.53 -       {  "test-exec", 0, "" , false},
    5.54 -       /* {  "test-raw-socket", 320, "", true },*/
    5.55 -       {  "test-iperf", 0, "" , false},
    5.56 -@@ -193,7 +200,10 @@
    5.57 - 
    5.58 -   for (unsigned int i = 0; i < sizeof(tests)/sizeof(testPair); i++)
    5.59 -     {
    5.60 --      AddTestCase (new DceManagerTestCase (tests[i].name,  Seconds (tests[i].duration), tests[i].stdinfile, tests[i].useNet, useKernel () ) );
    5.61 -+      AddTestCase (new DceManagerTestCase (tests[i].name,  Seconds (tests[i].duration), 
    5.62 -+                                           tests[i].stdinfile, 
    5.63 -+                                           tests[i].useNet, 
    5.64 -+                                           useKernel ()));
    5.65 -     }
    5.66 - }
    5.67 - 
    5.68 -diff -r 9c972df8a320 utils/test.sh
    5.69 ---- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    5.70 -+++ b/utils/test.sh	Tue Jul 10 00:56:45 2012 +0900
    5.71 -@@ -0,0 +1,20 @@
    5.72 -+#!/bin/sh
    5.73 -+
    5.74 -+. ./utils/setenv.sh
    5.75 -+#VERBOSE=""
    5.76 -+
    5.77 -+echo -n "Cooja (non-vdl) + Pthread:  "
    5.78 -+NS_ATTRIBUTE_DEFAULT='ns3::TaskManager::FiberManagerType=PthreadFiberManager' ./build/bin/ns3test-dce $VERBOSE
    5.79 -+echo -n "Cooja (non-vdl) + Ucontext: "
    5.80 -+NS_ATTRIBUTE_DEFAULT='ns3::TaskManager::FiberManagerType=UcontextFiberManager' ./build/bin/ns3test-dce $VERBOSE
    5.81 -+
    5.82 -+echo -n "Cooja (vdl) + Pthread:      "
    5.83 -+NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::CoojaLoaderFactory[];ns3::TaskManager::FiberManagerType=PthreadFiberManager' ./build/bin/ns3test-dce-vdl $VERBOSE
    5.84 -+
    5.85 -+echo -n "Cooja (vdl) + Ucontext:     "
    5.86 -+NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::CoojaLoaderFactory[];ns3::TaskManager::FiberManagerType=UcontextFiberManager' ./build/bin/ns3test-dce-vdl $VERBOSE
    5.87 -+
    5.88 -+echo -n "Dlm (vdl) + Pthread:        "
    5.89 -+NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::DlmLoaderFactory[];ns3::TaskManager::FiberManagerType=PthreadFiberManager' ./build/bin/ns3test-dce-vdl $VERBOSE
    5.90 -+echo -n "Dlm (vdl) + Ucontext:       "
    5.91 -+NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::DlmLoaderFactory[];ns3::TaskManager::FiberManagerType=UcontextFiberManager' ./build/bin/ns3test-dce-vdl $VERBOSE
    5.92 -diff -r 9c972df8a320 wscript
    5.93 ---- a/wscript	Mon Jul 09 17:35:31 2012 +0200
    5.94 -+++ b/wscript	Tue Jul 10 00:56:45 2012 +0900
    5.95 -@@ -136,8 +136,12 @@
    5.96 - def build_dce_tests(module, kern):
    5.97 -     if kern:
    5.98 -         module.add_runner_test(needed=['core', 'dce', 'internet'],  source=['test/dce-manager-test.cc', 'test/with-kernel.cc'])
    5.99 -+        module.add_runner_test(needed=['core', 'dce', 'internet'],  source=['test/dce-manager-test.cc', 'test/with-kernel.cc'],
   5.100 -+                               linkflags = ['-Wl,--dynamic-linker=' + os.path.abspath ('../build/lib/ldso')], name='vdl')
   5.101 -     else:
   5.102 -         module.add_runner_test(needed=['core', 'dce', 'internet'], source=['test/dce-manager-test.cc','test/without-kernel.cc'])
   5.103 -+        module.add_runner_test(needed=['core', 'dce', 'internet'], source=['test/dce-manager-test.cc','test/without-kernel.cc'],
   5.104 -+                               linkflags = ['-Wl,--dynamic-linker=' + os.path.abspath ('../build/lib/ldso')], name='vdl')
   5.105 -     	    
   5.106 -     module.add_test(features='cxx cxxshlib', source=['test/test-macros.cc'], 
   5.107 -                     target='lib/test', linkflags=['-Wl,-soname=libtest.so'])
     6.1 --- a/fedora8-nontimerfd.patch	Mon Aug 06 20:45:50 2012 +0900
     6.2 +++ b/fedora8-nontimerfd.patch	Thu Jun 20 09:56:26 2013 +0900
     6.3 @@ -1,8 +1,8 @@
     6.4  support Fedora8, timerfd check in configure, macro improvements, fix the issue of scandir imcompatibility
     6.5  
     6.6 -diff -r 4c90fdff71a0 model/dce-dirent.cc
     6.7 ---- a/model/dce-dirent.cc	Mon Jul 16 13:56:16 2012 +0200
     6.8 -+++ b/model/dce-dirent.cc	Wed Jul 18 14:28:29 2012 +0900
     6.9 +diff -r ce273c5b2ef9 model/dce-dirent.cc
    6.10 +--- a/model/dce-dirent.cc	Thu Sep 20 10:12:35 2012 +0900
    6.11 ++++ b/model/dce-dirent.cc	Thu Sep 20 10:13:19 2012 +0900
    6.12  @@ -236,9 +236,16 @@
    6.13     rewinddir (dirp);
    6.14     ds->fd = saveFd;
    6.15 @@ -20,9 +20,9 @@
    6.16   {
    6.17     NS_LOG_FUNCTION (Current () << UtilsGetNodeId () );
    6.18     NS_ASSERT (Current () != 0);
    6.19 -diff -r 4c90fdff71a0 model/dce-dirent.h
    6.20 ---- a/model/dce-dirent.h	Mon Jul 16 13:56:16 2012 +0200
    6.21 -+++ b/model/dce-dirent.h	Wed Jul 18 14:28:29 2012 +0900
    6.22 +diff -r ce273c5b2ef9 model/dce-dirent.h
    6.23 +--- a/model/dce-dirent.h	Thu Sep 20 10:12:35 2012 +0900
    6.24 ++++ b/model/dce-dirent.h	Thu Sep 20 10:13:19 2012 +0900
    6.25  @@ -35,9 +35,24 @@
    6.26   int dce_closedir (DIR *dirp);
    6.27   int dce_dirfd (DIR *dirp);
    6.28 @@ -48,9 +48,9 @@
    6.29   
    6.30   #ifdef __cplusplus
    6.31   }
    6.32 -diff -r 4c90fdff71a0 model/libc-dce.cc
    6.33 ---- a/model/libc-dce.cc	Mon Jul 16 13:56:16 2012 +0200
    6.34 -+++ b/model/libc-dce.cc	Wed Jul 18 14:28:29 2012 +0900
    6.35 +diff -r ce273c5b2ef9 model/libc-dce.cc
    6.36 +--- a/model/libc-dce.cc	Thu Sep 20 10:12:35 2012 +0900
    6.37 ++++ b/model/libc-dce.cc	Thu Sep 20 10:13:19 2012 +0900
    6.38  @@ -12,7 +12,9 @@
    6.39   #include "sys/dce-mman.h"
    6.40   #include "sys/dce-stat.h"
    6.41 @@ -61,7 +61,7 @@
    6.42   #include "dce-unistd.h"
    6.43   #include "dce-netdb.h"
    6.44   #include "dce-pthread.h"
    6.45 -@@ -67,7 +69,9 @@
    6.46 +@@ -68,7 +70,9 @@
    6.47   #include <sys/ioctl.h>
    6.48   #include <sys/io.h>
    6.49   #include <sys/mman.h>
    6.50 @@ -71,7 +71,7 @@
    6.51   #include <sys/time.h>
    6.52   #include <sys/types.h>
    6.53   #include <sys/resource.h>
    6.54 -@@ -142,6 +146,7 @@
    6.55 +@@ -146,6 +150,7 @@
    6.56   #define DCE(name) (*libc)->name ## _fn = (func_t)(__typeof(&name))dce_ ## name;
    6.57   #define DCET(rtype,name) DCE(name)
    6.58   #define DCE_EXPLICIT(name,rtype,...) (*libc)->name ## _fn = dce_ ## name;
    6.59 @@ -79,9 +79,9 @@
    6.60   
    6.61   #define NATIVE(name)							\
    6.62     (*libc)->name ## _fn = (func_t)name;
    6.63 -diff -r 4c90fdff71a0 model/libc-ns3.h
    6.64 ---- a/model/libc-ns3.h	Mon Jul 16 13:56:16 2012 +0200
    6.65 -+++ b/model/libc-ns3.h	Wed Jul 18 14:28:29 2012 +0900
    6.66 +diff -r ce273c5b2ef9 model/libc-ns3.h
    6.67 +--- a/model/libc-ns3.h	Thu Sep 20 10:12:35 2012 +0900
    6.68 ++++ b/model/libc-ns3.h	Thu Sep 20 10:13:19 2012 +0900
    6.69  @@ -108,7 +108,7 @@
    6.70   NATIVE (strerror_r)
    6.71   NATIVE (strcoll)
    6.72 @@ -91,7 +91,7 @@
    6.73   NATIVE (bcopy)
    6.74   NATIVE (memcmp)
    6.75   NATIVE (memmove)
    6.76 -@@ -426,11 +426,14 @@
    6.77 +@@ -440,11 +440,14 @@
    6.78   // CTYPE.H
    6.79   NATIVE (toupper)
    6.80   NATIVE (tolower)
    6.81 @@ -106,7 +106,7 @@
    6.82   
    6.83   // NET/IF.H
    6.84   DCE (if_nametoindex)
    6.85 -@@ -541,6 +544,7 @@
    6.86 +@@ -570,6 +573,7 @@
    6.87   #undef NATIVE_WITH_ALIAS
    6.88   #undef NATIVE_WITH_ALIAS2
    6.89   #undef NATIVE_EXPLICIT
    6.90 @@ -114,9 +114,9 @@
    6.91   #undef DCE_WITH_ALIAS
    6.92   #undef DCE_WITH_ALIAS2
    6.93   
    6.94 -diff -r 4c90fdff71a0 model/libc.cc
    6.95 ---- a/model/libc.cc	Mon Jul 16 13:56:16 2012 +0200
    6.96 -+++ b/model/libc.cc	Wed Jul 18 14:28:29 2012 +0900
    6.97 +diff -r ce273c5b2ef9 model/libc.cc
    6.98 +--- a/model/libc.cc	Thu Sep 20 10:12:35 2012 +0900
    6.99 ++++ b/model/libc.cc	Thu Sep 20 10:13:19 2012 +0900
   6.100  @@ -79,6 +79,12 @@
   6.101   	GCC_BUILTIN_APPLY(internal,name)			\
   6.102   	weak_alias(internal, name);
   6.103 @@ -130,9 +130,9 @@
   6.104   
   6.105   // Note: it looks like that the stdio.h header does
   6.106   // not define putc and getc as macros if you include
   6.107 -diff -r 4c90fdff71a0 model/libc.h
   6.108 ---- a/model/libc.h	Mon Jul 16 13:56:16 2012 +0200
   6.109 -+++ b/model/libc.h	Wed Jul 18 14:28:29 2012 +0900
   6.110 +diff -r ce273c5b2ef9 model/libc.h
   6.111 +--- a/model/libc.h	Thu Sep 20 10:12:35 2012 +0900
   6.112 ++++ b/model/libc.h	Thu Sep 20 10:13:19 2012 +0900
   6.113  @@ -13,6 +13,7 @@
   6.114   #define DCET(rtype, name) DCE(name)
   6.115   
   6.116 @@ -140,11 +140,11 @@
   6.117  +#define NATIVE_EXPLICIT2(name,rtype,...) rtype (*name ## _fn)(__VA_ARGS__);
   6.118   #include "libc-ns3.h"
   6.119   
   6.120 - };
   6.121 -diff -r 4c90fdff71a0 test/dce-manager-test.cc
   6.122 ---- a/test/dce-manager-test.cc	Mon Jul 16 13:56:16 2012 +0200
   6.123 -+++ b/test/dce-manager-test.cc	Wed Jul 18 14:28:29 2012 +0900
   6.124 -@@ -156,7 +156,9 @@
   6.125 +   char* (*strpbrk_fn) (const char *s, const char *accept);
   6.126 +diff -r ce273c5b2ef9 test/dce-manager-test.cc
   6.127 +--- a/test/dce-manager-test.cc	Thu Sep 20 10:12:35 2012 +0900
   6.128 ++++ b/test/dce-manager-test.cc	Thu Sep 20 10:13:19 2012 +0900
   6.129 +@@ -163,7 +163,9 @@
   6.130         {  "test-netdb", 3600, "", true },
   6.131         {  "test-env", 0, "", false }, 
   6.132         {  "test-cond", 0, "", false}, 
   6.133 @@ -154,9 +154,9 @@
   6.134         {  "test-stdlib", 0, "", false},
   6.135         {  "test-fork", 0, "", false },
   6.136         {  "test-select", 3600, "", true },
   6.137 -diff -r 4c90fdff71a0 test/test-poll.cc
   6.138 ---- a/test/test-poll.cc	Mon Jul 16 13:56:16 2012 +0200
   6.139 -+++ b/test/test-poll.cc	Wed Jul 18 14:28:29 2012 +0900
   6.140 +diff -r ce273c5b2ef9 test/test-poll.cc
   6.141 +--- a/test/test-poll.cc	Thu Sep 20 10:12:35 2012 +0900
   6.142 ++++ b/test/test-poll.cc	Thu Sep 20 10:13:19 2012 +0900
   6.143  @@ -1,7 +1,6 @@
   6.144   #include <stdlib.h>
   6.145   #include <sys/time.h>
   6.146 @@ -165,9 +165,9 @@
   6.147   #include <unistd.h>
   6.148   #include <pthread.h>
   6.149   #include <stdio.h>
   6.150 -diff -r 4c90fdff71a0 test/test-select.cc
   6.151 ---- a/test/test-select.cc	Mon Jul 16 13:56:16 2012 +0200
   6.152 -+++ b/test/test-select.cc	Wed Jul 18 14:28:29 2012 +0900
   6.153 +diff -r ce273c5b2ef9 test/test-select.cc
   6.154 +--- a/test/test-select.cc	Thu Sep 20 10:12:35 2012 +0900
   6.155 ++++ b/test/test-select.cc	Thu Sep 20 10:13:19 2012 +0900
   6.156  @@ -2,7 +2,9 @@
   6.157   #include <sys/time.h>
   6.158   #include <sys/types.h>
   6.159 @@ -225,18 +225,18 @@
   6.160         launch (client1, server1);
   6.161         launch (client2, server2);
   6.162         launch (client3, server3);
   6.163 -diff -r 4c90fdff71a0 wscript
   6.164 ---- a/wscript	Mon Jul 16 13:56:16 2012 +0200
   6.165 -+++ b/wscript	Wed Jul 18 14:28:29 2012 +0900
   6.166 -@@ -37,6 +37,7 @@
   6.167 +diff -r ce273c5b2ef9 wscript
   6.168 +--- a/wscript	Thu Sep 20 10:12:35 2012 +0900
   6.169 ++++ b/wscript	Thu Sep 20 10:13:19 2012 +0900
   6.170 +@@ -46,6 +46,7 @@
   6.171       conf.check(header_name='sys/types.h', define_name='HAVE_SYS_TYPES_H', mandatory=False)
   6.172       conf.check(header_name='sys/stat.h', define_name='HAVE_SYS_STAT_H', mandatory=False)
   6.173       conf.check(header_name='dirent.h', define_name='HAVE_DIRENT_H', mandatory=False)
   6.174  +    conf.check(header_name='sys/timerfd.h', define_name='HAVE_SYS_TIMER_H', mandatory=False)
   6.175   
   6.176 -     conf.env.prepend_value('LINKFLAGS', '-Wl,--no-as-needed')
   6.177 -     conf.env.append_value('LINKFLAGS', '-pthread')
   6.178 -@@ -91,7 +92,9 @@
   6.179 +     if Options.options.enable_mpi:
   6.180 +          conf.env.append_value ('DEFINES', 'DCE_MPI=1')
   6.181 +@@ -104,7 +105,9 @@
   6.182   
   6.183       if Options.options.kernel_stack is not None and os.path.isdir(Options.options.kernel_stack):
   6.184           conf.check(header_name='sim.h',
   6.185 @@ -247,7 +247,7 @@
   6.186         #  conf.check()
   6.187           conf.env['KERNEL_STACK'] = Options.options.kernel_stack
   6.188   
   6.189 -@@ -172,7 +175,6 @@
   6.190 +@@ -189,7 +192,6 @@
   6.191                ['test-netdb', []],
   6.192                ['test-env', []],
   6.193                ['test-cond', ['PTHREAD']],
   6.194 @@ -255,7 +255,7 @@
   6.195                ['test-stdlib', []],
   6.196                ['test-select', ['PTHREAD']],
   6.197                ['test-random', []],
   6.198 -@@ -194,6 +196,10 @@
   6.199 +@@ -211,6 +213,10 @@
   6.200                ['test-tsearch', []],
   6.201                ['test-signal', []],
   6.202                ]
   6.203 @@ -266,7 +266,7 @@
   6.204       for name,uselib in tests:
   6.205           module.add_test(**dce_kw(target='bin_dce/' + name, source = ['test/' + name + '.cc'],
   6.206                                    use = uselib + ['lib/test']))
   6.207 -@@ -201,7 +207,6 @@
   6.208 +@@ -218,7 +224,6 @@
   6.209   def build_dce_examples(module):
   6.210       dce_examples = [['udp-server', []],
   6.211                       ['udp-client', []],
   6.212 @@ -274,7 +274,7 @@
   6.213                       ['tcp-server', []],
   6.214                       ['tcp-client', []],
   6.215                       ['tcp-loopback', []],
   6.216 -@@ -211,6 +216,9 @@
   6.217 +@@ -228,6 +233,9 @@
   6.218                       ['udp-echo-client', []],
   6.219   #                    ['little-cout', []],
   6.220                       ]
   6.221 @@ -284,7 +284,7 @@
   6.222       for name,lib in dce_examples:
   6.223           module.add_example(**dce_kw(target = 'bin_dce/' + name, 
   6.224                                       source = ['example/' + name + '.cc'],
   6.225 -@@ -359,7 +367,6 @@
   6.226 +@@ -376,7 +384,6 @@
   6.227           'model/dce-string.cc',
   6.228           'model/dce-env.cc',
   6.229           'model/dce-pthread-cond.cc',
   6.230 @@ -292,7 +292,7 @@
   6.231           'model/dce-time.cc',
   6.232           'model/dce-stat.cc',
   6.233           'model/dce-syslog.cc',
   6.234 -@@ -424,6 +431,10 @@
   6.235 +@@ -443,6 +450,10 @@
   6.236           'helper/linux-stack-helper.h',
   6.237           'helper/ipv4-dce-routing-helper.h',
   6.238           ]
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/linux-stack-rework.patch	Thu Jun 20 09:56:26 2013 +0900
     7.3 @@ -0,0 +1,1054 @@
     7.4 +diff -r b4f69e2ed0b3 example/simple-point-to-point-olsr.cc
     7.5 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.6 ++++ b/example/simple-point-to-point-olsr.cc	Thu Dec 13 12:27:12 2012 +0900
     7.7 +@@ -0,0 +1,180 @@
     7.8 ++/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
     7.9 ++/*
    7.10 ++ * This program is free software; you can redistribute it and/or modify
    7.11 ++ * it under the terms of the GNU General Public License version 2 as
    7.12 ++ * published by the Free Software Foundation;
    7.13 ++ *
    7.14 ++ * This program is distributed in the hope that it will be useful,
    7.15 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
    7.16 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    7.17 ++ * GNU General Public License for more details.
    7.18 ++ *
    7.19 ++ * You should have received a copy of the GNU General Public License
    7.20 ++ * along with this program; if not, write to the Free Software
    7.21 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
    7.22 ++ *
    7.23 ++ */
    7.24 ++
    7.25 ++//
    7.26 ++// Simple example of OLSR routing over some point-to-point links
    7.27 ++//
    7.28 ++// Network topology
    7.29 ++//
    7.30 ++//   n0
    7.31 ++//     \ 5 Mb/s, 2ms
    7.32 ++//      \          1.5Mb/s, 10ms
    7.33 ++//       n2 -------------------------n3---------n4
    7.34 ++//      /
    7.35 ++//     / 5 Mb/s, 2ms
    7.36 ++//   n1
    7.37 ++//
    7.38 ++// - all links are point-to-point links with indicated one-way BW/delay
    7.39 ++// - CBR/UDP flows from n0 to n4, and from n3 to n1
    7.40 ++// - UDP packet size of 210 bytes, with per-packet interval 0.00375 sec.
    7.41 ++//   (i.e., DataRate of 448,000 bps)
    7.42 ++// - DropTail queues 
    7.43 ++// - Tracing of queues and packet receptions to file "simple-point-to-point-olsr.tr"
    7.44 ++
    7.45 ++#include <iostream>
    7.46 ++#include <fstream>
    7.47 ++#include <string>
    7.48 ++#include <cassert>
    7.49 ++
    7.50 ++#include "ns3/core-module.h"
    7.51 ++#include "ns3/network-module.h"
    7.52 ++#include "ns3/internet-module.h"
    7.53 ++#include "ns3/point-to-point-module.h"
    7.54 ++#include "ns3/applications-module.h"
    7.55 ++#include "ns3/olsr-helper.h"
    7.56 ++#include "ns3/ipv4-static-routing-helper.h"
    7.57 ++#include "ns3/ipv4-list-routing-helper.h"
    7.58 ++#include "ns3/dce-module.h"
    7.59 ++
    7.60 ++using namespace ns3;
    7.61 ++
    7.62 ++NS_LOG_COMPONENT_DEFINE ("SimplePointToPointOlsrExample");
    7.63 ++
    7.64 ++int 
    7.65 ++main (int argc, char *argv[])
    7.66 ++{
    7.67 ++  // Users may find it convenient to turn on explicit debugging
    7.68 ++  // for selected modules; the below lines suggest how to do this
    7.69 ++#if 0 
    7.70 ++  LogComponentEnable ("SimpleGlobalRoutingExample", LOG_LEVEL_INFO);
    7.71 ++#endif
    7.72 ++
    7.73 ++  // Set up some default values for the simulation.  Use the 
    7.74 ++
    7.75 ++  Config::SetDefault ("ns3::OnOffApplication::PacketSize", UintegerValue (210));
    7.76 ++  Config::SetDefault ("ns3::OnOffApplication::DataRate", StringValue ("448kb/s"));
    7.77 ++
    7.78 ++  //DefaultValue::Bind ("DropTailQueue::m_maxPackets", 30);
    7.79 ++
    7.80 ++  // Allow the user to override any of the defaults and the above
    7.81 ++  // DefaultValue::Bind ()s at run-time, via command-line arguments
    7.82 ++  CommandLine cmd;
    7.83 ++  cmd.Parse (argc, argv);
    7.84 ++
    7.85 ++  // Here, we will explicitly create four nodes.  In more sophisticated
    7.86 ++  // topologies, we could configure a node factory.
    7.87 ++  NS_LOG_INFO ("Create nodes.");
    7.88 ++  NodeContainer c;
    7.89 ++  c.Create (5);
    7.90 ++  NodeContainer n02 = NodeContainer (c.Get (0), c.Get (2));
    7.91 ++  NodeContainer n12 = NodeContainer (c.Get (1), c.Get (2));
    7.92 ++  NodeContainer n32 = NodeContainer (c.Get (3), c.Get (2));
    7.93 ++  NodeContainer n34 = NodeContainer (c.Get (3), c.Get (4));
    7.94 ++
    7.95 ++  // Enable OLSR
    7.96 ++  NS_LOG_INFO ("Enabling OLSR Routing.");
    7.97 ++  OlsrHelper olsr;
    7.98 ++
    7.99 ++  Ipv4StaticRoutingHelper staticRouting;
   7.100 ++
   7.101 ++  Ipv4ListRoutingHelper list;
   7.102 ++  list.Add (staticRouting, 0);
   7.103 ++  list.Add (olsr, 10);
   7.104 ++
   7.105 ++  DceManagerHelper dceManager;
   7.106 ++  dceManager.SetNetworkStack("ns3::LinuxSocketFdFactory",
   7.107 ++                             "Library", StringValue ("liblinux.so"));
   7.108 ++  LinuxStackHelper internet;
   7.109 ++  internet.SetRoutingHelper (list); // has effect on the next Install ()
   7.110 ++  internet.Install (c);
   7.111 ++
   7.112 ++  // We create the channels first without any IP addressing information
   7.113 ++  NS_LOG_INFO ("Create channels.");
   7.114 ++  PointToPointHelper p2p;
   7.115 ++  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
   7.116 ++  p2p.SetChannelAttribute ("Delay", StringValue ("2ms"));
   7.117 ++  NetDeviceContainer nd02 = p2p.Install (n02);
   7.118 ++  NetDeviceContainer nd12 = p2p.Install (n12);
   7.119 ++  p2p.SetDeviceAttribute ("DataRate", StringValue ("1500kbps"));
   7.120 ++  p2p.SetChannelAttribute ("Delay", StringValue ("10ms"));
   7.121 ++  NetDeviceContainer nd32 = p2p.Install (n32);
   7.122 ++  NetDeviceContainer nd34 = p2p.Install (n34);
   7.123 ++
   7.124 ++  // Later, we add IP addresses.
   7.125 ++  NS_LOG_INFO ("Assign IP Addresses.");
   7.126 ++  Ipv4AddressHelper ipv4;
   7.127 ++  ipv4.SetBase ("10.1.1.0", "255.255.255.0");
   7.128 ++  Ipv4InterfaceContainer i02 = ipv4.Assign (nd02);
   7.129 ++
   7.130 ++  ipv4.SetBase ("10.1.2.0", "255.255.255.0");
   7.131 ++  Ipv4InterfaceContainer i12 = ipv4.Assign (nd12);
   7.132 ++
   7.133 ++  ipv4.SetBase ("10.1.3.0", "255.255.255.0");
   7.134 ++  Ipv4InterfaceContainer i32 = ipv4.Assign (nd32);
   7.135 ++
   7.136 ++  ipv4.SetBase ("10.1.4.0", "255.255.255.0");
   7.137 ++  Ipv4InterfaceContainer i34 = ipv4.Assign (nd34);
   7.138 ++
   7.139 ++  dceManager.Install (c);
   7.140 ++
   7.141 ++  // Create the OnOff application to send UDP datagrams of size
   7.142 ++  // 210 bytes at a rate of 448 Kb/s from n0 to n4
   7.143 ++  NS_LOG_INFO ("Create Applications.");
   7.144 ++  uint16_t port = 9;   // Discard port (RFC 863)
   7.145 ++
   7.146 ++  OnOffHelper onoff ("ns3::LinuxUdpSocketFactory", 
   7.147 ++                     InetSocketAddress (i34.GetAddress (1), port));
   7.148 ++  onoff.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
   7.149 ++  onoff.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
   7.150 ++
   7.151 ++  ApplicationContainer apps = onoff.Install (c.Get (0));
   7.152 ++  apps.Start (Seconds (1.0));
   7.153 ++  apps.Stop (Seconds (10.0));
   7.154 ++
   7.155 ++  // Create a packet sink to receive these packets
   7.156 ++  PacketSinkHelper sink ("ns3::LinuxUdpSocketFactory",
   7.157 ++                         InetSocketAddress (Ipv4Address::GetAny (), port));
   7.158 ++
   7.159 ++  apps = sink.Install (c.Get (3));
   7.160 ++  apps.Start (Seconds (1.0));
   7.161 ++  apps.Stop (Seconds (10.0));
   7.162 ++
   7.163 ++  // Create a similar flow from n3 to n1, starting at time 1.1 seconds
   7.164 ++  onoff.SetAttribute ("Remote",
   7.165 ++                      AddressValue (InetSocketAddress (i12.GetAddress (0), port)));
   7.166 ++  apps = onoff.Install (c.Get (3));
   7.167 ++  apps.Start (Seconds (1.1));
   7.168 ++  apps.Stop (Seconds (10.0));
   7.169 ++
   7.170 ++  // Create a packet sink to receive these packets
   7.171 ++  apps = sink.Install (c.Get (1));
   7.172 ++  apps.Start (Seconds (1.1));
   7.173 ++  apps.Stop (Seconds (10.0));
   7.174 ++
   7.175 ++  AsciiTraceHelper ascii;
   7.176 ++  p2p.EnableAsciiAll (ascii.CreateFileStream ("simple-point-to-point-olsr.tr"));
   7.177 ++  p2p.EnablePcapAll ("simple-point-to-point-olsr");
   7.178 ++
   7.179 ++  Simulator::Stop (Seconds (30));
   7.180 ++
   7.181 ++  NS_LOG_INFO ("Run Simulation.");
   7.182 ++  Simulator::Run ();
   7.183 ++  Simulator::Destroy ();
   7.184 ++  NS_LOG_INFO ("Done.");
   7.185 ++
   7.186 ++  return 0;
   7.187 ++}
   7.188 +diff -r b4f69e2ed0b3 helper/linux-stack-helper.cc
   7.189 +--- a/helper/linux-stack-helper.cc	Thu Dec 13 12:07:18 2012 +0900
   7.190 ++++ b/helper/linux-stack-helper.cc	Thu Dec 13 12:27:12 2012 +0900
   7.191 +@@ -19,16 +19,56 @@
   7.192 +  */
   7.193 + #include "linux-stack-helper.h"
   7.194 + #include "ipv4-linux.h"
   7.195 ++#include "ipv6-linux.h"
   7.196 + #include "linux-socket-fd-factory.h"
   7.197 + #include "ns3/node.h"
   7.198 + #include "ns3/node-container.h"
   7.199 + #include "ns3/names.h"
   7.200 ++#include "ns3/ipv4-list-routing-helper.h"
   7.201 ++#include "ns3/ipv4-static-routing-helper.h"
   7.202 ++#include "ns3/ipv4-global-routing-helper.h"
   7.203 + 
   7.204 + namespace ns3 {
   7.205 ++LinuxStackHelper::LinuxStackHelper ()
   7.206 ++  : m_routing (0)
   7.207 ++{
   7.208 ++  Initialize ();
   7.209 ++}
   7.210 ++
   7.211 ++// private method called by both constructor and Reset ()
   7.212 ++void
   7.213 ++LinuxStackHelper::Initialize ()
   7.214 ++{
   7.215 ++  Ipv4StaticRoutingHelper staticRouting;
   7.216 ++  Ipv4GlobalRoutingHelper globalRouting;
   7.217 ++  Ipv4ListRoutingHelper listRouting;
   7.218 ++  listRouting.Add (staticRouting, 0);
   7.219 ++  listRouting.Add (globalRouting, -10);
   7.220 ++  SetRoutingHelper (listRouting);
   7.221 ++}
   7.222 ++
   7.223 ++LinuxStackHelper::~LinuxStackHelper ()
   7.224 ++{
   7.225 ++  delete m_routing;
   7.226 ++}
   7.227 ++
   7.228 ++void 
   7.229 ++LinuxStackHelper::SetRoutingHelper (const Ipv4RoutingHelper &routing)
   7.230 ++{
   7.231 ++  delete m_routing;
   7.232 ++  m_routing = routing.Copy ();
   7.233 ++}
   7.234 ++
   7.235 + void
   7.236 + LinuxStackHelper::Install (Ptr<Node> node)
   7.237 + {
   7.238 +   Ipv4Linux::InstallNode (node);
   7.239 ++  // Set routing
   7.240 ++  Ptr<Ipv4> ipv4 = node->GetObject<Ipv4> ();
   7.241 ++  Ptr<Ipv4RoutingProtocol> ipv4Routing = m_routing->Create (node);
   7.242 ++  ipv4->SetRoutingProtocol (ipv4Routing);
   7.243 ++
   7.244 ++  Ipv6Linux::InstallNode (node);
   7.245 + }
   7.246 + void
   7.247 + LinuxStackHelper::Install (std::string nodeName)
   7.248 +@@ -94,7 +134,11 @@
   7.249 +         {
   7.250 +           continue;
   7.251 +         }
   7.252 +-      sock->Set (path, value);      
   7.253 ++      // i.e., TaskManager::Current() needs it.
   7.254 ++      Simulator::ScheduleWithContext (node->GetId (), Seconds (0.0),
   7.255 ++                                      &LinuxSocketFdFactory::ScheduleTask, sock,
   7.256 ++                                      MakeEvent (&LinuxSocketFdFactory::Set, sock,
   7.257 ++                                                 path, value));
   7.258 +     }
   7.259 + }
   7.260 + 
   7.261 +diff -r b4f69e2ed0b3 helper/linux-stack-helper.h
   7.262 +--- a/helper/linux-stack-helper.h	Thu Dec 13 12:07:18 2012 +0900
   7.263 ++++ b/helper/linux-stack-helper.h	Thu Dec 13 12:27:12 2012 +0900
   7.264 +@@ -27,6 +27,7 @@
   7.265 + class Node;
   7.266 + class NodeContainer;
   7.267 + class Time;
   7.268 ++class Ipv4RoutingHelper;
   7.269 + 
   7.270 + /**
   7.271 +  * \brief aggregate Ipv4Linux to nodes
   7.272 +@@ -40,6 +41,10 @@
   7.273 + class LinuxStackHelper
   7.274 + {
   7.275 + public:
   7.276 ++
   7.277 ++  LinuxStackHelper ();
   7.278 ++  ~LinuxStackHelper ();
   7.279 ++
   7.280 +   /**
   7.281 +    * Aggregate ns3::Ipv4Linux classe onto the provided node.
   7.282 +    * This method will assert if called on a node that
   7.283 +@@ -47,7 +52,7 @@
   7.284 +    *
   7.285 +    * \param nodeName The name of the node on which to install the stack.
   7.286 +    */
   7.287 +-  static void Install (std::string nodeName);
   7.288 ++  void Install (std::string nodeName);
   7.289 + 
   7.290 +   /**
   7.291 +    * Aggregate ns3::Ipv4Linux classe onto the provided node.
   7.292 +@@ -56,7 +61,7 @@
   7.293 +    *
   7.294 +    * \param node The node on which to install the stack.
   7.295 +    */
   7.296 +-  static void Install (Ptr<Node> node);
   7.297 ++  void Install (Ptr<Node> node);
   7.298 + 
   7.299 +   /**
   7.300 +    * Aggregate ns3::Ipv4Linux class onto the provided node.
   7.301 +@@ -66,17 +71,30 @@
   7.302 +    * \param c NodeContainer that holds the set of nodes on which to install the
   7.303 +    * new stacks.
   7.304 +    */
   7.305 +-  static void Install (NodeContainer c);
   7.306 ++  void Install (NodeContainer c);
   7.307 + 
   7.308 +   /**
   7.309 +    * Aggregate ns3::Ipv4Linux to all nodes in the simulation
   7.310 +    */
   7.311 +-  static void InstallAll (void);
   7.312 ++  void InstallAll (void);
   7.313 ++
   7.314 ++  /**
   7.315 ++   * \param routing a new routing helper
   7.316 ++   *
   7.317 ++   * Set the routing helper to use during Install. The routing
   7.318 ++   * helper is really an object factory which is used to create 
   7.319 ++   * an object of type ns3::Ipv4RoutingProtocol per node. This routing
   7.320 ++   * object is then associated to a single ns3::Ipv4 object through its 
   7.321 ++   * ns3::Ipv4::SetRoutingProtocol.
   7.322 ++   */
   7.323 ++  void SetRoutingHelper (const Ipv4RoutingHelper &routing);
   7.324 + 
   7.325 +   void SysctlSet (NodeContainer c, std::string path, std::string value);
   7.326 +   static void SysctlGet (Ptr<Node> node, Time at, std::string path, 
   7.327 +                          void (*callback)(std::string, std::string));
   7.328 + private:
   7.329 ++  void Initialize ();
   7.330 ++  const Ipv4RoutingHelper *m_routing;
   7.331 +   static void SysctlGetCallback (Ptr<Node> node, std::string path, 
   7.332 +                                  void (*callback)(std::string, std::string));
   7.333 +   
   7.334 +diff -r b4f69e2ed0b3 model/linux/ipv6-linux.cc
   7.335 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   7.336 ++++ b/model/linux/ipv6-linux.cc	Thu Dec 13 12:27:12 2012 +0900
   7.337 +@@ -0,0 +1,397 @@
   7.338 ++/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
   7.339 ++/*
   7.340 ++ * Copyright (c) 2012 INRIA
   7.341 ++ *
   7.342 ++ * This program is free software; you can redistribute it and/or modify
   7.343 ++ * it under the terms of the GNU General Public License version 2 as
   7.344 ++ * published by the Free Software Foundation;
   7.345 ++ *
   7.346 ++ * This program is distributed in the hope that it will be useful,
   7.347 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
   7.348 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   7.349 ++ * GNU General Public License for more details.
   7.350 ++ *
   7.351 ++ * You should have received a copy of the GNU General Public License
   7.352 ++ * along with this program; if not, write to the Free Software
   7.353 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   7.354 ++ *
   7.355 ++ * Author: Fr辿d辿ric Urbani
   7.356 ++ *         Hajime Tazaki <tazaki@nict.go.jp>
   7.357 ++ */
   7.358 ++
   7.359 ++#include "ipv6-linux.h"
   7.360 ++#include "ns3/log.h"
   7.361 ++#include "ns3/node.h"
   7.362 ++#include "ns3/ipv6-list-routing-helper.h"
   7.363 ++#include "ns3/ipv6-static-routing-helper.h"
   7.364 ++//#include "ns3/ipv6-global-routing-helper.h"
   7.365 ++#include "ns3/ipv6-interface.h"
   7.366 ++//#include "linux-dccp6-socket-factory-impl.h"
   7.367 ++
   7.368 ++NS_LOG_COMPONENT_DEFINE ("Ipv6Linux");
   7.369 ++
   7.370 ++namespace ns3 {
   7.371 ++
   7.372 ++NS_OBJECT_ENSURE_REGISTERED (Ipv6Linux);
   7.373 ++
   7.374 ++TypeId
   7.375 ++Ipv6Linux::GetTypeId (void)
   7.376 ++{
   7.377 ++  static TypeId tid = TypeId ("ns3::Ipv6Linux")
   7.378 ++    .SetParent<Ipv6> ()
   7.379 ++    .AddConstructor<Ipv6Linux> ();
   7.380 ++
   7.381 ++  return tid;
   7.382 ++}
   7.383 ++
   7.384 ++Ipv6Linux::Ipv6Linux()
   7.385 ++{
   7.386 ++  NS_LOG_FUNCTION (this);
   7.387 ++}
   7.388 ++
   7.389 ++Ipv6Linux::~Ipv6Linux ()
   7.390 ++{
   7.391 ++  NS_LOG_FUNCTION (this);
   7.392 ++}
   7.393 ++
   7.394 ++void
   7.395 ++Ipv6Linux::SetRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol)
   7.396 ++{
   7.397 ++  NS_LOG_FUNCTION (this);
   7.398 ++  m_routingProtocol = routingProtocol;
   7.399 ++  m_routingProtocol->SetIpv6 (this);
   7.400 ++}
   7.401 ++
   7.402 ++Ptr<Ipv6RoutingProtocol>
   7.403 ++Ipv6Linux::GetRoutingProtocol (void) const
   7.404 ++{
   7.405 ++  NS_LOG_FUNCTION (this);
   7.406 ++  return m_routingProtocol;
   7.407 ++}
   7.408 ++
   7.409 ++uint32_t
   7.410 ++Ipv6Linux::AddInterface (Ptr<NetDevice> device)
   7.411 ++{
   7.412 ++  NS_LOG_FUNCTION (this << &device);
   7.413 ++
   7.414 ++  Ptr<Ipv6Interface> interface = CreateObject<Ipv6Interface> ();
   7.415 ++  interface->SetDevice (device);
   7.416 ++  interface->SetForwarding (m_ipForward);
   7.417 ++  return AddIpv6Interface (interface);
   7.418 ++}
   7.419 ++uint32_t
   7.420 ++Ipv6Linux::AddIpv6Interface (Ptr<Ipv6Interface>interface)
   7.421 ++{
   7.422 ++  NS_LOG_FUNCTION (this << interface);
   7.423 ++  uint32_t index = m_interfaces.size ();
   7.424 ++  m_interfaces.push_back (interface);
   7.425 ++  return index;
   7.426 ++}
   7.427 ++
   7.428 ++uint32_t
   7.429 ++Ipv6Linux::GetNInterfaces (void) const
   7.430 ++{
   7.431 ++  NS_LOG_FUNCTION (this);
   7.432 ++  return m_interfaces.size ();
   7.433 ++}
   7.434 ++
   7.435 ++int32_t
   7.436 ++Ipv6Linux::GetInterfaceForAddress (Ipv6Address address) const
   7.437 ++{
   7.438 ++  NS_LOG_FUNCTION (this);
   7.439 ++
   7.440 ++  int32_t interface = 0;
   7.441 ++  for (Ipv6InterfaceList::const_iterator i = m_interfaces.begin ();
   7.442 ++       i != m_interfaces.end ();
   7.443 ++       i++, interface++)
   7.444 ++    {
   7.445 ++      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
   7.446 ++        {
   7.447 ++          if ((*i)->GetAddress (j).GetAddress () == address)
   7.448 ++            {
   7.449 ++              return interface;
   7.450 ++            }
   7.451 ++        }
   7.452 ++    }
   7.453 ++
   7.454 ++  return -1;
   7.455 ++}
   7.456 ++
   7.457 ++void
   7.458 ++Ipv6Linux::Send (Ptr<Packet> packet, Ipv6Address source,
   7.459 ++                   Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route)
   7.460 ++{
   7.461 ++  NS_LOG_FUNCTION (this << "empty method.");
   7.462 ++}
   7.463 ++
   7.464 ++void
   7.465 ++Ipv6Linux::SendWithHeader (Ptr<Packet> packet, Ipv6Header ipHeader, Ptr<Ipv6Route> route)
   7.466 ++{
   7.467 ++  NS_LOG_FUNCTION (this << "empty method.");
   7.468 ++}
   7.469 ++
   7.470 ++#if 0
   7.471 ++void
   7.472 ++Ipv6Linux::Insert (Ptr<IpL4Protocol> protocol)
   7.473 ++{
   7.474 ++  NS_LOG_FUNCTION (this << "empty method.");
   7.475 ++}
   7.476 ++#endif
   7.477 ++
   7.478 ++
   7.479 ++int32_t
   7.480 ++Ipv6Linux::GetInterfaceForPrefix (Ipv6Address address, Ipv6Prefix mask) const
   7.481 ++{
   7.482 ++  NS_LOG_FUNCTION (this);
   7.483 ++  int32_t interface = 0;
   7.484 ++  for (Ipv6InterfaceList::const_iterator i = m_interfaces.begin ();
   7.485 ++       i != m_interfaces.end ();
   7.486 ++       i++, interface++)
   7.487 ++    {
   7.488 ++      for (uint32_t j = 0; j < (*i)->GetNAddresses (); j++)
   7.489 ++        {
   7.490 ++          if ((*i)->GetAddress (j).GetAddress ().CombinePrefix (mask) == address.CombinePrefix (mask))
   7.491 ++            {
   7.492 ++              return interface;
   7.493 ++            }
   7.494 ++        }
   7.495 ++    }
   7.496 ++
   7.497 ++  return -1;
   7.498 ++}
   7.499 ++
   7.500 ++Ptr<NetDevice>
   7.501 ++Ipv6Linux::GetNetDevice (uint32_t i)
   7.502 ++{
   7.503 ++  NS_LOG_FUNCTION (this);
   7.504 ++  return GetInterface (i)->GetDevice ();
   7.505 ++}
   7.506 ++
   7.507 ++int32_t
   7.508 ++Ipv6Linux::GetInterfaceForDevice (Ptr<const NetDevice> device) const
   7.509 ++{
   7.510 ++  NS_LOG_FUNCTION (this);
   7.511 ++  int32_t interface = 0;
   7.512 ++  for (Ipv6InterfaceList::const_iterator i = m_interfaces.begin ();
   7.513 ++       i != m_interfaces.end ();
   7.514 ++       i++, interface++)
   7.515 ++    {
   7.516 ++      if ((*i)->GetDevice () == device)
   7.517 ++        {
   7.518 ++          return interface;
   7.519 ++        }
   7.520 ++    }
   7.521 ++
   7.522 ++  return -1;
   7.523 ++}
   7.524 ++
   7.525 ++bool
   7.526 ++Ipv6Linux::AddAddress (uint32_t i, Ipv6InterfaceAddress address)
   7.527 ++{
   7.528 ++  NS_LOG_FUNCTION (this << i << address);
   7.529 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.530 ++  bool retVal = interface->AddAddress (address);
   7.531 ++  if (m_routingProtocol != 0)
   7.532 ++    {
   7.533 ++      m_routingProtocol->NotifyAddAddress (i, address);
   7.534 ++    }
   7.535 ++  return retVal;
   7.536 ++}
   7.537 ++
   7.538 ++uint32_t
   7.539 ++Ipv6Linux::GetNAddresses (uint32_t interface) const
   7.540 ++{
   7.541 ++  Ptr<Ipv6Interface> iface = GetInterface (interface);
   7.542 ++  return iface->GetNAddresses ();
   7.543 ++}
   7.544 ++
   7.545 ++Ipv6InterfaceAddress
   7.546 ++Ipv6Linux::GetAddress (uint32_t interfaceIndex, uint32_t addressIndex) const
   7.547 ++{
   7.548 ++  NS_LOG_FUNCTION (this);
   7.549 ++  Ptr<Ipv6Interface> interface = GetInterface (interfaceIndex);
   7.550 ++  return interface->GetAddress (addressIndex);
   7.551 ++}
   7.552 ++
   7.553 ++bool
   7.554 ++Ipv6Linux::RemoveAddress (uint32_t i, uint32_t addressIndex)
   7.555 ++{
   7.556 ++  NS_LOG_FUNCTION (this << i << addressIndex);
   7.557 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.558 ++  Ipv6InterfaceAddress address = interface->RemoveAddress (addressIndex);
   7.559 ++  if (address != Ipv6InterfaceAddress ())
   7.560 ++    {
   7.561 ++      if (m_routingProtocol != 0)
   7.562 ++        {
   7.563 ++          m_routingProtocol->NotifyRemoveAddress (i, address);
   7.564 ++        }
   7.565 ++      return true;
   7.566 ++    }
   7.567 ++  return false;
   7.568 ++}
   7.569 ++
   7.570 ++void
   7.571 ++Ipv6Linux::SetMetric (uint32_t i, uint16_t metric)
   7.572 ++{
   7.573 ++  NS_LOG_FUNCTION (this << i << metric);
   7.574 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.575 ++  interface->SetMetric (metric);
   7.576 ++}
   7.577 ++
   7.578 ++uint16_t
   7.579 ++Ipv6Linux::GetMetric (uint32_t i) const
   7.580 ++{
   7.581 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.582 ++  return interface->GetMetric ();
   7.583 ++}
   7.584 ++
   7.585 ++uint16_t
   7.586 ++Ipv6Linux::GetMtu (uint32_t i) const
   7.587 ++{
   7.588 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.589 ++  return interface->GetDevice ()->GetMtu ();
   7.590 ++}
   7.591 ++
   7.592 ++bool
   7.593 ++Ipv6Linux::IsUp (uint32_t i) const
   7.594 ++{
   7.595 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.596 ++  return interface->IsUp ();
   7.597 ++}
   7.598 ++
   7.599 ++void
   7.600 ++Ipv6Linux::SetUp (uint32_t i)
   7.601 ++{
   7.602 ++  NS_LOG_FUNCTION (this << i);
   7.603 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.604 ++  interface->SetUp ();
   7.605 ++
   7.606 ++  if (m_routingProtocol != 0)
   7.607 ++    {
   7.608 ++      m_routingProtocol->NotifyInterfaceUp (i);
   7.609 ++    }
   7.610 ++}
   7.611 ++
   7.612 ++void
   7.613 ++Ipv6Linux::SetDown (uint32_t ifaceIndex)
   7.614 ++{
   7.615 ++  NS_LOG_FUNCTION (this << ifaceIndex);
   7.616 ++  Ptr<Ipv6Interface> interface = GetInterface (ifaceIndex);
   7.617 ++  interface->SetDown ();
   7.618 ++
   7.619 ++  if (m_routingProtocol != 0)
   7.620 ++    {
   7.621 ++      m_routingProtocol->NotifyInterfaceDown (ifaceIndex);
   7.622 ++    }
   7.623 ++}
   7.624 ++
   7.625 ++bool
   7.626 ++Ipv6Linux::IsForwarding (uint32_t i) const
   7.627 ++{
   7.628 ++  NS_LOG_FUNCTION (this << i);
   7.629 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.630 ++  NS_LOG_LOGIC ("Forwarding state: " << interface->IsForwarding ());
   7.631 ++  return interface->IsForwarding ();
   7.632 ++}
   7.633 ++
   7.634 ++void
   7.635 ++Ipv6Linux::SetForwarding (uint32_t i, bool val)
   7.636 ++{
   7.637 ++  NS_LOG_FUNCTION (this << i);
   7.638 ++  Ptr<Ipv6Interface> interface = GetInterface (i);
   7.639 ++  interface->SetForwarding (val);
   7.640 ++}
   7.641 ++
   7.642 ++void
   7.643 ++Ipv6Linux::SetIpForward (bool forward)
   7.644 ++{
   7.645 ++  NS_LOG_FUNCTION (this << forward);
   7.646 ++  m_ipForward = forward;
   7.647 ++  for (Ipv6InterfaceList::const_iterator i = m_interfaces.begin (); i != m_interfaces.end (); i++)
   7.648 ++    {
   7.649 ++      (*i)->SetForwarding (forward);
   7.650 ++    }
   7.651 ++}
   7.652 ++
   7.653 ++bool
   7.654 ++Ipv6Linux::GetIpForward (void) const
   7.655 ++{
   7.656 ++  return m_ipForward;
   7.657 ++}
   7.658 ++
   7.659 ++void
   7.660 ++Ipv6Linux::SetWeakEsModel (bool model)
   7.661 ++{
   7.662 ++  m_weakEsModel = model;
   7.663 ++}
   7.664 ++
   7.665 ++bool
   7.666 ++Ipv6Linux::GetWeakEsModel (void) const
   7.667 ++{
   7.668 ++  return m_weakEsModel;
   7.669 ++}
   7.670 ++
   7.671 ++void
   7.672 ++Ipv6Linux::InstallNode (Ptr<Node> node)
   7.673 ++{
   7.674 ++  ObjectFactory factory;
   7.675 ++  factory.SetTypeId ("ns3::Ipv6Linux");
   7.676 ++  Ptr<Object> protocol = factory.Create <Object> ();
   7.677 ++  node->AggregateObject (protocol);
   7.678 ++  // Set routing
   7.679 ++  Ptr<Ipv6> ipv6 = node->GetObject<Ipv6> ();
   7.680 ++  Ipv6ListRoutingHelper listRoutingv6;
   7.681 ++  Ipv6StaticRoutingHelper staticRoutingv6;
   7.682 ++  listRoutingv6.Add (staticRoutingv6, 0);
   7.683 ++  Ptr<Ipv6RoutingProtocol> ipv6Routing = listRoutingv6.Create (node);
   7.684 ++  ipv6->SetRoutingProtocol (ipv6Routing);
   7.685 ++  // Socket related stuff
   7.686 ++  // Ptr<LinuxDccp6SocketFactoryImpl> dccpFactory = CreateObject<LinuxDccp6SocketFactoryImpl> ();
   7.687 ++  // node->AggregateObject (dccpFactory);
   7.688 ++}
   7.689 ++Ptr<Ipv6Interface>
   7.690 ++Ipv6Linux::GetInterface (uint32_t index) const
   7.691 ++{
   7.692 ++  if (index < m_interfaces.size ())
   7.693 ++    {
   7.694 ++      return m_interfaces[index];
   7.695 ++    }
   7.696 ++  return 0;
   7.697 ++}
   7.698 ++
   7.699 ++#if 0
   7.700 ++Ptr<IpL4Protocol>
   7.701 ++Ipv6Linux::GetProtocol (int protocolNumber) const
   7.702 ++{
   7.703 ++  return 0;
   7.704 ++}
   7.705 ++#endif
   7.706 ++
   7.707 ++Ptr<Socket>
   7.708 ++Ipv6Linux::CreateRawSocket (void)
   7.709 ++{
   7.710 ++  return 0;
   7.711 ++}
   7.712 ++
   7.713 ++/**
   7.714 ++ * Do nothing
   7.715 ++ */
   7.716 ++void
   7.717 ++Ipv6Linux::DeleteRawSocket (Ptr<Socket> socket)
   7.718 ++{
   7.719 ++
   7.720 ++}
   7.721 ++
   7.722 ++void
   7.723 ++Ipv6Linux::RegisterExtensions ()
   7.724 ++{
   7.725 ++  NS_ASSERT (0);
   7.726 ++}
   7.727 ++
   7.728 ++void 
   7.729 ++Ipv6Linux::RegisterOptions ()
   7.730 ++{
   7.731 ++  NS_ASSERT (0);
   7.732 ++}
   7.733 ++
   7.734 ++}
   7.735 +diff -r b4f69e2ed0b3 model/linux/ipv6-linux.h
   7.736 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   7.737 ++++ b/model/linux/ipv6-linux.h	Thu Dec 13 12:27:12 2012 +0900
   7.738 +@@ -0,0 +1,280 @@
   7.739 ++/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
   7.740 ++/*
   7.741 ++ * Copyright (c) 2012 INRIA
   7.742 ++ *
   7.743 ++ * This program is free software; you can redistribute it and/or modify
   7.744 ++ * it under the terms of the GNU General Public License version 2 as
   7.745 ++ * published by the Free Software Foundation;
   7.746 ++ *
   7.747 ++ * This program is distributed in the hope that it will be useful,
   7.748 ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
   7.749 ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   7.750 ++ * GNU General Public License for more details.
   7.751 ++ *
   7.752 ++ * You should have received a copy of the GNU General Public License
   7.753 ++ * along with this program; if not, write to the Free Software
   7.754 ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   7.755 ++ *
   7.756 ++ * Author: Fr辿d辿ric Urbani
   7.757 ++ */
   7.758 ++
   7.759 ++#ifndef IPV6_LINUX_H
   7.760 ++#define IPV6_LINUX_H
   7.761 ++
   7.762 ++#include "ns3/ipv6.h"
   7.763 ++#include "ns3/ipv6-routing-protocol.h"
   7.764 ++
   7.765 ++namespace ns3 {
   7.766 ++class Ipv6Interface;
   7.767 ++
   7.768 ++/**
   7.769 ++ * \brief This implementation of Ipv6 for nodes using a real Linux Stack.
   7.770 ++ *
   7.771 ++ * The main goal of this class is not to do the stack job which is done by the real code ....
   7.772 ++ * but it is used to not redo the wheel and in particular to be able to reuse these 2 standards NS-3 Helpers for two tasks:
   7.773 ++ *   1 - assign address to devices using Ipv6AddressHelper,
   7.774 ++ *   2 - create the static routes using Ipv6GlobalRoutingHelper
   7.775 ++ *
   7.776 ++ */
   7.777 ++class Ipv6Linux : public Ipv6
   7.778 ++{
   7.779 ++public:
   7.780 ++  static TypeId GetTypeId (void);
   7.781 ++  Ipv6Linux ();
   7.782 ++  virtual ~Ipv6Linux ();
   7.783 ++
   7.784 ++  /**
   7.785 ++   * \brief Register a new routing protocol to be used by this Ipv6 stack
   7.786 ++   *
   7.787 ++   * This call will replace any routing protocol that has been previously
   7.788 ++   * registered.  If you want to add multiple routing protocols, you must
   7.789 ++   * add them to a Ipv6ListRoutingProtocol directly.
   7.790 ++   *
   7.791 ++   * \param routingProtocol smart pointer to Ipv6RoutingProtocol object
   7.792 ++   */
   7.793 ++  virtual void SetRoutingProtocol (Ptr<Ipv6RoutingProtocol> routingProtocol);
   7.794 ++
   7.795 ++  /**
   7.796 ++   * \brief Get the routing protocol to be used by this Ipv6 stack
   7.797 ++   *
   7.798 ++   * \returns smart pointer to Ipv6RoutingProtocol object, or null pointer if none
   7.799 ++   */
   7.800 ++  virtual Ptr<Ipv6RoutingProtocol> GetRoutingProtocol (void) const;
   7.801 ++
   7.802 ++  /**
   7.803 ++   * \param device device to add to the list of Ipv6 interfaces
   7.804 ++   *        which can be used as output interfaces during packet forwarding.
   7.805 ++   * \returns the index of the Ipv6 interface added.
   7.806 ++   *
   7.807 ++   * Once a device has been added, it can never be removed: if you want
   7.808 ++   * to disable it, you can invoke Ipv6::SetDown which will
   7.809 ++   * make sure that it is never used during packet forwarding.
   7.810 ++   */
   7.811 ++  virtual uint32_t AddInterface (Ptr<NetDevice> device);
   7.812 ++
   7.813 ++  /**
   7.814 ++   * \returns the number of interfaces added by the user.
   7.815 ++   */
   7.816 ++  virtual uint32_t GetNInterfaces (void) const;
   7.817 ++
   7.818 ++  /**
   7.819 ++   * \brief Return the interface number of the interface that has been
   7.820 ++   *        assigned the specified IP address.
   7.821 ++   *
   7.822 ++   * \param address The IP address being searched for
   7.823 ++   * \returns The interface number of the Ipv6 interface with the given
   7.824 ++   *          address or -1 if not found.
   7.825 ++   *
   7.826 ++   * Each IP interface has one or more IP addresses associated with it.
   7.827 ++   * This method searches the list of interfaces for one that holds a
   7.828 ++   * particular address.  This call takes an IP address as a parameter and
   7.829 ++   * returns the interface number of the first interface that has been assigned
   7.830 ++   * that address, or -1 if not found.  There must be an exact match; this
   7.831 ++   * method will not match broadcast or multicast addresses.
   7.832 ++   */
   7.833 ++  virtual int32_t GetInterfaceForAddress (Ipv6Address address) const;
   7.834 ++
   7.835 ++  /**
   7.836 ++   * Do nothing
   7.837 ++   */
   7.838 ++  virtual void Send (Ptr<Packet> packet, Ipv6Address source,
   7.839 ++                     Ipv6Address destination, uint8_t protocol, Ptr<Ipv6Route> route);
   7.840 ++
   7.841 ++  /**
   7.842 ++   * Do nothing
   7.843 ++   */
   7.844 ++  virtual void SendWithHeader (Ptr<Packet> packet, Ipv6Header ipHeader, Ptr<Ipv6Route> route);
   7.845 ++
   7.846 ++  /**
   7.847 ++   * Do nothing
   7.848 ++   */
   7.849 ++  //  virtual void Insert (Ptr<IpL4Protocol> protocol);
   7.850 ++
   7.851 ++  /**
   7.852 ++   * \brief Return the interface number of first interface found that
   7.853 ++   *  has an Ipv6 address within the prefix specified by the input
   7.854 ++   *  address and mask parameters
   7.855 ++   *
   7.856 ++   * \param address The IP address assigned to the interface of interest.
   7.857 ++   * \param mask The IP prefix to use in the mask
   7.858 ++   * \returns The interface number of the Ipv6 interface with the given
   7.859 ++   *          address or -1 if not found.
   7.860 ++   *
   7.861 ++   * Each IP interface has one or more IP addresses associated with it.
   7.862 ++   * This method searches the list of interfaces for the first one found
   7.863 ++   * that holds an address that is included within the prefix
   7.864 ++   * formed by the input address and mask parameters.  The value -1 is
   7.865 ++   * returned if no match is found.
   7.866 ++   */
   7.867 ++  virtual int32_t GetInterfaceForPrefix (Ipv6Address address,
   7.868 ++                                         Ipv6Prefix mask) const;
   7.869 ++
   7.870 ++  /**
   7.871 ++   * \param interface The interface number of an Ipv6 interface.
   7.872 ++   * \returns The NetDevice associated with the Ipv6 interface number.
   7.873 ++   */
   7.874 ++  virtual Ptr<NetDevice> GetNetDevice (uint32_t interface);
   7.875 ++
   7.876 ++  /**
   7.877 ++   * \param device The NetDevice for an Ipv6Interface
   7.878 ++   * \returns The interface number of an Ipv6 interface or -1 if not found.
   7.879 ++   */
   7.880 ++  virtual int32_t GetInterfaceForDevice (Ptr<const NetDevice> device) const;
   7.881 ++
   7.882 ++  /**
   7.883 ++   * \param interface Interface number of an Ipv6 interface
   7.884 ++   * \param address Ipv6InterfaceAddress address to associate with the underlying Ipv6 interface
   7.885 ++   * \returns true if the operation succeeded
   7.886 ++   */
   7.887 ++  virtual bool AddAddress (uint32_t interface, Ipv6InterfaceAddress address);
   7.888 ++
   7.889 ++  /**
   7.890 ++   * \param interface Interface number of an Ipv6 interface
   7.891 ++   * \returns the number of Ipv6InterfaceAddress entries for the interface.
   7.892 ++   */
   7.893 ++  virtual uint32_t GetNAddresses (uint32_t interface) const;
   7.894 ++
   7.895 ++  /**
   7.896 ++   * Because addresses can be removed, the addressIndex is not guaranteed
   7.897 ++   * to be static across calls to this method.
   7.898 ++   *
   7.899 ++   * \param interface Interface number of an Ipv6 interface
   7.900 ++   * \param addressIndex index of Ipv6InterfaceAddress
   7.901 ++   * \returns the Ipv6InterfaceAddress associated to the interface and addressIndex
   7.902 ++   */
   7.903 ++  virtual Ipv6InterfaceAddress GetAddress (uint32_t interface, uint32_t addressIndex) const;
   7.904 ++
   7.905 ++  /**
   7.906 ++   * Remove the address at addressIndex on named interface.  The addressIndex
   7.907 ++   * for all higher indices will decrement by one after this method is called;
   7.908 ++   * so, for example, to remove 5 addresses from an interface i, one could
   7.909 ++   * call RemoveAddress (i, 0); 5 times.
   7.910 ++   *
   7.911 ++   * \param interface Interface number of an Ipv6 interface
   7.912 ++   * \param addressIndex index of Ipv6InterfaceAddress to remove
   7.913 ++   * \returns true if the operation succeeded
   7.914 ++   */
   7.915 ++  virtual bool RemoveAddress (uint32_t interface, uint32_t addressIndex);
   7.916 ++
   7.917 ++  /**
   7.918 ++   * \param interface The interface number of an Ipv6 interface
   7.919 ++   * \param metric routing metric (cost) associated to the underlying
   7.920 ++   *          Ipv6 interface
   7.921 ++   */
   7.922 ++  virtual void SetMetric (uint32_t interface, uint16_t metric);
   7.923 ++
   7.924 ++  /**
   7.925 ++   * \param interface The interface number of an Ipv6 interface
   7.926 ++   * \returns routing metric (cost) associated to the underlying
   7.927 ++   *          Ipv6 interface
   7.928 ++   */
   7.929 ++  virtual uint16_t GetMetric (uint32_t interface) const;
   7.930 ++
   7.931 ++  /**
   7.932 ++   * \param interface Interface number of Ipv6 interface
   7.933 ++   * \returns the Maximum Transmission Unit (in bytes) associated
   7.934 ++   *          to the underlying Ipv6 interface
   7.935 ++   */
   7.936 ++  virtual uint16_t GetMtu (uint32_t interface) const;
   7.937 ++
   7.938 ++  /**
   7.939 ++   * \param interface Interface number of Ipv6 interface
   7.940 ++   * \returns true if the underlying interface is in the "up" state,
   7.941 ++   *          false otherwise.
   7.942 ++   */
   7.943 ++  virtual bool IsUp (uint32_t interface) const;
   7.944 ++
   7.945 ++  /**
   7.946 ++   * \param interface Interface number of Ipv6 interface
   7.947 ++   *
   7.948 ++   * Set the interface into the "up" state. In this state, it is
   7.949 ++   * considered valid during Ipv6 forwarding.
   7.950 ++   */
   7.951 ++  virtual void SetUp (uint32_t interface);
   7.952 ++
   7.953 ++  /**
   7.954 ++   * \param interface Interface number of Ipv6 interface
   7.955 ++   *
   7.956 ++   * Set the interface into the "down" state. In this state, it is
   7.957 ++   * ignored during Ipv6 forwarding.
   7.958 ++   */
   7.959 ++  virtual void SetDown (uint32_t interface);
   7.960 ++
   7.961 ++  /**
   7.962 ++   * \param interface Interface number of Ipv6 interface
   7.963 ++   * \returns true if IP forwarding enabled for input datagrams on this device
   7.964 ++   */
   7.965 ++  virtual bool IsForwarding (uint32_t interface) const;
   7.966 ++
   7.967 ++  /**
   7.968 ++   * \param interface Interface number of Ipv6 interface
   7.969 ++   * \param val Value to set the forwarding flag
   7.970 ++   *
   7.971 ++   * If set to true, IP forwarding is enabled for input datagrams on this device
   7.972 ++   */
   7.973 ++  virtual void SetForwarding (uint32_t interface, bool val);
   7.974 ++
   7.975 ++  /**
   7.976 ++   * Do nothing
   7.977 ++   */
   7.978 ++  //  virtual Ptr<IpL4Protocol> GetProtocol (int protocolNumber) const ;
   7.979 ++
   7.980 ++  /**
   7.981 ++   * Do nothing
   7.982 ++   */
   7.983 ++  virtual Ptr<Socket> CreateRawSocket (void);
   7.984 ++
   7.985 ++  /**
   7.986 ++   * Do nothing
   7.987 ++   */
   7.988 ++  virtual void DeleteRawSocket (Ptr<Socket> socket);
   7.989 ++
   7.990 ++  static void InstallNode (Ptr<Node> node);
   7.991 ++
   7.992 ++  /**
   7.993 ++   * \brief Register the IPv6 Extensions.
   7.994 ++   */
   7.995 ++  virtual void RegisterExtensions ();
   7.996 ++
   7.997 ++  /**
   7.998 ++   * \brief Register the IPv6 Options.
   7.999 ++   */
  7.1000 ++  virtual void RegisterOptions ();
  7.1001 ++
  7.1002 ++private:
  7.1003 ++  // Indirect the Ipv6 attributes through private pure virtual methods
  7.1004 ++  virtual void SetIpForward (bool forward);
  7.1005 ++  virtual bool GetIpForward (void) const;
  7.1006 ++  virtual void SetWeakEsModel (bool model);
  7.1007 ++  virtual bool GetWeakEsModel (void) const;
  7.1008 ++  uint32_t AddIpv6Interface (Ptr<Ipv6Interface> interface);
  7.1009 ++  Ptr<Ipv6Interface> GetInterface (uint32_t i) const;
  7.1010 ++
  7.1011 ++  typedef std::vector<Ptr<Ipv6Interface> > Ipv6InterfaceList;
  7.1012 ++  Ptr<Ipv6RoutingProtocol> m_routingProtocol;
  7.1013 ++  bool m_ipForward;
  7.1014 ++  bool m_weakEsModel;
  7.1015 ++  Ipv6InterfaceList m_interfaces;
  7.1016 ++};
  7.1017 ++}
  7.1018 ++#endif // IPV6_LINUX_H
  7.1019 +diff -r b4f69e2ed0b3 wscript
  7.1020 +--- a/wscript	Thu Dec 13 12:07:18 2012 +0900
  7.1021 ++++ b/wscript	Thu Dec 13 12:27:12 2012 +0900
  7.1022 +@@ -35,7 +35,7 @@
  7.1023 +     ns3waf.check_modules(conf, ['wifi', 'point-to-point', 'csma', 'mobility'], mandatory = False)
  7.1024 +     ns3waf.check_modules(conf, ['point-to-point-layout'], mandatory = False)
  7.1025 +     ns3waf.check_modules(conf, ['mpi'], mandatory = False)
  7.1026 +-    ns3waf.check_modules(conf, ['applications'], mandatory = False)
  7.1027 ++    ns3waf.check_modules(conf, ['applications', 'olsr'], mandatory = False)
  7.1028 +     conf.check_tool('compiler_cc')
  7.1029 +     conf.check(header_name='stdint.h', define_name='HAVE_STDINT_H', mandatory=False)
  7.1030 +     conf.check(header_name='inttypes.h', define_name='HAVE_INTTYPES_H', mandatory=False)
  7.1031 +@@ -281,6 +281,10 @@
  7.1032 +                        target='bin/dce-tcp-ns3-nsc-comparison',
  7.1033 +                        source=['example/dce-tcp-ns3-nsc-comparison.cc'])
  7.1034 + 
  7.1035 ++    module.add_example(needed = ['point-to-point', 'internet', 'olsr', 'applications', 'wifi', 'dce'],
  7.1036 ++                       target='bin/simple-point-to-point-olsr',
  7.1037 ++                       source=['example/simple-point-to-point-olsr.cc'])
  7.1038 ++
  7.1039 + # Add a script to build system 
  7.1040 + def build_a_script(bld, name, needed = [], **kw):
  7.1041 +     external = [i for i in needed if not i == name]
  7.1042 +@@ -395,6 +399,7 @@
  7.1043 +         'model/dce-at.cc',
  7.1044 +         'model/exec-utils.cc',
  7.1045 +         'model/linux/ipv4-linux.cc',
  7.1046 ++        'model/linux/ipv6-linux.cc',
  7.1047 +         'model/dce-vfs.cc',
  7.1048 +         'model/elf-ldd.cc',
  7.1049 +         'model/dce-termio.cc',
  7.1050 +@@ -423,6 +428,7 @@
  7.1051 +         'model/dce-application.h',
  7.1052 +         'model/ipv4-dce-routing.h',
  7.1053 +         'model/linux/ipv4-linux.h',
  7.1054 ++        'model/linux/ipv6-linux.h',
  7.1055 +         'model/process-delay-model.h',
  7.1056 +         'model/linux/linux-socket-impl.h',
  7.1057 +         'model/linux/linux-ipv4-raw-socket-factory.h',
     8.1 --- a/modulize-quagga-mip6.patch	Mon Aug 06 20:45:50 2012 +0900
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,136 +0,0 @@
     8.4 -diff -r 4ab96eb6171d model/linux-socket-fd.cc
     8.5 ---- a/model/linux-socket-fd.cc	Thu Mar 29 13:58:26 2012 +0900
     8.6 -+++ b/model/linux-socket-fd.cc	Fri Apr 06 15:16:09 2012 +0900
     8.7 -@@ -215,4 +215,10 @@
     8.8 -   return m_factory->Poll (m_socket, ptable);
     8.9 - }
    8.10 - 
    8.11 -+int
    8.12 -+LinuxSocketFd::Ftruncate (off_t length)
    8.13 -+{
    8.14 -+  return -1;
    8.15 -+}
    8.16 -+
    8.17 - } // namespace ns3
    8.18 -diff -r 4ab96eb6171d model/linux-socket-fd.h
    8.19 ---- a/model/linux-socket-fd.h	Thu Mar 29 13:58:26 2012 +0900
    8.20 -+++ b/model/linux-socket-fd.h	Fri Apr 06 15:16:09 2012 +0900
    8.21 -@@ -49,6 +49,7 @@
    8.22 -   virtual int Gettime (struct itimerspec *cur_value) const;
    8.23 - 
    8.24 -   virtual bool HangupReceived (void) const;
    8.25 -+  virtual int Ftruncate(off_t);
    8.26 - 
    8.27 -   virtual int Poll (PollTable* ptable);
    8.28 - 
    8.29 -diff -r 4ab96eb6171d model/ns3-socket-fd-factory.cc
    8.30 ---- a/model/ns3-socket-fd-factory.cc	Thu Mar 29 13:58:26 2012 +0900
    8.31 -+++ b/model/ns3-socket-fd-factory.cc	Fri Apr 06 15:16:09 2012 +0900
    8.32 -@@ -140,6 +140,20 @@
    8.33 -           break;
    8.34 -         }
    8.35 -     }
    8.36 -+  else if (domain == PF_INET6)
    8.37 -+    {
    8.38 -+      switch (type) {
    8.39 -+        case SOCK_RAW: {
    8.40 -+        TypeId tid = TypeId::LookupByName ("ns3::Ipv6RawSocketFactory");
    8.41 -+        Ptr<SocketFactory> factory = GetObject<SocketFactory> (tid);
    8.42 -+        sock = factory->CreateSocket ();
    8.43 -+        sock->SetAttribute ("Protocol", UintegerValue (protocol));
    8.44 -+        socket = new UnixDatagramSocketFd (sock);
    8.45 -+          } break;
    8.46 -+      default:
    8.47 -+        break;
    8.48 -+      }
    8.49 -+    }
    8.50 -   else
    8.51 -     {
    8.52 -       //      NS_FATAL_ERROR ("unsupported domain");
    8.53 -diff -r 4ab96eb6171d model/unix-socket-fd.cc
    8.54 ---- a/model/unix-socket-fd.cc	Thu Mar 29 13:58:26 2012 +0900
    8.55 -+++ b/model/unix-socket-fd.cc	Fri Apr 06 15:16:09 2012 +0900
    8.56 -@@ -33,6 +33,7 @@
    8.57 - #include "ns3/boolean.h"
    8.58 - #include "ns3/simulator.h"
    8.59 - #include "ns3/netlink-socket-address.h"
    8.60 -+#include <linux/netlink.h>
    8.61 - #include <fcntl.h>
    8.62 - #include <errno.h>
    8.63 - #include <linux/icmp.h> // need ICMP_FILTER
    8.64 -diff -r 4ab96eb6171d wscript
    8.65 ---- a/wscript	Thu Mar 29 13:58:26 2012 +0900
    8.66 -+++ b/wscript	Fri Apr 06 15:16:09 2012 +0900
    8.67 -@@ -240,17 +240,10 @@
    8.68 -                        target='bin/dce-iperf',
    8.69 -                        source=['example/dce-iperf.cc', 'example/ccnx/misc-tools.cc'])
    8.70 -     
    8.71 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'point-to-point-layout'],
    8.72 --                       target='bin/dce-zebra-simple',
    8.73 --                       source=['example/dce-zebra-simple.cc'])
    8.74 --
    8.75 -     module.add_example(needed = ['core', 'internet', 'dce' ], 
    8.76 -                        target='bin/dce-bash-simple',
    8.77 -                        source=['example/bash/dce-bash-simple.cc'])
    8.78 -                                                 
    8.79 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'applications', 'topology-read', 'visualizer'],
    8.80 --                       target='bin/dce-quagga-ospfd-rocketfuel',
    8.81 --                       source=['example/dce-quagga-ospfd-rocketfuel.cc'])
    8.82 - 
    8.83 - def build_dce_kernel_examples(module):
    8.84 -     module.add_example(needed = ['core', 'network', 'dce'], 
    8.85 -@@ -261,33 +254,6 @@
    8.86 -                        target='bin/dce-linux',
    8.87 -                        source=['example/dce-linux.cc'])
    8.88 - 
    8.89 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point'],
    8.90 --                       target='bin/dce-quagga-ospfd',
    8.91 --                       source=['example/dce-quagga-ospfd.cc'])
    8.92 --
    8.93 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'visualizer', 'topology-read'],
    8.94 --                       target='bin/dce-quagga-bgpd-caida',
    8.95 --                       source=['example/dce-quagga-bgpd-caida.cc'])
    8.96 --
    8.97 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point'],
    8.98 --                       target='bin/dce-quagga-bgpd',
    8.99 --                       source=['example/dce-quagga-bgpd.cc'])
   8.100 --
   8.101 --    module.add_example(needed = ['core', 'internet', 'dce', 'csma', 'mobility', 'wifi', 'visualizer'],
   8.102 --                       target='bin/dce-mip6d',
   8.103 --                       source=['example/dce-mip6d.cc'])
   8.104 --
   8.105 --    module.add_example(needed = ['core', 'internet', 'dce', 'csma', 'mobility', 'wifi', 'visualizer'],
   8.106 --                       target='bin/dce-dsmip6d',
   8.107 --                       source=['example/dce-dsmip6d.cc'])
   8.108 --
   8.109 --    module.add_example(needed = ['core', 'internet', 'dce', 'csma', 'mobility', 'wifi', 'visualizer', 'topology-read'],
   8.110 --                       target='bin/dce-fga',
   8.111 --                       source=['example/dce-fga.cc'])
   8.112 --
   8.113 --    module.add_example(needed = ['core', 'internet', 'dce', 'csma', 'mobility', 'wifi', 'visualizer', 'topology-read'],
   8.114 --                       target='bin/dce-fga-crawdad',
   8.115 --                       source=['example/dce-fga-crawdad.cc'])
   8.116 - 
   8.117 - def build(bld):
   8.118 -     build_netlink(bld)
   8.119 -@@ -374,8 +340,6 @@
   8.120 -         'helper/ipv4-dce-routing-helper.cc',
   8.121 -         'helper/dce-manager-helper.cc',
   8.122 -         'helper/dce-application-helper.cc',
   8.123 --        'helper/quagga-helper.cc',
   8.124 --        'helper/mip6d-helper.cc',
   8.125 -         ]
   8.126 -     module_headers = [
   8.127 -         'model/dce-manager.h',
   8.128 -@@ -385,10 +349,9 @@
   8.129 -         'model/loader-factory.h',
   8.130 -         'model/dce-application.h',
   8.131 -         'model/ipv4-dce-routing.h',
   8.132 -+        'helper/ipv4-dce-routing-helper.h',
   8.133 -         'helper/dce-manager-helper.h',
   8.134 -         'helper/dce-application-helper.h',
   8.135 --        'helper/quagga-helper.h',
   8.136 --        'helper/mip6d-helper.h',
   8.137 -         ]
   8.138 -     module_source = module_source + kernel_source
   8.139 -     module_headers = module_headers + kernel_headers
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/more-test.patch	Thu Jun 20 09:56:26 2013 +0900
     9.3 @@ -0,0 +1,304 @@
     9.4 +diff --git a/example/dce-tcp-ns3-nsc-comparison.cc b/example/dce-tcp-ns3-nsc-comparison.cc
     9.5 +--- a/example/dce-tcp-ns3-nsc-comparison.cc
     9.6 ++++ b/example/dce-tcp-ns3-nsc-comparison.cc
     9.7 +@@ -202,6 +202,16 @@
     9.8 +   // dceManager.RunIp (rights.Get (1), Seconds (0.2), "route add default via 10.2.1.1");
     9.9 +   // dceManager.RunIp (rights.Get (0), Seconds (0.2), "route show");
    9.10 + 
    9.11 ++  // dceManager.RunIp (lefts.Get (0), Seconds (0.2), "route add default via 10.0.0.2");
    9.12 ++  // dceManager.RunIp (lefts.Get (1), Seconds (0.2), "route add default via 10.0.1.2");
    9.13 ++  // dceManager.RunIp (routers.Get (0), Seconds (0.2), "route add 10.2.0.0/16 via 10.1.0.2");
    9.14 ++  // dceManager.RunIp (routers.Get (1), Seconds (0.2), "route add 10.0.0.0/16 via 10.1.0.1");
    9.15 ++  // dceManager.RunIp (routers.Get (1), Seconds (0.2), "route show");
    9.16 ++  // dceManager.RunIp (routers.Get (1), Seconds (0.2), "link set lo up");
    9.17 ++  // dceManager.RunIp (rights.Get (0), Seconds (0.2), "route add 0.0.0.0/0 via 10.2.0.1");
    9.18 ++  // dceManager.RunIp (rights.Get (1), Seconds (0.2), "route add default via 10.2.1.1");
    9.19 ++  // dceManager.RunIp (rights.Get (0), Seconds (0.2), "route show");
    9.20 ++
    9.21 +   ApplicationContainer apps;
    9.22 +   DceApplicationHelper process;
    9.23 + 
    9.24 +diff --git a/example/dce-trinity.cc b/example/dce-trinity.cc
    9.25 +new file mode 100644
    9.26 +--- /dev/null
    9.27 ++++ b/example/dce-trinity.cc
    9.28 +@@ -0,0 +1,99 @@
    9.29 ++#include "ns3/core-module.h"
    9.30 ++#include "ns3/network-module.h"
    9.31 ++#include "ns3/dce-module.h"
    9.32 ++#include "ns3/point-to-point-module.h"
    9.33 ++#include "ns3/csma-module.h"
    9.34 ++#include "ns3/wifi-module.h"
    9.35 ++#include "ns3/mobility-module.h"
    9.36 ++#include "ns3/internet-module.h"
    9.37 ++#include <fstream>
    9.38 ++
    9.39 ++using namespace ns3;
    9.40 ++NS_LOG_COMPONENT_DEFINE ("DceLinux");
    9.41 ++
    9.42 ++static void RunIp (Ptr<Node> node, Time at, std::string str)
    9.43 ++{
    9.44 ++  DceApplicationHelper process;
    9.45 ++  ApplicationContainer apps;
    9.46 ++  process.SetBinary ("ip");
    9.47 ++  process.SetStackSize (1<<16);
    9.48 ++  process.ResetArguments();
    9.49 ++  process.ParseArguments(str.c_str ());
    9.50 ++  apps = process.Install (node);
    9.51 ++  apps.Start (at);
    9.52 ++}
    9.53 ++
    9.54 ++void
    9.55 ++PrintTcpFlags (std::string key, std::string value)
    9.56 ++{
    9.57 ++  NS_LOG_INFO (key << "=" << value);
    9.58 ++}
    9.59 ++
    9.60 ++int main (int argc, char *argv[])
    9.61 ++{
    9.62 ++  CommandLine cmd;
    9.63 ++  char linkType = 'p'; // P2P
    9.64 ++  bool reliable = true;
    9.65 ++
    9.66 ++  cmd.Parse (argc, argv);
    9.67 ++  NodeContainer nodes;
    9.68 ++  nodes.Create (2);
    9.69 ++
    9.70 ++  NetDeviceContainer devices;
    9.71 ++  PointToPointHelper p2p;
    9.72 ++  p2p.SetDeviceAttribute ("DataRate", StringValue ("5Gbps"));
    9.73 ++  p2p.SetChannelAttribute ("Delay", StringValue ("1ms"));
    9.74 ++  devices = p2p.Install (nodes);
    9.75 ++  p2p.EnablePcapAll ("trinity");
    9.76 ++
    9.77 ++  DceManagerHelper processManager;
    9.78 ++  // processManager.SetLoader ("ns3::DlmLoaderFactory");
    9.79 ++  //  processManager.SetLoader ("ns3::CopyLoaderFactory");
    9.80 ++  processManager.SetTaskManagerAttribute ("FiberManagerType",
    9.81 ++                                          StringValue ("UcontextFiberManager"));
    9.82 ++  processManager.SetNetworkStack("ns3::LinuxSocketFdFactory", "Library", StringValue ("liblinux.so"));
    9.83 ++  LinuxStackHelper stack;
    9.84 ++  stack.Install (nodes);
    9.85 ++
    9.86 ++  Ipv4AddressHelper address;
    9.87 ++  address.SetBase ("10.0.0.0", "255.255.255.0");
    9.88 ++  Ipv4InterfaceContainer interfaces = address.Assign (devices);
    9.89 ++
    9.90 ++  processManager.Install (nodes);
    9.91 ++
    9.92 ++
    9.93 ++  for (int n=0; n < 2; n++)
    9.94 ++    {
    9.95 ++      RunIp (nodes.Get (n), Seconds (0.2), "link show");
    9.96 ++      RunIp (nodes.Get (n), Seconds (0.3), "route show table all");
    9.97 ++      RunIp (nodes.Get (n), Seconds (0.4), "addr list");
    9.98 ++    }
    9.99 ++
   9.100 ++  DceApplicationHelper process;
   9.101 ++  ApplicationContainer apps;
   9.102 ++
   9.103 ++  process.SetBinary ("tcp-server");
   9.104 ++  process.ResetArguments ();
   9.105 ++  process.SetStackSize (1<<16);
   9.106 ++  apps = process.Install (nodes.Get (0));
   9.107 ++  apps.Start (Seconds (1.0));
   9.108 ++
   9.109 ++  process.SetBinary ("trinity");
   9.110 ++  process.SetUid (1000);
   9.111 ++  //process.SetBinary ("tcp-client");
   9.112 ++  process.ResetArguments ();
   9.113 ++  //  process.ParseArguments ("-L");
   9.114 ++  //process.ParseArguments ("10.0.0.1");
   9.115 ++  apps = process.Install (nodes.Get (1));
   9.116 ++  apps.Start (Seconds (1.5));
   9.117 ++
   9.118 ++  // print tcp sysctl value
   9.119 ++  LinuxStackHelper::SysctlGet (nodes.Get (0), Seconds (1.0), 
   9.120 ++                               ".net.ipv4.tcp_available_congestion_control", &PrintTcpFlags);
   9.121 ++
   9.122 ++  Simulator::Stop (Seconds (200.0));
   9.123 ++  Simulator::Run ();
   9.124 ++  Simulator::Destroy ();
   9.125 ++
   9.126 ++  return 0;
   9.127 ++}
   9.128 +diff --git a/model/dce-alloc.cc b/model/dce-alloc.cc
   9.129 +--- a/model/dce-alloc.cc
   9.130 ++++ b/model/dce-alloc.cc
   9.131 +@@ -77,3 +77,8 @@
   9.132 + {
   9.133 +   return sysconf (_SC_PAGESIZE);
   9.134 + }
   9.135 ++void *dce_memalign(size_t boundary, size_t size)
   9.136 ++{
   9.137 ++  // XXX
   9.138 ++  return dce_malloc (size);
   9.139 ++}
   9.140 +diff --git a/model/dce-stdlib.h b/model/dce-stdlib.h
   9.141 +--- a/model/dce-stdlib.h
   9.142 ++++ b/model/dce-stdlib.h
   9.143 +@@ -24,6 +24,7 @@
   9.144 + int dce_clearenv (void);
   9.145 + int dce_mkstemp (char *temp);
   9.146 + int dce_rename (const char *oldpath, const char *newpath);
   9.147 ++void *dce_memalign(size_t boundary, size_t size);
   9.148 + 
   9.149 + #ifdef __cplusplus
   9.150 + }
   9.151 +diff --git a/model/libc-dce.cc b/model/libc-dce.cc
   9.152 +--- a/model/libc-dce.cc
   9.153 ++++ b/model/libc-dce.cc
   9.154 +@@ -96,6 +96,10 @@
   9.155 + #include <langinfo.h>
   9.156 + #include <sys/vfs.h>
   9.157 + #include <termio.h>
   9.158 ++#include <sys/ipc.h>
   9.159 ++#include <sys/shm.h>
   9.160 ++#include <malloc.h>
   9.161 ++#include <sys/prctl.h>
   9.162 + 
   9.163 + extern void __cxa_finalize (void *d);
   9.164 + extern int __cxa_atexit (void (*func)(void *), void *arg, void *d);
   9.165 +diff --git a/model/libc-ns3.h b/model/libc-ns3.h
   9.166 +--- a/model/libc-ns3.h
   9.167 ++++ b/model/libc-ns3.h
   9.168 +@@ -104,6 +104,7 @@
   9.169 + DCE (abort)
   9.170 + DCE (mkstemp)
   9.171 + DCE (rename)
   9.172 ++DCE (memalign)
   9.173 + 
   9.174 + // STRING.H
   9.175 + NATIVE (strerror)
   9.176 +@@ -315,6 +316,7 @@
   9.177 + DCE (open)
   9.178 + DCE (open64)
   9.179 + DCE (unlinkat)
   9.180 ++DCE (creat)
   9.181 + 
   9.182 + // TIME.H
   9.183 + DCE (nanosleep)
   9.184 +@@ -546,6 +548,15 @@
   9.185 + DCE (tcgetattr)
   9.186 + DCE (tcsetattr)
   9.187 + 
   9.188 ++/* shm.h */
   9.189 ++NATIVE (shmget)
   9.190 ++NATIVE (shmat)
   9.191 ++NATIVE (shmctl)
   9.192 ++NATIVE (shmdt)
   9.193 ++
   9.194 ++NATIVE (prctl)
   9.195 ++NATIVE (chmod)
   9.196 ++
   9.197 + ///////////////////// END OF INVENTAIRE //////////////////////////////////////////////////
   9.198 + 
   9.199 + // ctype.h
   9.200 +diff --git a/utils/run-all-test-coverage.sh b/utils/run-all-test-coverage.sh
   9.201 +--- a/utils/run-all-test-coverage.sh
   9.202 ++++ b/utils/run-all-test-coverage.sh
   9.203 +@@ -1,27 +1,68 @@
   9.204 + #!/bin/bash
   9.205 +-set -x
   9.206 ++#set -x
   9.207 + 
   9.208 +-export NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::DlmLoaderFactory[];ns3::TaskManager::FiberManagerType=UcontextFiberManager'
   9.209 + 
   9.210 +-../build/bin/ns3test-dce-vdl
   9.211 +-./build/bin/dce-runner ../build/bin/dce-dccp
   9.212 +-./build/bin/dce-runner ../build/bin/dce-iperf --kernel=1
   9.213 +-../build/bin/ns3test-dce-quagga-vdl |& grep -v sockopt
   9.214 +-./build/bin/dce-runner ../build/bin/dce-quagga-radvd
   9.215 +-./build/bin/dce-runner ../build/bin/dce-quagga-bgpd
   9.216 +-./build/bin/dce-runner ../build/bin/dce-quagga-ospfd --netStack=linux 
   9.217 +-./build/bin/dce-runner ../build/bin/dce-quagga-ospf6d --netStack=linux 
   9.218 +-#./build/bin/dce-runner ../build/bin/dce-quagga-ospfd-rocketfuel --netStack=linux  
   9.219 +-./build/bin/dce-runner ../build/bin/dce-quagga-ripd
   9.220 +-./build/bin/dce-runner ../build/bin/dce-quagga-ripngd
   9.221 +-./build/bin/dce-runner ../build/bin/dce-umip-cmip6
   9.222 +-./build/bin/dce-runner ../build/bin/dce-umip-nemo |& grep -v bytes
   9.223 +-../build/bin/ns3test-dce-umip-vdl
   9.224 +-./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=icmp
   9.225 +-./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=udp
   9.226 +-./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=tcp
   9.227 +-./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=dccp
   9.228 +-./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=dccp -ccid=3
   9.229 +-./build/bin/dce-runner ../build/bin/dce-tcp-ns3-nsc-comparison --stack=dce
   9.230 ++echo ${NS_ATTRIBUTE_DEFAULT}
   9.231 + 
   9.232 + 
   9.233 ++run_test() {
   9.234 ++
   9.235 ++$2 >& /dev/null
   9.236 ++case "$?" in
   9.237 ++0)
   9.238 ++    echo $1 " PASS " $2
   9.239 ++    ;;
   9.240 ++1)
   9.241 ++    echo $1 " FAIL " $2
   9.242 ++    ;;
   9.243 ++*)
   9.244 ++    echo $1 " CRASH " $2
   9.245 ++    ;;
   9.246 ++esac
   9.247 ++
   9.248 ++}
   9.249 ++
   9.250 ++SEED=`seq 1 10 100`
   9.251 ++SEED=`seq 1 10 30`
   9.252 ++RUNS=`seq 1 1 5`
   9.253 ++ERROR_RATES=`seq 0.0 0.0001 0.0005`
   9.254 ++
   9.255 ++for seed in ${SEED}
   9.256 ++do
   9.257 ++for run in ${RUNS}
   9.258 ++do
   9.259 ++for err in ${ERROR_RATES}
   9.260 ++do
   9.261 ++
   9.262 ++export NS_ATTRIBUTE_DEFAULT='ns3::DceManagerHelper::LoaderFactory=ns3::DlmLoaderFactory[];ns3::TaskManager::FiberManagerType=UcontextFiberManager;ns3::LinuxSocketFdFactory::ErrorRate='$err';'
   9.263 ++echo $NS_ATTRIBUTE_DEFAULT
   9.264 ++export NS_GLOBAL_VALUE='RngSeed=$seed:RngRun=$run'
   9.265 ++echo $NS_GLOBAL_VALUE
   9.266 ++echo "RndSeed=$seed, RngRun=$run, ErrRatio=$err"
   9.267 ++
   9.268 ++run_test "DCE"  "../build/bin/ns3test-dce-vdl"
   9.269 ++run_test "DCCP" "./build/bin/dce-runner ../build/bin/dce-dccp"
   9.270 ++run_test "iperf" "./build/bin/dce-runner ../build/bin/dce-iperf --kernel=1"
   9.271 ++run_test "quagga" "../build/bin/ns3test-dce-quagga-vdl"
   9.272 ++run_test "radvd" "./build/bin/dce-runner ../build/bin/dce-quagga-radvd"
   9.273 ++run_test "bgpd" "./build/bin/dce-runner ../build/bin/dce-quagga-bgpd"
   9.274 ++run_test "ospfd" "./build/bin/dce-runner ../build/bin/dce-quagga-ospfd --netStack=linux"
   9.275 ++run_test "ospf6d" "./build/bin/dce-runner ../build/bin/dce-quagga-ospf6d --netStack=linux" 
   9.276 ++#run_test "Test1" "./build/bin/dce-runner ../build/bin/dce-quagga-ospfd-rocketfuel --netStack=linux"
   9.277 ++run_test "ripd" "./build/bin/dce-runner ../build/bin/dce-quagga-ripd"
   9.278 ++run_test "ripngd" "./build/bin/dce-runner ../build/bin/dce-quagga-ripngd"
   9.279 ++run_test "cmip6" "./build/bin/dce-runner ../build/bin/dce-umip-cmip6"
   9.280 ++run_test "nemo" "./build/bin/dce-runner ../build/bin/dce-umip-nemo"
   9.281 ++run_test "umip" "../build/bin/ns3test-dce-umip-vdl"
   9.282 ++run_test "icmp" "./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=icmp"
   9.283 ++run_test "udp" "./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=udp"
   9.284 ++run_test "tcp" "./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=tcp"
   9.285 ++run_test "dccp" "./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=dccp"
   9.286 ++run_test "dccp ccid=3" "./build/bin/dce-runner ../build/bin/dce-ns3-onoff --rate=10kbps --proto=dccp -ccid=3"
   9.287 ++run_test "dumbbel" "./build/bin/dce-runner ../build/bin/dce-tcp-ns3-nsc-comparison --stack=dce"
   9.288 ++run_test "fuzzer" "./build/bin/dce-runner ./build/bin/dce-trinity"
   9.289 ++
   9.290 ++
   9.291 ++done
   9.292 ++done
   9.293 ++done
   9.294 +diff --git a/wscript b/wscript
   9.295 +--- a/wscript
   9.296 ++++ b/wscript
   9.297 +@@ -342,6 +342,10 @@
   9.298 +                        target='bin/dce-tcp-ns3-nsc-comparison',
   9.299 +                        source=['example/dce-tcp-ns3-nsc-comparison.cc'])
   9.300 + 
   9.301 ++    module.add_example(needed = ['core', 'network', 'dce', 'wifi', 'point-to-point', 'csma', 'mobility' ],
   9.302 ++                       target='bin/dce-trinity',
   9.303 ++                       source=['example/dce-trinity.cc'])
   9.304 ++
   9.305 + # Add a script to build system 
   9.306 + def build_a_script(bld, name, needed = [], **kw):
   9.307 +     external = [i for i in needed if not i == name]
    10.1 --- a/mpitest.patch	Mon Aug 06 20:45:50 2012 +0900
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,87 +0,0 @@
    10.4 -diff -r fc08a4cc768f example/dce-quagga-ospfd-rocketfuel.cc
    10.5 ---- a/example/dce-quagga-ospfd-rocketfuel.cc	Thu Mar 29 13:55:22 2012 +0900
    10.6 -+++ b/example/dce-quagga-ospfd-rocketfuel.cc	Thu Mar 29 13:55:54 2012 +0900
    10.7 -@@ -13,15 +13,18 @@
    10.8 - 
    10.9 - #include <sys/resource.h>
   10.10 - 
   10.11 -+#define NS3_OPENMPI
   10.12 -+#define NS3_MPI
   10.13 - #ifdef NS3_MPI
   10.14 - #include <mpi.h>
   10.15 -+#include "ns3/mpi-interface.h"
   10.16 - #endif
   10.17 - using namespace ns3;
   10.18 - 
   10.19 - NS_LOG_COMPONENT_DEFINE ("quagga-ospfd-rocketfuel");
   10.20 - 
   10.21 - // Parameters
   10.22 --uint32_t stopTime = 60;
   10.23 -+uint32_t stopTime = 3600;
   10.24 - 
   10.25 - static void
   10.26 - SetRlimit ()
   10.27 -@@ -148,7 +151,7 @@
   10.28 -       p2p.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
   10.29 -       ndc[i] = p2p.Install (nc[i]);
   10.30 -     }
   10.31 --  //  p2p.EnablePcapAll ("quagga-rocketfuel");
   10.32 -+//  p2p.EnablePcapAll ("quagga-rocketfuel");
   10.33 - 
   10.34 -   NS_LOG_INFO ("creating ipv4 interfaces");
   10.35 -   Ipv4InterfaceContainer ipic[totlinks];
   10.36 -@@ -166,6 +169,7 @@
   10.37 -   NS_LOG_INFO ("creating quagga process");
   10.38 -   //run quagga programs in every node
   10.39 -   DceManagerHelper processManager;
   10.40 -+  processManager.SetLoader ("ns3::DlmLoaderFactory");
   10.41 -   QuaggaHelper quagga;
   10.42 - 
   10.43 -   // 
   10.44 -@@ -195,6 +199,7 @@
   10.45 -           //     std::cout << "[" << systemId << "] start quagga Node " << i << std::endl;
   10.46 -           processManager.Install (nodes.Get (i));
   10.47 -           quagga.EnableOspf (nodes.Get (i));
   10.48 -+          quagga.EnableOspfDebug (nodes.Get (i));
   10.49 -           quagga.Install (nodes.Get (i));
   10.50 -         }
   10.51 -     }
   10.52 -diff -r fc08a4cc768f helper/quagga-helper.cc
   10.53 ---- a/helper/quagga-helper.cc	Thu Mar 29 13:55:22 2012 +0900
   10.54 -+++ b/helper/quagga-helper.cc	Thu Mar 29 13:55:54 2012 +0900
   10.55 -@@ -829,9 +829,9 @@
   10.56 - 
   10.57 -       process.SetBinary ("ospfd");
   10.58 -       process.AddArguments ("-f", ospf_conf->GetFilename ());
   10.59 --      process.AddArguments ("-i", "/usr/local/etc/ospfd.pid");
   10.60 -+//      process.AddArguments ("-i", "/usr/local/etc/ospfd.pid");
   10.61 -       apps.Add (process.Install (node));
   10.62 --      apps.Get(1)->SetStartTime (Seconds (2.0 + 0.1 * node->GetId ()));
   10.63 -+      apps.Get(1)->SetStartTime (Seconds (20.0 + 0.1 * node->GetId ()));
   10.64 -       node->AddApplication (apps.Get (1));
   10.65 -     }
   10.66 - 
   10.67 -diff -r fc08a4cc768f utils/setenv.zsh
   10.68 ---- a/utils/setenv.zsh	Thu Mar 29 13:55:22 2012 +0900
   10.69 -+++ b/utils/setenv.zsh	Thu Mar 29 13:55:54 2012 +0900
   10.70 -@@ -3,7 +3,7 @@
   10.71 - # Set environnement for ns3 dce
   10.72 - cd `dirname ${BASH_SOURCE:-$0}`/../..
   10.73 - BASE=$PWD
   10.74 --LD_LIBRARY_PATH="$BASE/ns-3-dce/build/lib:$BASE/build/lib:$BASE/build/bin:$BASE/ns-3-dce/build/bin:."
   10.75 -+LD_LIBRARY_PATH="$BASE/ns-3-dce/build/lib:$BASE/build/lib:$BASE/build/bin:$BASE/ns-3-dce/build/bin:.:/usr/local/mpi/gcc/openmpi-1.4.3/lib/"
   10.76 - PKG_CONFIG_PATH="$BASE/build/lib/pkgconfig"
   10.77 - PATH="$BASE/build/bin:$BASE/build/sbin:/home/tazaki/hgworks/ns-3-dce-thehajime/build/bin:/home/tazaki/hgworks/ns-3-dce-thehajime/build/sbin:$PATH"
   10.78 - PYTHONPATH=$BASE/ns-3-dev/build/debug/bindings/python:$BASE/ns-3-dev/src/visualizer:$BASE/pybindgen-0.15.0.795:$BASE/build/lib/python2.6/site-packages/
   10.79 -diff -r fc08a4cc768f wscript
   10.80 ---- a/wscript	Thu Mar 29 13:55:22 2012 +0900
   10.81 -+++ b/wscript	Thu Mar 29 13:55:54 2012 +0900
   10.82 -@@ -248,7 +248,7 @@
   10.83 -                        target='bin/dce-bash-simple',
   10.84 -                        source=['example/bash/dce-bash-simple.cc'])
   10.85 -                                                 
   10.86 --    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'applications', 'topology-read'],
   10.87 -+    module.add_example(needed = ['core', 'internet', 'dce', 'point-to-point', 'applications', 'topology-read', 'visualizer'],
   10.88 -                        target='bin/dce-quagga-ospfd-rocketfuel',
   10.89 -                        source=['example/dce-quagga-ospfd-rocketfuel.cc'])
   10.90 - 
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/new-tutorial.patch	Thu Jun 20 09:56:26 2013 +0900
    11.3 @@ -0,0 +1,462 @@
    11.4 +diff -r 096bb07cdd73 doc/source/index.rst
    11.5 +--- a/doc/source/index.rst	Tue Sep 25 14:07:05 2012 +0900
    11.6 ++++ b/doc/source/index.rst	Tue Sep 25 18:34:48 2012 +0900
    11.7 +@@ -14,4 +14,5 @@
    11.8 +    getting-started
    11.9 +    how-it-works
   11.10 +    dce-readme
   11.11 ++   tutorial
   11.12 +     
   11.13 +diff -r 096bb07cdd73 doc/source/tutorial/index.rst
   11.14 +--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
   11.15 ++++ b/doc/source/tutorial/index.rst	Tue Sep 25 18:34:48 2012 +0900
   11.16 +@@ -0,0 +1,449 @@
   11.17 ++.. only:: html or latex
   11.18 ++ns-3 DCE Tutorial
   11.19 ++=================
   11.20 ++
   11.21 ++This is the *ns-3 DCE (Direct Code Execution) Tutorial*. 
   11.22 ++
   11.23 ++Introduction
   11.24 ++------------
   11.25 ++Direct Code Execution (DCE) is ...
   11.26 ++
   11.27 ++
   11.28 ++Contributing
   11.29 ++************
   11.30 ++How to contribute to DCE development?
   11.31 ++
   11.32 ++Tutorial Organization
   11.33 ++*********************
   11.34 ++
   11.35 ++The tutorial assumes that new users might initially follow a path such as the
   11.36 ++following:
   11.37 ++
   11.38 ++* Try to download and build a copy;
   11.39 ++* Try to run a few sample programs;
   11.40 ++* Look at simulation output, and try to adjust it.
   11.41 ++* Try to employ your own application as a simulation model.
   11.42 ++* Then, debugging if the simulation fails.
   11.43 ++
   11.44 ++As a result, we have tried to organize the tutorial along the above
   11.45 ++broad sequences of events.
   11.46 ++
   11.47 ++
   11.48 ++Getting Started
   11.49 ++---------------
   11.50 ++Downloading ns-3-dce
   11.51 ++********************
   11.52 ++::
   11.53 ++
   11.54 ++  $ mkdir test_build_ns3_dce
   11.55 ++  $ cd test_build_ns3_dce
   11.56 ++  $ hg clone http://code.nsnam.org/furbani/ns-3-dce 
   11.57 ++
   11.58 ++
   11.59 ++Building options
   11.60 ++****************
   11.61 ++
   11.62 ++DCE offers two major modes of operation:
   11.63 ++ 1. The basic mode, where DCE use the NS3 TCP stacks,
   11.64 ++ 2. The advanced mode, where DCE uses a linux network stack instead.
   11.65 ++
   11.66 ++Building and Testing ns-3-dce
   11.67 ++*****************************
   11.68 ++Then you can build the DCE and related/required codes and libraries:
   11.69 ++
   11.70 ++::
   11.71 ++
   11.72 ++  $ ns-3-dce/utils/clone_and_compile_ns3_dce.sh
   11.73 ++
   11.74 ++if you're going to use linux kernel (i.e., advanced mode), '-k' option will bring you all builds and tests.
   11.75 ++
   11.76 ++::
   11.77 ++
   11.78 ++  $ ns-3-dce/utils/clone_and_compile_ns3_dce.sh -k
   11.79 ++
   11.80 ++Once the building starts, the following outputs will be shown.
   11.81 ++
   11.82 ++::
   11.83 ++
   11.84 ++  $ ns-3-dce/utils/clone_and_compile_ns3_dce.sh
   11.85 ++  clone readversiondef
   11.86 ++  ...
   11.87 ++  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   11.88 ++  ...
   11.89 ++  Launch NS3TEST-DCE
   11.90 ++  PASS process-manager 16.030ms
   11.91 ++    PASS Check that process "test-empty" completes correctly. 1.220ms
   11.92 ++    PASS Check that process "test-sleep" completes correctly. 0.030ms
   11.93 ++    PASS Check that process "test-pthread" completes correctly. 0.020ms
   11.94 ++    PASS Check that process "test-mutex" completes correctly. 0.110ms
   11.95 ++    PASS Check that process "test-once" completes correctly. 0.030ms
   11.96 ++    PASS Check that process "test-pthread-key" completes correctly. 0.020ms
   11.97 ++    PASS Check that process "test-sem" completes correctly. 0.040ms
   11.98 ++    PASS Check that process "test-malloc" completes correctly. 0.030ms
   11.99 ++    PASS Check that process "test-malloc-2" completes correctly. 0.020ms
  11.100 ++    PASS Check that process "test-fd-simple" completes correctly. 0.030ms
  11.101 ++    PASS Check that process "test-strerror" completes correctly. 0.030ms
  11.102 ++    PASS Check that process "test-stdio" completes correctly. 0.030ms
  11.103 ++    PASS Check that process "test-string" completes correctly. 0.030ms
  11.104 ++    PASS Check that process "test-netdb" completes correctly. 0.220ms
  11.105 ++    PASS Check that process "test-env" completes correctly. 0.030ms
  11.106 ++    PASS Check that process "test-cond" completes correctly. 0.100ms
  11.107 ++    PASS Check that process "test-timer-fd" completes correctly. 0.030ms
  11.108 ++    PASS Check that process "test-stdlib" completes correctly. 0.030ms
  11.109 ++    PASS Check that process "test-select" completes correctly. 0.080ms
  11.110 ++    PASS Check that process "test-nanosleep" completes correctly. 0.030ms
  11.111 ++    PASS Check that process "test-random" completes correctly. 0.030ms
  11.112 ++    PASS Check that process "test-fork" completes correctly. 0.030ms
  11.113 ++    PASS Check that process "test-local-socket" completes correctly. 12.840ms
  11.114 ++    PASS Check that process "test-poll" completes correctly. 0.090ms
  11.115 ++    PASS Check that process "test-tcp-socket" completes correctly. 0.880ms
  11.116 ++
  11.117 ++
  11.118 ++\# The script includes the test for DCE.
  11.119 ++
  11.120 ++DCE is compiled after a few minutes and if the tests completed successfully, you should see the directories:
  11.121 ++
  11.122 ++::
  11.123 ++
  11.124 ++  $ ls
  11.125 ++  build  ns-3-dev  ns-3-dce  readversiondef ns-3-linux iproute2-2.6.33
  11.126 ++
  11.127 ++Where:
  11.128 ++ 1. *build* contains the result of compilation: some binaries some libs and some include files usable to do your simulations scripts.
  11.129 ++
  11.130 ++ 2. *ns-3-dev* contains the current sources of NS3, 
  11.131 ++
  11.132 ++ 3. *ns-3-dce* contains the DCE sources,
  11.133 ++
  11.134 ++ 4. *readversiondef* contains source of a tool used by DCE build system. 
  11.135 ++
  11.136 ++ 5. *ns-3-linux* (only in advanced mode) contains source of a linux kernel + some glue code for DCE / Kernel communication.
  11.137 ++
  11.138 ++ 6. *iproute2-2.6.33* (only in advanced mode) contains source of *ip* tool needed to be compiled for DCE in order to configure ip routes of the slave kernel used by DCE.
  11.139 ++
  11.140 ++Running Examples
  11.141 ++****************
  11.142 ++Unlike usual ns-3, DCE is currently not integrated with 'waf' command to execute simulation scripts. You need to run your script by executing the binary of the program with appropriately configured ENVIRONMENT variables (i.e., PATH, LD_LIBRARY_PATH and PKG_CONFIG_PATH).
  11.143 ++
  11.144 ++::
  11.145 ++
  11.146 ++  $ source ns-3-dce/utils/setenv.sh
  11.147 ++
  11.148 ++then you can execute the simulation script:
  11.149 ++
  11.150 ++::
  11.151 ++  $ dce-udp-simple
  11.152 ++
  11.153 ++
  11.154 ++Example: DCE UDP EXAMPLE
  11.155 ++########################
  11.156 ++
  11.157 ++This example execute the binaries named udp-client and udp-server under NS3 using DCE.
  11.158 ++
  11.159 ++These 2 binaries are writen using libc api in order to send and receive udp packets.
  11.160 ++
  11.161 ++Please take time to look at the source dce-udp-simple.cc which is our NS3 simulation "script":
  11.162 ++
  11.163 ++::
  11.164 ++
  11.165 ++  int main (int argc, char *argv[])
  11.166 ++  {
  11.167 ++    CommandLine cmd;
  11.168 ++    cmd.Parse (argc, argv);
  11.169 ++  
  11.170 ++    NodeContainer nodes;
  11.171 ++    nodes.Create (1);
  11.172 ++  
  11.173 ++    InternetStackHelper stack;
  11.174 ++    stack.Install (nodes);
  11.175 ++  
  11.176 ++    DceManagerHelper dceManager;
  11.177 ++    dceManager.Install (nodes);
  11.178 ++  
  11.179 ++    DceApplicationHelper dce;
  11.180 ++    ApplicationContainer apps;
  11.181 ++  
  11.182 ++    dce.SetStackSize (1<<20);
  11.183 ++  
  11.184 ++    dce.SetBinary ("udp-server");
  11.185 ++    dce.ResetArguments();
  11.186 ++    apps = dce.Install (nodes.Get (0));
  11.187 ++    apps.Start (Seconds (4.0));
  11.188 ++  
  11.189 ++    dce.SetBinary ("udp-client");
  11.190 ++    dce.ResetArguments();
  11.191 ++    dce.AddArgument ("127.0.0.1");
  11.192 ++    apps = dce.Install (nodes.Get (0));
  11.193 ++    apps.Start (Seconds (4.5));
  11.194 ++  
  11.195 ++    Simulator::Stop (Seconds(1000100.0));
  11.196 ++    Simulator::Run ();
  11.197 ++    Simulator::Destroy ();
  11.198 ++  
  11.199 ++    return 0;
  11.200 ++  }
  11.201 ++  
  11.202 ++You can notice that we create a NS-3 Node with an Internet Stack (please refer to `NS-3 <http://www.nsnam.org/documentation/>`_ doc. for more info),
  11.203 ++and we can also see 2 new Helpers:
  11.204 ++
  11.205 ++ 1. DceManagerHelper which is used to Manage DCE loading system in each node where DCE will be used.
  11.206 ++ 2. DceApplicationHelper which is used to describe real application to be lauched by DCE within NS-3 simulation environnement.
  11.207 ++ 
  11.208 ++As you have already set the environnement variables you can launch this simulation from anywhere:
  11.209 ++
  11.210 ++::
  11.211 ++
  11.212 ++  $ cd /tmp
  11.213 ++  $ mkdir my_test
  11.214 ++  $ cd my_test
  11.215 ++  $ dce-udp-simple
  11.216 ++  $ ls 
  11.217 ++    elf-cache  files-0
  11.218 ++  $ ls -lR files-0
  11.219 ++    files-0:
  11.220 ++    total 4
  11.221 ++    drwxr-x--- 3 furbani planete 4096 Sep  2 17:02 var
  11.222 ++
  11.223 ++    files-0/var:
  11.224 ++    total 4
  11.225 ++    drwxr-x--- 4 furbani planete 4096 Sep  2 17:02 log
  11.226 ++
  11.227 ++    files-0/var/log:
  11.228 ++    total 8
  11.229 ++    drwxr-x--- 2 furbani planete 4096 Sep  2 17:02 53512
  11.230 ++    drwxr-x--- 2 furbani planete 4096 Sep  2 17:02 53513
  11.231 ++
  11.232 ++    files-0/var/log/53512:
  11.233 ++    total 12
  11.234 ++    -rw------- 1 furbani planete  12 Sep  2 17:02 cmdline
  11.235 ++    -rw------- 1 furbani planete 185 Sep  2 17:02 status
  11.236 ++    -rw------- 1 furbani planete   0 Sep  2 17:02 stderr
  11.237 ++    -rw------- 1 furbani planete  21 Sep  2 17:02 stdout
  11.238 ++
  11.239 ++    files-0/var/log/53513:
  11.240 ++    total 12
  11.241 ++    -rw------- 1 furbani planete  22 Sep  2 17:02 cmdline
  11.242 ++    -rw------- 1 furbani planete 185 Sep  2 17:02 status
  11.243 ++    -rw------- 1 furbani planete   0 Sep  2 17:02 stderr
  11.244 ++    -rw------- 1 furbani planete  22 Sep  2 17:02 stdout
  11.245 ++
  11.246 ++This simulation produces two directories, the content of elf-cache is not important now for us, but files-0 is.
  11.247 ++files-0 contains first node's file system, it also contains the output files of the dce applications launched on this node. In the /var/log directory there is some directories named with the virtual pid of corresponding DCE applications. Under these directories there is always 4 files:
  11.248 ++
  11.249 ++1. cmdline: which contains the command line of the corresponding DCE application, in order to help you to retrieve what is it,
  11.250 ++2. stdout: contains the stdout produced by the execution of the corresponding application,
  11.251 ++3. stderr: contains the stderr produced by the execution of the corresponding application.
  11.252 ++4. status: contains a status of the corresponding process with its start time. This file also contains the end time and exit code if applicable.
  11.253 ++              
  11.254 ++Before launching a simulation, you may also create files-xx directories and provide files required by the applications to be executed correctly.
  11.255 ++
  11.256 ++DCE LINUX Example
  11.257 ++#################
  11.258 ++
  11.259 ++This example shows how to use DCE in advanced mode, with a linux kernel IP stack.
  11.260 ++It uses also the binaries *udp-server* and *udp-client* like the above example, there is also *tcp-server* and *tcp-client* if you choose the reliable transport option.
  11.261 ++Two other binaries are needed: the linux kernel stack named *libnet-next-2.6.so* and the tool needed to configure this kernel stack named *ip*.
  11.262 ++This example simulates an exchange of data between too nodes, using TCP or UDP, and the nodes are linked by one of three possible links , Wifi, Point 2 point or CSMA.
  11.263 ++The main executable is named *dce-linux*, it cames with too options:
  11.264 ++
  11.265 ++1. linkType allow to choose the link type between c, w or p for Csma, Wifi or Point 2 point,
  11.266 ++2. reliable allow to choose transport between TCP (1) or UDP (0).
  11.267 ++
  11.268 ++The following code snippet show how to enable DCE advanced mode (you can see it in the source file dce-linux.cc under example directory):
  11.269 ++
  11.270 ++::
  11.271 ++
  11.272 ++  DceManagerHelper processManager;
  11.273 ++  processManager.SetNetworkStack("ns3::LinuxSocketFdFactory", "Library", StringValue ("libnet-next-2.6.so"));
  11.274 ++  processManager.Install (nodes);
  11.275 ++
  11.276 ++  for (int n=0; n < 2; n++)
  11.277 ++    {
  11.278 ++      AddAddress (nodes.Get (n), Seconds (0.1), "sim0", "10.0.0.", 2 + n, "/8" );
  11.279 ++      RunIp (nodes.Get (n), Seconds (0.11), ( 'p' == linkType )? "link set sim0 up arp off":"link set sim0 up arp on");
  11.280 ++      RunIp (nodes.Get (n), Seconds (0.2), "link show");
  11.281 ++      RunIp (nodes.Get (n), Seconds (0.3), "route show table all");
  11.282 ++      RunIp (nodes.Get (n), Seconds (0.4), "addr list");
  11.283 ++    }
  11.284 ++
  11.285 ++The first important call is *SetNetworkStack* used to indicate which file contains the linux kernel stack.
  11.286 ++Then in the for loop we setup on each nodes the network interfaces using the ip executable to configure the kernel stack.
  11.287 ++Because this source code factorizes some call, it is not very readeable so below there is the corresponding calls to ip executable with the arguments:
  11.288 ++
  11.289 ++::
  11.290 ++
  11.291 ++   ip -f inet addr add 10.0.0.2 dev sim0        // set the ip adresse of the first (sim0) net device of the corresponding node
  11.292 ++   ip link set sim0 up arp on                   // enable the use of the device use arp off instead for P2P link
  11.293 ++   ip link show
  11.294 ++   ip route show table all
  11.295 ++   ip addr list
  11.296 ++
  11.297 ++
  11.298 ++Employing Your Own Applications
  11.299 ++-------------------------------
  11.300 ++The next tutorial presents how to execute your applications in ns-3 via DCE. We use 'ping' command as an example of this section. The example is included in the code repository under 'myscripts/ping/' directory.
  11.301 ++
  11.302 ++Rebuild the application as a special binary file
  11.303 ++************************************************
  11.304 ++DCE requires the special build, Position Independent Executable (PIE), for the loading binary in the ns-3 simulation.
  11.305 ++
  11.306 ++Let's start building a custom 'ping' command binary.
  11.307 ++
  11.308 ++First of all, we need to download the source code as follows (note: this information is validated at 25th September, 2012).
  11.309 ++
  11.310 ++::
  11.311 ++
  11.312 ++ $ wget http://www.skbuff.net/iputils/iputils-s20101006.tar.bz2
  11.313 ++
  11.314 ++then extract the file.
  11.315 ++
  11.316 ++::
  11.317 ++
  11.318 ++ $ tar xfj iputils-s20101006.tar.bz2
  11.319 ++ $ cd iputils-s20101006
  11.320 ++
  11.321 ++Then, build 'ping' command with specific compiler/linker options:
  11.322 ++
  11.323 ++::
  11.324 ++
  11.325 ++  $ sed "s/CFLAGS+=/CFLAGS=/" Makefile > a
  11.326 ++  $ mv a Makefile
  11.327 ++  $ make CFLAGS=-fPIC LDFLAGS=-pie ping
  11.328 ++
  11.329 ++where the line 1 and 2 replace the Makefile in order to override the variable.
  11.330 ++
  11.331 ++Now you will have a self-build 'ping' command.
  11.332 ++
  11.333 ++::
  11.334 ++
  11.335 ++  $ ls -l ping
  11.336 ++  -rwxr-xr-x 1 tazaki 56773 2012-09-25 17:40 ping*
  11.337 ++
  11.338 ++You can verify whether the compiler and linker option was appropriately specified by the following command (readelf tells you).
  11.339 ++
  11.340 ++::
  11.341 ++
  11.342 ++  $ readelf -h ping |grep Type
  11.343 ++  Type:                              DYN (Shared object file)
  11.344 ++
  11.345 ++**DYN** indicates the binary file has compiled and linked as position independent code.
  11.346 ++
  11.347 ++
  11.348 ++It's ready to put your custom file at the directory in DCE_PATH variable. If you've already set the environment variable (e.g., by setenv.sh), then you can copy the 'ping' file to the directory.
  11.349 ++
  11.350 ++::
  11.351 ++
  11.352 ++  $ echo $DCE_PATH
  11.353 ++  /where/is/ns-3-dce/build/bin_dce:/where/is/ns-3-dce/build/bin:/where/is/ns-3-dce/../build/bin
  11.354 ++  $ cp ping /where/is/ns-3-dce/build/bin_dce
  11.355 ++
  11.356 ++
  11.357 ++That's it!
  11.358 ++
  11.359 ++
  11.360 ++Writing the simulation script
  11.361 ++*****************************
  11.362 ++The next step to play your code with DCE is 'preparing the script'. You will find the example in 'myscripts/ping/dce-ping.cc'.
  11.363 ++
  11.364 ++The file contains the complete showcase to use 'ping' command in the ns-3 simulation, the fundamental part of using the binary is showing in the followings:
  11.365 ++
  11.366 ++::
  11.367 ++
  11.368 ++      dce.SetBinary ("ping");
  11.369 ++      dce.ResetArguments();
  11.370 ++      dce.ResetEnvironment();
  11.371 ++      dce.AddArgument ("-c 10");
  11.372 ++      dce.AddArgument ("-s 1000");
  11.373 ++      dce.AddArgument ("10.1.1.2");
  11.374 ++
  11.375 ++where *SetBinary* indicates the name of the binary loaded into the simulation, and *AddArgument* indicates the command line arguments to execute the command.
  11.376 ++
  11.377 ++Then you will need to build this script. The 'wscript' is used to define how to build as follows and put it in the specific directory.
  11.378 ++
  11.379 ++::
  11.380 ++
  11.381 ++  import ns3waf
  11.382 ++  import os
  11.383 ++  
  11.384 ++  def configure(conf):
  11.385 ++      ns3waf.check_modules(conf, ['core', 'internet', 'point-to-point', 'netanim'], mandatory = True)
  11.386 ++  
  11.387 ++  def build(bld):
  11.388 ++      bld.build_a_script('dce', needed = ['core', 'internet', 'dce', 'point-to-point', 'netanim' ],
  11.389 ++  				  target='bin/dce-ping',
  11.390 ++  				  source=['dce-ping.cc', 'misc-tools.cc'],
  11.391 ++  				  )
  11.392 ++
  11.393 ++The files are located like following, 
  11.394 ++
  11.395 ++::
  11.396 ++
  11.397 ++  $ ls myscripts/ping 
  11.398 ++  dce-ping.cc  misc-tools.cc  misc-tools.h  wscript
  11.399 ++
  11.400 ++then built it.
  11.401 ++
  11.402 ++::
  11.403 ++
  11.404 ++  $ ./waf configure
  11.405 ++  $ ./waf
  11.406 ++
  11.407 ++Now it's ready to do the simulation.
  11.408 ++
  11.409 ++::
  11.410 ++
  11.411 ++  $ dce-ping
  11.412 ++
  11.413 ++You can take a look the stdout of the ping command.
  11.414 ++
  11.415 ++::
  11.416 ++
  11.417 ++  $ cat files-0/var/log/3154/stdout 
  11.418 ++  PING 10.1.1.2 (10.1.1.2) 1000(1028) bytes of data.
  11.419 ++  1008 bytes from 10.1.1.2: icmp_req=1 ttl=64 time=5.29 ms
  11.420 ++  1008 bytes from 10.1.1.2: icmp_req=2 ttl=64 time=5.29 ms
  11.421 ++  1008 bytes from 10.1.1.2: icmp_req=3 ttl=64 time=5.29 ms
  11.422 ++  1008 bytes from 10.1.1.2: icmp_req=4 ttl=64 time=5.29 ms
  11.423 ++  1008 bytes from 10.1.1.2: icmp_req=5 ttl=64 time=5.29 ms
  11.424 ++  1008 bytes from 10.1.1.2: icmp_req=6 ttl=64 time=5.29 ms
  11.425 ++  1008 bytes from 10.1.1.2: icmp_req=7 ttl=64 time=5.29 ms
  11.426 ++  1008 bytes from 10.1.1.2: icmp_req=8 ttl=64 time=5.29 ms
  11.427 ++  1008 bytes from 10.1.1.2: icmp_req=9 ttl=64 time=5.29 ms
  11.428 ++  1008 bytes from 10.1.1.2: icmp_req=10 ttl=64 time=5.29 ms
  11.429 ++  
  11.430 ++  --- 10.1.1.2 ping statistics ---
  11.431 ++  10 packets transmitted, 10 received, 0% packet loss, time 9002ms
  11.432 ++  rtt min/avg/max/mdev = 5.295/5.295/5.296/0.097 ms
  11.433 ++
  11.434 ++
  11.435 ++
  11.436 ++
  11.437 ++Debugging the Program
  11.438 ++*********************
  11.439 ++
  11.440 ++
  11.441 ++Extending DCE core
  11.442 ++------------------
  11.443 ++
  11.444 ++
  11.445 ++.. .. toctree::
  11.446 ++..    :maxdepth: 2
  11.447 ++
  11.448 ++..    introduction
  11.449 ++..    resources
  11.450 ++..    getting-started
  11.451 ++..    conceptual-overview
  11.452 ++..    tweaking
  11.453 ++..    building-topologies
  11.454 ++..    tracing
  11.455 ++..    conclusion
  11.456 ++
  11.457 ++
  11.458 ++
  11.459 ++.. 	what should we do to use it?
  11.460 ++.. 	 - download
  11.461 ++.. 	 - install
  11.462 ++.. 	 - example
  11.463 ++.. 	 - debug example
  11.464 ++.. 	 - employ own code
  11.465 ++.. 	 - how to extend core
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/perf-update.patch	Thu Jun 20 09:56:26 2013 +0900
    12.3 @@ -0,0 +1,103 @@
    12.4 +diff --git a/example/dce-cradle-simple.cc b/example/dce-cradle-simple.cc
    12.5 +--- a/example/dce-cradle-simple.cc
    12.6 ++++ b/example/dce-cradle-simple.cc
    12.7 +@@ -63,8 +63,8 @@
    12.8 +   nodes.Create (2);
    12.9 + 
   12.10 +   PointToPointHelper pointToPoint;
   12.11 +-  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("100Mbps"));
   12.12 +-  pointToPoint.SetChannelAttribute ("Delay", StringValue ("100ms"));
   12.13 ++  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("1Gbps"));
   12.14 ++  pointToPoint.SetChannelAttribute ("Delay", StringValue ("1ns"));
   12.15 + 
   12.16 +   NetDeviceContainer devices;
   12.17 +   devices = pointToPoint.Install (nodes);
   12.18 +diff --git a/example/dce-iperf.cc b/example/dce-iperf.cc
   12.19 +--- a/example/dce-iperf.cc
   12.20 ++++ b/example/dce-iperf.cc
   12.21 +@@ -31,6 +31,11 @@
   12.22 + //        in source named Thread.c at line 412 in method named thread_rest
   12.23 + //        you must add a sleep (1); to break the infinite loop....
   12.24 + // ===========================================================================
   12.25 ++void
   12.26 ++PrintTcpFlags (std::string key, std::string value)
   12.27 ++{
   12.28 ++  std::cout << key << "=" << value << std::endl;
   12.29 ++}
   12.30 + int main (int argc, char *argv[])
   12.31 + {
   12.32 +   bool useKernel = 0;
   12.33 +@@ -46,8 +51,8 @@
   12.34 +   nodes.Create (2);
   12.35 + 
   12.36 +   PointToPointHelper pointToPoint;
   12.37 +-  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("5Mbps"));
   12.38 +-  pointToPoint.SetChannelAttribute ("Delay", StringValue ("1ms"));
   12.39 ++  pointToPoint.SetDeviceAttribute ("DataRate", StringValue ("1Gbps"));
   12.40 ++  pointToPoint.SetChannelAttribute ("Delay", StringValue ("1ns"));
   12.41 + 
   12.42 +   NetDeviceContainer devices;
   12.43 +   devices = pointToPoint.Install (nodes);
   12.44 +@@ -66,6 +71,7 @@
   12.45 +       dceManager.SetNetworkStack ("ns3::LinuxSocketFdFactory", "Library", StringValue ("liblinux.so"));
   12.46 +       LinuxStackHelper stack;
   12.47 +       stack.Install (nodes);
   12.48 ++
   12.49 + #else
   12.50 +       NS_LOG_ERROR ("Linux kernel stack for DCE is not available. build with dce-linux module.");
   12.51 +       // silently exit
   12.52 +@@ -88,6 +94,32 @@
   12.53 + 
   12.54 +   dceManager.Install (nodes);
   12.55 + 
   12.56 ++  LinuxStackHelper stack;
   12.57 ++#if 0
   12.58 ++      stack.SysctlSet (nodes, ".net.core.rmem_max",
   12.59 ++                       "26214400");
   12.60 ++      stack.SysctlSet (nodes, ".net.core.wmem_max",
   12.61 ++                       "26214400");
   12.62 ++      stack.SysctlSet (nodes, ".net.ipv4.udp_rmem_min",
   12.63 ++                       "4194304");
   12.64 ++      stack.SysctlSet (nodes, ".net.ipv4.udp_wmem_min",
   12.65 ++                       "4194304");
   12.66 ++  LinuxStackHelper::SysctlGet (nodes.Get (0), Seconds (1),
   12.67 ++                               ".net.ipv4.udp_rmem_min", &PrintTcpFlags);
   12.68 ++  LinuxStackHelper::SysctlGet (nodes.Get (0), Seconds (1),
   12.69 ++                               ".net.ipv4.udp_wmem_min", &PrintTcpFlags);
   12.70 ++  LinuxStackHelper::SysctlGet (nodes.Get (0), Seconds (1),
   12.71 ++                               ".net.core.rmem_max", &PrintTcpFlags);
   12.72 ++  LinuxStackHelper::SysctlGet (nodes.Get (0), Seconds (1),
   12.73 ++                               ".net.core.wmem_max", &PrintTcpFlags);
   12.74 ++#endif
   12.75 ++// sysctl -w net.ipv4.tcp_dctcp_enable=1
   12.76 ++// sysctl -w net.ipv4.net.ipv4.tcp_ecn=1
   12.77 ++#if 0
   12.78 ++  stack.SysctlSet (nodes, ".net.ipv4.tcp_dctcp_enable", "1");
   12.79 ++  stack.SysctlSet (nodes, ".net.ipv4.net.ipv4.tcp_ecn", "1");
   12.80 ++#endif
   12.81 ++
   12.82 +   DceApplicationHelper dce;
   12.83 +   ApplicationContainer apps;
   12.84 + 
   12.85 +@@ -101,6 +133,10 @@
   12.86 +   dce.AddArgument ("10.1.1.2");
   12.87 +   dce.AddArgument ("-i");
   12.88 +   dce.AddArgument ("1");
   12.89 ++  //  dce.AddArgument ("-l");
   12.90 ++  //  dce.AddArgument ("64");
   12.91 ++  dce.AddArgument ("-w");
   12.92 ++  dce.AddArgument ("100000");
   12.93 +   dce.AddArgument ("--time");
   12.94 +   dce.AddArgument ("10");
   12.95 +   if (useUdp)
   12.96 +@@ -119,6 +155,10 @@
   12.97 +   dce.ResetArguments ();
   12.98 +   dce.ResetEnvironment ();
   12.99 +   dce.AddArgument ("-s");
  12.100 ++  dce.AddArgument ("-w");
  12.101 ++  dce.AddArgument ("1000000");
  12.102 ++  // dce.AddArgument ("-l");
  12.103 ++  // dce.AddArgument ("64");
  12.104 +   dce.AddArgument ("-P");
  12.105 +   dce.AddArgument ("1");
  12.106 +   if (useUdp)
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/poll-rework.patch	Thu Jun 20 09:56:26 2013 +0900
    13.3 @@ -0,0 +1,68 @@
    13.4 +diff -r 957c0c1b6549 -r 403f06f014ab model/dce-poll.cc
    13.5 +--- a/model/dce-poll.cc	Mon Oct 15 13:51:29 2012 +0900
    13.6 ++++ b/model/dce-poll.cc	Fri Oct 19 19:07:45 2012 +0900
    13.7 +@@ -19,7 +19,7 @@
    13.8 + {
    13.9 +   int count = -1;
   13.10 +   int timed_out = 0;
   13.11 +-  Time endtime;
   13.12 ++  Time start_time, endtime;
   13.13 +   // key fd
   13.14 +   std::map <int, FileUsage*> toUnRef;
   13.15 +   Thread *current = Current ();
   13.16 +@@ -30,6 +30,8 @@
   13.17 +   NS_ASSERT (current != 0);
   13.18 +   int validFdCount = 0;
   13.19 + 
   13.20 ++  start_time = Now ();
   13.21 ++
   13.22 +   if (0 == timeout)
   13.23 +     {
   13.24 +       currentTable = 0;
   13.25 +@@ -37,7 +39,7 @@
   13.26 +     }
   13.27 +   else if (timeout > 0)
   13.28 +     {
   13.29 +-      endtime = Now () + MilliSeconds (timeout);
   13.30 ++      endtime = start_time + MilliSeconds (timeout);
   13.31 +     }
   13.32 + 
   13.33 +   for (uint32_t i = 0; i < nfds; ++i)
   13.34 +@@ -77,6 +79,10 @@
   13.35 +                   count++;
   13.36 +                   currentTable = 0;
   13.37 +                 }
   13.38 ++              if (mask < 0)
   13.39 ++                {
   13.40 ++                  NS_ASSERT (0);
   13.41 ++                }
   13.42 +             }
   13.43 +         }
   13.44 +       currentTable = 0; // Register only first time.
   13.45 +@@ -118,7 +124,7 @@
   13.46 +     }
   13.47 + 
   13.48 +   // Try to break infinite loop in poll with a 0 timeout !
   13.49 +-  if ( ( 0 == count ) && ( 0 == timeout ) )
   13.50 ++  if (start_time == Now ())
   13.51 +     {
   13.52 +       UtilsAdvanceTime (current);
   13.53 +     }
   13.54 +diff -r 957c0c1b6549 -r 403f06f014ab model/utils.cc
   13.55 +--- a/model/utils.cc	Mon Oct 15 13:51:29 2012 +0900
   13.56 ++++ b/model/utils.cc	Fri Oct 19 19:07:45 2012 +0900
   13.57 +@@ -272,10 +272,10 @@
   13.58 + 
   13.59 +   if (now == current->lastTime)
   13.60 +     {
   13.61 +-//      NS_LOG_DEBUG ("UtilsAdvanceTime current thread wait 1ms.");
   13.62 +-      //current->process->manager->Wait (Time ( MilliSeconds (1) ) );
   13.63 +-      NS_LOG_DEBUG ("UtilsAdvanceTime current thread wait 1袖s.");
   13.64 +-      current->process->manager->Wait (Time ( MicroSeconds (1) ) );
   13.65 ++      NS_LOG_DEBUG ("UtilsAdvanceTime current thread wait 1ms.");
   13.66 ++      current->process->manager->Wait (Time ( MilliSeconds (4) ) ); // 250HZ?
   13.67 ++//      NS_LOG_DEBUG ("UtilsAdvanceTime current thread wait 1袖s.");
   13.68 ++      //      current->process->manager->Wait (Time ( MicroSeconds (1) ) );
   13.69 +     }
   13.70 + 
   13.71 +   current->lastTime = Now ();
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/pyscan.patch	Thu Jun 20 09:56:26 2013 +0900
    14.3 @@ -0,0 +1,157 @@
    14.4 +diff --git a/wscript b/wscript
    14.5 +--- a/wscript
    14.6 ++++ b/wscript
    14.7 +@@ -44,6 +44,16 @@
    14.8 +                    help=('Change the default command template to run programs and unit tests with valgrind'),
    14.9 +                    action="store_true", default=False,
   14.10 +                    dest='valgrind')
   14.11 ++    opt.add_option('--apiscan',
   14.12 ++                   help=("Rescan the API for the indicated module(s), for Python bindings.  "
   14.13 ++                         "Needs working GCCXML / pygccxml environment.  "
   14.14 ++                         "The metamodule 'all' expands to all available ns-3 modules."),
   14.15 ++                   default=None, dest='apiscan', metavar="MODULE[,MODULE...]")
   14.16 ++#    opt.add_option('--with-pybindgen',
   14.17 ++#                   help=('Path to an existing pybindgen source tree to use.'),
   14.18 ++#                   default=None,
   14.19 ++#                   dest='with_pybindgen', type="string")
   14.20 ++
   14.21 +                                   
   14.22 + def search_file(files):
   14.23 +     for f in files:
   14.24 +@@ -554,6 +564,8 @@
   14.25 +                 gen.post()
   14.26 +         bld.env['PRINT_BUILT_MODULES_AT_END'] = False 
   14.27 + 
   14.28 ++    wutils.ns3_python_bindings(bld) 
   14.29 ++
   14.30 + from waflib import Context, Build
   14.31 + class Ns3ShellContext(Context.Context):
   14.32 +     """run a shell with an environment suitably modified to run locally built programs"""
   14.33 +diff --git a/wutils.py b/wutils.py
   14.34 +--- a/wutils.py
   14.35 ++++ b/wutils.py
   14.36 +@@ -251,4 +251,124 @@
   14.37 +         execvec.append("--SimulatorImplementationType=ns3::VisualSimulatorImpl")
   14.38 +     return run_argv([env['PYTHON'][0]] + execvec, env, cwd=cwd)
   14.39 + 
   14.40 ++def ns3_python_bindings(bld):
   14.41 + 
   14.42 ++    # this method is called from a module wscript, so remember bld.path is not bindings/python!
   14.43 ++    module_abs_src_path = bld.path.abspath()
   14.44 ++    module = os.path.basename(module_abs_src_path)
   14.45 ++    env = bld.env
   14.46 ++    env.append_value("MODULAR_BINDINGS_MODULES", "ns3-"+module)
   14.47 ++
   14.48 ++    if Options.options.apiscan == False:
   14.49 ++        return
   14.50 ++
   14.51 ++    env['ENABLE_PYTHON_BINDINGS'] = True
   14.52 ++    if not env['ENABLE_PYTHON_BINDINGS']:
   14.53 ++        return
   14.54 ++
   14.55 ++    bindings_dir = bld.path.find_dir("bindings")
   14.56 ++    if bindings_dir is None or not os.path.exists(bindings_dir.abspath()):
   14.57 ++        warnings.warn("(in %s) Requested to build modular python bindings, but apidefs dir not found "
   14.58 ++                      "=> skipped the bindings." % str(bld.path),
   14.59 ++                      Warning, stacklevel=2)
   14.60 ++        return
   14.61 ++
   14.62 ++    #if ("ns3-%s" % (module,)) not in env.NS3_ENABLED_MODULES:
   14.63 ++    #    #print "bindings for module %s which is not enabled, skip" % module
   14.64 ++    #    return
   14.65 ++
   14.66 ++    env.append_value('PYTHON_MODULES_BUILT', module)
   14.67 ++    apidefs = env['PYTHON_BINDINGS_APIDEFS'].replace("-", "_")
   14.68 ++
   14.69 ++    #debug = ('PYBINDGEN_DEBUG' in os.environ)
   14.70 ++    debug = True # XXX
   14.71 ++    source = [bld.srcnode.find_resource('bindings/python/ns3modulegen-modular.py').relpath_gen(bld.path),
   14.72 ++              "bindings/modulegen__%s.py" % apidefs]
   14.73 ++
   14.74 ++    if bindings_dir.find_resource("modulegen_customizations.py") is not None:
   14.75 ++        source.append("bindings/modulegen_customizations.py")
   14.76 ++
   14.77 ++    # the local customization file may or not exist
   14.78 ++    if bld.path.find_resource("bindings/modulegen_local.py"):
   14.79 ++        source.append("bindings/modulegen_local.py")
   14.80 ++
   14.81 ++    module_py_name = module.replace('-', '_')
   14.82 ++    module_target_dir = bld.srcnode.find_dir("bindings/python/ns").relpath_gen(bld.path)
   14.83 ++
   14.84 ++    # if bindings/<module>.py exists, it becomes the module frontend, and the C extension befomes _<module>
   14.85 ++    if bld.path.find_resource("bindings/%s.py" % (module_py_name,)) is not None:
   14.86 ++        bld.new_task_gen(
   14.87 ++            features='copy',
   14.88 ++            source=("bindings/%s.py" % (module_py_name,)),
   14.89 ++            target=('%s/%s.py' % (module_target_dir, module_py_name)))
   14.90 ++        extension_name = '_%s' % (module_py_name,)
   14.91 ++        bld.install_files('${PYTHONARCHDIR}/ns', ["bindings/%s.py" % (module_py_name,)])
   14.92 ++    else:
   14.93 ++        extension_name = module_py_name
   14.94 ++
   14.95 ++    target = ['bindings/ns3module.cc', 'bindings/ns3module.h', 'bindings/ns3modulegen.log']
   14.96 ++    #if not debug:
   14.97 ++    #    target.append('ns3modulegen.log')
   14.98 ++
   14.99 ++    argv = ['NS3_ENABLED_FEATURES=${FEATURES}',
  14.100 ++            'GCC_RTTI_ABI_COMPLETE=${GCC_RTTI_ABI_COMPLETE}',
  14.101 ++            '${PYTHON}']
  14.102 ++    #if debug:
  14.103 ++    #    argv.extend(["-m", "pdb"])
  14.104 ++    
  14.105 ++    argv.extend(['${SRC[0]}', module_abs_src_path, apidefs, extension_name, '${TGT[0]}'])
  14.106 ++
  14.107 ++    argv.extend(['2>', '${TGT[2]}']) # 2> ns3modulegen.log
  14.108 ++
  14.109 ++    features = []
  14.110 ++    for (name, caption, was_enabled, reason_not_enabled) in env['NS3_OPTIONAL_FEATURES']:
  14.111 ++        if was_enabled:
  14.112 ++            features.append(name)
  14.113 ++
  14.114 ++    bindgen = bld.new_task_gen(features=['command'], source=source, target=target, command=argv)
  14.115 ++    bindgen.env['FEATURES'] = ','.join(features)
  14.116 ++    bindgen.dep_vars = ['FEATURES', "GCC_RTTI_ABI_COMPLETE"]
  14.117 ++    bindgen.before = 'cxx'
  14.118 ++    bindgen.after = 'gen_ns3_module_header'
  14.119 ++    bindgen.name = "pybindgen(ns3 module %s)" % module
  14.120 ++    bindgen.install_path = None
  14.121 ++
  14.122 ++    # generate the extension module
  14.123 ++    pymod = bld.new_task_gen(features='cxx cxxshlib pyext')
  14.124 ++    pymod.source = ['bindings/ns3module.cc']
  14.125 ++    pymod.target = '%s/%s' % (module_target_dir, extension_name)
  14.126 ++    pymod.name = 'ns3module_%s' % module
  14.127 ++    pymod.use = ["%s" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] #  Should be '"ns3-"+module', but see bug 1117
  14.128 ++    if pymod.env['ENABLE_STATIC_NS3']:
  14.129 ++        if sys.platform == 'darwin':
  14.130 ++            pymod.env.append_value('LINKFLAGS', '-Wl,-all_load')
  14.131 ++            for mod in pymod.usel:
  14.132 ++                #mod = mod.split("--lib")[0]
  14.133 ++                pymod.env.append_value('LINKFLAGS', '-l' + mod)
  14.134 ++        else:
  14.135 ++            pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
  14.136 ++            for mod in pymod.use:
  14.137 ++                #mod = mod.split("--lib")[0]
  14.138 ++                pymod.env.append_value('LINKFLAGS', '-l' + mod)
  14.139 ++            pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
  14.140 ++    defines = list(pymod.env['DEFINES'])
  14.141 ++    defines.extend(['NS_DEPRECATED=', 'NS3_DEPRECATED_H'])
  14.142 ++    if Options.platform == 'win32':
  14.143 ++        try:
  14.144 ++            defines.remove('_DEBUG') # causes undefined symbols on win32
  14.145 ++        except ValueError:
  14.146 ++            pass
  14.147 ++    pymod.env['DEFINES'] = defines
  14.148 ++    pymod.includes = '# bindings'
  14.149 ++    pymod.install_path = '${PYTHONARCHDIR}/ns'
  14.150 ++
  14.151 ++    # Workaround to a WAF bug, remove this when ns-3 upgrades to WAF > 1.6.10
  14.152 ++    # https://www.nsnam.org/bugzilla/show_bug.cgi?id=1335
  14.153 ++    # http://code.google.com/p/waf/issues/detail?id=1098
  14.154 ++    if Utils.unversioned_sys_platform() == 'darwin':
  14.155 ++        pymod.mac_bundle = True
  14.156 ++
  14.157 ++    return pymod
  14.158 ++
  14.159 ++#    bld.ns3_python_bindings = types.MethodType(ns3_python_bindings, bld)
  14.160 ++
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/python-binding.patch	Thu Jun 20 09:56:26 2013 +0900
    15.3 @@ -0,0 +1,4120 @@
    15.4 +diff --git a/bindings/callbacks_list.py b/bindings/callbacks_list.py
    15.5 +new file mode 100644
    15.6 +--- /dev/null
    15.7 ++++ b/bindings/callbacks_list.py
    15.8 +@@ -0,0 +1,1 @@
    15.9 ++callback_classes = [
   15.10 +diff --git a/bindings/modulegen__gcc_ILP32.py b/bindings/modulegen__gcc_ILP32.py
   15.11 +new file mode 100644
   15.12 +--- /dev/null
   15.13 ++++ b/bindings/modulegen__gcc_ILP32.py
   15.14 +@@ -0,0 +1,33 @@
   15.15 ++from pybindgen import Module, FileCodeSink, param, retval, cppclass, typehandlers
   15.16 ++
   15.17 ++
   15.18 ++import pybindgen.settings
   15.19 ++import warnings
   15.20 ++
   15.21 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
   15.22 ++    def handle_error(self, wrapper, exception, traceback_):
   15.23 ++        warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
   15.24 ++        return True
   15.25 ++pybindgen.settings.error_handler = ErrorHandler()
   15.26 ++
   15.27 ++
   15.28 ++import sys
   15.29 ++
   15.30 ++def module_init():
   15.31 ++    root_module = Module('ns.dce_netlink', cpp_namespace='::ns3')
   15.32 ++    return root_module
   15.33 ++
   15.34 ++def register_types(module):
   15.35 ++    root_module = module.get_root()
   15.36 ++    
   15.37 ++    
   15.38 ++    ## Register a nested module for the namespace FatalImpl
   15.39 ++    
   15.40 ++    nested_module = module.add_cpp_namespace('FatalImpl')
   15.41 ++    register_types_ns3_FatalImpl(nested_module)
   15.42 ++    
   15.43 ++
   15.44 ++def register_types_ns3_FatalImpl(module):
   15.45 ++    root_module = module.get_root()
   15.46 ++    
   15.47 ++
   15.48 +diff --git a/bindings/modulegen__gcc_LP64.py b/bindings/modulegen__gcc_LP64.py
   15.49 +new file mode 100644
   15.50 +--- /dev/null
   15.51 ++++ b/bindings/modulegen__gcc_LP64.py
   15.52 +@@ -0,0 +1,391 @@
   15.53 ++from pybindgen import Module, FileCodeSink, param, retval, cppclass, typehandlers
   15.54 ++
   15.55 ++
   15.56 ++import pybindgen.settings
   15.57 ++import warnings
   15.58 ++
   15.59 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
   15.60 ++    def handle_error(self, wrapper, exception, traceback_):
   15.61 ++        warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
   15.62 ++        return True
   15.63 ++pybindgen.settings.error_handler = ErrorHandler()
   15.64 ++
   15.65 ++
   15.66 ++import sys
   15.67 ++
   15.68 ++def module_init():
   15.69 ++    root_module = Module('ns.dce', cpp_namespace='::ns3')
   15.70 ++    return root_module
   15.71 ++
   15.72 ++def register_types(module):
   15.73 ++    root_module = module.get_root()
   15.74 ++    
   15.75 ++    ## dce-application-helper.h (module 'dce'): ns3::DceApplicationHelper [class]
   15.76 ++    module.add_class('DceApplicationHelper', allow_subclassing=True)
   15.77 ++    ## linux-stack-helper.h (module 'dce'): ns3::LinuxStackHelper [class]
   15.78 ++    module.add_class('LinuxStackHelper')
   15.79 ++    ## loader-factory.h (module 'dce'): ns3::Loader [class]
   15.80 ++    module.add_class('Loader', allow_subclassing=True)
   15.81 ++    ## dce-manager-helper.h (module 'dce'): ns3::ProcStatus [class]
   15.82 ++    module.add_class('ProcStatus')
   15.83 ++    ## task-manager.h (module 'dce'): ns3::Sleeper [class]
   15.84 ++    module.add_class('Sleeper')
   15.85 ++    ## task-manager.h (module 'dce'): ns3::Task [class]
   15.86 ++    module.add_class('Task', destructor_visibility='private')
   15.87 ++    ## task-manager.h (module 'dce'): ns3::Task::SwitchType [enumeration]
   15.88 ++    module.add_enum('SwitchType', ['TO', 'FROM'], outer_class=root_module['ns3::Task'])
   15.89 ++    ## ccn-client-helper.h (module 'dce'): ns3::CcnClientHelper [class]
   15.90 ++    module.add_class('CcnClientHelper', parent=root_module['ns3::DceApplicationHelper'])
   15.91 ++    
   15.92 ++    ## Register a nested module for the namespace FatalImpl
   15.93 ++    
   15.94 ++    nested_module = module.add_cpp_namespace('FatalImpl')
   15.95 ++    register_types_ns3_FatalImpl(nested_module)
   15.96 ++    
   15.97 ++
   15.98 ++def register_types_ns3_FatalImpl(module):
   15.99 ++    root_module = module.get_root()
  15.100 ++    
  15.101 ++
  15.102 ++def register_methods(root_module):
  15.103 ++    register_Ns3DceApplicationHelper_methods(root_module, root_module['ns3::DceApplicationHelper'])
  15.104 ++    register_Ns3LinuxStackHelper_methods(root_module, root_module['ns3::LinuxStackHelper'])
  15.105 ++    register_Ns3Loader_methods(root_module, root_module['ns3::Loader'])
  15.106 ++    register_Ns3ProcStatus_methods(root_module, root_module['ns3::ProcStatus'])
  15.107 ++    register_Ns3Sleeper_methods(root_module, root_module['ns3::Sleeper'])
  15.108 ++    register_Ns3Task_methods(root_module, root_module['ns3::Task'])
  15.109 ++    register_Ns3CcnClientHelper_methods(root_module, root_module['ns3::CcnClientHelper'])
  15.110 ++    return
  15.111 ++
  15.112 ++def register_Ns3DceApplicationHelper_methods(root_module, cls):
  15.113 ++    ## dce-application-helper.h (module 'dce'): ns3::DceApplicationHelper::DceApplicationHelper(ns3::DceApplicationHelper const & arg0) [copy constructor]
  15.114 ++    cls.add_constructor([param('ns3::DceApplicationHelper const &', 'arg0')])
  15.115 ++    ## dce-application-helper.h (module 'dce'): ns3::DceApplicationHelper::DceApplicationHelper() [constructor]
  15.116 ++    cls.add_constructor([])
  15.117 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArgument(std::string arg) [member function]
  15.118 ++    cls.add_method('AddArgument', 
  15.119 ++                   'void', 
  15.120 ++                   [param('std::string', 'arg')])
  15.121 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1) [member function]
  15.122 ++    cls.add_method('AddArguments', 
  15.123 ++                   'void', 
  15.124 ++                   [param('std::string', 'a0'), param('std::string', 'a1')])
  15.125 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2) [member function]
  15.126 ++    cls.add_method('AddArguments', 
  15.127 ++                   'void', 
  15.128 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2')])
  15.129 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2, std::string a3) [member function]
  15.130 ++    cls.add_method('AddArguments', 
  15.131 ++                   'void', 
  15.132 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2'), param('std::string', 'a3')])
  15.133 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2, std::string a3, std::string a4) [member function]
  15.134 ++    cls.add_method('AddArguments', 
  15.135 ++                   'void', 
  15.136 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2'), param('std::string', 'a3'), param('std::string', 'a4')])
  15.137 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2, std::string a3, std::string a4, std::string a5) [member function]
  15.138 ++    cls.add_method('AddArguments', 
  15.139 ++                   'void', 
  15.140 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2'), param('std::string', 'a3'), param('std::string', 'a4'), param('std::string', 'a5')])
  15.141 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2, std::string a3, std::string a4, std::string a5, std::string a6) [member function]
  15.142 ++    cls.add_method('AddArguments', 
  15.143 ++                   'void', 
  15.144 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2'), param('std::string', 'a3'), param('std::string', 'a4'), param('std::string', 'a5'), param('std::string', 'a6')])
  15.145 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddArguments(std::string a0, std::string a1, std::string a2, std::string a3, std::string a4, std::string a5, std::string a6, std::string a7) [member function]
  15.146 ++    cls.add_method('AddArguments', 
  15.147 ++                   'void', 
  15.148 ++                   [param('std::string', 'a0'), param('std::string', 'a1'), param('std::string', 'a2'), param('std::string', 'a3'), param('std::string', 'a4'), param('std::string', 'a5'), param('std::string', 'a6'), param('std::string', 'a7')])
  15.149 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::AddEnvironment(std::string name, std::string value) [member function]
  15.150 ++    cls.add_method('AddEnvironment', 
  15.151 ++                   'void', 
  15.152 ++                   [param('std::string', 'name'), param('std::string', 'value')])
  15.153 ++    ## dce-application-helper.h (module 'dce'): ns3::ApplicationContainer ns3::DceApplicationHelper::Install(ns3::NodeContainer c) [member function]
  15.154 ++    cls.add_method('Install', 
  15.155 ++                   'ns3::ApplicationContainer', 
  15.156 ++                   [param('ns3::NodeContainer', 'c')], 
  15.157 ++                   is_virtual=True)
  15.158 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::ParseArguments(std::string args) [member function]
  15.159 ++    cls.add_method('ParseArguments', 
  15.160 ++                   'void', 
  15.161 ++                   [param('std::string', 'args')])
  15.162 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::ResetArguments() [member function]
  15.163 ++    cls.add_method('ResetArguments', 
  15.164 ++                   'void', 
  15.165 ++                   [])
  15.166 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::ResetEnvironment() [member function]
  15.167 ++    cls.add_method('ResetEnvironment', 
  15.168 ++                   'void', 
  15.169 ++                   [])
  15.170 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetBinary(std::string filename) [member function]
  15.171 ++    cls.add_method('SetBinary', 
  15.172 ++                   'void', 
  15.173 ++                   [param('std::string', 'filename')])
  15.174 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetEgid(uid_t i) [member function]
  15.175 ++    cls.add_method('SetEgid', 
  15.176 ++                   'void', 
  15.177 ++                   [param('uid_t', 'i')])
  15.178 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetEuid(uid_t i) [member function]
  15.179 ++    cls.add_method('SetEuid', 
  15.180 ++                   'void', 
  15.181 ++                   [param('uid_t', 'i')])
  15.182 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetFinishedCallback(ns3::Callback<void, unsigned short, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty> cb) [member function]
  15.183 ++    cls.add_method('SetFinishedCallback', 
  15.184 ++                   'void', 
  15.185 ++                   [param('ns3::Callback< void, unsigned short, int, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty, ns3::empty >', 'cb')])
  15.186 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetGid(uid_t i) [member function]
  15.187 ++    cls.add_method('SetGid', 
  15.188 ++                   'void', 
  15.189 ++                   [param('uid_t', 'i')])
  15.190 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetStackSize(uint32_t stackSize) [member function]
  15.191 ++    cls.add_method('SetStackSize', 
  15.192 ++                   'void', 
  15.193 ++                   [param('uint32_t', 'stackSize')])
  15.194 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetStdinFile(std::string filename) [member function]
  15.195 ++    cls.add_method('SetStdinFile', 
  15.196 ++                   'void', 
  15.197 ++                   [param('std::string', 'filename')])
  15.198 ++    ## dce-application-helper.h (module 'dce'): void ns3::DceApplicationHelper::SetUid(uid_t i) [member function]
  15.199 ++    cls.add_method('SetUid', 
  15.200 ++                   'void', 
  15.201 ++                   [param('uid_t', 'i')])
  15.202 ++    return
  15.203 ++
  15.204 ++def register_Ns3LinuxStackHelper_methods(root_module, cls):
  15.205 ++    ## linux-stack-helper.h (module 'dce'): ns3::LinuxStackHelper::LinuxStackHelper() [constructor]
  15.206 ++    cls.add_constructor([])
  15.207 ++    ## linux-stack-helper.h (module 'dce'): ns3::LinuxStackHelper::LinuxStackHelper(ns3::LinuxStackHelper const & arg0) [copy constructor]
  15.208 ++    cls.add_constructor([param('ns3::LinuxStackHelper const &', 'arg0')])
  15.209 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::Install(std::string nodeName) [member function]
  15.210 ++    cls.add_method('Install', 
  15.211 ++                   'void', 
  15.212 ++                   [param('std::string', 'nodeName')], 
  15.213 ++                   is_static=True)
  15.214 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::Install(ns3::Ptr<ns3::Node> node) [member function]
  15.215 ++    cls.add_method('Install', 
  15.216 ++                   'void', 
  15.217 ++                   [param('ns3::Ptr< ns3::Node >', 'node')], 
  15.218 ++                   is_static=True)
  15.219 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::Install(ns3::NodeContainer c) [member function]
  15.220 ++    cls.add_method('Install', 
  15.221 ++                   'void', 
  15.222 ++                   [param('ns3::NodeContainer', 'c')], 
  15.223 ++                   is_static=True)
  15.224 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::InstallAll() [member function]
  15.225 ++    cls.add_method('InstallAll', 
  15.226 ++                   'void', 
  15.227 ++                   [], 
  15.228 ++                   is_static=True)
  15.229 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::PopulateRoutingTables() [member function]
  15.230 ++    cls.add_method('PopulateRoutingTables', 
  15.231 ++                   'void', 
  15.232 ++                   [], 
  15.233 ++                   is_static=True)
  15.234 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::RunIp(ns3::Ptr<ns3::Node> node, ns3::Time at, std::string str) [member function]
  15.235 ++    cls.add_method('RunIp', 
  15.236 ++                   'void', 
  15.237 ++                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Time', 'at'), param('std::string', 'str')], 
  15.238 ++                   is_static=True)
  15.239 ++    ## linux-stack-helper.h (module 'dce'): static void ns3::LinuxStackHelper::SysctlGet(ns3::Ptr<ns3::Node> node, ns3::Time at, std::string path, void (*)( ::std::string,::std::string ) * callback) [member function]
  15.240 ++    cls.add_method('SysctlGet', 
  15.241 ++                   'void', 
  15.242 ++                   [param('ns3::Ptr< ns3::Node >', 'node'), param('ns3::Time', 'at'), param('std::string', 'path'), param('void ( * ) ( std::string, std::string ) *', 'callback')], 
  15.243 ++                   is_static=True)
  15.244 ++    ## linux-stack-helper.h (module 'dce'): void ns3::LinuxStackHelper::SysctlSet(ns3::NodeContainer c, std::string path, std::string value) [member function]
  15.245 ++    cls.add_method('SysctlSet', 
  15.246 ++                   'void', 
  15.247 ++                   [param('ns3::NodeContainer', 'c'), param('std::string', 'path'), param('std::string', 'value')])
  15.248 ++    return
  15.249 ++
  15.250 ++def register_Ns3Loader_methods(root_module, cls):
  15.251 ++    ## loader-factory.h (module 'dce'): ns3::Loader::Loader() [constructor]
  15.252 ++    cls.add_constructor([])
  15.253 ++    ## loader-factory.h (module 'dce'): ns3::Loader::Loader(ns3::Loader const & arg0) [copy constructor]
  15.254 ++    cls.add_constructor([param('ns3::Loader const &', 'arg0')])
  15.255 ++    ## loader-factory.h (module 'dce'): ns3::Loader * ns3::Loader::Clone() [member function]
  15.256 ++    cls.add_method('Clone', 
  15.257 ++                   'ns3::Loader *', 
  15.258 ++                   [], 
  15.259 ++                   is_pure_virtual=True, is_virtual=True)
  15.260 ++    ## loader-factory.h (module 'dce'): void * ns3::Loader::Load(std::string filename, int flag) [member function]
  15.261 ++    cls.add_method('Load', 
  15.262 ++                   'void *', 
  15.263 ++                   [param('std::string', 'filename'), param('int', 'flag')], 
  15.264 ++                   is_pure_virtual=True, is_virtual=True)
  15.265 ++    ## loader-factory.h (module 'dce'): void * ns3::Loader::Lookup(void * module, std::string symbol) [member function]
  15.266 ++    cls.add_method('Lookup', 
  15.267 ++                   'void *', 
  15.268 ++                   [param('void *', 'module'), param('std::string', 'symbol')], 
  15.269 ++                   is_pure_virtual=True, is_virtual=True)
  15.270 ++    ## loader-factory.h (module 'dce'): void ns3::Loader::NotifyEndExecute() [member function]
  15.271 ++    cls.add_method('NotifyEndExecute', 
  15.272 ++                   'void', 
  15.273 ++                   [], 
  15.274 ++                   is_virtual=True)
  15.275 ++    ## loader-factory.h (module 'dce'): void ns3::Loader::NotifyStartExecute() [member function]
  15.276 ++    cls.add_method('NotifyStartExecute', 
  15.277 ++                   'void', 
  15.278 ++                   [], 
  15.279 ++                   is_virtual=True)
  15.280 ++    ## loader-factory.h (module 'dce'): void ns3::Loader::Unload(void * module) [member function]
  15.281 ++    cls.add_method('Unload', 
  15.282 ++                   'void', 
  15.283 ++                   [param('void *', 'module')], 
  15.284 ++                   is_pure_virtual=True, is_virtual=True)
  15.285 ++    ## loader-factory.h (module 'dce'): void ns3::Loader::UnloadAll() [member function]
  15.286 ++    cls.add_method('UnloadAll', 
  15.287 ++                   'void', 
  15.288 ++                   [], 
  15.289 ++                   is_pure_virtual=True, is_virtual=True)
  15.290 ++    return
  15.291 ++
  15.292 ++def register_Ns3ProcStatus_methods(root_module, cls):
  15.293 ++    ## dce-manager-helper.h (module 'dce'): ns3::ProcStatus::ProcStatus(ns3::ProcStatus const & arg0) [copy constructor]
  15.294 ++    cls.add_constructor([param('ns3::ProcStatus const &', 'arg0')])
  15.295 ++    ## dce-manager-helper.h (module 'dce'): ns3::ProcStatus::ProcStatus(int n, int e, int p, int64_t ns, int64_t ne, long int rs, long int re, double nd, long int rd, std::string cmd) [constructor]
  15.296 ++    cls.add_constructor([param('int', 'n'), param('int', 'e'), param('int', 'p'), param('int64_t', 'ns'), param('int64_t', 'ne'), param('long int', 'rs'), param('long int', 're'), param('double', 'nd'), param('long int', 'rd'), param('std::string', 'cmd')])
  15.297 ++    ## dce-manager-helper.h (module 'dce'): std::string ns3::ProcStatus::GetCmdLine() const [member function]
  15.298 ++    cls.add_method('GetCmdLine', 
  15.299 ++                   'std::string', 
  15.300 ++                   [], 
  15.301 ++                   is_const=True)
  15.302 ++    ## dce-manager-helper.h (module 'dce'): int ns3::ProcStatus::GetExitCode() const [member function]
  15.303 ++    cls.add_method('GetExitCode', 
  15.304 ++                   'int', 
  15.305 ++                   [], 
  15.306 ++                   is_const=True)
  15.307 ++    ## dce-manager-helper.h (module 'dce'): int ns3::ProcStatus::GetNode() const [member function]
  15.308 ++    cls.add_method('GetNode', 
  15.309 ++                   'int', 
  15.310 ++                   [], 
  15.311 ++                   is_const=True)
  15.312 ++    ## dce-manager-helper.h (module 'dce'): int ns3::ProcStatus::GetPid() const [member function]
  15.313 ++    cls.add_method('GetPid', 
  15.314 ++                   'int', 
  15.315 ++                   [], 
  15.316 ++                   is_const=True)
  15.317 ++    ## dce-manager-helper.h (module 'dce'): long int ns3::ProcStatus::GetRealDuration() const [member function]
  15.318 ++    cls.add_method('GetRealDuration', 
  15.319 ++                   'long int', 
  15.320 ++                   [], 
  15.321 ++                   is_const=True)
  15.322 ++    ## dce-manager-helper.h (module 'dce'): long int ns3::ProcStatus::GetRealEndTime() const [member function]
  15.323 ++    cls.add_method('GetRealEndTime', 
  15.324 ++                   'long int', 
  15.325 ++                   [], 
  15.326 ++                   is_const=True)
  15.327 ++    ## dce-manager-helper.h (module 'dce'): long int ns3::ProcStatus::GetRealStartTime() const [member function]
  15.328 ++    cls.add_method('GetRealStartTime', 
  15.329 ++                   'long int', 
  15.330 ++                   [], 
  15.331 ++                   is_const=True)
  15.332 ++    ## dce-manager-helper.h (module 'dce'): double ns3::ProcStatus::GetSimulatedDuration() const [member function]
  15.333 ++    cls.add_method('GetSimulatedDuration', 
  15.334 ++                   'double', 
  15.335 ++                   [], 
  15.336 ++                   is_const=True)
  15.337 ++    ## dce-manager-helper.h (module 'dce'): int64_t ns3::ProcStatus::GetSimulatedEndTime() const [member function]
  15.338 ++    cls.add_method('GetSimulatedEndTime', 
  15.339 ++                   'int64_t', 
  15.340 ++                   [], 
  15.341 ++                   is_const=True)
  15.342 ++    ## dce-manager-helper.h (module 'dce'): int64_t ns3::ProcStatus::GetSimulatedStartTime() const [member function]
  15.343 ++    cls.add_method('GetSimulatedStartTime', 
  15.344 ++                   'int64_t', 
  15.345 ++                   [], 
  15.346 ++                   is_const=True)
  15.347 ++    return
  15.348 ++
  15.349 ++def register_Ns3Sleeper_methods(root_module, cls):
  15.350 ++    ## task-manager.h (module 'dce'): ns3::Sleeper::m_task [variable]
  15.351 ++    cls.add_instance_attribute('m_task', 'ns3::Task * const', is_const=True)
  15.352 ++    ## task-manager.h (module 'dce'): ns3::Sleeper::m_timeout [variable]
  15.353 ++    cls.add_instance_attribute('m_timeout', 'ns3::Time const', is_const=True)
  15.354 ++    ## task-manager.h (module 'dce'): ns3::Sleeper::Sleeper(ns3::Sleeper const & arg0) [copy constructor]
  15.355 ++    cls.add_constructor([param('ns3::Sleeper const &', 'arg0')])
  15.356 ++    ## task-manager.h (module 'dce'): ns3::Sleeper::Sleeper(ns3::Task * t, ns3::Time to) [constructor]
  15.357 ++    cls.add_constructor([param('ns3::Task *', 't'), param('ns3::Time', 'to')])
  15.358 ++    return
  15.359 ++
  15.360 ++def register_Ns3Task_methods(root_module, cls):
  15.361 ++    ## task-manager.h (module 'dce'): ns3::Task::Task() [constructor]
  15.362 ++    cls.add_constructor([])
  15.363 ++    ## task-manager.h (module 'dce'): ns3::Task::Task(ns3::Task const & arg0) [copy constructor]
  15.364 ++    cls.add_constructor([param('ns3::Task const &', 'arg0')])
  15.365 ++    ## task-manager.h (module 'dce'): void * ns3::Task::GetContext() const [member function]
  15.366 ++    cls.add_method('GetContext', 
  15.367 ++                   'void *', 
  15.368 ++                   [], 
  15.369 ++                   is_const=True)
  15.370 ++    ## task-manager.h (module 'dce'): void * ns3::Task::GetExtraContext() const [member function]
  15.371 ++    cls.add_method('GetExtraContext', 
  15.372 ++                   'void *', 
  15.373 ++                   [], 
  15.374 ++                   is_const=True)
  15.375 ++    ## task-manager.h (module 'dce'): bool ns3::Task::IsActive() const [member function]
  15.376 ++    cls.add_method('IsActive', 
  15.377 ++                   'bool', 
  15.378 ++                   [], 
  15.379 ++                   is_const=True)
  15.380 ++    ## task-manager.h (module 'dce'): bool ns3::Task::IsBlocked() const [member function]
  15.381 ++    cls.add_method('IsBlocked', 
  15.382 ++                   'bool', 
  15.383 ++                   [], 
  15.384 ++                   is_const=True)
  15.385 ++    ## task-manager.h (module 'dce'): bool ns3::Task::IsDead() const [member function]
  15.386 ++    cls.add_method('IsDead', 
  15.387 ++                   'bool', 
  15.388 ++                   [], 
  15.389 ++                   is_const=True)
  15.390 ++    ## task-manager.h (module 'dce'): bool ns3::Task::IsRunning() const [member function]
  15.391 ++    cls.add_method('IsRunning', 
  15.392 ++                   'bool', 
  15.393 ++                   [], 
  15.394 ++                   is_const=True)
  15.395 ++    ## task-manager.h (module 'dce'): void ns3::Task::SetContext(void * ctx) [member function]
  15.396 ++    cls.add_method('SetContext', 
  15.397 ++                   'void', 
  15.398 ++                   [param('void *', 'ctx')])
  15.399 ++    ## task-manager.h (module 'dce'): void ns3::Task::SetExtraContext(void * ctx) [member function]
  15.400 ++    cls.add_method('SetExtraContext', 
  15.401 ++                   'void', 
  15.402 ++                   [param('void *', 'ctx')])
  15.403 ++    ## task-manager.h (module 'dce'): void ns3::Task::SetSwitchNotifier(void (*)( ::ns3::Task::SwitchType,void * ) * fn, void * context) [member function]
  15.404 ++    cls.add_method('SetSwitchNotifier', 
  15.405 ++                   'void', 
  15.406 ++                   [param('void ( * ) ( ns3::Task::SwitchType, void * ) *', 'fn'), param('void *', 'context')])
  15.407 ++    return
  15.408 ++
  15.409 ++def register_Ns3CcnClientHelper_methods(root_module, cls):
  15.410 ++    ## ccn-client-helper.h (module 'dce'): ns3::CcnClientHelper::CcnClientHelper(ns3::CcnClientHelper const & arg0) [copy constructor]
  15.411 ++    cls.add_constructor([param('ns3::CcnClientHelper const &', 'arg0')])
  15.412 ++    ## ccn-client-helper.h (module 'dce'): ns3::CcnClientHelper::CcnClientHelper() [constructor]
  15.413 ++    cls.add_constructor([])
  15.414 ++    ## ccn-client-helper.h (module 'dce'): void ns3::CcnClientHelper::AddFile(std::string from, std::string to) [member function]
  15.415 ++    cls.add_method('AddFile', 
  15.416 ++                   'void', 
  15.417 ++                   [param('std::string', 'from'), param('std::string', 'to')])
  15.418 ++    ## ccn-client-helper.h (module 'dce'): ns3::ApplicationContainer ns3::CcnClientHelper::Install(ns3::NodeContainer c) [member function]
  15.419 ++    cls.add_method('Install', 
  15.420 ++                   'ns3::ApplicationContainer', 
  15.421 ++                   [param('ns3::NodeContainer', 'c')], 
  15.422 ++                   is_virtual=True)
  15.423 ++    return
  15.424 ++
  15.425 ++def register_functions(root_module):
  15.426 ++    module = root_module
  15.427 ++    register_functions_ns3_FatalImpl(module.get_submodule('FatalImpl'), root_module)
  15.428 ++    return
  15.429 ++
  15.430 ++def register_functions_ns3_FatalImpl(module, root_module):
  15.431 ++    return
  15.432 ++
  15.433 ++def main():
  15.434 ++    out = FileCodeSink(sys.stdout)
  15.435 ++    root_module = module_init()
  15.436 ++    register_types(root_module)
  15.437 ++    register_methods(root_module)
  15.438 ++    register_functions(root_module)
  15.439 ++    root_module.generate(out)
  15.440 ++
  15.441 ++if __name__ == '__main__':
  15.442 ++    main()
  15.443 ++
  15.444 +diff --git a/bindings/ns/_placeholder_ b/bindings/ns/_placeholder_
  15.445 +new file mode 100644
  15.446 +diff --git a/bindings/ns3modulegen-modular.py b/bindings/ns3modulegen-modular.py
  15.447 +new file mode 100644
  15.448 +--- /dev/null
  15.449 ++++ b/bindings/ns3modulegen-modular.py
  15.450 +@@ -0,0 +1,132 @@
  15.451 ++import warnings
  15.452 ++import sys
  15.453 ++import os
  15.454 ++import pybindgen.settings
  15.455 ++from pybindgen import Module, FileCodeSink, param, retval, cppclass, typehandlers
  15.456 ++from pybindgen.module import MultiSectionFactory
  15.457 ++import ns3modulegen_core_customizations
  15.458 ++
  15.459 ++pybindgen.settings.wrapper_registry = pybindgen.settings.StdMapWrapperRegistry
  15.460 ++
  15.461 ++import traceback
  15.462 ++
  15.463 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
  15.464 ++
  15.465 ++    def __init__(self, apidefs_file):
  15.466 ++        self.apidefs_file = apidefs_file
  15.467 ++
  15.468 ++    def handle_error(self, wrapper, exception, traceback_):
  15.469 ++        stack = getattr(wrapper, 'stack_where_defined', [])
  15.470 ++        stack.reverse()
  15.471 ++        for l in stack:
  15.472 ++            if l[0] == self.apidefs_file:
  15.473 ++                warnings.warn_explicit("exception %r in wrapper %s" % (exception, wrapper),
  15.474 ++                                       Warning, l[0], l[1])
  15.475 ++                break
  15.476 ++        else:
  15.477 ++            warnings.warn("exception %r in wrapper %s" % (exception, wrapper))
  15.478 ++        return True
  15.479 ++
  15.480 ++
  15.481 ++#print >> sys.stderr, ">>>>>>>>>>>>>>>>>>>>>>>>>>>> ", bool(eval(os.environ["GCC_RTTI_ABI_COMPLETE"]))
  15.482 ++pybindgen.settings.gcc_rtti_abi_complete = bool(eval(os.environ["GCC_RTTI_ABI_COMPLETE"]))
  15.483 ++
  15.484 ++class MyMultiSectionFactory(MultiSectionFactory):
  15.485 ++    def __init__(self, main_file_name):
  15.486 ++        super(MyMultiSectionFactory, self).__init__()
  15.487 ++        self.main_file_name = main_file_name
  15.488 ++        self.main_sink = FileCodeSink(open(main_file_name, "wt"))
  15.489 ++        self.header_name = "ns3module.h"
  15.490 ++        header_file_name = os.path.join(os.path.dirname(self.main_file_name), self.header_name)
  15.491 ++        #print >> sys.stderr, ">>>>>>>>>>>>>>>>>", header_file_name, main_file_name
  15.492 ++        self.header_sink = FileCodeSink(open(header_file_name, "wt"))
  15.493 ++    def get_section_code_sink(self, section_name):
  15.494 ++        return self.main_sink
  15.495 ++    def get_main_code_sink(self):
  15.496 ++        return self.main_sink
  15.497 ++    def get_common_header_code_sink(self):
  15.498 ++        return self.header_sink
  15.499 ++    def get_common_header_include(self):
  15.500 ++        return '"%s"' % self.header_name
  15.501 ++    def close(self):
  15.502 ++        self.header_sink.file.close()
  15.503 ++        self.main_sink.file.close()
  15.504 ++
  15.505 ++
  15.506 ++
  15.507 ++def main(argv):
  15.508 ++    module_abs_src_path, target, extension_name, output_cc_file_name = argv[1:]
  15.509 ++    if module_abs_src_path.endswith('build'):
  15.510 ++        module_name = extension_name
  15.511 ++    else:
  15.512 ++        module_name = os.path.basename(module_abs_src_path).replace('ns-3-','')
  15.513 ++    print module_name
  15.514 ++    print extension_name
  15.515 ++    out = MyMultiSectionFactory(output_cc_file_name)
  15.516 ++
  15.517 ++    sys.path.insert(0, os.path.join(module_abs_src_path, "bindings"))
  15.518 ++    try:
  15.519 ++        module_apidefs = __import__("modulegen__%s" % target)
  15.520 ++        del sys.modules["modulegen__%s" % target]
  15.521 ++        try:
  15.522 ++            module_customization = __import__("modulegen_customizations")
  15.523 ++            del sys.modules["modulegen_customizations"]
  15.524 ++        except ImportError:
  15.525 ++            module_customization = object()
  15.526 ++
  15.527 ++        try:
  15.528 ++            from callbacks_list import callback_classes
  15.529 ++        except ImportError, ex:
  15.530 ++            print >> sys.stderr, "***************", repr(ex)
  15.531 ++            callback_classes = []
  15.532 ++        else:
  15.533 ++            print >> sys.stderr, ">>>>>>>>>>>>>>>>", repr(callback_classes)
  15.534 ++
  15.535 ++    finally:
  15.536 ++        sys.path.pop(0)
  15.537 ++
  15.538 ++    apidefs_file, dummy = os.path.splitext(module_apidefs.__file__)
  15.539 ++    apidefs_file += '.py'
  15.540 ++    pybindgen.settings.error_handler = ErrorHandler(apidefs_file)
  15.541 ++
  15.542 ++    root_module = module_apidefs.module_init()
  15.543 ++    root_module.set_name(extension_name)
  15.544 ++    root_module.add_include('"ns3/%s-module.h"' % module_name)
  15.545 ++
  15.546 ++    ns3modulegen_core_customizations.add_std_ios_openmode(root_module)
  15.547 ++
  15.548 ++    # -----------
  15.549 ++    module_apidefs.register_types(root_module)
  15.550 ++
  15.551 ++    if hasattr(module_customization, 'post_register_types'):
  15.552 ++        module_customization.post_register_types(root_module)
  15.553 ++
  15.554 ++    # register Callback<...> type handlers
  15.555 ++    ns3modulegen_core_customizations.generate_callback_classes(root_module.after_forward_declarations,
  15.556 ++                                                               callback_classes)
  15.557 ++
  15.558 ++    # -----------
  15.559 ++    module_apidefs.register_methods(root_module)
  15.560 ++
  15.561 ++    if hasattr(module_customization, 'post_register_methods'):
  15.562 ++        module_customization.post_register_methods(root_module)
  15.563 ++
  15.564 ++    ns3modulegen_core_customizations.Object_customizations(root_module)
  15.565 ++    ns3modulegen_core_customizations.Attribute_customizations(root_module)
  15.566 ++
  15.567 ++
  15.568 ++    # -----------
  15.569 ++    module_apidefs.register_functions(root_module)
  15.570 ++    
  15.571 ++    if hasattr(module_customization, 'post_register_functions'):
  15.572 ++        module_customization.post_register_functions(root_module)
  15.573 ++
  15.574 ++
  15.575 ++    # -----------
  15.576 ++    root_module.generate(out)
  15.577 ++
  15.578 ++if __name__ == '__main__':
  15.579 ++    import sys
  15.580 ++    main(sys.argv)
  15.581 ++
  15.582 ++    
  15.583 +diff --git a/bindings/ns3modulegen_core_customizations.pyc b/bindings/ns3modulegen_core_customizations.pyc
  15.584 +new file mode 100644
  15.585 +index 0000000000000000000000000000000000000000..ce57d2480927177d87cce5535d01e7b1eb9f3422
  15.586 +GIT binary patch
  15.587 +literal 18612
  15.588 +zc$~dlTWs9ec|PPwBhBb;-7I^(roFK}(%RZ=Hcb=Rt45Z!US(}rp|tU?HZDsIDT&q$
  15.589 +zIVL%_Cy|mMP8ugb8=ytdHhpVQphZ#SCFm7s(WXy*Xd9q6^sSeNzVszPU)%oQ|C1b!
  15.590 +zF1y=@mE}1ao^yE4;eY<?_aEvfKOHE4^<Qp&zN(Uc1N8YUeIid&%Ax<7+Er>pzUyjN
  15.591 +zQ#D;}6qJVRg4*p;wQjZ1t!hQJQIy&)wcDd=y=tRZ)k<okB(>dYx2$S?YNJoCi#%4p
  15.592 +z+US?-9v*8zZ4AgY%{!<z26^6IwL7G0!)jwVYa3A;Bg!c$x1hXJYD-g2S$#vPXG*=h
  15.593 +zF{<2AeA^h~=5ggsD0fUf)0Bqm$=vmOW6J4MZjndm&qg?{oB_UfiW>&AhBL|;!o|i}
  15.594 +z<qY$e7nC!?U(PA#6n}Y9IivjLymH3)i=mux{&GP%6a3|(awhr9OL&^K%4s6G_rLUS
  15.595 +zr9yO9aTgVvcH~xcT=h|5x^Xk~zhKvzZd{`4RXeonZtRBAWrB*uW)uhY#YW?<8}9_p
  15.596 +z{m^bS+%P_yZ(0oeC=Q#|I0%z=nQ)MbyKX%QTZ@6?u6h2h)MM&u+-kTDJB-rKy{K$7
  15.597 +zsx>=`q-GRz(2ciU-wo~93;d-p48r&f)vwj<FkTHjpBB3w+J3YZgmvzdaUI6E39h?E
  15.598 +zg-c}7u<si>hyyAWz<c=81*XH7Ztxkt6v0~f(gU8tmtJMAReCVmAJDjEgZ{1Wc#*-&
  15.599 +zH5y^?*mK;-u#Jm&E+g(((nTZQv1224eJ3*Fz=)cS20aIlva)vVH6y~)7!7%xXx1>Y
  15.600 +zjfkjob;qzH<Kk)@-gqMj=8df&xM<j+%lBt9xsE}%)8GN!xa0ZTM$OxG+at~T?vu(z
  15.601 +z8erz)RpTPYxSAWl4Xxk_kvZD&8n3@$*CKbCmLdFMJO+cbSCTE{*fr$%DnBiEuG+Pl
  15.602 +z%obT8_iN8bEK()n?YKtMcigbn!ea!R58Y}U89Vl4nJ#o`xh{HEgQg!-pR2}d>!#;B
  15.603 +z#3_ao&{8o(=xy&1(Lst?nORG?q5#IiUQUC}=)b1+NEUVF>5xb*CL!$tn>^zNs~e27
  15.604 +z#xk)I8B|vM=(V}Iy}3F0Jq?Of-uwCa2QN?0e=(Z*Sfz-8yD>$Rq`@qu3~pJT@5PoC
  15.605 +zV=Q`la8xy@H@uoFRZrWZ8o9Nt3K*G-Xq}2zc4%{7iR~}hyWT51+fRaUH+sd7uDy26
  15.606 +zsk+zbp?B<u9`#78=*w&Mz-iXpZP&M|LFigl7FzF1%$U(^qh&%Gr!YeoOU<ZO#Y*r5
  15.607 +z-6@^^jtU}#NB@Z;OqYFK(TevAYEK7s9`>q0lrYt9>1s`*`izKPH|V<GrS`g%SA^VA
  15.608 +zWpGAmbWJpn>+{r3M4};mja$4D1QR{aW<B}3&p6nX<aTnuTkUo8@ZEgVAhmR30q3cO
  15.609 +z`%#AiFOIhpPq^aYS)(Fv11T|szZ(2KLX$DWzvkvDW$4SnbYDrZt2_LSnU^<gCGcIY
  15.610 +z+75$eL$*H-y+&N-ZzST;6EEJ0!G1N@=X=&eQoY~|=mxa%vdp2B3491ISfb9oyvX9U
  15.611 +z@!)8Cm8(g{EL@!cyTmVojkn#{BGGHhy#=*rQH2*r=P>_^%uJ`WqBfxQ>Eqfk{gml5
  15.612 +zLS<PW)&_;m@QixOW>XoP36FhI2b&3xt+8N;B{MO2r7I<riTliRsl{=c^?J)nDRmMg
  15.613 +zft@@|5p2lE+j2E758Ru`);+ZRrRX1eTH0gMKj2xCAL3GC+Z+BRx{}tyfmWSbd+4f5
  15.614 +zeVtVl2^i$Cpr#VCbtw^t;1mfZ%N<FDF|l7%{t(p^^EEMD71g!|0mCRg>O74yDMC)O
  15.615 +z@9~_!Oae^pJ<99FjC4OONu%qv3Z7{tK81%lWK6jFu+H~*N5;UrP@zzu#-&IE&zSfA
  15.616 +zhrE_(@L=ma{6|$`ZCYk&h?<*hflZLs96^zJ9t#oq7Ma(;Ji}rWHybq(*qTR@G{UMj
  15.617 +z2JiZr#pXv6DeOl9=H9V=hn|A(w8QNv#y0Lg;jdUtKnBNRx5k8b6c4ac2}3eoQq9^v
  15.618 +z8RaC{68=*)bnV!+@(=JyOnQcS5@JXny;zvidbCsepmt6lqMB-VqWv>V2`V|P`#s)!
  15.619 +z(xMZoMZBD9PpfK2@r_H-ydeg1)pd6hAI+#-il(RAeqE=iFnKE7nLt-k!aFW)ulRmK
  15.620 +z<SO}t)@CiJ?((Jkv=O>dgdIBpg7$ST{7p=zGa)mAb)^J@<O{WkY*Qq#4|Uam$Z8N-
  15.621 +zjYKtTH8Og#6=9d1b^c5=dPoGAkW6^<6%-%CV|P-{#N6hqC_a%A<s+s{DU*Go%Uf-w
  15.622 +zcUG(9d>?2;@_ovDA!E{I4_`V#)w0+ZVM#R&6tgH^L-8{m5AqRvL|8JY$r`9wDr%*!
  15.623 +z(kOk#N(Fw>g>d^Z`_+eI4G=sZYq;!6l5VBoVp}2$EsZSnc4PrL<EV!nRf?w`lcGU5
  15.624 +zLA2cod;^;5TCjBu{)E3x4dHgPPA&wZ3F>5fp%H8uS4h;*R82hX9Xm8;==$+{53Xdl
  15.625 +za0Jpo)WWX%;%u2a-}5O}kjb*aH(l~g;Y~lGe#TbQuYyFmk*>`fUVH`Xtb3tdt+^Lu
  15.626 +zu$3To=iqu%Xq3hu1_wro4l=044`OoVx9Q2qn|F-OmSOuX13Yq_2dUG(&=QPhM6D#~
  15.627 +zHLvQ$wN~QGLjv@K@+@#=v87+v#94293#@NwMay;4`&hT@utg9dVjT|_e3C@2C#9HW
  15.628 +zkFBZ|2bS!zlhY@MTyT1>L}QQ<BpxE}f!){1PV0%CPTC6ahM$SwlvQ>oy`Qmf(5^4S
  15.629 +z+@rFaD<$yh1qkAlVfZJv(|Mj1$l9|j4;Q-+MqrO!{Rv<mNlOm^4{FKR6@hz@2A~Ka
  15.630 +zUtLmOnWL?Cx4|R2^#L4lh5?AkI;c_0-E)c;(tU6tG<yGm(MMJ1qQ>CW9C(BQ<qe{`
  15.631 +z^SX<#nXSgz;xSgzy2pX(4Eytqmc_qGrcwu?Dq#f);mi!{yw#RPrs_*%jisyelz02y
  15.632 +zg$SnZ@@nf2$%3^GPXT;;IfBw7o&UN~5mBC*HtOU_1=R|M3AVU;W_l*MbB!w5%wFdO
  15.633 +zZiOyiUS|NLOq!W&M}=mc#*iPsZlo7CjE(^+^em9VX}UG-^YY8n<u8|`&tRbR!HpR&
  15.634 +zcIz}$a`)|}b!&Nj>27|6tLXsK*UJ%TcVV@)#yZSe+;OYB6$~*QLkPEQuhxXP)Lh$d
  15.635 +zHloil#Yj@EH8+-fDs=s{$`oP=zG_^|bQRGlRTws_ODM!dU0x&_Twq$hcPV<nD^3=%
  15.636 +z5G5n?I<7O__j#dA_XC8zUKvWwYdoBJC$9C_4n2Fb=5ipyehULz7VEx<9YNc1tV|WM
  15.637 +zBeCgjv38&hW$t(q(i$xIH#|0ONJt@-;3}FZ5^TWpciI2+e21Q%omd&b1!1fzh|5;D
  15.638 +z=_g$nbfd}ARpD-EJl|=DoaXgZ8zwu*Lx7j@j1p%poRCYASCXP1p((4|Dsirq_5#IJ
  15.639 +zr|I)jS3mi&V_K;IZ?>cl>Lm(03tFF6qHq&|=NSq(*%2{6h2m#Xd>VzGZrH75b7^sX
  15.640 +z`QD1Pyu#a&Rje_k7T4chU0O45;HLGH^hF?YUr6m6`67D1R@BK4nZ%-KJ2&m>E-c$>
  15.641 +z7(8tWMtj&RG1Lbkps5dHtJDW!V3TpnZNXm|-fUnR<FOaUO}l2)c|Pd{-a?Pat9v9B
  15.642 +zH8JH*>cL3Y#CT(>^uyNeoH_)=N#KbXGiT3ngULwDJ1D@@QkR8l5?)#iS@K3^QWu>R
  15.643 +znD*VA9Z%uL%#Qz+%0X$g4>2G|ZJ$Fc+Knmx6c8;06B4>h{iOW9!9bQuEp<06c;Wy^
  15.644 +zWj72uqWE4IIl)mf3nyKAVBYsS>$($rpRenMneV)>Uo7DOZ3uj0MtPu};8TJD7<ld2
  15.645 +z@fa~aX}T(zJp|qsN2Ek9MgUmhUSxBX*tlt<)4H0#XrsxtMz(G?y_&<=vRF4z`l`Xc
  15.646 +zI<?+fS~Qp5kd}{&A|sX{cHo<3Pz!=1Un_Oiz>p%cRk&%S^QPC0mACKQVUy4vJ!_x7
  15.647 +zz9In*SZ@;xOVulu15BvRekLBmM9^q1p;%T4#`lmyWE1AjT<PFv^8t$K6VkV1ykL>^
  15.648 +zRN;a&zoHVLM(N|EY$xc`uT7G=9V5jmk>>%W%0b*OoTQS3GWd>4fZSpM3X(l&EPFVS
  15.649 +z!03lm^YnN0I7Jt4J@~#Z2;;W}e^YRo#kD5=^PD?Pe4Al4NXEAnJVTG&>*uPY7hPum
  15.650 +zw~C1nv4p|}ea`;(6fkS{JjI{fXW89jr<r;^EUI8cX*(KxU=ra^0jlev3R+cBwO&v$
  15.651 +zJIrLp_ZZ&ZE2>}8fXLnV7gQJVANi^%2O;eb%PN>wnzrAoG;*%IVW<O|_BpAEUbR(F
  15.652 +z6XY>KwLTh9KK*)!tm=M=A@wrC)UN$LJQ=Bp^S2(nsP@UH?}vhTSYVWYuMgL!9=)b%
  15.653 +z^!ZAk+8<C)f5J%SfKc|w3_=d7{UHt&1~Js+#Qtzffgz^A2vcC>!%^U}+AAR~OO8Q8
  15.654 +zhY_a3Fq48a2-^Ke+uBjIc%_pT{a66qn2@6@BL@iq5r78K-l5|DUYQ{q5Qzql$ANy*
  15.655 +zBA{<6>^Oy#FTmIVL@wK~TN>~Bqy!$qD?=(}hSO}@pgxE35L=r1mQvrMQpb)^eDjNv
  15.656 +z58fYDG~<1?dH_#X+9*(J@C6D=HQyNPCJ1caA-Lp4pP&w9$xu@NIiu0sq#)Yp7z$kh
  15.657 +z*^zrM&2wy`+fII4K}uMDDXO#^)23-|`ZAYtJNZ$pDzhHfv&Qy_q?0=b-{&%QFTO%^
  15.658 +z9WipEgxkX$H#RhPI&R0nn?X=BmZPOdbWzFhH36RwQRk)|x${OqswuRPKA#qp`oOy6
  15.659 +zW+L+p_oUgK7CAs(RY1|SdFDuLG&gweS-h>J#ke5PGMzO^8kCc>(&gHG{>fiAjwFs-
  15.660 +zi`=7z*g^^`Ba|5CZk2$#3}#2b^k(qSc-u#)1B0J}H|;&_NEjPeE=5-ijz^3NgE*cK
  15.661 +z6FX;I3K_^}mzIg))*Epv!ju$i5aWKx+1l6=O=TQE8&4E8VA_JPGA&smirs)gdRrdZ
  15.662 +z<_H#I|9Y9->P}h866l#*jdgO`@Vx_WHR%%|eFf!q!K3OTTjCa>-JY|0n$VX&=k@}d
  15.663 +zK(8{4#RluyjsDaTA4rcP48kMlNDqq@XFS2qA_m-rJSkC-C(pJ&>4zt0D~R>NFs`v*
  15.664 +zs^?Np0thiIU0_%mo?aI~736b&EEotsfg@?AUe!jM*d95ld7RwNdL%$mA0QZqQKE?i
  15.665 +zf9fUEsOLv5a`gap=*e|RkgGmua2T#a(rb@3Wd_!WGH0a96LjblTZBU9@cO5;BOU=>
  15.666 +zZQ+BSf{X+y>1T!f00Rf7nn?N%s!5?7#_h^2eu&qswbxA5V;L^>{uGiChB;Gr;0ZHo
  15.667 +zbajk8o*#J-CZ&T^DUNlD3=2$3^pZ-DiYWEjk<5ayk>_eGzWj1>@}m>(g6Q5eIj&3)
  15.668 +z9f%6VG{JO8>KJnRVDzR#fUjf#j&O3#1#Z)?av2b^Q!LAuBCEP-d8C{<k;RdL=xt7S
  15.669 +zNeYU+`H4fOGi^((r)2I)xiZudG~iQ`IvhFbK1KqpHcg<QX(Z#z(QM}`I_5fRVbj-5
  15.670 +zP-vxs^(DDXkCd(LSKTb*n94h+P~Ql`Cw7>gzk*HT)DMG8j=N<yYq6}%L~ls}ahSoN
  15.671 +z%^N6gXYmK(j2I28@2<ajZ^c?%xO3;`!s1)j^4--t*2==&C5}$aRTQ5`VWo4eFHx6;
  15.672 +z^(AY;yuBtN&0Q48XXo-z3?%hQD3vNE$%rNwynAeAc-1EnC1BwH#ticu%>WcStr=QL
  15.673 +z>(K_O#OZ{7z)0E!{j7GGeveXJzdorA=-fx|*G_38`hYg9XXyt$)vFMwI1TEbX;~gZ
  15.674 +zQlwj;iTju~(>0PrLu3Gv?c|r)+1Yu{lSD=(k;rD0*X@x(d+qsR-AF*EIg8@8GaIv#
  15.675 +z)qo9WP;e!P*W|R>p{xh*(Mix9pxJpX!$br`JrFbA$AURbYY8+N#SR&BlMhls&G<;o
  15.676 +z*BCuVE?baYN&CNz0vMTDLs3@=M#mG&0~S&-V{cfXP2Mr`JZc>9W?{M<M65;a12rEV
  15.677 +zW#Cf$7iK_^TGWcfb7zPLi-7oMDvTyW&$xcG&T+Zfoynr4ti0H*`67VD^brMn<^u;9
  15.678 +zHgxO3W4G<<h|Fp!y?ytI&^-=?Yp^@e(RYGix7m;rmlH|dV&HFi+s*u8Oi+sylMkGo
  15.679 +zbtx`*b@!!K^hf)A24Z!-D+L=^b#TpAtr_iDaZnjcR~Iy6ra;F3%+wt^#3JIDchZ$-
  15.680 +zP2$?-AwfBsF_S8$q?YM~)wxf3rYyP1mBB7Qll9)K4|qM)D!_C)O^$DRq#f%?VRIQh
  15.681 +zy<o2EQwb!QtOr8Ke9&f8vx(v{iYFf>`>_ScAfN1!SVY|Dw=nevOYDH^hc?v9T5;+!
  15.682 +z&TnZ$q#H+cfb1{OPe~gf{n)F6gFnT+2laN3%iLp_dJNI0hgv3Rqyf^ZjE;iLARVKl
  15.683 +z0CD!@$i#kn+C-c)Cq+BSQ`{~{tS!xwtvt5541e$V=6-hT4mY#%9%SX6okLpl>dhKr
  15.684 +z2;S1Q>W&Kn$2ezgL91I?2P<prX1=ybIKYZ`m)763zOZ1zc(OU<ino^Dy?@WVwZ_cB
  15.685 +zHEZh&>&uILosP5;JmFK<$IXQHp<Mr4E{Sx|iqF5#J!v1|I-gnlU|*`2G&;D2vr^1Q
  15.686 +zmcYAKnl|T53UrWg9m`TS$VuRrr}GmYXrF=gImNtOE(~eIUCD=dG2_8v%7gcg;Xyvy
  15.687 +zDsLz}<3NwN1_$$!5Fy7x!jjv1n~}=QNW&>3Ee7>EId^xw<iO}ERCby-e$2G<BC>I`
  15.688 +z`YQ9<f+L7GpM94d%8g;A&E~ITBYy+M_f_JLu}#3f$%cu0_?b){L(Ih|_(7@}b0eR`
  15.689 +z#+~V$@<5ND(-NS7woZGIl?ZQHdf<w;Y?q4GU~bp$`(vt$+%bTEy-L$$8?<*M%uYf-
  15.690 +zNifM_tZxYT%g6td2u{x*1SoWz0_f)L>`S*(BBP9xAWiHO!p}^iPD%Rks0dE?wIp97
  15.691 +zP;?r1>q*~<Y^DOw^mQuB!Vcmw!Wb_*#%(uFzEvIvo`W2{VI0vf_M9{}N&8>C6kQZN
  15.692 +zX_g{1VnDKa=?OEb2OyLHM0Ef4@;>L#SJte1H$S(uxNa@2ti5e6S?1F1<+b%CbLp0Z
  15.693 +zToMFKrRqQ&E@tViX00YhaO5ae!V=7R@*s+>?d+uwPJdUjOzn<aBYh)QibV!U&Pnj;
  15.694 +z$breN9rBRY!Jd#%)jLIzL9u-jush{~UxPkLP!=U9i{6eC`t$XCz$KVuI3{5RiSVg4
  15.695 +zP5gCd9STQuV5~wQ1)Pg1bO0uNG(Ju8wa>t_O5hYMPT<-;LJCCT>03P%ZE(Om^S(Vi
  15.696 +zA1^YH=65-QnPzP#F|qpus4>UmeO!5M-gGH;CT4-<=Rnqklh2;MjBjnaR&IQg59Iz(
  15.697 +zC2n4OGIp^zS`}@_-eRL6Tf~PTnGI_a8^fPTPZr3~5>A}d;rUCVGAwzg#Y#i|EGcTG
  15.698 +zhwPwClC0YxMXBU@@yU6VXF8APGLJ!Yvh$=l$SD_sp3NB_rd;;cmWVAMtk39Z{-H|G
  15.699 +zkp2-05YGH#buy{QnNBLPJ~*CKjV!d(88Kyp`Ig&~_+&g$Du*POUu3|+@8d^~UrM@s
  15.700 +zzzT$7KS+5^%z^nMRQ?HyKRqG3jc1b|XuO?qQ%^w~q@QA;G%%o-21;E6VopK0%mae&
  15.701 +z@bp&`TXgHeb4BLr=~ok*`3zN$U_+nofYnH2-Fol<){}G+DV&(GZ@jK>OY&YR_=+P9
  15.702 +z*QBbKUl}T?;GA5S(^rV_o+jH}tE?V<M`@3)@#p@dbMz@ENinvGa>PH5LvOPgyX^h2
  15.703 +z6flb~A)nCMSb^q|_pKzpVLgHjJ<ddl1&V~tcTk`w=fv@TBkK}(D@z54bTG08*Mk)(
  15.704 +zqjVie9IF<2O@(=*z>|y7!i4PlaV&UJ{&7Z<1MN@29|-c*Kv@+jf-7qHJxV_~K6N-w
  15.705 +zyQcmhaT;$Lza!FinZylY0t?V^v$aCBeZ%%@Yxb5K!_^Q!S9)4U^*Z40n!gDuvK~9&
  15.706 +z)q=BSoRbp6WYwLG-_?>M3W`JM>~K&iCF`H5^l*^V_6xN(WuIxuNg)zCdCM*BQA}yy
  15.707 +zBQB*5A6MrLGzr^T<-DMrbIN&9Ip>vQsO_S>y~FS5NlxAw$9u$7n_NyR=d^OBkPM<t
  15.708 +z+!jw6H;^!&fxIH)T_8`Sl;yRt&+H>II(}n|%!_N+=UM6kxnSbp;G?%q^dmbB%NsT9
  15.709 +zs>|uWxw$BI7)!M`=?1$>euf>n@|vw6^vS5arww*n6Xf3Y>o_OLFioSu;T{b(H|GTr
  15.710 +zr&j0Ys9Kt1_sHhh<xw|1-ws=x+&IufS{NB3YcO)SgXf#yR7tFPpb1bGdnh4U4OYen
  15.711 +zI!FUtTuBzoc_;zKyqe2|no4Oz<0XWkZ|S46Vxcdrlq7>&3zGM}&A&fpT|^Y=@DImz
  15.712 +zh-HN6!_Y>0z8`_4M*{90Ln!I<!PMfonqyX&cybDBO-G;yIX(-fnM!Q<k#416bJQ0Q
  15.713 +zD_aD<vHd=~0GE3xelOGXV@W?+l7$te8zAT%G>-YVD1M?&#_kX2)|0Zu_q6OK%mHnj
  15.714 +zK4-O(R>*$J`ndLjHmYaFKhr_r9fy+_^bLmp3P7@356-v4W=~JfAL5*$ya)JbRNa3%
  15.715 +z3oPx{gUg)2Rk>FM3ds?lTx#~w>xngIjE&!UYBPhiOjNy>P_=_c+T3m;x;Fm_#Wz#-
  15.716 +zWhOWO8O1;1rq3#5A@9nYMhlL!?8of&+J0QAUp2BLhZon@Z&}Ot)+`E&uNv*S*fG{S
  15.717 +z<l@6Djl-%`2vSZ@6;G<4+T7iiE4Gr1@-<pi<ItYZ<}-n_;C+VaP3$bY90DeD6vHni
  15.718 +zyCJ(q;0La>Yo0Cd&e>b!y6_9=a`q4_Xfk-$_EAdtxw(hjj~;+APa<FRuQc%QYDrc^
  15.719 +zY5iIc`6B0Zl>OS_m-s)eI#1L-%OYtpoe9FT$A3j+DmyrPqa6T8e@<n&7Wms`3vtJC
  15.720 +z<MAhnTkvL~6*sIMJK8aFhn^@b5v0XfZLLJF<$4=4M0TA0A^V1tJ&n*!UWz>2bKa<6
  15.721 +zAU<}Jz$}8?$PHLcnmo?k_a?7p+NkhM*XA(<jj><m6f|x!KI|i07vTDs-mFz~^=!nG
  15.722 +zHi@+P&xr(1%WSE{#oBRghuDuTbBj|S{0@9Ah~+POFpHg(ugeyJ)^FLJ5B8%BvC&FB
  15.723 +zJvhV4@B=5^CytdomN${S|5Qo-Ox_+C?YM_rngnNMTfp(?`Qzmo&=%h1ki;Iphrx)*
  15.724 +z*HHXB3dTLcRM_EGcK*2&`P&kl{Ns9FPcFBWDTPU{m*YZK=ietW|3f91Fi(;ss`Ez;
  15.725 +z__Y1^Q2aKE-$(HmDE=D7-=O$66cAnWr|RU6{;~nTA-(4LP#NC9?AM323Hll4AG*@}
  15.726 +g^{IstUlj@ypPV{fdR`hY^_E^OO_qwKu~Ogv0Zb@~5dZ)H
  15.727 +
  15.728 +diff --git a/bindings/ns3modulescan-modular.py b/bindings/ns3modulescan-modular.py
  15.729 +new file mode 100644
  15.730 +--- /dev/null
  15.731 ++++ b/bindings/ns3modulescan-modular.py
  15.732 +@@ -0,0 +1,281 @@
  15.733 ++#! /usr/bin/env python
  15.734 ++
  15.735 ++import sys
  15.736 ++import os.path
  15.737 ++
  15.738 ++import pybindgen.settings
  15.739 ++from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning, find_declaration_from_name
  15.740 ++from pybindgen.typehandlers.codesink import FileCodeSink
  15.741 ++from pygccxml.declarations import templates
  15.742 ++from pygccxml.declarations.enumeration import enumeration_t
  15.743 ++from pygccxml.declarations.class_declaration import class_t
  15.744 ++from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t, calldef_t
  15.745 ++
  15.746 ++
  15.747 ++## we need the smart pointer type transformation to be active even
  15.748 ++## during gccxml scanning.
  15.749 ++import ns3modulegen_core_customizations
  15.750 ++
  15.751 ++
  15.752 ++## silence gccxmlparser errors; we only want error handling in the
  15.753 ++## generated python script, not while scanning.
  15.754 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
  15.755 ++    def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
  15.756 ++        return True
  15.757 ++pybindgen.settings.error_handler = ErrorHandler()
  15.758 ++import warnings
  15.759 ++warnings.filterwarnings(category=WrapperWarning, action='ignore')
  15.760 ++
  15.761 ++
  15.762 ++import ns3modulescan
  15.763 ++type_annotations = ns3modulescan.type_annotations
  15.764 ++
  15.765 ++
  15.766 ++def get_ns3_relative_path(path):
  15.767 ++    l = []
  15.768 ++    head = path
  15.769 ++    while head:
  15.770 ++        new_head, tail = os.path.split(head)
  15.771 ++        if new_head == head:
  15.772 ++            raise ValueError
  15.773 ++        head = new_head
  15.774 ++        if tail == 'ns3':
  15.775 ++            return os.path.join(*l)
  15.776 ++        l.insert(0, tail)
  15.777 ++    raise AssertionError("is the path %r inside ns3?!" % path)
  15.778 ++
  15.779 ++class PreScanHook:
  15.780 ++
  15.781 ++    def __init__(self, headers_map, module):
  15.782 ++        self.headers_map = headers_map
  15.783 ++        self.module = module
  15.784 ++
  15.785 ++    def __call__(self, module_parser,
  15.786 ++                 pygccxml_definition,
  15.787 ++                 global_annotations,
  15.788 ++                 parameter_annotations):
  15.789 ++        try:
  15.790 ++            ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
  15.791 ++        except ValueError: # the header is not from ns3
  15.792 ++            return # ignore the definition, it's not ns-3 def.
  15.793 ++
  15.794 ++        definition_module = self.headers_map[ns3_header]
  15.795 ++
  15.796 ++        ## Note: we don't include line numbers in the comments because
  15.797 ++        ## those numbers are very likely to change frequently, which would
  15.798 ++        ## cause needless changes, since the generated python files are
  15.799 ++        ## kept under version control.
  15.800 ++
  15.801 ++        #global_annotations['pygen_comment'] = "%s:%i: %s" % \
  15.802 ++        #    (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
  15.803 ++        global_annotations['pygen_comment'] = "%s (module %r): %s" % \
  15.804 ++            (ns3_header, definition_module, pygccxml_definition)
  15.805 ++
  15.806 ++
  15.807 ++        ## handle ns3::Object::GetObject (left to its own devices,
  15.808 ++        ## pybindgen will generate a mangled name containing the template
  15.809 ++        ## argument type name).
  15.810 ++        if isinstance(pygccxml_definition, member_function_t) \
  15.811 ++                and pygccxml_definition.parent.name == 'Object' \
  15.812 ++                and pygccxml_definition.name == 'GetObject':
  15.813 ++            template_args = templates.args(pygccxml_definition.demangled_name)
  15.814 ++            if template_args == ['ns3::Object']:
  15.815 ++                global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
  15.816 ++
  15.817 ++        ## Don't wrap Simulator::Schedule* (manually wrapped)
  15.818 ++        if isinstance(pygccxml_definition, member_function_t) \
  15.819 ++                and pygccxml_definition.parent.name == 'Simulator' \
  15.820 ++                and pygccxml_definition.name.startswith('Schedule'):
  15.821 ++            global_annotations['ignore'] = None
  15.822 ++
  15.823 ++        # manually wrapped
  15.824 ++        if isinstance(pygccxml_definition, member_function_t) \
  15.825 ++                and pygccxml_definition.parent.name == 'Simulator' \
  15.826 ++                and pygccxml_definition.name == 'Run':
  15.827 ++            global_annotations['ignore'] = True
  15.828 ++
  15.829 ++        ## http://www.gccxml.org/Bug/view.php?id=9915
  15.830 ++        if isinstance(pygccxml_definition, calldef_t):
  15.831 ++            for arg in pygccxml_definition.arguments:
  15.832 ++                if arg.default_value is None:
  15.833 ++                    continue
  15.834 ++                elif arg.default_value == "ns3::MilliSeconds( )":
  15.835 ++                    arg.default_value = "ns3::MilliSeconds(0)"
  15.836 ++                elif arg.default_value == "ns3::Seconds( )":
  15.837 ++                    arg.default_value = "ns3::Seconds(0)"
  15.838 ++
  15.839 ++        ## classes
  15.840 ++        if isinstance(pygccxml_definition, class_t):
  15.841 ++            print >> sys.stderr, pygccxml_definition
  15.842 ++            # no need for helper classes to allow subclassing in Python, I think...
  15.843 ++            #if pygccxml_definition.name.endswith('Helper'):
  15.844 ++            #    global_annotations['allow_subclassing'] = 'false'
  15.845 ++
  15.846 ++            #
  15.847 ++            # If a class is template instantiation, even if the
  15.848 ++            # template was defined in some other module, if a template
  15.849 ++            # argument belongs to this module then the template
  15.850 ++            # instantiation will belong to this module.
  15.851 ++            # 
  15.852 ++            if templates.is_instantiation(pygccxml_definition.decl_string):
  15.853 ++                cls_name, template_parameters = templates.split(pygccxml_definition.name)
  15.854 ++                template_parameters_decls = [find_declaration_from_name(module_parser.global_ns, templ_param)
  15.855 ++                                             for templ_param in template_parameters]
  15.856 ++                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_decls)
  15.857 ++                
  15.858 ++                template_parameters_modules = []
  15.859 ++                for templ in template_parameters_decls:
  15.860 ++                    if not hasattr(templ, 'location'):
  15.861 ++                        continue
  15.862 ++                    try:
  15.863 ++                        h = get_ns3_relative_path(templ.location.file_name)
  15.864 ++                    except ValueError:
  15.865 ++                        continue
  15.866 ++                    template_parameters_modules.append(self.headers_map[h])
  15.867 ++
  15.868 ++                for templ_mod in template_parameters_modules:
  15.869 ++                    if templ_mod == self.module:
  15.870 ++                        definition_module = templ_mod
  15.871 ++                        break
  15.872 ++                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_modules)
  15.873 ++
  15.874 ++
  15.875 ++            if definition_module != self.module:
  15.876 ++                global_annotations['import_from_module'] = 'ns.%s' % (definition_module.replace('-', '_'),)
  15.877 ++
  15.878 ++            if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
  15.879 ++                global_annotations['incref_method'] = 'Ref'
  15.880 ++                global_annotations['decref_method'] = 'Unref'
  15.881 ++                global_annotations['peekref_method'] = 'GetReferenceCount'
  15.882 ++                global_annotations['automatic_type_narrowing'] = 'true'
  15.883 ++                return
  15.884 ++
  15.885 ++            if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
  15.886 ++                # manually handled in ns3modulegen_core_customizations.py
  15.887 ++                global_annotations['ignore'] = None
  15.888 ++                return
  15.889 ++
  15.890 ++            if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
  15.891 ++                global_annotations['ignore'] = None
  15.892 ++                return
  15.893 ++
  15.894 ++            if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
  15.895 ++                # handled by pybindgen "type transformation"
  15.896 ++                global_annotations['ignore'] = None
  15.897 ++                return
  15.898 ++
  15.899 ++            # table driven class customization
  15.900 ++            try:
  15.901 ++                annotations = type_annotations[pygccxml_definition.decl_string]
  15.902 ++            except KeyError:
  15.903 ++                pass
  15.904 ++            else:
  15.905 ++                global_annotations.update(annotations)
  15.906 ++
  15.907 ++        ## enums
  15.908 ++        if isinstance(pygccxml_definition, enumeration_t):
  15.909 ++            if definition_module != self.module:
  15.910 ++                global_annotations['import_from_module'] = 'ns.%s' % definition_module
  15.911 ++
  15.912 ++        ## free functions
  15.913 ++        if isinstance(pygccxml_definition, free_function_t):
  15.914 ++
  15.915 ++            if definition_module != self.module:
  15.916 ++                global_annotations['ignore'] = None
  15.917 ++                return
  15.918 ++
  15.919 ++            if pygccxml_definition.name == 'PeekPointer':
  15.920 ++                global_annotations['ignore'] = None
  15.921 ++                return
  15.922 ++
  15.923 ++        ## table driven methods/constructors/functions customization
  15.924 ++        if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
  15.925 ++            try:
  15.926 ++                annotations = type_annotations[str(pygccxml_definition)]
  15.927 ++            except KeyError:
  15.928 ++                pass
  15.929 ++            else:
  15.930 ++                for key,value in annotations.items():
  15.931 ++                    if key == 'params':
  15.932 ++                        parameter_annotations.update (value)
  15.933 ++                        del annotations['params']
  15.934 ++                global_annotations.update(annotations)
  15.935 ++
  15.936 ++
  15.937 ++# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
  15.938 ++#     ## classes
  15.939 ++#     if isinstance(pybindgen_wrapper, CppClass):
  15.940 ++#         if pybindgen_wrapper.name.endswith('Checker'):
  15.941 ++#             print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
  15.942 ++#             #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
  15.943 ++
  15.944 ++
  15.945 ++def scan_callback_classes(module_parser, callback_classes_file):
  15.946 ++    callback_classes_file.write("callback_classes = [\n")
  15.947 ++    for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
  15.948 ++                                                      recursive=False):
  15.949 ++        if not cls.name.startswith("Callback<"):
  15.950 ++            continue
  15.951 ++        assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
  15.952 ++        dummy_cls_name, template_parameters = templates.split(cls.decl_string)
  15.953 ++        callback_classes_file.write("    %r,\n" % template_parameters)
  15.954 ++    callback_classes_file.write("]\n")
  15.955 ++
  15.956 ++
  15.957 ++def ns3_module_scan(top_builddir, module_name, headers_map, output_file_name, cflags):
  15.958 ++    module_parser = ModuleParser('ns.%s' % module_name.replace('-', '_'), 'ns3')
  15.959 ++    module_parser.add_pre_scan_hook(PreScanHook(headers_map, module_name))
  15.960 ++    #module_parser.add_post_scan_hook(post_scan_hook)
  15.961 ++
  15.962 ++    gccxml_options = dict(
  15.963 ++        include_paths=[top_builddir],
  15.964 ++         define_symbols={
  15.965 ++            #'NS3_ASSERT_ENABLE': None,
  15.966 ++            #'NS3_LOG_ENABLE': None,
  15.967 ++            },
  15.968 ++        cflags=('--gccxml-cxxflags "%s -DPYTHON_SCAN"' % cflags)
  15.969 ++        )
  15.970 ++
  15.971 ++    try:
  15.972 ++        os.unlink(output_file_name)
  15.973 ++    except OSError:
  15.974 ++        pass
  15.975 ++    try:
  15.976 ++        os.makedirs(os.path.dirname(output_file_name))
  15.977 ++    except OSError:
  15.978 ++        pass
  15.979 ++    output_file = open(output_file_name, "wt")
  15.980 ++    output_sink = FileCodeSink(output_file)
  15.981 ++
  15.982 ++    # if there exists a scan-header.h file in src/<module>/bindings,
  15.983 ++    # scan it, otherwise scan ns3/xxxx-module.h.
  15.984 ++    scan_header = os.path.join(os.path.dirname(output_file_name), "scan-header.h")
  15.985 ++    if not os.path.exists(scan_header):
  15.986 ++        scan_header = os.path.join(top_builddir, "ns3", "%s-module.h" % module_name)
  15.987 ++
  15.988 ++    module_parser.parse_init([scan_header],
  15.989 ++                             None, whitelist_paths=[top_builddir],
  15.990 ++                             #includes=['"ns3/everything.h"'],
  15.991 ++                             pygen_sink=output_sink,
  15.992 ++                             gccxml_options=gccxml_options)
  15.993 ++    module_parser.scan_types()
  15.994 ++
  15.995 ++    callback_classes_file = open(os.path.join(os.path.dirname(output_file_name), "callbacks_list.py"), "wt")
  15.996 ++    scan_callback_classes(module_parser, callback_classes_file)
  15.997 ++    callback_classes_file.close()
  15.998 ++
  15.999 ++
 15.1000 ++    module_parser.scan_methods()
 15.1001 ++    module_parser.scan_functions()
 15.1002 ++    module_parser.parse_finalize()
 15.1003 ++
 15.1004 ++    output_file.close()
 15.1005 ++    os.chmod(output_file_name, 0400)
 15.1006 ++
 15.1007 ++
 15.1008 ++if __name__ == '__main__':
 15.1009 ++    if len(sys.argv) != 6:
 15.1010 ++        print "ns3modulescan-modular.py top_builddir module_path module_headers output_file_name cflags"
 15.1011 ++        sys.exit(1)
 15.1012 ++    ns3_module_scan(sys.argv[1], sys.argv[2], eval(sys.argv[3]), sys.argv[4], sys.argv[5])
 15.1013 ++    sys.exit(0)
 15.1014 +diff --git a/bindings/ns3modulescan-modular.py~ b/bindings/ns3modulescan-modular.py~
 15.1015 +new file mode 100644
 15.1016 +--- /dev/null
 15.1017 ++++ b/bindings/ns3modulescan-modular.py~
 15.1018 +@@ -0,0 +1,282 @@
 15.1019 ++#! /usr/bin/env python
 15.1020 ++
 15.1021 ++import sys
 15.1022 ++import os.path
 15.1023 ++
 15.1024 ++import pybindgen.settings
 15.1025 ++from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning, find_declaration_from_name
 15.1026 ++from pybindgen.typehandlers.codesink import FileCodeSink
 15.1027 ++from pygccxml.declarations import templates
 15.1028 ++from pygccxml.declarations.enumeration import enumeration_t
 15.1029 ++from pygccxml.declarations.class_declaration import class_t
 15.1030 ++from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t, calldef_t
 15.1031 ++
 15.1032 ++
 15.1033 ++## we need the smart pointer type transformation to be active even
 15.1034 ++## during gccxml scanning.
 15.1035 ++import ns3modulegen_core_customizations
 15.1036 ++
 15.1037 ++
 15.1038 ++## silence gccxmlparser errors; we only want error handling in the
 15.1039 ++## generated python script, not while scanning.
 15.1040 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
 15.1041 ++    def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
 15.1042 ++        return True
 15.1043 ++pybindgen.settings.error_handler = ErrorHandler()
 15.1044 ++import warnings
 15.1045 ++warnings.filterwarnings(category=WrapperWarning, action='ignore')
 15.1046 ++
 15.1047 ++
 15.1048 ++import ns3modulescan
 15.1049 ++type_annotations = ns3modulescan.type_annotations
 15.1050 ++
 15.1051 ++
 15.1052 ++def get_ns3_relative_path(path):
 15.1053 ++    l = []
 15.1054 ++    head = path
 15.1055 ++    while head:
 15.1056 ++        new_head, tail = os.path.split(head)
 15.1057 ++        if new_head == head:
 15.1058 ++            raise ValueError
 15.1059 ++        head = new_head
 15.1060 ++        if tail == 'ns3':
 15.1061 ++            return os.path.join(*l)
 15.1062 ++        l.insert(0, tail)
 15.1063 ++    raise AssertionError("is the path %r inside ns3?!" % path)
 15.1064 ++
 15.1065 ++class PreScanHook:
 15.1066 ++
 15.1067 ++    def __init__(self, headers_map, module):
 15.1068 ++        self.headers_map = headers_map
 15.1069 ++        self.module = module
 15.1070 ++
 15.1071 ++    def __call__(self, module_parser,
 15.1072 ++                 pygccxml_definition,
 15.1073 ++                 global_annotations,
 15.1074 ++                 parameter_annotations):
 15.1075 ++	print "==="% pygccxml_definition
 15.1076 ++        try:
 15.1077 ++            ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
 15.1078 ++        except ValueError: # the header is not from ns3
 15.1079 ++            return # ignore the definition, it's not ns-3 def.
 15.1080 ++
 15.1081 ++        definition_module = self.headers_map[ns3_header]
 15.1082 ++
 15.1083 ++        ## Note: we don't include line numbers in the comments because
 15.1084 ++        ## those numbers are very likely to change frequently, which would
 15.1085 ++        ## cause needless changes, since the generated python files are
 15.1086 ++        ## kept under version control.
 15.1087 ++
 15.1088 ++        #global_annotations['pygen_comment'] = "%s:%i: %s" % \
 15.1089 ++        #    (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
 15.1090 ++        global_annotations['pygen_comment'] = "%s (module %r): %s" % \
 15.1091 ++            (ns3_header, definition_module, pygccxml_definition)
 15.1092 ++
 15.1093 ++
 15.1094 ++        ## handle ns3::Object::GetObject (left to its own devices,
 15.1095 ++        ## pybindgen will generate a mangled name containing the template
 15.1096 ++        ## argument type name).
 15.1097 ++        if isinstance(pygccxml_definition, member_function_t) \
 15.1098 ++                and pygccxml_definition.parent.name == 'Object' \
 15.1099 ++                and pygccxml_definition.name == 'GetObject':
 15.1100 ++            template_args = templates.args(pygccxml_definition.demangled_name)
 15.1101 ++            if template_args == ['ns3::Object']:
 15.1102 ++                global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
 15.1103 ++
 15.1104 ++        ## Don't wrap Simulator::Schedule* (manually wrapped)
 15.1105 ++        if isinstance(pygccxml_definition, member_function_t) \
 15.1106 ++                and pygccxml_definition.parent.name == 'Simulator' \
 15.1107 ++                and pygccxml_definition.name.startswith('Schedule'):
 15.1108 ++            global_annotations['ignore'] = None
 15.1109 ++
 15.1110 ++        # manually wrapped
 15.1111 ++        if isinstance(pygccxml_definition, member_function_t) \
 15.1112 ++                and pygccxml_definition.parent.name == 'Simulator' \
 15.1113 ++                and pygccxml_definition.name == 'Run':
 15.1114 ++            global_annotations['ignore'] = True
 15.1115 ++
 15.1116 ++        ## http://www.gccxml.org/Bug/view.php?id=9915
 15.1117 ++        if isinstance(pygccxml_definition, calldef_t):
 15.1118 ++            for arg in pygccxml_definition.arguments:
 15.1119 ++                if arg.default_value is None:
 15.1120 ++                    continue
 15.1121 ++                elif arg.default_value == "ns3::MilliSeconds( )":
 15.1122 ++                    arg.default_value = "ns3::MilliSeconds(0)"
 15.1123 ++                elif arg.default_value == "ns3::Seconds( )":
 15.1124 ++                    arg.default_value = "ns3::Seconds(0)"
 15.1125 ++
 15.1126 ++        ## classes
 15.1127 ++        if isinstance(pygccxml_definition, class_t):
 15.1128 ++            print >> sys.stderr, pygccxml_definition
 15.1129 ++            # no need for helper classes to allow subclassing in Python, I think...
 15.1130 ++            #if pygccxml_definition.name.endswith('Helper'):
 15.1131 ++            #    global_annotations['allow_subclassing'] = 'false'
 15.1132 ++
 15.1133 ++            #
 15.1134 ++            # If a class is template instantiation, even if the
 15.1135 ++            # template was defined in some other module, if a template
 15.1136 ++            # argument belongs to this module then the template
 15.1137 ++            # instantiation will belong to this module.
 15.1138 ++            # 
 15.1139 ++            if templates.is_instantiation(pygccxml_definition.decl_string):
 15.1140 ++                cls_name, template_parameters = templates.split(pygccxml_definition.name)
 15.1141 ++                template_parameters_decls = [find_declaration_from_name(module_parser.global_ns, templ_param)
 15.1142 ++                                             for templ_param in template_parameters]
 15.1143 ++                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_decls)
 15.1144 ++                
 15.1145 ++                template_parameters_modules = []
 15.1146 ++                for templ in template_parameters_decls:
 15.1147 ++                    if not hasattr(templ, 'location'):
 15.1148 ++                        continue
 15.1149 ++                    try:
 15.1150 ++                        h = get_ns3_relative_path(templ.location.file_name)
 15.1151 ++                    except ValueError:
 15.1152 ++                        continue
 15.1153 ++                    template_parameters_modules.append(self.headers_map[h])
 15.1154 ++
 15.1155 ++                for templ_mod in template_parameters_modules:
 15.1156 ++                    if templ_mod == self.module:
 15.1157 ++                        definition_module = templ_mod
 15.1158 ++                        break
 15.1159 ++                #print >> sys.stderr, "********************", cls_name, repr(template_parameters_modules)
 15.1160 ++
 15.1161 ++
 15.1162 ++            if definition_module != self.module:
 15.1163 ++                global_annotations['import_from_module'] = 'ns.%s' % (definition_module.replace('-', '_'),)
 15.1164 ++
 15.1165 ++            if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
 15.1166 ++                global_annotations['incref_method'] = 'Ref'
 15.1167 ++                global_annotations['decref_method'] = 'Unref'
 15.1168 ++                global_annotations['peekref_method'] = 'GetReferenceCount'
 15.1169 ++                global_annotations['automatic_type_narrowing'] = 'true'
 15.1170 ++                return
 15.1171 ++
 15.1172 ++            if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
 15.1173 ++                # manually handled in ns3modulegen_core_customizations.py
 15.1174 ++                global_annotations['ignore'] = None
 15.1175 ++                return
 15.1176 ++
 15.1177 ++            if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
 15.1178 ++                global_annotations['ignore'] = None
 15.1179 ++                return
 15.1180 ++
 15.1181 ++            if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
 15.1182 ++                # handled by pybindgen "type transformation"
 15.1183 ++                global_annotations['ignore'] = None
 15.1184 ++                return
 15.1185 ++
 15.1186 ++            # table driven class customization
 15.1187 ++            try:
 15.1188 ++                annotations = type_annotations[pygccxml_definition.decl_string]
 15.1189 ++            except KeyError:
 15.1190 ++                pass
 15.1191 ++            else:
 15.1192 ++                global_annotations.update(annotations)
 15.1193 ++
 15.1194 ++        ## enums
 15.1195 ++        if isinstance(pygccxml_definition, enumeration_t):
 15.1196 ++            if definition_module != self.module:
 15.1197 ++                global_annotations['import_from_module'] = 'ns.%s' % definition_module
 15.1198 ++
 15.1199 ++        ## free functions
 15.1200 ++        if isinstance(pygccxml_definition, free_function_t):
 15.1201 ++
 15.1202 ++            if definition_module != self.module:
 15.1203 ++                global_annotations['ignore'] = None
 15.1204 ++                return
 15.1205 ++
 15.1206 ++            if pygccxml_definition.name == 'PeekPointer':
 15.1207 ++                global_annotations['ignore'] = None
 15.1208 ++                return
 15.1209 ++
 15.1210 ++        ## table driven methods/constructors/functions customization
 15.1211 ++        if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
 15.1212 ++            try:
 15.1213 ++                annotations = type_annotations[str(pygccxml_definition)]
 15.1214 ++            except KeyError:
 15.1215 ++                pass
 15.1216 ++            else:
 15.1217 ++                for key,value in annotations.items():
 15.1218 ++                    if key == 'params':
 15.1219 ++                        parameter_annotations.update (value)
 15.1220 ++                        del annotations['params']
 15.1221 ++                global_annotations.update(annotations)
 15.1222 ++
 15.1223 ++
 15.1224 ++# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
 15.1225 ++#     ## classes
 15.1226 ++#     if isinstance(pybindgen_wrapper, CppClass):
 15.1227 ++#         if pybindgen_wrapper.name.endswith('Checker'):
 15.1228 ++#             print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
 15.1229 ++#             #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
 15.1230 ++
 15.1231 ++
 15.1232 ++def scan_callback_classes(module_parser, callback_classes_file):
 15.1233 ++    callback_classes_file.write("callback_classes = [\n")
 15.1234 ++    for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
 15.1235 ++                                                      recursive=False):
 15.1236 ++        if not cls.name.startswith("Callback<"):
 15.1237 ++            continue
 15.1238 ++        assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
 15.1239 ++        dummy_cls_name, template_parameters = templates.split(cls.decl_string)
 15.1240 ++        callback_classes_file.write("    %r,\n" % template_parameters)
 15.1241 ++    callback_classes_file.write("]\n")
 15.1242 ++
 15.1243 ++
 15.1244 ++def ns3_module_scan(top_builddir, module_name, headers_map, output_file_name, cflags):
 15.1245 ++    module_parser = ModuleParser('ns.%s' % module_name.replace('-', '_'), 'ns3')
 15.1246 ++    module_parser.add_pre_scan_hook(PreScanHook(headers_map, module_name))
 15.1247 ++    #module_parser.add_post_scan_hook(post_scan_hook)
 15.1248 ++
 15.1249 ++    gccxml_options = dict(
 15.1250 ++        include_paths=[top_builddir],
 15.1251 ++         define_symbols={
 15.1252 ++            #'NS3_ASSERT_ENABLE': None,
 15.1253 ++            #'NS3_LOG_ENABLE': None,
 15.1254 ++            },
 15.1255 ++        cflags=('--gccxml-cxxflags "%s -DPYTHON_SCAN"' % cflags)
 15.1256 ++        )
 15.1257 ++
 15.1258 ++    try:
 15.1259 ++        os.unlink(output_file_name)
 15.1260 ++    except OSError:
 15.1261 ++        pass
 15.1262 ++    try:
 15.1263 ++        os.makedirs(os.path.dirname(output_file_name))
 15.1264 ++    except OSError:
 15.1265 ++        pass
 15.1266 ++    output_file = open(output_file_name, "wt")
 15.1267 ++    output_sink = FileCodeSink(output_file)
 15.1268 ++
 15.1269 ++    # if there exists a scan-header.h file in src/<module>/bindings,
 15.1270 ++    # scan it, otherwise scan ns3/xxxx-module.h.
 15.1271 ++    scan_header = os.path.join(os.path.dirname(output_file_name), "scan-header.h")
 15.1272 ++    if not os.path.exists(scan_header):
 15.1273 ++        scan_header = os.path.join(top_builddir, "ns3", "%s-module.h" % module_name)
 15.1274 ++
 15.1275 ++    module_parser.parse_init([scan_header],
 15.1276 ++                             None, whitelist_paths=[top_builddir],
 15.1277 ++                             #includes=['"ns3/everything.h"'],
 15.1278 ++                             pygen_sink=output_sink,
 15.1279 ++                             gccxml_options=gccxml_options)
 15.1280 ++    module_parser.scan_types()
 15.1281 ++
 15.1282 ++    callback_classes_file = open(os.path.join(os.path.dirname(output_file_name), "callbacks_list.py"), "wt")
 15.1283 ++    scan_callback_classes(module_parser, callback_classes_file)
 15.1284 ++    callback_classes_file.close()
 15.1285 ++
 15.1286 ++
 15.1287 ++    module_parser.scan_methods()
 15.1288 ++    module_parser.scan_functions()
 15.1289 ++    module_parser.parse_finalize()
 15.1290 ++
 15.1291 ++    output_file.close()
 15.1292 ++    os.chmod(output_file_name, 0400)
 15.1293 ++
 15.1294 ++
 15.1295 ++if __name__ == '__main__':
 15.1296 ++    if len(sys.argv) != 6:
 15.1297 ++        print "ns3modulescan-modular.py top_builddir module_path module_headers output_file_name cflags"
 15.1298 ++        sys.exit(1)
 15.1299 ++    ns3_module_scan(sys.argv[1], sys.argv[2], eval(sys.argv[3]), sys.argv[4], sys.argv[5])
 15.1300 ++    sys.exit(0)
 15.1301 +diff --git a/bindings/ns3modulescan.py b/bindings/ns3modulescan.py
 15.1302 +new file mode 100644
 15.1303 +--- /dev/null
 15.1304 ++++ b/bindings/ns3modulescan.py
 15.1305 +@@ -0,0 +1,333 @@
 15.1306 ++#! /usr/bin/env python
 15.1307 ++
 15.1308 ++import sys
 15.1309 ++import os.path
 15.1310 ++
 15.1311 ++import pybindgen.settings
 15.1312 ++from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning
 15.1313 ++from pybindgen.typehandlers.codesink import FileCodeSink
 15.1314 ++from pygccxml.declarations import templates
 15.1315 ++from pygccxml.declarations.class_declaration import class_t
 15.1316 ++from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t, calldef_t
 15.1317 ++
 15.1318 ++
 15.1319 ++## we need the smart pointer type transformation to be active even
 15.1320 ++## during gccxml scanning.
 15.1321 ++import ns3modulegen_core_customizations
 15.1322 ++
 15.1323 ++
 15.1324 ++## silence gccxmlparser errors; we only want error handling in the
 15.1325 ++## generated python script, not while scanning.
 15.1326 ++class ErrorHandler(pybindgen.settings.ErrorHandler):
 15.1327 ++    def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
 15.1328 ++        return True
 15.1329 ++pybindgen.settings.error_handler = ErrorHandler()
 15.1330 ++import warnings
 15.1331 ++warnings.filterwarnings(category=WrapperWarning, action='ignore')
 15.1332 ++
 15.1333 ++type_annotations = {
 15.1334 ++    '::ns3::AttributeChecker': {
 15.1335 ++        'automatic_type_narrowing': 'true',
 15.1336 ++        'allow_subclassing': 'false',
 15.1337 ++        },
 15.1338 ++    '::ns3::AttributeValue': {
 15.1339 ++        'automatic_type_narrowing': 'true',
 15.1340 ++        'allow_subclassing': 'false',
 15.1341 ++        },
 15.1342 ++
 15.1343 ++    '::ns3::CommandLine': {
 15.1344 ++        'allow_subclassing': 'true', # needed so that AddValue is able to set attributes on the object
 15.1345 ++        },
 15.1346 ++
 15.1347 ++    '::ns3::NscTcpL4Protocol': {
 15.1348 ++        'ignore': 'true', # this class is implementation detail
 15.1349 ++        },
 15.1350 ++
 15.1351 ++
 15.1352 ++    'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': {
 15.1353 ++        'ignore': None,
 15.1354 ++        },
 15.1355 ++    'ns3::RandomVariableBase * ns3::RandomVariable::Peek() const [member function]': {
 15.1356 ++        'ignore': None,
 15.1357 ++        },
 15.1358 ++    'void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function]': {
 15.1359 ++        'params': {'seed':{'direction':'out',
 15.1360 ++                           'array_length':'6'}}
 15.1361 ++        },
 15.1362 ++    'bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInformation * info) const [member function]': {
 15.1363 ++        'params': {'info':{'transfer_ownership': 'false'}}
 15.1364 ++        },
 15.1365 ++    'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': {
 15.1366 ++        'ignore': None, # manually wrapped in 
 15.1367 ++        },
 15.1368 ++    'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
 15.1369 ++        'params': {'obj': {'transfer_ownership':'false'}}
 15.1370 ++        },
 15.1371 ++    'bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
 15.1372 ++        'params': {'obj': {'transfer_ownership':'false'}}
 15.1373 ++        },
 15.1374 ++    'bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
 15.1375 ++        'params': {'obj': {'transfer_ownership':'false'}}
 15.1376 ++        },
 15.1377 ++    'bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
 15.1378 ++        'params': {'obj': {'transfer_ownership':'false'}}
 15.1379 ++        },
 15.1380 ++    'bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function]': {
 15.1381 ++        'params': {'object': {'transfer_ownership':'false'}}
 15.1382 ++        },
 15.1383 ++    'ns3::EmpiricalVariable::EmpiricalVariable(ns3::RandomVariableBase const & variable) [constructor]': {
 15.1384 ++        'ignore': None
 15.1385 ++        },
 15.1386 ++    'static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function]': {
 15.1387 ++        'caller_owns_return': 'false'
 15.1388 ++        },
 15.1389 ++    'void ns3::CommandLine::Parse(int argc, char * * argv) const [member function]': {
 15.1390 ++        'ignore': None # manually wrapped
 15.1391 ++        },
 15.1392 ++    'extern void ns3::PythonCompleteConstruct(ns3::Ptr<ns3::Object> object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': {
 15.1393 ++        'ignore': None # used transparently by, should not be wrapped
 15.1394 ++        },
 15.1395 ++
 15.1396 ++    'ns3::Ptr<ns3::Ipv4RoutingProtocol> ns3::Ipv4ListRouting::GetRoutingProtocol(uint32_t index, int16_t & priority) const [member function]': {
 15.1397 ++        'params': {'priority':{'direction':'out'}}
 15.1398 ++        },
 15.1399 ++    'ns3::Ipv4RoutingTableEntry * ns3::GlobalRouter::GetInjectedRoute(uint32_t i) [member function]': {
 15.1400 ++        'params': {'return': { 'caller_owns_return': 'false',}},
 15.1401 ++        },
 15.1402 ++    'ns3::Ipv4RoutingTableEntry * ns3::Ipv4GlobalRouting::GetRoute(uint32_t i) const [member function]': {
 15.1403 ++        'params': {'return': { 'caller_owns_return': 'false',}},
 15.1404 ++        },
 15.1405 ++
 15.1406 ++    '::ns3::TestCase': {
 15.1407 ++        'ignore': 'true', # we don't need to write test cases in Python
 15.1408 ++        },
 15.1409 ++    '::ns3::TestRunner': {
 15.1410 ++        'ignore': 'true', # we don't need to write test cases in Python
 15.1411 ++        },
 15.1412 ++    '::ns3::TestSuite': {
 15.1413 ++        'ignore': 'true', # we don't need to write test cases in Python
 15.1414 ++        },
 15.1415 ++    
 15.1416 ++    }
 15.1417 ++
 15.1418 ++def get_ns3_relative_path(path):
 15.1419 ++    l = []
 15.1420 ++    head = path
 15.1421 ++    while head:
 15.1422 ++        head, tail = os.path.split(head)
 15.1423 ++        if tail == 'ns3':
 15.1424 ++            return os.path.join(*l)
 15.1425 ++        l.insert(0, tail)
 15.1426 ++    raise AssertionError("is the path %r inside ns3?!" % path)
 15.1427 ++
 15.1428 ++
 15.1429 ++def pre_scan_hook(dummy_module_parser,
 15.1430 ++                  pygccxml_definition,
 15.1431 ++                  global_annotations,
 15.1432 ++                  parameter_annotations):
 15.1433 ++    ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
 15.1434 ++
 15.1435 ++    ## Note: we don't include line numbers in the comments because
 15.1436 ++    ## those numbers are very likely to change frequently, which would
 15.1437 ++    ## cause needless changes, since the generated python files are
 15.1438 ++    ## kept under version control.
 15.1439 ++
 15.1440 ++    #global_annotations['pygen_comment'] = "%s:%i: %s" % \
 15.1441 ++    #    (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
 15.1442 ++    global_annotations['pygen_comment'] = "%s: %s" % \
 15.1443 ++        (ns3_header, pygccxml_definition)
 15.1444 ++
 15.1445 ++
 15.1446 ++    ## handle ns3::Object::GetObject (left to its own devices,
 15.1447 ++    ## pybindgen will generate a mangled name containing the template
 15.1448 ++    ## argument type name).
 15.1449 ++    if isinstance(pygccxml_definition, member_function_t) \
 15.1450 ++            and pygccxml_definition.parent.name == 'Object' \
 15.1451 ++            and pygccxml_definition.name == 'GetObject':
 15.1452 ++        template_args = templates.args(pygccxml_definition.demangled_name)
 15.1453 ++        if template_args == ['ns3::Object']:
 15.1454 ++            global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
 15.1455 ++
 15.1456 ++    ## Don't wrap Simulator::Schedule* (manually wrapped)
 15.1457 ++    if isinstance(pygccxml_definition, member_function_t) \
 15.1458 ++            and pygccxml_definition.parent.name == 'Simulator' \
 15.1459 ++            and pygccxml_definition.name.startswith('Schedule'):
 15.1460 ++        global_annotations['ignore'] = None
 15.1461 ++
 15.1462 ++    # manually wrapped
 15.1463 ++    if isinstance(pygccxml_definition, member_function_t) \
 15.1464 ++            and pygccxml_definition.parent.name == 'Simulator' \
 15.1465 ++            and pygccxml_definition.name == 'Run':
 15.1466 ++        global_annotations['ignore'] = True
 15.1467 ++
 15.1468 ++    ## http://www.gccxml.org/Bug/view.php?id=9915
 15.1469 ++    if isinstance(pygccxml_definition, calldef_t):
 15.1470 ++        for arg in pygccxml_definition.arguments:
 15.1471 ++            if arg.default_value is None:
 15.1472 ++                continue
 15.1473 ++            if "ns3::MilliSeconds( )" == arg.default_value:
 15.1474 ++                arg.default_value = "ns3::MilliSeconds(0)"
 15.1475 ++            if "ns3::Seconds( )" == arg.default_value:
 15.1476 ++                arg.default_value = "ns3::Seconds(0)"
 15.1477 ++
 15.1478 ++    ## classes
 15.1479 ++    if isinstance(pygccxml_definition, class_t):
 15.1480 ++        # no need for helper classes to allow subclassing in Python, I think...
 15.1481 ++        #if pygccxml_definition.name.endswith('Helper'):
 15.1482 ++        #    global_annotations['allow_subclassing'] = 'false'
 15.1483 ++
 15.1484 ++        if pygccxml_definition.decl_string.startswith('::ns3::SimpleRefCount<'):
 15.1485 ++            global_annotations['incref_method'] = 'Ref'
 15.1486 ++            global_annotations['decref_method'] = 'Unref'
 15.1487 ++            global_annotations['peekref_method'] = 'GetReferenceCount'
 15.1488 ++            global_annotations['automatic_type_narrowing'] = 'true'
 15.1489 ++            return
 15.1490 ++
 15.1491 ++        if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
 15.1492 ++            # manually handled in ns3modulegen_core_customizations.py
 15.1493 ++            global_annotations['ignore'] = None
 15.1494 ++            return
 15.1495 ++
 15.1496 ++        if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
 15.1497 ++            global_annotations['ignore'] = None
 15.1498 ++            return
 15.1499 ++
 15.1500 ++        if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
 15.1501 ++            # handled by pybindgen "type transformation"
 15.1502 ++            global_annotations['ignore'] = None
 15.1503 ++            return
 15.1504 ++
 15.1505 ++        # table driven class customization
 15.1506 ++        try:
 15.1507 ++            annotations = type_annotations[pygccxml_definition.decl_string]
 15.1508 ++        except KeyError:
 15.1509 ++            pass
 15.1510 ++        else:
 15.1511 ++            global_annotations.update(annotations)
 15.1512 ++
 15.1513 ++    ## free functions
 15.1514 ++    if isinstance(pygccxml_definition, free_function_t):
 15.1515 ++        if pygccxml_definition.name == 'PeekPointer':
 15.1516 ++            global_annotations['ignore'] = None
 15.1517 ++            return
 15.1518 ++
 15.1519 ++    ## table driven methods/constructors/functions customization
 15.1520 ++    if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
 15.1521 ++        try:
 15.1522 ++            annotations = type_annotations[str(pygccxml_definition)]
 15.1523 ++        except KeyError:
 15.1524 ++            pass
 15.1525 ++        else:
 15.1526 ++            for key,value in annotations.items():
 15.1527 ++                if key == 'params':
 15.1528 ++                    parameter_annotations.update (value)
 15.1529 ++                    del annotations['params']
 15.1530 ++            global_annotations.update(annotations)
 15.1531 ++
 15.1532 ++
 15.1533 ++# def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
 15.1534 ++#     ## classes
 15.1535 ++#     if isinstance(pybindgen_wrapper, CppClass):
 15.1536 ++#         if pybindgen_wrapper.name.endswith('Checker'):
 15.1537 ++#             print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
 15.1538 ++#             #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
 15.1539 ++
 15.1540 ++
 15.1541 ++def scan_callback_classes(module_parser, callback_classes_file):
 15.1542 ++    callback_classes_file.write("callback_classes = [\n")
 15.1543 ++    for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
 15.1544 ++                                                      recursive=False):
 15.1545 ++        if not cls.name.startswith("Callback<"):
 15.1546 ++            continue
 15.1547 ++        assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
 15.1548 ++        dummy_cls_name, template_parameters = templates.split(cls.decl_string)
 15.1549 ++        callback_classes_file.write("    %r,\n" % template_parameters)
 15.1550 ++    callback_classes_file.write("]\n")
 15.1551 ++
 15.1552 ++
 15.1553 ++class MyPygenClassifier(PygenClassifier):
 15.1554 ++    def __init__(self, headers_map, section_precendences):
 15.1555 ++        self.headers_map = headers_map
 15.1556 ++        self.section_precendences = section_precendences
 15.1557 ++
 15.1558 ++    def classify(self, pygccxml_definition):
 15.1559 ++        name = os.path.basename(pygccxml_definition.location.file_name)
 15.1560 ++        try:
 15.1561 ++            return self.headers_map[name]
 15.1562 ++        except KeyError:
 15.1563 ++            return '__main__'
 15.1564 ++
 15.1565 ++    def get_section_precedence(self, section_name):
 15.1566 ++        if section_name == '__main__':
 15.1567 ++            return -1
 15.1568 ++        return self.section_precendences[section_name]
 15.1569 ++
 15.1570 ++
 15.1571 ++def ns3_module_scan(top_builddir, pygen_file_name, everything_h, cflags):
 15.1572 ++
 15.1573 ++    ns3_modules = eval(sys.stdin.readline())
 15.1574 ++
 15.1575 ++    ## do a topological sort on the modules graph
 15.1576 ++    from topsort import topsort
 15.1577 ++    graph = []
 15.1578 ++    module_names = ns3_modules.keys()
 15.1579 ++    module_names.sort()
 15.1580 ++    for ns3_module_name in module_names:
 15.1581 ++        ns3_module_deps = list(ns3_modules[ns3_module_name][0])
 15.1582 ++        ns3_module_deps.sort()
 15.1583 ++        for dep in ns3_module_deps:
 15.1584 ++            graph.append((dep, ns3_module_name))
 15.1585 ++    sorted_ns3_modules = topsort(graph)
 15.1586 ++    #print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules
 15.1587 ++
 15.1588 ++    sections = [PygenSection('__main__', FileCodeSink(open(pygen_file_name, "wt")))]
 15.1589 ++    headers_map = {} # header_name -> section_name
 15.1590 ++    section_precendences = {} # section_name -> precedence
 15.1591 ++    for prec, ns3_module in enumerate(sorted_ns3_modules):
 15.1592 ++        section_name = "ns3_module_%s" % ns3_module.replace('-', '_')
 15.1593 ++        file_name = os.path.join(os.path.dirname(pygen_file_name), "%s.py" % section_name)
 15.1594 ++        sections.append(PygenSection(section_name, FileCodeSink(open(file_name, "wt")),
 15.1595 ++                                     section_name + "__local"))
 15.1596 ++        for header in ns3_modules[ns3_module][1]:
 15.1597 ++            headers_map[header] = section_name
 15.1598 ++        section_precendences[section_name] = prec
 15.1599 ++
 15.1600 ++    module_parser = ModuleParser('ns3', 'ns3')
 15.1601 ++
 15.1602 ++    module_parser.add_pre_scan_hook(pre_scan_hook)
 15.1603 ++    #module_parser.add_post_scan_hook(post_scan_hook)
 15.1604 ++
 15.1605 ++    gccxml_options = dict(
 15.1606 ++        include_paths=[top_builddir],
 15.1607 ++         define_symbols={
 15.1608 ++            #'NS3_ASSERT_ENABLE': None,
 15.1609 ++            #'NS3_LOG_ENABLE': None,
 15.1610 ++            },
 15.1611 ++        cflags=('--gccxml-cxxflags "%s -DPYTHON_SCAN"' % cflags)
 15.1612 ++        )
 15.1613 ++
 15.1614 ++    module_parser.parse_init([everything_h],
 15.1615 ++                             None, whitelist_paths=[top_builddir, os.path.dirname(everything_h)],
 15.1616 ++                             #includes=['"ns3/everything.h"'],
 15.1617 ++                             pygen_sink=sections,
 15.1618 ++                             pygen_classifier=MyPygenClassifier(headers_map, section_precendences),
 15.1619 ++                             gccxml_options=gccxml_options)
 15.1620 ++    module_parser.scan_types()
 15.1621 ++
 15.1622 ++    callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt")
 15.1623 ++    scan_callback_classes(module_parser, callback_classes_file)
 15.1624 ++    callback_classes_file.close()
 15.1625 ++
 15.1626 ++
 15.1627 ++    module_parser.scan_methods()
 15.1628 ++    module_parser.scan_functions()
 15.1629 ++    module_parser.parse_finalize()
 15.1630 ++
 15.1631 ++    for section in sections:
 15.1632 ++        section.code_sink.file.close()
 15.1633 ++
 15.1634 ++
 15.1635 ++
 15.1636 ++if __name__ == '__main__':
 15.1637 ++    ns3_module_scan(sys.argv[1], sys.argv[3], sys.argv[2], sys.argv[4])
 15.1638 ++
 15.1639 +diff --git a/bindings/ns3modulescan.pyc b/bindings/ns3modulescan.pyc
 15.1640 +new file mode 100644
 15.1641 +index 0000000000000000000000000000000000000000..c7d2db0c669ed9783e23ca852462136e50bdfe0e
 15.1642 +GIT binary patch
 15.1643 +literal 10599
 15.1644 +zc$~F5+j1Mpb!Pw&Btd{TkRY+TETpw;NERjUN>LJptBpizEje1687k%)yUf&Zra?40
 15.1645 +zn1QAnBC#PWWy@7b<yOfb_{C4D%BQ3%uX)H9<S9>fRZ_`0r)O~CMeDeVlrZQ%-F^D>
 15.1646 +zxt|{V+kce`|N3C<Pd!NfX7TgK_)*O)fRFzzH~?t$+ZHr3X*&yz9Je!YFa|*$8hHrD
 15.1647 +zp)n4@1T-cfn1se8STrLG2L%YGpfP3oIXEanP=ZFu^vB>}8iE;U%$R;24rU>kgT@>L
 15.1648 +z^U#=wpbU*N1PjnuFf(xfMQAL7KMo=XvI24mnilvI@C$%<06%RkfmouJ8FrRava8Uj
 15.1649 +zf~bQ00Q^Z1li(M?pTe0LtF;U*JYEs}5<K#!!JomeS$K37IEO%sfz+Gt_olE{Ha*Mq
 15.1650 +z7DjrD+@t@9vI71R!jQ5metm$SEBLwEpMq;}yK4x$o{W7sf~<DV%p1wfo9`L>=sjcK
 15.1651 +zdC%CbbH=`#jD2r}vbyQvoZHyDGcxx5k>1^5oC!l#5}fx=?MJxoCu2W&&)CN!;`n5w
 15.1652 +z_h6*=5FRzIg8zG@G>vQEKjOx9@PD5hAA<h}AjVm-{;;oDHSizv@C^_*!T%%J&p`A5
 15.1653 +zEP;Ih`4RZ5P)%B&_FGT-t<RwPE(ca<p(b0fRVRCs|BHVc^&B>J5g%Vfem4-CZmdMC
 15.1654 +zXArR2+Y{kh;3_4X5@E#@wk13*qfk#HU^{j@9T9K4aVW#Rx|L%4Tn1t-^2L@64-9mY
 15.1655 +z9-`d|TrHFVjpM_k4IFLgplzG65Kglj@*a-Xa|mmT_O6JBp(R=xg-XX=Pe(CA2*2kB
 15.1656 +zfiIfaBO0E^aTLFBLq8C4-`&v0&&b^nUSv<hA}b}{X29NJx;&yKm&{$Gxl9~@8Qw6&
 15.1657 +z6YO=|6^3$pC=oQ7Fu&Vw_nbq+8a|YPh$ByQn02##n2udf?7H58Qz!EHp?-vq`>m)g
 15.1658 +z?rZlO_dwon?Hxw(fw~{6l?N-nCsuSzwA_7(Gg8p~T^af)1Df=p&B9ck8{X^mm>DhR
 15.1659 +zgCmG171|@i+^A=X`U!kEPUyCU<LCl+3<k%s=TfRJjXrw{(JiJl<t--1Lp9lp;-1c9
 15.1660 +z$2AH^O}Q6Fv0#3q?1f&Y;jWI_u9lvodmVx2z(XG5R(g!|$qkfXEkfmp4jt9qWt}5Z
 15.1661 +zmJs^*G1Bw+@l&m1x!cuZttGqz5v#>>#(v@kU7_X&BWqE+jf{OILotkOLwT>g&Z~!;
 15.1662 +zaik+J3e;CP#v?Y)j@mzQW9jY&;&i`$&YWki5;a!!+IMSj6X5OIS3}yrqrNyFKd-%0
 15.1663 +zJ9p<zAr9)d6U<*33#+9TwxdZeqOLJ3U&e{aljc8SeL^0)Jtq*z<yNBo!e<F}+}Ld^
 15.1664 +z){(c7^v~b@heB`Rf_hhm`oSlTMk)!x#q`Xxz}-+a(Gf(4AxfwvJG`?Do00kpZ0tr+
 15.1665 +zV77aWdhpVJ{P<NA9dtW=`914xppMs-#vx=Lsz8mD{_g0a{`8lKI3~r4LZpwjxsX2P
 15.1666 +z6ALscVeKL^%<iANGT3sP-$DiMrzNuE0>SL=tDlV?nB2%#)Qvsy)boT=QB2wyhA6mg
 15.1667 +zsaq&Y>}heNjgI|zcOOR*{Xlfd=4)sp<cvm?&fC5C*nj<7Q*qJ0!))*jiN7l`zxZ}y
 15.1668 +z)}`_;pDTa+{~_e^8N+57@dm0pLRw$d2ZU{j3n;?Q-P$?+aL74f?_#F7sgHWz?#NhT
 15.1669 +ztRA?7Goatq6SAM6G{ATX<zTGn#vwb%#5_lj@JcG3y2ueA`=}oV(XJcR&#^<sIPh;n
 15.1670 +zfdE}AB~f+sY&AFD^X}HXmK)<9cc}aJVg~&aWh6&h#9?iKc(aFU8Y22mATT(kM>YJ}
 15.1671 +z)bZ+&te%XDDe)wlzfOye&z&;UO`!@;N(tDI?ocr9#4?Jd?y0{@W!T^OW#{cf8|?_S
 15.1672 +zG>vvoYW)$~B^hOYo|-vu|Ck$yqr3Q}KYrv8N$HmFSL#H%f1Z*xM9pi`j_09{d#QMh
 15.1673 +zFlkuCOwG%XxFviB4bgI*xZU4s3mP13Gkoe%{1>Uf%piw&EtFnEjpsyl2xfOf3VySr
 15.1674 +z(5<f2!n2aZHJc``WbJzZCl(yzGXqC99AoM5Bd{=?l@`bh_1{_Wb%usdvT&TGLW$~&
 15.1675 +zx&9=CTJU$6|62Ghb5wrgw09Y>-eC2-jcFE^+qgjm5&fL==`GHRH#k@!jgqs*D-^3$
 15.1676 +z4O7Ef$JMRctr+F4q%VkfpWUdFKsBX+k>a>clQ@M_oj_^^?ME_614AlPxCD8ssEO?3
 15.1677 +ze4jVA?+_~DM!?Hj!u3tch{5;r@@z^O_k?zE0R0XYI`XY>=oD{gvw2Rq^Y||d<JPiO
 15.1678 +zvgWKsi;E3Pxr?dHKF@NoL9Av0AyZFsB$VSE0h<}9pv+JPtC|Ia2SZUr+rZKp1DPjr
 15.1679 +zkObEaC{MQ^)PIN)9S1qVxF;F$7#xq$Wyqe9`7{=Yc~S{~99G}_y(t+-ws|<b%>*yH
 15.1680 +zk!~XkbiaXU84oa?0<50F@$p$4*ZZVSrG#Lbc@{y55lFC(ntY0BSl`)(6QmippCQ%T
 15.1681 +zpMYo_HS?}1cZ<mgA*HLI67`)K;KAurgEPq>E+z!qLmSWX#{Xf+oa3X;@=;fC-5gUo
 15.1682 +z537EeTMO7)<W>b+OWaz<R%$|KeU;bG472Lgj1Rtb#+3_Z^yUCVp_x}b8Heq#3^`qf
 15.1683 +z{Q`3b|K9X6)|a?MF2M0PVHuY7BA@o7zEG|*i_UH{vIM28E6`-m5S@V4TOb<r5)C8%
 15.1684 +z3&?nuwZ1(1jA)R{blb7M^D%p)2{@UA;|aR+p}m)pmMjy?8fM{q9QpLke`hTGY@ay@
 15.1685 +zJE803gcSLUTk3J`mg4HXLw6XChXGrJnw^P>o?Pmnw>CXBl{);SUm5Lx`lLTqQ{|Ul
 15.1686 +zZ8+$ev>SSY%W1_(w`9AEV^Pe(bjxcA@)|Z_WDkihT`i>OzmP#7w**EAU)5{3FBtg2
 15.1687 +zZH^T@Ff{oL4Chq_kpc<9G{P3mwWu5FRkOJ;mliVgV$pQk0`m=@-R_@-aWdwM;juZx
 15.1688 +zCtN6EfhT2T?20>BQw}ED#21?i^x<fgCa<f*gmH@O4~C`&LzHP~>QlkGN&a8Nc8y$k
 15.1689 +zmC%2Z-d_Zf$CVm$yeR`C0KUzTDiw-NGt(-S#82Lr=Gk;$?qQCm_%Ob}jBYOw{s0jo
 15.1690 +ziM2YENy)nrg~BGkZPOrcjH|n(S1RFK)9nV@;mp|P_%>zO88{}h=bIqDwQ$2Q(tHBN
 15.1691 +z=lK)S<ABE0b~`@mmQ5FC_GGFyh=JvVk-x3#OhOsbd!^+5rep5&%0}-!@2DL(NR<pF
 15.1692 +z^NM299_K3~`!A+tJf@uS$VkB`m_rd2@s@@)pE;K`OyF}4FC_SZ=rO^}j>`+fY~-<U
 15.1693 +zsPD9}^ggCd=mEL;$*eV(pS8-?tTj)cEVawlbk@M=y8wA?jpL_;pT+F#SlKEh|Hd-q
 15.1694 +z3_l0$EMl~#u{VcnakVv>ty)=Yfng;mB9@XhV|kR>j3plq^#2Sd%JWMC@>@rLLs^uG
 15.1695 +z`jle<rCu1zDQrS!eP^F?H1c#~Nl?c{9gcMz&XU-kNn(44VrYSaJAx`d&zK2Qg9%@A
 15.1696 +z!grEOiO5riK{*^D+)jYTqp~-hU~fvg;U$LZ@J*UfwNGnb6<BN2RF;h)7G5`2m;@>6
 15.1697 +z4XpbnJLDSXf~X%gx0Y&9&6uf{MrR0L4gYS%cME(qxKpT;wXqHzVsRkYdJ;`%ciTZX
 15.1698 +zGPqVo_d7G>865NqsL#CobGj9@pOZbkpa+}(Ec*&)gbMo=4d0{3_eo)SVrj5#VqoWS
 15.1699 +zh4vGy_+F5>6gExl8JAKXww}Jdsmo1J*(y$x`kyqgzzJ#zQ`2#@fHGRZ4Qwx3?C`(n
 15.1700 +zoq8W|_D209ICG<picO6ysWUZlbjQvdp$C03sWnuLHK5WvoMTWUsU^&<dnR?C#`h?v
 15.1701 +z?RGTLtjy)4gEsF8tRvCSE8fH=IoSa{+Hi>%*vb7lIaSB`4J0oNz?w8hpB*-O;?$t_
 15.1702 +z;^IoOA){&cX4vN0V5?i(;R5DLdCrw4I9H-~H`bTT62iNY?Avx_=s0x_4!0q#erRkL
 15.1703 +z>qm}mPYL|2&y5XY#DGIv^mu;h95UDL&EEeI{sMDo86D*eI!fkK`e8m@GwP7kqGRZS
 15.1704 +zGL-lNIVFTwjT&v(5hSm&SWAqYGwI3rraDy*V#MVgkkprIzY%3*UCbe2oP&~WjalqL
 15.1705 +zYzn+K*}omqg9=1j!KJ@xIY4y3hJ>EHHJO_n=K_?HwAqyP|CnJF)vThZpO}>QYfyUg
 15.1706 +zo`WDqm7_&B3mi01WpNVb_msuwscju?QfGbV1!eN+lBsx|fGS3_Dj}PsJU*RzgF5Rw
 15.1707 +zRX8bdL54xBK(m`%{911mY`=Md5owG@Y4sE(TNwW^yrD-RH5sF#1BdX5rR+%&T1Zcc
 15.1708 +zpVM&kFQf^_Q#4_H=a(G#X5eI&L*6XN5`{S|L~(KD1PiBWstM(6+L%iU7_4oN=P*Fx
 15.1709 +zYAmgaM5ks@LdN`n3<P40wDc}(;(CpbKa0nog6jItES!{S$}twBWvsKmwziMa^rs27
 15.1710 +z`sUwZ8}l-HUtA<?Cs@`jfGh+0Izom{oQhbWb7BFDC&aQ9Yf-F@D(@hBvdGgb<U{t@
 15.1711 +ze^PY{LuX+E_qblgLtw?Kmzk1j+6_zBV=De~7GbHfeDG`+vV;pobL^7}=nrV~;|kvm
 15.1712 +z;g`I^2nf~He(PGlb=`>nI?=JdQ-KpK6_-GM2(p$geG_N4+2N6WZ43;ZgS?J93KL|$
 15.1713 +zU1CSTw?~Isk?m8Kn#5=<{AkSzKOIE|cuSGdj<f%y{2-9*KFH|OYAERX=JqBn2QX{K
 15.1714 +zq_WrEjWC>(0eQ{9-Bap2gnPv#*DK!95kqS?F~eC|-~8$87eC%`w$`3*+~j2Bu!VU`
 15.1715 +zAeBx~lOHq{DHbUQoPs0;>fp^gZJ*@s5x+lHd?}a)ape#`JWu@wBt?wC6x-AYJ!P)Y
 15.1716 +zG<pQ~!ZAkA08e7;bTX#p=E9Ab$qmA1Uc7cX7*TC@sQvfc5yCjX6Cu_*F(xm}$XH+^
 15.1717 +zgC$l!1le~}LHRP~FhqhfuVQ`Q8A;LYuT$*4#EP1^LYWl@Rr@7jBj07JFj_=4ld|_A
 15.1718 +zNe8_kQo^`<8Z`x|5gY^3ywrdUYLq9+{TpF^IuN0>Sp-A`Wp4H5G=iX>IlEmM_;?N$
 15.1719 +zqLI*`$Sg9;McmUZ^t(>WrnixLYD5c_VK@=H7rUJnFB;BW^~|W&GUih-Uvx|<g$*v=
 15.1720 +zNMux@4z^(-Cs9ZZk{@%UO7C$CBPi_{lGK0&ZgMMI5b!VQ(M)BSpuD^Ydg`bIE>P&C
 15.1721 +z%YDdT8D{0JB9>Q_oGv8aSFB?82H&Ytp;fVNS=TX}n8A^0YdSNNDP=LpS@~QkTePlc
 15.1722 +z@|bIkTZPOW48(;j7jzlIVv-1Q0FrnsN!=y!t4^kE|14!egiZsEmNlHY-|5kDP#5l@
 15.1723 +z^3ip_x$o(NIV%`UGB#`~2DSy8oeo<U{|@8Bk?Ex3=4TtRx<~p+>S@ey5eD`AJ-SZ7
 15.1724 +z;=u@<>yz(YG<?te+-3-5ZY8c=yukdV##}v+YVrMpx$vkNi5Y>JOEt7<ud8&_mfsBB
 15.1725 +zWu)BUUwW{A<=>$=$?15`q4^1sF;G*fr66Pf^ump=d)Qa7>9bF;e+5ZGmEPaHz1%E{
 15.1726 +z$z3&|C+uYZ0Ut%Hm?>H}ty%tebF4UaH9La}TghZG$sM<*GW^VD%_o;-2z^Rc8K2dp
 15.1727 +eS3T!5HT=mAjb#V$>9NVF$<Ac4GC%pWWc?qXaVOgV
 15.1728 +
 15.1729 +diff --git a/bindings/ns__init__.py b/bindings/ns__init__.py
 15.1730 +new file mode 100644
 15.1731 +--- /dev/null
 15.1732 ++++ b/bindings/ns__init__.py
 15.1733 +@@ -0,0 +1,1 @@
 15.1734 ++
 15.1735 +diff --git a/bindings/wscript b/bindings/wscript
 15.1736 +new file mode 100644
 15.1737 +--- /dev/null
 15.1738 ++++ b/bindings/wscript
 15.1739 +@@ -0,0 +1,655 @@
 15.1740 ++## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 15.1741 ++import types
 15.1742 ++import re
 15.1743 ++import os
 15.1744 ++import subprocess
 15.1745 ++import shutil
 15.1746 ++import sys
 15.1747 ++import warnings
 15.1748 ++
 15.1749 ++import Task
 15.1750 ++import Options
 15.1751 ++import Configure
 15.1752 ++import TaskGen
 15.1753 ++import Logs
 15.1754 ++import Build
 15.1755 ++import Utils
 15.1756 ++import ns3waf
 15.1757 ++
 15.1758 ++from waflib.Errors import WafError
 15.1759 ++
 15.1760 ++## https://launchpad.net/pybindgen/
 15.1761 ++REQUIRED_PYBINDGEN_VERSION = (0, 15, 0, 809)
 15.1762 ++REQUIRED_PYGCCXML_VERSION = (0, 9, 5)
 15.1763 ++
 15.1764 ++
 15.1765 ++from TaskGen import feature, after
 15.1766 ++import Task
 15.1767 ++
 15.1768 ++def add_to_python_path(path):
 15.1769 ++    if os.environ.get('PYTHONPATH', ''):
 15.1770 ++        os.environ['PYTHONPATH'] = path + os.pathsep + os.environ.get('PYTHONPATH')
 15.1771 ++    else:
 15.1772 ++        os.environ['PYTHONPATH'] = path
 15.1773 ++
 15.1774 ++def set_pybindgen_pythonpath(env):
 15.1775 ++    env['WITH_PYBINDGEN'] = '../pybindgen'
 15.1776 ++    if env['WITH_PYBINDGEN']:
 15.1777 ++        add_to_python_path(env['WITH_PYBINDGEN'])
 15.1778 ++
 15.1779 ++def options(opt):
 15.1780 ++    opt.tool_options('python')
 15.1781 ++    opt.add_option('--apiscan',
 15.1782 ++                   help=("Rescan the API for the indicated module(s), for Python bindings.  "
 15.1783 ++                         "Needs working GCCXML / pygccxml environment.  "
 15.1784 ++                         "The metamodule 'all' expands to all available ns-3 modules."),
 15.1785 ++                   default=None, dest='apiscan', metavar="MODULE[,MODULE...]")
 15.1786 ++
 15.1787 ++def _check_nonfatal(conf, *args, **kwargs):
 15.1788 ++    try:
 15.1789 ++        return conf.check(*args, **kwargs)
 15.1790 ++    except conf.errors.ConfigurationError:
 15.1791 ++        return None
 15.1792 ++
 15.1793 ++def configure(conf):
 15.1794 ++    # conf.env['ENABLE_PYTHON_BINDINGS'] = False
 15.1795 ++    # if Options.options.python_disable:
 15.1796 ++    #     conf.report_optional_feature("python", "Python Bindings", False,
 15.1797 ++    #                                  "disabled by user request")
 15.1798 ++    #     return
 15.1799 ++    # Disable python in static builds (bug #1253)
 15.1800 ++    if ((conf.env['ENABLE_STATIC_NS3']) or \
 15.1801 ++      (conf.env['ENABLE_SHARED_AND_STATIC_NS3'])):
 15.1802 ++        conf.report_optional_feature("python", "Python Bindings", False,
 15.1803 ++                                     "bindings incompatible with static build")
 15.1804 ++        return
 15.1805 ++
 15.1806 ++    enabled_modules = list(conf.env['NS3_ENABLED_MODULES'])
 15.1807 ++    enabled_modules.sort()
 15.1808 ++    available_modules = list(conf.env['NS3_MODULES'])
 15.1809 ++    available_modules.sort()
 15.1810 ++    all_modules_enabled = (enabled_modules == available_modules)
 15.1811 ++
 15.1812 ++    conf.check_tool('misc', tooldir=['waf-tools'])
 15.1813 ++
 15.1814 ++    if sys.platform == 'cygwin':
 15.1815 ++        conf.report_optional_feature("python", "Python Bindings", False,
 15.1816 ++                                     "unsupported platform 'cygwin'")
 15.1817 ++        Logs.warn("Python is not supported in CygWin environment.  Try MingW instead.")
 15.1818 ++        return
 15.1819 ++
 15.1820 ++
 15.1821 ++    ## Check for Python
 15.1822 ++
 15.1823 ++    # if Options.options.with_python is not None:
 15.1824 ++    #     conf.env.PYTHON = Options.options.with_python
 15.1825 ++
 15.1826 ++    try:
 15.1827 ++        conf.check_tool('python')
 15.1828 ++    except Configure.ConfigurationError, ex:
 15.1829 ++        conf.report_optional_feature("python", "Python Bindings", False,
 15.1830 ++                                     "The python interpreter was not found")
 15.1831 ++        return
 15.1832 ++    try:
 15.1833 ++        conf.check_python_version((2,3))
 15.1834 ++    except Configure.ConfigurationError, ex:
 15.1835 ++        conf.report_optional_feature("python", "Python Bindings", False,
 15.1836 ++                                     "The python found version is too low (2.3 required)")
 15.1837 ++        return
 15.1838 ++    try:
 15.1839 ++        conf.check_python_headers()
 15.1840 ++    except Configure.ConfigurationError, ex:
 15.1841 ++        conf.report_optional_feature("python", "Python Bindings", False,
 15.1842 ++                                     "Python library or headers missing")
 15.1843 ++        return
 15.1844 ++
 15.1845 ++    # stupid Mac OSX Python wants to build extensions as "universal
 15.1846 ++    # binaries", i386, x86_64, and ppc, but this way the type
 15.1847 ++    # __uint128_t is not available.  We need to disable the multiarch
 15.1848 ++    # crap by removing the -arch parameters.
 15.1849 ++    for flags_var in ["CFLAGS_PYEXT", "CFLAGS_PYEMBED", "CXXFLAGS_PYEMBED",
 15.1850 ++                      "CXXFLAGS_PYEXT", "LINKFLAGS_PYEMBED", "LINKFLAGS_PYEXT"]:
 15.1851 ++        flags = conf.env[flags_var]
 15.1852 ++        i = 0
 15.1853 ++        while i < len(flags):
 15.1854 ++            if flags[i] == '-arch':
 15.1855 ++                del flags[i]
 15.1856 ++                del flags[i]
 15.1857 ++                continue
 15.1858 ++            i += 1
 15.1859 ++        conf.env[flags_var] = flags
 15.1860 ++
 15.1861 ++    # -fvisibility=hidden optimization
 15.1862 ++    # if (conf.env['CXX_NAME'] == 'gcc' and [int(x) for x in conf.env['CC_VERSION']] >= [4,0,0]
 15.1863 ++    #     and conf.check_compilation_flag('-fvisibility=hidden')):
 15.1864 ++        conf.env.append_value('CXXFLAGS_PYEXT', '-fvisibility=hidden')
 15.1865 ++        conf.env.append_value('CCFLAGS_PYEXT', '-fvisibility=hidden')
 15.1866 ++
 15.1867 ++    # if conf.check_compilation_flag('-Wno-array-bounds'):
 15.1868 ++        conf.env.append_value('CXXFLAGS_PYEXT', '-Wno-array-bounds')
 15.1869 ++
 15.1870 ++    # Check for the location of pybindgen
 15.1871 ++    # if Options.options.with_pybindgen is not None:
 15.1872 ++    #     if os.path.isdir(Options.options.with_pybindgen):
 15.1873 ++    #         conf.msg("Checking for pybindgen location", ("%s (given)" % Options.options.with_pybindgen))
 15.1874 ++    #         conf.env['WITH_PYBINDGEN'] = os.path.abspath(Options.options.with_pybindgen)
 15.1875 ++    # else:
 15.1876 ++    #     # ns-3-dev uses ../pybindgen, while ns-3 releases use ../REQUIRED_PYBINDGEN_VERSION
 15.1877 ++    #     pybindgen_dir = os.path.join('..', "pybindgen")
 15.1878 ++    #     pybindgen_release_str = "pybindgen-" + '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION])
 15.1879 ++    #     pybindgen_release_dir = os.path.join('..', pybindgen_release_str)
 15.1880 ++    #     if os.path.isdir(pybindgen_dir):
 15.1881 ++    #         conf.msg("Checking for pybindgen location", ("%s (guessed)" % pybindgen_dir))
 15.1882 ++    #         conf.env['WITH_PYBINDGEN'] = os.path.abspath(pybindgen_dir)
 15.1883 ++    #     elif os.path.isdir(pybindgen_release_dir):
 15.1884 ++    #         conf.msg("Checking for pybindgen location", ("%s (guessed)" % pybindgen_release_dir))
 15.1885 ++    #         conf.env['WITH_PYBINDGEN'] = os.path.abspath(pybindgen_release_dir)
 15.1886 ++    #     del pybindgen_dir
 15.1887 ++    #     del pybindgen_release_dir
 15.1888 ++    # if not conf.env['WITH_PYBINDGEN']:
 15.1889 ++    #     conf.msg("Checking for pybindgen location", False)
 15.1890 ++
 15.1891 ++    # Check for pybindgen
 15.1892 ++
 15.1893 ++    set_pybindgen_pythonpath(conf.env)
 15.1894 ++
 15.1895 ++    # try:
 15.1896 ++    #     conf.check_python_module('pybindgen')
 15.1897 ++    # except Configure.ConfigurationError:
 15.1898 ++    #     Logs.warn("pybindgen missing => no python bindings")
 15.1899 ++    #     conf.report_optional_feature("python", "Python Bindings", False,
 15.1900 ++    #                                  "PyBindGen missing")
 15.1901 ++    #     return
 15.1902 ++    # else:
 15.1903 ++    #     out = subprocess.Popen([conf.env['PYTHON'][0], "-c",
 15.1904 ++    #                             "import pybindgen.version; "
 15.1905 ++    #                             "print '.'.join([str(x) for x in pybindgen.version.__version__])"],
 15.1906 ++    #                             stdout=subprocess.PIPE).communicate()[0]
 15.1907 ++    #     pybindgen_version_str = out.strip()
 15.1908 ++    #     pybindgen_version = tuple([int(x) for x in pybindgen_version_str.split('.')])
 15.1909 ++    #     conf.msg('Checking for pybindgen version', pybindgen_version_str)
 15.1910 ++    #     if not (pybindgen_version == REQUIRED_PYBINDGEN_VERSION):
 15.1911 ++    #         Logs.warn("pybindgen (found %s), (need %s)" %
 15.1912 ++    #                 (pybindgen_version_str,
 15.1913 ++    #                  '.'.join([str(x) for x in REQUIRED_PYBINDGEN_VERSION])))
 15.1914 ++    #         conf.report_optional_feature("python", "Python Bindings", False,
 15.1915 ++    #                                      "PyBindGen version not correct and newer version could not be retrieved")
 15.1916 ++    #         return
 15.1917 ++
 15.1918 ++
 15.1919 ++    def test(t1, t2):
 15.1920 ++        test_program = '''
 15.1921 ++#include <stdint.h>
 15.1922 ++#include <vector>
 15.1923 ++
 15.1924 ++int main ()
 15.1925 ++{
 15.1926 ++   std::vector< %(type1)s > t = std::vector< %(type2)s > ();
 15.1927 ++   return 0;
 15.1928 ++}
 15.1929 ++''' % dict(type1=t1, type2=t2)
 15.1930 ++
 15.1931 ++        try:
 15.1932 ++            ret = conf.run_c_code(code=test_program,
 15.1933 ++                                  env=conf.env.copy(), compile_filename='test.cc',
 15.1934 ++                                  features='cxx cprogram', execute=False)
 15.1935 ++        except Configure.ConfigurationError:
 15.1936 ++            ret = 1
 15.1937 ++        conf.msg('Checking for types %s and %s equivalence' % (t1, t2), (ret and 'no' or 'yes'))
 15.1938 ++        return not ret
 15.1939 ++
 15.1940 ++    uint64_is_long = test("uint64_t", "unsigned long")
 15.1941 ++    uint64_is_long_long = test("uint64_t", "unsigned long long")
 15.1942 ++
 15.1943 ++    if uint64_is_long:
 15.1944 ++        conf.env['PYTHON_BINDINGS_APIDEFS'] = 'gcc-LP64'
 15.1945 ++    elif uint64_is_long_long:
 15.1946 ++        conf.env['PYTHON_BINDINGS_APIDEFS'] = 'gcc-ILP32'
 15.1947 ++    else:
 15.1948 ++        conf.env['PYTHON_BINDINGS_APIDEFS'] = None
 15.1949 ++    if conf.env['PYTHON_BINDINGS_APIDEFS'] is None:
 15.1950 ++        msg = 'none available'
 15.1951 ++    else:
 15.1952 ++        msg = conf.env['PYTHON_BINDINGS_APIDEFS']
 15.1953 ++
 15.1954 ++    conf.msg('Checking for the apidefs that can be used for Python bindings', msg)
 15.1955 ++
 15.1956 ++    if conf.env['PYTHON_BINDINGS_APIDEFS'] is None:
 15.1957 ++        ns3waf._report_optional_feature(conf, "python", "Python Bindings", False,
 15.1958 ++                                     "No apidefs are available that can be used in this system")
 15.1959 ++        return
 15.1960 ++
 15.1961 ++
 15.1962 ++    ## If all has gone well, we finally enable the Python bindings
 15.1963 ++    conf.env['ENABLE_PYTHON_BINDINGS'] = True
 15.1964 ++    ns3waf._report_optional_feature(conf, "python", "Python Bindings", True, None)
 15.1965 ++
 15.1966 ++
 15.1967 ++    # check cxxabi stuff (which Mac OS X Lion breaks)
 15.1968 ++    fragment = r"""
 15.1969 ++# include <cxxabi.h>
 15.1970 ++int main ()
 15.1971 ++{
 15.1972 ++   const abi::__si_class_type_info *_typeinfo  __attribute__((unused)) = NULL;
 15.1973 ++   return 0;
 15.1974 ++}
 15.1975 ++"""
 15.1976 ++    gcc_rtti_abi = _check_nonfatal(conf, fragment=fragment, msg="Checking for internal GCC cxxabi",
 15.1977 ++                                  okmsg="complete", errmsg='incomplete',
 15.1978 ++                                  mandatory=False)
 15.1979 ++    conf.env["GCC_RTTI_ABI_COMPLETE"] = str(bool(gcc_rtti_abi))
 15.1980 ++
 15.1981 ++
 15.1982 ++
 15.1983 ++    ## Check for pygccxml
 15.1984 ++    try:
 15.1985 ++        conf.check_python_module('pygccxml')
 15.1986 ++    except Configure.ConfigurationError:
 15.1987 ++        ns3waf._report_optional_feature(conf, "pygccxml", "Python API Scanning Support", False,
 15.1988 ++                                     "Missing 'pygccxml' Python module")
 15.1989 ++        return
 15.1990 ++
 15.1991 ++    out = subprocess.Popen([conf.env['PYTHON'][0], "-c",
 15.1992 ++                            "import pygccxml; print pygccxml.__version__"],
 15.1993 ++                            stdout=subprocess.PIPE).communicate()[0]
 15.1994 ++    pygccxml_version_str = out.strip()
 15.1995 ++    pygccxml_version = tuple([int(x) for x in pygccxml_version_str.split('.')])
 15.1996 ++    conf.msg('Checking for pygccxml version', pygccxml_version_str)
 15.1997 ++    if not (pygccxml_version >= REQUIRED_PYGCCXML_VERSION):
 15.1998 ++        Logs.warn("pygccxml (found %s) is too old (need %s) => "
 15.1999 ++                "automatic scanning of API definitions will not be possible" %
 15.2000 ++                (pygccxml_version_str,
 15.2001 ++                 '.'.join([str(x) for x in REQUIRED_PYGCCXML_VERSION])))
 15.2002 ++        ns3waf._report_optional_feature(conf, "pygccxml", "Python API Scanning Support", False,
 15.2003 ++                                     "pygccxml too old")
 15.2004 ++        return
 15.2005 ++    
 15.2006 ++
 15.2007 ++    ## Check gccxml version
 15.2008 ++    try:
 15.2009 ++        gccxml = conf.find_program('gccxml', var='GCCXML')
 15.2010 ++    except WafError:
 15.2011 ++        gccxml = None
 15.2012 ++    if not gccxml:
 15.2013 ++        Logs.warn("gccxml missing; automatic scanning of API definitions will not be possible")
 15.2014 ++        ns3waf._report_optional_feature(conf, "pygccxml", "Python API Scanning Support", False,
 15.2015 ++                                     "gccxml missing")
 15.2016 ++        return
 15.2017 ++
 15.2018 ++    gccxml_version_line = os.popen(gccxml + " --version").readline().strip()
 15.2019 ++    m = re.match( "^GCC-XML version (\d\.\d(\.\d)?)$", gccxml_version_line)
 15.2020 ++    gccxml_version = m.group(1)
 15.2021 ++    gccxml_version_ok = ([int(s) for s in gccxml_version.split('.')] >= [0, 9])
 15.2022 ++    conf.msg('Checking for gccxml version', gccxml_version)
 15.2023 ++    if not gccxml_version_ok:
 15.2024 ++        Logs.warn("gccxml too old, need version >= 0.9; automatic scanning of API definitions will not be possible")
 15.2025 ++        ns3waf._report_optional_feature(conf, "pygccxml", "Python API Scanning Support", False,
 15.2026 ++                                     "gccxml too old")
 15.2027 ++        return
 15.2028 ++
 15.2029 ++    ## If we reached
 15.2030 ++    conf.env['ENABLE_PYTHON_SCANNING'] = True
 15.2031 ++    ns3waf._report_optional_feature(conf, "pygccxml", "Python API Scanning Support", True, None)
 15.2032 ++
 15.2033 ++# ---------------------
 15.2034 ++def get_headers_map(headers, module):
 15.2035 ++    headers_map = {} # header => module
 15.2036 ++    for header in headers:
 15.2037 ++        headers_map[os.path.basename(header)] = module
 15.2038 ++    return headers_map
 15.2039 ++# def get_headers_map(bld, module):
 15.2040 ++#     headers_map = {} # header => module
 15.2041 ++#     for ns3headers in bld.all_task_gen:
 15.2042 ++#         if 'ns3header' in getattr(ns3headers, "headers", []):
 15.2043 ++#             if ns3headers.name.find('lib/ns3-') is -1:
 15.2044 ++#                 continue
 15.2045 ++#             if ns3headers.name.find('-test') is not -1:
 15.2046 ++#                 continue
 15.2047 ++#             for h in ns3headers.to_list(ns3headers.headers):
 15.2048 ++#                 print "h = %s" % h
 15.2049 ++#                 headers_map[os.path.basename(h)] = ns3headers.module
 15.2050 ++#     return headers_map
 15.2051 ++
 15.2052 ++def get_module_path(bld, module):
 15.2053 ++    for ns3headers in bld.all_task_gen:
 15.2054 ++        if 'ns3header' in getattr(ns3headers, "features", []):
 15.2055 ++            if ns3headers.module == module:
 15.2056 ++                break
 15.2057 ++    else:
 15.2058 ++        raise ValueError("Module %r not found" % module)
 15.2059 ++    return ns3headers.path.abspath()
 15.2060 ++
 15.2061 ++def python_bin_scan(bld, target, module):
 15.2062 ++    for root, dirs, files in os.walk(str(module.bld.bldnode)):
 15.2063 ++        for f in files:
 15.2064 ++            if os.path.basename(module.headers[0]) == f:
 15.2065 ++                # XXX: FIXME
 15.2066 ++                top_builddir = os.path.dirname(os.path.join(root, f)).replace('/ns3','')
 15.2067 ++                out_topdir = os.path.dirname(os.path.join(root, f)).replace('build/','./').replace('include/ns3','')
 15.2068 ++
 15.2069 ++    argv = [
 15.2070 ++        'python',
 15.2071 ++        os.path.join('bindings', 'ns3modulescan-modular.py'), # scanning script
 15.2072 ++        top_builddir, #'build/include', 
 15.2073 ++        module.name.split('lib/ns3-')[1], #self.module,
 15.2074 ++        repr(get_headers_map(module.headers, module.name.split('lib/ns3-')[1])), #repr(get_headers_map(bld, module)),
 15.2075 ++        os.path.join(out_topdir, "bindings", 'modulegen__%s.py' % (target)), # output file
 15.2076 ++        # XXX: FIXME
 15.2077 ++        "-I../build/include/ns3-dev -I./build/include/", #self.cflags,
 15.2078 ++        ]
 15.2079 ++    print argv
 15.2080 ++    scan = subprocess.Popen(argv, stdin=subprocess.PIPE)
 15.2081 ++    retval = scan.wait()
 15.2082 ++    return retval
 15.2083 ++
 15.2084 ++class apiscan_task(Task.TaskBase):
 15.2085 ++    """Uses gccxml to scan the file 'everything.h' and extract API definitions.
 15.2086 ++    """
 15.2087 ++    after = 'gen_ns3_module_header ns3header'
 15.2088 ++    before = 'cc cxx command'
 15.2089 ++    color = "BLUE"
 15.2090 ++    def __init__(self, curdirnode, env, bld, target, cflags, module):
 15.2091 ++        self.bld = bld
 15.2092 ++        super(apiscan_task, self).__init__(generator=self)
 15.2093 ++        self.curdirnode = curdirnode
 15.2094 ++        self.env = env
 15.2095 ++        self.target = target
 15.2096 ++        self.cflags = cflags
 15.2097 ++        self.module = module
 15.2098 ++
 15.2099 ++    def display(self):
 15.2100 ++        return 'api-scan-%s\n' % (self.target,)
 15.2101 ++
 15.2102 ++    def run(self):
 15.2103 ++        top_builddir = self.bld.bldnode.abspath()
 15.2104 ++        #module_path = get_module_path(self.bld, self.module)
 15.2105 ++        #headers_map = get_headers_map(self.bld)
 15.2106 ++        # scan_header = os.path.join(top_builddir, "ns3", "%s-module.h" % self.module)
 15.2107 ++
 15.2108 ++        # if not os.path.exists(scan_header):
 15.2109 ++        #     Logs.error("Cannot apiscan module %r: %s does not exist" % (self.module, scan_header))
 15.2110 ++        #     return 0
 15.2111 ++
 15.2112 ++        # python scan
 15.2113 ++	retval = python_bin_scan(self.bld, self.target, self.module)
 15.2114 ++        return retval
 15.2115 ++
 15.2116 ++
 15.2117 ++def get_modules_and_headers(bld):
 15.2118 ++    """
 15.2119 ++    Gets a dict of
 15.2120 ++       module_name => ([module_dep1, module_dep2, ...], [module_header1, module_header2, ...])
 15.2121 ++    tuples, one for each module.
 15.2122 ++    """
 15.2123 ++
 15.2124 ++    retval = {}
 15.2125 ++    for module in bld.all_task_gen:
 15.2126 ++        if not module.name.startswith('ns3-'):
 15.2127 ++            continue
 15.2128 ++        if module.name.endswith('-test'):
 15.2129 ++            continue
 15.2130 ++        module_name = module.name[4:] # strip the ns3- prefix
 15.2131 ++        ## find the headers object for this module
 15.2132 ++        headers = []
 15.2133 ++        for ns3headers in bld.all_task_gen:
 15.2134 ++            if 'ns3header' not in getattr(ns3headers, "features", []):
 15.2135 ++                continue
 15.2136 ++            if ns3headers.module != module_name:
 15.2137 ++                continue
 15.2138 ++            for source in ns3headers.to_list(ns3headers.headers):
 15.2139 ++                headers.append(os.path.basename(source))
 15.2140 ++        retval[module_name] = (list(module.module_deps), headers)
 15.2141 ++    return retval
 15.2142 ++
 15.2143 ++
 15.2144 ++
 15.2145 ++
 15.2146 ++class python_scan_task_collector(Task.TaskBase):
 15.2147 ++    """Tasks that waits for the python-scan-* tasks to complete and then signals WAF to exit
 15.2148 ++    """
 15.2149 ++    after = 'apiscan'
 15.2150 ++    before = 'cc cxx'
 15.2151 ++    color = "BLUE"
 15.2152 ++    def __init__(self, curdirnode, env, bld):
 15.2153 ++        self.bld = bld
 15.2154 ++        super(python_scan_task_collector, self).__init__(generator=self)
 15.2155 ++        self.curdirnode = curdirnode
 15.2156 ++        self.env = env
 15.2157 ++
 15.2158 ++    def display(self):
 15.2159 ++        return 'python-scan-collector\n'
 15.2160 ++
 15.2161 ++    def run(self):
 15.2162 ++        # signal stop (we generated files into the source dir and WAF
 15.2163 ++        # can't cope with it, so we have to force the user to restart
 15.2164 ++        # WAF)
 15.2165 ++        self.bld.producer.stop = 1
 15.2166 ++        return 0
 15.2167 ++
 15.2168 ++
 15.2169 ++
 15.2170 ++class gen_ns3_compat_pymod_task(Task.Task):
 15.2171 ++    """Generates a 'ns3.py' compatibility module."""
 15.2172 ++    before = 'cc cxx'
 15.2173 ++    color = 'BLUE'
 15.2174 ++    
 15.2175 ++    def run(self):
 15.2176 ++        assert len(self.outputs) == 1
 15.2177 ++        outfile = file(self.outputs[0].abspath(), "w")
 15.2178 ++        print >> outfile, "import warnings"
 15.2179 ++        print >> outfile, 'warnings.warn("the ns3 module is a compatibility layer '\
 15.2180 ++            'and should not be used in newly written code", DeprecationWarning, stacklevel=2)'
 15.2181 ++        print >> outfile
 15.2182 ++        for module in self.bld.env['PYTHON_MODULES_BUILT']:
 15.2183 ++            print >> outfile, "from ns.%s import *" % (module.replace('-', '_'))
 15.2184 ++        outfile.close()
 15.2185 ++        return 0
 15.2186 ++
 15.2187 ++
 15.2188 ++def _ns3_python_apiscan(bld):
 15.2189 ++    env = bld.env
 15.2190 ++    #if not env['ENABLE_PYTHON_SCANNING']:
 15.2191 ++    #    raise WafError("Cannot re-scan python bindings: (py)gccxml not available")
 15.2192 ++    scan_targets = []
 15.2193 ++    if sys.platform == 'cygwin':
 15.2194 ++        scan_targets.append(('gcc_cygwin', ''))
 15.2195 ++    else:
 15.2196 ++        import struct
 15.2197 ++        if struct.calcsize('I') == 4 and struct.calcsize('L') == 8 and struct.calcsize('P') == 8:
 15.2198 ++            scan_targets.extend([('gcc_ILP32', '-m32'), ('gcc_LP64', '-m64')])
 15.2199 ++        elif struct.calcsize('I') == 4 and struct.calcsize('L') == 4 and struct.calcsize('P') == 4:
 15.2200 ++            scan_targets.append(('gcc_ILP32', ''))
 15.2201 ++        else:
 15.2202 ++            raise WafError("Cannot scan python bindings for unsupported data model")
 15.2203 ++
 15.2204 ++    test_module_path = bld.path.find_dir("./test")
 15.2205 ++    scan_modules = []
 15.2206 ++    for mod in bld.all_task_gen:
 15.2207 ++        if hasattr(mod, 'name') is False:
 15.2208 ++            continue
 15.2209 ++        if mod.name.find('lib/ns3-') is -1:
 15.2210 ++            continue
 15.2211 ++        if mod.name.find('-test') is not -1:
 15.2212 ++            continue
 15.2213 ++        #bindings_enabled = (mod.name in env.MODULAR_BINDINGS_MODULES)
 15.2214 ++        bindings_enabled = True
 15.2215 ++        #print mod.name, bindings_enabled
 15.2216 ++        if bindings_enabled:
 15.2217 ++            if Options.options.apiscan == 'all':
 15.2218 ++                #scan_modules.append(mod.name.split('lib/ns3-')[1])
 15.2219 ++                scan_modules.append(mod)
 15.2220 ++            else:
 15.2221 ++                if mod.name.split('lib/ns3-')[1] == Options.options.apiscan:
 15.2222 ++                    scan_modules.append(mod)
 15.2223 ++    print "Modules to scan: ", [mod.name for mod in scan_modules]
 15.2224 ++    for target, cflags in scan_targets:
 15.2225 ++        group = bld.get_group(bld.current_group)
 15.2226 ++        for module in scan_modules:
 15.2227 ++            group.append(apiscan_task(bld.path, env, bld, target, cflags, module))
 15.2228 ++    group.append(python_scan_task_collector(bld.path, env, bld))
 15.2229 ++    return
 15.2230 ++
 15.2231 ++def _ns3_python_bindings(bld, module):
 15.2232 ++    for root, dirs, files in os.walk(str(module.bld.bldnode)):
 15.2233 ++        for f in files:
 15.2234 ++            if os.path.basename(module.headers[0]) == f:
 15.2235 ++                # XXX: FIXME
 15.2236 ++                out_binding_dir = os.path.dirname(os.path.join(root, f)).replace('/include/ns3','').replace('build','./')
 15.2237 ++                include_dir = '../' + os.path.dirname(os.path.join(root, f)).replace('/ns3','').replace('build','./')
 15.2238 ++
 15.2239 ++    # this method is called from a module wscript, so remember bld.path is not bindings/python!
 15.2240 ++    module_abs_src_path = os.path.abspath(os.path.join('build', out_binding_dir))
 15.2241 ++    # module = os.path.basename(module_abs_src_path)
 15.2242 ++    env = bld.env
 15.2243 ++    # env.append_value("MODULAR_BINDINGS_MODULES", "ns3-"+module)
 15.2244 ++
 15.2245 ++    # if Options.options.apiscan:
 15.2246 ++    #     return
 15.2247 ++
 15.2248 ++    # if not env['ENABLE_PYTHON_BINDINGS']:
 15.2249 ++    #     return
 15.2250 ++
 15.2251 ++    bindings_dir = bld.path
 15.2252 ++    if bindings_dir is None or not os.path.exists(bindings_dir.abspath()):
 15.2253 ++        warnings.warn("(in %s) Requested to build modular python bindings, but apidefs dir not found "
 15.2254 ++                      "=> skipped the bindings." % str(bld.path),
 15.2255 ++                      Warning, stacklevel=2)
 15.2256 ++        return
 15.2257 ++
 15.2258 ++    # if ("ns3-%s" % (module,)) not in env.NS3_ENABLED_MODULES:
 15.2259 ++    #     #print "bindings for module %s which is not enabled, skip" % module
 15.2260 ++    #     return
 15.2261 ++
 15.2262 ++    #env.append_value('PYTHON_MODULES_BUILT', module)
 15.2263 ++    apidefs = env['PYTHON_BINDINGS_APIDEFS'].replace("-", "_")
 15.2264 ++
 15.2265 ++    #debug = ('PYBINDGEN_DEBUG' in os.environ)
 15.2266 ++    debug = True # XXX
 15.2267 ++    source = [bld.srcnode.find_resource('bindings/ns3modulegen-modular.py').relpath_gen(bld.path),
 15.2268 ++              "modulegen__%s.py" % apidefs]
 15.2269 ++
 15.2270 ++    if bindings_dir.find_resource("modulegen_customizations.py") is not None:
 15.2271 ++        source.append("bindings/modulegen_customizations.py")
 15.2272 ++
 15.2273 ++    # the local customization file may or not exist
 15.2274 ++    if bld.path.find_resource("bindings/modulegen_local.py"):
 15.2275 ++        source.append("bindings/modulegen_local.py")
 15.2276 ++
 15.2277 ++    module_py_name = module.name.split('lib/ns3-')[1].replace('-', '_')
 15.2278 ++    module_target_dir = bld.srcnode.find_dir("bindings/ns").relpath_gen(bld.path)
 15.2279 ++
 15.2280 ++    # if bindings/<module>.py exists, it becomes the module frontend, and the C extension befomes _<module>
 15.2281 ++    if bld.path.find_resource("bindings/%s.py" % (module_py_name,)) is not None:
 15.2282 ++        bld.new_task_gen(
 15.2283 ++            features='copy',
 15.2284 ++            source=("bindings/%s.py" % (module_py_name,)),
 15.2285 ++            target=('%s/%s.py' % (module_target_dir, module_py_name)))
 15.2286 ++        extension_name = '_%s' % (module_py_name,)
 15.2287 ++        bld.install_files('${PYTHONARCHDIR}/ns', ["bindings/%s.py" % (module_py_name,)])
 15.2288 ++    else:
 15.2289 ++        extension_name = module_py_name
 15.2290 ++
 15.2291 ++    target = ['../' + out_binding_dir + '/bindings/ns3module.cc', 
 15.2292 ++              '../' + out_binding_dir + '/bindings/ns3module.h', 
 15.2293 ++              '../' + out_binding_dir + '/bindings/ns3modulegen.log']
 15.2294 ++    #if not debug:
 15.2295 ++    #    target.append('ns3modulegen.log')
 15.2296 ++
 15.2297 ++    argv = ['NS3_ENABLED_FEATURES=${FEATURES}',
 15.2298 ++            'GCC_RTTI_ABI_COMPLETE=${GCC_RTTI_ABI_COMPLETE}',
 15.2299 ++            '${PYTHON}']
 15.2300 ++    #if debug:
 15.2301 ++    #    argv.extend(["-m", "pdb"])
 15.2302 ++
 15.2303 ++    argv.extend(['${SRC[0]}', module_abs_src_path, apidefs, extension_name, '${TGT[0]}'])
 15.2304 ++
 15.2305 ++    argv.extend(['2>', '${TGT[2]}']) # 2> ns3modulegen.log
 15.2306 ++
 15.2307 ++    features = []
 15.2308 ++    for (name, caption, was_enabled, reason_not_enabled) in env['NS3_OPTIONAL_FEATURES']:
 15.2309 ++        if was_enabled:
 15.2310 ++            features.append(name)
 15.2311 ++
 15.2312 ++    bindgen = bld.new_task_gen(features=['command'], source=source, target=target, command=argv)
 15.2313 ++    bindgen.env['FEATURES'] = ','.join(features)
 15.2314 ++    bindgen.dep_vars = ['FEATURES', "GCC_RTTI_ABI_COMPLETE"]
 15.2315 ++    bindgen.before = 'cxx'
 15.2316 ++    bindgen.after = 'gen_ns3_module_header'
 15.2317 ++    bindgen.name = "pybindgen(ns3 module %s)" % module.name.split('lib/ns3-')[1]
 15.2318 ++    bindgen.install_path = None
 15.2319 ++
 15.2320 ++    # generate the extension module
 15.2321 ++    pymod = bld.new_task_gen(features='cxx cxxshlib pyext')
 15.2322 ++    pymod.source = ['../' + out_binding_dir + '/bindings/ns3module.cc']
 15.2323 ++    pymod.target = '%s/%s' % (module_target_dir, extension_name)
 15.2324 ++    pymod.name = 'ns3module_%s' % module.name.split('lib/ns3-')[1]
 15.2325 ++    pymod.use = ["%s" % mod for mod in pymod.env['NS3_ENABLED_MODULES']] #  Should be '"ns3-"+module', but see bug 1117
 15.2326 ++    if pymod.env['ENABLE_STATIC_NS3']:
 15.2327 ++        if sys.platform == 'darwin':
 15.2328 ++            pymod.env.append_value('LINKFLAGS', '-Wl,-all_load')
 15.2329 ++            for mod in pymod.usel:
 15.2330 ++                #mod = mod.split("--lib")[0]
 15.2331 ++                pymod.env.append_value('LINKFLAGS', '-l' + mod)
 15.2332 ++        else:
 15.2333 ++            pymod.env.append_value('LINKFLAGS', '-Wl,--whole-archive,-Bstatic')
 15.2334 ++            for mod in pymod.use:
 15.2335 ++                #mod = mod.split("--lib")[0]
 15.2336 ++                pymod.env.append_value('LINKFLAGS', '-l' + mod)
 15.2337 ++            pymod.env.append_value('LINKFLAGS', '-Wl,-Bdynamic,--no-whole-archive')
 15.2338 ++    defines = list(pymod.env['DEFINES'])
 15.2339 ++    defines.extend(['NS_DEPRECATED=', 'NS3_DEPRECATED_H'])
 15.2340 ++    if Options.platform == 'win32':
 15.2341 ++        try:
 15.2342 ++            defines.remove('_DEBUG') # causes undefined symbols on win32
 15.2343 ++        except ValueError:
 15.2344 ++            pass
 15.2345 ++    pymod.env['DEFINES'] = defines
 15.2346 ++    # XXX: FIXME
 15.2347 ++    pymod.includes = '# ../include # ../../build/include/ns3-dev # ' + include_dir #'# bindings'
 15.2348 ++    pymod.install_path = '${PYTHONARCHDIR}/ns'
 15.2349 ++
 15.2350 ++    # Workaround to a WAF bug, remove this when ns-3 upgrades to WAF > 1.6.10
 15.2351 ++    # https://www.nsnam.org/bugzilla/show_bug.cgi?id=1335
 15.2352 ++    # http://code.google.com/p/waf/issues/detail?id=1098
 15.2353 ++    if Utils.unversioned_sys_platform() == 'darwin':
 15.2354 ++        pymod.mac_bundle = True
 15.2355 ++
 15.2356 ++    return pymod
 15.2357 ++
 15.2358 ++def build(bld):
 15.2359 ++    #if Options.options.python_disable:
 15.2360 ++    #    return
 15.2361 ++
 15.2362 ++    bld.ns3_python_apiscan = types.MethodType(_ns3_python_apiscan, bld)
 15.2363 ++    bld.ns3_python_bindings = types.MethodType(_ns3_python_bindings, bld)
 15.2364 ++    env = bld.env
 15.2365 ++    curdir = bld.path.abspath()
 15.2366 ++
 15.2367 ++    set_pybindgen_pythonpath(env)
 15.2368 ++
 15.2369 ++    if Options.options.apiscan:
 15.2370 ++        bld.ns3_python_apiscan()
 15.2371 ++        return
 15.2372 ++
 15.2373 ++    if env['ENABLE_PYTHON_BINDINGS']:
 15.2374 ++        task = gen_ns3_compat_pymod_task(env=env.derive())
 15.2375 ++        task.set_outputs(bld.path.find_or_declare("ns3.py"))
 15.2376 ++        task.dep_vars = ['PYTHON_MODULES_BUILT']
 15.2377 ++        task.bld = bld
 15.2378 ++        grp = bld.get_group(bld.current_group)
 15.2379 ++        grp.append(task)
 15.2380 ++
 15.2381 ++        bld.new_task_gen(features='copy',
 15.2382 ++                         source="ns__init__.py",
 15.2383 ++                         target='ns/__init__.py')
 15.2384 ++        bld.install_as('${PYTHONARCHDIR}/ns/__init__.py', 'ns__init__.py')
 15.2385 ++
 15.2386 ++        for mod in bld.all_task_gen:
 15.2387 ++            if hasattr(mod, 'name') is False:
 15.2388 ++                continue
 15.2389 ++            if mod.name.find('lib/ns3-') is -1:
 15.2390 ++                continue
 15.2391 ++            if mod.name.find('-test') is not -1:
 15.2392 ++                continue
 15.2393 ++            bld.ns3_python_bindings(mod)
 15.2394 ++
 15.2395 +diff --git a/example/dce-tcp-simple.py b/example/dce-tcp-simple.py
 15.2396 +new file mode 100644
 15.2397 +--- /dev/null
 15.2398 ++++ b/example/dce-tcp-simple.py
 15.2399 +@@ -0,0 +1,21 @@
 15.2400 ++# -*- coding: utf-8 -*-
 15.2401 ++
 15.2402 ++from ns.dce import *
 15.2403 ++from ns.core import *
 15.2404 ++from ns.network import *
 15.2405 ++from ns.internet import *
 15.2406 ++
 15.2407 ++nodes = NodeContainer()
 15.2408 ++nodes.Create (1)
 15.2409 ++stack = InternetStackHelper()
 15.2410 ++stack.Install (nodes)
 15.2411 ++dceManager = DceManagerHelper()
 15.2412 ++dceManager.Install (nodes);
 15.2413 ++dce = DceApplicationHelper()
 15.2414 ++apps = ApplicationContainer ()
 15.2415 ++dce.SetBinary ("/ns3-dev-tcp-loopback-debug")
 15.2416 ++dce.SetStackSize (1<<20)
 15.2417 ++apps = dce.Install (nodes)
 15.2418 ++apps.Start (Seconds (4.0))
 15.2419 ++Simulator.Stop (Seconds(10.0))
 15.2420 ++Simulator.Run ()
 15.2421 +diff --git a/test/netlink-socket-test.cc b/test/netlink-socket-test.cc
 15.2422 +--- a/test/netlink-socket-test.cc
 15.2423 ++++ b/test/netlink-socket-test.cc
 15.2424 +@@ -33,8 +33,8 @@
 15.2425 + #include "ns3/assert.h"
 15.2426 + #include "ns3/log.h"
 15.2427 + #include "ns3/socket.h"
 15.2428 +-#include "netlink-message.h"
 15.2429 +-#include "netlink-socket-address.h"
 15.2430 ++#include "../netlink/netlink-message.h"
 15.2431 ++#include "../netlink/netlink-socket-address.h"
 15.2432 + #include <sys/socket.h>
 15.2433 + #include <string>
 15.2434 + #include <list>
 15.2435 +diff --git a/waf-tools/boost.py b/waf-tools/boost.py
 15.2436 +new file mode 100644
 15.2437 +--- /dev/null
 15.2438 ++++ b/waf-tools/boost.py
 15.2439 +@@ -0,0 +1,278 @@
 15.2440 ++#!/usr/bin/env python
 15.2441 ++# encoding: utf-8
 15.2442 ++#
 15.2443 ++# partially based on boost.py written by Gernot Vormayr
 15.2444 ++# written by Ruediger Sonderfeld <ruediger@c-plusplus.de>, 2008
 15.2445 ++# modified by Bjoern Michaelsen, 2008
 15.2446 ++# modified by Luca Fossati, 2008
 15.2447 ++# rewritten for waf 1.5.1, Thomas Nagy, 2008
 15.2448 ++# rewritten for waf 1.6.2, Sylvain Rouquette, 2011
 15.2449 ++
 15.2450 ++'''
 15.2451 ++To add the boost tool to the waf file:
 15.2452 ++$ ./waf-light --tools=compat15,boost
 15.2453 ++	or, if you have waf >= 1.6.2
 15.2454 ++$ ./waf update --files=boost
 15.2455 ++
 15.2456 ++The wscript will look like:
 15.2457 ++
 15.2458 ++def options(opt):
 15.2459 ++	opt.load('compiler_cxx boost')
 15.2460 ++
 15.2461 ++def configure(conf):
 15.2462 ++	conf.load('compiler_cxx boost')
 15.2463 ++	conf.check_boost(lib='system filesystem', mt=True, static=True)
 15.2464 ++
 15.2465 ++def build(bld):
 15.2466 ++	bld(source='main.cpp', target='app', use='BOOST')
 15.2467 ++'''
 15.2468 ++
 15.2469 ++import sys
 15.2470 ++import re
 15.2471 ++from waflib import Utils, Logs
 15.2472 ++from waflib.Configure import conf
 15.2473 ++from waflib.Errors import WafError
 15.2474 ++
 15.2475 ++BOOST_LIBS = ('/usr/lib', '/usr/local/lib',
 15.2476 ++			  '/opt/local/lib', '/sw/lib', '/lib')
 15.2477 ++BOOST_INCLUDES = ('/usr/include', '/usr/local/include',
 15.2478 ++				  '/opt/local/include', '/sw/include')
 15.2479 ++BOOST_VERSION_FILE = 'boost/version.hpp'
 15.2480 ++BOOST_VERSION_CODE = '''
 15.2481 ++#include <iostream>
 15.2482 ++#include <boost/version.hpp>
 15.2483 ++int main() { std::cout << BOOST_LIB_VERSION << std::endl; }
 15.2484 ++'''
 15.2485 ++
 15.2486 ++# toolsets from {boost_dir}/tools/build/v2/tools/common.jam
 15.2487 ++PLATFORM = Utils.unversioned_sys_platform()
 15.2488 ++detect_intel = lambda env: (PLATFORM == 'win32') and 'iw' or 'il'
 15.2489 ++detect_clang = lambda env: (PLATFORM == 'darwin') and 'clang-darwin' or 'clang'
 15.2490 ++detect_mingw = lambda env: (re.search('MinGW', env.CXX[0])) and 'mgw' or 'gcc'
 15.2491 ++BOOST_TOOLSETS = {
 15.2492 ++	'borland':  'bcb',
 15.2493 ++	'clang':	detect_clang,
 15.2494 ++	'como':	 'como',
 15.2495 ++	'cw':	   'cw',
 15.2496 ++	'darwin':   'xgcc',
 15.2497 ++	'edg':	  'edg',
 15.2498 ++	'g++':	  detect_mingw,
 15.2499 ++	'gcc':	  detect_mingw,
 15.2500 ++	'icpc':	 detect_intel,
 15.2501 ++	'intel':	detect_intel,
 15.2502 ++	'kcc':	  'kcc',
 15.2503 ++	'kylix':	'bck',
 15.2504 ++	'mipspro':  'mp',
 15.2505 ++	'mingw':	'mgw',
 15.2506 ++	'msvc':	 'vc',
 15.2507 ++	'qcc':	  'qcc',
 15.2508 ++	'sun':	  'sw',
 15.2509 ++	'sunc++':   'sw',
 15.2510 ++	'tru64cxx': 'tru',
 15.2511 ++	'vacpp':	'xlc'
 15.2512 ++}
 15.2513 ++
 15.2514 ++
 15.2515 ++def options(opt):
 15.2516 ++	opt.add_option('--boost-includes', type='string',
 15.2517 ++				   default='', dest='boost_includes',
 15.2518 ++				   help='''path to the boost directory where the includes are
 15.2519 ++				   e.g. /boost_1_45_0/include''')
 15.2520 ++	opt.add_option('--boost-libs', type='string',
 15.2521 ++				   default='', dest='boost_libs',
 15.2522 ++				   help='''path to the directory where the boost libs are
 15.2523 ++				   e.g. /boost_1_45_0/stage/lib''')
 15.2524 ++	opt.add_option('--boost-static', action='store_true',
 15.2525 ++				   default=False, dest='boost_static',
 15.2526 ++				   help='link static libraries')
 15.2527 ++	opt.add_option('--boost-mt', action='store_true',
 15.2528 ++				   default=False, dest='boost_mt',
 15.2529 ++				   help='select multi-threaded libraries')
 15.2530 ++	opt.add_option('--boost-abi', type='string', default='', dest='boost_abi',
 15.2531 ++				   help='''select libraries with tags (dgsyp, d for debug),
 15.2532 ++				   see doc Boost, Getting Started, chapter 6.1''')
 15.2533 ++	opt.add_option('--boost-toolset', type='string',
 15.2534 ++				   default='', dest='boost_toolset',
 15.2535 ++				   help='force a toolset e.g. msvc, vc90, \
 15.2536 ++						gcc, mingw, mgw45 (default: auto)')
 15.2537 ++	py_version = '%d%d' % (sys.version_info[0], sys.version_info[1])
 15.2538 ++	opt.add_option('--boost-python', type='string',
 15.2539 ++				   default=py_version, dest='boost_python',
 15.2540 ++				   help='select the lib python with this version \
 15.2541 ++						(default: %s)' % py_version)
 15.2542 ++
 15.2543 ++
 15.2544 ++@conf
 15.2545 ++def __boost_get_version_file(self, dir):
 15.2546 ++	try:
 15.2547 ++		return self.root.find_dir(dir).find_node(BOOST_VERSION_FILE)
 15.2548 ++	except:
 15.2549 ++		return None
 15.2550 ++
 15.2551 ++
 15.2552 ++@conf
 15.2553 ++def boost_get_version(self, dir):
 15.2554 ++	"""silently retrieve the boost version number"""
 15.2555 ++	re_but = re.compile('^#define\\s+BOOST_LIB_VERSION\\s+"(.*)"$', re.M)
 15.2556 ++	try:
 15.2557 ++		val = re_but.search(self.__boost_get_version_file(dir).read()).group(1)
 15.2558 ++	except:
 15.2559 ++		val = self.check_cxx(fragment=BOOST_VERSION_CODE, includes=[dir],
 15.2560 ++							 execute=True, define_ret=True)
 15.2561 ++	return val
 15.2562 ++
 15.2563 ++
 15.2564 ++@conf
 15.2565 ++def boost_get_includes(self, *k, **kw):
 15.2566 ++	includes = k and k[0] or kw.get('includes', None)
 15.2567 ++	if includes and self.__boost_get_version_file(includes):
 15.2568 ++		return includes
 15.2569 ++	for dir in BOOST_INCLUDES:
 15.2570 ++		if self.__boost_get_version_file(dir):
 15.2571 ++			return dir
 15.2572 ++	if includes:
 15.2573 ++		self.fatal('headers not found in %s' % includes)
 15.2574 ++	else:
 15.2575 ++		self.fatal('headers not found, use --boost-includes=/path/to/boost')
 15.2576 ++
 15.2577 ++
 15.2578 ++@conf
 15.2579 ++def boost_get_toolset(self, cc):
 15.2580 ++	toolset = cc
 15.2581 ++	if not cc:
 15.2582 ++		build_platform = Utils.unversioned_sys_platform()
 15.2583 ++		if build_platform in BOOST_TOOLSETS:
 15.2584 ++			cc = build_platform
 15.2585 ++		else:
 15.2586 ++			cc = self.env.CXX_NAME
 15.2587 ++	if cc in BOOST_TOOLSETS:
 15.2588 ++		toolset = BOOST_TOOLSETS[cc]
 15.2589 ++	return isinstance(toolset, str) and toolset or toolset(self.env)
 15.2590 ++
 15.2591 ++
 15.2592 ++@conf
 15.2593 ++def __boost_get_libs_path(self, *k, **kw):
 15.2594 ++	''' return the lib path and all the files in it '''
 15.2595 ++	if 'files' in kw:
 15.2596 ++		return self.root.find_dir('.'), Utils.to_list(kw['files'])
 15.2597 ++	libs = k and k[0] or kw.get('libs', None)
 15.2598 ++	if libs:
 15.2599 ++		path = self.root.find_dir(libs)
 15.2600 ++		files = path.ant_glob('*boost_*')
 15.2601 ++	if not libs or not files:
 15.2602 ++		for dir in BOOST_LIBS:
 15.2603 ++			try:
 15.2604 ++				path = self.root.find_dir(dir)
 15.2605 ++				files = path.ant_glob('*boost_*')
 15.2606 ++				if files:
 15.2607 ++					break
 15.2608 ++				path = self.root.find_dir(dir + '64')
 15.2609 ++				files = path.ant_glob('*boost_*')
 15.2610 ++				if files:
 15.2611 ++					break
 15.2612 ++			except:
 15.2613 ++				path = None
 15.2614 ++	if not path:
 15.2615 ++		if libs:
 15.2616 ++			self.fatal('libs not found in %s' % libs)
 15.2617 ++		else:
 15.2618 ++			self.fatal('libs not found, \
 15.2619 ++					   use --boost-includes=/path/to/boost/lib')
 15.2620 ++	return path, files
 15.2621 ++
 15.2622 ++
 15.2623 ++@conf
 15.2624 ++def boost_get_libs(self, *k, **kw):
 15.2625 ++	'''
 15.2626 ++	return the lib path and the required libs
 15.2627 ++	according to the parameters
 15.2628 ++	'''
 15.2629 ++	path, files = self.__boost_get_libs_path(**kw)
 15.2630 ++	t = []
 15.2631 ++	if kw.get('mt', False):
 15.2632 ++		t.append('mt')
 15.2633 ++	if kw.get('abi', None):
 15.2634 ++		t.append(kw['abi'])
 15.2635 ++	tags = t and '(-%s)+' % '-'.join(t) or ''
 15.2636 ++	toolset = '(-%s[0-9]{0,3})+' % self.boost_get_toolset(kw.get('toolset', ''))
 15.2637 ++	version = '(-%s)+' % self.env.BOOST_VERSION
 15.2638 ++
 15.2639 ++	def find_lib(re_lib, files):
 15.2640 ++		for file in files:
 15.2641 ++			if re_lib.search(file.name):
 15.2642 ++				return file
 15.2643 ++		return None
 15.2644 ++
 15.2645 ++	def format_lib_name(name):
 15.2646 ++		if name.startswith('lib'):
 15.2647 ++			name = name[3:]
 15.2648 ++		return name.split('.')[0]
 15.2649 ++
 15.2650 ++	libs = []
 15.2651 ++	for lib in Utils.to_list(k and k[0] or kw.get('lib', None)):
 15.2652 ++		py = (lib == 'python') and '(-py%s)+' % kw['python'] or ''
 15.2653 ++		# Trying libraries, from most strict match to least one
 15.2654 ++		for pattern in ['boost_%s%s%s%s%s' % (lib, toolset, tags, py, version),
 15.2655 ++						'boost_%s%s%s%s' % (lib, tags, py, version),
 15.2656 ++						'boost_%s%s%s' % (lib, tags, version),
 15.2657 ++						# Give up trying to find the right version
 15.2658 ++						'boost_%s%s%s%s' % (lib, toolset, tags, py),
 15.2659 ++						'boost_%s%s%s' % (lib, tags, py),
 15.2660 ++						'boost_%s%s' % (lib, tags)]:
 15.2661 ++			file = find_lib(re.compile(pattern), files)
 15.2662 ++			if file:
 15.2663 ++				libs.append(format_lib_name(file.name))
 15.2664 ++				break
 15.2665 ++		else:
 15.2666 ++			self.fatal('lib %s not found in %s' % (lib, path))
 15.2667 ++
 15.2668 ++	return path.abspath(), libs
 15.2669 ++
 15.2670 ++
 15.2671 ++@conf
 15.2672 ++def check_boost(self, *k, **kw):
 15.2673 ++	"""
 15.2674 ++	initialize boost
 15.2675 ++
 15.2676 ++	You can pass the same parameters as the command line (without "--boost-"),
 15.2677 ++	but the command line has the priority.
 15.2678 ++	"""
 15.2679 ++	if not self.env['CXX']:
 15.2680 ++		self.fatal('load a c++ compiler first, conf.load("compiler_cxx")')
 15.2681 ++
 15.2682 ++	params = {'lib': k and k[0] or kw.get('lib', None)}
 15.2683 ++	for key, value in self.options.__dict__.items():
 15.2684 ++		if not key.startswith('boost_'):
 15.2685 ++			continue
 15.2686 ++		key = key[len('boost_'):]
 15.2687 ++		params[key] = value and value or kw.get(key, '')
 15.2688 ++
 15.2689 ++	var = kw.get('uselib_store', 'BOOST')
 15.2690 ++
 15.2691 ++	self.start_msg('Checking boost includes')
 15.2692 ++	try:
 15.2693 ++		self.env['INCLUDES_%s' % var] = self.boost_get_includes(**params)
 15.2694 ++		self.env.BOOST_VERSION = self.boost_get_version(self.env['INCLUDES_%s' % var])
 15.2695 ++	except WafError:
 15.2696 ++		self.end_msg("not found", 'YELLOW')
 15.2697 ++		raise
 15.2698 ++	self.end_msg(self.env.BOOST_VERSION)
 15.2699 ++	if Logs.verbose:
 15.2700 ++		Logs.pprint('CYAN', '	path : %s' % self.env['INCLUDES_%s' % var])
 15.2701 ++
 15.2702 ++	if not params['lib']:
 15.2703 ++		return
 15.2704 ++	self.start_msg('Checking boost libs')
 15.2705 ++	try:
 15.2706 ++		suffix = params.get('static', 'ST') or ''
 15.2707 ++		path, libs = self.boost_get_libs(**params)
 15.2708 ++	except WafError:
 15.2709 ++		self.end_msg("not found", 'YELLOW')
 15.2710 ++		raise
 15.2711 ++	self.env['%sLIBPATH_%s' % (suffix, var)] = [path]
 15.2712 ++	self.env['%sLIB_%s' % (suffix, var)] = libs
 15.2713 ++	self.end_msg('ok')
 15.2714 ++	if Logs.verbose:
 15.2715 ++		Logs.pprint('CYAN', '	path : %s' % path)
 15.2716 ++		Logs.pprint('CYAN', '	libs : %s' % libs)
 15.2717 ++
 15.2718 +diff --git a/waf-tools/cflags.py b/waf-tools/cflags.py
 15.2719 +new file mode 100644
 15.2720 +--- /dev/null
 15.2721 ++++ b/waf-tools/cflags.py
 15.2722 +@@ -0,0 +1,192 @@
 15.2723 ++import Logs
 15.2724 ++import Options
 15.2725 ++import Utils
 15.2726 ++
 15.2727 ++
 15.2728 ++class CompilerTraits(object):
 15.2729 ++	def get_warnings_flags(self, level):
 15.2730 ++		"""get_warnings_flags(level) -> list of cflags"""
 15.2731 ++		raise NotImplementedError
 15.2732 ++
 15.2733 ++	def get_optimization_flags(self, level):
 15.2734 ++		"""get_optimization_flags(level) -> list of cflags"""
 15.2735 ++		raise NotImplementedError
 15.2736 ++
 15.2737 ++	def get_debug_flags(self, level):
 15.2738 ++		"""get_debug_flags(level) -> (list of cflags, list of cppdefines)"""
 15.2739 ++		raise NotImplementedError
 15.2740 ++
 15.2741 ++
 15.2742 ++class GccTraits(CompilerTraits):
 15.2743 ++	def __init__(self):
 15.2744 ++		super(GccTraits, self).__init__()
 15.2745 ++		# cumulative list of warnings per level
 15.2746 ++		self.warnings_flags = [['-Wall'], ['-Werror'], ['-Wextra']]
 15.2747 ++
 15.2748 ++	def get_warnings_flags(self, level):
 15.2749 ++		warnings = []
 15.2750 ++		for l in range(level):
 15.2751 ++			if l < len(self.warnings_flags):
 15.2752 ++				warnings.extend(self.warnings_flags[l])
 15.2753 ++			else:
 15.2754 ++				break
 15.2755 ++		return warnings
 15.2756 ++
 15.2757 ++	def get_optimization_flags(self, level):
 15.2758 ++		if level == 0:
 15.2759 ++			return ['-O0']
 15.2760 ++		elif level == 1:
 15.2761 ++			return ['-O']
 15.2762 ++		elif level == 2:
 15.2763 ++			return ['-O2']
 15.2764 ++		elif level == 3:
 15.2765 ++			return ['-O3']
 15.2766 ++
 15.2767 ++	def get_debug_flags(self, level):
 15.2768 ++		if level == 0:
 15.2769 ++			return (['-g0'], ['NDEBUG'])
 15.2770 ++		elif level == 1:
 15.2771 ++			return (['-g'], [])
 15.2772 ++		elif level >= 2:
 15.2773 ++			return (['-ggdb', '-g3'], ['_DEBUG'])
 15.2774 ++		
 15.2775 ++
 15.2776 ++class IccTraits(CompilerTraits):
 15.2777 ++	def __init__(self):
 15.2778 ++		super(IccTraits, self).__init__()
 15.2779 ++		# cumulative list of warnings per level
 15.2780 ++		# icc is _very_ verbose with -Wall, -Werror is barely achievable
 15.2781 ++		self.warnings_flags = [[], [], ['-Wall']]
 15.2782 ++		
 15.2783 ++	def get_warnings_flags(self, level):
 15.2784 ++		warnings = []
 15.2785 ++		for l in range(level):
 15.2786 ++			if l < len(self.warnings_flags):
 15.2787 ++				warnings.extend(self.warnings_flags[l])
 15.2788 ++			else:
 15.2789 ++				break
 15.2790 ++		return warnings
 15.2791 ++
 15.2792 ++	def get_optimization_flags(self, level):
 15.2793 ++		if level == 0:
 15.2794 ++			return ['-O0']
 15.2795 ++		elif level == 1:
 15.2796 ++			return ['-O']
 15.2797 ++		elif level == 2:
 15.2798 ++			return ['-O2']
 15.2799 ++		elif level == 3:
 15.2800 ++			return ['-O3']
 15.2801 ++
 15.2802 ++	def get_debug_flags(self, level):
 15.2803 ++		if level == 0:
 15.2804 ++			return (['-g0'], ['NDEBUG'])
 15.2805 ++		elif level == 1:
 15.2806 ++			return (['-g'], [])
 15.2807 ++		elif level >= 2:
 15.2808 ++			return (['-ggdb', '-g3'], ['_DEBUG'])
 15.2809 ++		
 15.2810 ++
 15.2811 ++
 15.2812 ++class MsvcTraits(CompilerTraits):
 15.2813 ++	def __init__(self):
 15.2814 ++		super(MsvcTraits, self).__init__()
 15.2815 ++		# cumulative list of warnings per level
 15.2816 ++		self.warnings_flags = [['/W2'], ['/WX'], ['/Wall']]
 15.2817 ++
 15.2818 ++	def get_warnings_flags(self, level):
 15.2819 ++		warnings = []
 15.2820 ++		for l in range(level):
 15.2821 ++			if l < len(self.warnings_flags):
 15.2822 ++				warnings.extend(self.warnings_flags[l])
 15.2823 ++			else:
 15.2824 ++				break
 15.2825 ++		return warnings
 15.2826 ++
 15.2827 ++	def get_optimization_flags(self, level):
 15.2828 ++		if level == 0:
 15.2829 ++			return ['/Od']
 15.2830 ++		elif level == 1:
 15.2831 ++			return []
 15.2832 ++		elif level == 2:
 15.2833 ++			return ['/O2']
 15.2834 ++		elif level == 3:
 15.2835 ++			return ['/Ox']
 15.2836 ++
 15.2837 ++	def get_debug_flags(self, level):
 15.2838 ++		if level == 0:
 15.2839 ++			return ([], ['NDEBUG'])
 15.2840 ++		elif level == 1:
 15.2841 ++			return (['/ZI', '/RTC1'], [])
 15.2842 ++		elif level >= 2:
 15.2843 ++			return (['/ZI', '/RTC1'], ['_DEBUG'])
 15.2844 ++
 15.2845 ++
 15.2846 ++
 15.2847 ++gcc = GccTraits()
 15.2848 ++icc = IccTraits()
 15.2849 ++msvc = MsvcTraits()
 15.2850 ++
 15.2851 ++# how to map env['COMPILER_CC'] or env['COMPILER_CXX'] into a traits object
 15.2852 ++compiler_mapping = {
 15.2853 ++	'gcc': gcc,
 15.2854 ++	'g++': gcc,
 15.2855 ++	'msvc': msvc,
 15.2856 ++	'icc': icc,
 15.2857 ++	'icpc': icc,
 15.2858 ++}
 15.2859 ++
 15.2860 ++profiles = {
 15.2861 ++	# profile name: [optimization_level, warnings_level, debug_level]
 15.2862 ++	'default': [2, 1, 1],
 15.2863 ++	'debug': [0, 2, 3],
 15.2864 ++	'release': [3, 1, 0],
 15.2865 ++	}
 15.2866 ++
 15.2867 ++default_profile = 'default'
 15.2868 ++
 15.2869 ++def options(opt):
 15.2870 ++	assert default_profile in profiles
 15.2871 ++	opt.add_option('-d', '--build-profile',
 15.2872 ++		       action='store',
 15.2873 ++		       default=default_profile,
 15.2874 ++		       help=("Specify the build profile.  "
 15.2875 ++			     "Build profiles control the default compilation flags"
 15.2876 ++			     " used for C/C++ programs, if CCFLAGS/CXXFLAGS are not"
 15.2877 ++			     " set set in the environment. [Allowed Values: %s]"
 15.2878 ++			     % ", ".join([repr(p) for p in profiles.keys()])),
 15.2879 ++		       choices=profiles.keys(),
 15.2880 ++		       dest='build_profile')
 15.2881 ++
 15.2882 ++def configure(conf):
 15.2883 ++	cc = conf.env['COMPILER_CC'] or None
 15.2884 ++	cxx = conf.env['COMPILER_CXX'] or None
 15.2885 ++	if not (cc or cxx):
 15.2886 ++		raise Utils.WafError("neither COMPILER_CC nor COMPILER_CXX are defined; "
 15.2887 ++				     "maybe the compiler_cc or compiler_cxx tool has not been configured yet?")
 15.2888 ++	
 15.2889 ++	try:
 15.2890 ++		compiler = compiler_mapping[cc]
 15.2891 ++	except KeyError:
 15.2892 ++		try:
 15.2893 ++			compiler = compiler_mapping[cxx]
 15.2894 ++		except KeyError:
 15.2895 ++			Logs.warn("No compiler flags support for compiler %r or %r"
 15.2896 ++				  % (cc, cxx))
 15.2897 ++			return
 15.2898 ++
 15.2899 ++	opt_level, warn_level, dbg_level = profiles[Options.options.build_profile]
 15.2900 ++
 15.2901 ++	optimizations = compiler.get_optimization_flags(opt_level)
 15.2902 ++	debug, debug_defs = compiler.get_debug_flags(dbg_level)
 15.2903 ++	warnings = compiler.get_warnings_flags(warn_level)
 15.2904 ++	
 15.2905 ++	if cc and not conf.env['CCFLAGS']:
 15.2906 ++		conf.env.append_value('CCFLAGS', optimizations)
 15.2907 ++		conf.env.append_value('CCFLAGS', debug)
 15.2908 ++		conf.env.append_value('CCFLAGS', warnings)
 15.2909 ++		conf.env.append_value('CCDEFINES', debug_defs)
 15.2910 ++	if cxx and not conf.env['CXXFLAGS']:
 15.2911 ++		conf.env.append_value('CXXFLAGS', optimizations)
 15.2912 ++		conf.env.append_value('CXXFLAGS', debug)
 15.2913 ++		conf.env.append_value('CXXFLAGS', warnings)
 15.2914 ++		conf.env.append_value('CXXDEFINES', debug_defs)
 15.2915 +diff --git a/waf-tools/command.py b/waf-tools/command.py
 15.2916 +new file mode 100644
 15.2917 +--- /dev/null
 15.2918 ++++ b/waf-tools/command.py
 15.2919 +@@ -0,0 +1,134 @@
 15.2920 ++import TaskGen# import feature, taskgen_method, before_method, task_gen
 15.2921 ++import Node, Task, Utils, Build
 15.2922 ++import subprocess
 15.2923 ++import Options
 15.2924 ++
 15.2925 ++import shellcmd
 15.2926 ++#shellcmd.subprocess = pproc # the WAF version of the subprocess module is supposedly less buggy
 15.2927 ++
 15.2928 ++from Logs import debug, error
 15.2929 ++shellcmd.debug = debug
 15.2930 ++
 15.2931 ++import Task
 15.2932 ++
 15.2933 ++import re
 15.2934 ++
 15.2935 ++
 15.2936 ++arg_rx = re.compile(r"(?P<dollar>\$\$)|(?P<subst>\$\{(?P<var>\w+)(?P<code>.*?)\})", re.M)
 15.2937 ++
 15.2938 ++class command_task(Task.Task):
 15.2939 ++	color = "BLUE"
 15.2940 ++	def __init__(self, env, generator):
 15.2941 ++		Task.Task.__init__(self, env=env, normal=1, generator=generator)
 15.2942 ++
 15.2943 ++	def __str__(self):
 15.2944 ++		"string to display to the user"
 15.2945 ++		env = self.env
 15.2946 ++		src_str = ' '.join([a.nice_path(env) for a in self.inputs])
 15.2947 ++		tgt_str = ' '.join([a.nice_path(env) for a in self.outputs])
 15.2948 ++		if self.outputs:
 15.2949 ++			sep = ' -> '
 15.2950 ++		else:
 15.2951 ++			sep = ''
 15.2952 ++
 15.2953 ++		pipeline = shellcmd.Pipeline()
 15.2954 ++		pipeline.parse(self.generator.command)
 15.2955 ++		cmd = pipeline.get_abbreviated_command()
 15.2956 ++		return 'command (%s): %s%s%s\n' % (cmd, src_str, sep, tgt_str)
 15.2957 ++
 15.2958 ++	def _subst_arg(self, arg, direction, namespace):
 15.2959 ++		"""
 15.2960 ++		@param arg: the command argument (or stdin/stdout/stderr) to substitute
 15.2961 ++		@param direction: direction of the argument: 'in', 'out', or None
 15.2962 ++		"""
 15.2963 ++		def repl(match):
 15.2964 ++			if match.group('dollar'):
 15.2965 ++				return "$"
 15.2966 ++			elif match.group('subst'):
 15.2967 ++				var = match.group('var')
 15.2968 ++				code = match.group('code')
 15.2969 ++				result = eval(var+code, namespace)
 15.2970 ++				if isinstance(result, Node.Node):
 15.2971 ++					if var == 'TGT':
 15.2972 ++						return result.get_bld().abspath()
 15.2973 ++					elif var == 'SRC':
 15.2974 ++						return result.srcpath()
 15.2975 ++					else:
 15.2976 ++						raise ValueError("Bad subst variable %r" % var)
 15.2977 ++				elif result is self.inputs:
 15.2978 ++					if len(self.inputs) == 1:
 15.2979 ++						return result[0].srcpath()
 15.2980 ++					else:
 15.2981 ++						raise ValueError("${SRC} requested but have multiple sources; which one?")
 15.2982 ++				elif result is self.outputs:
 15.2983 ++					if len(self.outputs) == 1:
 15.2984 ++						return result[0].get_bld().abspath()
 15.2985 ++					else:
 15.2986 ++						raise ValueError("${TGT} requested but have multiple targets; which one?")
 15.2987 ++				elif isinstance(result, list):
 15.2988 ++					assert len(result) == 1
 15.2989 ++					return result[0]
 15.2990 ++				else:
 15.2991 ++					return result
 15.2992 ++			return None
 15.2993 ++
 15.2994 ++		return arg_rx.sub(repl, arg)
 15.2995 ++
 15.2996 ++	def run(self):
 15.2997 ++		pipeline = shellcmd.Pipeline()
 15.2998 ++		pipeline.parse(self.generator.command)
 15.2999 ++		namespace = self.env.get_merged_dict()
 15.3000 ++		if self.generator.variables is not None:
 15.3001 ++			namespace.update(self.generator.variables)
 15.3002 ++		namespace.update(env=self.env, SRC=self.inputs, TGT=self.outputs)
 15.3003 ++		for cmd in pipeline.pipeline:
 15.3004 ++			if isinstance(cmd, shellcmd.Command):
 15.3005 ++				if isinstance(cmd.stdin, basestring):
 15.3006 ++					cmd.stdin = self._subst_arg(cmd.stdin, 'in', namespace)
 15.3007 ++				if isinstance(cmd.stdout, basestring):
 15.3008 ++					cmd.stdout = self._subst_arg(cmd.stdout, 'out', namespace)
 15.3009 ++				if isinstance(cmd.stderr, basestring):
 15.3010 ++					cmd.stderr = self._subst_arg(cmd.stderr, 'out', namespace)
 15.3011 ++				for argI in xrange(len(cmd.argv)):
 15.3012 ++					cmd.argv[argI] = self._subst_arg(cmd.argv[argI], None, namespace)
 15.3013 ++				if cmd.env_vars is not None:
 15.3014 ++					env_vars = dict()
 15.3015 ++					for name, value in cmd.env_vars.iteritems():
 15.3016 ++						env_vars[name] = self._subst_arg(value, None, namespace)
 15.3017 ++					cmd.env_vars = env_vars
 15.3018 ++			elif isinstance(cmd, shellcmd.Chdir):
 15.3019 ++				cmd.dir = self._subst_arg(cmd.dir, None, namespace)
 15.3020 ++		return pipeline.run(verbose=(Options.options.verbose > 0))
 15.3021 ++
 15.3022 ++@TaskGen.taskgen_method
 15.3023 ++@TaskGen.feature('command')
 15.3024 ++def init_command(self):
 15.3025 ++	Utils.def_attrs(self,
 15.3026 ++					# other variables that can be used in the command: ${VARIABLE}
 15.3027 ++					variables = None,
 15.3028 ++					rule='')
 15.3029 ++
 15.3030 ++
 15.3031 ++
 15.3032 ++@TaskGen.feature('command')
 15.3033 ++@TaskGen.after_method('process_rule')
 15.3034 ++def apply_command(self):
 15.3035 ++	#self.meths.remove('apply_core')
 15.3036 ++	# create the task
 15.3037 ++	task = self.create_task('command')
 15.3038 ++	setattr(task, "dep_vars", getattr(self, "dep_vars", None))
 15.3039 ++	# process the sources
 15.3040 ++	inputs = []
 15.3041 ++	for node in self.source:
 15.3042 ++		inputs.append(node)
 15.3043 ++	task.set_inputs(inputs)
 15.3044 ++	task.set_outputs([self.path.find_or_declare(tgt) for tgt in self.to_list(self.target)])
 15.3045 ++	self.source = ''
 15.3046 ++	#Task.file_deps = Task.extract_deps
 15.3047 ++
 15.3048 ++
 15.3049 ++
 15.3050 ++# class command_taskgen(task_gen):
 15.3051 ++# 	def __init__(self, *k, **kw):
 15.3052 ++# 		task_gen.__init__(self, *k, **kw)
 15.3053 ++# 		self.features.append('command')
 15.3054 +diff --git a/waf-tools/misc.py b/waf-tools/misc.py
 15.3055 +new file mode 100644
 15.3056 +--- /dev/null
 15.3057 ++++ b/waf-tools/misc.py
 15.3058 +@@ -0,0 +1,416 @@
 15.3059 ++#!/usr/bin/env python
 15.3060 ++# encoding: utf-8
 15.3061 ++# Thomas Nagy, 2006-2010 (ita)
 15.3062 ++
 15.3063 ++"""
 15.3064 ++This tool is totally deprecated
 15.3065 ++
 15.3066 ++Try using:
 15.3067 ++	.pc.in files for .pc files
 15.3068 ++	the feature intltool_in - see demos/intltool
 15.3069 ++	make-like rules
 15.3070 ++"""
 15.3071 ++
 15.3072 ++import shutil, re, os
 15.3073 ++from waflib import TaskGen, Node, Task, Utils, Build, Errors
 15.3074 ++from waflib.TaskGen import feature, after_method, before_method
 15.3075 ++from waflib.Logs import debug
 15.3076 ++
 15.3077 ++def copy_attrs(orig, dest, names, only_if_set=False):
 15.3078 ++	"""
 15.3079 ++	copy class attributes from an object to another
 15.3080 ++	"""
 15.3081 ++	for a in Utils.to_list(names):
 15.3082 ++		u = getattr(orig, a, ())
 15.3083 ++		if u or not only_if_set:
 15.3084 ++			setattr(dest, a, u)
 15.3085 ++
 15.3086 ++def copy_func(tsk):
 15.3087 ++	"Make a file copy. This might be used to make other kinds of file processing (even calling a compiler is possible)"
 15.3088 ++	env = tsk.env
 15.3089 ++	infile = tsk.inputs[0].abspath()
 15.3090 ++	outfile = tsk.outputs[0].abspath()
 15.3091 ++	try:
 15.3092 ++		shutil.copy2(infile, outfile)
 15.3093 ++	except (OSError, IOError):
 15.3094 ++		return 1
 15.3095 ++	else:
 15.3096 ++		if tsk.chmod: os.chmod(outfile, tsk.chmod)
 15.3097 ++		return 0
 15.3098 ++
 15.3099 ++def action_process_file_func(tsk):
 15.3100 ++	"Ask the function attached to the task to process it"
 15.3101 ++	if not tsk.fun: raise Errors.WafError('task must have a function attached to it for copy_func to work!')
 15.3102 ++	return tsk.fun(tsk)
 15.3103 ++
 15.3104 ++@feature('cmd')
 15.3105 ++def apply_cmd(self):
 15.3106 ++	"call a command everytime"
 15.3107 ++	if not self.fun: raise Errors.WafError('cmdobj needs a function!')
 15.3108 ++	tsk = Task.TaskBase()
 15.3109 ++	tsk.fun = self.fun
 15.3110 ++	tsk.env = self.env
 15.3111 ++	self.tasks.append(tsk)
 15.3112 ++	tsk.install_path = self.install_path
 15.3113 ++
 15.3114 ++@feature('copy')
 15.3115 ++@before_method('process_source')
 15.3116 ++def apply_copy(self):
 15.3117 ++	Utils.def_attrs(self, fun=copy_func)
 15.3118 ++	self.default_install_path = 0
 15.3119 ++
 15.3120 ++	lst = self.to_list(self.source)
 15.3121 ++	self.meths.remove('process_source')
 15.3122 ++
 15.3123 ++	for filename in lst:
 15.3124 ++		node = self.path.find_resource(filename)
 15.3125 ++		if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
 15.3126 ++
 15.3127 ++		target = self.target
 15.3128 ++		if not target or len(lst)>1: target = node.name
 15.3129 ++
 15.3130 ++		# TODO the file path may be incorrect
 15.3131 ++		newnode = self.path.find_or_declare(target)
 15.3132 ++
 15.3133 ++		tsk = self.create_task('copy', node, newnode)
 15.3134 ++		tsk.fun = self.fun
 15.3135 ++		tsk.chmod = getattr(self, 'chmod', Utils.O644)
 15.3136 ++
 15.3137 ++		if not tsk.env:
 15.3138 ++			tsk.debug()
 15.3139 ++			raise Errors.WafError('task without an environment')
 15.3140 ++
 15.3141 ++def subst_func(tsk):
 15.3142 ++	"Substitutes variables in a .in file"
 15.3143 ++
 15.3144 ++	m4_re = re.compile('@(\w+)@', re.M)
 15.3145 ++
 15.3146 ++	code = tsk.inputs[0].read() #Utils.readf(infile)
 15.3147 ++
 15.3148 ++	# replace all % by %% to prevent errors by % signs in the input file while string formatting
 15.3149 ++	code = code.replace('%', '%%')
 15.3150 ++
 15.3151 ++	s = m4_re.sub(r'%(\1)s', code)
 15.3152 ++
 15.3153 ++	env = tsk.env
 15.3154 ++	di = getattr(tsk, 'dict', {}) or getattr(tsk.generator, 'dict', {})
 15.3155 ++	if not di:
 15.3156 ++		names = m4_re.findall(code)
 15.3157 ++		for i in names:
 15.3158 ++			di[i] = env.get_flat(i) or env.get_flat(i.upper())
 15.3159 ++
 15.3160 ++	tsk.outputs[0].write(s % di)
 15.3161 ++
 15.3162 ++@feature('subst')
 15.3163 ++@before_method('process_source')
 15.3164 ++def apply_subst(self):
 15.3165 ++	Utils.def_attrs(self, fun=subst_func)
 15.3166 ++	lst = self.to_list(self.source)
 15.3167 ++	self.meths.remove('process_source')
 15.3168 ++
 15.3169 ++	self.dict = getattr(self, 'dict', {})
 15.3170 ++
 15.3171 ++	for filename in lst:
 15.3172 ++		node = self.path.find_resource(filename)
 15.3173 ++		if not node: raise Errors.WafError('cannot find input file %s for processing' % filename)
 15.3174 ++
 15.3175 ++		if self.target:
 15.3176 ++			newnode = self.path.find_or_declare(self.target)
 15.3177 ++		else:
 15.3178 ++			newnode = node.change_ext('')
 15.3179 ++
 15.3180 ++		try:
 15.3181 ++			self.dict = self.dict.get_merged_dict()
 15.3182 ++		except AttributeError:
 15.3183 ++			pass
 15.3184 ++
 15.3185 ++		if self.dict and not self.env['DICT_HASH']:
 15.3186 ++			self.env = self.env.derive()
 15.3187 ++			keys = list(self.dict.keys())
 15.3188 ++			keys.sort()
 15.3189 ++			lst = [self.dict[x] for x in keys]
 15.3190 ++			self.env['DICT_HASH'] = str(Utils.h_list(lst))
 15.3191 ++
 15.3192 ++		tsk = self.create_task('copy', node, newnode)
 15.3193 ++		tsk.fun = self.fun
 15.3194 ++		tsk.dict = self.dict
 15.3195 ++		tsk.dep_vars = ['DICT_HASH']
 15.3196 ++		tsk.chmod = getattr(self, 'chmod', Utils.O644)
 15.3197 ++
 15.3198 ++		if not tsk.env:
 15.3199 ++			tsk.debug()
 15.3200 ++			raise Errors.WafError('task without an environment')
 15.3201 ++
 15.3202 ++####################
 15.3203 ++## command-output ####
 15.3204 ++####################
 15.3205 ++
 15.3206 ++class cmd_arg(object):
 15.3207 ++	"""command-output arguments for representing files or folders"""
 15.3208 ++	def __init__(self, name, template='%s'):
 15.3209 ++		self.name = name
 15.3210 ++		self.template = template
 15.3211 ++		self.node = None
 15.3212 ++
 15.3213 ++class input_file(cmd_arg):
 15.3214 ++	def find_node(self, base_path):
 15.3215 ++		assert isinstance(base_path, Node.Node)
 15.3216 ++		self.node = base_path.find_resource(self.name)
 15.3217 ++		if self.node is None:
 15.3218 ++			raise Errors.WafError("Input file %s not found in " % (self.name, base_path))
 15.3219 ++
 15.3220 ++	def get_path(self, env, absolute):
 15.3221 ++		if absolute:
 15.3222 ++			return self.template % self.node.abspath()
 15.3223 ++		else:
 15.3224 ++			return self.template % self.node.srcpath()
 15.3225 ++
 15.3226 ++class output_file(cmd_arg):
 15.3227 ++	def find_node(self, base_path):
 15.3228 ++		assert isinstance(base_path, Node.Node)
 15.3229 ++		self.node = base_path.find_or_declare(self.name)
 15.3230 ++		if self.node is None:
 15.3231 ++			raise Errors.WafError("Output file %s not found in " % (self.name, base_path))
 15.3232 ++
 15.3233 ++	def get_path(self, env, absolute):
 15.3234 ++		if absolute:
 15.3235 ++			return self.template % self.node.abspath()
 15.3236 ++		else:
 15.3237 ++			return self.template % self.node.bldpath()
 15.3238 ++
 15.3239 ++class cmd_dir_arg(cmd_arg):
 15.3240 ++	def find_node(self, base_path):
 15.3241 ++		assert isinstance(base_path, Node.Node)
 15.3242 ++		self.node = base_path.find_dir(self.name)
 15.3243 ++		if self.node is None:
 15.3244 ++			raise Errors.WafError("Directory %s not found in " % (self.name, base_path))
 15.3245 ++
 15.3246 ++class input_dir(cmd_dir_arg):
 15.3247 ++	def get_path(self, dummy_env, dummy_absolute):
 15.3248 ++		return self.template % self.node.abspath()
 15.3249 ++
 15.3250 ++class output_dir(cmd_dir_arg):
 15.3251 ++	def get_path(self, env, dummy_absolute):
 15.3252 ++		return self.template % self.node.abspath()
 15.3253 ++
 15.3254 ++
 15.3255 ++class command_output(Task.Task):
 15.3256 ++	color = "BLUE"
 15.3257 ++	def __init__(self, env, command, command_node, command_args, stdin, stdout, cwd, os_env, stderr):
 15.3258 ++		Task.Task.__init__(self, env=env)
 15.3259 ++		assert isinstance(command, (str, Node.Node))
 15.3260 ++		self.command = command
 15.3261 ++		self.command_args = command_args
 15.3262 ++		self.stdin = stdin
 15.3263 ++		self.stdout = stdout
 15.3264 ++		self.cwd = cwd
 15.3265 ++		self.os_env = os_env
 15.3266 ++		self.stderr = stderr
 15.3267 ++
 15.3268 ++		if command_node is not None: self.dep_nodes = [command_node]
 15.3269 ++		self.dep_vars = [] # additional environment variables to look
 15.3270 ++
 15.3271 ++	def run(self):
 15.3272 ++		task = self
 15.3273 ++		#assert len(task.inputs) > 0
 15.3274 ++
 15.3275 ++		def input_path(node, template):
 15.3276 ++			if task.cwd is None:
 15.3277 ++				return template % node.bldpath()
 15.3278 ++			else:
 15.3279 ++				return template % node.abspath()
 15.3280 ++		def output_path(node, template):
 15.3281 ++			fun = node.abspath
 15.3282 ++			if task.cwd is None: fun = node.bldpath
 15.3283 ++			return template % fun()
 15.3284 ++
 15.3285 ++		if isinstance(task.command, Node.Node):
 15.3286 ++			argv = [input_path(task.command, '%s')]
 15.3287 ++		else:
 15.3288 ++			argv = [task.command]
 15.3289 ++
 15.3290 ++		for arg in task.command_args:
 15.3291 ++			if isinstance(arg, str):
 15.3292 ++				argv.append(arg)
 15.3293 ++			else:
 15.3294 ++				assert isinstance(arg, cmd_arg)
 15.3295 ++				argv.append(arg.get_path(task.env, (task.cwd is not None)))
 15.3296 ++
 15.3297 ++		if task.stdin:
 15.3298 ++			stdin = open(input_path(task.stdin, '%s'))
 15.3299 ++		else:
 15.3300 ++			stdin = None
 15.3301 ++
 15.3302 ++		if task.stdout:
 15.3303 ++			stdout = open(output_path(task.stdout, '%s'), "w")
 15.3304 ++		else:
 15.3305 ++			stdout = None
 15.3306 ++
 15.3307 ++		if task.stderr:
 15.3308 ++			stderr = open(output_path(task.stderr, '%s'), "w")
 15.3309 ++		else:
 15.3310 ++			stderr = None
 15.3311 ++
 15.3312 ++		if task.cwd is None:
 15.3313 ++			cwd = ('None (actually %r)' % os.getcwd())
 15.3314 ++		else:
 15.3315 ++			cwd = repr(task.cwd)
 15.3316 ++		debug("command-output: cwd=%s, stdin=%r, stdout=%r, argv=%r" %
 15.3317 ++			     (cwd, stdin, stdout, argv))
 15.3318 ++
 15.3319 ++		if task.os_env is None:
 15.3320 ++			os_env = os.environ
 15.3321 ++		else:
 15.3322 ++			os_env = task.os_env
 15.3323 ++		command = Utils.subprocess.Popen(argv, stdin=stdin, stdout=stdout, stderr=stderr, cwd=task.cwd, env=os_env)
 15.3324 ++		return command.wait()
 15.3325 ++
 15.3326 ++@feature('command-output')
 15.3327 ++def init_cmd_output(self):
 15.3328 ++	Utils.def_attrs(self,
 15.3329 ++		stdin = None,
 15.3330 ++		stdout = None,
 15.3331 ++		stderr = None,
 15.3332 ++		# the command to execute
 15.3333 ++		command = None,
 15.3334 ++
 15.3335 ++		# whether it is an external command; otherwise it is assumed
 15.3336 ++		# to be an executable binary or script that lives in the
 15.3337 ++		# source or build tree.
 15.3338 ++		command_is_external = False,
 15.3339 ++
 15.3340 ++		# extra parameters (argv) to pass to the command (excluding
 15.3341 ++		# the command itself)
 15.3342 ++		argv = [],
 15.3343 ++
 15.3344 ++		# dependencies to other objects -> this is probably not what you want (ita)
 15.3345 ++		# values must be 'task_gen' instances (not names!)
 15.3346 ++		dependencies = [],
 15.3347 ++
 15.3348 ++		# dependencies on env variable contents
 15.3349 ++		dep_vars = [],
 15.3350 ++
 15.3351 ++		# input files that are implicit, i.e. they are not
 15.3352 ++		# stdin, nor are they mentioned explicitly in argv
 15.3353 ++		hidden_inputs = [],
 15.3354 ++
 15.3355 ++		# output files that are implicit, i.e. they are not
 15.3356 ++		# stdout, nor are they mentioned explicitly in argv
 15.3357 ++		hidden_outputs = [],
 15.3358 ++
 15.3359 ++		# change the subprocess to this cwd (must use obj.input_dir() or output_dir() here)
 15.3360 ++		cwd = None,
 15.3361 ++
 15.3362 ++		# OS environment variables to pass to the subprocess
 15.3363 ++		# if None, use the default environment variables unchanged
 15.3364 ++		os_env = None)
 15.3365 ++
 15.3366 ++@feature('command-output')
 15.3367 ++@after_method('init_cmd_output')
 15.3368 ++def apply_cmd_output(self):
 15.3369 ++	if self.command is None:
 15.3370 ++		raise Errors.WafError("command-output missing command")
 15.3371 ++	if self.command_is_external:
 15.3372 ++		cmd = self.command
 15.3373 ++		cmd_node = None
 15.3374 ++	else:
 15.3375 ++		cmd_node = self.path.find_resource(self.command)
 15.3376 ++		assert cmd_node is not None, ('''Could not find command '%s' in source tree.
 15.3377 ++Hint: if this is an external command,
 15.3378 ++use command_is_external=True''') % (self.command,)
 15.3379 ++		cmd = cmd_node
 15.3380 ++
 15.3381 ++	if self.cwd is None:
 15.3382 ++		cwd = None
 15.3383 ++	else:
 15.3384 ++		assert isinstance(cwd, CmdDirArg)
 15.3385 ++		self.cwd.find_node(self.path)
 15.3386 ++
 15.3387 ++	args = []
 15.3388 ++	inputs = []
 15.3389 ++	outputs = []
 15.3390 ++
 15.3391 ++	for arg in self.argv:
 15.3392 ++		if isinstance(arg, cmd_arg):
 15.3393 ++			arg.find_node(self.path)
 15.3394 ++			if isinstance(arg, input_file):
 15.3395 ++				inputs.append(arg.node)
 15.3396 ++			if isinstance(arg, output_file):
 15.3397 ++				outputs.append(arg.node)
 15.3398 ++
 15.3399 ++	if self.stdout is None:
 15.3400 ++		stdout = None
 15.3401 ++	else:
 15.3402 ++		assert isinstance(self.stdout, str)
 15.3403 ++		stdout = self.path.find_or_declare(self.stdout)
 15.3404 ++		if stdout is None:
 15.3405 ++			raise Errors.WafError("File %s not found" % (self.stdout,))
 15.3406 ++		outputs.append(stdout)
 15.3407 ++
 15.3408 ++	if self.stderr is None:
 15.3409 ++		stderr = None
 15.3410 ++	else:
 15.3411 ++		assert isinstance(self.stderr, str)
 15.3412 ++		stderr = self.path.find_or_declare(self.stderr)
 15.3413 ++		if stderr is None:
 15.3414 ++			raise Errors.WafError("File %s not found" % (self.stderr,))
 15.3415 ++		outputs.append(stderr)
 15.3416 ++
 15.3417 ++	if self.stdin is None:
 15.3418 ++		stdin = None
 15.3419 ++	else:
 15.3420 ++		assert isinstance(self.stdin, str)
 15.3421 ++		stdin = self.path.find_resource(self.stdin)
 15.3422 ++		if stdin is None:
 15.3423 ++			raise Errors.WafError("File %s not found" % (self.stdin,))
 15.3424 ++		inputs.append(stdin)
 15.3425 ++
 15.3426 ++	for hidden_input in self.to_list(self.hidden_inputs):
 15.3427 ++		node = self.path.find_resource(hidden_input)
 15.3428 ++		if node is None:
 15.3429 ++			raise Errors.WafError("File %s not found in dir %s" % (hidden_input, self.path))
 15.3430 ++		inputs.append(node)
 15.3431 ++
 15.3432 ++	for hidden_output in self.to_list(self.hidden_outputs):
 15.3433 ++		node = self.path.find_or_declare(hidden_output)
 15.3434 ++		if node is None:
 15.3435 ++			raise Errors.WafError("File %s not found in dir %s" % (hidden_output, self.path))
 15.3436 ++		outputs.append(node)
 15.3437 ++
 15.3438 ++	if not (inputs or getattr(self, 'no_inputs', None)):
 15.3439 ++		raise Errors.WafError('command-output objects must have at least one input file or give self.no_inputs')
 15.3440 ++	if not (outputs or getattr(self, 'no_outputs', None)):
 15.3441 ++		raise Errors.WafError('command-output objects must have at least one output file or give self.no_outputs')
 15.3442 ++
 15.3443 ++	cwd = self.bld.variant_dir
 15.3444 ++	task = command_output(self.env, cmd, cmd_node, self.argv, stdin, stdout, cwd, self.os_env, stderr)
 15.3445 ++	task.generator = self
 15.3446 ++	copy_attrs(self, task, 'before after ext_in ext_out', only_if_set=True)
 15.3447 ++	self.tasks.append(task)
 15.3448 ++
 15.3449 ++	task.inputs = inputs
 15.3450 ++	task.outputs = outputs
 15.3451 ++	task.dep_vars = self.to_list(self.dep_vars)
 15.3452 ++
 15.3453 ++	for dep in self.dependencies:
 15.3454 ++		assert dep is not self
 15.3455 ++		dep.post()
 15.3456 ++		for dep_task in dep.tasks:
 15.3457 ++			task.set_run_after(dep_task)
 15.3458 ++
 15.3459 ++	if not task.inputs:
 15.3460 ++		# the case for svnversion, always run, and update the output nodes
 15.3461 ++		task.runnable_status = type(Task.TaskBase.run)(runnable_status, task, task.__class__) # always run
 15.3462 ++		task.post_run = type(Task.TaskBase.run)(post_run, task, task.__class__)
 15.3463 ++
 15.3464 ++	# TODO the case with no outputs?
 15.3465 ++
 15.3466 ++def post_run(self):
 15.3467 ++	for x in self.outputs:
 15.3468 ++		x.sig = Utils.h_file(x.abspath())
 15.3469 ++
 15.3470 ++def runnable_status(self):
 15.3471 ++	return self.RUN_ME
 15.3472 ++
 15.3473 ++Task.task_factory('copy', vars=[], func=action_process_file_func)
 15.3474 ++
 15.3475 +diff --git a/waf-tools/pkgconfig.py b/waf-tools/pkgconfig.py
 15.3476 +new file mode 100644
 15.3477 +--- /dev/null
 15.3478 ++++ b/waf-tools/pkgconfig.py
 15.3479 +@@ -0,0 +1,78 @@
 15.3480 ++# -*- mode: python; encoding: utf-8 -*-
 15.3481 ++# Gustavo Carneiro (gjamc) 2008
 15.3482 ++
 15.3483 ++import Options
 15.3484 ++import Configure
 15.3485 ++import subprocess
 15.3486 ++import config_c
 15.3487 ++import sys
 15.3488 ++
 15.3489 ++def configure(conf):
 15.3490 ++	pkg_config = conf.find_program('pkg-config', var='PKG_CONFIG')
 15.3491 ++	if not pkg_config: return
 15.3492 ++
 15.3493 ++@Configure.conf
 15.3494 ++def pkg_check_modules(conf, uselib_name, expression, mandatory=True):
 15.3495 ++	pkg_config = conf.env['PKG_CONFIG']
 15.3496 ++	if not pkg_config:
 15.3497 ++		if mandatory:
 15.3498 ++			conf.fatal("pkg-config is not available")
 15.3499 ++		else:
 15.3500 ++			return False
 15.3501 ++
 15.3502 ++	if Options.options.verbose:
 15.3503 ++		extra_msg = ' (%s)' % expression
 15.3504 ++	else:
 15.3505 ++		extra_msg = ''
 15.3506 ++
 15.3507 ++	conf.start_msg('Checking for pkg-config flags for %s%s' % (uselib_name, extra_msg))
 15.3508 ++
 15.3509 ++	argv = [pkg_config, '--cflags', '--libs', expression]
 15.3510 ++	cmd = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 15.3511 ++	out, err = cmd.communicate()
 15.3512 ++	retval = cmd.wait()
 15.3513 ++
 15.3514 ++	conf.to_log('%r: %r (exit code %i)\n%s' % (argv, out, retval, err))
 15.3515 ++
 15.3516 ++	if retval != 0:
 15.3517 ++		conf.end_msg(False)
 15.3518 ++		sys.stderr.write(err)
 15.3519 ++	else:
 15.3520 ++		if Options.options.verbose:
 15.3521 ++			conf.end_msg(out)
 15.3522 ++		else:
 15.3523 ++			conf.end_msg(True)
 15.3524 ++
 15.3525 ++	if retval == 0:
 15.3526 ++		conf.parse_flags(out, uselib_name, conf.env)
 15.3527 ++		conf.env[uselib_name] = True
 15.3528 ++		return True
 15.3529 ++
 15.3530 ++	else:
 15.3531 ++
 15.3532 ++		conf.env[uselib_name] = False
 15.3533 ++		if mandatory:
 15.3534 ++			raise Configure.ConfigurationError('pkg-config check failed')
 15.3535 ++		else:
 15.3536 ++			return False
 15.3537 ++
 15.3538 ++@Configure.conf
 15.3539 ++def pkg_check_module_variable(conf, module, variable):
 15.3540 ++	pkg_config = conf.env['PKG_CONFIG']
 15.3541 ++	if not pkg_config:
 15.3542 ++		conf.fatal("pkg-config is not available")
 15.3543 ++
 15.3544 ++	argv = [pkg_config, '--variable', variable, module]
 15.3545 ++	cmd = subprocess.Popen(argv, stdout=subprocess.PIPE)
 15.3546 ++	out, dummy = cmd.communicate()
 15.3547 ++	retval = cmd.wait()
 15.3548 ++	out = out.rstrip() # strip the trailing newline
 15.3549 ++
 15.3550 ++	msg_checking = ("Checking for pkg-config variable %r in %s" % (variable, module,))
 15.3551 ++	conf.check_message_custom(msg_checking, '', out)
 15.3552 ++	conf.log.write('%r: %r (exit code %i)\n' % (argv, out, retval))
 15.3553 ++
 15.3554 ++	if retval == 0:
 15.3555 ++		return out
 15.3556 ++	else:
 15.3557 ++		raise Configure.ConfigurationError('pkg-config check failed')
 15.3558 +diff --git a/waf-tools/relocation.py b/waf-tools/relocation.py
 15.3559 +new file mode 100644
 15.3560 +--- /dev/null
 15.3561 ++++ b/waf-tools/relocation.py
 15.3562 +@@ -0,0 +1,85 @@
 15.3563 ++#! /usr/bin/env python
 15.3564 ++# encoding: utf-8
 15.3565 ++
 15.3566 ++"""
 15.3567 ++Waf 1.6
 15.3568 ++
 15.3569 ++Try to detect if the project directory was relocated, and if it was,
 15.3570 ++change the node representing the project directory. Just call:
 15.3571 ++
 15.3572 ++ waf configure build
 15.3573 ++
 15.3574 ++Note that if the project directory name changes, the signatures for the tasks using
 15.3575 ++files in that directory will change, causing a partial build.
 15.3576 ++"""
 15.3577 ++
 15.3578 ++import os
 15.3579 ++from waflib import Build, ConfigSet, Task, Utils, Errors
 15.3580 ++from waflib.TaskGen import feature, before_method, after_method
 15.3581 ++
 15.3582 ++EXTRA_LOCK = '.old_srcdir'
 15.3583 ++
 15.3584 ++old1 = Build.BuildContext.store
 15.3585 ++def store(self):
 15.3586 ++	old1(self)
 15.3587 ++	db = os.path.join(self.variant_dir, EXTRA_LOCK)
 15.3588 ++	env = ConfigSet.ConfigSet()
 15.3589 ++	env.SRCDIR = self.srcnode.abspath()
 15.3590 ++	env.store(db)
 15.3591 ++Build.BuildContext.store = store
 15.3592 ++
 15.3593 ++old2 = Build.BuildContext.init_dirs
 15.3594 ++def init_dirs(self):
 15.3595 ++
 15.3596 ++	if not (os.path.isabs(self.top_dir) and os.path.isabs(self.out_dir)):
 15.3597 ++		raise Errors.WafError('The project was not configured: run "waf configure" first!')
 15.3598 ++
 15.3599 ++	srcdir = None
 15.3600 ++	db = os.path.join(self.variant_dir, EXTRA_LOCK)
 15.3601 ++	env = ConfigSet.ConfigSet()
 15.3602 ++	try:
 15.3603 ++		env.load(db)
 15.3604 ++		srcdir = env.SRCDIR
 15.3605 ++	except:
 15.3606 ++		pass
 15.3607 ++
 15.3608 ++	if srcdir:
 15.3609 ++		d = self.root.find_node(srcdir)
 15.3610 ++		if d and srcdir != self.top_dir and getattr(d, 'children', ''):
 15.3611 ++			srcnode = self.root.make_node(self.top_dir)
 15.3612 ++			print("relocating the source directory %r -> %r" % (srcdir, self.top_dir))
 15.3613 ++			srcnode.children = {}
 15.3614 ++
 15.3615 ++			for (k, v) in d.children.items():
 15.3616 ++				srcnode.children[k] = v
 15.3617 ++				v.parent = srcnode
 15.3618 ++			d.children = {}
 15.3619 ++
 15.3620 ++	old2(self)
 15.3621 ++
 15.3622 ++Build.BuildContext.init_dirs = init_dirs
 15.3623 ++
 15.3624 ++
 15.3625 ++def uid(self):
 15.3626 ++	try:
 15.3627 ++		return self.uid_
 15.3628 ++	except AttributeError:
 15.3629 ++		# this is not a real hot zone, but we want to avoid surprizes here
 15.3630 ++		m = Utils.md5()
 15.3631 ++		up = m.update
 15.3632 ++		up(self.__class__.__name__.encode())
 15.3633 ++		for x in self.inputs + self.outputs:
 15.3634 ++			up(x.path_from(x.ctx.srcnode).encode())
 15.3635 ++		self.uid_ = m.digest()
 15.3636 ++		return self.uid_
 15.3637 ++Task.Task.uid = uid
 15.3638 ++
 15.3639 ++@feature('c', 'cxx', 'd', 'go', 'asm', 'fc', 'includes')
 15.3640 ++@after_method('propagate_uselib_vars', 'process_source')
 15.3641 ++def apply_incpaths(self):
 15.3642 ++	lst = self.to_incnodes(self.to_list(getattr(self, 'includes', [])) + self.env['INCLUDES'])
 15.3643 ++	self.includes_nodes = lst
 15.3644 ++	bld = self.bld
 15.3645 ++	self.env['INCPATHS'] = [x.is_child_of(bld.srcnode) and x.path_from(bld.srcnode) or x.abspath() for x in lst]
 15.3646 ++
 15.3647 ++
 15.3648 +diff --git a/waf-tools/shellcmd.py b/waf-tools/shellcmd.py
 15.3649 +new file mode 100644
 15.3650 +--- /dev/null
 15.3651 ++++ b/waf-tools/shellcmd.py
 15.3652 +@@ -0,0 +1,356 @@
 15.3653 ++# Copyright (C) 2008 Gustavo J. A. M. Carneiro  <gjcarneiro@gmail.com>
 15.3654 ++
 15.3655 ++# This program is free software; you can redistribute it and/or modify
 15.3656 ++# it under the terms of the GNU General Public License as published by
 15.3657 ++# the Free Software Foundation; either version 2 of the License, or
 15.3658 ++# (at your option) any later version.
 15.3659 ++
 15.3660 ++# This program is distributed in the hope that it will be useful,
 15.3661 ++# but WITHOUT ANY WARRANTY; without even the implied warranty of
 15.3662 ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 15.3663 ++# GNU General Public License for more details.
 15.3664 ++
 15.3665 ++# You should have received a copy of the GNU General Public License
 15.3666 ++# along with this program; if not, write to the Free Software
 15.3667 ++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 15.3668 ++
 15.3669 ++import shlex
 15.3670 ++import subprocess
 15.3671 ++import sys
 15.3672 ++import re
 15.3673 ++import os
 15.3674 ++
 15.3675 ++env_var_rx = re.compile(r"^([a-zA-Z0-9_]+)=(\S+)$")
 15.3676 ++
 15.3677 ++def debug(message):
 15.3678 ++    print >> sys.stderr, message
 15.3679 ++
 15.3680 ++
 15.3681 ++if sys.platform == 'win32':
 15.3682 ++    dev_null = open("NUL:", "w")
 15.3683 ++else:
 15.3684 ++    dev_null = open("/dev/null", "w")
 15.3685 ++
 15.3686 ++fcntl = fd = fl = None
 15.3687 ++try:
 15.3688 ++    import fcntl
 15.3689 ++except ImportError:
 15.3690 ++    pass
 15.3691 ++else:
 15.3692 ++    fd = dev_null.fileno()
 15.3693 ++    fl = fcntl.fcntl(fd, fcntl.F_GETFD)
 15.3694 ++    fcntl.fcntl(fd, fcntl.F_SETFD, fl | fcntl.FD_CLOEXEC)
 15.3695 ++del fcntl, fd, fl
 15.3696 ++
 15.3697 ++def _open_out_file(filename):
 15.3698 ++    if filename in ['NUL:', '/dev/null']:
 15.3699 ++        return dev_null
 15.3700 ++    else:
 15.3701 ++        return open(filename, 'wb')
 15.3702 ++
 15.3703 ++
 15.3704 ++class Node(object):
 15.3705 ++    pass
 15.3706 ++
 15.3707 ++class Op(Node):
 15.3708 ++    pass
 15.3709 ++
 15.3710 ++class Pipe(Op):
 15.3711 ++    pass
 15.3712 ++
 15.3713 ++class And(Op):
 15.3714 ++    pass
 15.3715 ++
 15.3716 ++class Or(Op):
 15.3717 ++    pass
 15.3718 ++
 15.3719 ++class Command(Node):
 15.3720 ++    class PIPE(object):
 15.3721 ++        pass # PIPE is a constant
 15.3722 ++    class STDOUT(object):
 15.3723 ++        pass # PIPE is a constant
 15.3724 ++
 15.3725 ++    def __init__(self, name):
 15.3726 ++        super(Command, self).__init__()
 15.3727 ++        self.name = name # command name
 15.3728 ++        self.argv = [name] # command argv
 15.3729 ++        self.stdin = None
 15.3730 ++        self.stdout = None
 15.3731 ++        self.stderr = None
 15.3732 ++        self.env_vars = None
 15.3733 ++
 15.3734 ++    def __repr__(self):
 15.3735 ++        return "Command(%r, argv=%r, stdin=%r, stdout=%r, stderr=%r)" \
 15.3736 ++            % (self.name, self.argv, self.stdin, self.stdout, self.stderr)
 15.3737 ++
 15.3738 ++class Chdir(Node):
 15.3739 ++    def __init__(self):
 15.3740 ++        super(Chdir, self).__init__()
 15.3741 ++        self.dir = None
 15.3742 ++
 15.3743 ++    def __repr__(self):
 15.3744 ++        return "Chdir(%r)" \
 15.3745 ++            % (self.dir)
 15.3746 ++
 15.3747 ++class Pipeline(object):
 15.3748 ++    def __init__(self):
 15.3749 ++        self.current_command = None
 15.3750 ++        self.pipeline = []
 15.3751 ++
 15.3752 ++    def _commit_command(self):
 15.3753 ++        assert self.current_command is not None
 15.3754 ++        self.pipeline.append(self.current_command)
 15.3755 ++        self.current_command = None
 15.3756 ++
 15.3757 ++    def get_abbreviated_command(self):
 15.3758 ++        l = []
 15.3759 ++        for node in self.pipeline:
 15.3760 ++            if isinstance(node, Command):
 15.3761 ++                l.append(node.name)
 15.3762 ++            if isinstance(node, Chdir):
 15.3763 ++                l.append('cd %s' % node.dir)
 15.3764 ++            elif isinstance(node, Pipe):
 15.3765 ++                l.append('|')
 15.3766 ++            elif isinstance(node, And):
 15.3767 ++                l.append('&&')
 15.3768 ++            elif isinstance(node, And):
 15.3769 ++                l.append('||')
 15.3770 ++        return ' '.join(l)
 15.3771 ++
 15.3772 ++    def parse(self, command):
 15.3773 ++        self.current_command = None
 15.3774 ++        self.pipeline = []
 15.3775 ++
 15.3776 ++        if isinstance(command, list):
 15.3777 ++            tokens = list(command)
 15.3778 ++        else:
 15.3779 ++            tokens = shlex.split(command)
 15.3780 ++        debug("command: shlex: %r" % (tokens,))
 15.3781 ++
 15.3782 ++        BEGIN, COMMAND, CHDIR, STDERR, STDOUT, STDIN = range(6)
 15.3783 ++        state = BEGIN
 15.3784 ++        self.current_command = None
 15.3785 ++        env_vars = dict()
 15.3786 ++
 15.3787 ++        while tokens:
 15.3788 ++            token = tokens.pop(0)
 15.3789 ++            if state == BEGIN:
 15.3790 ++                env_var_match = env_var_rx.match(token)
 15.3791 ++                if env_var_match is not None:
 15.3792 ++                    env_vars[env_var_match.group(1)] = env_var_match.group(2)
 15.3793 ++                else:
 15.3794 ++                    assert self.current_command is None
 15.3795 ++                    if token == 'cd':
 15.3796 ++                        self.current_command = Chdir()
 15.3797 ++                        assert not env_vars
 15.3798 ++                        state = CHDIR
 15.3799 ++                    else:
 15.3800 ++                        self.current_command = Command(token)
 15.3801 ++                        if env_vars:
 15.3802 ++                            self.current_command.env_vars = env_vars
 15.3803 ++                            env_vars = dict()
 15.3804 ++                        state = COMMAND
 15.3805 ++            elif state == COMMAND:
 15.3806 ++                if token == '>':
 15.3807 ++                    state = STDOUT
 15.3808 ++                elif token == '2>':
 15.3809 ++                    state = STDERR
 15.3810 ++                elif token == '2>&1':
 15.3811 ++                    assert self.current_command.stderr is None
 15.3812 ++                    self.current_command.stderr = Command.STDOUT
 15.3813 ++                elif token == '<':
 15.3814 ++                    state = STDIN
 15.3815 ++                elif token == '|':
 15.3816 ++                    assert self.current_command.stdout is None
 15.3817 ++                    self.current_command.stdout = Command.PIPE
 15.3818 ++                    self._commit_command()
 15.3819 ++                    self.pipeline.append(Pipe())
 15.3820 ++                    state = BEGIN
 15.3821 ++                elif token == '&&':
 15.3822 ++                    self._commit_command()
 15.3823 ++                    self.pipeline.append(And())
 15.3824 ++                    state = BEGIN
 15.3825 ++                elif token == '||':
 15.3826 ++                    self._commit_command()
 15.3827 ++                    self.pipeline.append(Or())
 15.3828 ++                    state = BEGIN
 15.3829 ++                else:
 15.3830 ++                    self.current_command.argv.append(token)
 15.3831 ++            elif state == CHDIR:
 15.3832 ++                if token == '&&':
 15.3833 ++                    self._commit_command()
 15.3834 ++                    self.pipeline.append(And())
 15.3835 ++                    state = BEGIN
 15.3836 ++                else:
 15.3837 ++                    assert self.current_command.dir is None
 15.3838 ++                    self.current_command.dir = token
 15.3839 ++            elif state == STDOUT:
 15.3840 ++                assert self.current_command.stdout is None
 15.3841 ++                self.current_command.stdout = token
 15.3842 ++                state = COMMAND
 15.3843 ++            elif state == STDERR:
 15.3844 ++                assert self.current_command.stderr is None
 15.3845 ++                self.current_command.stderr = token
 15.3846 ++                state = COMMAND
 15.3847 ++            elif state == STDIN:
 15.3848 ++                assert self.current_command.stdin is None
 15.3849 ++                self.current_command.stdin = token
 15.3850 ++                state = COMMAND
 15.3851 ++        self._commit_command()
 15.3852 ++        return self.pipeline
 15.3853 ++
 15.3854 ++    def _exec_piped_commands(self, commands):
 15.3855 ++        retvals = []
 15.3856 ++        for cmd in commands:
 15.3857 ++            retvals.append(cmd.wait())
 15.3858 ++        retval = 0
 15.3859 ++        for r in retvals:
 15.3860 ++            if r:
 15.3861 ++                retval = retvals[-1]
 15.3862 ++                break
 15.3863 ++        return retval
 15.3864 ++
 15.3865 ++    def run(self, verbose=False):
 15.3866 ++        pipeline = list(self.pipeline)
 15.3867 ++        files_to_close = []
 15.3868 ++        piped_commands = []
 15.3869 ++        piped_commands_display = []
 15.3870 ++        BEGIN, PIPE = range(2)
 15.3871 ++        state = BEGIN
 15.3872 ++        cwd = '.'
 15.3873 ++        while pipeline:
 15.3874 ++            node = pipeline.pop(0)
 15.3875 ++
 15.3876 ++            if isinstance(node, Chdir):
 15.3877 ++                next_op = pipeline.pop(0)
 15.3878 ++                assert isinstance(next_op, And)
 15.3879 ++                cwd = os.path.join(cwd, node.dir)
 15.3880 ++                if verbose:
 15.3881 ++                    piped_commands_display.append("cd %s &&" % node.dir)
 15.3882 ++                continue
 15.3883 ++            
 15.3884 ++            assert isinstance(node, (Command, Chdir))
 15.3885 ++            cmd = node
 15.3886 ++            if verbose:
 15.3887 ++                if cmd.env_vars:
 15.3888 ++                    env_vars_str = ' '.join(['%s=%s' % (key, val) for key, val in cmd.env_vars.iteritems()])
 15.3889 ++                    piped_commands_display.append("%s %s" % (env_vars_str, ' '.join(cmd.argv)))
 15.3890 ++                else:
 15.3891 ++                    piped_commands_display.append(' '.join(cmd.argv))
 15.3892 ++
 15.3893 ++            if state == PIPE:
 15.3894 ++                stdin = piped_commands[-1].stdout
 15.3895 ++            elif cmd.stdin is not None:
 15.3896 ++                stdin = open(cmd.stdin, "r")
 15.3897 ++                if verbose:
 15.3898 ++                    piped_commands_display.append('< %s' % cmd.stdin)
 15.3899 ++                files_to_close.append(stdin)
 15.3900 ++            else:
 15.3901 ++                stdin = None
 15.3902 ++
 15.3903 ++            if cmd.stdout is None:
 15.3904 ++                stdout = None
 15.3905 ++            elif cmd.stdout is Command.PIPE:
 15.3906 ++                stdout = subprocess.PIPE
 15.3907 ++            else:
 15.3908 ++                stdout = _open_out_file(cmd.stdout)
 15.3909 ++                files_to_close.append(stdout)
 15.3910 ++                if verbose:
 15.3911 ++                    piped_commands_display.append('> %s' % cmd.stdout)
 15.3912 ++
 15.3913 ++            if cmd.stderr is None:
 15.3914 ++                stderr = None
 15.3915 ++            elif cmd.stderr is Command.PIPE:
 15.3916 ++                stderr = subprocess.PIPE
 15.3917 ++            elif cmd.stderr is Command.STDOUT:
 15.3918 ++                stderr = subprocess.STDOUT
 15.3919 ++                if verbose:
 15.3920 ++                    piped_commands_display.append('2>&1')
 15.3921 ++            else:
 15.3922 ++                stderr = _open_out_file(cmd.stderr)
 15.3923 ++                files_to_close.append(stderr)
 15.3924 ++                if verbose:
 15.3925 ++                    piped_commands_display.append('2> %s' % cmd.stderr)
 15.3926 ++
 15.3927 ++            if cmd.env_vars:
 15.3928 ++                env = dict(os.environ)
 15.3929 ++                env.update(cmd.env_vars)
 15.3930 ++            else:
 15.3931 ++                env = None
 15.3932 ++
 15.3933 ++            if cwd == '.':
 15.3934 ++                proc_cwd = None
 15.3935 ++            else:
 15.3936 ++                proc_cwd = cwd
 15.3937 ++
 15.3938 ++            debug("command: subprocess.Popen(argv=%r, stdin=%r, stdout=%r, stderr=%r, env_vars=%r, cwd=%r)"
 15.3939 ++                  % (cmd.argv, stdin, stdout, stderr, cmd.env_vars, proc_cwd))
 15.3940 ++            proc = subprocess.Popen(cmd.argv, stdin=stdin, stdout=stdout, stderr=stderr, env=env, cwd=proc_cwd)
 15.3941 ++            del stdin, stdout, stderr
 15.3942 ++            piped_commands.append(proc)
 15.3943 ++
 15.3944 ++            try:
 15.3945 ++                next_node = pipeline.pop(0)
 15.3946 ++            except IndexError:
 15.3947 ++                try:
 15.3948 ++                    retval = self._exec_piped_commands(piped_commands)
 15.3949 ++                    if verbose:
 15.3950 ++                        print "%s: exit code %i" % (' '.join(piped_commands_display), retval)
 15.3951 ++                finally:
 15.3952 ++                    for f in files_to_close:
 15.3953 ++                        if f is not dev_null:
 15.3954 ++                            f.close()
 15.3955 ++                    files_to_close = []
 15.3956 ++                return retval
 15.3957 ++            else:
 15.3958 ++
 15.3959 ++                if isinstance(next_node, Pipe):
 15.3960 ++                    state = PIPE
 15.3961 ++                    piped_commands_display.append('|')
 15.3962 ++
 15.3963 ++                elif isinstance(next_node, Or):
 15.3964 ++                    try:
 15.3965 ++                        this_retval = self._exec_piped_commands(piped_commands)
 15.3966 ++                    finally:
 15.3967 ++                        for f in files_to_close:
 15.3968 ++                            if f is not dev_null:
 15.3969 ++                                f.close()
 15.3970 ++                        files_to_close = []
 15.3971 ++                    if this_retval == 0:
 15.3972 ++                        if verbose:
 15.3973 ++                            print "%s: exit code %i (|| is short-circuited)" % (' '.join(piped_commands_display), retval)
 15.3974 ++                        return this_retval
 15.3975 ++                    if verbose:
 15.3976 ++                        print "%s: exit code %i (|| proceeds)" % (' '.join(piped_commands_display), retval)
 15.3977 ++                    state = BEGIN
 15.3978 ++                    piped_commands = []
 15.3979 ++                    piped_commands_display = []
 15.3980 ++
 15.3981 ++                elif isinstance(next_node, And):
 15.3982 ++                    try:
 15.3983 ++                        this_retval = self._exec_piped_commands(piped_commands)
 15.3984 ++                    finally:
 15.3985 ++                        for f in files_to_close:
 15.3986 ++                            if f is not dev_null:
 15.3987 ++                                f.close()
 15.3988 ++                        files_to_close = []
 15.3989 ++                    if this_retval != 0:
 15.3990 ++                        if verbose:
 15.3991 ++                            print "%s: exit code %i (&& is short-circuited)" % (' '.join(piped_commands_display), retval)
 15.3992 ++                        return this_retval
 15.3993 ++                    if verbose:
 15.3994 ++                        print "%s: exit code %i (&& proceeds)" % (' '.join(piped_commands_display), retval)
 15.3995 ++                    state = BEGIN
 15.3996 ++                    piped_commands = []
 15.3997 ++                    piped_commands_display = []
 15.3998 ++
 15.3999 ++
 15.4000 ++
 15.4001 ++def _main():
 15.4002 ++    pipeline = Pipeline()
 15.4003 ++    pipeline.parse('./foo.py 2>&1 < xxx | cat && ls')
 15.4004 ++    print pipeline.run()
 15.4005 ++
 15.4006 ++if __name__ == '__main__':
 15.4007 ++    _main()
 15.4008 ++
 15.4009 +diff --git a/wscript b/wscript
 15.4010 +--- a/wscript
 15.4011 ++++ b/wscript
 15.4012 +@@ -54,10 +54,21 @@
 15.4013 +     opt.add_option('--visualize',
 15.4014 +                    help=('Modify --run arguments to enable the visualizer'),
 15.4015 +                    action="store_true", default=False, dest='visualize')
 15.4016 ++    opt.add_option('--command-template',
 15.4017 ++                   help=('Template of the command used to run the program given by --run;'
 15.4018 ++                         ' It should be a shell command string containing %s inside,'