summaryrefslogtreecommitdiff
path: root/Mac/Lib/py_resource.py
blob: 0faf1f1ebaed1a361e7a729d415e40d9fce28f0a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
"""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