Files
python-uncompyle6/scripts/uncompyle2
Josh ef0f83232f call python via /usr/bin/env python =more portable
The shebang line of the uncompyle2 script is not using /usr/bin/env python causing it to fail to run when invoked as a standalone script

```Shell
uncompyle2# ./scripts/uncompyle2 -h
bash: ./scripts/uncompyle2: python: bad interpreter: No such file or directory
```
Changing the shebang line to #!/usr/bin/env python fixes the problem and is best practice (or so I'm told)

```Shell
uncompyle2# ./scripts/uncompyle2 -h

Usage: uncompyle2 [OPTIONS]... [ FILE | DIR]...
...snip...
```
2015-06-23 15:55:55 -05:00

188 lines
6.0 KiB
Python
Executable File

#!/usr/bin/env python
# Mode: -*- python -*-
#
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
#
'''
Usage: uncompyle2 [OPTIONS]... [ FILE | DIR]...
Examples:
uncompyle2 foo.pyc bar.pyc # decompile foo.pyc, bar.pyc to stdout
uncompyle2 -o . foo.pyc bar.pyc # decompile to ./foo.pyc_dis and ./bar.pyc_dis
uncompyle2 -o /tmp /usr/lib/python1.5 # decompile whole library
Options:
-o <path> output decompiled files to this path:
if multiple input files are decompiled, the common prefix
is stripped from these names and the remainder appended to
<path>
uncompyle -o /tmp bla/fasel.pyc bla/foo.pyc
-> /tmp/fasel.pyc_dis, /tmp/foo.pyc_dis
uncompyle -o /tmp bla/fasel.pyc bar/foo.pyc
-> /tmp/bla/fasel.pyc_dis, /tmp/bar/foo.pyc_dis
uncompyle -o /tmp /usr/lib/python1.5
-> /tmp/smtplib.pyc_dis ... /tmp/lib-tk/FixTk.pyc_dis
-c <file> attempts a disassembly after compiling <file>
-d do not print timestamps
-p <integer> use <integer> number of processes
-r recurse directories looking for .pyc and .pyo files
--verify compare generated source with input byte-code
(requires -o)
--help show this message
Debugging Options:
--showasm -a include byte-code (disables --verify)
--showast -t include AST (abstract syntax tree) (disables --verify)
Extensions of generated files:
'.pyc_dis' '.pyo_dis' successfully decompiled (and verified if --verify)
+ '_unverified' successfully decompile but --verify failed
+ '_failed' decompile failed (contact author for enhancement)
'''
Usage_short = \
"uncompyle2 [--help] [--verify] [--showasm] [--showast] [-o <path>] FILE|DIR..."
import sys, os, getopt
import os.path
from uncompyle2 import main, verify
import time
if sys.version[:3] != '2.7':
print >>sys.stderr, 'Error: uncompyle2 requires Python 2.7.'
sys.exit(-1)
showasm = showast = do_verify = numproc = recurse_dirs = 0
outfile = '-'
out_base = None
codes = []
timestamp = True
timestampfmt = "# %Y.%m.%d %H:%M:%S %Z"
try:
opts, files = getopt.getopt(sys.argv[1:], 'hatdro:c:p:',
['help', 'verify', 'showast', 'showasm'])
except getopt.GetoptError, e:
print >>sys.stderr, '%s: %s' % (os.path.basename(sys.argv[0]), e)
sys.exit(-1)
for opt, val in opts:
if opt in ('-h', '--help'):
print __doc__
sys.exit(0)
elif opt == '--verify':
do_verify = 1
elif opt in ('--showasm', '-a'):
showasm = 1
do_verify = 0
elif opt in ('--showast', '-t'):
showast = 1
do_verify = 0
elif opt == '-o':
outfile = val
elif opt == '-d':
timestamp = False
elif opt == '-c':
codes.append(val)
elif opt == '-p':
numproc = int(val)
elif opt == '-r':
recurse_dirs = 1
else:
print opt
print Usage_short
sys.exit(1)
# expand directory if specified
if recurse_dirs:
expanded_files = []
for f in files:
if os.path.isdir(f):
for root, _, dir_files in os.walk(f):
for df in dir_files:
if df.endswith('.pyc') or df.endswith('.pyo'):
expanded_files.append(os.path.join(root, df))
files = expanded_files
# argl, commonprefix works on strings, not on path parts,
# thus we must handle the case with files in 'some/classes'
# and 'some/cmds'
src_base = os.path.commonprefix(files)
if src_base[-1:] != os.sep:
src_base = os.path.dirname(src_base)
if src_base:
sb_len = len( os.path.join(src_base, '') )
files = map(lambda f: f[sb_len:], files)
del sb_len
if outfile == '-':
outfile = None # use stdout
elif outfile and os.path.isdir(outfile):
out_base = outfile; outfile = None
elif outfile and len(files) > 1:
out_base = outfile; outfile = None
if timestamp:
print time.strftime(timestampfmt)
if numproc <= 1:
try:
result = main(src_base, out_base, files, codes, outfile, showasm, showast, do_verify)
print '# decompiled %i files: %i okay, %i failed, %i verify failed' % result
except (KeyboardInterrupt):
pass
except verify.VerifyCmpError:
raise
else:
from multiprocessing import Process, Queue
from Queue import Empty
fqueue = Queue(len(files)+numproc)
for f in files:
fqueue.put(f)
for i in range(numproc):
fqueue.put(None)
rqueue = Queue(numproc)
def process_func():
try:
(tot_files, okay_files, failed_files, verify_failed_files) = (0,0,0,0)
while 1:
f = fqueue.get()
if f == None:
break
(t, o, f, v) = \
main(src_base, out_base, [f], codes, outfile, showasm, showast, do_verify)
tot_files += t
okay_files += o
failed_files += f
verify_failed_files += v
except (Empty, KeyboardInterrupt):
pass
rqueue.put((tot_files, okay_files, failed_files, verify_failed_files))
rqueue.close()
try:
procs = [Process(target=process_func) for i in range(numproc)]
for p in procs:
p.start()
for p in procs:
p.join()
try:
(tot_files, okay_files, failed_files, verify_failed_files) = (0,0,0,0)
while 1:
(t, o, f, v) = rqueue.get(False)
tot_files += t
okay_files += o
failed_files += f
verify_failed_files += v
except Empty:
pass
print '# decompiled %i files: %i okay, %i failed, %i verify failed' % \
(tot_files, okay_files, failed_files, verify_failed_files)
except (KeyboardInterrupt, OSError):
pass
if timestamp:
print time.strftime(timestampfmt)