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``.
233 Add here a basic description of what is being modeled.
238 Briefly describe the software design of the model and how it fits into
239 the existing ns-3 architecture.
241 Scope and Limitations
242 =====================
244 What can the model do? What can it not do? Please use this section to
245 describe the scope and limitations of the model.
250 Add academic citations here, such as if you published a paper on this
251 model, or if readers should read a particular specification or other work.
256 This section is principally concerned with the usage of your model, using
257 the public API. Focus first on most common usage patterns, then go
258 into more advanced topics.
263 Include this subsection only if there are special build instructions or
264 platform limitations.
269 What helper API will users typically use? Describe it here.
274 What classes hold attributes, and what are the key ones worth mentioning?
279 What kind of data does the model generate? What are the key trace
280 sources? What kind of logging output can be enabled?
285 Go into further details (such as using the API outside of the helpers)
286 in additional sections, as needed.
291 What examples using this new code are available? Describe them here.
296 Add any tips for avoiding pitfalls, etc.
301 Describe how the model has been tested/validated. What tests run in the
302 test suite? How much API and code is covered by the tests? Again,
303 references to outside published work may help here.
308 parser = OptionParser(usage=(
"Usage: %prog [options] modulename\n"
309 "Utility script to create a basic template for a new ns-3 module"))
310 (options, args) = parser.parse_args()
316 assert os.path.sep
not in modname
318 moduledir = os.path.join(os.path.dirname(__file__), modname)
320 if os.path.exists(moduledir):
321 print >> sys.stderr,
"Module %r already exists" % (modname,)
325 wscript = file(os.path.join(moduledir,
"wscript"),
"wt")
326 wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
333 modeldir = os.path.join(moduledir,
"model")
336 model_cc = file(os.path.join(moduledir,
"model",
"%s.cc" % modname),
"wt")
337 model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
340 model_h = file(os.path.join(moduledir,
"model",
"%s.h" % modname),
"wt")
341 model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"__%s_H__" % (modname.upper()),))
349 testdir = os.path.join(moduledir,
"test")
351 test_cc = file(os.path.join(moduledir,
"test",
"%s-test-suite.cc" % modname),
"wt")
352 test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,CAPITALIZED=modname.capitalize()))
360 helperdir = os.path.join(moduledir,
"helper")
363 helper_cc = file(os.path.join(moduledir,
"helper",
"%s-helper.cc" % modname),
"wt")
364 helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
367 helper_h = file(os.path.join(moduledir,
"helper",
"%s-helper.h" % modname),
"wt")
368 helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"__%s_HELPER_H__" % (modname.upper()),))
374 examplesdir = os.path.join(moduledir,
"examples")
375 os.mkdir(examplesdir)
377 examples_wscript = file(os.path.join(examplesdir,
"wscript"),
"wt")
378 examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
379 examples_wscript.close()
381 example_cc = file(os.path.join(moduledir,
"examples",
"%s-example.cc" % modname),
"wt")
382 example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
388 docdir = os.path.join(moduledir,
"doc")
391 doc_rst = file(os.path.join(moduledir,
"doc",
"%s.rst" % modname),
"wt")
392 doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
398 if __name__ ==
'__main__':
399 sys.exit(
main(sys.argv))