cxx_svc_impl.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 # -*- python -*-
3 #
4 # @file cxx_svc_impl.py
5 # @brief rtc-template C++ service source code generator class
6 # @date $Date: 2007/02/07 02:51:49 $
7 # @author Noriaki Ando <n-ando@aist.go.jp>
8 #
9 # Copyright (C) 2005-2007
10 # Task-intelligence Research Group,
11 # Intelligent Systems Research Institute,
12 # National Institute of
13 # Advanced Industrial Science and Technology (AIST), Japan
14 # All rights reserved.
15 #
16 # $Id: cxx_svc_impl.py,v 1.4 2007/02/07 02:51:49 n-ando Exp $
17 #
18 
19 #
20 # $Log: cxx_svc_impl.py,v $
21 # Revision 1.4 2007/02/07 02:51:49 n-ando
22 # RCS Id tag was removed from template source code.
23 #
24 # Revision 1.3 2007/01/11 07:44:39 n-ando
25 # Now service implementation class does not inherit RtcServiceBase.
26 # The implementation template was changed.
27 #
28 # Revision 1.2 2005/09/06 14:37:18 n-ando
29 # rtc-template's command options and data structure for ezt (Easy Template)
30 # are changed for RTComponent's service features.
31 # Now rtc-template can generate services' skeletons, stubs and
32 # implementation files.
33 # The implementation code generation uses omniidl's IDL parser.
34 #
35 # Revision 1.1 2005/08/29 17:50:57 n-ando
36 # The first version.
37 #
38 #
39 
40 import string
41 import os
42 
43 # omniidl modules
44 import _omniidl
45 from omniidl import idlast, idlvisitor
46 from omniidl_be.cxx import ast, util, id, types, output
47 
48 # import myself
49 import cxx_svc_impl
50 self = cxx_svc_impl
51 
52 
53 #------------------------------------------------------------
54 # Example code
55 #------------------------------------------------------------
56 interface_def = """\
57 /*
58  * Example class implementing IDL interface @fq_name@
59  */
60 class @impl_fqname@
61  : public virtual @fq_POA_name@,
62  public virtual PortableServer::RefCountServantBase
63 {
64  private:
65  // Make sure all instances are built on the heap by making the
66  // destructor non-public
67  //virtual ~@impl_name@();
68 
69  public:
70  // standard constructor
71  @impl_name@();
72  virtual ~@impl_name@();
73 
74  // attributes and operations
75  @operations@
76 };
77 """
78 
79 interface_code = """\
80 /*
81  * Example implementational code for IDL interface @fqname@
82  */
83 @impl_fqname@::@impl_name@()
84 {
85  // Please add extra constructor code here.
86 }
87 
88 
89 @impl_fqname@::~@impl_name@()
90 {
91  // Please add extra destructor code here.
92 }
93 
94 
95 /*
96  * Methods corresponding to IDL attributes and operations
97  */
98 @operations@
99 
100 // End of example implementational code
101 """
102 
103 class_h = """\
104 // -*-C++-*-
105 /*!
106  * @atmark@file @impl_h@
107  * @atmark@brief Service implementation header of @file@
108  *
109  */
110 
111 #include "@skel_h@"
112 
113 
114 #ifndef @include_guard@
115 #define @include_guard@
116 
117 @interfaces@
118 
119 #endif // @include_guard@
120 
121 """
122 
123 class_cpp = """\
124 // -*-C++-*-
125 /*!
126  * @atmark@file @impl_cpp@
127  * @atmark@brief Service implementation code of @file@
128  *
129  */
130 
131 #include "@impl_h@"
132 
133 @interfaces@
134 """
135 
136 def generate(idl_file, preproc_args, impl_suffix, skel_suffix = "Skel", fd_h=None, fd_cpp=None):
137  basename = idl_file.replace(".idl","")
138  preprocessor_cmd = "omnicpp"
139  preprocessor_opt = "-I" + string.join(preproc_args, " -I")
140 
141  preproc_cmd = '%s %s %s' % (preprocessor_cmd,\
142  preprocessor_opt, idl_file)
143 
144  file = os.popen(preproc_cmd, "r")
145 
146  skel_filename = basename + skel_suffix + ".h"
147  idl_filename = idl_file
148 
149  # ignore the following operations
150  ignore_operations = ["profile"]
151 
152  tree = _omniidl.compile(file)
153  ast.__init__(tree)
154 
155  cxx_svc_impl.__init__(idl_filename, \
156  basename, \
157  skel_filename, \
158  impl_suffix, \
159  ignore_operations, \
160  fd_h, \
161  fd_cpp)
162  ifs = cxx_svc_impl.run(tree)
163  file.close()
164  _omniidl.clear()
165  return ifs
166 
167 
168 #============================================================
169 # This module's __init__()
170 #============================================================
171 def __init__(idl_filename, impl_basename, skel_filename, \
172  suffix = "_impl", ignore_op = [], fd_h = None, fd_cpp = None):
173  self.idl_filename = idl_filename
174  self.suffix = suffix
175  self.impl_h_filename = impl_basename + self.suffix + ".h"
176  self.impl_cpp_filename = impl_basename + self.suffix + ".cpp"
177  self.skel_filename = skel_filename
178  self.ignore_op = ignore_op
179 
180  self.include_guard = self.impl_h_filename.upper().replace(".","_")
181 
182  if fd_h == None:
183  self.stream_h = \
184  output.Stream(output.createFile(self.impl_h_filename), 2)
185  else:
186  self.stream_h = output.Stream(fd_h, 2)
187 
188  if fd_cpp == None:
189  self.stream_cpp = \
190  output.Stream(output.createFile(self.impl_cpp_filename), 2)
191  else:
192  self.stream_cpp = output.Stream(fd_cpp, 2)
193 
194 
195 
196 # Given an IDL name convert it into the fully qualified name of the
197 # implementation class
198 def impl_fullname(name):
199  bits = name.suffix(self.suffix).fullName()
200  return string.join(bits, "_")
201 
202 # Convert an IDL name into the simple name of the implementation class
203 def impl_simplename(name):
204  return impl_fullname(name)
205 
206 #
207 # Main code entrypoint
208 #
209 def run(tree):
210  # The implementation template code stream
211  impl_cpp = output.StringStream()
212  # The implementation template header stream
213  impl_h = output.StringStream()
214  bii = BuildInterfaceImplementations(impl_h, impl_cpp, self.ignore_op)
215  tree.accept(bii)
216 
217  # Generate mplementation class template header
218  stream_h.out(class_h,
219  atmark = "@",
220  impl_h = self.impl_h_filename,
221  include_guard = self.include_guard,
222  skel_h = self.skel_filename,
223  file = self.idl_filename,
224  interfaces = str(impl_h))
225 
226  # Generate implementation class template code
227  stream_cpp.out(class_cpp,
228  atmark = "@",
229  impl_cpp = self.impl_cpp_filename,
230  impl_h = self.impl_h_filename,
231  file = self.idl_filename,
232  interfaces = str(impl_cpp))
233 
234  self.ifs = []
235  for n in bii.allInterfaces():
236  self.ifs.append(string.join(n.scopedName(), "_") + self.suffix)
237  return self.ifs
238 
239 
240 
241 
242 #============================================================
243 # Build the interface implementations
244 #============================================================
245 class BuildInterfaceImplementations(idlvisitor.AstVisitor):
246 
247  def __init__(self, stream_h, stream_cpp, ignore_operations):
248  self.stream_h = stream_h
249  self.stream_cpp = stream_cpp
250  self.ignore_operations = ignore_operations
251  # keep track of all interfaces for later use
252  self.__allInterfaces = []
253 
254  # Returns the list of all present interfaces (each one will be
255  # implemented)
256  def allInterfaces(self):
257  return self.__allInterfaces[:]
258 
259  # Tree walking code
260  def visitAST(self, node):
261  for n in node.declarations():
262  if ast.shouldGenerateCodeForDecl(n):
263  n.accept(self)
264 
265  # modules can contain interfaces
266  def visitModule(self, node):
267  for n in node.definitions():
268  n.accept(self)
269 
270  # interfaces cannot be further nested
271  def visitInterface(self, node):
272  self.__allInterfaces.append(node)
273 
274  scopedName = id.Name(node.scopedName())
275 
276  cxx_fqname = scopedName.fullyQualify()
277  impl_flat_name = impl_fullname(scopedName)
278 
279  fqname = scopedName.fullyQualify(cxx = 0)
280 
281 
282  # build methods corresponding to attributes, operations etc.
283  # attributes[] and operations[] will contain lists of function
284  # signatures eg
285  # [ char *echoString(const char *mesg) ]
286  attributes = []
287  operations = []
288  virtual_operations = []
289 
290  # we need to consider all callables, including inherited ones
291  # since this implementation class is not inheriting from anywhere
292  # other than the IDL skeleton
293  allInterfaces = [node] + ast.allInherits(node)
294  allCallables = util.fold( map(lambda x:x.callables(), allInterfaces),
295  [], lambda x, y: x + y )
296 
297 
298  # declarations[] contains a list of in-class decl signatures
299  # implementations[] contains a list of out of line impl signatures
300  # (typically differ by classname::)
301  declarations = []
302  implementations = []
303 
304  for c in allCallables:
305 
306  if isinstance(c, idlast.Attribute) :
307  attrType = types.Type(c.attrType())
308  d_attrType = attrType.deref()
309 
310  for i in c.identifiers():
311  attribname = id.mapID(i)
312  returnType = attrType.op(types.RET)
313  inType = attrType.op(types.IN)
314  attributes.append(returnType + " " + attribname + "()")
315  # need a set method if not a readonly attribute
316  if not c.readonly():
317  args = attribname + "(" + inType + ")"
318  declarations.append("void " + args)
319  implementations.append("void " + impl_flat_name +\
320  "::" + args)
321  if not attribname in self.ignore_operations:
322  declarations.append(returnType + " " + attribname + "()")
323  implementations.append(returnType + " " + impl_flat_name+\
324  "::" + attribname + "()")
325  elif isinstance(c, idlast.Operation):
326  params = []
327  for p in c.parameters():
328  paramType = types.Type(p.paramType())
329  cxx_type = paramType.op(types.direction(p), use_out = 0)
330 
331  argname = id.mapID(p.identifier())
332  params.append(cxx_type + " " + argname)
333 
334  # deal with possible "context"
335  if c.contexts() != []:
336  params.append("CORBA::Context_ptr _ctxt")
337 
338  return_type = types.Type(c.returnType()).op(types.RET)
339 
340  opname = id.mapID(c.identifier())
341  if not opname in self.ignore_operations:
342  arguments = string.join(params, ", ")
343  args = opname + "(" + arguments + ")"
344  declarations.append(return_type + " " + args)
345  implementations.append(return_type + " " + \
346  impl_flat_name + \
347  "::" + args)
348  else:
349  util.fatalError("Internal error generating interface member")
350  raise "No code for interface member: " + repr(c)
351 
352  # the class definition has no actual code...
353  defs = string.join(map(lambda x:x + ";\n", declarations), "")
354 
355  # Output the class definition of the implementation
356  self.stream_h.out(interface_def,
357  impl_fqname = impl_flat_name,
358  impl_name = impl_flat_name,
359  fq_name = fqname,
360  fq_POA_name = "POA_" + cxx_fqname,
361  operations = defs)
362 
363  # Output the class methods implementations
364  impls = string.join(map(lambda x: x + """\
365 
366 {
367  // Please insert your code here and remove the following warning pragma
368  #warning "Code missing in function <""" + x + """>"
369 }
370 
371 """,
372  implementations), "")
373 
374  self.stream_cpp.out(interface_code,
375  fqname = fqname,
376  impl_name = impl_flat_name,
377  impl_fqname = impl_flat_name,
378  operations = impls)
379 
380 
381 if __name__ == "__main__":
382  import cxx_svc_impl
383  import sys
384  print "Interfaces:"
385  print cxx_svc_impl.generate(sys.argv[1], "SVC_impl")
def __init__(self, stream_h, stream_cpp, ignore_operations)
def generate(idl_file, preproc_args, impl_suffix, skel_suffix="Skel", fd_h=None, fd_cpp=None)
def __init__(idl_filename, impl_basename, skel_filename, suffix="_impl", ignore_op=[], fd_h=None, fd_cpp=None)
def append(dest, src)
Definition: NVUtil.py:386


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Mon Feb 28 2022 23:01:06