blob: 0faf1f1ebaed1a361e7a729d415e40d9fce28f0a [file] [log] [blame]
"""Creation of PYC resources"""
import os
from Carbon import Res
import __builtin__
READ = 1
WRITE = 2
smAllScripts = -3
def Pstring(str):
"""Return a pascal-style string from a python-style string"""
if len(str) > 255:
raise ValueError, 'String too large'
return chr(len(str))+str
def create(dst, creator='Pyth'):
"""Create output file. Return handle and first id to use."""
try:
os.unlink(dst)
except os.error:
pass
Res.FSpCreateResFile(dst, creator, 'rsrc', smAllScripts)
return open(dst)
def open(dst):
output = Res.FSpOpenResFile(dst, WRITE)
Res.UseResFile(output)
return output
def writemodule(name, id, data, type='PYC ', preload=0, ispackage=0):
"""Write pyc code to a PYC resource with given name and id."""
# XXXX Check that it doesn't exist
# Normally, byte 4-7 are the time stamp, but that is not used
# for 'PYC ' resources. We abuse byte 4 as a flag to indicate
# that it is a package rather than an ordinary module.
# See also macimport.c. (jvr)
if ispackage:
data = data[:4] + '\377\0\0\0' + data[8:] # flag resource as package
else:
data = data[:4] + '\0\0\0\0' + data[8:] # clear mod date field, used as package flag
res = Res.Resource(data)
res.AddResource(type, id, name)
if preload:
attrs = res.GetResAttrs()
attrs = attrs | 0x04
res.SetResAttrs(attrs)
res.WriteResource()
res.ReleaseResource()
def frompycfile(file, name=None, preload=0, ispackage=0):
"""Copy one pyc file to the open resource file"""
if name == None:
d, name = os.path.split(file)
name = name[:-4]
id = findfreeid()
data = __builtin__.open(file, 'rb').read()
writemodule(name, id, data, preload=preload, ispackage=ispackage)
return id, name
def frompyfile(file, name=None, preload=0, ispackage=0):
"""Compile python source file to pyc file and add to resource file"""
import py_compile
py_compile.compile(file)
file = file +'c'
return frompycfile(file, name, preload=preload, ispackage=ispackage)
# XXXX Note this is incorrect, it only handles one type and one file....
_firstfreeid = None
def findfreeid(type='PYC '):
"""Find next free id-number for given resource type"""
global _firstfreeid
if _firstfreeid == None:
Res.SetResLoad(0)
highest = 511
num = Res.Count1Resources(type)
for i in range(1, num+1):
r = Res.Get1IndResource(type, i)
id, d1, d2 = r.GetResInfo()
highest = max(highest, id)
Res.SetResLoad(1)
_firstfreeid = highest+1
id = _firstfreeid
_firstfreeid = _firstfreeid+1
return id