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" % (modname,)
337 wscript = file(os.path.join(moduledir,
"wscript"),
"wt")
338 wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
345 modeldir = os.path.join(moduledir,
"model")
348 model_cc = file(os.path.join(moduledir,
"model",
"%s.cc" % modname),
"wt")
349 model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
352 model_h = file(os.path.join(moduledir,
"model",
"%s.h" % modname),
"wt")
353 model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_H" % (modname.replace(
"-",
"_").upper()),))
361 testdir = os.path.join(moduledir,
"test")
363 test_cc = file(os.path.join(moduledir,
"test",
"%s-test-suite.cc" % modname),
"wt")
364 test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,
365 CAPITALIZED=
''.join([word.capitalize()
for word
in modname.split(
'-')]),
366 COMPOUND=
''.join([modname.split(
'-')[0]] + [word.capitalize()
for word
in modname.split(
'-')[1:]]),
375 helperdir = os.path.join(moduledir,
"helper")
378 helper_cc = file(os.path.join(moduledir,
"helper",
"%s-helper.cc" % modname),
"wt")
379 helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
382 helper_h = file(os.path.join(moduledir,
"helper",
"%s-helper.h" % modname),
"wt")
383 helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_HELPER_H" % (modname.replace(
"-",
"_").upper()),))
389 examplesdir = os.path.join(moduledir,
"examples")
390 os.mkdir(examplesdir)
392 examples_wscript = file(os.path.join(examplesdir,
"wscript"),
"wt")
393 examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
394 examples_wscript.close()
396 example_cc = file(os.path.join(moduledir,
"examples",
"%s-example.cc" % modname),
"wt")
397 example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
403 docdir = os.path.join(moduledir,
"doc")
406 doc_rst = file(os.path.join(moduledir,
"doc",
"%s.rst" % modname),
"wt")
407 doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
413 if __name__ ==
'__main__':
414 sys.exit(
main(sys.argv))