2 from __future__ 
import print_function
 
    4 from optparse 
import OptionParser
 
    8 WSCRIPT_TEMPLATE = 
'''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 
   13 # def configure(conf): 
   14 #     conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H') 
   17     module = bld.create_ns3_module(%(MODULE)r, ['core']) 
   19         'model/%(MODULE)s.cc', 
   20         'helper/%(MODULE)s-helper.cc', 
   23     module_test = bld.create_ns3_module_test_library('%(MODULE)s') 
   24     module_test.source = [ 
   25         'test/%(MODULE)s-test-suite.cc', 
   28     headers = bld(features='ns3header') 
   29     headers.module = %(MODULE)r 
   32         'helper/%(MODULE)s-helper.h', 
   35     if bld.env.ENABLE_EXAMPLES: 
   36         bld.recurse('examples') 
   38     # bld.ns3_python_bindings() 
   44 MODEL_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   46 #include "%(MODULE)s.h" 
   59 MODEL_H_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   60 #ifndef %(INCLUDE_GUARD)s 
   61 #define %(INCLUDE_GUARD)s 
   69 #endif /* %(INCLUDE_GUARD)s */ 
   75 HELPER_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   77 #include "%(MODULE)s-helper.h" 
   90 HELPER_H_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   91 #ifndef %(INCLUDE_GUARD)s 
   92 #define %(INCLUDE_GUARD)s 
   94 #include "ns3/%(MODULE)s.h" 
  102 #endif /* %(INCLUDE_GUARD)s */ 
  107 EXAMPLES_WSCRIPT_TEMPLATE = 
'''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 
  110     obj = bld.create_ns3_program('%(MODULE)s-example', [%(MODULE)r]) 
  111     obj.source = '%(MODULE)s-example.cc' 
  115 EXAMPLE_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
  117 #include "ns3/core-module.h" 
  118 #include "ns3/%(MODULE)s-helper.h" 
  124 main (int argc, char *argv[]) 
  129   cmd.AddValue ("verbose", "Tell application to log if true", verbose); 
  131   cmd.Parse (argc,argv); 
  136   Simulator::Destroy (); 
  144 TEST_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
  146 // Include a header file from your module to test. 
  147 #include "ns3/%(MODULE)s.h" 
  149 // An essential include is test.h 
  150 #include "ns3/test.h" 
  152 // Do not put your test classes in namespace ns3.  You may find it useful 
  153 // to use the using directive to access the ns3 namespace directly 
  156 // This is an example TestCase. 
  157 class %(CAPITALIZED)sTestCase1 : public TestCase 
  160   %(CAPITALIZED)sTestCase1 (); 
  161   virtual ~%(CAPITALIZED)sTestCase1 (); 
  164   virtual void DoRun (void); 
  167 // Add some help text to this case to describe what it is intended to test 
  168 %(CAPITALIZED)sTestCase1::%(CAPITALIZED)sTestCase1 () 
  169   : TestCase ("%(CAPITALIZED)s test case (does nothing)") 
  173 // This destructor does nothing but we include it as a reminder that 
  174 // the test case should clean up after itself 
  175 %(CAPITALIZED)sTestCase1::~%(CAPITALIZED)sTestCase1 () 
  180 // This method is the pure virtual method from class TestCase that every 
  181 // TestCase must implement 
  184 %(CAPITALIZED)sTestCase1::DoRun (void) 
  186   // A wide variety of test macros are available in src/core/test.h 
  187   NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason"); 
  188   // Use this one for floating point comparisons 
  189   NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance"); 
  192 // The TestSuite class names the TestSuite, identifies what type of TestSuite, 
  193 // and enables the TestCases to be run.  Typically, only the constructor for 
  194 // this class must be defined 
  196 class %(CAPITALIZED)sTestSuite : public TestSuite 
  199   %(CAPITALIZED)sTestSuite (); 
  202 %(CAPITALIZED)sTestSuite::%(CAPITALIZED)sTestSuite () 
  203   : TestSuite ("%(MODULE)s", UNIT) 
  205   // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER 
  206   AddTestCase (new %(CAPITALIZED)sTestCase1, TestCase::QUICK); 
  209 // Do not forget to allocate an instance of this TestSuite 
  210 static %(CAPITALIZED)sTestSuite %(COMPOUND)sTestSuite; 
  215 DOC_RST_TEMPLATE = 
'''Example Module Documentation 
  216 ---------------------------- 
  218 .. include:: replace.txt 
  221 .. heading hierarchy: 
  222    ------------- Chapter 
  223    ************* Section (#.#) 
  224    ============= Subsection (#.#.#) 
  225    ############# Paragraph (no number) 
  227 This is a suggested outline for adding new module documentation to |ns3|. 
  228 See ``src/click/doc/click.rst`` for an example. 
  230 The introductory paragraph is for describing what this code is trying to 
  233 For consistency (italicized formatting), please use |ns3| to refer to 
  234 ns-3 in the documentation (and likewise, |ns2| for ns-2).  These macros 
  235 are defined in the file ``replace.txt``. 
  240 The source code for the new module lives in the directory ``src/%(MODULE)s``. 
  242 Add here a basic description of what is being modeled. 
  247 Briefly describe the software design of the model and how it fits into  
  248 the existing ns-3 architecture.  
  250 Scope and Limitations 
  251 ===================== 
  253 What can the model do?  What can it not do?  Please use this section to 
  254 describe the scope and limitations of the model. 
  259 Add academic citations here, such as if you published a paper on this 
  260 model, or if readers should read a particular specification or other work. 
  265 This section is principally concerned with the usage of your model, using 
  266 the public API.  Focus first on most common usage patterns, then go 
  267 into more advanced topics. 
  272 Include this subsection only if there are special build instructions or 
  273 platform limitations. 
  278 What helper API will users typically use?  Describe it here. 
  283 What classes hold attributes, and what are the key ones worth mentioning? 
  288 What kind of data does the model generate?  What are the key trace 
  289 sources?   What kind of logging output can be enabled? 
  294 Go into further details (such as using the API outside of the helpers) 
  295 in additional sections, as needed. 
  300 What examples using this new code are available?  Describe them here. 
  305 Add any tips for avoiding pitfalls, etc. 
  310 Describe how the model has been tested/validated.  What tests run in the 
  311 test suite?  How much API and code is covered by the tests?  Again,  
  312 references to outside published work may help here. 
  317     parser = OptionParser(usage=(
"Usage: %prog [options] modulename\n" 
  318                                  "Utility script to create a basic template for a new ns-3 module"))
 
  319     (options, args) = parser.parse_args()
 
  324     modname = args[0].lower()
 
  325     if False in [word.isalnum() 
for word 
in modname.split(
"-")]:
 
  326         print(
"Module name should only contain alphanumeric characters and dashes", file=sys.stderr)
 
  328     assert os.path.sep 
not in modname
 
  330     moduledir = os.path.join(os.path.dirname(__file__), modname)
 
  332     if os.path.exists(moduledir):
 
  333         print(
"Module %r already exists" % (modname,), file=sys.stderr)
 
  336     print(
"Creating module %r, " 
  337           "run './waf configure' to include it in the build" % (modname,))
 
  340     wscript = open(os.path.join(moduledir, 
"wscript"), 
"wt")
 
  341     wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
 
  348     modeldir = os.path.join(moduledir, 
"model")
 
  351     model_cc = open(os.path.join(moduledir, 
"model", 
"%s.cc" % modname), 
"wt")
 
  352     model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
 
  355     model_h = open(os.path.join(moduledir, 
"model", 
"%s.h" % modname), 
"wt")
 
  356     model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_H" % (modname.replace(
"-", 
"_").upper()),))
 
  364     testdir = os.path.join(moduledir, 
"test")
 
  366     test_cc = open(os.path.join(moduledir, 
"test", 
"%s-test-suite.cc" % modname), 
"wt")
 
  367     test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,
 
  368                                           CAPITALIZED=
''.join([word.capitalize() 
for word 
in modname.split(
'-')]),
 
  369                                           COMPOUND=
''.join([modname.split(
'-')[0]] + [word.capitalize() 
for word 
in modname.split(
'-')[1:]]),
 
  378     helperdir = os.path.join(moduledir, 
"helper")
 
  381     helper_cc = open(os.path.join(moduledir, 
"helper", 
"%s-helper.cc" % modname), 
"wt")
 
  382     helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
 
  385     helper_h = open(os.path.join(moduledir, 
"helper", 
"%s-helper.h" % modname), 
"wt")
 
  386     helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_HELPER_H" % (modname.replace(
"-", 
"_").upper()),))
 
  392     examplesdir = os.path.join(moduledir, 
"examples")
 
  393     os.mkdir(examplesdir)
 
  395     examples_wscript = open(os.path.join(examplesdir, 
"wscript"), 
"wt")
 
  396     examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
 
  397     examples_wscript.close()
 
  399     example_cc = open(os.path.join(moduledir, 
"examples", 
"%s-example.cc" % modname), 
"wt")
 
  400     example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
 
  406     docdir = os.path.join(moduledir, 
"doc")
 
  409     doc_rst = open(os.path.join(moduledir, 
"doc", 
"%s.rst" % modname), 
"wt")
 
  410     doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
 
  416 if __name__ == 
'__main__':
 
  417     sys.exit(main(sys.argv))