📄 skutil.py
字号:
# -*- python -*-# Package : omniidl# skutil.py Created on: 1999/11/15# Author : David Scott (djs)## Copyright (C) 1999 AT&T Laboratories Cambridge## This file is part of omniidl.## omniidl is free software; you can redistribute it and/or modify it# under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU# General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA# 02111-1307, USA.## Description:# # Skeleton utility functions designed for the C++ backend# $Id: skutil.py,v 1.17.2.10 2003/07/27 19:24:32 dgrisby Exp $# $Log: skutil.py,v $# Revision 1.17.2.10 2003/07/27 19:24:32 dgrisby# Avoid name clash in struct marshalling with evil IDL.## Revision 1.17.2.9 2001/06/19 16:41:49 sll# Type cast now correctly distinguishes between normal and array types.## Revision 1.17.2.8 2001/06/19 14:23:21 sll# In the marshalling and unmarshalling code, only cast from a sequence T_var to# T&. Otherwise, the generate code is wrong with gcc 3.0. Suppose T is a# sequence of A, even though T is always a derived class of the template# instance seq<A>, casting a T_var to a seq<A>& causes GCC 3.0 to generate# wrong code quietly!## Revision 1.17.2.7 2001/06/15 10:22:09 sll# Work around for MSVC++ bug. Changed the casting of the array of base types# when they are marshalled using the quick method.## Revision 1.17.2.6 2001/06/08 17:12:13 dpg1# Merge all the bug fixes from omni3_develop.## Revision 1.17.2.5 2001/04/19 10:04:13 dpg1# Bug in sort_exceptions()## Revision 1.17.2.4 2000/11/07 18:28:21 sll# Use helper marshal functions if the interface is a forward declaration.## Revision 1.17.2.3 2000/11/03 19:26:01 sll# Simplified the marshalling functions.## Revision 1.17.2.2 2000/10/12 15:37:48 sll# Updated from omni3_1_develop.## Revision 1.18.2.2 2000/08/21 11:34:35 djs# Lots of omniidl/C++ backend changes## Revision 1.18.2.1 2000/08/04 17:10:26 dpg1# Long long support## Revision 1.18 2000/07/13 15:26:01 dpg1# Merge from omni3_develop for 3.0 release.## Revision 1.15.2.4 2000/05/31 18:02:16 djs# Better output indenting (and preprocessor directives now correctly output at# the beginning of lines)## Revision 1.15.2.3 2000/04/26 18:22:13 djs# Rewrote type mapping code (now in types.py)# Rewrote identifier handling code (now in id.py)## Revision 1.15.2.2 2000/03/09 15:21:40 djs# Better handling of internal compiler exceptions (eg attempts to use# wide string types)## Revision 1.15.2.1 2000/02/14 18:34:57 dpg1# New omniidl merged in.## Revision 1.15 2000/01/17 16:58:52 djs# Marshalling code: exceptions (BAD_PARAM, MARSHAL) and bounded strings## Revision 1.14 2000/01/11 12:02:34 djs# More tidying up## Revision 1.13 2000/01/07 20:31:18 djs# Regression tests in CVSROOT/testsuite now pass for# * no backend arguments# * tie templates# * flattened tie templates# * TypeCode and Any generation## Revision 1.12 1999/12/26 16:38:06 djs# Support for bounded strings (specifically a bounds check raising# CORBA::BAD_PARAM)## Revision 1.11 1999/12/16 16:08:02 djs# More TypeCode and Any fixes## Revision 1.10 1999/12/15 12:11:54 djs# Marshalling arrays of Anys fix## Revision 1.9 1999/12/14 11:53:56 djs# Support for CORBA::TypeCode and CORBA::Any## Revision 1.8 1999/12/10 18:26:03 djs# Added a utility function to order exceptions based on their names## Revision 1.7 1999/11/29 19:26:59 djs# Code tidied and moved around. Some redundant code eliminated.## Revision 1.6 1999/11/29 15:26:04 djs# Marshalling bugfixes.## Revision 1.5 1999/11/26 18:52:06 djs# Bugfixes and refinements## Revision 1.4 1999/11/23 18:49:26 djs# Lots of fixes, especially marshalling code# Added todo list to keep track of issues## Revision 1.3 1999/11/19 20:07:33 djs# Bugfixes. Added utility functions for operations and attributes## Revision 1.2 1999/11/17 20:37:09 djs# General util functions## Revision 1.1 1999/11/15 19:10:55 djs# Added module for utility functions specific to generating skeletons# Union skeletons working#import stringfrom omniidl import idlutil, idltype, idlastfrom omniidl_be.cxx import util, types, id, ast, output, cxx# From http://www-i3.informatik.rwth-aachen.de/funny/babbage.html:## A hotly contested issue among language designers is the method for# passing parameters to subfunctions. Some advocate "call by name," others# prefer "call by value." Babbage uses a new method - "call by telephone."# This is especially effective for long-distance parameter passing.# Code for marshalling and unmarshalling various data types.def marshall(to, environment, type, decl, argname, to_where, exception = "BAD_PARAM"): assert isinstance(type, types.Type) d_type = type.deref() # If this is an array of base types, the quick marshalling option is used. # slice_cast is set to the casting required to cast the variable to a # pointer to the beginning of the array. There are 3 possibilities: # 1. The variable is a declarator, e.g. it is a member of a struct or a # union. No casting is required. slice_cast = "" # 2. The variable is not a declarator and its dimension is > 1, # cast the variable to its array slice pointer. # 3. Same as 2 but its dimension == 1, just cast the variable to a pointer # to its base class (because the type's array slice may not be # defined). if decl: assert isinstance(decl, idlast.Declarator) dims = decl.sizes() + type.dims() slice_cast = "" else: dims = type.dims() if len(dims) != 1: slice_cast = "(" + type.base(environment) + "_slice" + "*)" else: slice_cast = "(" + d_type.base(environment) + "*)" if dims != []: n_elements = reduce(lambda x,y:x*y, dims, 1) array_marshal_helpers = { idltype.tk_octet: ("omni::ALIGN_1",1), idltype.tk_boolean: ("omni::ALIGN_1",1), idltype.tk_short: ("omni::ALIGN_2",2), idltype.tk_long: ("omni::ALIGN_4",4), idltype.tk_ushort: ("omni::ALIGN_2",2), idltype.tk_ulong: ("omni::ALIGN_4",4), idltype.tk_float: ("omni::ALIGN_4",4), idltype.tk_double: ("omni::ALIGN_8",8), idltype.tk_longlong: ("omni::ALIGN_8",8), idltype.tk_ulonglong: ("omni::ALIGN_8",8) } if array_marshal_helpers.has_key(d_type.type().kind()): (alignment,elmsize) = array_marshal_helpers[d_type.type().kind()] if alignment != "omni::ALIGN_1": to.out("""\if (! @where@.marshal_byte_swap()) { @where@.put_octet_array((CORBA::Octet*)(@slice_cast@@name@),@num@,@align@);}else """, where = to_where, name = argname, slice_cast = slice_cast, num = str(n_elements * elmsize), align = alignment) # Do not return here. # let the code below to deal with the else block. else: to.out("@where@.put_octet_array((CORBA::Octet*)(@slice_cast@@name@),@num@);", where = to_where, name = argname, slice_cast = slice_cast, num = str(n_elements)) return # No quick route, generate iteration loop block = cxx.Block(to) loop = cxx.For(to, dims) indexing_string = loop.index() element_name = argname + indexing_string if dims != []: type_name = d_type.base(environment) if type_name == element_name: type_name = d_type.base() else: type_name = type.base(environment) if type_name == element_name: type_name = type.base() bounded = "" kind = d_type.type().kind() if d_type.objref(): type_name = string.replace(type_name,"_ptr","") if isinstance(d_type.type().decl(),idlast.Forward): # hack to denote an interface forward declaration # kind is used to index the associative array below kind = idltype.tk_objref * 1000 elif d_type.string() or d_type.wstring(): bounded = str(d_type.type().bound()) if not d_type.is_basic_data_types() and not d_type.enum(): type_cast = "(const " + type_name + "&) " else: type_cast = "" special_marshal_functions = { idltype.tk_boolean: "@to_where@.marshalBoolean(@element_name@);", idltype.tk_octet: "@to_where@.marshalOctet(@element_name@);", idltype.tk_char: "@to_where@.marshalChar(@element_name@);", idltype.tk_wchar: "@to_where@.marshalWChar(@element_name@);", idltype.tk_string: "@to_where@.marshalString(@element_name@,@bounded@);", idltype.tk_wstring: "@to_where@.marshalWString(@element_name@,@bounded@);", idltype.tk_objref: "@type@::_marshalObjRef(@element_name@,@to_where@);", idltype.tk_TypeCode: "CORBA::TypeCode::marshalTypeCode(@element_name@,@to_where@);", idltype.tk_objref * 1000: "@type@_Helper::marshalObjRef(@element_name@,@to_where@);" } if special_marshal_functions.has_key(kind): out_template = special_marshal_functions[kind] else: out_template = "@type_cast@@element_name@ >>= @to_where@;" to.out(out_template, to_where = to_where, element_name = element_name, bounded = bounded, type = type_name, type_cast = type_cast) loop.end() if dims != []: block.end() def unmarshall(to, environment, type, decl, name, from_where): assert isinstance(type, types.Type) d_type = type.deref() # If this is an array of base types, the quick marshalling option is used. # slice_cast is set to the casting required to cast the variable to a # pointer to the beginning of the array. There are 3 possibilities: # 1. The variable is a declarator, e.g. it is a member of a struct or a # union. No casting is required. slice_cast = "" # 2. The variable is not a declarator and its dimension is > 1, # cast the variable to its array slice pointer. # 3. Same as 2 but its dimension == 1, just cast the variable to a pointer # to its base class (because the type's array slice may not be # defined). if decl: assert isinstance(decl, idlast.Declarator) dims = decl.sizes() + type.dims() slice_cast = "" else: dims = type.dims() if len(dims) != 1: slice_cast = "(" + type.base(environment) + "_slice" + "*)" else: slice_cast = "(" + d_type.base(environment) + "*)" if dims != []: n_elements = reduce(lambda x,y:x*y, dims, 1) array_unmarshal_helpers = { idltype.tk_octet: ("get_octet_array","(CORBA::Octet*)"), idltype.tk_boolean: ("get_octet_array","(CORBA::Octet*)"), idltype.tk_short: ("unmarshalArrayShort","(CORBA::Short*)"), idltype.tk_long: ("unmarshalArrayLong","(CORBA::Long*)"), idltype.tk_ushort: ("unmarshalArrayUShort","(CORBA::UShort*)"), idltype.tk_ulong: ("unmarshalArrayULong","(CORBA::ULong*)"), idltype.tk_float: ("unmarshalArrayFloat","(CORBA::Float*)"), idltype.tk_double: ("unmarshalArrayDouble","(CORBA::Double*)"), idltype.tk_longlong:("unmarshalArrayLongLong","(CORBA::LongLong*)"), idltype.tk_ulonglong:("unmarshalArrayULongLong","(CORBA::ULongLong*)") } if array_unmarshal_helpers.has_key(d_type.type().kind()): (helper,typecast) = array_unmarshal_helpers[d_type.type().kind()] to.out("@where@.@helper@(@typecast@(@slice_cast@@name@), @num@);", helper = helper, where = from_where, typecast = typecast, name = name, slice_cast = slice_cast, num = str(n_elements)) return # No quick route, generate iteration loop block = cxx.Block(to) loop = cxx.For(to, dims) indexing_string = loop.index() element_name = name + indexing_string if dims != []: type_name = d_type.base(environment) if type_name == element_name: type_name = d_type.base() else: type_name = type.base(environment) if type_name == element_name: type_name = type.base() bounded = "" kind = d_type.type().kind() if d_type.objref(): type_name = string.replace(type_name,"_ptr","") if isinstance(d_type.type().decl(),idlast.Forward): # hack to denote an interface forward declaration # kind is used to index the associative array below kind = idltype.tk_objref * 1000 elif d_type.string() or d_type.wstring(): bounded = str(d_type.type().bound()) special_unmarshal_functions = { idltype.tk_boolean: "@element_name@ = @where@.unmarshalBoolean();", idltype.tk_octet: "@element_name@ = @where@.unmarshalOctet();", idltype.tk_char: "@element_name@ = @where@.unmarshalChar();", idltype.tk_wchar: "@element_name@ = @where@.unmarshalWChar();", idltype.tk_string: "@element_name@ = @where@.unmarshalString(@bounded@);", idltype.tk_wstring: "@element_name@ = @where@.unmarshalWString(@bounded@);", idltype.tk_objref: "@element_name@ = @type@::_unmarshalObjRef(@where@);", idltype.tk_TypeCode: "@element_name@ = CORBA::TypeCode::unmarshalTypeCode(@where@);", idltype.tk_objref * 1000: "@element_name@ = @type@_Helper::unmarshalObjRef(@where@);" } if special_unmarshal_functions.has_key(kind): out_template = special_unmarshal_functions[kind] else: out_template = "(@type@&)@element_name@ <<= @where@;" to.out(out_template, type = type_name, element_name = element_name, where = from_where, bounded = bounded) loop.end() if dims != []: block.end()def sort_exceptions(ex): # sort the exceptions into lexicographical order def lexicographic(exception_a, exception_b): name_a = exception_a.repoId() name_b = exception_b.repoId() return cmp(name_a, name_b) raises = ex[:] raises.sort(lexicographic) return raises
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -