📄 descriptor.py
字号:
# -*- python -*-# Package : omniidl# descriptor.py Created on: 2000/08/23# 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 internal descriptors## $Id: descriptor.py,v 1.1.4.6 2003/10/23 11:55:12 dgrisby Exp $# $Log: descriptor.py,v $# Revision 1.1.4.6 2003/10/23 11:55:12 dgrisby# Fix hex_word for Python 1.5.2.## Revision 1.1.4.5 2003/08/21 15:06:03 dgrisby# Avoid spurious Python 2.3 complaints about unsigned long integers.## Revision 1.1.4.4 2001/06/08 17:12:12 dpg1# Merge all the bug fixes from omni3_develop.## Revision 1.1.4.3 2001/03/26 11:11:54 dpg1# Python clean-ups. Output routine optimised.## Revision 1.1.4.2 2001/03/13 10:34:01 dpg1# Minor Python clean-ups## Revision 1.1.4.1 2000/10/12 15:37:47 sll# Updated from omni3_1_develop.## Revision 1.1.2.1 2000/09/14 16:03:02 djs# Remodularised C++ descriptor name generator# Bug in listing all inherited interfaces if one is a forward# repoID munging function now handles #pragma ID in bootstrap.idl# Naming environments generating code now copes with new IDL AST types# Modified type utility functions# Minor tidying#from omniidl import idlvisitor, idlastfrom omniidl_be.cxx import config, id, astimport string# All descriptors are of the form:# TAG _ PREFIX _ BASE# TAG: groups descriptors by type (eg context, call descriptor, callback)# PREFIX: derived from a hash of the first callable in the IDL# BASE: counter added to guarantee uniqueness# There are two categories of descriptors.# o Signature dependent (where there is only one instance per operation# signature, which can be shared by multiple interfaces) eg normal# call descriptors.# o Interface & operation dependent eg local callback functionsdef __init__(ast): global prefix, counter, signature_descriptors, iface_descriptors prefix = "" counter = 0 # Descriptors keyed by signature alone signature_descriptors = {} # Descriptors keyed by interface and operation name (a two level # hashtable) iface_descriptors = {} # initialise the prefix HV = HashVisitor() ast.accept(HV)def call_descriptor(signature): return private_prefix + "_cd_" + get_signature_descriptor(signature)def context_descriptor(signature): return private_prefix + "_ctx_" + get_signature_descriptor(signature)def local_callback_fn(iname, operation_name, signature): return private_prefix + "_lcfn_" +\ get_interface_operation_descriptor(iname, operation_name, signature)###################################################################### Internalsprivate_prefix = config.state['Private Prefix']# Walks over the AST, finds the first callable and creates the prefix hashclass HashVisitor(idlvisitor.AstVisitor): def __init__(self): self.base_initialised = 0 def visitAST(self, node): for declaration in node.declarations(): if self.base_initialised: return if ast.shouldGenerateCodeForDecl(declaration): declaration.accept(self) def visitModule(self, node): for definition in node.definitions(): if self.base_initialised: return definition.accept(self) def visitInterface(self, node): if node.callables() != []: name = node.scopedName() # Use an op first if available for c in node.callables(): if isinstance(c, idlast.Operation): self.initialise_base(name + [c.identifier()]) return # Use first attribute self.initialise_base(name + [node.callables()[0].identifiers()[0]]) # Knuth-style string -> int hash def initialise_base(self, name): if self.base_initialised: return self.base_initialised = 1 string_seed = id.Name(name).guard() # equivalent to >> only without sign extension # (python uses 2's complement signed arithmetic) def rshift(x, distance): sign_bit = x & 0x80000000L # remove the sign bit to make it unsigned x = x & 0x7fffffffL # perform shift (thinks number is unsigned, no extension) x = x >> distance # add sign bit back in if sign_bit: x = x | (1 << (32 - distance -1)) return x def lshift(x, distance): # same as non-sign extended case return (x << distance) & 0xffffffffL high = low = 0L for char in string_seed: tmp = rshift((high & 0xfe000000L), 25) high = (lshift(high, 7)) ^ (rshift((low & 0xfe000000L), 25)) low = lshift(low, 7) ^ tmp low = low ^ (ord(char)) high = list(hex_word(high)) low = list(hex_word(low)) high.reverse() low.reverse() global prefix prefix = string.join(high + low, "")# Return a unique PREFIX + BASEdef unique(): global counter clist = list(hex_word(counter)) clist.reverse() name = prefix + "_" + string.join(clist, "") counter = counter + 1 return namedef get_signature_descriptor(signature): global signature_descriptors if not signature_descriptors.has_key(signature): signature_descriptors[signature] = unique() return signature_descriptors[signature]def get_interface_operation_descriptor(iname, operation_name, signature): global iface_descriptors assert isinstance(iname, id.Name) key = iname.hash() if not iface_descriptors.has_key(key): iface_descriptors[key] = {} iface_table = iface_descriptors[key] key = signature + "/" + operation_name if iface_table.has_key(key): return iface_table[key] descriptor = unique() iface_table[key] = descriptor return descriptor# Takes an int and returns the int in hex, without leading 0x and with# 0s padding. Can't use %08x because Python 1.5.2 can't do it with# longs >= 2**31.def hex_word(x): s = hex(x)[2:] if s[-1] == "L": s = s[:-1] return string.zfill(s, 8)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -