*** D:/John/osaf/distutils/distutils/msvccompiler.py	Tue Jun 18 12:08:40 2002
--- D:/John/osaf/bin/Lib/site-packages/distutils/msvccompiler.py	Wed Sep 25 09:30:24 2002
*************** for the Microsoft Visual Studio."""
*** 7,16 ****
  # created 1999/08/19, Perry Stoll
  # hacked by Robin Becker and Thomas Heller to do a better job of
  #   finding DevStudio (through the registry)
  
  __revision__ = "$Id: msvccompiler.py,v 1.49 2002/06/18 19:08:40 jhylton Exp $"
  
! import sys, os, string
  from types import *
  from distutils.errors import \
       DistutilsExecError, DistutilsPlatformError, \
--- 7,22 ----
  # created 1999/08/19, Perry Stoll
  # hacked by Robin Becker and Thomas Heller to do a better job of
  #   finding DevStudio (through the registry)
+ #
+ # Rehacked by John Anderson to fix problems with finding DevStudio
+ #   through the registry. Using the registry is always going to be
+ #   an inexact science, since Microsoft can always change how they
+ #   store data in the registry and the data in the registry isn't
+ #   documented.
  
  __revision__ = "$Id: msvccompiler.py,v 1.49 2002/06/18 19:08:40 jhylton Exp $"
  
! import sys, os, string, log
  from types import *
  from distutils.errors import \
       DistutilsExecError, DistutilsPlatformError, \
*************** except ImportError:
*** 44,49 ****
--- 50,59 ----
          RegError = win32api.error
  
      except ImportError:
+         log.info("Warning: Can't read registry to find the "
+                  "necessary compiler setting\n"
+                  "Make sure that Python modules _winreg, "
+                  "win32api or win32con are installed.")
          pass
  
  if _can_read_reg:
*************** def get_devstudio_versions ():
*** 64,70 ****
      if not _can_read_reg:
          return []
  
!     K = 'Software\\Microsoft\\Devstudio'
      L = []
      for base in (HKEY_CLASSES_ROOT,
                   HKEY_LOCAL_MACHINE,
--- 74,80 ----
      if not _can_read_reg:
          return []
  
!     K = 'SOFTWARE\\Microsoft\\VisualStudio'
      L = []
      for base in (HKEY_CLASSES_ROOT,
                   HKEY_LOCAL_MACHINE,
*************** def get_devstudio_versions ():
*** 83,88 ****
--- 93,100 ----
                  i = i + 1
          except RegError:
              pass
+     if not L:
+         log.info("Warning: Can't find the Microsoft compiler in the registry")
      L.sort()
      L.reverse()
      return L
*************** def get_devstudio_versions ():
*** 90,95 ****
--- 102,190 ----
  # get_devstudio_versions ()
  
  
+ def convert_mbcs (string):
+     """Convert from multibyte character set (mbcs) if possible."""
+ 
+     if hasattr(string, "encode"):
+         try:
+             string = string.encode("mbcs")
+         except UnicodeError:
+             pass
+     return string
+ # convert_mbcs()
+ 
+ 
+ def read_key (base, key, lowerCaseKeys):
+     """Open the registry key and returns a dictionary of the name values
+        pairs. Converts all the names to lowerCaseKeys when lowerCaseKeys is true."""
+ 
+     handle = RegOpenKeyEx(base, key)
+     dict = {}
+     i = 0
+     while 1:
+         try:
+             (name, value, type) = RegEnumValue(handle, i)
+             if lowerCaseKeys:
+                 name = name.lower()
+             dict[convert_mbcs(name)] = convert_mbcs(value)
+         except RegError:
+             break
+         i = i + 1
+     return dict
+ # read_key()
+ 
+ 
+ VC_INSTALL_DIR = "$(VCInstallDir)"
+ VS_INSTALL_DIR = "$(VSInstallDir)"
+ FRAMEWORK_DIR = "$(FrameworkDir)"
+ FRAMEWORK_SDK_DIR = "$(FrameworkSDKDir)"
+ FRAMEWORK_VERSION = "$(FrameworkVersion)"
+ _initializedMacros = 0
+ 
+ def expand_macros (string, base, version, numericVersion):
+     """Expand macros of the form $(VCInstallDir), $(VCInstallDir),
+        $(FrameworkDir), $(FrameworkSDKDir) in paths.
+        The locations of these macros in the registry apparently are
+        not documented, so they were determined by just looking around
+        in regedit. Consequently """
+ 
+     global _initializedMacros, VC_INSTALL_DIR, VS_INSTALL_DIR
+     global FRAMEWORK_DIR, FRAMEWORK_SDK_DIR
+     if numericVersion >= 7.0:
+         if not _initializedMacros:
+             try:
+                 _initializedMacros = 1
+ 
+                 key = ('SOFTWARE\\Microsoft\\VisualStudio\\%s\\Setup\\VC') % (version)
+                 pairs = read_key(base, key, 1)
+                 VC_INSTALL_DIR = pairs['productdir']
+ 
+                 key = ('SOFTWARE\\Microsoft\\VisualStudio\\%s\\Setup\\VS') % (version)
+                 pairs = read_key(base, key, 1)
+                 VS_INSTALL_DIR = pairs['productdir']
+ 
+                 pairs = read_key (base, 'SOFTWARE\\Microsoft\\.NETFramework', 1)
+                 FRAMEWORK_DIR = pairs['installroot']
+                 FRAMEWORK_SDK_DIR = pairs['sdkinstallroot']
+         
+                 location = 'SOFTWARE\\Microsoft\\NET Framework Setup\\Product';
+                 handle = RegOpenKeyEx(base, location)
+                 key = RegEnumKey(handle, 0)
+                 pairs = read_key (base, location + '\\' + key, 1)
+                 FRAMEWORK_VERSION = pairs['version']
+ 
+             except RegError:
+                 log.info("Warning: Can't read registry node: " + key)
+             except KeyError:
+                 log.info("Warning: Can't read registry key:" + KeyError)
+         string = string.replace ('$(VCInstallDir)', VC_INSTALL_DIR)
+         string = string.replace ('$(VSInstallDir)', VS_INSTALL_DIR)
+         string = string.replace ('$(FrameworkDir)', FRAMEWORK_DIR)
+         string = string.replace ('$(FrameworkSDKDir)', FRAMEWORK_SDK_DIR)
+     return string
+ # expand_macros()
+ 
+ 
  def get_msvc_paths (path, version='6.0', platform='x86'):
      """Get a list of devstudio directories (include, lib or path).  Return
         a list of strings; will be empty list if unable to access the
*************** def get_msvc_paths (path, version='6.0',
*** 101,134 ****
      L = []
      if path=='lib':
          path= 'Library'
!     path = string.upper(path + ' Dirs')
!     K = ('Software\\Microsoft\\Devstudio\\%s\\' +
!          'Build System\\Components\\Platforms\\Win32 (%s)\\Directories') % \
!         (version,platform)
      for base in (HKEY_CLASSES_ROOT,
                   HKEY_LOCAL_MACHINE,
                   HKEY_CURRENT_USER,
                   HKEY_USERS):
          try:
!             k = RegOpenKeyEx(base,K)
!             i = 0
!             while 1:
!                 try:
!                     (p,v,t) = RegEnumValue(k,i)
!                     if string.upper(p) == path:
!                         V = string.split(v,';')
!                         for v in V:
!                             if hasattr(v, "encode"):
!                                 try:
!                                     v = v.encode("mbcs")
!                                 except UnicodeError:
!                                     pass
!                             if v == '' or v in L: continue
!                             L.append(v)
!                         break
!                     i = i + 1
!                 except RegError:
!                     break
          except RegError:
              pass
      return L
--- 196,230 ----
      L = []
      if path=='lib':
          path= 'Library'
!     path = string.lower(path + ' Dirs')
!     numericVersion = 6.0;
!     try:
!         numericVersion = float (version)
!     except ValueError:
!         pass
!     
!     if numericVersion < 7.0: 
!         key = ('SOFTWARE\\Microsoft\\Devstudio\\%s\\'
!                'Build System\\Components\\Platforms\\'
!                'Win32 (%s)\\Directories') % (version, platform)
!     else:
!         key = ('SOFTWARE\\Microsoft\\VisualStudio\\%s\\'
!                'VC\\VC_OBJECTS_PLATFORM_INFO\\Win32\\Directories') % (version)
! 
      for base in (HKEY_CLASSES_ROOT,
                   HKEY_LOCAL_MACHINE,
                   HKEY_CURRENT_USER,
                   HKEY_USERS):
          try:
!             pairs = read_key(base, key, 1)
!             if pairs.has_key(path):
!                 for s in string.split(expand_macros(pairs[path],
!                                                     base,
!                                                     version,
!                                                     numericVersion),';'):
!                     if not (s in L):
!                         L.append(s)
!                 break
          except RegError:
              pass
      return L
*************** class MSVCCompiler (CCompiler) :
*** 220,226 ****
              path=get_msvc_paths('path', version)
              try:
                  for p in string.split(os.environ['path'],';'):
!                     path.append(p)
              except KeyError:
                  pass
              os.environ['path'] = string.join(path,';')
--- 316,323 ----
              path=get_msvc_paths('path', version)
              try:
                  for p in string.split(os.environ['path'],';'):
!                     if not (p in path):
!                         path.append(p)
              except KeyError:
                  pass
              os.environ['path'] = string.join(path,';')
