f
176 lines
| 6.5 KiB
| text/plain
|
FortranFixedLexer
/ tests / f
|
r23860 | #!/usr/bin/env python | ||
""" | ||||
Utility for inspecting files in various ways. | ||||
This tool is like the collection of tools found in a unix environment but are | ||||
cross platform and stable and suitable for our needs in the test suite. | ||||
This can be used instead of tools like: | ||||
[ | ||||
dd | ||||
find | ||||
head | ||||
hexdump | ||||
ls | ||||
md5sum | ||||
readlink | ||||
sha1sum | ||||
stat | ||||
tail | ||||
test | ||||
readlink.py | ||||
md5sum.py | ||||
""" | ||||
|
r29160 | from __future__ import absolute_import | ||
|
r36275 | import binascii | ||
|
r29160 | import glob | ||
|
r29233 | import hashlib | ||
|
r29160 | import optparse | ||
import os | ||||
import re | ||||
import sys | ||||
|
r23860 | |||
|
r34271 | # Python 3 adapters | ||
ispy3 = (sys.version_info[0] >= 3) | ||||
if ispy3: | ||||
def iterbytes(s): | ||||
for i in range(len(s)): | ||||
yield s[i:i + 1] | ||||
else: | ||||
iterbytes = iter | ||||
|
r23860 | def visit(opts, filenames, outfile): | ||
"""Process filenames in the way specified in opts, writing output to | ||||
outfile.""" | ||||
for f in sorted(filenames): | ||||
isstdin = f == '-' | ||||
if not isstdin and not os.path.lexists(f): | ||||
|
r34271 | outfile.write(b'%s: file not found\n' % f.encode('utf-8')) | ||
|
r23860 | continue | ||
quiet = opts.quiet and not opts.recurse or isstdin | ||||
isdir = os.path.isdir(f) | ||||
islink = os.path.islink(f) | ||||
isfile = os.path.isfile(f) and not islink | ||||
dirfiles = None | ||||
content = None | ||||
facts = [] | ||||
if isfile: | ||||
if opts.type: | ||||
|
r36275 | facts.append(b'file') | ||
|
r35488 | if any((opts.hexdump, opts.dump, opts.md5, opts.sha1, opts.sha256)): | ||
|
r32898 | content = open(f, 'rb').read() | ||
|
r23860 | elif islink: | ||
if opts.type: | ||||
|
r36275 | facts.append(b'link') | ||
|
r23860 | content = os.readlink(f) | ||
elif isstdin: | ||||
|
r34271 | content = getattr(sys.stdin, 'buffer', sys.stdin).read() | ||
|
r23860 | if opts.size: | ||
|
r36275 | facts.append(b'size=%d' % len(content)) | ||
|
r23860 | elif isdir: | ||
if opts.recurse or opts.type: | ||||
dirfiles = glob.glob(f + '/*') | ||||
|
r36275 | facts.append(b'directory with %d files' % len(dirfiles)) | ||
|
r23860 | elif opts.type: | ||
|
r36275 | facts.append(b'type unknown') | ||
|
r23860 | if not isstdin: | ||
stat = os.lstat(f) | ||||
|
r23911 | if opts.size and not isdir: | ||
|
r36275 | facts.append(b'size=%d' % stat.st_size) | ||
|
r23912 | if opts.mode and not islink: | ||
|
r36275 | facts.append(b'mode=%o' % (stat.st_mode & 0o777)) | ||
|
r23860 | if opts.links: | ||
|
r36275 | facts.append(b'links=%s' % stat.st_nlink) | ||
|
r23860 | if opts.newer: | ||
# mtime might be in whole seconds so newer file might be same | ||||
if stat.st_mtime >= os.stat(opts.newer).st_mtime: | ||||
|
r36275 | facts.append(b'newer than %s' % opts.newer) | ||
|
r23860 | else: | ||
|
r36275 | facts.append(b'older than %s' % opts.newer) | ||
|
r23860 | if opts.md5 and content is not None: | ||
|
r29233 | h = hashlib.md5(content) | ||
|
r36275 | facts.append(b'md5=%s' % binascii.hexlify(h.digest())[:opts.bytes]) | ||
|
r23860 | if opts.sha1 and content is not None: | ||
|
r29233 | h = hashlib.sha1(content) | ||
|
r36275 | facts.append(b'sha1=%s' % binascii.hexlify(h.digest())[:opts.bytes]) | ||
|
r35488 | if opts.sha256 and content is not None: | ||
h = hashlib.sha256(content) | ||||
|
r36275 | facts.append(b'sha256=%s' % | ||
binascii.hexlify(h.digest())[:opts.bytes]) | ||||
|
r23860 | if isstdin: | ||
|
r34271 | outfile.write(b', '.join(facts) + b'\n') | ||
|
r23860 | elif facts: | ||
|
r34271 | outfile.write(b'%s: %s\n' % (f.encode('utf-8'), b', '.join(facts))) | ||
|
r23860 | elif not quiet: | ||
|
r34271 | outfile.write(b'%s:\n' % f.encode('utf-8')) | ||
|
r23860 | if content is not None: | ||
chunk = content | ||||
if not islink: | ||||
if opts.lines: | ||||
if opts.lines >= 0: | ||||
|
r34271 | chunk = b''.join(chunk.splitlines(True)[:opts.lines]) | ||
|
r23860 | else: | ||
|
r34271 | chunk = b''.join(chunk.splitlines(True)[opts.lines:]) | ||
|
r23860 | if opts.bytes: | ||
if opts.bytes >= 0: | ||||
chunk = chunk[:opts.bytes] | ||||
else: | ||||
chunk = chunk[opts.bytes:] | ||||
if opts.hexdump: | ||||
for i in range(0, len(chunk), 16): | ||||
|
r28044 | s = chunk[i:i + 16] | ||
|
r34271 | outfile.write(b'%04x: %-47s |%s|\n' % | ||
(i, b' '.join( | ||||
b'%02x' % ord(c) for c in iterbytes(s)), | ||||
re.sub(b'[^ -~]', b'.', s))) | ||||
|
r23860 | if opts.dump: | ||
if not quiet: | ||||
|
r34271 | outfile.write(b'>>>\n') | ||
|
r23860 | outfile.write(chunk) | ||
if not quiet: | ||||
|
r34271 | if chunk.endswith(b'\n'): | ||
outfile.write(b'<<<\n') | ||||
|
r23860 | else: | ||
|
r34271 | outfile.write(b'\n<<< no trailing newline\n') | ||
|
r23860 | if opts.recurse and dirfiles: | ||
assert not isstdin | ||||
visit(opts, dirfiles, outfile) | ||||
if __name__ == "__main__": | ||||
parser = optparse.OptionParser("%prog [options] [filenames]") | ||||
parser.add_option("-t", "--type", action="store_true", | ||||
help="show file type (file or directory)") | ||||
parser.add_option("-m", "--mode", action="store_true", | ||||
help="show file mode") | ||||
parser.add_option("-l", "--links", action="store_true", | ||||
help="show number of links") | ||||
parser.add_option("-s", "--size", action="store_true", | ||||
help="show size of file") | ||||
parser.add_option("-n", "--newer", action="store", | ||||
help="check if file is newer (or same)") | ||||
parser.add_option("-r", "--recurse", action="store_true", | ||||
help="recurse into directories") | ||||
parser.add_option("-S", "--sha1", action="store_true", | ||||
help="show sha1 hash of the content") | ||||
|
r35488 | parser.add_option("", "--sha256", action="store_true", | ||
help="show sha256 hash of the content") | ||||
|
r23860 | parser.add_option("-M", "--md5", action="store_true", | ||
help="show md5 hash of the content") | ||||
parser.add_option("-D", "--dump", action="store_true", | ||||
help="dump file content") | ||||
parser.add_option("-H", "--hexdump", action="store_true", | ||||
help="hexdump file content") | ||||
parser.add_option("-B", "--bytes", type="int", | ||||
help="number of characters to dump") | ||||
parser.add_option("-L", "--lines", type="int", | ||||
help="number of lines to dump") | ||||
parser.add_option("-q", "--quiet", action="store_true", | ||||
help="no default output") | ||||
(opts, filenames) = parser.parse_args(sys.argv[1:]) | ||||
if not filenames: | ||||
filenames = ['-'] | ||||
|
r34271 | visit(opts, filenames, getattr(sys.stdout, 'buffer', sys.stdout)) | ||