mirror of
https://github.com/elliotnunn/macresources.git
synced 2024-12-14 01:31:03 +00:00
77 lines
2.3 KiB
Python
Executable File
77 lines
2.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import macresources
|
|
import sys
|
|
import tempfile
|
|
from os import path
|
|
|
|
def fourcc(s):
|
|
b = s.encode('mac_roman').ljust(4, b' ')
|
|
if len(b) != 4:
|
|
raise ValueError('wrong length')
|
|
return b
|
|
|
|
def seemshex(s):
|
|
s = s.lower()
|
|
if not s: return False
|
|
return all(c in '0123456789abcdef' for c in s)
|
|
|
|
def seemsdec(s):
|
|
if not s: return False
|
|
return all(c in '0123456789' for c in s)
|
|
|
|
def resid(s):
|
|
s = s.lower()
|
|
if s.startswith('0x') and seemshex(s[2:]):
|
|
thenum = int(s[2:], 16)
|
|
if thenum > 0x7fff: thenum -= 0x8000
|
|
elif s.startswith('$') and seemshex(s[1:]):
|
|
thenum = int(s[1:], 16)
|
|
if thenum > 0x7fff: thenum -= 0x8000
|
|
else:
|
|
thenum = int(s)
|
|
if not (-0x8000 <= thenum <= 0x7fff): raise ValueError
|
|
return thenum
|
|
|
|
parser = argparse.ArgumentParser(description='''
|
|
Copy a single MacOS resource from a source file to the standard
|
|
output. If the source filename ends with `.r' or `.rdump', then it
|
|
is parsed using the `SimpleRez' subset of the Rez language. TODO:
|
|
find a way to specify null characters so that desk accessories can
|
|
be looked up by name.
|
|
''')
|
|
|
|
parser.add_argument('srcfile', help='resource file or Rez file')
|
|
parser.add_argument('type', type=fourcc, help='four-byte type of resource (converted to Mac Roman pre-lookup)')
|
|
parser.add_argument('id', type=resid, help='ID number of resource (-32768 to 32767)')
|
|
parser.add_argument('-f', dest='tofile', action='store_true', help='copy to a tempfile instead')
|
|
|
|
args = parser.parse_args()
|
|
|
|
with open(args.srcfile, 'rb') as f:
|
|
raw = f.read()
|
|
|
|
if args.srcfile.endswith('.r') or args.srcfile.endswith('.rdump'):
|
|
resources = macresources.parse_rez_code(raw)
|
|
else:
|
|
resources = macresources.parse_file(raw)
|
|
|
|
for r in resources:
|
|
if r.type == args.type and r.id == args.id:
|
|
myres = r
|
|
break
|
|
else:
|
|
raise ValueError(args.type, args.id)
|
|
|
|
if args.tofile:
|
|
tmpname = '-%s-%s-%d' % (path.basename(args.srcfile), myres.type.decode('mac_roman'), myres.id)
|
|
with tempfile.NamedTemporaryFile(suffix=tmpname, delete=False, mode='wb') as f:
|
|
f.write(myres.data)
|
|
print(f.name)
|
|
else:
|
|
try:
|
|
sys.stdout.buffer.write(myres.data)
|
|
except BrokenPipeError:
|
|
pass
|