Mac version of freeze. Uses standard freeze modules where it can,
augmenting them here and there. For now, it works more-or-less similar
to unix/windows freeze, generating a config.c file, but storing
modules in PYC resources. A template project is also copied.

The hooks are in place to freeze by merging shared libraries so you
can freeze without a C compiler/linker, but this does not work yet.
diff --git a/Mac/Tools/macfreeze/macmodulefinder.py b/Mac/Tools/macfreeze/macmodulefinder.py
new file mode 100644
index 0000000..d87ca9b
--- /dev/null
+++ b/Mac/Tools/macfreeze/macmodulefinder.py
@@ -0,0 +1,101 @@
+"""macmodulefinder - Find modules used in a script. Only slightly
+mac-specific, really."""
+
+import sys
+import os
+
+import directives
+
+try:
+	# This will work if we are frozen ourselves
+	import modulefinder
+except ImportError:
+	# And this will work otherwise
+	_FREEZEDIR=os.path.join(sys.prefix, ':Tools:freeze')
+	sys.path.insert(0, _FREEZEDIR)
+	import modulefinder
+
+#
+# Modules that must be included, and modules that need not be included
+# (but are if they are found)
+#
+MAC_INCLUDE_MODULES=['site', 'exceptions']
+MAC_MAYMISS_MODULES=['posix', 'os2', 'nt', 'dos', 'dospath', 'nturl2path', 'pwd', 'sitecustomize']
+
+# An exception:
+Missing="macmodulefinder.Missing"
+
+class Module(modulefinder.Module):
+	
+	def gettype(self):
+		"""Return type of module"""
+		if self.__path__:
+			return 'package'
+		if self.__code__:
+			return 'module'
+		if self.__file__:
+			return 'dynamic'
+		return 'builtin'
+
+class ModuleFinder(modulefinder.ModuleFinder):
+
+    def add_module(self, fqname):
+        if self.modules.has_key(fqname):
+            return self.modules[fqname]
+        self.modules[fqname] = m = Module(fqname)
+        return m
+        
+def process(program, modules=[], module_files = [], debug=0):
+	error = []
+	#
+	# Add the standard modules needed for startup
+	#
+	modules = modules + MAC_INCLUDE_MODULES
+	#
+	# search the main source for directives
+	#
+	extra_modules, exclude_modules, extra_path = \
+			directives.findfreezedirectives(program)
+	for m in extra_modules:
+		if os.sep in m:
+			# It is a file
+			module_files.append(m)
+		else:
+			modules.append(m)
+	path = extra_path + sys.path[:]
+	#
+	# Create the module finder and let it do its work
+	#
+	modfinder = ModuleFinder(path, 
+			excludes=exclude_modules, debug=debug)
+	for m in modules:
+		modfinder.import_hook(m)
+	for m in module_files:
+		modfinder.load_file(m)
+	modfinder.run_script(program)
+	module_dict = modfinder.modules
+	#
+	# Tell the user about missing modules
+	#
+	maymiss = exclude_modules + MAC_MAYMISS_MODULES
+	for m in modfinder.badmodules.keys():
+		if not m in maymiss:
+			if debug > 0:
+				print 'Missing', m
+			error.append(m)
+	#
+	# Warn the user about unused builtins
+	#
+	for m in sys.builtin_module_names:
+		if m in ('__main__', '__builtin__'):
+			pass
+		elif not module_dict.has_key(m):
+			if debug > 0:
+				print 'Unused', m
+		elif module_dict[m].gettype() != 'builtin':
+			# XXXX Can this happen?
+			if debug > 0:
+				print 'Conflict', m
+	if error:
+		raise Missing, error
+	return module_dict