📄 typecode.py
字号:
# -*- python -*-# Package : omniidl# typecode.py Created on: 1999/12/2# 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:# # Produces the instances of CORBA::TypeCode# $Id: typecode.py,v 1.16.2.9 2004/03/24 22:08:41 dgrisby Exp $# $Log: typecode.py,v $# Revision 1.16.2.9 2004/03/24 22:08:41 dgrisby# TypeCodes for sequences of forward declared structs / unions used by# other compilation units were broken.## Revision 1.16.2.8 2001/11/14 17:13:43 dpg1# Long double support.## Revision 1.16.2.7 2001/10/29 17:42:39 dpg1# Support forward-declared structs/unions, ORB::create_recursive_tc().## Revision 1.16.2.6 2001/06/08 17:12:16 dpg1# Merge all the bug fixes from omni3_develop.## Revision 1.16.2.5 2001/03/13 10:32:08 dpg1# Fixed point support.## Revision 1.16.2.4 2000/11/20 14:43:24 sll# Added support for wchar and wstring.## Revision 1.16.2.3 2000/11/09 12:27:55 dpg1# Huge merge from omni3_develop, plus full long long from omni3_1_develop.## Revision 1.16.2.2 2000/10/12 15:37:50 sll# Updated from omni3_1_develop.## Revision 1.17.2.2 2000/08/21 11:35:08 djs# Lots of tidying## Revision 1.17.2.1 2000/08/04 17:10:29 dpg1# Long long support## Revision 1.17 2000/07/13 15:26:00 dpg1# Merge from omni3_develop for 3.0 release.## Revision 1.14.2.7 2000/07/03 14:56:43 djs# Fixed bug generating typecodes for struct members which are anonymous# sequences.## Revision 1.14.2.6 2000/06/26 16:23:27 djs# Refactoring of configuration state mechanism.## Revision 1.14.2.5 2000/05/04 14:35:12 djs# Added new flag splice-modules which causes all continuations to be output# as one lump. Default is now to output them in pieces following the IDL.## Revision 1.14.2.4 2000/04/26 18:22:20 djs# Rewrote type mapping code (now in types.py)# Rewrote identifier handling code (now in id.py)## Revision 1.14.2.3 2000/03/23 15:31:10 djs# Failed to handle recursive unions properly where the cycle had more# than one node (didn't use recursion detection functions everywhere it# should have)## Revision 1.14.2.2 2000/03/09 15:21:48 djs# Better handling of internal compiler exceptions (eg attempts to use# wide string types)## Revision 1.14.2.1 2000/02/14 18:34:55 dpg1# New omniidl merged in.## Revision 1.14 2000/01/20 18:26:45 djs# Moved large C++ output strings into an external template file## Revision 1.13 2000/01/19 09:35:48 djs# *** empty log message ***## Revision 1.12 2000/01/17 17:07:29 djs# Better handling of recursive types## Revision 1.11 2000/01/13 18:16:35 djs# A little formatting## Revision 1.10 2000/01/13 15:56:35 djs# Factored out private identifier prefix rather than hard coding it all through# the code.## Revision 1.9 2000/01/13 14:16:25 djs# Properly clears state between processing separate IDL input files## Revision 1.8 2000/01/11 11:33:55 djs# Tidied up## Revision 1.7 2000/01/07 20:31:24 djs# Regression tests in CVSROOT/testsuite now pass for# * no backend arguments# * tie templates# * flattened tie templates# * TypeCode and Any generation## Revision 1.6 1999/12/26 16:41:28 djs# Fix to output TypeCode information on Enums #included from another IDL# file. Mimics behaviour of the old BE## Revision 1.5 1999/12/24 18:16:39 djs# Array handling and TypeCode building fixes (esp. across multiple files)## Revision 1.4 1999/12/16 16:10:05 djs# Fix to make the output order consistent with the old compiler## Revision 1.3 1999/12/14 11:51:53 djs# Support for CORBA::TypeCode, CORBA::Any and CORBA::Object## Revision 1.2 1999/12/10 18:26:36 djs# Moved most #ifdef buildDesc code into a separate module# General tidying up## Revision 1.1 1999/12/09 20:40:14 djs# TypeCode and Any generation option performs identically to old compiler for# all current test fragments.#"""Produces the instances of CORBA::TypeCode"""import string, refrom omniidl import idlast, idltype, idlutilfrom omniidl_be.cxx import cxx, ast, output, util, config, types, idfrom omniidl_be.cxx.dynskel import tcstring, templateimport typecodeself = typecode# For a given type declaration, creates (private) static instances of# CORBA::TypeCode_ptr for that type, and any necessary for contained# constructed types. Contained types from other files cannot be used# because the order of static initialiser execution is not defined.# eg# IDL: struct testStruct{# char a;# foo b; // b is defined elsewhere# };# becomes: static CORBA::PR_StructMember _0RL_structmember_testStruct[] = {# {"a", CORBA::TypeCode::PR_char_tc()},# {"b", _0RL_tc_foo} // defined elsewhere# };# static CORBA::TypeCode_ptr _0RL_tc_testStruct = .....## Types constructed in the main file have an externally visible symbol# defined:# const CORBA::TypeCode_ptr _tc_testStruct = _0RL_tc_testStruct## ----------------------------------------------------------------------# Utility functions local to this module start here# ----------------------------------------------------------------------class NameAlreadyDefined: def __str__(self): return "Name has already been defined in this scope/block/file/section" pass# returns true if the name has already been defined, and need not be defined# again.def alreadyDefined(mangledname): return self.__defined_names.has_key(mangledname)def defineName(mangledname): self.__defined_names[mangledname] = 1def forwardUsed(node): sname = idlutil.slashName(node.scopedName()) self.__forwards_pending[sname] = 1def resolveForward(node): sname = idlutil.slashName(node.scopedName()) if self.__forwards_pending.has_key(sname): del self.__forwards_pending[sname] return 1 return 0# mangleName("_0RL_tc", ["CORBA", "Object"]) -> "_ORL_tc_CORBA_Object"def mangleName(prefix, scopedName): mangled = prefix + id.Name(scopedName).guard() return mangled# Note: The AST has a notion of recursive structs and unions, but it can only# say whether it is recursive, and not tell you how many nodes up the tree# the recursive definition is. So we keep track of currently being-defined# nodes here for that purpose.self.__currentNodes = []def startingNode(node): self.__currentNodes.append(node)def finishingNode(): assert(self.__currentNodes != []) self.__currentNodes = self.__currentNodes[:-1]def currently_being_defined(node): return node in self.__currentNodesdef recursive_Depth(node): return len(self.__currentNodes) - self.__currentNodes.index(node)def __init__(stream): self.stream = stream # declarations are built in two halves, this is to allow us # to keep the same order as the old backend. It could be simpler. self.tophalf = stream self.bottomhalf = stream self.__immediatelyInsideModule = 0 # Dictionary with keys representing names defined. If two structures both # have a member of type foo, we should still only define the TypeCode for # foo once. self.__defined_names = {} # Dictionary of forward-declared structs/unions that have been # used in sequence TypeCodes, but not yet defined. self.__forwards_pending = {} # Normally when walking over the tree we only consider things # defined in the current file. However if we encounter a # dependency between something in the current file and something # defined elsewhere, we set the resolving_dependency flag and # recurse again. self.__resolving_dependency = 0 return self# Places TypeCode symbol in appropriate namespace with a non-static const# declaration (performs MSVC workaround)def external_linkage(decl, mangled_name = ""): assert isinstance(decl, idlast.DeclRepoId) # Don't give external linkage if we met this declaration in # resolving an out-of-file dependency if self.__resolving_dependency: return where = bottomhalf scopedName = id.Name(decl.scopedName()) scope = scopedName.scope() tc_name = scopedName.prefix("_tc_") tc_unscoped_name = tc_name.simple() tc_name = tc_name.fullyQualify() if mangled_name == "": mangled_name = mangleName(config.state['Private Prefix'] + "_tc_", decl.scopedName()) if alreadyDefined(tc_name): return defineName(tc_name) global_scope = len(scope) == 0 # Needs the workaround if directly inside a module if not self.__immediatelyInsideModule: where.out("""\const CORBA::TypeCode_ptr @tc_name@ = @mangled_name@;""", tc_name = tc_name, mangled_name = mangled_name) return open_namespace = "" close_namespace = "" for s in scope: open_namespace = open_namespace + "namespace " + s + " { " close_namespace = close_namespace + "} " where.out(template.external_linkage, open_namespace = open_namespace, close_namespace = close_namespace, tc_name = tc_name, mangled_name = mangled_name, tc_unscoped_name = tc_unscoped_name)# Gets a TypeCode instance for a type# Basic types have new typecodes generated, derived types are assumed# to already exist and a name is passed insteaddef mkTypeCode(type, declarator = None, node = None): assert isinstance(type, types.Type) prefix = "CORBA::TypeCode::PR_" if declarator: assert isinstance(declarator, idlast.Declarator) dims = declarator.sizes() pre_str = "" post_str = "" for dim in dims: pre_str = pre_str + prefix + "array_tc(" + str(dim) + ", " post_str = post_str + ")" return pre_str + mkTypeCode(type, None, node) + post_str type = type.type() basic = { idltype.tk_short: "short", idltype.tk_long: "long", idltype.tk_ushort: "ushort", idltype.tk_ulong: "ulong", idltype.tk_float: "float", idltype.tk_double: "double", idltype.tk_boolean: "boolean", idltype.tk_char: "char", idltype.tk_wchar: "wchar", idltype.tk_octet: "octet", idltype.tk_any: "any", idltype.tk_TypeCode: "TypeCode", idltype.tk_longlong: "longlong", idltype.tk_ulonglong: "ulonglong", idltype.tk_longdouble: "longdouble" } if basic.has_key(type.kind()): return prefix + basic[type.kind()] + "_tc()" if isinstance(type, idltype.Base): util.fatalError("Internal error generating TypeCode data") raise "Don't know how to generate TypeCode for Base kind = " +\ repr(type.kind()) if isinstance(type, idltype.String): return prefix + "string_tc(" + str(type.bound()) + ")" if isinstance(type, idltype.WString): return prefix + "wstring_tc(" + str(type.bound()) + ")" if isinstance(type, idltype.Sequence): seqType = type.seqType() if isinstance(seqType, idltype.Declared): decl = seqType.decl() if isinstance(decl, idlast.StructForward) or \ isinstance(decl, idlast.UnionForward) : forwardUsed(decl) scopedName = decl.scopedName() mangled_name = mangleName(config.state['Private Prefix'] +\ "_fs_", scopedName) if not alreadyDefined(mangled_name): defineName(mangled_name) tophalf.out("""\static CORBA::TypeCode_ptr @name@ = @prefix@forward_sequence_tc(@bound@);""", name=mangled_name, prefix=prefix, bound=type.bound()) return mangled_name elif hasattr(decl, "recursive") and decl.recursive() and \ currently_being_defined(decl): depth = recursive_Depth(decl) return prefix + "recursive_sequence_tc(" +\ str(type.bound()) + ", " + str(depth) + ")" startingNode(type) ret = prefix + "sequence_tc(" + str(type.bound()) + ", " +\ mkTypeCode(types.Type(type.seqType())) + ")" finishingNode() return ret if isinstance(type, idltype.Fixed): return prefix + "fixed_tc(%d,%d)" % (type.digits(),type.scale()) assert isinstance(type, idltype.Declared) if type.kind() == idltype.tk_objref: scopedName = type.decl().scopedName() if scopedName == ["CORBA", "Object"]: return prefix + "Object_tc()" scopedName = id.Name(scopedName) repoID = type.decl().repoId() iname = scopedName.simple() return prefix + 'interface_tc("' + repoID + '", "' + iname + '")' guard_name = id.Name(type.scopedName()).guard() return config.state['Private Prefix'] + "_tc_" + guard_name # ---------------------------------------------------------------# Tree-walking part of module starts here# ---------------------------------------------------------------# Control arrives here#def visitAST(node): self.__completedModules = {} for n in node.declarations(): if ast.shouldGenerateCodeForDecl(n): n.accept(self)def visitModule(node): slash_scopedName = string.join(node.scopedName(), '/') if self.__completedModules.has_key(slash_scopedName): return self.__completedModules[slash_scopedName] = 1 # This has a bearing on making symbols externally visible/ linkable insideModule = self.__immediatelyInsideModule self.__immediatelyInsideModule = 1 for n in node.definitions(): n.accept(self) # Treat a reopened module as if it had been defined all at once for c in node.continuations(): slash_scopedName = string.join(c.scopedName(), '/') self.__completedModules[slash_scopedName] = 1 for n in c.definitions(): n.accept(self) self.__immediatelyInsideModule = insideModule# builds an instance of CORBA::PR_structMember containing pointers# to all the TypeCodes of the structure membersdef buildMembersStructure(node): struct = output.StringStream() mangled_name = mangleName(config.state['Private Prefix'] + \ "_structmember_", node.scopedName()) if alreadyDefined(mangled_name): # no need to regenerate return struct
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -