Fix variable interpolation with spaces, and problems with the WIN32 environment ...
authorstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 9 Feb 2002 23:42:29 +0000 (23:42 +0000)
committerstevenknight <stevenknight@fdb21ef1-2011-0410-befe-b5e4ea1792b1>
Sat, 9 Feb 2002 23:42:29 +0000 (23:42 +0000)
git-svn-id: http://scons.tigris.org/svn/scons/trunk@250 fdb21ef1-2011-0410-befe-b5e4ea1792b1

etc/TestCmd.py
src/CHANGES.txt
src/engine/SCons/Defaults.py
src/engine/SCons/Util.py
src/engine/SCons/UtilTests.py

index 8df039e1eea181489a453c3b7aedec3316bf102a..912be48c0d7344a2bda98e43338883d226502504 100644 (file)
@@ -402,7 +402,7 @@ class TestCmd:
        if self.verbose:
            sys.stderr.write(cmd + "\n")
        try:
-           p = popen2.Popen3(cmd, 1)
+            p = popen2.Popen3(cmd, 1)
        except AttributeError:
            (tochild, fromchild, childerr) = os.popen3(cmd)
            if stdin:
@@ -415,7 +415,9 @@ class TestCmd:
            self._stdout.append(fromchild.read())
            self._stderr.append(childerr.read())
            fromchild.close()
-           self._status = childerr.close()
+            self.status = childerr.close()
+            if not self.status:
+                self.status = 0
        except:
            raise
        else:
index d533be97eeb10f7b2ef731b2b8853d84b4235d01..29f99f6a2af1e0c2ccf824bc8c520760911f6708 100644 (file)
@@ -25,6 +25,9 @@ RELEASE 0.05 -
   - More performance optimizations:  cache #include lines from files,
     eliminate unnecessary calls.
 
+  - Fix irregularities in the way we fetch DevStudio information from
+    the Windows registry, and in our registry error handling.
+
   From Steven Knight:
 
   - Flush stdout after print so it intermixes correctly with stderr
index 9a510d689c82503011efed3f8856722cc5655b93..d12983803811ead901b357690aff81afd68bdc51 100644 (file)
@@ -95,7 +95,7 @@ def get_devstudio_versions ():
     """
 
     if not SCons.Util.can_read_reg:
-        raise InternalError, "No Windows registry module was found"
+        raise SCons.Errors.InternalError, "No Windows registry module was found"
 
     K = 'Software\\Microsoft\\Devstudio'
     L = []
@@ -118,7 +118,7 @@ def get_devstudio_versions ():
             pass
     
     if not L:
-        raise InternalError, "DevStudio was not found."
+        raise SCons.Errors.InternalError, "DevStudio was not found."
     
     L.sort()
     L.reverse()
@@ -132,7 +132,7 @@ def get_msvc_path (path, version, platform='x86'):
     """
        
     if not SCons.Util.can_read_reg:
-        raise InternalError, "No Windows registry module was found"
+        raise SCons.Errors.InternalError, "No Windows registry module was found"
 
     if path=='lib':
         path= 'Library'
@@ -159,8 +159,24 @@ def get_msvc_path (path, version, platform='x86'):
             pass
 
     # if we got here, then we didn't find the registry entries:
-    raise InternalError, "%s was not found in the registry."%path
+    raise SCons.Errors.InternalError, "%s was not found in the registry."%path
 
+def get_msdev_dir(version):
+    """Returns the root directory of the MSDev installation from the
+    registry if it can be found, otherwise we guess."""
+    if SCons.Util.can_read_reg:  
+        K = ('Software\\Microsoft\\Devstudio\\%s\\' +
+             'Products\\Microsoft Visual C++') % \
+             version
+        for base in (SCons.Util.HKEY_LOCAL_MACHINE,
+                     SCons.Util.HKEY_CURRENT_USER):
+            try:
+                k = SCons.Util.RegOpenKeyEx(base,K)
+                val, tok = SCons.Util.RegQueryValueEx(k, 'ProductDir')
+                return os.path.split(val)[0]
+            except SCons.Util.RegError:
+                pass
+    
 def make_win32_env_from_paths(include, lib, path):
     """
     Build a dictionary of construction variables for a win32 platform. 
@@ -217,7 +233,7 @@ def make_win32_env(version):
     return make_win32_env_from_paths(get_msvc_path("include", version),
                                      get_msvc_path("lib", version),
                                      get_msvc_path("path", version) 
-                                     + ";" + os.environ[PATH])
+                                     + ";" + os.environ['PATH'])
     
 
 if os.name == 'posix':
@@ -259,24 +275,50 @@ if os.name == 'posix':
     }
 
 elif os.name == 'nt':
-    
+    versions = None
     try:
         versions = get_devstudio_versions()
         ConstructionEnvironment = make_win32_env(versions[0]) #use highest version
-    except:
-        try:
-            # We failed to detect DevStudio, so fall back to the
-            # DevStudio environment variables:
+    except (SCons.Util.RegError, SCons.Errors.InternalError):
+        # Could not get the configured directories from the registry.
+        # However, the configured directories only appear if the user
+        # changes them from the default.  Therefore, we'll see if
+        # we can get the path to the MSDev base installation from
+        # the registry and deduce the default directories.
+        MVSdir = None
+        if versions:
+            MVSdir = get_msdev_dir(versions[0])
+        if MVSdir:
+            MVSVCdir = r'%s\VC98' % MVSdir
+            MVSCommondir = r'%s\Common' % MVSdir
+            try:
+                extra_path = os.pathsep + os.environ['PATH']
+            except KeyError:
+                extra_path = ''
             ConstructionEnvironment = make_win32_env_from_paths(
-                os.environ["INCLUDE"], os.environ["LIB"], os.environ["PATH"])
-        except KeyError:
-            # The DevStudio environment variables don't exists,
-            # so fall back to a reasonable default:
+                r'%s\atl\include;%s\mfc\include;%s\include' % (MVSVCdir, MVSVCdir, MVSVCdir),
+                r'%s\mfc\lib;%s\lib' % (MVSVCdir, MVSVCdir),
+                (r'%s\MSDev98\Bin;%s\Bin' % (MVSCommondir, MVSVCdir)) + extra_path)
+        else:
+            # The DevStudio environment variables don't exist,
+            # so just use the variables from the source environment.
             MVSdir = r'C:\Program Files\Microsoft Visual Studio'
             MVSVCdir = r'%s\VC98' % MVSdir
             MVSCommondir = r'%s\Common' % MVSdir
+            try:
+                include_path = os.environ['INCLUDE']
+            except KeyError:
+                include_path = ''
+            try:
+                lib_path = os.environ['LIB']
+            except KeyError:
+                lib_path = ''
+            try:
+                exe_path = os.environ['PATH']
+            except KeyError:
+                exe_path = ''
             ConstructionEnvironment = make_win32_env_from_paths(
-                r'%s\atl\include;%s\mfc\include;%s\include' % (MVSVCdir, MVSVCdir, MVSVCdir),
-                r'%s\mvc\lib;%s\lib' % (MVSVCdir, MVSVCdir),
-                (r'%s\MSDev98\Bin' % MVSCommondir) + os.pathsep + os.environ["PATH"])
+                include_path,
+                lib_path,
+                exe_path)
 
index 2c921dcbd7e6e8a2c35c92631f39a70cf25ec2b0..fd95438dc688436ea32094938c1ce759a41c2151 100644 (file)
@@ -318,9 +318,23 @@ class VarInterpolator:
         except KeyError:
             suffix =''
 
-        dict[self.dest] = map(lambda x, suff=suffix, pref=prefix: \
-                              pref + str(x) + suff,
-                              src)
+        def autogenFunc(x, suff=suffix, pref=prefix):
+            """Generate the interpolated variable.  If the prefix
+            ends in a space, or the suffix begins in a space,
+            leave it as a separate element of the list."""
+            ret = [ str(x) ]
+            if pref and pref[-1] == ' ':
+                ret.insert(0, pref[:-1])
+            else:
+                ret[0] = pref + ret[0]
+            if suff and suff[0] == ' ':
+                ret.append(suff[1:])
+            else:
+                ret[-1] = ret[-1] + suff
+            return ret
+        dict[self.dest] = reduce(lambda x, y: x+y,
+                                 map(autogenFunc,
+                                     src))
 
     def instance(self, dir, fs):
         return self
index bb698341268a920fc1cb9f6cde8cf2c525785d20..11238c928528a015080956f26a93c223631a0841 100644 (file)
@@ -207,27 +207,28 @@ class UtilTestCase(unittest.TestCase):
                dict['_LIBFLAGS'][2]
 
         blat = SCons.Node.FS.default_fs.File('blat')
-        dict = {'CPPPATH'   : [ 'foo', 'bar', 'baz', '$FOO/bar', blat],
-                'INCPREFIX' : 'foo',
+        dict = {'CPPPATH'   : [ 'foo', '$FOO/bar', blat],
+                'INCPREFIX' : 'foo ',
                 'INCSUFFIX' : 'bar',
                 'FOO'       : 'baz' }
         autogenerate(dict, dir = SCons.Node.FS.default_fs.Dir('/xx'))
-        assert len(dict['_INCFLAGS']) == 7, dict['_INCFLAGS']
+        assert len(dict['_INCFLAGS']) == 8, dict['_INCFLAGS']
         assert dict['_INCFLAGS'][0] == '$(', \
                dict['_INCFLAGS'][0]
-        assert dict['_INCFLAGS'][1] == os.path.normpath('foo/xx/foobar'), \
+        assert dict['_INCFLAGS'][1] == os.path.normpath('foo'), \
                dict['_INCFLAGS'][1]
-        assert dict['_INCFLAGS'][2] == os.path.normpath('foo/xx/barbar'), \
+        assert dict['_INCFLAGS'][2] == os.path.normpath('/xx/foobar'), \
                dict['_INCFLAGS'][2]
-        assert dict['_INCFLAGS'][3] == os.path.normpath('foo/xx/bazbar'), \
+        assert dict['_INCFLAGS'][3] == os.path.normpath('foo'), \
                dict['_INCFLAGS'][3]
-        assert dict['_INCFLAGS'][4] == os.path.normpath('foo/xx/baz/barbar'), \
+        assert dict['_INCFLAGS'][4] == os.path.normpath('/xx/baz/barbar'), \
                dict['_INCFLAGS'][4]
-        
-        assert dict['_INCFLAGS'][5] == os.path.normpath('fooblatbar'), \
+        assert dict['_INCFLAGS'][5] == os.path.normpath('foo'), \
                dict['_INCFLAGS'][5]
-        assert dict['_INCFLAGS'][6] == '$)', \
+        assert dict['_INCFLAGS'][6] == os.path.normpath('blatbar'), \
                dict['_INCFLAGS'][6]
+        assert dict['_INCFLAGS'][7] == '$)', \
+               dict['_INCFLAGS'][7]
 
     def test_render_tree(self):
         class Node: