summaryrefslogtreecommitdiffstats
path: root/Mac/Tools
diff options
context:
space:
mode:
authorJack Jansen <jack.jansen@cwi.nl>1998-06-26 14:56:00 (GMT)
committerJack Jansen <jack.jansen@cwi.nl>1998-06-26 14:56:00 (GMT)
commit144fa678d28492b5544b6a31d947b3cd1a2e5ef9 (patch)
treebed5ac957f360dd4622a49d3295c3ce5a8c0e4b2 /Mac/Tools
parentfa68b07526082bfcece1c5a17ef63e46fc7cb82b (diff)
downloadcpython-144fa678d28492b5544b6a31d947b3cd1a2e5ef9.zip
cpython-144fa678d28492b5544b6a31d947b3cd1a2e5ef9.tar.gz
cpython-144fa678d28492b5544b6a31d947b3cd1a2e5ef9.tar.bz2
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.
Diffstat (limited to 'Mac/Tools')
-rw-r--r--Mac/Tools/macfreeze/directives.py39
-rw-r--r--Mac/Tools/macfreeze/macfreeze.py72
-rw-r--r--Mac/Tools/macfreeze/macfreeze.rsrc.hqx21
-rw-r--r--Mac/Tools/macfreeze/macfreezegui.py158
-rw-r--r--Mac/Tools/macfreeze/macgen_bin.py6
-rw-r--r--Mac/Tools/macfreeze/macgen_info.py8
-rw-r--r--Mac/Tools/macfreeze/macgen_rsrc.py35
-rw-r--r--Mac/Tools/macfreeze/macgen_src.py109
-rw-r--r--Mac/Tools/macfreeze/macgenerate.py8
-rw-r--r--Mac/Tools/macfreeze/macmodulefinder.py101
10 files changed, 557 insertions, 0 deletions
diff --git a/Mac/Tools/macfreeze/directives.py b/Mac/Tools/macfreeze/directives.py
new file mode 100644
index 0000000..e233745
--- /dev/null
+++ b/Mac/Tools/macfreeze/directives.py
@@ -0,0 +1,39 @@
+import re
+import os
+
+# The regular expression for freeze directives. These are comments with the
+# word macfreeze immedeately followed by a colon, followed by a directive,
+# followed by argument(s)
+#
+# The directives supported are
+# include - Include a module or file
+# exclude - Exclude a module
+# path - Add sys.path entries. Relative paths are relative to the source file.
+#
+# See the macfreeze.py main program for a real live example.
+#
+DIRECTIVE_RE=r'^\s*#\s*macfreeze:\s*(\S*)\s*(.*)\s*$'
+REPROG=re.compile(DIRECTIVE_RE)
+
+def findfreezedirectives(program):
+ extra_modules = []
+ exclude_modules = []
+ extra_path = []
+ progdir, filename = os.path.split(program)
+ fp = open(program)
+ for line in fp.readlines():
+ match = REPROG.match(line)
+ if match:
+ directive = match.group(1)
+ argument = match.group(2)
+ if directive == 'include':
+ extra_modules.append(argument)
+ elif directive == 'exclude':
+ exclude_modules.append(argument)
+ elif directive == 'path':
+ argument = os.path.join(progdir, argument)
+ extra_path.append(argument)
+ else:
+ print '** Unknown directive', line
+ return extra_modules, exclude_modules, extra_path
+
diff --git a/Mac/Tools/macfreeze/macfreeze.py b/Mac/Tools/macfreeze/macfreeze.py
new file mode 100644
index 0000000..60962ee
--- /dev/null
+++ b/Mac/Tools/macfreeze/macfreeze.py
@@ -0,0 +1,72 @@
+"""macfreeze - Main program and GUI
+
+macfreeze allows you to turn Python scripts into fully self-contained
+Mac applications, by including all the Python and C code needed in a single
+executable. Like unix/windows freeze it can produce a config.c allowing you
+to build the application with a development environment (CodeWarrior, to be
+precise), but unlike the standard freeze it is also possible to create frozen
+applications without a development environment, by glueing all the
+shared libraries and extension modules needed together in a single
+executable, using some Code Fragment Manager tricks."""
+
+import macfs
+import sys
+import EasyDialogs
+import string
+
+import macfreezegui
+import macmodulefinder
+
+#
+# Here are the macfreeze directives, used when freezing macfreeze itself
+# (see directives.py for an explanation)
+#
+# macfreeze: path ::::Tools:freeze
+# macfreeze: exclude win32api
+#
+
+def main():
+ if len(sys.argv) < 2:
+ gentype, program, output, debug = macfreezegui.dialog()
+ elif len(sys.argv) == 2:
+ gentype, program, output, debug = macfreezegui.dialog(sys.argv[1])
+ else:
+ EasyDialog.Message(
+ "Please pass a single script. Additional modules can be specified with directives")
+ sys.exit(0)
+ 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)
+ except macmodulefinder.Missing, arg:
+ arg.sort()
+ print '** Missing modules:', string.join(arg, ' ')
+ sys.exit(1)
+ #
+ # And generate
+ #
+ if gentype == 'info':
+ import macgen_info
+ macgen_info.generate(output, module_dict)
+ return 1 # So the user can inspect it
+ elif gentype == 'source':
+ import macgen_src
+ warnings = macgen_src.generate(output, module_dict, debug)
+ return warnings
+ elif gentype == 'resource':
+ import macgen_rsrc
+ macgen_rsrc.generate(output, module_dict, debug)
+ warnings = macgen_rsrc.warnings(module_dict)
+ return warnings
+ elif gentype == 'applet':
+ import macgen_bin
+ macgen_bin.generate(output, module_dict, debug)
+ else:
+ raise 'unknown gentype', gentype
+
+if __name__ == '__main__':
+ main()
+
diff --git a/Mac/Tools/macfreeze/macfreeze.rsrc.hqx b/Mac/Tools/macfreeze/macfreeze.rsrc.hqx
new file mode 100644
index 0000000..303068b
--- /dev/null
+++ b/Mac/Tools/macfreeze/macfreeze.rsrc.hqx
@@ -0,0 +1,21 @@
+(This file must be converted with BinHex 4.0)
+
+:$QeKBfCbC@9kC5jbFh*M!(*cFQ058d9%!3#3"`1-AQF!N!3"!!!!!cS!!!)k!!!
+!8M4lA$"F-M!dA$)`0(YF-&`b-$4F-M!dHe``A$)`0&`b$QeKBfCbC@9kC5jbFh*
+MFfaKH@9bFR0bG(4iG#ia0f`!-(*cFQ058d9%!3!!J!#"!*!5XE4#FJ#3"J0ZA$-
+b-&`c0cGF-&`b06"F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-&`c0cG
+F-&`b06"F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-&`c0cGF-&`b06"
+F-c)`A$-h0e``A$)e-&`c-M"F-cFhA$"F-M8`A$-b-!!!!"J!2!!U!@)"m3!&!*!
+)!J!!!$!+!!!#'J!6!*!&$`!*!"m!9)J(8f0bDA"d1J#3"Ji!L`!H!@@)"R0MFQP
+`G!#3"3d"F3!K!Ed%#8*bEhGcC5iZ,R)!N!93!!N!BJ&P"L0(C@jPFQ&dC5"bCA0
+[GA*MC5"KEQ3JFfpeFQ0P)'C[FL"$9f`!N!9S!"X!H!#"L!j2GA4`GA3JCQpXC'9
+b1J#3"@J!L`"i!@@)"R0MFQP`G!#3"@F"F3"k!Ed%#8*bEhGcC5iZ,Q%!N!@%!!N
+!PJ&P"Kp(C@jPFQ&dC5"3@8-JFQ9cEh9bBf8JCQPXC5"[EQajG!#3"Cd!'`#Y!(f
+)$%peG("eG#"QD@aP1J#3"Ci!L!#Y!@@)"R0MFQP`G!#3"CX"F!#[!Ed%#8*bEhG
+cC5iZ,Q%!N!@j!!N!bJ&L"L9(C@jPFQ&dC5"KF("XD@0KG'P[EL"QFQpY)(0SBA*
+PC#"XD@*cE!#3"G%!'`$K!(b)$%peG("eG#"QD@aP1J#3"G%!L!$K!@@)"R0MFQP
+`G!#3"Fm"E`$M!Ed%#8*bEhGcC5iZ,T`!N!3""`&[!4X"[33#6dX!N!3""J!,!4S
+!8!3'3f&ZBf9X!*!&+J!*!$X!ISJ04'9LG@FJ)'aPGQ9X1XJ!N!8U!)X!1J$@%!%
+aG!#3"H`!#3$q!@-'%%PZCQpbE@&dD@pZ)'pZE(N!!!%!!!!$1J!!!MS!!!"5"cH
+I$#UD!!!!(!"'!!&%6%p(!!!!%N4*9%`!!!!H!J#3"`FhXI3#!2rr!!!!(!FhY5!
+,6@&TEL"ND@&XEfGZ5!:
diff --git a/Mac/Tools/macfreeze/macfreezegui.py b/Mac/Tools/macfreeze/macfreezegui.py
new file mode 100644
index 0000000..bd70c00
--- /dev/null
+++ b/Mac/Tools/macfreeze/macfreezegui.py
@@ -0,0 +1,158 @@
+"""macfreezegui - The GUI for macfreeze"""
+import Dlg
+import macfs
+import EasyDialogs
+import sys
+import os
+import string
+import Res
+
+ID_MAINDIALOG=512
+
+ITEM_SCRIPTNAME=2
+ITEM_SCRIPTBROWSE=3
+ITEM_GENSOURCE=4
+ITEM_GENSOURCE_ITEMS=(7,)
+ITEM_SOURCEDIRNAME=6
+ITEM_SOURCEDIRBROWSE=7
+ITEM_GENRESOURCE=8
+ITEM_GENRESOURCE_ITEMS=(11,)
+ITEM_RESOURCENAME=10
+ITEM_RESOURCEBROWSE=11
+ITEM_GENAPPLET=12
+ITEM_GENAPPLET_ITEMS=(15,)
+ITEM_APPLETNAME=14
+ITEM_APPLETBROWSE=15
+ITEM_OK=16
+ITEM_CANCEL=17
+ITEM_DEBUG=19
+ITEM_GENINFO=20
+
+RADIO_GROUPING={
+ ITEM_GENSOURCE: ITEM_GENSOURCE_ITEMS,
+ ITEM_GENRESOURCE: ITEM_GENRESOURCE_ITEMS,
+ ITEM_GENAPPLET: ITEM_GENAPPLET_ITEMS,
+ ITEM_GENINFO: ()
+}
+
+def dialog(script=None):
+
+ # Invent the various names
+ if not script:
+ fss, ok = macfs.PromptGetFile("Script?", "TEXT")
+ if not ok:
+ sys.exit(0)
+ script = fss.as_pathname()
+ basename, ext = os.path.splitext(script)
+ if ext:
+ appletname = basename
+ rsrcname = basename + 'modules.rsrc'
+ else:
+ appletname = script + '.applet'
+ rsrcname = script + 'modules.rsrc'
+ dirname, basebase = os.path.split(basename)
+ dirname = os.path.join(dirname, 'build.'+basebase)
+
+ # Get the dialog, possibly opening the resource file (if needed)
+ try:
+ d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
+ except Dlg.Error:
+ d = None
+ if d == None:
+ try:
+ Res.OpenResFile('macfreeze.rsrc')
+ except Res.Error:
+ d = None
+ else:
+ d = Dlg.GetNewDialog(ID_MAINDIALOG, -1)
+ if d == None:
+ EasyDialogs.Message("Dialog resource not found or faulty")
+ sys.exit(1)
+
+ # Fill the dialog
+ d.SetDialogDefaultItem(ITEM_OK)
+ d.SetDialogCancelItem(ITEM_CANCEL)
+
+ _dialogsetfile(d, ITEM_SCRIPTNAME, script)
+ _dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
+ _dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
+ _dialogsetfile(d, ITEM_APPLETNAME, appletname)
+
+ gentype = ITEM_GENSOURCE
+ _dialogradiogroup(d, ITEM_GENSOURCE)
+
+ # Interact
+ d.GetDialogWindow().SetWTitle("Standalone application creation options")
+ d.GetDialogWindow().ShowWindow()
+ d.DrawDialog()
+ while 1:
+ item = Dlg.ModalDialog(None)
+ if item == ITEM_OK:
+ break
+ elif item == ITEM_CANCEL:
+ sys.exit(0)
+ elif item in RADIO_GROUPING.keys():
+ gentype = item
+ _dialogradiogroup(d, item)
+ elif item == ITEM_SCRIPTBROWSE:
+ fss, ok = macfs.PromptGetFile("Script?")
+ if ok:
+ script = fss.as_pathname()
+ _dialogsetfile(d, ITEM_SCRIPTNAME, script)
+ elif item == ITEM_SOURCEDIRBROWSE:
+ fss, ok = macfs.StandardPutFile("Output folder name", os.path.split(dirname)[1])
+ if ok:
+ dirname = fss.as_pathname()
+ _dialogsetfile(d, ITEM_SOURCEDIRNAME, dirname)
+ elif item == ITEM_RESOURCEBROWSE:
+ fss, ok = macfs.StandardPutFile("Resource output file", os.path.split(rsrcname)[1])
+ if ok:
+ rsrcname = fss.as_pathname()
+ _dialogsetfile(d, ITEM_RESOURCENAME, rsrcname)
+ elif item == ITEM_APPLETBROWSE:
+ fss, ok = macfs.StandardPutFile("Applet output file", os.path.split(appletname)[1])
+ if ok:
+ appletname = fss.as_pathname()
+ _dialogsetfile(d, ITEM_APPLETNAME, appletname)
+ else:
+ pass
+ tp, h, rect = d.GetDialogItem(ITEM_DEBUG)
+ debug = Dlg.GetDialogItemText(h)
+ try:
+ debug = string.atoi(string.strip(debug))
+ except ValueError:
+ EasyDialogs.Message("Illegal debug value %s, set to zero."%`debug`)
+ debug = 0
+ if gentype == ITEM_GENSOURCE:
+ return 'source', script, dirname, debug
+ elif gentype == ITEM_GENRESOURCE:
+ return 'resource', script, rsrcname, debug
+ elif gentype == ITEM_GENAPPLET:
+ return 'applet', script, appletname, debug
+ elif gentype == ITEM_GENINFO:
+ return 'info', script, '', debug
+ raise 'Error in gentype', gentype
+
+def _dialogradiogroup(d, item):
+ for k in RADIO_GROUPING.keys():
+ subitems = RADIO_GROUPING[k]
+ tp, h, rect = d.GetDialogItem(k)
+ if k == item:
+ h.as_Control().SetControlValue(1)
+ for i2 in subitems:
+ d.ShowDialogItem(i2)
+ else:
+ h.as_Control().SetControlValue(0)
+ for i2 in subitems:
+ d.HideDialogItem(i2)
+
+def _dialogsetfile(d, item, file):
+ if len(file) > 32:
+ file = '\311:' + os.path.split(file)[1]
+ tp, h, rect = d.GetDialogItem(item)
+ Dlg.SetDialogItemText(h, file)
+
+if __name__ == '__main__':
+ type, script, file, debug = dialog()
+ print type, script, file, 'debug=%d'%debug
+ sys.exit(1)
diff --git a/Mac/Tools/macfreeze/macgen_bin.py b/Mac/Tools/macfreeze/macgen_bin.py
new file mode 100644
index 0000000..d524e9b
--- /dev/null
+++ b/Mac/Tools/macfreeze/macgen_bin.py
@@ -0,0 +1,6 @@
+"""macgen_bin - Generate application from shared libraries"""
+import EasyDialogs
+
+def generate(output, module_dict):
+ EasyDialogs.Message('Not yet implemented')
+
diff --git a/Mac/Tools/macfreeze/macgen_info.py b/Mac/Tools/macfreeze/macgen_info.py
new file mode 100644
index 0000000..9ec6aa0
--- /dev/null
+++ b/Mac/Tools/macfreeze/macgen_info.py
@@ -0,0 +1,8 @@
+"""macgen_info - Generate informational output"""
+
+def generate(output, module_dict):
+ for name in module_dict.keys():
+ print 'Include %-20s\t'%name,
+ module = module_dict[name]
+ print module.gettype(), '\t', `module`
+ return 0
diff --git a/Mac/Tools/macfreeze/macgen_rsrc.py b/Mac/Tools/macfreeze/macgen_rsrc.py
new file mode 100644
index 0000000..107e734
--- /dev/null
+++ b/Mac/Tools/macfreeze/macgen_rsrc.py
@@ -0,0 +1,35 @@
+"""macgen_info - Generate PYC resource file only"""
+import EasyDialogs
+import py_resource
+import Res
+import sys
+
+def generate(output, module_dict, debug=0, preload=1):
+ fsid = py_resource.create(output)
+
+ for name, module in module_dict.items():
+ if module.gettype() != 'module':
+ continue
+ location = module.__file__
+
+ if location[-4:] == '.pyc':
+ # Attempt corresponding .py
+ location = location[:-1]
+ if location[-3:] != '.py':
+ print '*** skipping', location
+ continue
+
+ id, name = py_resource.frompyfile(location, name, preload=preload)
+ if debug > 0:
+ print 'PYC resource %5d\t%s\t%s'%(id, name, location)
+
+ Res.CloseResFile(fsid)
+
+def warnings(module_dict):
+ problems = 0
+ for name, module in module_dict.items():
+ if module.gettype() not in ('builtin', 'module'):
+ problems = problems + 1
+ print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
+ return problems
+
diff --git a/Mac/Tools/macfreeze/macgen_src.py b/Mac/Tools/macfreeze/macgen_src.py
new file mode 100644
index 0000000..ad0739e
--- /dev/null
+++ b/Mac/Tools/macfreeze/macgen_src.py
@@ -0,0 +1,109 @@
+"""macgen_info - Generate CodeWarrior project, config source, resource file"""
+import EasyDialogs
+import os
+import sys
+import macfs
+import MacOS
+import macostools
+import macgen_rsrc
+# Note: this depends on being frozen, or on sys.path already being
+# modified by macmodulefinder.
+import makeconfig
+
+TEMPLATEDIR=os.path.join(sys.prefix, ':Mac:mwerks:projects:build.macfreeze')
+PROJECT_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozen.prj')
+CONFIG_TEMPLATE=os.path.join(TEMPLATEDIR, ':templatefrozenconfig.c')
+BUNDLE_TEMPLATE=os.path.join(TEMPLATEDIR, ':frozenbundle.rsrc')
+
+def generate(output, module_dict, debug=0):
+ problems = 0
+ output_created=0
+ if not os.path.exists(output):
+ print 'Creating project folder', output
+ os.mkdir(output)
+ output_created = 1
+ # Resolve aliases, if needed
+ try:
+ fss, dummy1, dummy2 = macfs.ResolveAliasFile(output)
+ except macfs.error:
+ pass
+ else:
+ newname = fss.as_pathname()
+ if newname != output:
+ if debug:
+ print 'Alias', output
+ print 'Resolved to', newname
+ output = newname
+ # Construct the filenames
+ dummy, outfile = os.path.split(output)
+ build, ext = os.path.splitext(outfile)
+ if build == 'build' and ext[0] == '.':
+ # This is probably a good name for the project
+ projname = ext[1:]
+ else:
+ projname = 'frozenapplet.prj'
+ config_name = os.path.join(output, ':macfrozenconfig.c')
+ project_name = os.path.join(output, ':' + projname + '.prj')
+ resource_name = os.path.join(output, ':frozenmodules.rsrc')
+ bundle_name = os.path.join(output, ':frozenbundle.rsrc')
+
+ # Fill the output folder, if needed.
+ if output_created:
+ # Create the project, if needed
+ if not os.path.exists(project_name):
+ print 'Creating project', project_name
+ if not os.path.exists(PROJECT_TEMPLATE):
+ print '** No template CodeWarrior project found at', PROJECT_TEMPLATE
+ print ' To generate standalone Python applications from source you need'
+ print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
+ print ' for details.'
+ problems = 1
+ else:
+ macostools.copy(PROJECT_TEMPLATE, project_name)
+ print 'A template CodeWarrior project has been copied to', project_name
+ print 'It is up to you to make the following changes:'
+ print '- Change the output file name'
+ print '- Change the search path, unless the folder is in the python home'
+ print '- Add sourcefiles/libraries for any extension modules used'
+ print '- Remove unused sources, to speed up the build process'
+ print '- Remove unused resource files (like tcl/tk) for a smaller binary'
+ problems = 1
+ macostools.copy(BUNDLE_TEMPLATE, bundle_name)
+ print 'A template bundle file has also been copied to', bundle_name
+ print 'You may want to adapt signature, size resource, etc'
+
+
+ # Create the resource file
+ macgen_rsrc.generate(resource_name, module_dict, debug=debug)
+
+ # Create the config.c file
+ if not os.path.exists(CONFIG_TEMPLATE):
+ print '** No template config.c found at', PROJECT_TEMPLATE
+ print ' To generate standalone Python applications from source you need'
+ print ' a full source distribution. Check http://www.cwi.nl/~jack/macpython.html'
+ print ' for details.'
+ problems = 1
+ else:
+ # Find elegible modules (builtins and dynamically loaded modules)
+ c_modules = []
+ for module in module_dict.keys():
+ if module_dict[module].gettype() in ('builtin', 'dynamic'):
+ c_modules.append(module)
+ ifp = open(CONFIG_TEMPLATE)
+ ofp = open(config_name, 'w')
+ makeconfig.makeconfig(ifp, ofp, c_modules)
+ ifp.close()
+ ofp.close()
+ MacOS.SetCreatorAndType(config_name, 'CWIE', 'TEXT')
+
+ if warnings(module_dict):
+ problems = 1
+ return problems
+
+def warnings(module_dict):
+ problems = 0
+ for name, module in module_dict.items():
+ if module.gettype() not in ('builtin', 'module', 'dynamic'):
+ problems = problems + 1
+ print 'Warning: %s not included: %s %s'%(name, module.gettype(), module)
+ return problems
diff --git a/Mac/Tools/macfreeze/macgenerate.py b/Mac/Tools/macfreeze/macgenerate.py
new file mode 100644
index 0000000..6c60605
--- /dev/null
+++ b/Mac/Tools/macfreeze/macgenerate.py
@@ -0,0 +1,8 @@
+"""macgenerate - Generate the out for macfreeze"""
+
+def generate(program, module_dict):
+ for name in module_dict.keys():
+ print 'Include %-20s\t'%name,
+ module = module_dict[name]
+ print module.gettype(), '\t', `module`
+ return 0
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