[Lldb-commits] [lldb] r343242 - Add an interactive mode to BSD archive parser.
Greg Clayton via lldb-commits
lldb-commits at lists.llvm.org
Thu Sep 27 10:45:14 PDT 2018
Author: gclayton
Date: Thu Sep 27 10:45:14 2018
New Revision: 343242
URL: http://llvm.org/viewvc/llvm-project?rev=343242&view=rev
Log:
Add an interactive mode to BSD archive parser.
Modified:
lldb/trunk/examples/python/bsd.py
Modified: lldb/trunk/examples/python/bsd.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/examples/python/bsd.py?rev=343242&r1=343241&r2=343242&view=diff
==============================================================================
--- lldb/trunk/examples/python/bsd.py (original)
+++ lldb/trunk/examples/python/bsd.py Thu Sep 27 10:45:14 2018
@@ -1,5 +1,6 @@
#!/usr/bin/python
+import cmd
import optparse
import os
import shlex
@@ -76,6 +77,22 @@ class Object(object):
self.file.seek(saved_pos, 0)
return bytes
+ def save(self, path=None, overwrite=False):
+ '''
+ Save the contents of the object to disk using 'path' argument as
+ the path, or save it to the current working directory using the
+ object name.
+ '''
+
+ if path is None:
+ path = self.name
+ if not overwrite and os.path.exists(path):
+ print('error: outfile "%s" already exists' % (path))
+ return
+ print('Saving "%s" to "%s"...' % (self.name, path))
+ with open(path, 'w') as f:
+ f.write(self.get_bytes())
+
class StringTable(object):
def __init__(self, bytes):
@@ -186,6 +203,67 @@ class Archive(object):
for obj in self.objects:
obj.dump(f=f, flat=flat)
+class Interactive(cmd.Cmd):
+ '''Interactive prompt for exploring contents of BSD archive files, type
+ "help" to see a list of supported commands.'''
+ image_option_parser = None
+
+ def __init__(self, archives):
+ cmd.Cmd.__init__(self)
+ self.use_rawinput = False
+ self.intro = ('Interactive BSD archive prompt, type "help" to see a '
+ 'list of supported commands.')
+ self.archives = archives
+ self.prompt = '% '
+
+ def default(self, line):
+ '''Catch all for unknown command, which will exit the interpreter.'''
+ print("unknown command: %s" % line)
+ return True
+
+ def do_q(self, line):
+ '''Quit command'''
+ return True
+
+ def do_quit(self, line):
+ '''Quit command'''
+ return True
+
+ def do_extract(self, line):
+ args = shlex.split(line)
+ if args:
+ extracted = False
+ for object_name in args:
+ for archive in self.archives:
+ matches = archive.find(object_name)
+ if matches:
+ for object in matches:
+ object.save(overwrite=False)
+ extracted = True
+ if not extracted:
+ print('error: no object matches "%s" in any archives' % (
+ object_name))
+ else:
+ print('error: must specify the name of an object to extract')
+
+ def do_ls(self, line):
+ args = shlex.split(line)
+ if args:
+ for object_name in args:
+ for archive in self.archives:
+ matches = archive.find(object_name)
+ if matches:
+ for object in matches:
+ object.dump(flat=False)
+ else:
+ print('error: no object matches "%s" in "%s"' % (
+ object_name, archive.path))
+ else:
+ for archive in self.archives:
+ archive.dump(flat=True)
+ print('')
+
+
def main():
parser = optparse.OptionParser(
@@ -243,9 +321,24 @@ def main():
'then the extracted object file will be extracted into the '
'current working directory if a file doesn\'t already exist '
'with that name.'))
+ parser.add_option(
+ '-i', '--interactive',
+ action='store_true',
+ dest='interactive',
+ default=False,
+ help=('Enter an interactive shell that allows users to interactively '
+ 'explore contents of .a files.'))
(options, args) = parser.parse_args(sys.argv[1:])
+ if options.interactive:
+ archives = []
+ for path in args:
+ archives.append(Archive(path))
+ interpreter = Interactive(archives)
+ interpreter.cmdloop()
+ return
+
for path in args:
archive = Archive(path)
if options.object_name:
@@ -256,17 +349,7 @@ def main():
if options.extract:
if len(matches) == 1:
dump_all = False
- if options.outfile is None:
- outfile_path = matches[0].name
- else:
- outfile_path = options.outfile
- if os.path.exists(outfile_path):
- print('error: outfile "%s" already exists' % (
- outfile_path))
- else:
- print('Saving file to "%s"...' % (outfile_path))
- with open(outfile_path, 'w') as outfile:
- outfile.write(matches[0].get_bytes())
+ matches[0].save(path=options.outfile, overwrite=False)
else:
print('error: multiple objects match "%s". Specify '
'the modification time using --mtime.' % (
More information about the lldb-commits
mailing list