blob: 0faf1f1ebaed1a361e7a729d415e40d9fce28f0a [file] [log] [blame]
Jack Jansen0acb7f71996-05-31 13:02:21 +00001"""Creation of PYC resources"""
2import os
Jack Jansen5a6fdcd2001-08-25 12:15:04 +00003from Carbon import Res
Jack Jansen0acb7f71996-05-31 13:02:21 +00004import __builtin__
5
6READ = 1
7WRITE = 2
8smAllScripts = -3
9
10def Pstring(str):
11 """Return a pascal-style string from a python-style string"""
12 if len(str) > 255:
13 raise ValueError, 'String too large'
14 return chr(len(str))+str
15
16def create(dst, creator='Pyth'):
17 """Create output file. Return handle and first id to use."""
18
19 try:
20 os.unlink(dst)
21 except os.error:
22 pass
23 Res.FSpCreateResFile(dst, creator, 'rsrc', smAllScripts)
24 return open(dst)
25
26def open(dst):
27 output = Res.FSpOpenResFile(dst, WRITE)
28 Res.UseResFile(output)
29 return output
30
Jack Jansenb93f5211998-08-18 12:23:11 +000031def writemodule(name, id, data, type='PYC ', preload=0, ispackage=0):
Jack Jansen0acb7f71996-05-31 13:02:21 +000032 """Write pyc code to a PYC resource with given name and id."""
33 # XXXX Check that it doesn't exist
Jack Jansenb93f5211998-08-18 12:23:11 +000034
35 # Normally, byte 4-7 are the time stamp, but that is not used
36 # for 'PYC ' resources. We abuse byte 4 as a flag to indicate
37 # that it is a package rather than an ordinary module.
38 # See also macimport.c. (jvr)
39 if ispackage:
40 data = data[:4] + '\377\0\0\0' + data[8:] # flag resource as package
41 else:
42 data = data[:4] + '\0\0\0\0' + data[8:] # clear mod date field, used as package flag
Jack Jansen0acb7f71996-05-31 13:02:21 +000043 res = Res.Resource(data)
44 res.AddResource(type, id, name)
Jack Jansend3b06a81997-06-12 10:50:47 +000045 if preload:
46 attrs = res.GetResAttrs()
47 attrs = attrs | 0x04
48 res.SetResAttrs(attrs)
Jack Jansen0acb7f71996-05-31 13:02:21 +000049 res.WriteResource()
50 res.ReleaseResource()
51
Jack Jansenb93f5211998-08-18 12:23:11 +000052def frompycfile(file, name=None, preload=0, ispackage=0):
Jack Jansen0acb7f71996-05-31 13:02:21 +000053 """Copy one pyc file to the open resource file"""
54 if name == None:
55 d, name = os.path.split(file)
56 name = name[:-4]
57 id = findfreeid()
Jack Jansenb93f5211998-08-18 12:23:11 +000058 data = __builtin__.open(file, 'rb').read()
59 writemodule(name, id, data, preload=preload, ispackage=ispackage)
Jack Jansen0acb7f71996-05-31 13:02:21 +000060 return id, name
61
Jack Jansenb93f5211998-08-18 12:23:11 +000062def frompyfile(file, name=None, preload=0, ispackage=0):
Jack Jansen0acb7f71996-05-31 13:02:21 +000063 """Compile python source file to pyc file and add to resource file"""
64 import py_compile
65
66 py_compile.compile(file)
67 file = file +'c'
Jack Jansenb93f5211998-08-18 12:23:11 +000068 return frompycfile(file, name, preload=preload, ispackage=ispackage)
Jack Jansen0acb7f71996-05-31 13:02:21 +000069
70# XXXX Note this is incorrect, it only handles one type and one file....
71
72_firstfreeid = None
73
74def findfreeid(type='PYC '):
75 """Find next free id-number for given resource type"""
76 global _firstfreeid
77
78 if _firstfreeid == None:
79 Res.SetResLoad(0)
80 highest = 511
81 num = Res.Count1Resources(type)
82 for i in range(1, num+1):
83 r = Res.Get1IndResource(type, i)
84 id, d1, d2 = r.GetResInfo()
85 highest = max(highest, id)
86 Res.SetResLoad(1)
87 _firstfreeid = highest+1
88 id = _firstfreeid
89 _firstfreeid = _firstfreeid+1
90 return id