port wscripts, test.py, and waf-tools to Python3
authorSiddharth Santurkar <siddharth.santurkar@ieee.org>
Thu, 03 Sep 2015 21:14:55 -0700
changeset 11634 99173c0ad09b
parent 11633 6b74df04cf44
child 11635 56b840516e80
port wscripts, test.py, and waf-tools to Python3
bindings/python/wscript
src/core/wscript
src/internet/wscript
src/netanim/wscript
src/openflow/wscript
src/wscript
test.py
waf-tools/cflags.py
waf-tools/command.py
waf-tools/relocation.py
waf-tools/shellcmd.py
wscript
wutils.py
--- a/bindings/python/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/bindings/python/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -1,4 +1,5 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+from __future__ import print_function
 import types
 import re
 import os
@@ -88,19 +89,19 @@
 
     try:
         conf.load('python')
-    except Errors.ConfigurationError, ex:
+    except Errors.ConfigurationError as ex:
         conf.report_optional_feature("python", "Python Bindings", False,
                                      "The python interpreter was not found")
         return
     try:
         conf.check_python_version((2,3))
-    except Errors.ConfigurationError, ex:
+    except Errors.ConfigurationError as ex:
         conf.report_optional_feature("python", "Python Bindings", False,
                                      "The python found version is too low (2.3 required)")
         return
     try:
         conf.check_python_headers()
-    except Errors.ConfigurationError, ex:
+    except Errors.ConfigurationError as ex:
         conf.report_optional_feature("python", "Python Bindings", False,
                                      "Python library or headers missing")
         return
@@ -415,12 +416,12 @@
     def run(self):
         assert len(self.outputs) == 1
         outfile = file(self.outputs[0].abspath(), "w")
-        print >> outfile, "import warnings"
-        print >> outfile, 'warnings.warn("the ns3 module is a compatibility layer '\
-            'and should not be used in newly written code", DeprecationWarning, stacklevel=2)'
-        print >> outfile
+        print("import warnings", file=outfile)
+        print('warnings.warn("the ns3 module is a compatibility layer '\
+            'and should not be used in newly written code", DeprecationWarning, stacklevel=2)', file=outfile)
+        print(file=outfile)
         for module in self.bld.env['PYTHON_MODULES_BUILT']:
-            print >> outfile, "from ns.%s import *" % (module.replace('-', '_'))
+            print("from ns.%s import *" % (module.replace('-', '_')), file=outfile)
         outfile.close()
         return 0
 
@@ -466,7 +467,7 @@
                     scan_modules.append(mod.name.split('ns3-')[1])
         else:
             scan_modules = Options.options.apiscan.split(',')
-        print "Modules to scan: ", scan_modules
+        print("Modules to scan: ", scan_modules)
         for target, cflags in scan_targets:
             group = bld.get_group(bld.current_group)
             for module in scan_modules:
@@ -488,4 +489,3 @@
 
     # note: the actual build commands for the python bindings are in
     # src/wscript, not here.
-
--- a/src/core/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/src/core/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -32,8 +32,8 @@
                          "the implementation-defined numerical precision may "
                          "be less than the other implementations.  "
                          "[Allowed Values: %s]"
-                         % ", ".join([repr(p) for p in int64x64.keys()])),
-                   choices=int64x64.keys(),
+                         % ", ".join([repr(p) for p in list(int64x64.keys())])),
+                   choices=list(int64x64.keys()),
                    dest='int64x64_impl')
                    
     opt.add_option('--disable-pthread',
--- a/src/internet/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/src/internet/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -65,7 +65,7 @@
         conf.msg("Checking for NSC location", False)
         conf.report_optional_feature("nsc", "Network Simulation Cradle", False,
                                      "NSC not found (see option --with-nsc)")
-	return
+        return
     
     if Options.platform in ['linux', 'freebsd']:
         arch = os.uname()[4]
--- a/src/netanim/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/src/netanim/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -5,24 +5,15 @@
 # Required NetAnim version
 NETANIM_RELEASE_NAME = "netanim-3.106"
 
+def build (bld) :
+    module = bld.create_ns3_module ('netanim', ['internet', 'mobility', 'wimax', 'wifi', 'csma', 'lte', 'uan', 'energy'])
+    module.includes = '.'
+    module.source = [ 'model/animation-interface.cc', ]
+    netanim_test = bld.create_ns3_module_test_library('netanim')
+    netanim_test.source = ['test/netanim-test.cc', ]
+    headers = bld(features='ns3header')
+    headers.module = 'netanim'
+    headers.source = ['model/animation-interface.h', ]
+    if (bld.env['ENABLE_EXAMPLES']) :
+       bld.recurse('examples')
 
-def build (bld) :
-	module = bld.create_ns3_module ('netanim', ['internet', 'mobility', 'wimax', 'wifi', 'csma', 'lte', 'uan', 'energy'])
-	module.includes = '.'
-	module.source = [
-			  'model/animation-interface.cc',
-		        ]
-    	netanim_test = bld.create_ns3_module_test_library('netanim')
-    	netanim_test.source = [
-        	'test/netanim-test.cc',
-        ]
-
-	headers = bld(features='ns3header')
-	headers.module = 'netanim'
-	headers.source = [
-			  'model/animation-interface.h',
-  			 ]
-
-	if (bld.env['ENABLE_EXAMPLES']) :
-		bld.recurse('examples')
-
--- a/src/openflow/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/src/openflow/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -16,14 +16,13 @@
 
 def configure(conf):
     if not conf.env['LIB_BOOST']:
-	conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
+        conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
 				     "Required boost libraries not found")
 
         # Add this module to the list of modules that won't be built
         # if they are enabled.
         conf.env['MODULES_NOT_BUILT'].append('openflow')
-
-	return 
+        return 
 
     present_boost_libs = []
     for boost_lib_name in conf.env['LIB_BOOST']:
@@ -35,19 +34,18 @@
 
     missing_boost_libs = [lib for lib in REQUIRED_BOOST_LIBS if lib not in present_boost_libs]
     if missing_boost_libs != []:
-	conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
+        conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
 				     "Required boost libraries not found, missing: %s" % ', '.join(missing_boost_libs))
 
         # Add this module to the list of modules that won't be built
         # if they are enabled.
         conf.env['MODULES_NOT_BUILT'].append('openflow')
-
-	return 
+        return 
 
     if Options.options.with_openflow:
-	if os.path.isdir(Options.options.with_openflow):
-	    conf.msg("Checking for OpenFlow location", ("%s (given)" % Options.options.with_openflow))
-	    conf.env['WITH_OPENFLOW'] = os.path.abspath(Options.options.with_openflow)
+        if os.path.isdir(Options.options.with_openflow):
+            conf.msg("Checking for OpenFlow location", ("%s (given)" % Options.options.with_openflow))
+            conf.env['WITH_OPENFLOW'] = os.path.abspath(Options.options.with_openflow)
     else:
         # bake.py uses ../../build, while ns-3-dev uses ../openflow.
         lib_to_check = 'libopenflow.a'
@@ -59,19 +57,18 @@
             conf.env['WITH_OPENFLOW'] = os.path.abspath(openflow_bake_build_dir)
         elif os.path.isdir(openflow_dir):
             conf.msg("Checking for OpenFlow location", ("%s (guessed)" % openflow_dir))
-	    conf.env['WITH_OPENFLOW'] = os.path.abspath(openflow_dir)
+            conf.env['WITH_OPENFLOW'] = os.path.abspath(openflow_dir)
         del openflow_bake_build_dir
         del openflow_bake_lib_dir
-	del openflow_dir
+        del openflow_dir
     if not conf.env['WITH_OPENFLOW']:
-	conf.msg("Checking for OpenFlow location", False)
-	conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
+        conf.msg("Checking for OpenFlow location", False)
+        conf.report_optional_feature("openflow", "NS-3 OpenFlow Integration", False,
 				     "OpenFlow not enabled (see option --with-openflow)")
         # Add this module to the list of modules that won't be built
         # if they are enabled.
         conf.env['MODULES_NOT_BUILT'].append('openflow')
-
-	return 
+        return 
 
     test_code = '''
 #include "openflow/openflow.h"
@@ -164,8 +161,8 @@
         ]
 
     if bld.env['OPENFLOW'] and bld.env['DL'] and bld.env['XML2']:
-	obj.use.extend('OPENFLOW DL XML2'.split())
-	obj_test.use.extend('OPENFLOW DL XML2'.split())
+        obj.use.extend('OPENFLOW DL XML2'.split())
+        obj_test.use.extend('OPENFLOW DL XML2'.split())
 
     headers = bld(features='ns3header')
     headers.module = 'openflow'
@@ -173,16 +170,15 @@
         ]
 
     if bld.env['ENABLE_OPENFLOW']:
-	obj.source.append('model/openflow-interface.cc')
+        obj.source.append('model/openflow-interface.cc')
         obj.source.append('model/openflow-switch-net-device.cc')
-	obj.source.append('helper/openflow-switch-helper.cc')
+        obj.source.append('helper/openflow-switch-helper.cc')
 
         obj.env.append_value('DEFINES', 'NS3_OPENFLOW')
-
-	obj_test.source.append('test/openflow-switch-test-suite.cc')
-	headers.source.append('model/openflow-interface.h')
+        obj_test.source.append('test/openflow-switch-test-suite.cc')
+        headers.source.append('model/openflow-interface.h')
         headers.source.append('model/openflow-switch-net-device.h')
-	headers.source.append('helper/openflow-switch-helper.h')
+        headers.source.append('helper/openflow-switch-helper.h')
 
     if bld.env['ENABLE_EXAMPLES'] and bld.env['ENABLE_OPENFLOW']:
         bld.recurse('examples')
--- a/src/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/src/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -1,6 +1,6 @@
 
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
-
+from __future__ import print_function
 import os, os.path
 import sys
 import shutil
@@ -406,7 +406,7 @@
             if dep.startswith('ns3-'):
                 dep_name = dep[4:]
                 requires.append("libns%s-%s%s" % (wutils.VERSION, dep_name, env.BUILD_SUFFIX))
-        print >> outfile, """\
+        print("""\
 prefix=%s
 libdir=%s
 includedir=%s
@@ -418,7 +418,7 @@
 Cflags: %s
 Requires: %s\
 """ % (prefix, libdir, includedir,
-       name, name, wutils.VERSION, ' '.join(libs), ' '.join(cflags), ' '.join(requires))
+       name, name, wutils.VERSION, ' '.join(libs), ' '.join(cflags), ' '.join(requires)), file=outfile)
         outfile.close()
 
     def run(self):
@@ -492,8 +492,8 @@
             up = m.update
             up(self.__class__.__name__.encode())
             for x in self.inputs + self.outputs:
-                up(x.abspath())
-            up(self.mode)
+                up(x.abspath().encode())
+            up(self.mode.encode())
             if self.mode == 'remove':
                 up(self.header_to_remove.abspath().encode())
             self.uid_ = m.digest()
@@ -515,13 +515,13 @@
             outputs = [node.abspath() for node in self.outputs]
             for src, dst in zip(inputs, outputs):
                 try:
-                    os.chmod(dst, 0600)
+                    os.chmod(dst, 0o600)
                 except OSError:
                     pass
                 shutil.copy2(src, dst)
                 ## make the headers in builddir read-only, to prevent
                 ## accidental modification
-                os.chmod(dst, 0400)
+                os.chmod(dst, 0o400)
             return 0
         else:
             assert len(self.inputs) == 0
@@ -529,7 +529,7 @@
             out_file_name = self.header_to_remove.abspath()
             try:
                 os.unlink(out_file_name)
-            except OSError, ex:
+            except OSError as ex:
                 if ex.errno != 2:
                     raise
             return 0
@@ -584,8 +584,8 @@
             up = m.update
             up(self.__class__.__name__.encode())
             for x in self.inputs + self.outputs:
-                up(x.abspath())
-            up(self.mode)
+                up(x.abspath().encode())
+            up(self.mode.encode())
             if self.mode == 'remove':
                 up(self.header_to_remove.abspath().encode())
             self.uid_ = m.digest()
@@ -607,13 +607,13 @@
             outputs = [node.abspath() for node in self.outputs]
             for src, dst in zip(inputs, outputs):
                 try:
-                    os.chmod(dst, 0600)
+                    os.chmod(dst, 0o600)
                 except OSError:
                     pass
                 shutil.copy2(src, dst)
                 ## make the headers in builddir read-only, to prevent
                 ## accidental modification
-                os.chmod(dst, 0400)
+                os.chmod(dst, 0o400)
             return 0
         else:
             assert len(self.inputs) == 0
@@ -621,7 +621,7 @@
             out_file_name = self.header_to_remove.abspath()
             try:
                 os.unlink(out_file_name)
-            except OSError, ex:
+            except OSError as ex:
                 if ex.errno != 2:
                     raise
             return 0
@@ -659,41 +659,41 @@
             out_file_name = self.header_to_remove.abspath()
             try:
                 os.unlink(out_file_name)
-            except OSError, ex:
+            except OSError as ex:
                 if ex.errno != 2:
                     raise
             return 0
         assert len(self.outputs) == 1
         out_file_name = self.outputs[0].get_bld().abspath()#self.env)
         header_files = [os.path.basename(node.abspath()) for node in self.inputs]
-        outfile = file(out_file_name, "w")
+        outfile = open(out_file_name, "w")
         header_files.sort()
 
-        print >> outfile, """
+        print("""
 #ifdef NS3_MODULE_COMPILATION
 # error "Do not include ns3 module aggregator headers from other modules; these are meant only for end user scripts."
 #endif
 
 #ifndef NS3_MODULE_%s
-    """ % (self.module.upper().replace('-', '_'),)
+    """ % (self.module.upper().replace('-', '_'),), file=outfile)
 
     #     if self.module_deps:
     #         print >> outfile, "// Module dependencies:"
     #     for dep in self.module_deps:
     #         print >> outfile, "#include \"%s-module.h\"" % dep
 
-        print >> outfile
-        print >> outfile, "// Module headers:"
+        print(file=outfile)
+        print("// Module headers:", file=outfile)
         for header in header_files:
-            print >> outfile, "#include \"%s\"" % (header,)
+            print("#include \"%s\"" % (header,), file=outfile)
 
-        print >> outfile, "#endif"
+        print("#endif", file=outfile)
 
         outfile.close()
         return 0
 
     def sig_explicit_deps(self):
-        self.m.update('\n'.join([node.abspath() for node in self.inputs]))
+        self.m.update('\n'.join([node.abspath() for node in self.inputs]).encode('utf-8'))
         return self.m.digest()
 
     def unique_id(self):
--- a/test.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/test.py	Thu Sep 03 21:14:55 2015 -0700
@@ -16,14 +16,13 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #
-
+from __future__ import print_function
 import os
 import sys
 import time
 import optparse
 import subprocess
 import threading
-import Queue
 import signal
 import xml.dom.minidom
 import shutil
@@ -31,6 +30,10 @@
 
 from utils import get_list_from_file
 
+try:
+    import queue
+except ImportError:
+    import Queue as queue
 #
 # XXX This should really be part of a waf command to list the configuration
 # items relative to optional ns-3 pieces.
@@ -590,7 +593,7 @@
 
     if options.verbose:
         for item in interesting_config_items:
-            print "%s ==" % item, eval(item)
+            print("%s ==" % item, eval(item))
 
 #
 # It seems pointless to fork a process to run waf to fork a process to run
@@ -608,7 +611,7 @@
     have_PATH = False
     have_PYTHONPATH = False
 
-    keys = os.environ.keys()
+    keys = list(os.environ.keys())
     for key in keys:
         if key == "DYLD_LIBRARY_PATH":
             have_DYLD_LIBRARY_PATH = True
@@ -627,7 +630,7 @@
         os.environ["PYTHONPATH"] += ":" + pypath
 
     if options.verbose:
-        print "os.environ[\"PYTHONPATH\"] == %s" % os.environ["PYTHONPATH"]
+        print("os.environ[\"PYTHONPATH\"] == %s" % os.environ["PYTHONPATH"])
 
     if sys.platform == "darwin":
         if not have_DYLD_LIBRARY_PATH:
@@ -635,28 +638,28 @@
         for path in NS3_MODULE_PATH:
             os.environ["DYLD_LIBRARY_PATH"] += ":" + path
         if options.verbose:
-            print "os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_LIBRARY_PATH"]
+            print("os.environ[\"DYLD_LIBRARY_PATH\"] == %s" % os.environ["DYLD_LIBRARY_PATH"])
     elif sys.platform == "win32":
         if not have_PATH:
             os.environ["PATH"] = ""
         for path in NS3_MODULE_PATH:
             os.environ["PATH"] += ';' + path
         if options.verbose:
-            print "os.environ[\"PATH\"] == %s" % os.environ["PATH"]
+            print("os.environ[\"PATH\"] == %s" % os.environ["PATH"])
     elif sys.platform == "cygwin":
         if not have_PATH:
             os.environ["PATH"] = ""
         for path in NS3_MODULE_PATH:
             os.environ["PATH"] += ":" + path
         if options.verbose:
-            print "os.environ[\"PATH\"] == %s" % os.environ["PATH"]
+            print("os.environ[\"PATH\"] == %s" % os.environ["PATH"])
     else:
         if not have_LD_LIBRARY_PATH:
             os.environ["LD_LIBRARY_PATH"] = ""
         for path in NS3_MODULE_PATH:
-            os.environ["LD_LIBRARY_PATH"] += ":" + path
+            os.environ["LD_LIBRARY_PATH"] += ":" + str(path)
         if options.verbose:
-            print "os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRARY_PATH"]
+            print("os.environ[\"LD_LIBRARY_PATH\"] == %s" % os.environ["LD_LIBRARY_PATH"])
 
 #
 # Short note on generating suppressions:
@@ -756,7 +759,7 @@
         cmd = path_cmd
 
     if options.verbose:
-        print "Synchronously execute %s" % cmd
+        print("Synchronously execute %s" % cmd)
 
     start_time = time.time()
     proc = subprocess.Popen(cmd, shell = True, cwd = directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
@@ -778,8 +781,8 @@
         retval = 2
     
     if options.verbose:
-        print "Return code = ", retval
-        print "stderr = ", stderr_results
+        print("Return code = ", retval)
+        print("stderr = ", stderr_results)
 
     return (retval, stdout_results, stderr_results, elapsed_time)
 
@@ -947,7 +950,7 @@
             #
             if job.is_skip:
                 if options.verbose:
-                    print "Skip %s" % job.shell_command
+                    print("Skip %s" % job.shell_command)
                 self.output_queue.put(job)
                 continue
 
@@ -956,7 +959,7 @@
             #
             else:
                 if options.verbose:
-                    print "Launch %s" % job.shell_command
+                    print("Launch %s" % job.shell_command)
 
                 if job.is_example or job.is_pyexample:
                     #
@@ -983,12 +986,12 @@
                 job.set_elapsed_time(et)
 
                 if options.verbose:
-                    print "returncode = %d" % job.returncode
-                    print "---------- begin standard out ----------"
-                    print standard_out
-                    print "---------- begin standard err ----------"
-                    print standard_err
-                    print "---------- end standard err ----------"
+                    print("returncode = %d" % job.returncode)
+                    print("---------- begin standard out ----------")
+                    print(standard_out)
+                    print("---------- begin standard err ----------")
+                    print(standard_err)
+                    print("---------- end standard err ----------")
 
                 self.output_queue.put(job)
 
@@ -1047,30 +1050,31 @@
         #
         if options.kinds or options.list or (len(options.constrain) and options.constrain in core_kinds):
             if sys.platform == "win32":
-                waf_cmd = "waf --target=test-runner"
+                waf_cmd = sys.executable + " waf --target=test-runner"
             else:
-                waf_cmd = "./waf --target=test-runner"
+                waf_cmd = sys.executable + " waf --target=test-runner"
         elif len(options.example):
-            if sys.platform == "win32":
-                waf_cmd = "waf --target=%s" % os.path.basename(options.example)
+            if sys.platform == "win32": #Modify for windows
+                waf_cmd = sys.executable + " waf --target=%s" % os.path.basename(options.example)
             else:
-                waf_cmd = "./waf --target=%s" % os.path.basename(options.example)
+                waf_cmd = sys.executable + " waf --target=%s" % os.path.basename(options.example)
 
         else:
-            if sys.platform == "win32":
-                waf_cmd = "waf"
+            if sys.platform == "win32": #Modify for windows
+                waf_cmd = sys.executable + " waf"
             else:
-                waf_cmd = "./waf"
+                waf_cmd = sys.executable + " waf"
 
         if options.verbose:
-            print "Building: %s" % waf_cmd
+            print("Building: %s" % waf_cmd)
 
         proc = subprocess.Popen(waf_cmd, shell = True)
         proc.communicate()
         if proc.returncode:
-            print >> sys.stderr, "Waf died. Not running tests"
+            print("Waf died. Not running tests", file=sys.stderr)
             return proc.returncode
 
+
     #
     # Dynamically set up paths.
     #
@@ -1084,7 +1088,7 @@
         ns3_runnable_programs = get_list_from_file(build_status_file, "ns3_runnable_programs")
         ns3_runnable_scripts = get_list_from_file(build_status_file, "ns3_runnable_scripts")
     else:
-        print >> sys.stderr, 'The build status file was not found.  You must do waf build before running test.py.'
+        print('The build status file was not found.  You must do waf build before running test.py.', file=sys.stderr)
         sys.exit(2)
 
     #
@@ -1154,7 +1158,7 @@
     if options.kinds:
         path_cmd = os.path.join("utils", test_runner_name + " --print-test-type-list")
         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
-        print standard_out
+        print(standard_out.decode())
 
     if options.list:
         if len(options.constrain):
@@ -1164,20 +1168,22 @@
         (rc, standard_out, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
         if rc != 0:
             # This is usually a sign that ns-3 crashed or exited uncleanly
-            print('test.py error:  test-runner return code returned {}'.format(rc))
-            print('To debug, try running {}\n'.format('\'./waf --run \"test-runner --print-test-name-list\"\''))
+            print(('test.py error:  test-runner return code returned {}'.format(rc)))
+            print(('To debug, try running {}\n'.format('\'./waf --run \"test-runner --print-test-name-list\"\'')))
             return
+        if isinstance(standard_out, bytes):
+            standard_out = standard_out.decode()
         list_items = standard_out.split('\n')
         list_items.sort()
-        print "Test Type    Test Name"
-        print "---------    ---------"
+        print("Test Type    Test Name")
+        print("---------    ---------")
         for item in list_items:
             if len(item.strip()):
-                print item
+                print(item)
         example_names_original.sort()
         for item in example_names_original:
-                print "example     ", item
-        print
+                print("example     ", item)
+        print()
 
     if options.kinds or options.list:
         return
@@ -1248,10 +1254,12 @@
         # See if this is a valid test suite.
         path_cmd = os.path.join("utils", test_runner_name + " --print-test-name-list")
         (rc, suites, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
+        if isinstance(suites, bytes):
+            suites = suites.decode()
         if options.suite in suites.split('\n'):
             suites = options.suite + "\n"
         else:
-            print >> sys.stderr, 'The test suite was not run because an unknown test suite name was requested.'
+            print('The test suite was not run because an unknown test suite name was requested.', file=sys.stderr)
             sys.exit(2)
 
     elif len(options.example) == 0 and len(options.pyexample) == 0:
@@ -1272,6 +1280,8 @@
     # even in the case of a single suite to avoid having two process the
     # results in two different places.
     #
+    if isinstance(suites, bytes):
+        suites = suites.decode()
     suite_list = suites.split('\n')
 
     #
@@ -1283,6 +1293,8 @@
         # Get a list of all of the performance tests.
         path_cmd = os.path.join("utils", test_runner_name + " --print-test-name-list --test-type=%s" % "performance")
         (rc, performance_tests, standard_err, et) = run_job_synchronously(path_cmd, os.getcwd(), False, False)
+        if isinstance(performance_tests, bytes):
+            performance_tests = performance_tests.decode()
         performance_test_list = performance_tests.split('\n')
 
         # Remove any performance tests from the suites list.
@@ -1294,8 +1306,8 @@
     # run them in parallel.  We're going to spin up a number of worker threads
     # that will run our test jobs for us.
     #
-    input_queue = Queue.Queue(0)
-    output_queue = Queue.Queue(0)
+    input_queue = queue.Queue(0)
+    output_queue = queue.Queue(0)
 
     jobs = 0
     threads=[]
@@ -1374,7 +1386,7 @@
                 job.set_is_skip(True)
 
             if options.verbose:
-                print "Queue %s" % test
+                print("Queue %s" % test)
 
             input_queue.put(job)
             jobs = jobs + 1
@@ -1428,7 +1440,7 @@
                     test_name = os.path.basename(test_name)
 
                     # Don't try to run this example if it isn't runnable.
-                    if ns3_runnable_programs_dictionary.has_key(test_name):
+                    if test_name in ns3_runnable_programs_dictionary:
                         if eval(do_run):
                             job = Job()
                             job.set_is_example(True)
@@ -1445,7 +1457,7 @@
                                 job.set_is_skip (True)
 
                             if options.verbose:
-                                print "Queue %s" % test
+                                print("Queue %s" % test)
 
                             input_queue.put(job)
                             jobs = jobs + 1
@@ -1457,8 +1469,8 @@
         example_name = "%s%s-%s%s" % (APPNAME, VERSION, options.example, BUILD_PROFILE_SUFFIX)
 
         # Don't try to run this example if it isn't runnable.
-        if not ns3_runnable_programs_dictionary.has_key(example_name):
-            print "Example %s is not runnable." % example_name
+        if example_name not in ns3_runnable_programs_dictionary:
+            print("Example %s is not runnable." % example_name)
         else:
             #
             # If you tell me to run an example, I will try and run the example
@@ -1478,7 +1490,7 @@
             job.set_build_path(options.buildpath)
 
             if options.verbose:
-                print "Queue %s" % example_name
+                print("Queue %s" % example_name)
 
             input_queue.put(job)
             jobs = jobs + 1
@@ -1545,7 +1557,7 @@
                                 job.set_is_skip (True)
 
                             if options.verbose:
-                                print "Queue %s" % test
+                                print("Queue %s" % test)
 
                             input_queue.put(job)
                             jobs = jobs + 1
@@ -1555,7 +1567,7 @@
         # Don't try to run this example if it isn't runnable.
         example_name = os.path.basename(options.pyexample)
         if example_name not in ns3_runnable_scripts:
-            print "Example %s is not runnable." % example_name
+            print("Example %s is not runnable." % example_name)
         else:
             #
             # If you tell me to run a python example, I will try and run the example
@@ -1572,7 +1584,7 @@
             job.set_build_path("")
 
             if options.verbose:
-                print "Queue %s" % options.pyexample
+                print("Queue %s" % options.pyexample)
 
             input_queue.put(job)
             jobs = jobs + 1
@@ -1636,9 +1648,9 @@
                 status = "CRASH"
 
         if options.duration or options.constrain == "performance":
-            print "%s (%.3f): %s %s" % (status, job.elapsed_time, kind, job.display_name)
+            print("%s (%.3f): %s %s" % (status, job.elapsed_time, kind, job.display_name))
         else:
-            print "%s: %s %s" % (status, kind, job.display_name)
+            print("%s: %s %s" % (status, kind, job.display_name))
 
         if job.is_example or job.is_pyexample:
             #
@@ -1766,23 +1778,23 @@
     #
     # Print a quick summary of events
     #
-    print "%d of %d tests passed (%d passed, %d skipped, %d failed, %d crashed, %d valgrind errors)" % (passed_tests, 
-        total_tests, passed_tests, skipped_tests, failed_tests, crashed_tests, valgrind_errors)
+    print("%d of %d tests passed (%d passed, %d skipped, %d failed, %d crashed, %d valgrind errors)" % (passed_tests, 
+        total_tests, passed_tests, skipped_tests, failed_tests, crashed_tests, valgrind_errors))
     #
     # Repeat summary of skipped, failed, crashed, valgrind events 
     #
     if skipped_testnames:
         skipped_testnames.sort()
-        print 'List of SKIPped tests:\n    %s' % '\n    '.join(map(str, skipped_testnames))
+        print('List of SKIPped tests:\n    %s' % '\n    '.join(map(str, skipped_testnames)))
     if failed_testnames:
         failed_testnames.sort()
-        print 'List of FAILed tests:\n    %s' % '\n    '.join(map(str, failed_testnames))
+        print('List of FAILed tests:\n    %s' % '\n    '.join(map(str, failed_testnames)))
     if crashed_testnames:
         crashed_testnames.sort()
-        print 'List of CRASHed tests:\n    %s' % '\n    '.join(map(str, crashed_testnames))
+        print('List of CRASHed tests:\n    %s' % '\n    '.join(map(str, crashed_testnames)))
     if valgrind_testnames:
         valgrind_testnames.sort()
-        print 'List of VALGR failures:\n    %s' % '\n    '.join(map(str, valgrind_testnames))
+        print('List of VALGR failures:\n    %s' % '\n    '.join(map(str, valgrind_testnames)))
     #
     # The last things to do are to translate the XML results file to "human
     # readable form" if the user asked for it (or make an XML file somewhere)
@@ -1800,25 +1812,25 @@
     # Let the user know if they need to turn on tests or examples.
     #
     if not ENABLE_TESTS or not ENABLE_EXAMPLES:
-        print
+        print()
         if not ENABLE_TESTS:
-            print '***  Note: ns-3 tests are currently disabled. Enable them by adding'
-            print '***  "--enable-tests" to ./waf configure or modifying your .ns3rc file.'
-            print
+            print('***  Note: ns-3 tests are currently disabled. Enable them by adding')
+            print('***  "--enable-tests" to ./waf configure or modifying your .ns3rc file.')
+            print()
         if not ENABLE_EXAMPLES:
-            print '***  Note: ns-3 examples are currently disabled. Enable them by adding'
-            print '***  "--enable-examples" to ./waf configure or modifying your .ns3rc file.'
-            print
+            print('***  Note: ns-3 examples are currently disabled. Enable them by adding')
+            print('***  "--enable-examples" to ./waf configure or modifying your .ns3rc file.')
+            print()
 
     #
     # Let the user know if they tried to use valgrind but it was not
     # present on their machine.
     #
     if options.valgrind and not VALGRIND_FOUND:
-        print
-        print '***  Note: you are trying to use valgrind, but valgrind could not be found'
-        print '***  on your machine.  All tests and examples will crash or be skipped.'
-        print
+        print()
+        print('***  Note: you are trying to use valgrind, but valgrind could not be found')
+        print('***  on your machine.  All tests and examples will crash or be skipped.')
+        print()
 
     #
     # If we have been asked to retain all of the little temporary files, we
--- a/waf-tools/cflags.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/waf-tools/cflags.py	Thu Sep 03 21:14:55 2015 -0700
@@ -153,8 +153,8 @@
 			     "Build profiles control the default compilation flags"
 			     " used for C/C++ programs, if CCFLAGS/CXXFLAGS are not"
 			     " set set in the environment. [Allowed Values: %s]"
-			     % ", ".join([repr(p) for p in profiles.keys()])),
-		       choices=profiles.keys(),
+			     % ", ".join([repr(p) for p in list(profiles.keys())])),
+		       choices=list(profiles.keys()),
 		       dest='build_profile')
 
 def configure(conf):
--- a/waf-tools/command.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/waf-tools/command.py	Thu Sep 03 21:14:55 2015 -0700
@@ -80,17 +80,17 @@
 		namespace.update(env=self.env, SRC=self.inputs, TGT=self.outputs)
 		for cmd in pipeline.pipeline:
 			if isinstance(cmd, shellcmd.Command):
-				if isinstance(cmd.stdin, basestring):
+				if isinstance(cmd.stdin, str):
 					cmd.stdin = self._subst_arg(cmd.stdin, 'in', namespace)
-				if isinstance(cmd.stdout, basestring):
+				if isinstance(cmd.stdout, str):
 					cmd.stdout = self._subst_arg(cmd.stdout, 'out', namespace)
-				if isinstance(cmd.stderr, basestring):
+				if isinstance(cmd.stderr, str):
 					cmd.stderr = self._subst_arg(cmd.stderr, 'out', namespace)
-				for argI in xrange(len(cmd.argv)):
+				for argI in range(len(cmd.argv)):
 					cmd.argv[argI] = self._subst_arg(cmd.argv[argI], None, namespace)
 				if cmd.env_vars is not None:
 					env_vars = dict()
-					for name, value in cmd.env_vars.iteritems():
+					for name, value in cmd.env_vars.items():
 						env_vars[name] = self._subst_arg(value, None, namespace)
 					cmd.env_vars = env_vars
 			elif isinstance(cmd, shellcmd.Chdir):
--- a/waf-tools/relocation.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/waf-tools/relocation.py	Thu Sep 03 21:14:55 2015 -0700
@@ -12,7 +12,7 @@
 Note that if the project directory name changes, the signatures for the tasks using
 files in that directory will change, causing a partial build.
 """
-
+from __future__ import print_function
 import os
 from waflib import Build, ConfigSet, Task, Utils, Errors
 from waflib.TaskGen import feature, before_method, after_method
@@ -47,10 +47,10 @@
 		d = self.root.find_node(srcdir)
 		if d and srcdir != self.top_dir and getattr(d, 'children', ''):
 			srcnode = self.root.make_node(self.top_dir)
-			print("relocating the source directory %r -> %r" % (srcdir, self.top_dir))
+			print(("relocating the source directory %r -> %r" % (srcdir, self.top_dir)))
 			srcnode.children = {}
 
-			for (k, v) in d.children.items():
+			for (k, v) in list(d.children.items()):
 				srcnode.children[k] = v
 				v.parent = srcnode
 			d.children = {}
--- a/waf-tools/shellcmd.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/waf-tools/shellcmd.py	Thu Sep 03 21:14:55 2015 -0700
@@ -14,6 +14,7 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
+from __future__ import print_function
 import shlex
 import subprocess
 import sys
@@ -23,7 +24,7 @@
 env_var_rx = re.compile(r"^([a-zA-Z0-9_]+)=(\S+)$")
 
 def debug(message):
-    print >> sys.stderr, message
+    print(message, file=sys.stderr)
 
 
 if sys.platform == 'win32':
@@ -127,7 +128,7 @@
             tokens = shlex.split(command)
         debug("command: shlex: %r" % (tokens,))
 
-        BEGIN, COMMAND, CHDIR, STDERR, STDOUT, STDIN = range(6)
+        BEGIN, COMMAND, CHDIR, STDERR, STDOUT, STDIN = list(range(6))
         state = BEGIN
         self.current_command = None
         env_vars = dict()
@@ -215,7 +216,7 @@
         files_to_close = []
         piped_commands = []
         piped_commands_display = []
-        BEGIN, PIPE = range(2)
+        BEGIN, PIPE = list(range(2))
         state = BEGIN
         cwd = '.'
         while pipeline:
@@ -233,7 +234,7 @@
             cmd = node
             if verbose:
                 if cmd.env_vars:
-                    env_vars_str = ' '.join(['%s=%s' % (key, val) for key, val in cmd.env_vars.iteritems()])
+                    env_vars_str = ' '.join(['%s=%s' % (key, val) for key, val in cmd.env_vars.items()])
                     piped_commands_display.append("%s %s" % (env_vars_str, ' '.join(cmd.argv)))
                 else:
                     piped_commands_display.append(' '.join(cmd.argv))
@@ -295,7 +296,7 @@
                 try:
                     retval = self._exec_piped_commands(piped_commands)
                     if verbose:
-                        print "%s: exit code %i" % (' '.join(piped_commands_display), retval)
+                        print("%s: exit code %i" % (' '.join(piped_commands_display), retval))
                 finally:
                     for f in files_to_close:
                         if f is not dev_null:
@@ -318,10 +319,10 @@
                         files_to_close = []
                     if this_retval == 0:
                         if verbose:
-                            print "%s: exit code %i (|| is short-circuited)" % (' '.join(piped_commands_display), retval)
+                            print("%s: exit code %i (|| is short-circuited)" % (' '.join(piped_commands_display), retval))
                         return this_retval
                     if verbose:
-                        print "%s: exit code %i (|| proceeds)" % (' '.join(piped_commands_display), retval)
+                        print("%s: exit code %i (|| proceeds)" % (' '.join(piped_commands_display), retval))
                     state = BEGIN
                     piped_commands = []
                     piped_commands_display = []
@@ -336,10 +337,10 @@
                         files_to_close = []
                     if this_retval != 0:
                         if verbose:
-                            print "%s: exit code %i (&& is short-circuited)" % (' '.join(piped_commands_display), retval)
+                            print("%s: exit code %i (&& is short-circuited)" % (' '.join(piped_commands_display), retval))
                         return this_retval
                     if verbose:
-                        print "%s: exit code %i (&& proceeds)" % (' '.join(piped_commands_display), retval)
+                        print("%s: exit code %i (&& proceeds)" % (' '.join(piped_commands_display), retval))
                     state = BEGIN
                     piped_commands = []
                     piped_commands_display = []
@@ -349,7 +350,7 @@
 def _main():
     pipeline = Pipeline()
     pipeline.parse('./foo.py 2>&1 < xxx | cat && ls')
-    print pipeline.run()
+    print(pipeline.run())
 
 if __name__ == '__main__':
     _main()
--- a/wscript	Thu Sep 03 21:20:53 2015 -0700
+++ b/wscript	Thu Sep 03 21:14:55 2015 -0700
@@ -1,6 +1,7 @@
 ## -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
 
 # python lib modules
+from __future__ import print_function
 import sys
 import shutil
 import types
@@ -54,7 +55,7 @@
 Configure.autoconfig = 0
 
 # the following two variables are used by the target "waf dist"
-VERSION = file("VERSION", "rt").read().strip()
+VERSION = open("VERSION", "rt").read().strip()
 APPNAME = 'ns'
 
 wutils.VERSION = VERSION
@@ -106,14 +107,14 @@
     # Print the list of module names in 3 columns.
     i = 1
     for name in names:
-        print name.ljust(25),
+        print(name.ljust(25), end=' ')
         if i == 3:
-                print
+                print()
                 i = 0
         i = i+1
 
     if i != 1:
-        print
+        print()
 
 def options(opt):
     # options provided by the modules
@@ -232,7 +233,7 @@
         flag_str = 'flags ' + ' '.join(l)
     else:
         flag_str = 'flag ' + ' '.join(l)
-    if flag_str > 28:
+    if len(flag_str) > 28:
         flag_str = flag_str[:28] + "..."
 
     conf.start_msg('Checking for compilation %s support' % (flag_str,))
@@ -532,12 +533,12 @@
             conf.env.append_value(confvar, value)
 
     # Write a summary of optional features status
-    print "---- Summary of optional NS-3 features:"
-    print "%-30s: %s%s%s" % ("Build profile", Logs.colors('GREEN'),
-                             Options.options.build_profile, Logs.colors('NORMAL'))
+    print("---- Summary of optional NS-3 features:")
+    print("%-30s: %s%s%s" % ("Build profile", Logs.colors('GREEN'),
+                             Options.options.build_profile, Logs.colors('NORMAL')))
     bld = wutils.bld
-    print "%-30s: %s%s%s" % ("Build directory", Logs.colors('GREEN'),
-                             Options.options.out, Logs.colors('NORMAL'))
+    print("%-30s: %s%s%s" % ("Build directory", Logs.colors('GREEN'),
+                             Options.options.out, Logs.colors('NORMAL')))
     
     
     for (name, caption, was_enabled, reason_not_enabled) in conf.env['NS3_OPTIONAL_FEATURES']:
@@ -547,7 +548,7 @@
         else:
             status = 'not enabled (%s)' % reason_not_enabled
             color = 'RED'
-        print "%-30s: %s%s%s" % (caption, Logs.colors(color), status, Logs.colors('NORMAL'))
+        print("%-30s: %s%s%s" % (caption, Logs.colors(color), status, Logs.colors('NORMAL')))
 
 
 class SuidBuild_task(Task.Task):
@@ -559,14 +560,14 @@
         self.m_display = 'build-suid'
         try:
             program_obj = wutils.find_program(self.generator.name, self.generator.env)
-        except ValueError, ex:
+        except ValueError as ex:
             raise WafError(str(ex))
         program_node = program_obj.path.find_or_declare(program_obj.target)
         self.filename = program_node.get_bld().abspath()
 
 
     def run(self):
-        print >> sys.stderr, 'setting suid bit on executable ' + self.filename
+        print('setting suid bit on executable ' + self.filename, file=sys.stderr)
         if subprocess.Popen(['sudo', 'chown', 'root', self.filename]).wait():
             return 1
         if subprocess.Popen(['sudo', 'chmod', 'u+s', self.filename]).wait():
@@ -907,8 +908,8 @@
     if (env['PRINT_BUILT_MODULES_AT_END']):
 
         # Print the list of built modules.
-        print
-        print 'Modules built:'
+        print()
+        print('Modules built:')
         names_without_prefix = []
         for name in env['NS3_ENABLED_MODULES']:
             name1 = name[len('ns3-'):]
@@ -916,13 +917,13 @@
                 name1 += " (no Python)"
             names_without_prefix.append(name1)
         print_module_names(names_without_prefix)
-        print
+        print()
 
         # Print the list of enabled modules that were not built.
         if env['MODULES_NOT_BUILT']:
-            print 'Modules not built (see ns-3 tutorial for explanation):'
+            print('Modules not built (see ns-3 tutorial for explanation):')
             print_module_names(env['MODULES_NOT_BUILT'])
-            print
+            print()
 
         # Set this so that the lists won't be printed until the next
         # build is done.
@@ -967,15 +968,13 @@
 class CheckContext(Context.Context):
     """run the equivalent of the old ns-3 unit tests using test.py"""
     cmd = 'check'
-
     def execute(self):
-
         # first we execute the build
-	bld = Context.create_context("build")
-	bld.options = Options.options # provided for convenience
-	bld.cmd = "build"
-	bld.execute()
-
+        bld = Context.create_context("build")
+        bld.options = Options.options # provided for convenience
+        bld.cmd = "build"
+        bld.execute()
+        
         wutils.bld = bld
         wutils.run_python_program("test.py -n -c core", bld.env)
 
@@ -1062,19 +1061,18 @@
 class Ns3ShellContext(Context.Context):
     """run a shell with an environment suitably modified to run locally built programs"""
     cmd = 'shell'
-
+    
     def execute(self):
-
         # first we execute the build
-	bld = Context.create_context("build")
-	bld.options = Options.options # provided for convenience
-	bld.cmd = "build"
-	bld.execute()
+        bld = Context.create_context("build")
+        bld.options = Options.options # provided for convenience
+        bld.cmd = "build"
+        bld.execute()
 
         # Set this so that the lists won't be printed when the user
         # exits the shell.
         bld.env['PRINT_BUILT_MODULES_AT_END'] = False
-
+        
         if sys.platform == 'win32':
             shell = os.environ.get("COMSPEC", "cmd.exe")
         else:
@@ -1144,10 +1142,10 @@
     cmd = 'doxygen'
     def execute(self):
         # first we execute the build
-	bld = Context.create_context("build")
-	bld.options = Options.options # provided for convenience
-	bld.cmd = "build"
-	bld.execute()
+        bld = Context.create_context("build")
+        bld.options = Options.options # provided for convenience
+        bld.cmd = "build"
+        bld.execute()
         _doxygen(bld)
 
 class Ns3SphinxContext(Context.Context):
@@ -1156,8 +1154,8 @@
     cmd = 'sphinx'
 
     def sphinx_build(self, path):
-        print
-        print "[waf] Building sphinx docs for " + path
+        print()
+        print("[waf] Building sphinx docs for " + path)
         if subprocess.Popen(["make", "SPHINXOPTS=-N", "-k",
                              "html", "singlehtml", "latexpdf" ],
                             cwd=path).wait() :
--- a/wutils.py	Thu Sep 03 21:20:53 2015 -0700
+++ b/wutils.py	Thu Sep 03 21:14:55 2015 -0700
@@ -68,7 +68,7 @@
 
 def get_proc_env(os_env=None):
     env = bld.env
-    if sys.platform == 'linux2':
+    if sys.platform == 'linux2' or sys.platform == 'linux':
         pathvar = 'LD_LIBRARY_PATH'
     elif sys.platform == 'darwin':
         pathvar = 'DYLD_LIBRARY_PATH'
@@ -90,9 +90,9 @@
 
     if pathvar is not None:
         if pathvar in proc_env:
-            proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH']) + [proc_env[pathvar]])
+            proc_env[pathvar] = os.pathsep.join(list(str(env['NS3_MODULE_PATH'])) + [proc_env[pathvar]])
         else:
-            proc_env[pathvar] = os.pathsep.join(list(env['NS3_MODULE_PATH']))
+            proc_env[pathvar] = os.pathsep.join(list(str(env['NS3_MODULE_PATH'])))
 
     pymoddir = bld.path.find_dir('bindings/python').get_bld().abspath()
     pyvizdir = bld.path.find_dir('src/visualizer').abspath()
@@ -133,13 +133,13 @@
         else:
             try:
                 retval = subprocess.Popen(argv, env=proc_env, cwd=cwd).wait()
-            except WindowsError, ex:
+            except WindowsError as ex:
                 raise WafError("Command %s raised exception %s" % (argv, ex))
     if retval:
         signame = None
         if retval < 0: # signal?
             import signal
-            for name, val in vars(signal).iteritems():
+            for name, val in vars(signal).items():
                 if len(name) > 3 and name[:3] == 'SIG' and name[3] != '_':
                     if val == -retval:
                         signame = name
@@ -167,7 +167,7 @@
 
         try:
             program_obj = find_program(program_name, env)
-        except ValueError, ex:
+        except ValueError as ex:
             raise WafError(str(ex))
 
         program_node = program_obj.path.find_or_declare(program_obj.target)
@@ -183,7 +183,7 @@
         program_name = program_string
         try:
             program_obj = find_program(program_name, env)
-        except ValueError, ex:
+        except ValueError as ex:
             raise WafError(str(ex))
 
         program_node = program_obj.path.find_or_declare(program_obj.target)