1 """codefragments.py -- wrapper to modify code fragments."""
3 # (c) 1998, Just van Rossum, Letterror
10 from Carbon
import Res
20 def mergecfmfiles(srclist
, dst
, architecture
= 'fat'):
21 """Merge all files in srclist into a new file dst.
23 If architecture is given, only code fragments of that type will be used:
24 "pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic"
25 68k code, since it does not use code fragments to begin with.
26 If architecture is None, all fragments will be used, enabling FAT binaries.
29 srclist
= list(srclist
)
30 for i
in range(len(srclist
)):
31 srclist
[i
] = Carbon
.File
.pathname(srclist
[i
])
32 dst
= Carbon
.File
.pathname(dst
)
34 dstfile
= open(dst
, "wb")
35 rf
= Res
.FSpOpenResFile(dst
, 3)
37 dstcfrg
= CfrgResource()
39 srccfrg
= CfrgResource(src
)
40 for frag
in srccfrg
.fragments
:
41 if frag
.architecture
== 'pwpc' and architecture
== 'm68k':
43 if frag
.architecture
== 'm68k' and architecture
== 'pwpc':
47 frag
.copydata(dstfile
)
49 cfrgres
= Res
.Resource(dstcfrg
.build())
51 cfrgres
.AddResource('cfrg', 0, "")
54 rf
= Res
.CloseResFile(rf
)
59 def __init__(self
, path
= None):
63 if path
is not None and os
.path
.exists(path
):
64 currentresref
= Res
.CurResFile()
65 resref
= Res
.FSpOpenResFile(path
, 1)
66 Res
.UseResFile(resref
)
69 data
= Res
.Get1Resource('cfrg', 0).data
71 raise Res
.Error
, "no 'cfrg' resource found", sys
.exc_traceback
73 Res
.CloseResFile(resref
)
74 Res
.UseResFile(currentresref
)
77 raise error
, "unknown 'cfrg' resource format"
79 def parse(self
, data
):
80 (res1
, res2
, self
.version
,
81 res3
, res4
, res5
, res6
,
82 self
.memberCount
) = struct
.unpack("8l", data
[:32])
85 frag
= FragmentDescriptor(self
.path
, data
)
86 data
= data
[frag
.memberSize
:]
87 self
.fragments
.append(frag
)
90 self
.memberCount
= len(self
.fragments
)
91 data
= struct
.pack("8l", 0, 0, self
.version
, 0, 0, 0, 0, self
.memberCount
)
92 for frag
in self
.fragments
:
93 data
= data
+ frag
.build()
96 def append(self
, frag
):
97 self
.fragments
.append(frag
)
100 class FragmentDescriptor
:
102 def __init__(self
, path
, data
= None):
107 def parse(self
, data
):
108 self
.architecture
= data
[:4]
118 self
.res1
, self
.res2
,
119 self
.memberSize
,) = struct
.unpack("4lhBB4lh", data
[4:42])
120 pname
= data
[42:self
.memberSize
]
121 self
.name
= pname
[1:1+ord(pname
[0])]
124 data
= self
.architecture
125 data
= data
+ struct
.pack("4lhBB4l",
135 self
.res1
, self
.res2
)
136 self
.memberSize
= len(data
) + 2 + 1 + len(self
.name
)
137 # pad to 4 byte boundaries
138 if self
.memberSize
% 4:
139 self
.memberSize
= self
.memberSize
+ 4 - (self
.memberSize
% 4)
140 data
= data
+ struct
.pack("hb", self
.memberSize
, len(self
.name
))
141 data
= data
+ self
.name
142 data
= data
+ '\000' * (self
.memberSize
- len(data
))
145 def getfragment(self
):
147 raise error
, "can't read fragment, unsupported location"
148 f
= open(self
.path
, "rb")
151 frag
= f
.read(self
.length
)
157 def copydata(self
, outfile
):
159 raise error
, "can't read fragment, unsupported location"
160 infile
= open(self
.path
, "rb")
163 self
.length
= infile
.tell()
165 # Position input file and record new offset from output file
166 infile
.seek(self
.offset
)
168 # pad to 16 byte boundaries
169 offset
= outfile
.tell()
171 offset
= offset
+ 16 - (offset
% 16)
178 outfile
.write(infile
.read(BUFSIZE
))
181 outfile
.write(infile
.read(l
))