Don't python-bind the class NscTcpL4Protocol, it is implementation detail.
6 import pybindgen.settings
7 from pybindgen.gccxmlparser import ModuleParser, PygenClassifier, PygenSection, WrapperWarning
8 from pybindgen.typehandlers.codesink import FileCodeSink
9 from pygccxml.declarations import templates
10 from pygccxml.declarations.class_declaration import class_t
11 from pygccxml.declarations.calldef import free_function_t, member_function_t, constructor_t
14 ## we need the smart pointer type transformation to be active even
15 ## during gccxml scanning.
16 import ns3modulegen_core_customizations
19 ## silence gccxmlparser errors; we only want error handling in the
20 ## generated python script, not while scanning.
21 class ErrorHandler(pybindgen.settings.ErrorHandler):
22 def handle_error(self, dummy_wrapper, dummy_exception, dummy_traceback_):
24 pybindgen.settings.error_handler = ErrorHandler()
26 warnings.filterwarnings(category=WrapperWarning, action='ignore')
29 '::ns3::RefCountBase': {
30 'incref_method': 'Ref',
31 'decref_method': 'Unref',
32 'peekref_method': 'GetReferenceCount',
33 'automatic_type_narrowing': 'true',
36 'incref_method': 'Ref',
37 'decref_method': 'Unref',
38 'peekref_method': 'GetReferenceCount',
39 'automatic_type_narrowing': 'true',
42 'incref_method': 'Ref',
43 'decref_method': 'Unref',
44 'peekref_method': 'GetReferenceCount',
46 '::ns3::CallbackImplBase': {
47 'incref_method': 'Ref',
48 'decref_method': 'Unref',
49 'peekref_method': 'GetReferenceCount',
51 '::ns3::AttributeChecker': {
52 'automatic_type_narrowing': 'true',
53 'allow_subclassing': 'false',
55 '::ns3::AttributeValue': {
56 'automatic_type_narrowing': 'true',
57 'allow_subclassing': 'false',
60 '::ns3::CommandLine': {
61 'allow_subclassing': 'true', # needed so that AddValue is able to set attributes on the object
64 '::ns3::NscTcpL4Protocol': {
65 'ignore': 'true', # this class is implementation detail
69 'ns3::RandomVariable::RandomVariable(ns3::RandomVariableBase const & variable) [constructor]': {
72 'ns3::RandomVariableBase * ns3::RandomVariable::Peek() const [member function]': {
75 'void ns3::RandomVariable::GetSeed(uint32_t * seed) const [member function]': {
76 'params': {'seed':{'direction':'out',
79 'bool ns3::TypeId::LookupAttributeByName(std::string name, ns3::TypeId::AttributeInfo * info) const [member function]': {
80 'params': {'info':{'transfer_ownership': 'false'}}
82 'static bool ns3::TypeId::LookupByNameFailSafe(std::string name, ns3::TypeId * tid) [member function]': {
83 'ignore': None, # manually wrapped in
85 'bool ns3::TraceSourceAccessor::ConnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
86 'params': {'obj': {'transfer_ownership':'false'}}
88 'bool ns3::TraceSourceAccessor::Connect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
89 'params': {'obj': {'transfer_ownership':'false'}}
91 'bool ns3::TraceSourceAccessor::DisconnectWithoutContext(ns3::ObjectBase * obj, ns3::CallbackBase const & cb) const [member function]': {
92 'params': {'obj': {'transfer_ownership':'false'}}
94 'bool ns3::TraceSourceAccessor::Disconnect(ns3::ObjectBase * obj, std::string context, ns3::CallbackBase const & cb) const [member function]': {
95 'params': {'obj': {'transfer_ownership':'false'}}
97 'bool ns3::AttributeAccessor::Set(ns3::ObjectBase * object, ns3::AttributeValue const & value) const [member function]': {
98 'params': {'object': {'transfer_ownership':'false'}}
100 'ns3::EmpiricalVariable::EmpiricalVariable(ns3::RandomVariableBase const & variable) [constructor]': {
103 'static ns3::AttributeList * ns3::AttributeList::GetGlobal() [member function]': {
104 'caller_owns_return': 'false'
106 'void ns3::CommandLine::Parse(int argc, char * * argv) const [member function]': {
107 'ignore': None # manually wrapped
109 'extern void ns3::PythonCompleteConstruct(ns3::Ptr<ns3::Object> object, ns3::TypeId typeId, ns3::AttributeList const & attributes) [free function]': {
110 'ignore': None # used transparently by, should not be wrapped
114 def get_ns3_relative_path(path):
118 head, tail = os.path.split(head)
120 return os.path.join(*l)
122 raise AssertionError("is the path %r inside ns3?!" % path)
125 def pre_scan_hook(dummy_module_parser,
128 parameter_annotations):
129 ns3_header = get_ns3_relative_path(pygccxml_definition.location.file_name)
131 ## Note: we don't include line numbers in the comments because
132 ## those numbers are very likely to change frequently, which would
133 ## cause needless changes, since the generated python files are
134 ## kept under version control.
136 #global_annotations['pygen_comment'] = "%s:%i: %s" % \
137 # (ns3_header, pygccxml_definition.location.line, pygccxml_definition)
138 global_annotations['pygen_comment'] = "%s: %s" % \
139 (ns3_header, pygccxml_definition)
142 ## handle ns3::Object::GetObject (left to its own devices,
143 ## pybindgen will generate a mangled name containing the template
144 ## argument type name).
145 if isinstance(pygccxml_definition, member_function_t) \
146 and pygccxml_definition.parent.name == 'Object' \
147 and pygccxml_definition.name == 'GetObject':
148 template_args = templates.args(pygccxml_definition.demangled_name)
149 if template_args == ['ns3::Object']:
150 global_annotations['template_instance_names'] = 'ns3::Object=>GetObject'
152 ## Don't wrap Simulator::Schedule* (manually wrapped)
153 if isinstance(pygccxml_definition, member_function_t) \
154 and pygccxml_definition.parent.name == 'Simulator' \
155 and pygccxml_definition.name.startswith('Schedule'):
156 global_annotations['ignore'] = None
159 if isinstance(pygccxml_definition, member_function_t) \
160 and pygccxml_definition.parent.name == 'Simulator' \
161 and pygccxml_definition.name == 'Run':
162 global_annotations['ignore'] = True
166 if isinstance(pygccxml_definition, class_t):
167 # no need for helper classes to allow subclassing in Python, I think...
168 if pygccxml_definition.name.endswith('Helper'):
169 global_annotations['allow_subclassing'] = 'false'
171 if pygccxml_definition.decl_string.startswith('::ns3::Callback<'):
172 # manually handled in ns3modulegen_core_customizations.py
173 global_annotations['ignore'] = None
176 if pygccxml_definition.decl_string.startswith('::ns3::TracedCallback<'):
177 global_annotations['ignore'] = None
180 if pygccxml_definition.decl_string.startswith('::ns3::Ptr<'):
181 # handled by pybindgen "type transformation"
182 global_annotations['ignore'] = None
185 # table driven class customization
187 annotations = type_annotations[pygccxml_definition.decl_string]
191 global_annotations.update(annotations)
194 if isinstance(pygccxml_definition, free_function_t):
195 if pygccxml_definition.name == 'PeekPointer':
196 global_annotations['ignore'] = None
199 ## table driven methods/constructors/functions customization
200 if isinstance(pygccxml_definition, (free_function_t, member_function_t, constructor_t)):
202 annotations = type_annotations[str(pygccxml_definition)]
206 for key,value in annotations.items():
208 parameter_annotations.update (value)
209 del annotations['params']
210 global_annotations.update(annotations)
213 # def post_scan_hook(dummy_module_parser, dummy_pygccxml_definition, pybindgen_wrapper):
215 # if isinstance(pybindgen_wrapper, CppClass):
216 # if pybindgen_wrapper.name.endswith('Checker'):
217 # print >> sys.stderr, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", pybindgen_wrapper
218 # #pybindgen_wrapper.set_instance_creation_function(AttributeChecker_instance_creation_function)
221 def scan_callback_classes(module_parser, callback_classes_file):
222 callback_classes_file.write("callback_classes = [\n")
223 for cls in module_parser.module_namespace.classes(function=module_parser.location_filter,
225 if not cls.name.startswith("Callback<"):
227 assert templates.is_instantiation(cls.decl_string), "%s is not a template instantiation" % cls
228 dummy_cls_name, template_parameters = templates.split(cls.decl_string)
229 callback_classes_file.write(" %r,\n" % template_parameters)
230 callback_classes_file.write("]\n")
233 class MyPygenClassifier(PygenClassifier):
234 def __init__(self, headers_map):
235 self.headers_map = headers_map
237 def classify(self, pygccxml_definition):
238 name = os.path.basename(pygccxml_definition.location.file_name)
240 return self.headers_map[name]
245 def ns3_module_scan(top_builddir, pygen_file_name, everything_h):
247 ns3_modules = eval(sys.stdin.read())
249 ## do a topological sort on the modules graph
250 from topsort import topsort
252 for ns3_module_name, (ns3_module_deps, dummy) in ns3_modules.iteritems():
253 for dep in ns3_module_deps:
254 graph.append((dep, ns3_module_name))
255 sorted_ns3_modules = topsort(graph)
256 #print >> sys.stderr, "******* topological sort: ", sorted_ns3_modules
258 sections = [PygenSection('__main__', FileCodeSink(open(pygen_file_name, "wt")))]
259 headers_map = {} # header_name -> section_name
260 for ns3_module in sorted_ns3_modules:
261 section_name = "ns3_module_%s" % ns3_module.replace('-', '_')
262 file_name = os.path.join(os.path.dirname(pygen_file_name), "%s.py" % section_name)
263 sections.append(PygenSection(section_name, FileCodeSink(open(file_name, "wt")),
264 section_name + "__local"))
265 for header in ns3_modules[ns3_module][1]:
266 headers_map[header] = section_name
268 module_parser = ModuleParser('ns3', 'ns3')
270 module_parser.add_pre_scan_hook(pre_scan_hook)
271 #module_parser.add_post_scan_hook(post_scan_hook)
273 gccxml_options = dict(
274 include_paths=[top_builddir],
276 #'NS3_ASSERT_ENABLE': None,
277 #'NS3_LOG_ENABLE': None,
281 module_parser.parse_init([everything_h],
282 None, whitelist_paths=[top_builddir, os.path.dirname(everything_h)],
283 #includes=['"ns3/everything.h"'],
285 pygen_classifier=MyPygenClassifier(headers_map),
286 gccxml_options=gccxml_options)
287 module_parser.scan_types()
289 callback_classes_file = open(os.path.join(os.path.dirname(pygen_file_name), "callbacks_list.py"), "wt")
290 scan_callback_classes(module_parser, callback_classes_file)
291 callback_classes_file.close()
294 module_parser.scan_methods()
295 module_parser.scan_functions()
296 module_parser.parse_finalize()
298 for section in sections:
299 section.code_sink.file.close()
303 if __name__ == '__main__':
304 ns3_module_scan(sys.argv[1], sys.argv[3], sys.argv[2])