📄 mangler.py
字号:
# -*- python -*-# Package : omniidl# mangler.py Created on: 1999/11/16# Author : David Scott (djs)## Copyright (C) 1999-2000 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:# Produce mangled names for types and operation signatures# # $Id: mangler.py,v 1.15.2.9 2002/11/21 16:12:52 dgrisby Exp $# $Log: mangler.py,v $# Revision 1.15.2.9 2002/11/21 16:12:52 dgrisby# Oneway call descriptor bug.## Revision 1.15.2.8 2001/11/27 14:37:25 dpg1# long double TC descriptor.## Revision 1.15.2.7 2001/11/13 15:23:52 dpg1# Bug in forward declared structs/unions.## Revision 1.15.2.6 2001/10/29 17:42:42 dpg1# Support forward-declared structs/unions, ORB::create_recursive_tc().## Revision 1.15.2.5 2001/06/08 17:12:20 dpg1# Merge all the bug fixes from omni3_develop.## Revision 1.15.2.4 2001/03/13 10:32:09 dpg1# Fixed point support.## Revision 1.15.2.3 2000/11/20 14:43:26 sll# Added support for wchar and wstring.## Revision 1.15.2.2 2000/10/12 15:37:53 sll# Updated from omni3_1_develop.## Revision 1.16.2.2 2000/09/14 16:03:59 djs# Remodularised C++ descriptor name generator## Revision 1.16.2.1 2000/08/21 11:35:33 djs# Lots of tidying## Revision 1.16 2000/07/13 15:25:59 dpg1# Merge from omni3_develop for 3.0 release.## Revision 1.13.2.5 2000/06/26 16:24:18 djs# Refactoring of configuration state mechanism.## Revision 1.13.2.4 2000/04/26 18:22:56 djs# Rewrote type mapping code (now in types.py)# Rewrote identifier handling code (now in id.py)# Removed superfluous externs in front of function definitions## Revision 1.13.2.3 2000/03/09 15:21:57 djs# Better handling of internal compiler exceptions (eg attempts to use# wide string types)## Revision 1.13.2.2 2000/02/16 16:30:03 djs# Fix to proxy call descriptor code- failed to handle special case of# Object method(in string x)## Revision 1.13.2.1 2000/02/14 18:34:53 dpg1# New omniidl merged in.## Revision 1.13 2000/01/13 17:02:05 djs# Added support for operation contexts.## Revision 1.12 2000/01/13 15:56:44 djs# Factored out private identifier prefix rather than hard coding it all through# the code.## Revision 1.11 2000/01/13 14:16:35 djs# Properly clears state between processing separate IDL input files## Revision 1.10 1999/12/17 10:48:11 djs# Typedef to a sequence<sequence< name mangling bug## Revision 1.9 1999/12/14 17:38:25 djs# Fixed anonymous sequences of sequences bug## Revision 1.8 1999/12/14 11:53:23 djs# Support for CORBA::TypeCode and CORBA::Any# Exception member bugfix## Revision 1.7 1999/12/13 10:50:07 djs# Treats the two call descriptors associated with an attribute separately,# since it can happen that one needs to be generated but not the other.## Revision 1.6 1999/12/10 18:27:05 djs# Fixed bug to do with marshalling arrays of things, mirrored in the old# compiler## Revision 1.5 1999/12/09 20:40:58 djs# Bugfixes and integration with dynskel/ code## Revision 1.4 1999/12/01 16:59:01 djs# Fixed name generation for attributes with user exceptions.## Revision 1.3 1999/11/23 18:48:26 djs# Bugfixes, more interface operations and attributes code## Revision 1.2 1999/11/19 20:09:03 djs# Fixed signature generating bug when return type is void## Revision 1.1 1999/11/17 20:37:23 djs# Code for call descriptors and proxies#from omniidl import idlast, idltypefrom omniidl_be.cxx import types, id, skutil, utilimport string######################################################################### Produce cannonical names for types and operation signatures# Separator constantsSCOPE_SEPARATOR = "_m"ARRAY_SEPARATOR = "_a"SEQ_SEPARATOR = "_s"FORWARD_SEQ_SEPARATOR = "_f"CANNON_NAME_SEPARATOR = "_c"ONEWAY_SEPARATOR = "_w"IN_SEPARATOR = "_i"OUT_SEPARATOR = "_o"INOUT_SEPARATOR = "_n"EXCEPTION_SEPARATOR = "_e"# Canonical names for basic typesname_map = { idltype.tk_short: "short", idltype.tk_long: "long", idltype.tk_longlong: "longlong", idltype.tk_ushort: "unsigned_pshort", idltype.tk_ulong: "unsigned_plong", idltype.tk_ulonglong: "unsigned_plonglong", idltype.tk_float: "float", idltype.tk_double: "double", idltype.tk_longdouble: "longdouble", idltype.tk_char: "char", idltype.tk_wchar: "wchar", idltype.tk_boolean: "boolean", idltype.tk_octet: "octet", idltype.tk_void: "void", idltype.tk_any: "any", idltype.tk_TypeCode: "TypeCode", }# Produce a cannonical type namedef canonTypeName(type, decl = None, useScopedName = 0): assert isinstance(type, types.Type) type_dims = type.dims() decl_dims = [] if decl != None: assert isinstance(decl, idlast.Declarator) decl_dims = decl.sizes() # flatten a list of dimensions into a string def dims(d): if d == []: return "" d_str = map(lambda x:ARRAY_SEPARATOR + str(x), d) return string.join(d_str, "") full_dims = decl_dims + type_dims is_array = full_dims != [] dims_string = dims(full_dims) # The canonical type name always has the full dimensions # prepended to it. canon_name = dims_string d_type = type.deref() # consider anonymous sequence<sequence<.... if type.sequence() and types.Type(type.type().seqType()).sequence(): bound = type.type().bound() canon_name = canon_name + SEQ_SEPARATOR + str(bound) +\ canonTypeName(types.Type(type.type().seqType()), None, useScopedName) return canon_name # sometimes we don't want to call a sequence a sequence # (operation signatures) if useScopedName and not is_array and \ type.typedef() and d_type.sequence(): # find the last typedef in the chain while types.Type(type.type().decl().alias().aliasType()).typedef(): type = types.Type(type.type().decl().alias().aliasType()) scopedName = id.Name(type.type().scopedName()).guard() return canon_name + CANNON_NAME_SEPARATOR + scopedName # _arrays_ of sequences seem to get handled differently # to simple aliases to sequences if d_type.sequence(): bound = d_type.type().bound() seqType = types.Type(d_type.type().seqType()) if seqType.structforward() or seqType.unionforward(): canon_name = canon_name + FORWARD_SEQ_SEPARATOR + str(bound) else: canon_name = canon_name + SEQ_SEPARATOR + str(bound) while seqType.sequence(): bound = seqType.type().bound() canon_name = canon_name + SEQ_SEPARATOR + str(bound) seqType = types.Type(seqType.type().seqType()) # straight forward sequences of sequences use their # flattened scoped name dkd_seqType = seqType.deref(keep_dims = 1) if not dkd_seqType.sequence(): canon_name = canon_name + canonTypeName(dkd_seqType) return canon_name type = seqType d_type = type.deref() # add in the name for the most dereferenced type def typeName(type): assert isinstance(type, types.Type) d_type = type.deref() # dereference the type, until just -before- it becomes a # sequence. Since a sequence doesn't have a scopedName(), # we use the scopedName() of the immediately preceeding # typedef which is an instance of idltype.Declared while type.typedef() and \ not types.Type(type.type().decl().alias().aliasType()).sequence(): type = types.Type(type.type().decl().alias().aliasType()) if name_map.has_key(type.type().kind()): return name_map[type.type().kind()] if type.string(): bound = "" if type.type().bound() != 0: bound = str(type.type().bound()) return bound + "string" if type.wstring(): bound = "" if type.type().bound() != 0: bound = str(type.type().bound()) return bound + "wstring" if isinstance(type.type(), idltype.Fixed): return str(type.type().digits()) + "_" + \ str(type.type().scale()) + "fixed" if isinstance(type.type(), idltype.Declared): return id.Name(type.type().scopedName()).guard() util.fatalError("Error generating mangled name") canon_name = canon_name + CANNON_NAME_SEPARATOR + typeName(type) return canon_namedef produce_signature(returnType, parameters, raises, oneway): returnType = types.Type(returnType) d_returnType = returnType.deref() # return type if d_returnType.void(): sig = "void" else: sig = canonTypeName(returnType, useScopedName = 1) if oneway: # Can only validly happen with void return, but you never know # what the future may hold. sig = ONEWAY_SEPARATOR + sig # parameter list for param in parameters: if param.is_in() and param.is_out(): sig = sig + INOUT_SEPARATOR elif param.is_in(): sig = sig + IN_SEPARATOR elif param.is_out(): sig = sig + OUT_SEPARATOR sig = sig + canonTypeName(types.Type(param.paramType()), useScopedName = 1) # exception list raises = skutil.sort_exceptions(raises) def exception_signature(exception): cname = CANNON_NAME_SEPARATOR +\ id.Name(exception.scopedName()).guard() return EXCEPTION_SEPARATOR + cname raises_sigs = map(exception_signature, raises) raises_str = string.join(raises_sigs, "") sig = sig + raises_str return sig
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -