cxx_svc_impl.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # -*- python -*-
00003 #
00004 #  @file cxx_svc_impl.py
00005 #  @brief rtc-template C++ service source code generator class
00006 #  @date $Date: 2007/02/07 02:51:49 $
00007 #  @author Noriaki Ando <n-ando@aist.go.jp>
00008 # 
00009 #  Copyright (C) 2005-2007
00010 #      Task-intelligence Research Group,
00011 #      Intelligent Systems Research Institute,
00012 #      National Institute of
00013 #          Advanced Industrial Science and Technology (AIST), Japan
00014 #      All rights reserved.
00015 # 
00016 #  $Id: cxx_svc_impl.py,v 1.4 2007/02/07 02:51:49 n-ando Exp $
00017 # 
00018 
00019 #
00020 # $Log: cxx_svc_impl.py,v $
00021 # Revision 1.4  2007/02/07 02:51:49  n-ando
00022 # RCS Id tag was removed from template source code.
00023 #
00024 # Revision 1.3  2007/01/11 07:44:39  n-ando
00025 # Now service implementation class does not inherit RtcServiceBase.
00026 # The implementation template was changed.
00027 #
00028 # Revision 1.2  2005/09/06 14:37:18  n-ando
00029 # rtc-template's command options and data structure for ezt (Easy Template)
00030 # are changed for RTComponent's service features.
00031 # Now rtc-template can generate services' skeletons, stubs and
00032 # implementation files.
00033 # The implementation code generation uses omniidl's IDL parser.
00034 #
00035 # Revision 1.1  2005/08/29 17:50:57  n-ando
00036 # The first version.
00037 #
00038 #
00039 
00040 import string
00041 import os
00042 
00043 # omniidl modules
00044 import _omniidl
00045 from omniidl import idlast, idlvisitor
00046 from omniidl_be.cxx import ast, util, id, types, output
00047 
00048 # import myself
00049 import cxx_svc_impl
00050 self = cxx_svc_impl
00051 
00052 
00053 #------------------------------------------------------------
00054 # Example code
00055 #------------------------------------------------------------
00056 interface_def = """\
00057 /*
00058  * Example class implementing IDL interface @fq_name@
00059  */
00060 class @impl_fqname@
00061  : public virtual @fq_POA_name@,
00062    public virtual PortableServer::RefCountServantBase
00063 {
00064  private:
00065    // Make sure all instances are built on the heap by making the
00066    // destructor non-public
00067    //virtual ~@impl_name@();
00068 
00069  public:
00070    // standard constructor
00071    @impl_name@();
00072    virtual ~@impl_name@();
00073 
00074    // attributes and operations
00075    @operations@
00076 };
00077 """
00078 
00079 interface_code = """\
00080 /*
00081  * Example implementational code for IDL interface @fqname@
00082  */
00083 @impl_fqname@::@impl_name@()
00084 {
00085   // Please add extra constructor code here.
00086 }
00087 
00088 
00089 @impl_fqname@::~@impl_name@()
00090 {
00091   // Please add extra destructor code here.
00092 }
00093 
00094 
00095 /*
00096  * Methods corresponding to IDL attributes and operations
00097  */
00098 @operations@
00099 
00100 // End of example implementational code
00101 """
00102 
00103 class_h = """\
00104 // -*-C++-*-
00105 /*!
00106  * @atmark@file  @impl_h@
00107  * @atmark@brief Service implementation header of @file@
00108  *
00109  */
00110 
00111 #include "@skel_h@"
00112 
00113 
00114 #ifndef @include_guard@
00115 #define @include_guard@
00116  
00117 @interfaces@
00118 
00119 #endif // @include_guard@
00120 
00121 """
00122 
00123 class_cpp = """\
00124 // -*-C++-*-
00125 /*!
00126  * @atmark@file  @impl_cpp@
00127  * @atmark@brief Service implementation code of @file@
00128  *
00129  */
00130 
00131 #include "@impl_h@"
00132 
00133 @interfaces@
00134 """
00135 
00136 def generate(idl_file, preproc_args, impl_suffix, skel_suffix = "Skel", fd_h=None, fd_cpp=None):
00137         basename = idl_file.replace(".idl","")
00138         preprocessor_cmd = "omnicpp"
00139         preprocessor_opt = "-I" + string.join(preproc_args, " -I")
00140 
00141         preproc_cmd = '%s %s %s' % (preprocessor_cmd,\
00142                                   preprocessor_opt, idl_file)
00143 
00144         file = os.popen(preproc_cmd, "r")
00145 
00146         skel_filename = basename + skel_suffix + ".h"
00147         idl_filename = idl_file
00148 
00149         # ignore the following operations
00150         ignore_operations = ["profile"]
00151         
00152         tree = _omniidl.compile(file)
00153         ast.__init__(tree)
00154 
00155         cxx_svc_impl.__init__(idl_filename, \
00156                                           basename, \
00157                                           skel_filename, \
00158                                           impl_suffix, \
00159                                           ignore_operations, \
00160                                           fd_h, \
00161                                           fd_cpp)
00162         ifs = cxx_svc_impl.run(tree)
00163         file.close()
00164         _omniidl.clear()
00165         return ifs
00166 
00167 
00168 #============================================================
00169 # This module's __init__()
00170 #============================================================
00171 def __init__(idl_filename, impl_basename, skel_filename, \
00172                 suffix = "_impl", ignore_op = [], fd_h = None, fd_cpp = None):
00173         self.idl_filename = idl_filename
00174         self.suffix = suffix
00175         self.impl_h_filename = impl_basename + self.suffix + ".h"
00176         self.impl_cpp_filename = impl_basename + self.suffix + ".cpp"
00177         self.skel_filename = skel_filename
00178         self.ignore_op = ignore_op
00179 
00180         self.include_guard = self.impl_h_filename.upper().replace(".","_")
00181 
00182         if fd_h == None:
00183                 self.stream_h = \
00184                     output.Stream(output.createFile(self.impl_h_filename), 2)
00185         else:
00186                 self.stream_h = output.Stream(fd_h, 2)
00187                 
00188         if fd_cpp == None:
00189                 self.stream_cpp = \
00190                     output.Stream(output.createFile(self.impl_cpp_filename), 2)
00191         else:
00192                 self.stream_cpp = output.Stream(fd_cpp, 2)
00193                 
00194         
00195 
00196 # Given an IDL name convert it into the fully qualified name of the
00197 # implementation class
00198 def impl_fullname(name):
00199     bits = name.suffix(self.suffix).fullName()
00200     return string.join(bits, "_")
00201 
00202 # Convert an IDL name into the simple name of the implementation class
00203 def impl_simplename(name):
00204     return impl_fullname(name)
00205 
00206 #
00207 # Main code entrypoint
00208 #
00209 def run(tree):
00210         # The implementation template code stream
00211         impl_cpp = output.StringStream()
00212         # The implementation template header stream
00213         impl_h   = output.StringStream()
00214         bii = BuildInterfaceImplementations(impl_h, impl_cpp, self.ignore_op)
00215         tree.accept(bii)
00216 
00217         # Generate mplementation class template header
00218         stream_h.out(class_h,
00219                                  atmark = "@",
00220                                  impl_h = self.impl_h_filename,
00221                                  include_guard = self.include_guard,
00222                                  skel_h = self.skel_filename,
00223                                  file = self.idl_filename,
00224                                  interfaces = str(impl_h))
00225         
00226         # Generate implementation class template code
00227         stream_cpp.out(class_cpp,
00228                                    atmark = "@",
00229                                    impl_cpp = self.impl_cpp_filename,
00230                                    impl_h = self.impl_h_filename,
00231                                    file = self.idl_filename,
00232                                    interfaces = str(impl_cpp))
00233 
00234         self.ifs = []
00235         for n in bii.allInterfaces():
00236                 self.ifs.append(string.join(n.scopedName(), "_") + self.suffix)
00237         return self.ifs
00238         
00239         
00240 
00241 
00242 #============================================================
00243 # Build the interface implementations
00244 #============================================================
00245 class BuildInterfaceImplementations(idlvisitor.AstVisitor):
00246 
00247         def __init__(self, stream_h, stream_cpp, ignore_operations):
00248                 self.stream_h = stream_h
00249                 self.stream_cpp = stream_cpp
00250                 self.ignore_operations = ignore_operations
00251                 # keep track of all interfaces for later use
00252                 self.__allInterfaces = []
00253 
00254         # Returns the list of all present interfaces (each one will be
00255         # implemented)
00256         def allInterfaces(self):
00257                 return self.__allInterfaces[:]
00258 
00259         # Tree walking code
00260         def visitAST(self, node):
00261                 for n in node.declarations():
00262                         if ast.shouldGenerateCodeForDecl(n):
00263                                 n.accept(self)
00264 
00265         # modules can contain interfaces
00266         def visitModule(self, node):
00267                 for n in node.definitions():
00268                         n.accept(self)
00269 
00270         # interfaces cannot be further nested
00271         def visitInterface(self, node):
00272                 self.__allInterfaces.append(node)
00273         
00274                 scopedName = id.Name(node.scopedName())
00275                 
00276                 cxx_fqname = scopedName.fullyQualify()
00277                 impl_flat_name = impl_fullname(scopedName)
00278 
00279                 fqname = scopedName.fullyQualify(cxx = 0)
00280 
00281                 
00282                 # build methods corresponding to attributes, operations etc.
00283                 # attributes[] and operations[] will contain lists of function
00284                 # signatures eg
00285                 #   [ char *echoString(const char *mesg) ]
00286                 attributes = []
00287                 operations = []
00288                 virtual_operations = []
00289 
00290                 # we need to consider all callables, including inherited ones
00291                 # since this implementation class is not inheriting from anywhere
00292                 # other than the IDL skeleton
00293                 allInterfaces = [node] + ast.allInherits(node)
00294                 allCallables = util.fold( map(lambda x:x.callables(), allInterfaces),
00295                                                                   [], lambda x, y: x + y )
00296 
00297 
00298                 # declarations[] contains a list of in-class decl signatures
00299                 # implementations[] contains a list of out of line impl signatures
00300                 # (typically differ by classname::)
00301                 declarations = []
00302                 implementations = []
00303                 
00304                 for c in allCallables:
00305 
00306                         if isinstance(c, idlast.Attribute) :
00307                                 attrType = types.Type(c.attrType())
00308                                 d_attrType = attrType.deref()
00309 
00310                                 for i in c.identifiers():
00311                                         attribname = id.mapID(i)
00312                                         returnType = attrType.op(types.RET)
00313                                         inType = attrType.op(types.IN)
00314                                         attributes.append(returnType + " " + attribname + "()")
00315                                         # need a set method if not a readonly attribute
00316                                         if not c.readonly():
00317                                                 args = attribname + "(" + inType + ")"
00318                                                 declarations.append("void " + args)
00319                                                 implementations.append("void " + impl_flat_name +\
00320                                                                                            "::" + args)
00321                                         if not attribname in self.ignore_operations:
00322                                                 declarations.append(returnType + " " + attribname + "()")
00323                                                 implementations.append(returnType + " " + impl_flat_name+\
00324                                                                                    "::" + attribname + "()")
00325                         elif isinstance(c, idlast.Operation):
00326                                 params = []
00327                                 for p in c.parameters():
00328                                         paramType = types.Type(p.paramType())
00329                                         cxx_type = paramType.op(types.direction(p), use_out = 0)
00330                                         
00331                                         argname = id.mapID(p.identifier())
00332                                         params.append(cxx_type + " " + argname)
00333 
00334                                 # deal with possible "context"
00335                                 if c.contexts() != []:
00336                                         params.append("CORBA::Context_ptr _ctxt")
00337 
00338                                 return_type = types.Type(c.returnType()).op(types.RET)
00339 
00340                                 opname = id.mapID(c.identifier())
00341                                 if not opname in self.ignore_operations:
00342                                         arguments = string.join(params, ", ")
00343                                         args = opname + "(" + arguments + ")"
00344                                         declarations.append(return_type + " " + args)
00345                                         implementations.append(return_type + " " + \
00346                                                                                    impl_flat_name + \
00347                                                                                    "::" + args)
00348                         else:
00349                                 util.fatalError("Internal error generating interface member")
00350                                 raise "No code for interface member: " + repr(c)
00351 
00352                 # the class definition has no actual code...
00353                 defs = string.join(map(lambda x:x + ";\n", declarations), "")
00354 
00355                 # Output the class definition of the implementation
00356                 self.stream_h.out(interface_def,
00357                                                   impl_fqname = impl_flat_name,
00358                                                   impl_name = impl_flat_name,
00359                                                   fq_name = fqname,
00360                                                   fq_POA_name = "POA_" + cxx_fqname,
00361                                                   operations = defs)
00362 
00363                 # Output the class methods implementations
00364                 impls = string.join(map(lambda x: x + """\
00365 
00366 {
00367   // Please insert your code here and remove the following warning pragma
00368   #warning "Code missing in function <""" + x + """>"
00369 }
00370 
00371 """,
00372                                                                 implementations), "")
00373                 
00374                 self.stream_cpp.out(interface_code,
00375                                                         fqname = fqname,
00376                                                         impl_name = impl_flat_name,
00377                                                         impl_fqname = impl_flat_name,
00378                                                         operations = impls)
00379 
00380 
00381 if __name__ == "__main__":
00382         import cxx_svc_impl
00383         import sys
00384         print "Interfaces:"
00385         print cxx_svc_impl.generate(sys.argv[1], "SVC_impl")


openrtm_aist_python
Author(s): Shinji Kurihara
autogenerated on Thu Aug 27 2015 14:17:28