mirror of
https://github.com/GLEGram/GLEGram-iOS.git
synced 2026-05-08 18:45:20 +02:00
4647310322
Based on Swiftgram 12.5 (Telegram iOS 12.5). All GLEGram features ported and organized in GLEGram/ folder. Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass, Font Replacement, Fake Profile, Chat Export, Plugin System, and more. See CHANGELOG_12.5.md for full details.
302 lines
8.8 KiB
Python
Executable File
302 lines
8.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
""" cdecl.py - parse c declarations
|
|
|
|
(c) 2002, 2003, 2004, 2005 Simon Burton <simon@arrowtheory.com>
|
|
Released under GNU LGPL license.
|
|
|
|
version 0.xx
|
|
|
|
"""
|
|
|
|
import string
|
|
|
|
|
|
class Node(list):
|
|
" A node in a parse tree "
|
|
|
|
def __init__(self,*items,**kw):
|
|
list.__init__( self, items )
|
|
self.lock1 = 0 # these two should be properties (simplifies serializing)
|
|
self.lock2 = 0
|
|
self.verbose = 0
|
|
for key in kw.keys():
|
|
self.__dict__[key] = kw[key]
|
|
|
|
def __str__(self):
|
|
attrs = []
|
|
for item in self:
|
|
if isinstance(item,Node):
|
|
attrs.append( str(item) )
|
|
else:
|
|
attrs.append( repr(item) )
|
|
attrs = ','.join(attrs)
|
|
return "%s(%s)"%(self.__class__.__name__,attrs)
|
|
|
|
def safe_repr( self, tank ):
|
|
tank[ str(self) ] = None
|
|
attrs = []
|
|
for item in self:
|
|
if isinstance(item,Node):
|
|
attrs.append( item.safe_repr(tank) ) # can we use repr here ?
|
|
else:
|
|
attrs.append( repr(item) )
|
|
# this is the dangerous bit:
|
|
for key, val in self.__dict__.items():
|
|
if isinstance(val,Node):
|
|
if str(val) not in tank:
|
|
attrs.append( '%s=%s'%(key,val.safe_repr(tank)) )
|
|
else:
|
|
attrs.append( '%s=%s'%(key,repr(val)) )
|
|
attrs = ','.join(attrs)
|
|
return "%s(%s)"%(self.__class__.__name__,attrs)
|
|
|
|
def __repr__(self):
|
|
#attrs = ','.join( [repr(item) for item in self] + \
|
|
# [ '%s=%s'%(key,repr(val)) for key,val in self.__dict__.items() ] )
|
|
#return "%s%s"%(self.__class__.__name__,tuple(attrs))
|
|
return self.safe_repr({})
|
|
|
|
def __eq__(self,other):
|
|
if not isinstance(other,Node):
|
|
return 0
|
|
if len(self)!=len(other):
|
|
return 0
|
|
for i in range(len(self)):
|
|
if not self[i]==other[i]:
|
|
return 0
|
|
return 1
|
|
|
|
def __ne__(self,other):
|
|
return not self==other
|
|
|
|
def filter(self,cls):
|
|
return [x for x in self if isinstance(x,cls)]
|
|
#return filter( lambda x:isinstance(x,cls), self )
|
|
|
|
def deepfilter(self,cls):
|
|
" bottom-up "
|
|
return [x for x in self.nodes() if isinstance(x,cls)]
|
|
|
|
def find(self,cls):
|
|
for x in self:
|
|
if isinstance(x,cls):
|
|
return x
|
|
return None
|
|
|
|
def deepfind(self,cls):
|
|
" bottom-up isinstance search "
|
|
for x in self:
|
|
if isinstance(x,Node):
|
|
if isinstance(x,cls):
|
|
return x
|
|
node = x.deepfind(cls)
|
|
if node is not None:
|
|
return node
|
|
if isinstance(self,cls):
|
|
return self
|
|
return None
|
|
|
|
def leaves(self):
|
|
for i in self:
|
|
if isinstance( i, Node ):
|
|
for j in i.leaves():
|
|
yield j
|
|
else:
|
|
yield i
|
|
|
|
def nodes(self):
|
|
" bottom-up iteration "
|
|
for i in self:
|
|
if isinstance( i, Node ):
|
|
for j in i.nodes():
|
|
yield j
|
|
yield self
|
|
|
|
def deeplen(self):
|
|
i=0
|
|
if not self.lock2:
|
|
self.lock2=1
|
|
for item in self:
|
|
i+=1
|
|
if isinstance(item,Node):
|
|
i+=item.deeplen()
|
|
self.lock2=0
|
|
else:
|
|
i+=1
|
|
return i
|
|
|
|
def deepstr(self,level=0,comment=False,nl='\n',indent=' '):
|
|
if self.deeplen() < 4:
|
|
nl = ""; indent = ""
|
|
#else:
|
|
#nl="\n"; indent = " "
|
|
s = []
|
|
if not self.lock1:
|
|
self.lock1=1
|
|
for item in self:
|
|
if isinstance(item,Node):
|
|
s.append( indent*(level+1)+item.deepstr(level+1,False,nl,indent) )
|
|
else:
|
|
s.append( indent*(level+1)+repr(item) )
|
|
self.lock1=0
|
|
else:
|
|
for item in self:
|
|
if isinstance(item,Node):
|
|
s.append( indent*(level+1)+"<recursion...>" )
|
|
else:
|
|
s.append( indent*(level+1)+"%s"%repr(item) )
|
|
s = "%s(%s)"%(self.__class__.__name__,nl+string.join(s,","+nl))
|
|
if comment:
|
|
s = '#' + s.replace('\n','\n#')
|
|
return s
|
|
|
|
def clone(self):
|
|
items = []
|
|
for item in self:
|
|
if isinstance(item,Node):
|
|
item = item.clone()
|
|
items.append(item)
|
|
# we skip any attributes...
|
|
return self.__class__(*items)
|
|
|
|
def fastclone(self):
|
|
# XX is it faster ???
|
|
#print "clone"
|
|
nodes = [self]
|
|
idxs = [0]
|
|
itemss = [ [] ]
|
|
while nodes:
|
|
assert len(nodes)==len(idxs)==len(itemss)
|
|
node = nodes[-1]
|
|
items = itemss[-1]
|
|
assert idxs[-1] == len(items)
|
|
while idxs[-1]==len(node):
|
|
# pop
|
|
_node = node.__class__( *items )
|
|
_node.__dict__.update( node.__dict__ )
|
|
nodes.pop(-1)
|
|
idxs.pop(-1)
|
|
itemss.pop(-1)
|
|
if not nodes:
|
|
#for node0 in self.nodes():
|
|
#for node1 in _node.nodes():
|
|
#assert node0 is not node1
|
|
#assert _node == self
|
|
return _node # Done !!
|
|
node = nodes[-1]
|
|
items = itemss[-1]
|
|
items.append(_node) # set
|
|
idxs[-1] += 1
|
|
assert idxs[-1] == len(items)
|
|
#assert idxs[-1] < len(node), str( (node,nodes,idxs,itemss) )
|
|
|
|
_node = node[ idxs[-1] ]
|
|
# while idxs[-1]<len(node):
|
|
if isinstance(_node,Node):
|
|
# push
|
|
nodes.append( _node )
|
|
idxs.append( 0 )
|
|
itemss.append( [] )
|
|
else:
|
|
# next
|
|
items.append(_node)
|
|
idxs[-1] += 1
|
|
assert idxs[-1] == len(items)
|
|
|
|
def expose(self,cls):
|
|
' expose children of any <cls> instance '
|
|
# children first
|
|
for x in self:
|
|
if isinstance(x,Node):
|
|
x.expose(cls)
|
|
# now the tricky bit
|
|
i=0
|
|
while i < len(self):
|
|
if isinstance(self[i],cls):
|
|
node=self.pop(i)
|
|
for x in node:
|
|
assert not isinstance(x,cls)
|
|
# pass on some attributes
|
|
if hasattr(node,'lines') and not hasattr(x,'lines'):
|
|
x.lines=node.lines
|
|
if hasattr(node,'file') and not hasattr(x,'file'):
|
|
x.file=node.file
|
|
self.insert(i,x) # expose
|
|
i=i+1
|
|
assert i<=len(self)
|
|
else:
|
|
i=i+1
|
|
|
|
def get_parent( self, item ): # XX 25% CPU time here XX
|
|
assert self != item
|
|
if item in self:
|
|
return self
|
|
for child in self:
|
|
if isinstance(child, Node):
|
|
parent = child.get_parent(item)
|
|
if parent is not None:
|
|
return parent
|
|
return None
|
|
|
|
def expose_node( self, item ):
|
|
assert self != item
|
|
parent = self.get_parent(item)
|
|
idx = parent.index( item )
|
|
parent[idx:idx+1] = item[:]
|
|
|
|
def delete(self,cls):
|
|
' delete any <cls> subtree '
|
|
for x in self:
|
|
if isinstance(x,Node):
|
|
x.delete(cls)
|
|
# now the tricky bit
|
|
i=0
|
|
while i < len(self):
|
|
if isinstance(self[i],cls):
|
|
self.pop(i)
|
|
else:
|
|
i=i+1
|
|
|
|
def deeprm(self,item):
|
|
' remove any items matching <item> '
|
|
for x in self:
|
|
if isinstance(x,Node):
|
|
x.deeprm(item)
|
|
# now the tricky bit
|
|
i=0
|
|
while i < len(self):
|
|
if self[i] == item:
|
|
self.pop(i)
|
|
else:
|
|
i=i+1
|
|
|
|
def idem(self,cls):
|
|
" <cls> is made idempotent "
|
|
# children first
|
|
for x in self:
|
|
if isinstance(x,Node):
|
|
x.idem(cls)
|
|
if isinstance(self,cls):
|
|
# now the tricky bit
|
|
i=0
|
|
while i < len(self):
|
|
if isinstance(self[i],cls):
|
|
node = self.pop(i)
|
|
for x in node:
|
|
assert not isinstance(x,cls)
|
|
self.insert(i,x) # idempotent
|
|
i=i+1
|
|
assert i<=len(self)
|
|
else:
|
|
i=i+1
|
|
|
|
if __name__=="__main__":
|
|
node = Node( 'a', Node(1,2), Node(Node(Node(),1)) )
|
|
|
|
print node
|
|
print node.clone()
|
|
|
|
|
|
|
|
|