3 from optparse 
import OptionParser
 
    7 WSCRIPT_TEMPLATE = 
'''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 
   12 # def configure(conf): 
   13 #     conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H') 
   16     module = bld.create_ns3_module(%(MODULE)r, ['core']) 
   18         'model/%(MODULE)s.cc', 
   19         'helper/%(MODULE)s-helper.cc', 
   22     module_test = bld.create_ns3_module_test_library('%(MODULE)s') 
   23     module_test.source = [ 
   24         'test/%(MODULE)s-test-suite.cc', 
   27     headers = bld(features='ns3header') 
   28     headers.module = %(MODULE)r 
   31         'helper/%(MODULE)s-helper.h', 
   34     if bld.env.ENABLE_EXAMPLES: 
   35         bld.recurse('examples') 
   37     # bld.ns3_python_bindings() 
   43 MODEL_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   45 #include "%(MODULE)s.h" 
   58 MODEL_H_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   59 #ifndef %(INCLUDE_GUARD)s 
   60 #define %(INCLUDE_GUARD)s 
   68 #endif /* %(INCLUDE_GUARD)s */ 
   74 HELPER_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   76 #include "%(MODULE)s-helper.h" 
   89 HELPER_H_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
   90 #ifndef %(INCLUDE_GUARD)s 
   91 #define %(INCLUDE_GUARD)s 
   93 #include "ns3/%(MODULE)s.h" 
  101 #endif /* %(INCLUDE_GUARD)s */ 
  106 EXAMPLES_WSCRIPT_TEMPLATE = 
'''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*- 
  109     obj = bld.create_ns3_program('%(MODULE)s-example', [%(MODULE)r]) 
  110     obj.source = '%(MODULE)s-example.cc' 
  114 EXAMPLE_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
  116 #include "ns3/core-module.h" 
  117 #include "ns3/%(MODULE)s-helper.h" 
  123 main (int argc, char *argv[]) 
  128   cmd.AddValue ("verbose", "Tell application to log if true", verbose); 
  130   cmd.Parse (argc,argv); 
  135   Simulator::Destroy (); 
  143 TEST_CC_TEMPLATE = 
'''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ 
  145 // Include a header file from your module to test. 
  146 #include "ns3/%(MODULE)s.h" 
  148 // An essential include is test.h 
  149 #include "ns3/test.h" 
  151 // Do not put your test classes in namespace ns3.  You may find it useful 
  152 // to use the using directive to access the ns3 namespace directly 
  155 // This is an example TestCase. 
  156 class %(CAPITALIZED)sTestCase1 : public TestCase 
  159   %(CAPITALIZED)sTestCase1 (); 
  160   virtual ~%(CAPITALIZED)sTestCase1 (); 
  163   virtual void DoRun (void); 
  166 // Add some help text to this case to describe what it is intended to test 
  167 %(CAPITALIZED)sTestCase1::%(CAPITALIZED)sTestCase1 () 
  168   : TestCase ("%(CAPITALIZED)s test case (does nothing)") 
  172 // This destructor does nothing but we include it as a reminder that 
  173 // the test case should clean up after itself 
  174 %(CAPITALIZED)sTestCase1::~%(CAPITALIZED)sTestCase1 () 
  179 // This method is the pure virtual method from class TestCase that every 
  180 // TestCase must implement 
  183 %(CAPITALIZED)sTestCase1::DoRun (void) 
  185   // A wide variety of test macros are available in src/core/test.h 
  186   NS_TEST_ASSERT_MSG_EQ (true, true, "true doesn't equal true for some reason"); 
  187   // Use this one for floating point comparisons 
  188   NS_TEST_ASSERT_MSG_EQ_TOL (0.01, 0.01, 0.001, "Numbers are not equal within tolerance"); 
  191 // The TestSuite class names the TestSuite, identifies what type of TestSuite, 
  192 // and enables the TestCases to be run.  Typically, only the constructor for 
  193 // this class must be defined 
  195 class %(CAPITALIZED)sTestSuite : public TestSuite 
  198   %(CAPITALIZED)sTestSuite (); 
  201 %(CAPITALIZED)sTestSuite::%(CAPITALIZED)sTestSuite () 
  202   : TestSuite ("%(MODULE)s", UNIT) 
  204   // TestDuration for TestCase can be QUICK, EXTENSIVE or TAKES_FOREVER 
  205   AddTestCase (new %(CAPITALIZED)sTestCase1, TestCase::QUICK); 
  208 // Do not forget to allocate an instance of this TestSuite 
  209 static %(CAPITALIZED)sTestSuite %(COMPOUND)sTestSuite; 
  214 DOC_RST_TEMPLATE = 
'''Example Module Documentation 
  215 ---------------------------- 
  217 .. include:: replace.txt 
  219 .. heading hierarchy: 
  220    ------------- Chapter 
  221    ************* Section (#.#) 
  222    ============= Subsection (#.#.#) 
  223    ############# Paragraph (no number) 
  225 This is a suggested outline for adding new module documentation to |ns3|. 
  226 See ``src/click/doc/click.rst`` for an example. 
  228 The introductory paragraph is for describing what this code is trying to 
  231 For consistency (italicized formatting), please use |ns3| to refer to 
  232 ns-3 in the documentation (and likewise, |ns2| for ns-2).  These macros 
  233 are defined in the file ``replace.txt``. 
  238 The source code for the new module lives in the directory ``src/%(MODULE)s``. 
  240 Add here a basic description of what is being modeled. 
  245 Briefly describe the software design of the model and how it fits into  
  246 the existing ns-3 architecture.  
  248 Scope and Limitations 
  249 ===================== 
  251 What can the model do?  What can it not do?  Please use this section to 
  252 describe the scope and limitations of the model. 
  257 Add academic citations here, such as if you published a paper on this 
  258 model, or if readers should read a particular specification or other work. 
  263 This section is principally concerned with the usage of your model, using 
  264 the public API.  Focus first on most common usage patterns, then go 
  265 into more advanced topics. 
  270 Include this subsection only if there are special build instructions or 
  271 platform limitations. 
  276 What helper API will users typically use?  Describe it here. 
  281 What classes hold attributes, and what are the key ones worth mentioning? 
  286 What kind of data does the model generate?  What are the key trace 
  287 sources?   What kind of logging output can be enabled? 
  292 Go into further details (such as using the API outside of the helpers) 
  293 in additional sections, as needed. 
  298 What examples using this new code are available?  Describe them here. 
  303 Add any tips for avoiding pitfalls, etc. 
  308 Describe how the model has been tested/validated.  What tests run in the 
  309 test suite?  How much API and code is covered by the tests?  Again,  
  310 references to outside published work may help here. 
  315     parser = OptionParser(usage=(
"Usage: %prog [options] modulename\n" 
  316                                  "Utility script to create a basic template for a new ns-3 module"))
 
  317     (options, args) = parser.parse_args()
 
  322     modname = args[0].lower()
 
  323     if False in [word.isalnum() 
for word 
in modname.split(
"-")]:
 
  324         print >> sys.stderr, 
"Module name should only contain alphanumeric characters and dashes" 
  326     assert os.path.sep 
not in modname
 
  328     moduledir = os.path.join(os.path.dirname(__file__), modname)
 
  330     if os.path.exists(moduledir):
 
  331         print >> sys.stderr, 
"Module %r already exists" % (modname,)
 
  334     print(
"Creating module %r, " 
  335           "run './waf configure' to include it in the build" % (modname,))
 
  338     wscript = file(os.path.join(moduledir, 
"wscript"), 
"wt")
 
  339     wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
 
  346     modeldir = os.path.join(moduledir, 
"model")
 
  349     model_cc = file(os.path.join(moduledir, 
"model", 
"%s.cc" % modname), 
"wt")
 
  350     model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
 
  353     model_h = file(os.path.join(moduledir, 
"model", 
"%s.h" % modname), 
"wt")
 
  354     model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_H" % (modname.replace(
"-", 
"_").upper()),))
 
  362     testdir = os.path.join(moduledir, 
"test")
 
  364     test_cc = file(os.path.join(moduledir, 
"test", 
"%s-test-suite.cc" % modname), 
"wt")
 
  365     test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,
 
  366                                           CAPITALIZED=
''.join([word.capitalize() 
for word 
in modname.split(
'-')]),
 
  367                                           COMPOUND=
''.join([modname.split(
'-')[0]] + [word.capitalize() 
for word 
in modname.split(
'-')[1:]]),
 
  376     helperdir = os.path.join(moduledir, 
"helper")
 
  379     helper_cc = file(os.path.join(moduledir, 
"helper", 
"%s-helper.cc" % modname), 
"wt")
 
  380     helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
 
  383     helper_h = file(os.path.join(moduledir, 
"helper", 
"%s-helper.h" % modname), 
"wt")
 
  384     helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_HELPER_H" % (modname.replace(
"-", 
"_").upper()),))
 
  390     examplesdir = os.path.join(moduledir, 
"examples")
 
  391     os.mkdir(examplesdir)
 
  393     examples_wscript = file(os.path.join(examplesdir, 
"wscript"), 
"wt")
 
  394     examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
 
  395     examples_wscript.close()
 
  397     example_cc = file(os.path.join(moduledir, 
"examples", 
"%s-example.cc" % modname), 
"wt")
 
  398     example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
 
  404     docdir = os.path.join(moduledir, 
"doc")
 
  407     doc_rst = file(os.path.join(moduledir, 
"doc", 
"%s.rst" % modname), 
"wt")
 
  408     doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
 
  414 if __name__ == 
'__main__':
 
  415     sys.exit(
main(sys.argv))