cfmfile.py revision 0a8c90248264a8b26970b4473770bcc3df8515f
10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao"""codefragments.py -- wrapper to modify code fragments.""" 20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 30a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# (c) 1998, Just van Rossum, Letterror 40a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 50a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__version__ = "0.8b3" 60a8c90248264a8b26970b4473770bcc3df8515fJosh Gao__author__ = "jvr" 70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport warnings 90a8c90248264a8b26970b4473770bcc3df8515fJosh Gaowarnings.warnpy3k("the cfmfile module is deprecated and is removed in 3,0", 100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao stacklevel=2) 110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 120a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport Carbon.File 130a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport struct 140a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom Carbon import Res 150a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport os 160a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport sys 170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 180a8c90248264a8b26970b4473770bcc3df8515fJosh GaoDEBUG = 0 190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 200a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoerror = "cfm.error" 210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 220a8c90248264a8b26970b4473770bcc3df8515fJosh GaoBUFSIZE = 0x80000 230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 240a8c90248264a8b26970b4473770bcc3df8515fJosh Gaodef mergecfmfiles(srclist, dst, architecture = 'fat'): 250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """Merge all files in srclist into a new file dst. 260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If architecture is given, only code fragments of that type will be used: 280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao "pwpc" for PPC, "m68k" for cfm68k. This does not work for "classic" 290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 68k code, since it does not use code fragments to begin with. 300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao If architecture is None, all fragments will be used, enabling FAT binaries. 310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao """ 320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao srclist = list(srclist) 340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for i in range(len(srclist)): 350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao srclist[i] = Carbon.File.pathname(srclist[i]) 360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dst = Carbon.File.pathname(dst) 370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dstfile = open(dst, "wb") 390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rf = Res.FSpOpenResFile(dst, 3) 400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dstcfrg = CfrgResource() 420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for src in srclist: 430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao srccfrg = CfrgResource(src) 440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for frag in srccfrg.fragments: 450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if frag.architecture == 'pwpc' and architecture == 'm68k': 460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if frag.architecture == 'm68k' and architecture == 'pwpc': 480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao continue 490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dstcfrg.append(frag) 500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao frag.copydata(dstfile) 520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cfrgres = Res.Resource(dstcfrg.build()) 540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Res.UseResFile(rf) 550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao cfrgres.AddResource('cfrg', 0, "") 560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao dstfile.close() 580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao rf = Res.CloseResFile(rf) 590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 610a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass CfrgResource: 620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, path = None): 640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.version = 1 650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fragments = [] 660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.path = path 670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if path is not None and os.path.exists(path): 680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao currentresref = Res.CurResFile() 690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao resref = Res.FSpOpenResFile(path, 1) 700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Res.UseResFile(resref) 710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao try: 730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = Res.Get1Resource('cfrg', 0).data 740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao except Res.Error: 750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise Res.Error, "no 'cfrg' resource found", sys.exc_traceback 760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao finally: 770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Res.CloseResFile(resref) 780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao Res.UseResFile(currentresref) 790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.parse(data) 800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.version != 1: 810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise error, "unknown 'cfrg' resource format" 820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def parse(self, data): 840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao (res1, res2, self.version, 850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao res3, res4, res5, res6, 860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.memberCount) = struct.unpack("8l", data[:32]) 870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data[32:] 880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while data: 890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao frag = FragmentDescriptor(self.path, data) 900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data[frag.memberSize:] 910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fragments.append(frag) 920a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def build(self): 940a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.memberCount = len(self.fragments) 950a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = struct.pack("8l", 0, 0, self.version, 0, 0, 0, 0, self.memberCount) 960a8c90248264a8b26970b4473770bcc3df8515fJosh Gao for frag in self.fragments: 970a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data + frag.build() 980a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return data 990a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1000a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def append(self, frag): 1010a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fragments.append(frag) 1020a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1030a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1040a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass FragmentDescriptor: 1050a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1060a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def __init__(self, path, data = None): 1070a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.path = path 1080a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if data is not None: 1090a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.parse(data) 1100a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def parse(self, data): 1120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.architecture = data[:4] 1130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao ( self.updatelevel, 1140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.currentVersion, 1150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.oldDefVersion, 1160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.stacksize, 1170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.applibdir, 1180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fragtype, 1190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.where, 1200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.offset, 1210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.length, 1220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.res1, self.res2, 1230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.memberSize,) = struct.unpack("4lhBB4lh", data[4:42]) 1240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao pname = data[42:self.memberSize] 1250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.name = pname[1:1+ord(pname[0])] 1260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def build(self): 1280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = self.architecture 1290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data + struct.pack("4lhBB4l", 1300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.updatelevel, 1310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.currentVersion, 1320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.oldDefVersion, 1330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.stacksize, 1340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.applibdir, 1350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.fragtype, 1360a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.where, 1370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.offset, 1380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.length, 1390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.res1, self.res2) 1400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.memberSize = len(data) + 2 + 1 + len(self.name) 1410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # pad to 4 byte boundaries 1420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.memberSize % 4: 1430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.memberSize = self.memberSize + 4 - (self.memberSize % 4) 1440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data + struct.pack("hb", self.memberSize, len(self.name)) 1450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data + self.name 1460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao data = data + '\000' * (self.memberSize - len(data)) 1470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return data 1480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def getfragment(self): 1500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.where != 1: 1510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise error, "can't read fragment, unsupported location" 1520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f = open(self.path, "rb") 1530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f.seek(self.offset) 1540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.length: 1550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao frag = f.read(self.length) 1560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao frag = f.read() 1580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao f.close() 1590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao return frag 1600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao def copydata(self, outfile): 1620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.where != 1: 1630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao raise error, "can't read fragment, unsupported location" 1640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao infile = open(self.path, "rb") 1650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if self.length == 0: 1660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao infile.seek(0, 2) 1670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.length = infile.tell() 1680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # Position input file and record new offset from output file 1700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao infile.seek(self.offset) 1710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao # pad to 16 byte boundaries 1730a8c90248264a8b26970b4473770bcc3df8515fJosh Gao offset = outfile.tell() 1740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if offset % 16: 1750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao offset = offset + 16 - (offset % 16) 1760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao outfile.seek(offset) 1770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao self.offset = offset 1780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao 1790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l = self.length 1800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao while l: 1810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao if l > BUFSIZE: 1820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao outfile.write(infile.read(BUFSIZE)) 1830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l = l - BUFSIZE 1840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao else: 1850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao outfile.write(infile.read(l)) 1860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao l = 0 1870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao infile.close() 188