1 """codefragments.py -- wrapper to modify code fragments."""
3 # © 1998, Just van Rossum, Letterror
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 if type(srclist
[i
]) == macfs
.FSSpecType
:
32 srclist
[i
] = srclist
[i
].as_pathname()
33 if type(dst
) == macfs
.FSSpecType
:
34 dst
= dst
.as_pathname()
36 dstfile
= open(dst
, "wb")
37 rf
= Res
.OpenResFile(dst
)
39 dstcfrg
= CfrgResource()
41 srccfrg
= CfrgResource(src
)
42 for frag
in srccfrg
.fragments
:
43 if frag
.architecture
== 'pwpc' and architecture
== 'm68k':
45 if frag
.architecture
== 'm68k' and architecture
== 'pwpc':
49 frag
.copydata(dstfile
)
51 cfrgres
= Res
.Resource(dstcfrg
.build())
53 cfrgres
.AddResource('cfrg', 0, "")
56 rf
= Res
.CloseResFile(rf
)
61 def __init__(self
, path
= None):
65 if path
is not None and os
.path
.exists(path
):
66 currentresref
= Res
.CurResFile()
67 resref
= Res
.OpenResFile(path
)
68 Res
.UseResFile(resref
)
71 data
= Res
.Get1Resource('cfrg', 0).data
73 raise Res
.Error
, "no Œcfrg¹ resource found", sys
.exc_traceback
75 Res
.CloseResFile(resref
)
76 Res
.UseResFile(currentresref
)
79 raise error
, "unknown 'cfrg' resource format"
81 def parse(self
, data
):
82 (res1
, res2
, self
.version
,
83 res3
, res4
, res5
, res6
,
84 self
.memberCount
) = struct
.unpack("8l", data
[:32])
87 frag
= FragmentDescriptor(self
.path
, data
)
88 data
= data
[frag
.memberSize
:]
89 self
.fragments
.append(frag
)
92 self
.memberCount
= len(self
.fragments
)
93 data
= struct
.pack("8l", 0, 0, self
.version
, 0, 0, 0, 0, self
.memberCount
)
94 for frag
in self
.fragments
:
95 data
= data
+ frag
.build()
98 def append(self
, frag
):
99 self
.fragments
.append(frag
)
102 class FragmentDescriptor
:
104 def __init__(self
, path
, data
= None):
109 def parse(self
, data
):
110 self
.architecture
= data
[:4]
120 self
.res1
, self
.res2
,
121 self
.memberSize
,) = struct
.unpack("4lhBB4lh", data
[4:42])
122 pname
= data
[42:self
.memberSize
]
123 self
.name
= pname
[1:1+ord(pname
[0])]
126 data
= self
.architecture
127 data
= data
+ struct
.pack("4lhBB4l",
137 self
.res1
, self
.res2
)
138 self
.memberSize
= len(data
) + 2 + 1 + len(self
.name
)
139 # pad to 4 byte boundaries
140 if self
.memberSize
% 4:
141 self
.memberSize
= self
.memberSize
+ 4 - (self
.memberSize
% 4)
142 data
= data
+ struct
.pack("hb", self
.memberSize
, len(self
.name
))
143 data
= data
+ self
.name
144 data
= data
+ '\000' * (self
.memberSize
- len(data
))
147 def getfragment(self
):
149 raise error
, "can¹t read fragment, unsupported location"
150 f
= open(self
.path
, "rb")
153 frag
= f
.read(self
.length
)
159 def copydata(self
, outfile
):
161 raise error
, "can¹t read fragment, unsupported location"
162 infile
= open(self
.path
, "rb")
165 self
.length
= infile
.tell()
167 # Position input file and record new offset from output file
168 infile
.seek(self
.offset
)
170 # pad to 16 byte boundaries
171 offset
= outfile
.tell()
173 offset
= offset
+ 16 - (offset
% 16)
180 outfile
.write(infile
.read(BUFSIZE
))
183 outfile
.write(infile
.read(l
))