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


openrtm_aist
Author(s): Noriaki Ando
autogenerated on Thu Jun 6 2019 19:25:58