[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