src/create-module.py
author John Abraham <john.abraham@gatech.edu>
Tue May 22 09:24:00 2012 -0400 (2 hours ago)
changeset 8789 b72463a93d84
parent 7646 0c1ed7ef4ee7
permissions -rwxr-xr-x
NetAnim: Documentation first version
     1 #! /usr/bin/env python
     2 import sys
     3 from optparse import OptionParser
     4 import os
     5 
     6 
     7 WSCRIPT_TEMPLATE = '''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
     8 
     9 # def options(opt):
    10 #     pass
    11 
    12 # def configure(conf):
    13 #     conf.check_nonfatal(header_name='stdint.h', define_name='HAVE_STDINT_H')
    14 
    15 def build(bld):
    16     module = bld.create_ns3_module(%(MODULE)r, ['core'])
    17     module.source = [
    18         'model/%(MODULE)s.cc',
    19         'helper/%(MODULE)s-helper.cc',
    20         ]
    21 
    22     module_test = bld.create_ns3_module_test_library('%(MODULE)s')
    23     module_test.source = [
    24         'test/%(MODULE)s-test-suite.cc',
    25         ]
    26 
    27     headers = bld.new_task_gen(features=['ns3header'])
    28     headers.module = %(MODULE)r
    29     headers.source = [
    30         'model/%(MODULE)s.h',
    31         'helper/%(MODULE)s-helper.h',
    32         ]
    33 
    34     if bld.env.ENABLE_EXAMPLES:
    35         bld.add_subdirs('examples')
    36 
    37     # bld.ns3_python_bindings()
    38 
    39 '''
    40 
    41 
    42 
    43 MODEL_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    44 
    45 #include "%(MODULE)s.h"
    46 
    47 namespace ns3 {
    48 
    49 /* ... */
    50 
    51 
    52 }
    53 
    54 '''
    55 
    56 
    57 
    58 MODEL_H_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    59 #ifndef %(INCLUDE_GUARD)s
    60 #define %(INCLUDE_GUARD)s
    61 
    62 namespace ns3 {
    63 
    64 /* ... */
    65 
    66 }
    67 
    68 #endif /* %(INCLUDE_GUARD)s */
    69 
    70 '''
    71 
    72 
    73 
    74 HELPER_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    75 
    76 #include "%(MODULE)s-helper.h"
    77 
    78 namespace ns3 {
    79 
    80 /* ... */
    81 
    82 
    83 }
    84 
    85 '''
    86 
    87 
    88 
    89 HELPER_H_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
    90 #ifndef %(INCLUDE_GUARD)s
    91 #define %(INCLUDE_GUARD)s
    92 
    93 #include "ns3/%(MODULE)s.h"
    94 
    95 namespace ns3 {
    96 
    97 /* ... */
    98 
    99 }
   100 
   101 #endif /* %(INCLUDE_GUARD)s */
   102 
   103 '''
   104 
   105 
   106 EXAMPLES_WSCRIPT_TEMPLATE = '''# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
   107 
   108 def build(bld):
   109     obj = bld.create_ns3_program('%(MODULE)s-example', [%(MODULE)r])
   110     obj.source = '%(MODULE)s-example.cc'
   111 
   112 '''
   113 
   114 EXAMPLE_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
   115 
   116 #include "ns3/core-module.h"
   117 #include "ns3/%(MODULE)s-helper.h"
   118 
   119 using namespace ns3;
   120 
   121 
   122 int 
   123 main (int argc, char *argv[])
   124 {
   125   bool verbose = true;
   126 
   127   CommandLine cmd;
   128   cmd.AddValue ("verbose", "Tell application to log if true", verbose);
   129 
   130   cmd.Parse (argc,argv);
   131 
   132   /* ... */
   133 
   134   Simulator::Run ();
   135   Simulator::Destroy ();
   136   return 0;
   137 }
   138 
   139 
   140 '''
   141 
   142 
   143 TEST_CC_TEMPLATE = '''/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
   144 
   145 // Include a header file from your module to test.
   146 #include "ns3/%(MODULE)s.h"
   147 
   148 // An essential include is test.h
   149 #include "ns3/test.h"
   150 
   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
   153 using namespace ns3;
   154 
   155 // This is an example TestCase.
   156 class %(CAPITALIZED)sTestCase1 : public TestCase
   157 {
   158 public:
   159   %(CAPITALIZED)sTestCase1 ();
   160   virtual ~%(CAPITALIZED)sTestCase1 ();
   161 
   162 private:
   163   virtual void DoRun (void);
   164 };
   165 
   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)")
   169 {
   170 }
   171 
   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 ()
   175 {
   176 }
   177 
   178 //
   179 // This method is the pure virtual method from class TestCase that every
   180 // TestCase must implement
   181 //
   182 void
   183 %(CAPITALIZED)sTestCase1::DoRun (void)
   184 {
   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");
   189 }
   190 
   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
   194 //
   195 class %(CAPITALIZED)sTestSuite : public TestSuite
   196 {
   197 public:
   198   %(CAPITALIZED)sTestSuite ();
   199 };
   200 
   201 %(CAPITALIZED)sTestSuite::%(CAPITALIZED)sTestSuite ()
   202   : TestSuite ("%(MODULE)s", UNIT)
   203 {
   204   AddTestCase (new %(CAPITALIZED)sTestCase1);
   205 }
   206 
   207 // Do not forget to allocate an instance of this TestSuite
   208 static %(CAPITALIZED)sTestSuite %(MODULE)sTestSuite;
   209 
   210 '''
   211 
   212 
   213 DOC_RST_TEMPLATE = '''Example Module Documentation
   214 ----------------------------
   215 
   216 .. heading hierarchy:
   217    ------------- Chapter
   218    ************* Section (#.#)
   219    ============= Subsection (#.#.#)
   220    ############# Paragraph (no number)
   221 
   222 This is a suggested outline for adding new module documentation to ns-3.
   223 See ``src/click/doc/click.rst`` for an example.
   224 
   225 The introductory paragraph is for describing what this code is trying to
   226 model.
   227 
   228 Model Description
   229 *****************
   230 
   231 The source code for the new module lives in the directory ``src/%(MODULE)s``.
   232 
   233 Design
   234 ======
   235 
   236 Add here an overall description of the software design and how it fits
   237 into the existing ns-3 architecture. 
   238 
   239 Scope and Limitations
   240 =====================
   241 
   242 What can the model do?  What can it not do?  Please use this section to
   243 describe the scope and limitations of the model.
   244 
   245 References
   246 ==========
   247 
   248 Add academic citations here, such as if you published a paper on this
   249 model, or if readers should read a particular specification or other work.
   250 
   251 Usage
   252 *****
   253 
   254 This section is principally concerned with the usage of your model, using
   255 the public API.
   256 
   257 Building New Module
   258 ===================
   259 
   260 Include this section if there are special build instructions.
   261 
   262 Helper
   263 ======
   264 
   265 What helper API will users typically use?  Describe it here.
   266 
   267 Advanced Usage
   268 ==============
   269 
   270 Go into further details (such as using the API outside of the helpers)
   271 in additional sections, as needed.
   272 
   273 Examples
   274 ========
   275 
   276 What examples using this new code are available?  Describe them here.
   277 
   278 Validation
   279 **********
   280 
   281 Describe how the model has been tested/validated.  What tests run in the
   282 test suite?  How much API and code is covered by the tests?  Again, 
   283 references to outside published work may help here.
   284 '''
   285 
   286 
   287 def main(argv):
   288     parser = OptionParser(usage=("Usage: %prog [options] modulename\n"
   289                                  "Utility script to create a basic template for a new ns-3 module"))
   290     (options, args) = parser.parse_args()
   291     if len(args) != 1:
   292         parser.print_help()
   293         return 1
   294 
   295     modname = args[0]
   296     assert os.path.sep not in modname
   297 
   298     moduledir = os.path.join(os.path.dirname(__file__), modname)
   299 
   300     if os.path.exists(moduledir):
   301         print >> sys.stderr, "Module %r already exists" % (modname,)
   302         return 2
   303 
   304     os.mkdir(moduledir)
   305     wscript = file(os.path.join(moduledir, "wscript"), "wt")
   306     wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
   307     wscript.close()
   308 
   309 
   310     #
   311     # model
   312     # 
   313     modeldir = os.path.join(moduledir, "model")
   314     os.mkdir(modeldir)
   315 
   316     model_cc = file(os.path.join(moduledir, "model", "%s.cc" % modname), "wt")
   317     model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
   318     model_cc.close()
   319 
   320     model_h = file(os.path.join(moduledir, "model", "%s.h" % modname), "wt")
   321     model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD="__%s_H__" % (modname.upper()),))
   322     model_h.close()
   323 
   324 
   325 
   326     #
   327     # test
   328     # 
   329     testdir = os.path.join(moduledir, "test")
   330     os.mkdir(testdir)
   331     test_cc = file(os.path.join(moduledir, "test", "%s-test-suite.cc" % modname), "wt")
   332     test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,CAPITALIZED=modname.capitalize()))
   333     test_cc.close()
   334 
   335 
   336 
   337     #
   338     # helper
   339     # 
   340     helperdir = os.path.join(moduledir, "helper")
   341     os.mkdir(helperdir)
   342 
   343     helper_cc = file(os.path.join(moduledir, "helper", "%s-helper.cc" % modname), "wt")
   344     helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
   345     helper_cc.close()
   346 
   347     helper_h = file(os.path.join(moduledir, "helper", "%s-helper.h" % modname), "wt")
   348     helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD="__%s_HELPER_H__" % (modname.upper()),))
   349     helper_h.close()
   350 
   351     #
   352     # examples
   353     #
   354     examplesdir = os.path.join(moduledir, "examples")
   355     os.mkdir(examplesdir)
   356 
   357     examples_wscript = file(os.path.join(examplesdir, "wscript"), "wt")
   358     examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
   359     examples_wscript.close()
   360 
   361     example_cc = file(os.path.join(moduledir, "examples", "%s-example.cc" % modname), "wt")
   362     example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
   363     example_cc.close()
   364 
   365     #
   366     # doc
   367     # 
   368     docdir = os.path.join(moduledir, "doc")
   369     os.mkdir(docdir)
   370 
   371     doc_rst = file(os.path.join(moduledir, "doc", "%s.rst" % modname), "wt")
   372     doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
   373     doc_rst.close()
   374 
   375 
   376     return 0
   377 
   378 if __name__ == '__main__':
   379     sys.exit(main(sys.argv))