Added msvccompiler module exactly as supplied by Perry Stoll.
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
new file mode 100644
index 0000000..ff66f91
--- /dev/null
+++ b/Lib/distutils/msvccompiler.py
@@ -0,0 +1,317 @@
+"""distutils.ccompiler
+
+Contains MSVCCompiler, an implementation of the abstract CCompiler class
+for the Microsoft Visual Studio """
+
+
+# created 1999/08/19, Perry Stoll
+# 
+__rcsid__ = "$Id$"
+
+import os
+import sys
+from distutils.errors import *
+from distutils.ccompiler import CCompiler
+
+
+class MSVCCompiler ( CCompiler) :
+    """Abstract base class to define the interface that must be implemented
+       by real compiler abstraction classes.  Might have some use as a
+       place for shared code, but it's not yet clear what code can be
+       shared between compiler abstraction models for different platforms.
+
+       The basic idea behind a compiler abstraction class is that each
+       instance can be used for all the compile/link steps in building
+       a single project.  Thus, attributes common to all of those compile
+       and link steps -- include directories, macros to define, libraries
+       to link against, etc. -- are attributes of the compiler instance.
+       To allow for variability in how individual files are treated,
+       most (all?) of those attributes may be varied on a per-compilation
+       or per-link basis."""
+
+    def __init__ (self,
+                  verbose=0,
+                  dry_run=0):
+
+        CCompiler.__init__ (self, verbose, dry_run)
+
+        
+        # XXX This is a nasty dependency to add on something otherwise
+        #       pretty clean.  move it to build_ext under an nt
+        #       specific part.
+        #       shared libraries need to link against python15.lib
+        self.add_library ( "python" + sys.version[0] + sys.version[2] )
+        self.add_library_dir( os.path.join( sys.exec_prefix, 'libs' ) )
+        
+        self.cc   = "cl.exe"
+        self.link = "link.exe"
+        self.preprocess_options = None
+        self.compile_options = [ '/nologo' ]
+
+        self.ldflags_shared = ['/DLL', '/nologo']
+        self.ldflags_static = [ '/nologo']
+
+    # XXX things not handled by this compiler abstraction model:
+    #   * client can't provide additional options for a compiler,
+    #     e.g. warning, optimization, debugging flags.  Perhaps this
+    #     should be the domain of concrete compiler abstraction classes
+    #     (UnixCCompiler, MSVCCompiler, etc.) -- or perhaps the base
+    #     class should have methods for the common ones.
+    #   * can't put output files (object files, libraries, whatever)
+    #     into a separate directory from their inputs.  Should this be
+    #     handled by an 'output_dir' attribute of the whole object, or a
+    #     parameter to the compile/link_* methods, or both?
+    #   * can't completely override the include or library searchg
+    #     path, ie. no "cc -I -Idir1 -Idir2" or "cc -L -Ldir1 -Ldir2".
+    #     I'm not sure how widely supported this is even by Unix
+    #     compilers, much less on other platforms.  And I'm even less
+    #     sure how useful it is; maybe for cross-compiling, but
+    #     support for that is a ways off.  (And anyways, cross
+    #     compilers probably have a dedicated binary with the
+    #     right paths compiled in.  I hope.)
+    #   * can't do really freaky things with the library list/library
+    #     dirs, e.g. "-Ldir1 -lfoo -Ldir2 -lfoo" to link against
+    #     different versions of libfoo.a in different locations.  I
+    #     think this is useless without the ability to null out the
+    #     library search path anyways.
+    
+
+    # -- Worker methods ------------------------------------------------
+    # (must be implemented by subclasses)
+
+    _c_extensions = [ '.c' ]
+    _cpp_extensions = [ '.cc', 'cpp' ]
+
+    _obj_ext = '.obj'
+    _exe_ext = 'exe'
+    _shared_lib_ext = '.dll'
+    _static_lib_ext = '.lib'
+    
+    def compile (self,
+                 sources,
+                 macros=None,
+                 includes=None):
+        """Compile one or more C/C++ source files.  'sources' must be
+           a list of strings, each one the name of a C/C++ source
+           file.  Return a list of the object filenames generated
+           (one for each source filename in 'sources').
+
+           'macros', if given, must be a list of macro definitions.  A
+           macro definition is either a (name, value) 2-tuple or a (name,)
+           1-tuple.  The former defines a macro; if the value is None, the
+           macro is defined without an explicit value.  The 1-tuple case
+           undefines a macro.  Later definitions/redefinitions/
+           undefinitions take precedence.
+
+           'includes', if given, must be a list of strings, the directories
+           to add to the default include file search path for this
+           compilation only."""
+
+        if macros is None:
+            macros = []
+        if includes is None:
+            includes = []
+
+        objectFiles = []
+
+        base_pp_opts = _gen_preprocess_options (self.macros + macros,
+                                                self.include_dirs + includes)
+
+        base_pp_opts.append('/c')
+        
+        for srcFile in sources:
+            base,ext = os.path.splitext(srcFile)
+            objFile = base + ".obj"
+
+            if ext in self._c_extensions:
+                fileOpt = "/Tc"
+            elif ext in self._cpp_extensions:
+                fileOpt = "/Tp"
+
+            inputOpt  = fileOpt + srcFile
+            outputOpt = "/Fo"   + objFile
+
+            pp_opts = base_pp_opts + [ outputOpt, inputOpt ]
+
+            returnCode = self.spawn( [ self.cc ] + self.compile_options + pp_opts )
+            # XXX check for valid return code
+
+            objectFiles.append( objFile )
+
+
+        return objectFiles
+    
+    # XXX this is kind of useless without 'link_binary()' or
+    # 'link_executable()' or something -- or maybe 'link_static_lib()'
+    # should not exist at all, and we just have 'link_binary()'?
+    def link_static_lib (self,
+                         objects,
+                         output_libname,
+                         libraries=None,
+                         library_dirs=None):
+        """Link a bunch of stuff together to create a static library
+           file.  The "bunch of stuff" consists of the list of object
+           files supplied as 'objects', the extra object files supplied
+           to 'add_link_object()' and/or 'set_link_objects()', the
+           libraries supplied to 'add_library()' and/or
+           'set_libraries()', and the libraries supplied as 'libraries'
+           (if any).
+
+           'output_libname' should be a library name, not a filename;
+           the filename will be inferred from the library name.
+
+           'library_dirs', if supplied, should be a list of additional
+           directories to search on top of the system default and those
+           supplied to 'add_library_dir()' and/or 'set_library_dirs()'."""
+        
+        if libraries is None:
+            libraries = []
+        if library_dirs is None:
+            library_dirs = []
+        if build_info is None:
+            build_info = {}
+        
+        lib_opts = _gen_lib_options (self.libraries + libraries,
+                                     self.library_dirs + library_dirs)
+
+        if build_info.has_key('def_file') :
+            lib_opts.append('/DEF:' + build_info['def_file'] )
+                            
+        ld_args = self.ldflags_static + lib_opts + \
+                  objects + ['/OUT:' + output_filename]
+
+        self.spawn ( [ self.link ] + ld_args )
+    
+
+    def link_shared_lib (self,
+                         objects,
+                         output_libname,
+                         libraries=None,
+                         library_dirs=None,
+                         build_info=None):
+        """Link a bunch of stuff together to create a shared library
+           file.  Has the same effect as 'link_static_lib()' except
+           that the filename inferred from 'output_libname' will most
+           likely be different, and the type of file generated will
+           almost certainly be different."""
+        # XXX should we sanity check the library name? (eg. no
+        # slashes)
+        self.link_shared_object (objects, self.shared_library_name(output_libname),
+                                 build_info=build_info )
+    
+    def link_shared_object (self,
+                            objects,
+                            output_filename,
+                            libraries=None,
+                            library_dirs=None,
+                            build_info=None):
+        """Link a bunch of stuff together to create a shared object
+           file.  Much like 'link_shared_lib()', except the output
+           filename is explicitly supplied as 'output_filename'."""
+        if libraries is None:
+            libraries = []
+        if library_dirs is None:
+            library_dirs = []
+        if build_info is None:
+            build_info = {}
+        
+        lib_opts = _gen_lib_options (self.libraries + libraries,
+                                     self.library_dirs + library_dirs)
+
+        if build_info.has_key('def_file') :
+            lib_opts.append('/DEF:' + build_info['def_file'] )
+                            
+        ld_args = self.ldflags_shared + lib_opts + \
+                  objects + ['/OUT:' + output_filename]
+
+        self.spawn ( [ self.link ] + ld_args )
+
+
+    # -- Filename mangling methods -------------------------------------
+
+    def _change_extensions( self, filenames, newExtension ):
+        object_filenames = []
+
+        for srcFile in filenames:
+            base,ext = os.path.splitext( srcFile )
+            # XXX should we strip off any existing path?
+            object_filenames.append( base + newExtension )
+
+        return object_filenames
+
+    def object_filenames (self, source_filenames):
+        """Return the list of object filenames corresponding to each
+           specified source filename."""
+        return self._change_extensions( source_filenames, self._obj_ext )
+
+    def shared_object_filename (self, source_filename):
+        """Return the shared object filename corresponding to a
+           specified source filename."""
+        return self._change_extensions( source_filenames, self._shared_lib_ext )
+
+    def library_filename (self, libname):
+        """Return the static library filename corresponding to the
+           specified library name."""
+        return "lib%s%s" %( libname, self._static_lib_ext )
+
+    def shared_library_filename (self, libname):
+        """Return the shared library filename corresponding to the
+           specified library name."""
+        return "lib%s%s" %( libname, self._shared_lib_ext )
+
+# class MSVCCompiler
+
+def _gen_preprocess_options (macros, includes):
+
+    # XXX it would be nice (mainly aesthetic, and so we don't generate
+    # stupid-looking command lines) to go over 'macros' and eliminate
+    # redundant definitions/undefinitions (ie. ensure that only the
+    # latest mention of a particular macro winds up on the command
+    # line).  I don't think it's essential, though, since most (all?)
+    # Unix C compilers only pay attention to the latest -D or -U
+    # mention of a macro on their command line.  Similar situation for
+    # 'includes'.  I'm punting on both for now.  Anyways, weeding out
+    # redundancies like this should probably be the province of
+    # CCompiler, since the data structures used are inherited from it
+    # and therefore common to all CCompiler classes.
+
+
+    pp_opts = []
+    for macro in macros:
+        if len (macro) == 1:        # undefine this macro
+            pp_opts.append ("-U%s" % macro[0])
+        elif len (macro) == 2:
+            if macro[1] is None:    # define with no explicit value
+                pp_opts.append ("-D%s" % macro[0])
+            else:
+                # XXX *don't* need to be clever about quoting the
+                # macro value here, because we're going to avoid the
+                # shell at all costs when we spawn the command!
+                pp_opts.append ("-D%s=%s" % macro)
+
+    for dir in includes:
+        pp_opts.append ("-I%s" % dir)
+
+    return pp_opts
+
+def _gen_lib_options (libraries, library_dirs):
+
+    lib_opts = []
+
+    for dir in library_dirs:
+        lib_opts.append ("/LIBPATH:%s" % dir)
+
+    # XXX it's important that we *not* remove redundant library mentions!
+    # sometimes you really do have to say "-lfoo -lbar -lfoo" in order to
+    # resolve all symbols.  I just hope we never have to say "-lfoo obj.o
+    # -lbar" to get things to work -- that's certainly a possibility, but a
+    # pretty nasty way to arrange your C code.
+
+    for lib in libraries:
+        lib_opts.append ("%s.lib" % lib) # import libraries end in .lib
+
+    return lib_opts
+
+# _gen_lib_options ()
+
+