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.new_task_gen(features=['ns3header'])
28 headers.module = %(MODULE)r
31 'helper/%(MODULE)s-helper.h',
34 if bld.env.ENABLE_EXAMPLES:
35 bld.add_subdirs('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 AddTestCase (new %(CAPITALIZED)sTestCase1);
207 // Do not forget to allocate an instance of this TestSuite
208 static %(CAPITALIZED)sTestSuite %(MODULE)sTestSuite;
213 DOC_RST_TEMPLATE = '''Example Module Documentation
214 ----------------------------
216 .. heading hierarchy:
217 ------------- Chapter
218 ************* Section (#.#)
219 ============= Subsection (#.#.#)
220 ############# Paragraph (no number)
222 This is a suggested outline for adding new module documentation to ns-3.
223 See ``src/click/doc/click.rst`` for an example.
225 The introductory paragraph is for describing what this code is trying to
231 The source code for the new module lives in the directory ``src/%(MODULE)s``.
236 Add here an overall description of the software design and how it fits
237 into the existing ns-3 architecture.
239 Scope and Limitations
240 =====================
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.
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.
254 This section is principally concerned with the usage of your model, using
260 Include this section if there are special build instructions.
265 What helper API will users typically use? Describe it here.
270 Go into further details (such as using the API outside of the helpers)
271 in additional sections, as needed.
276 What examples using this new code are available? Describe them here.
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.
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()
296 assert os.path.sep not in modname
298 moduledir = os.path.join(os.path.dirname(__file__), modname)
300 if os.path.exists(moduledir):
301 print >> sys.stderr, "Module %r already exists" % (modname,)
305 wscript = file(os.path.join(moduledir, "wscript"), "wt")
306 wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
313 modeldir = os.path.join(moduledir, "model")
316 model_cc = file(os.path.join(moduledir, "model", "%s.cc" % modname), "wt")
317 model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
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()),))
329 testdir = os.path.join(moduledir, "test")
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()))
340 helperdir = os.path.join(moduledir, "helper")
343 helper_cc = file(os.path.join(moduledir, "helper", "%s-helper.cc" % modname), "wt")
344 helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
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()),))
354 examplesdir = os.path.join(moduledir, "examples")
355 os.mkdir(examplesdir)
357 examples_wscript = file(os.path.join(examplesdir, "wscript"), "wt")
358 examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
359 examples_wscript.close()
361 example_cc = file(os.path.join(moduledir, "examples", "%s-example.cc" % modname), "wt")
362 example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
368 docdir = os.path.join(moduledir, "doc")
371 doc_rst = file(os.path.join(moduledir, "doc", "%s.rst" % modname), "wt")
372 doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
378 if __name__ == '__main__':
379 sys.exit(main(sys.argv))