Implementation of freezing from shared libraries, without source. (Just)
diff --git a/Mac/Tools/macfreeze/macfreeze.py b/Mac/Tools/macfreeze/macfreeze.py
index 60962ee..2f43e20 100644
--- a/Mac/Tools/macfreeze/macfreeze.py
+++ b/Mac/Tools/macfreeze/macfreeze.py
@@ -37,7 +37,7 @@
 	mustwait = process(gentype, program, output, debug=debug)
 	if mustwait:
 		sys.exit(1)
-		
+
 def process(gentype, program, output, modules=[], module_files=[], debug=0):
 	try:
 		module_dict = macmodulefinder.process(program, modules, module_files, debug)
@@ -63,10 +63,10 @@
 		return warnings
 	elif gentype == 'applet':
 		import macgen_bin
-		macgen_bin.generate(output, module_dict, debug)
+		architecture = 'fat' # user should choose
+		macgen_bin.generate(program, output, module_dict, architecture, debug)
 	else:
 		raise 'unknown gentype', gentype
-			
+
 if __name__ == '__main__':
 	main()
-		
diff --git a/Mac/Tools/macfreeze/macgen_bin.py b/Mac/Tools/macfreeze/macgen_bin.py
index d524e9b..a4ee828 100644
--- a/Mac/Tools/macfreeze/macgen_bin.py
+++ b/Mac/Tools/macfreeze/macgen_bin.py
@@ -1,6 +1,200 @@
 """macgen_bin - Generate application from shared libraries"""
-import EasyDialogs
 
-def generate(output, module_dict):
-	EasyDialogs.Message('Not yet implemented')
+import os
+import sys
+import string
+import types
+import macfs
+from MACFS import *
+import Res
+import py_resource
+import cfmfile
+import buildtools
+
+
+def generate(input, output, module_dict = None, architecture = 'fat', debug=0):
+	# try to remove old file
+	try:
+		os.remove(output)
+	except:
+		pass
 	
+	if module_dict is None:
+		import macmodulefinder
+		print "Searching for modules..."
+		module_dict = macmodulefinder.process(input, [], [], 1)
+	
+	applettemplatepath = buildtools.findtemplate()
+	corepath = findpythoncore()
+	
+	dynamicmodules, dynamicfiles, extraresfiles = findfragments(module_dict, architecture)
+	
+	print "Adding ³__main__²"
+	buildtools.process(applettemplatepath, input, output, 0)
+	
+	outputref = Res.OpenResFile(output)
+	try:
+		Res.UseResFile(outputref)
+		
+		print "Adding Python modules"
+		addpythonmodules(module_dict)
+		
+		print "Adding PythonCore resources"
+		copyres(corepath, outputref, ['cfrg', 'Popt', 'GUÂ…I'], 1)
+		
+		print "Adding resources from shared libraries"
+		for ppcpath, cfm68kpath in extraresfiles:
+			if os.path.exists(ppcpath):
+				copyres(ppcpath, outputref, ['cfrg'], 1)
+			elif os.path.exists(cfm68kpath):
+				copyres(cfm68kpath, outputref, ['cfrg'], 1)
+		
+		print "Fixing sys.path prefs"
+		Res.UseResFile(outputref)
+		try:
+			res = Res.Get1Resource('STR#', 228) # from PythonCore
+		except Res.Error: pass
+		else:
+			res.RemoveResource()
+		# setting pref file name to empty string
+		res = Res.Get1NamedResource('STR ', "PythonPreferenceFileName")
+		res.data = Pstring("")
+		res.ChangedResource()
+		syspathpref = "$(APPLICATION)"
+		res = Res.Resource("\000\001" + Pstring(syspathpref))
+		res.AddResource("STR#", 229, "sys.path preference")
+		
+		print "Creating 'PYD ' resources"
+		for modname, (ppcfrag, cfm68kfrag) in dynamicmodules.items():
+			res = Res.Resource(Pstring(ppcfrag) + Pstring(cfm68kfrag))
+			id = 0
+			while id < 128:
+				id = Res.Unique1ID('PYD ')
+			res.AddResource('PYD ', id, modname)
+	finally:
+		Res.CloseResFile(outputref)
+	print "Merging code fragments"
+	cfmfile.mergecfmfiles([applettemplatepath, corepath] + dynamicfiles.keys(), 
+			output, architecture)
+	
+	fss = macfs.FSSpec(output)
+	fss.SetCreatorType('Pyta', 'APPL')
+	print "done!"
+
+
+def findfragments(module_dict, architecture):
+	dynamicmodules = {}
+	dynamicfiles = {}
+	extraresfiles = []
+	for name, module in module_dict.items():
+		if module.gettype() <> 'dynamic':
+			continue
+		path = resolvealiasfile(module.__file__)
+		dir, filename = os.path.split(path)
+		ppcfile, cfm68kfile = makefilenames(filename)
+		
+		# ppc stuff
+		ppcpath = os.path.join(dir, ppcfile)
+		if architecture <> 'm68k':
+			ppcfrag, dynamicfiles = getfragname(ppcpath, dynamicfiles)
+		else:
+			ppcfrag = "_no_fragment_"
+		
+		# 68k stuff
+		cfm68kpath = os.path.join(dir, cfm68kfile)
+		if architecture <> 'pwpc':
+			cfm68kfrag, dynamicfiles = getfragname(cfm68kpath, dynamicfiles)
+		else:
+			cfm68kfrag = "_no_fragment_"
+		
+		dynamicmodules[name] = ppcfrag, cfm68kfrag
+		if (ppcpath, cfm68kpath) not in extraresfiles:
+			extraresfiles.append((ppcpath, cfm68kpath))
+	return dynamicmodules, dynamicfiles, extraresfiles
+
+
+def getfragname(path, dynamicfiles):
+	if not dynamicfiles.has_key(path):
+		if os.path.exists(path):
+			lib = cfmfile.CfrgResource(path)
+			fragname = lib.fragments[0].name
+		else:
+			print "shared lib not found:", path
+			fragname = "_no_fragment_"
+		dynamicfiles[path] = fragname
+	else:
+		fragname = dynamicfiles[path]
+	return fragname, dynamicfiles
+
+
+def addpythonmodules(module_dict):
+	items = module_dict.items()
+	items.sort()
+	for name, module in items:
+		if module.gettype() != 'module' or name == "__main__":
+			continue
+		location = module.__file__
+		
+		if location[-4:] == '.pyc':
+			# Attempt corresponding .py
+			location = location[:-1]
+		if location[-3:] != '.py':
+			print '*** skipping', location
+			continue
+		
+		print 'Adding module ³%s²' % name
+		id, name = py_resource.frompyfile(location, name, preload=0)
+
+def Pstring(str):
+	if len(str) > 255:
+		raise TypeError, "Str255 must be at most 255 chars long"
+	return chr(len(str)) + str
+
+def makefilenames(name):
+	lname = string.lower(name)
+	pos = string.find(lname, ".ppc.")
+	if pos > 0:
+		return name, name[:pos] + '.CFM68K.' + name[pos+5:]
+	pos = string.find(lname, ".cfm68k.")
+	if pos > 0:
+		return name[:pos] + '.ppc.' + name[pos+8:], name
+	raise ValueError, "can't make ppc/cfm68k filenames"
+
+def copyres(input, output, *args, **kwargs):
+	openedin = openedout = 0
+	if type(input) == types.StringType:
+		input = Res.OpenResFile(input)
+		openedin = 1
+	if type(output) == types.StringType:
+		output = Res.OpenResFile(output)
+		openedout = 1
+	try:
+		apply(buildtools.copyres, (input, output) + args, kwargs)
+	finally:
+		if openedin:
+			Res.CloseResFile(input)
+		if openedout:
+			Res.CloseResFile(output)
+
+def findpythoncore():
+	"""find the PythonCore shared library, possibly asking the user if we can't find it"""
+	
+	vRefNum, dirID = macfs.FindFolder(kOnSystemDisk, kExtensionFolderType, 0)
+	extpath = macfs.FSSpec((vRefNum, dirID, "")).as_pathname()
+	version = string.split(sys.version)[0]
+	corepath = os.path.join(extpath, "PythonCore " + version)
+	if not os.path.exists(corepath):
+		fss, ok = macfs.PromptGetFile("Please locate PythonCore:", "shlb")
+		if not ok:
+			raise KeyboardInterrupt, "cancelled"
+		corepath = fss.as_pathname()
+	return resolvealiasfile(corepath)
+
+def resolvealiasfile(path):
+	try:
+		fss, dummy1, dummy2 = macfs.ResolveAliasFile(path)
+	except macfs.error:
+		pass
+	else:
+		path = fss.as_pathname()
+	return path