Skip to content

Commit

Permalink
modify-python-lldb.py: (Re)move __len__ and __iter__ support
Browse files Browse the repository at this point in the history
Summary:
This patch moves the modify-python-lldb code for adding new functions to
the SBModule class into the SBModule interface file. As this is the last
class using this functionality, I also remove all support for this kind
of modifications from modify-python-lldb.py.

Reviewers: amccarth, clayborg, jingham

Subscribers: zturner, lldb-commits

Differential Revision: https://reviews.llvm.org/D60195

llvm-svn: 357680
  • Loading branch information
labath committed Apr 4, 2019
1 parent 5ad10f4 commit e090389
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 106 deletions.
Expand Up @@ -45,6 +45,7 @@ def test_module_and_section(self):

print("Exe module: %s" % str(exe_module))
print("Number of sections: %d" % exe_module.GetNumSections())
print("Number of symbols: %d" % len(exe_module))
INDENT = ' ' * 4
INDENT2 = INDENT * 2
for sec in exe_module.section_iter():
Expand Down
103 changes: 3 additions & 100 deletions lldb/scripts/Python/modify-python-lldb.py
Expand Up @@ -75,55 +75,6 @@ def char_to_str_xform(line):
'^(%s|%s)""".*"""$' %
(TWO_SPACES, EIGHT_SPACES))

# This supports the iteration protocol.
iter_def = " def __iter__(self): return lldb_iter(self, '%s', '%s')"
section_iter = " def section_iter(self): return lldb_iter(self, '%s', '%s')"
compile_unit_iter = " def compile_unit_iter(self): return lldb_iter(self, '%s', '%s')"

# Called to implement the built-in function len().
# Eligible objects are those containers with unambiguous iteration support.
len_def = " def __len__(self): return self.%s()"

# A convenience iterator for SBSymbol!
symbol_in_section_iter_def = '''
def symbol_in_section_iter(self, section):
"""Given a module and its contained section, returns an iterator on the
symbols within the section."""
for sym in self:
if in_range(sym, section):
yield sym
'''

#
# This dictionary defines a mapping from classname to (getsize, getelem) tuple.
#
d = {'SBModule': ('GetNumSymbols', 'GetSymbolAtIndex'),

# SBModule has an additional section_iter(), see below.
'SBModule-section': ('GetNumSections', 'GetSectionAtIndex'),
# And compile_unit_iter().
'SBModule-compile-unit': ('GetNumCompileUnits', 'GetCompileUnitAtIndex'),
# As well as symbol_in_section_iter().
'SBModule-symbol-in-section': symbol_in_section_iter_def
}

def list_to_frag(list):
"""Transform a list to equality program fragment.
For example, ['GetID'] is transformed to 'self.GetID() == other.GetID()',
and ['GetFilename', 'GetDirectory'] to 'self.GetFilename() == other.GetFilename()
and self.GetDirectory() == other.GetDirectory()'.
"""
if not list:
raise Exception("list should be non-empty")
frag = StringIO.StringIO()
for i in range(len(list)):
if i > 0:
frag.write(" and ")
frag.write("self.{0}() == other.{0}()".format(list[i]))
return frag.getvalue()


class NewContent(StringIO.StringIO):
"""Simple facade to keep track of the previous line to be committed."""

Expand Down Expand Up @@ -159,34 +110,16 @@ def finish(self):
with open(output_name, 'r') as f_in:
content = f_in.read()

# The pattern for recognizing the beginning of an SB class definition.
class_pattern = re.compile("^class (SB.*)\(_object\):$")

# The pattern for recognizing the beginning of the __init__ method definition.
init_pattern = re.compile("^ def __init__\(self.*\):")

# These define the states of our finite state machine.
NORMAL = 1
DEFINING_ITERATOR = 2
CLEANUP_DOCSTRING = 8

# Our FSM begins its life in the NORMAL state, and transitions to the
# DEFINING_ITERATOR state whenever it encounters the beginning of certain class
# definitions, see dictionary 'd' above.
#
# In the DEFINING_ITERATOR state, the FSM is eagerly searching for the __init__
# method definition in order to insert the appropriate method(s) into the lldb
# module.
#
# The state CLEANUP_DOCSTRING can be entered from either the NORMAL or the
# DEFINING_ITERATOR state. While in this state, the FSM is fixing/cleaning the
# Python docstrings generated by the swig docstring features.
# Our FSM begins its life in the NORMAL state. The state CLEANUP_DOCSTRING can
# be entered from the NORMAL. While in this state, the FSM is fixing/cleaning
# the Python docstrings generated by the swig docstring features.
state = NORMAL

for line in content.splitlines():
# Handle the state transition into CLEANUP_DOCSTRING state as it is possible
# to enter this state from either NORMAL or DEFINING_ITERATOR/EQUALITY.
#
# If ' """' is the sole line, prepare to transition to the
# CLEANUP_DOCSTRING state or out of it.

Expand All @@ -199,36 +132,6 @@ def finish(self):
else:
state |= CLEANUP_DOCSTRING

if state == NORMAL:
match = class_pattern.search(line)
# If we are at the beginning of the class definitions, prepare to
# transition to the DEFINING_ITERATOR state for the right class names.
if match:
cls = match.group(1)
if cls in d:
# Adding support for iteration for the matched SB class.
state |= DEFINING_ITERATOR

if state & DEFINING_ITERATOR:
match = init_pattern.search(line)
if match:
# We found the beginning of the __init__ method definition.
# This is a good spot to insert the iter support.

new_content.add_line(iter_def % d[cls])
new_content.add_line(len_def % d[cls][0])

# SBModule has extra SBSection, SBCompileUnit iterators and
# symbol_in_section_iter()!
if cls == "SBModule":
new_content.add_line(section_iter % d[cls + '-section'])
new_content.add_line(compile_unit_iter %
d[cls + '-compile-unit'])
new_content.add_line(d[cls + '-symbol-in-section'])

# Next state will be NORMAL.
state = NORMAL

if (state & CLEANUP_DOCSTRING):
# Cleanse the lldb.py of the autodoc'ed residues.
if c_ifdef_swig in line or c_endif_swig in line:
Expand Down
23 changes: 23 additions & 0 deletions lldb/scripts/interface/SBModule.i
Expand Up @@ -370,6 +370,29 @@ public:
operator != (const lldb::SBModule &rhs) const;

%pythoncode %{
def __len__(self):
'''Return the number of symbols in a lldb.SBModule object.'''
return self.GetNumSymbols()

def __iter__(self):
'''Iterate over all symbols in a lldb.SBModule object.'''
return lldb_iter(self, 'GetNumSymbols', 'GetSymbolAtIndex')

def section_iter(self):
'''Iterate over all sections in a lldb.SBModule object.'''
return lldb_iter(self, 'GetNumSections', 'GetSectionAtIndex')

def compile_unit_iter(self):
'''Iterate over all compile units in a lldb.SBModule object.'''
return lldb_iter(self, 'GetNumCompileUnits', 'GetCompileUnitAtIndex')

def symbol_in_section_iter(self, section):
'''Given a module and its contained section, returns an iterator on the
symbols within the section.'''
for sym in self:
if in_range(sym, section):
yield sym

class symbols_access(object):
re_compile_type = type(re.compile('.'))
'''A helper object that will lazily hand out lldb.SBSymbol objects for a module when supplied an index, name, or regular expression.'''
Expand Down
6 changes: 0 additions & 6 deletions lldb/scripts/lldb.swig
Expand Up @@ -91,12 +91,6 @@ def lldb_iter(obj, getsize, getelem):
elem = getattr(obj, getelem)
for i in range(size()):
yield elem(i)

# ==============================================================================
# The modify-python-lldb.py script is responsible for post-processing this SWIG-
# generated lldb.py module. It is responsible for adding support for: iteration
# protocol: __iter__, and built-in function len(): __len__.
# ==============================================================================
%}

%include "./Python/python-typemaps.swig"
Expand Down

0 comments on commit e090389

Please sign in to comment.