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
220 .. heading hierarchy:
221 ------------- Chapter
222 ************* Section (#.#)
223 ============= Subsection (#.#.#)
224 ############# Paragraph (no number)
226 This is a suggested outline for adding new module documentation to |ns3|.
227 See ``src/click/doc/click.rst`` for an example.
229 The introductory paragraph is for describing what this code is trying to
232 For consistency (italicized formatting), please use |ns3| to refer to
233 ns-3 in the documentation (and likewise, |ns2| for ns-2). These macros
234 are defined in the file ``replace.txt``.
239 The source code for the new module lives in the directory ``src/%(MODULE)s``.
241 Add here a basic description of what is being modeled.
246 Briefly describe the software design of the model and how it fits into
247 the existing ns-3 architecture.
249 Scope and Limitations
250 =====================
252 What can the model do? What can it not do? Please use this section to
253 describe the scope and limitations of the model.
258 Add academic citations here, such as if you published a paper on this
259 model, or if readers should read a particular specification or other work.
264 This section is principally concerned with the usage of your model, using
265 the public API. Focus first on most common usage patterns, then go
266 into more advanced topics.
271 Include this subsection only if there are special build instructions or
272 platform limitations.
277 What helper API will users typically use? Describe it here.
282 What classes hold attributes, and what are the key ones worth mentioning?
287 What kind of data does the model generate? What are the key trace
288 sources? What kind of logging output can be enabled?
293 Go into further details (such as using the API outside of the helpers)
294 in additional sections, as needed.
299 What examples using this new code are available? Describe them here.
304 Add any tips for avoiding pitfalls, etc.
309 Describe how the model has been tested/validated. What tests run in the
310 test suite? How much API and code is covered by the tests? Again,
311 references to outside published work may help here.
316 parser = OptionParser(usage=(
"Usage: %prog [options] modulename\n"
317 "Utility script to create a basic template for a new ns-3 module"))
318 (options, args) = parser.parse_args()
323 modname = args[0].lower()
324 if False in [word.isalnum()
for word
in modname.split(
"-")]:
325 print >> sys.stderr,
"Module name should only contain alphanumeric characters and dashes"
327 assert os.path.sep
not in modname
329 moduledir = os.path.join(os.path.dirname(__file__), modname)
331 if os.path.exists(moduledir):
332 print >> sys.stderr,
"Module %r already exists" % (modname,)
335 print(
"Creating module %r, "
336 "run './waf configure' to include it in the build" % (modname,))
339 wscript = file(os.path.join(moduledir,
"wscript"),
"wt")
340 wscript.write(WSCRIPT_TEMPLATE % dict(MODULE=modname))
347 modeldir = os.path.join(moduledir,
"model")
350 model_cc = file(os.path.join(moduledir,
"model",
"%s.cc" % modname),
"wt")
351 model_cc.write(MODEL_CC_TEMPLATE % dict(MODULE=modname))
354 model_h = file(os.path.join(moduledir,
"model",
"%s.h" % modname),
"wt")
355 model_h.write(MODEL_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_H" % (modname.replace(
"-",
"_").upper()),))
363 testdir = os.path.join(moduledir,
"test")
365 test_cc = file(os.path.join(moduledir,
"test",
"%s-test-suite.cc" % modname),
"wt")
366 test_cc.write(TEST_CC_TEMPLATE % dict(MODULE=modname,
367 CAPITALIZED=
''.join([word.capitalize()
for word
in modname.split(
'-')]),
368 COMPOUND=
''.join([modname.split(
'-')[0]] + [word.capitalize()
for word
in modname.split(
'-')[1:]]),
377 helperdir = os.path.join(moduledir,
"helper")
380 helper_cc = file(os.path.join(moduledir,
"helper",
"%s-helper.cc" % modname),
"wt")
381 helper_cc.write(HELPER_CC_TEMPLATE % dict(MODULE=modname))
384 helper_h = file(os.path.join(moduledir,
"helper",
"%s-helper.h" % modname),
"wt")
385 helper_h.write(HELPER_H_TEMPLATE % dict(MODULE=modname, INCLUDE_GUARD=
"%s_HELPER_H" % (modname.replace(
"-",
"_").upper()),))
391 examplesdir = os.path.join(moduledir,
"examples")
392 os.mkdir(examplesdir)
394 examples_wscript = file(os.path.join(examplesdir,
"wscript"),
"wt")
395 examples_wscript.write(EXAMPLES_WSCRIPT_TEMPLATE % dict(MODULE=modname))
396 examples_wscript.close()
398 example_cc = file(os.path.join(moduledir,
"examples",
"%s-example.cc" % modname),
"wt")
399 example_cc.write(EXAMPLE_CC_TEMPLATE % dict(MODULE=modname))
405 docdir = os.path.join(moduledir,
"doc")
408 doc_rst = file(os.path.join(moduledir,
"doc",
"%s.rst" % modname),
"wt")
409 doc_rst.write(DOC_RST_TEMPLATE % dict(MODULE=modname))
415 if __name__ ==
'__main__':
416 sys.exit(
main(sys.argv))