libv8 3.3.10.2 → 3.3.10.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (204) hide show
  1. data/.gitignore +1 -0
  2. data/README.md +35 -7
  3. data/Rakefile +61 -20
  4. data/ext/libv8/extconf.rb +15 -0
  5. data/lib/libv8/scons/CHANGES.txt +231 -24
  6. data/lib/libv8/scons/LICENSE.txt +1 -1
  7. data/lib/libv8/scons/MANIFEST +1 -0
  8. data/lib/libv8/scons/PKG-INFO +1 -1
  9. data/lib/libv8/scons/README.txt +9 -9
  10. data/lib/libv8/scons/RELEASE.txt +77 -75
  11. data/lib/libv8/scons/engine/SCons/Action.py +22 -6
  12. data/lib/libv8/scons/engine/SCons/Builder.py +2 -2
  13. data/lib/libv8/scons/engine/SCons/CacheDir.py +2 -2
  14. data/lib/libv8/scons/engine/SCons/Debug.py +2 -2
  15. data/lib/libv8/scons/engine/SCons/Defaults.py +24 -10
  16. data/lib/libv8/scons/engine/SCons/Environment.py +118 -19
  17. data/lib/libv8/scons/engine/SCons/Errors.py +2 -2
  18. data/lib/libv8/scons/engine/SCons/Executor.py +2 -2
  19. data/lib/libv8/scons/engine/SCons/Job.py +2 -2
  20. data/lib/libv8/scons/engine/SCons/Memoize.py +2 -2
  21. data/lib/libv8/scons/engine/SCons/Node/Alias.py +2 -2
  22. data/lib/libv8/scons/engine/SCons/Node/FS.py +281 -121
  23. data/lib/libv8/scons/engine/SCons/Node/Python.py +2 -2
  24. data/lib/libv8/scons/engine/SCons/Node/__init__.py +6 -5
  25. data/lib/libv8/scons/engine/SCons/Options/BoolOption.py +2 -2
  26. data/lib/libv8/scons/engine/SCons/Options/EnumOption.py +2 -2
  27. data/lib/libv8/scons/engine/SCons/Options/ListOption.py +2 -2
  28. data/lib/libv8/scons/engine/SCons/Options/PackageOption.py +2 -2
  29. data/lib/libv8/scons/engine/SCons/Options/PathOption.py +2 -2
  30. data/lib/libv8/scons/engine/SCons/Options/__init__.py +2 -2
  31. data/lib/libv8/scons/engine/SCons/PathList.py +2 -2
  32. data/lib/libv8/scons/engine/SCons/Platform/__init__.py +2 -2
  33. data/lib/libv8/scons/engine/SCons/Platform/aix.py +2 -2
  34. data/lib/libv8/scons/engine/SCons/Platform/cygwin.py +2 -2
  35. data/lib/libv8/scons/engine/SCons/Platform/darwin.py +27 -3
  36. data/lib/libv8/scons/engine/SCons/Platform/hpux.py +2 -2
  37. data/lib/libv8/scons/engine/SCons/Platform/irix.py +2 -2
  38. data/lib/libv8/scons/engine/SCons/Platform/os2.py +2 -2
  39. data/lib/libv8/scons/engine/SCons/Platform/posix.py +2 -2
  40. data/lib/libv8/scons/engine/SCons/Platform/sunos.py +2 -2
  41. data/lib/libv8/scons/engine/SCons/Platform/win32.py +2 -2
  42. data/lib/libv8/scons/engine/SCons/SConf.py +2 -2
  43. data/lib/libv8/scons/engine/SCons/SConsign.py +9 -3
  44. data/lib/libv8/scons/engine/SCons/Scanner/C.py +2 -2
  45. data/lib/libv8/scons/engine/SCons/Scanner/D.py +2 -2
  46. data/lib/libv8/scons/engine/SCons/Scanner/Dir.py +2 -2
  47. data/lib/libv8/scons/engine/SCons/Scanner/Fortran.py +2 -2
  48. data/lib/libv8/scons/engine/SCons/Scanner/IDL.py +2 -2
  49. data/lib/libv8/scons/engine/SCons/Scanner/LaTeX.py +5 -2
  50. data/lib/libv8/scons/engine/SCons/Scanner/Prog.py +2 -2
  51. data/lib/libv8/scons/engine/SCons/Scanner/RC.py +3 -3
  52. data/lib/libv8/scons/engine/SCons/Scanner/__init__.py +2 -2
  53. data/lib/libv8/scons/engine/SCons/Script/Interactive.py +2 -2
  54. data/lib/libv8/scons/engine/SCons/Script/Main.py +82 -11
  55. data/lib/libv8/scons/engine/SCons/Script/SConsOptions.py +5 -5
  56. data/lib/libv8/scons/engine/SCons/Script/SConscript.py +2 -2
  57. data/lib/libv8/scons/engine/SCons/Script/__init__.py +2 -2
  58. data/lib/libv8/scons/engine/SCons/Sig.py +2 -2
  59. data/lib/libv8/scons/engine/SCons/Subst.py +2 -2
  60. data/lib/libv8/scons/engine/SCons/Taskmaster.py +10 -2
  61. data/lib/libv8/scons/engine/SCons/Tool/386asm.py +2 -2
  62. data/lib/libv8/scons/engine/SCons/Tool/BitKeeper.py +2 -2
  63. data/lib/libv8/scons/engine/SCons/Tool/CVS.py +2 -2
  64. data/lib/libv8/scons/engine/SCons/Tool/FortranCommon.py +19 -2
  65. data/lib/libv8/scons/engine/SCons/Tool/JavaCommon.py +2 -2
  66. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/__init__.py +2 -2
  67. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/arch.py +2 -2
  68. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/common.py +2 -2
  69. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/netframework.py +2 -2
  70. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/sdk.py +2 -2
  71. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vc.py +9 -6
  72. data/lib/libv8/scons/engine/SCons/Tool/MSCommon/vs.py +29 -2
  73. data/lib/libv8/scons/engine/SCons/Tool/Perforce.py +2 -2
  74. data/lib/libv8/scons/engine/SCons/Tool/PharLapCommon.py +2 -2
  75. data/lib/libv8/scons/engine/SCons/Tool/RCS.py +2 -2
  76. data/lib/libv8/scons/engine/SCons/Tool/SCCS.py +2 -2
  77. data/lib/libv8/scons/engine/SCons/Tool/Subversion.py +2 -2
  78. data/lib/libv8/scons/engine/SCons/Tool/__init__.py +3 -3
  79. data/lib/libv8/scons/engine/SCons/Tool/aixc++.py +2 -2
  80. data/lib/libv8/scons/engine/SCons/Tool/aixcc.py +2 -2
  81. data/lib/libv8/scons/engine/SCons/Tool/aixf77.py +2 -2
  82. data/lib/libv8/scons/engine/SCons/Tool/aixlink.py +2 -2
  83. data/lib/libv8/scons/engine/SCons/Tool/applelink.py +2 -2
  84. data/lib/libv8/scons/engine/SCons/Tool/ar.py +2 -2
  85. data/lib/libv8/scons/engine/SCons/Tool/as.py +2 -2
  86. data/lib/libv8/scons/engine/SCons/Tool/bcc32.py +2 -2
  87. data/lib/libv8/scons/engine/SCons/Tool/c++.py +2 -2
  88. data/lib/libv8/scons/engine/SCons/Tool/cc.py +2 -2
  89. data/lib/libv8/scons/engine/SCons/Tool/cvf.py +2 -2
  90. data/lib/libv8/scons/engine/SCons/Tool/default.py +2 -2
  91. data/lib/libv8/scons/engine/SCons/Tool/dmd.py +24 -7
  92. data/lib/libv8/scons/engine/SCons/Tool/dvi.py +2 -2
  93. data/lib/libv8/scons/engine/SCons/Tool/dvipdf.py +3 -2
  94. data/lib/libv8/scons/engine/SCons/Tool/dvips.py +3 -2
  95. data/lib/libv8/scons/engine/SCons/Tool/f03.py +63 -0
  96. data/lib/libv8/scons/engine/SCons/Tool/f77.py +2 -2
  97. data/lib/libv8/scons/engine/SCons/Tool/f90.py +2 -2
  98. data/lib/libv8/scons/engine/SCons/Tool/f95.py +2 -2
  99. data/lib/libv8/scons/engine/SCons/Tool/filesystem.py +2 -2
  100. data/lib/libv8/scons/engine/SCons/Tool/fortran.py +2 -2
  101. data/lib/libv8/scons/engine/SCons/Tool/g++.py +2 -2
  102. data/lib/libv8/scons/engine/SCons/Tool/g77.py +2 -2
  103. data/lib/libv8/scons/engine/SCons/Tool/gas.py +2 -2
  104. data/lib/libv8/scons/engine/SCons/Tool/gcc.py +2 -2
  105. data/lib/libv8/scons/engine/SCons/Tool/gfortran.py +3 -3
  106. data/lib/libv8/scons/engine/SCons/Tool/gnulink.py +2 -3
  107. data/lib/libv8/scons/engine/SCons/Tool/gs.py +2 -2
  108. data/lib/libv8/scons/engine/SCons/Tool/hpc++.py +2 -2
  109. data/lib/libv8/scons/engine/SCons/Tool/hpcc.py +2 -2
  110. data/lib/libv8/scons/engine/SCons/Tool/hplink.py +2 -2
  111. data/lib/libv8/scons/engine/SCons/Tool/icc.py +2 -2
  112. data/lib/libv8/scons/engine/SCons/Tool/icl.py +2 -2
  113. data/lib/libv8/scons/engine/SCons/Tool/ifl.py +2 -2
  114. data/lib/libv8/scons/engine/SCons/Tool/ifort.py +2 -2
  115. data/lib/libv8/scons/engine/SCons/Tool/ilink.py +2 -2
  116. data/lib/libv8/scons/engine/SCons/Tool/ilink32.py +2 -2
  117. data/lib/libv8/scons/engine/SCons/Tool/install.py +57 -3
  118. data/lib/libv8/scons/engine/SCons/Tool/intelc.py +65 -25
  119. data/lib/libv8/scons/engine/SCons/Tool/ipkg.py +2 -2
  120. data/lib/libv8/scons/engine/SCons/Tool/jar.py +9 -3
  121. data/lib/libv8/scons/engine/SCons/Tool/javac.py +2 -2
  122. data/lib/libv8/scons/engine/SCons/Tool/javah.py +2 -2
  123. data/lib/libv8/scons/engine/SCons/Tool/latex.py +3 -2
  124. data/lib/libv8/scons/engine/SCons/Tool/lex.py +2 -2
  125. data/lib/libv8/scons/engine/SCons/Tool/link.py +6 -5
  126. data/lib/libv8/scons/engine/SCons/Tool/linkloc.py +2 -2
  127. data/lib/libv8/scons/engine/SCons/Tool/m4.py +2 -2
  128. data/lib/libv8/scons/engine/SCons/Tool/masm.py +2 -2
  129. data/lib/libv8/scons/engine/SCons/Tool/midl.py +2 -2
  130. data/lib/libv8/scons/engine/SCons/Tool/mingw.py +31 -10
  131. data/lib/libv8/scons/engine/SCons/Tool/mslib.py +2 -2
  132. data/lib/libv8/scons/engine/SCons/Tool/mslink.py +61 -9
  133. data/lib/libv8/scons/engine/SCons/Tool/mssdk.py +2 -2
  134. data/lib/libv8/scons/engine/SCons/Tool/msvc.py +21 -11
  135. data/lib/libv8/scons/engine/SCons/Tool/msvs.py +477 -59
  136. data/lib/libv8/scons/engine/SCons/Tool/mwcc.py +2 -2
  137. data/lib/libv8/scons/engine/SCons/Tool/mwld.py +2 -2
  138. data/lib/libv8/scons/engine/SCons/Tool/nasm.py +2 -2
  139. data/lib/libv8/scons/engine/SCons/Tool/packaging/__init__.py +2 -2
  140. data/lib/libv8/scons/engine/SCons/Tool/packaging/ipk.py +2 -2
  141. data/lib/libv8/scons/engine/SCons/Tool/packaging/msi.py +2 -2
  142. data/lib/libv8/scons/engine/SCons/Tool/packaging/rpm.py +2 -2
  143. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_tarbz2.py +2 -2
  144. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_targz.py +2 -2
  145. data/lib/libv8/scons/engine/SCons/Tool/packaging/src_zip.py +2 -2
  146. data/lib/libv8/scons/engine/SCons/Tool/packaging/tarbz2.py +2 -2
  147. data/lib/libv8/scons/engine/SCons/Tool/packaging/targz.py +2 -2
  148. data/lib/libv8/scons/engine/SCons/Tool/packaging/zip.py +2 -2
  149. data/lib/libv8/scons/engine/SCons/Tool/pdf.py +2 -2
  150. data/lib/libv8/scons/engine/SCons/Tool/pdflatex.py +3 -2
  151. data/lib/libv8/scons/engine/SCons/Tool/pdftex.py +3 -2
  152. data/lib/libv8/scons/engine/SCons/Tool/qt.py +2 -2
  153. data/lib/libv8/scons/engine/SCons/Tool/rmic.py +9 -3
  154. data/lib/libv8/scons/engine/SCons/Tool/rpcgen.py +2 -2
  155. data/lib/libv8/scons/engine/SCons/Tool/rpm.py +2 -2
  156. data/lib/libv8/scons/engine/SCons/Tool/sgiar.py +2 -2
  157. data/lib/libv8/scons/engine/SCons/Tool/sgic++.py +2 -2
  158. data/lib/libv8/scons/engine/SCons/Tool/sgicc.py +2 -2
  159. data/lib/libv8/scons/engine/SCons/Tool/sgilink.py +2 -3
  160. data/lib/libv8/scons/engine/SCons/Tool/sunar.py +2 -2
  161. data/lib/libv8/scons/engine/SCons/Tool/sunc++.py +2 -2
  162. data/lib/libv8/scons/engine/SCons/Tool/suncc.py +2 -2
  163. data/lib/libv8/scons/engine/SCons/Tool/sunf77.py +2 -2
  164. data/lib/libv8/scons/engine/SCons/Tool/sunf90.py +2 -2
  165. data/lib/libv8/scons/engine/SCons/Tool/sunf95.py +2 -2
  166. data/lib/libv8/scons/engine/SCons/Tool/sunlink.py +2 -3
  167. data/lib/libv8/scons/engine/SCons/Tool/swig.py +6 -5
  168. data/lib/libv8/scons/engine/SCons/Tool/tar.py +2 -2
  169. data/lib/libv8/scons/engine/SCons/Tool/tex.py +96 -43
  170. data/lib/libv8/scons/engine/SCons/Tool/textfile.py +2 -2
  171. data/lib/libv8/scons/engine/SCons/Tool/tlib.py +2 -2
  172. data/lib/libv8/scons/engine/SCons/Tool/wix.py +2 -2
  173. data/lib/libv8/scons/engine/SCons/Tool/yacc.py +12 -2
  174. data/lib/libv8/scons/engine/SCons/Tool/zip.py +2 -2
  175. data/lib/libv8/scons/engine/SCons/Util.py +3 -3
  176. data/lib/libv8/scons/engine/SCons/Variables/BoolVariable.py +2 -2
  177. data/lib/libv8/scons/engine/SCons/Variables/EnumVariable.py +3 -3
  178. data/lib/libv8/scons/engine/SCons/Variables/ListVariable.py +2 -2
  179. data/lib/libv8/scons/engine/SCons/Variables/PackageVariable.py +2 -2
  180. data/lib/libv8/scons/engine/SCons/Variables/PathVariable.py +2 -2
  181. data/lib/libv8/scons/engine/SCons/Variables/__init__.py +2 -2
  182. data/lib/libv8/scons/engine/SCons/Warnings.py +2 -2
  183. data/lib/libv8/scons/engine/SCons/__init__.py +6 -6
  184. data/lib/libv8/scons/engine/SCons/compat/__init__.py +2 -2
  185. data/lib/libv8/scons/engine/SCons/compat/_scons_builtins.py +2 -2
  186. data/lib/libv8/scons/engine/SCons/compat/_scons_collections.py +2 -2
  187. data/lib/libv8/scons/engine/SCons/compat/_scons_dbm.py +2 -2
  188. data/lib/libv8/scons/engine/SCons/compat/_scons_hashlib.py +2 -2
  189. data/lib/libv8/scons/engine/SCons/compat/_scons_io.py +2 -2
  190. data/lib/libv8/scons/engine/SCons/cpp.py +2 -2
  191. data/lib/libv8/scons/engine/SCons/dblite.py +4 -1
  192. data/lib/libv8/scons/engine/SCons/exitfuncs.py +2 -2
  193. data/lib/libv8/scons/scons-time.1 +3 -3
  194. data/lib/libv8/scons/scons.1 +1209 -1203
  195. data/lib/libv8/scons/sconsign.1 +3 -3
  196. data/lib/libv8/scons/script/scons +22 -22
  197. data/lib/libv8/scons/script/scons-time +2 -2
  198. data/lib/libv8/scons/script/scons.bat +7 -4
  199. data/lib/libv8/scons/script/sconsign +21 -20
  200. data/lib/libv8/scons/setup.cfg +0 -1
  201. data/lib/libv8/scons/setup.py +38 -40
  202. data/lib/libv8/version.rb +4 -2
  203. data/libv8.gemspec +7 -2
  204. metadata +46 -67
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
2
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -28,7 +28,7 @@ and user errors in SCons.
28
28
 
29
29
  """
30
30
 
31
- __revision__ = "src/engine/SCons/Errors.py 5134 2010/08/16 23:02:40 bdeegan"
31
+ __revision__ = "src/engine/SCons/Errors.py 5357 2011/09/09 21:31:03 bdeegan"
32
32
 
33
33
  import SCons.Util
34
34
 
@@ -6,7 +6,7 @@ Nodes.
6
6
  """
7
7
 
8
8
  #
9
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
9
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
10
10
  #
11
11
  # Permission is hereby granted, free of charge, to any person obtaining
12
12
  # a copy of this software and associated documentation files (the
@@ -27,7 +27,7 @@ Nodes.
27
27
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28
28
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29
29
 
30
- __revision__ = "src/engine/SCons/Executor.py 5134 2010/08/16 23:02:40 bdeegan"
30
+ __revision__ = "src/engine/SCons/Executor.py 5357 2011/09/09 21:31:03 bdeegan"
31
31
 
32
32
  import collections
33
33
 
@@ -7,7 +7,7 @@ stop, and wait on jobs.
7
7
  """
8
8
 
9
9
  #
10
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
10
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
11
11
  #
12
12
  # Permission is hereby granted, free of charge, to any person obtaining
13
13
  # a copy of this software and associated documentation files (the
@@ -29,7 +29,7 @@ stop, and wait on jobs.
29
29
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30
30
  #
31
31
 
32
- __revision__ = "src/engine/SCons/Job.py 5134 2010/08/16 23:02:40 bdeegan"
32
+ __revision__ = "src/engine/SCons/Job.py 5357 2011/09/09 21:31:03 bdeegan"
33
33
 
34
34
  import SCons.compat
35
35
 
@@ -1,5 +1,5 @@
1
1
  #
2
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
2
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
3
3
  #
4
4
  # Permission is hereby granted, free of charge, to any person obtaining
5
5
  # a copy of this software and associated documentation files (the
@@ -21,7 +21,7 @@
21
21
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
22
  #
23
23
 
24
- __revision__ = "src/engine/SCons/Memoize.py 5134 2010/08/16 23:02:40 bdeegan"
24
+ __revision__ = "src/engine/SCons/Memoize.py 5357 2011/09/09 21:31:03 bdeegan"
25
25
 
26
26
  __doc__ = """Memoizer
27
27
 
@@ -8,7 +8,7 @@ This creates a hash of global Aliases (dummy targets).
8
8
  """
9
9
 
10
10
  #
11
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
11
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
12
12
  #
13
13
  # Permission is hereby granted, free of charge, to any person obtaining
14
14
  # a copy of this software and associated documentation files (the
@@ -30,7 +30,7 @@ This creates a hash of global Aliases (dummy targets).
30
30
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
31
31
  #
32
32
 
33
- __revision__ = "src/engine/SCons/Node/Alias.py 5134 2010/08/16 23:02:40 bdeegan"
33
+ __revision__ = "src/engine/SCons/Node/Alias.py 5357 2011/09/09 21:31:03 bdeegan"
34
34
 
35
35
  import collections
36
36
 
@@ -11,7 +11,7 @@ that can be used by scripts or modules looking for the canonical default.
11
11
  """
12
12
 
13
13
  #
14
- # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 The SCons Foundation
14
+ # Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 The SCons Foundation
15
15
  #
16
16
  # Permission is hereby granted, free of charge, to any person obtaining
17
17
  # a copy of this software and associated documentation files (the
@@ -32,7 +32,7 @@ that can be used by scripts or modules looking for the canonical default.
32
32
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33
33
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34
34
 
35
- __revision__ = "src/engine/SCons/Node/FS.py 5134 2010/08/16 23:02:40 bdeegan"
35
+ __revision__ = "src/engine/SCons/Node/FS.py 5357 2011/09/09 21:31:03 bdeegan"
36
36
 
37
37
  import fnmatch
38
38
  import os
@@ -56,6 +56,7 @@ import SCons.Warnings
56
56
  from SCons.Debug import Trace
57
57
 
58
58
  do_store_info = True
59
+ print_duplicate = 0
59
60
 
60
61
 
61
62
  class EntryProxyAttributeError(AttributeError):
@@ -110,33 +111,85 @@ def save_strings(val):
110
111
  #
111
112
 
112
113
  do_splitdrive = None
114
+ _my_splitdrive =None
113
115
 
114
116
  def initialize_do_splitdrive():
115
117
  global do_splitdrive
118
+ global has_unc
116
119
  drive, path = os.path.splitdrive('X:/foo')
117
- do_splitdrive = not not drive
120
+ has_unc = hasattr(os.path, 'splitunc')
121
+
122
+ do_splitdrive = not not drive or has_unc
123
+
124
+ global _my_splitdrive
125
+ if has_unc:
126
+ def splitdrive(p):
127
+ if p[1:2] == ':':
128
+ return p[:2], p[2:]
129
+ if p[0:2] == '//':
130
+ # Note that we leave a leading slash in the path
131
+ # because UNC paths are always absolute.
132
+ return '//', p[1:]
133
+ return '', p
134
+ else:
135
+ def splitdrive(p):
136
+ if p[1:2] == ':':
137
+ return p[:2], p[2:]
138
+ return '', p
139
+ _my_splitdrive = splitdrive
140
+
141
+ # Keep some commonly used values in global variables to skip to
142
+ # module look-up costs.
143
+ global OS_SEP
144
+ global UNC_PREFIX
145
+ global os_sep_is_slash
146
+
147
+ OS_SEP = os.sep
148
+ UNC_PREFIX = OS_SEP + OS_SEP
149
+ os_sep_is_slash = OS_SEP == '/'
118
150
 
119
151
  initialize_do_splitdrive()
120
152
 
121
- #
122
-
123
- needs_normpath_check = None
124
-
125
- def initialize_normpath_check():
126
- """
127
- Initialize the normpath_check regular expression.
128
-
129
- This function is used by the unit tests to re-initialize the pattern
130
- when testing for behavior with different values of os.sep.
131
- """
132
- global needs_normpath_check
133
- if os.sep == '/':
134
- pattern = r'.*/|\.$|\.\.$'
135
- else:
136
- pattern = r'.*[/%s]|\.$|\.\.$' % re.escape(os.sep)
137
- needs_normpath_check = re.compile(pattern)
138
-
139
- initialize_normpath_check()
153
+ # Used to avoid invoking os.path.normpath if not necessary.
154
+ needs_normpath_check = re.compile(
155
+ r'''
156
+ # We need to renormalize the path if it contains any consecutive
157
+ # '/' characters.
158
+ .*// |
159
+
160
+ # We need to renormalize the path if it contains a '..' directory.
161
+ # Note that we check for all the following cases:
162
+ #
163
+ # a) The path is a single '..'
164
+ # b) The path starts with '..'. E.g. '../' or '../moredirs'
165
+ # but we not match '..abc/'.
166
+ # c) The path ends with '..'. E.g. '/..' or 'dirs/..'
167
+ # d) The path contains a '..' in the middle.
168
+ # E.g. dirs/../moredirs
169
+
170
+ (.*/)?\.\.(?:/|$) |
171
+
172
+ # We need to renormalize the path if it contains a '.'
173
+ # directory, but NOT if it is a single '.' '/' characters. We
174
+ # do not want to match a single '.' because this case is checked
175
+ # for explicitely since this is common enough case.
176
+ #
177
+ # Note that we check for all the following cases:
178
+ #
179
+ # a) We don't match a single '.'
180
+ # b) We match if the path starts with '.'. E.g. './' or
181
+ # './moredirs' but we not match '.abc/'.
182
+ # c) We match if the path ends with '.'. E.g. '/.' or
183
+ # 'dirs/.'
184
+ # d) We match if the path contains a '.' in the middle.
185
+ # E.g. dirs/./moredirs
186
+
187
+ \./|.*/\.(?:/|$)
188
+
189
+ ''',
190
+ re.VERBOSE
191
+ )
192
+ needs_normpath_match = needs_normpath_check.match
140
193
 
141
194
  #
142
195
  # SCons.Action objects for interacting with the outside world.
@@ -438,21 +491,21 @@ class EntryProxy(SCons.Util.Proxy):
438
491
  def __get_posix_path(self):
439
492
  """Return the path with / as the path separator,
440
493
  regardless of platform."""
441
- if os.sep == '/':
494
+ if os_sep_is_slash:
442
495
  return self
443
496
  else:
444
497
  entry = self.get()
445
- r = entry.get_path().replace(os.sep, '/')
498
+ r = entry.get_path().replace(OS_SEP, '/')
446
499
  return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_posix")
447
500
 
448
501
  def __get_windows_path(self):
449
502
  """Return the path with \ as the path separator,
450
503
  regardless of platform."""
451
- if os.sep == '\\':
504
+ if OS_SEP == '\\':
452
505
  return self
453
506
  else:
454
507
  entry = self.get()
455
- r = entry.get_path().replace(os.sep, '\\')
508
+ r = entry.get_path().replace(OS_SEP, '\\')
456
509
  return SCons.Subst.SpecialAttrWrapper(r, entry.name + "_windows")
457
510
 
458
511
  def __get_srcnode(self):
@@ -533,9 +586,13 @@ class Base(SCons.Node.Node):
533
586
 
534
587
  # Filenames and paths are probably reused and are intern'ed to
535
588
  # save some memory.
589
+
590
+ #: Filename with extension as it was specified when the object was
591
+ #: created; to obtain filesystem path, use Python str() function
536
592
  self.name = SCons.Util.silent_intern(name)
593
+ #: Cached filename extension
537
594
  self.suffix = SCons.Util.silent_intern(SCons.Util.splitext(name)[1])
538
- self.fs = fs
595
+ self.fs = fs #: Reference to parent Node.FS object
539
596
 
540
597
  assert directory, "A directory must be provided"
541
598
 
@@ -606,7 +663,7 @@ class Base(SCons.Node.Node):
606
663
  else:
607
664
  result = srcnode.get_path()
608
665
  if not Save_Strings:
609
- # We're not at the point where we're saving the string string
666
+ # We're not at the point where we're saving the string
610
667
  # representations of FS Nodes (because we haven't finished
611
668
  # reading the SConscript files and need to have str() return
612
669
  # things relative to them). That also means we can't yet
@@ -695,11 +752,15 @@ class Base(SCons.Node.Node):
695
752
  if self == dir:
696
753
  return '.'
697
754
  path_elems = self.path_elements
755
+ pathname = ''
698
756
  try: i = path_elems.index(dir)
699
- except ValueError: pass
700
- else: path_elems = path_elems[i+1:]
701
- path_elems = [n.name for n in path_elems]
702
- return os.sep.join(path_elems)
757
+ except ValueError:
758
+ for p in path_elems[:-1]:
759
+ pathname += p.dirname
760
+ else:
761
+ for p in path_elems[i+1:-1]:
762
+ pathname += p.dirname
763
+ return pathname + path_elems[-1].name
703
764
 
704
765
  def set_src_builder(self, builder):
705
766
  """Set the source code builder for this node."""
@@ -1063,7 +1124,7 @@ class FS(LocalFS):
1063
1124
  self.pathTop = os.getcwd()
1064
1125
  else:
1065
1126
  self.pathTop = path
1066
- self.defaultDrive = _my_normcase(os.path.splitdrive(self.pathTop)[0])
1127
+ self.defaultDrive = _my_normcase(_my_splitdrive(self.pathTop)[0])
1067
1128
 
1068
1129
  self.Top = self.Dir(self.pathTop)
1069
1130
  self.Top.path = '.'
@@ -1083,7 +1144,10 @@ class FS(LocalFS):
1083
1144
  self.max_drift = max_drift
1084
1145
 
1085
1146
  def getcwd(self):
1086
- return self._cwd
1147
+ if hasattr(self, "_cwd"):
1148
+ return self._cwd
1149
+ else:
1150
+ return "<no cwd>"
1087
1151
 
1088
1152
  def chdir(self, dir, change_os_dir=0):
1089
1153
  """Change the current working directory for lookups.
@@ -1147,54 +1211,110 @@ class FS(LocalFS):
1147
1211
  # str(p) in case it's something like a proxy object
1148
1212
  p = str(p)
1149
1213
 
1150
- initial_hash = (p[0:1] == '#')
1151
- if initial_hash:
1214
+ if not os_sep_is_slash:
1215
+ p = p.replace(OS_SEP, '/')
1216
+
1217
+ if p[0:1] == '#':
1152
1218
  # There was an initial '#', so we strip it and override
1153
1219
  # whatever directory they may have specified with the
1154
1220
  # top-level SConstruct directory.
1155
1221
  p = p[1:]
1156
1222
  directory = self.Top
1157
1223
 
1158
- if directory and not isinstance(directory, Dir):
1159
- directory = self.Dir(directory)
1224
+ # There might be a drive letter following the
1225
+ # '#'. Although it is not described in the SCons man page,
1226
+ # the regression test suite explicitly tests for that
1227
+ # syntax. It seems to mean the following thing:
1228
+ #
1229
+ # Assuming the the SCons top dir is in C:/xxx/yyy,
1230
+ # '#X:/toto' means X:/xxx/yyy/toto.
1231
+ #
1232
+ # i.e. it assumes that the X: drive has a directory
1233
+ # structure similar to the one found on drive C:.
1234
+ if do_splitdrive:
1235
+ drive, p = _my_splitdrive(p)
1236
+ if drive:
1237
+ root = self.get_root(drive)
1238
+ else:
1239
+ root = directory.root
1240
+ else:
1241
+ root = directory.root
1160
1242
 
1161
- if do_splitdrive:
1162
- drive, p = os.path.splitdrive(p)
1163
- else:
1164
- drive = ''
1165
- if drive and not p:
1166
- # This causes a naked drive letter to be treated as a synonym
1167
- # for the root directory on that drive.
1168
- p = os.sep
1169
- absolute = os.path.isabs(p)
1170
-
1171
- needs_normpath = needs_normpath_check.match(p)
1172
-
1173
- if initial_hash or not absolute:
1174
- # This is a relative lookup, either to the top-level
1175
- # SConstruct directory (because of the initial '#') or to
1176
- # the current directory (the path name is not absolute).
1177
- # Add the string to the appropriate directory lookup path,
1178
- # after which the whole thing gets normalized.
1179
- if not directory:
1180
- directory = self._cwd
1181
- if p:
1243
+ # We can only strip trailing after splitting the drive
1244
+ # since the drive might the UNC '//' prefix.
1245
+ p = p.strip('/')
1246
+
1247
+ needs_normpath = needs_normpath_match(p)
1248
+
1249
+ # The path is relative to the top-level SCons directory.
1250
+ if p in ('', '.'):
1251
+ p = directory.labspath
1252
+ else:
1182
1253
  p = directory.labspath + '/' + p
1254
+ else:
1255
+ if do_splitdrive:
1256
+ drive, p = _my_splitdrive(p)
1257
+ if drive and not p:
1258
+ # This causes a naked drive letter to be treated
1259
+ # as a synonym for the root directory on that
1260
+ # drive.
1261
+ p = '/'
1183
1262
  else:
1184
- p = directory.labspath
1263
+ drive = ''
1185
1264
 
1186
- if needs_normpath:
1187
- p = os.path.normpath(p)
1265
+ # We can only strip trailing '/' since the drive might the
1266
+ # UNC '//' prefix.
1267
+ if p != '/':
1268
+ p = p.rstrip('/')
1188
1269
 
1189
- if drive or absolute:
1190
- root = self.get_root(drive)
1191
- else:
1192
- if not directory:
1193
- directory = self._cwd
1194
- root = directory.root
1270
+ needs_normpath = needs_normpath_match(p)
1271
+
1272
+ if p[0:1] == '/':
1273
+ # Absolute path
1274
+ root = self.get_root(drive)
1275
+ else:
1276
+ # This is a relative lookup or to the current directory
1277
+ # (the path name is not absolute). Add the string to the
1278
+ # appropriate directory lookup path, after which the whole
1279
+ # thing gets normalized.
1280
+ if directory:
1281
+ if not isinstance(directory, Dir):
1282
+ directory = self.Dir(directory)
1283
+ else:
1284
+ directory = self._cwd
1285
+
1286
+ if p in ('', '.'):
1287
+ p = directory.labspath
1288
+ else:
1289
+ p = directory.labspath + '/' + p
1290
+
1291
+ if drive:
1292
+ root = self.get_root(drive)
1293
+ else:
1294
+ root = directory.root
1295
+
1296
+ if needs_normpath is not None:
1297
+ # Normalize a pathname. Will return the same result for
1298
+ # equivalent paths.
1299
+ #
1300
+ # We take advantage of the fact that we have an absolute
1301
+ # path here for sure. In addition, we know that the
1302
+ # components of lookup path are separated by slashes at
1303
+ # this point. Because of this, this code is about 2X
1304
+ # faster than calling os.path.normpath() followed by
1305
+ # replacing os.sep with '/' again.
1306
+ ins = p.split('/')[1:]
1307
+ outs = []
1308
+ for d in ins:
1309
+ if d == '..':
1310
+ try:
1311
+ outs.pop()
1312
+ except IndexError:
1313
+ pass
1314
+ elif d not in ('', '.'):
1315
+ outs.append(d)
1316
+ p = '/' + '/'.join(outs)
1195
1317
 
1196
- if os.sep != '/':
1197
- p = p.replace(os.sep, '/')
1198
1318
  return root._lookup_abs(p, fsclass, create)
1199
1319
 
1200
1320
  def Entry(self, name, directory = None, create = 1):
@@ -1300,7 +1420,7 @@ class DirNodeInfo(SCons.Node.NodeInfoBase):
1300
1420
  top = self.fs.Top
1301
1421
  root = top.root
1302
1422
  if do_splitdrive:
1303
- drive, s = os.path.splitdrive(s)
1423
+ drive, s = _my_splitdrive(s)
1304
1424
  if drive:
1305
1425
  root = self.fs.get_root(drive)
1306
1426
  if not os.path.isabs(s):
@@ -1350,11 +1470,34 @@ class Dir(Base):
1350
1470
  self.variant_dirs = []
1351
1471
  self.root = self.dir.root
1352
1472
 
1473
+ # For directories, we make a difference between the directory
1474
+ # 'name' and the directory 'dirname'. The 'name' attribute is
1475
+ # used when we need to print the 'name' of the directory or
1476
+ # when we it is used as the last part of a path. The 'dirname'
1477
+ # is used when the directory is not the last element of the
1478
+ # path. The main reason for making that distinction is that
1479
+ # for RoorDir's the dirname can not be easily inferred from
1480
+ # the name. For example, we have to add a '/' after a drive
1481
+ # letter but not after a UNC path prefix ('//').
1482
+ self.dirname = self.name + OS_SEP
1483
+
1353
1484
  # Don't just reset the executor, replace its action list,
1354
1485
  # because it might have some pre-or post-actions that need to
1355
1486
  # be preserved.
1356
- self.builder = get_MkdirBuilder()
1357
- self.get_executor().set_action_list(self.builder.action)
1487
+ #
1488
+ # But don't reset the executor if there is a non-null executor
1489
+ # attached already. The existing executor might have other
1490
+ # targets, in which case replacing the action list with a
1491
+ # Mkdir action is a big mistake.
1492
+ if not hasattr(self, 'executor'):
1493
+ self.builder = get_MkdirBuilder()
1494
+ self.get_executor().set_action_list(self.builder.action)
1495
+ else:
1496
+ # Prepend MkdirBuilder action to existing action list
1497
+ l = self.get_executor().action_list
1498
+ a = get_MkdirBuilder().action
1499
+ l.insert(0, a)
1500
+ self.get_executor().set_action_list(l)
1358
1501
 
1359
1502
  def diskcheck_match(self):
1360
1503
  diskcheck_match(self, self.isfile,
@@ -1403,23 +1546,6 @@ class Dir(Base):
1403
1546
  """
1404
1547
  return self.fs.File(name, self)
1405
1548
 
1406
- def _lookup_rel(self, name, klass, create=1):
1407
- """
1408
- Looks up a *normalized* relative path name, relative to this
1409
- directory.
1410
-
1411
- This method is intended for use by internal lookups with
1412
- already-normalized path data. For general-purpose lookups,
1413
- use the Entry(), Dir() and File() methods above.
1414
-
1415
- This method does *no* input checking and will die or give
1416
- incorrect results if it's passed a non-normalized path name (e.g.,
1417
- a path containing '..'), an absolute path name, a top-relative
1418
- ('#foo') path name, or any kind of object.
1419
- """
1420
- name = self.entry_labspath(name)
1421
- return self.root._lookup_abs(name, klass, create)
1422
-
1423
1549
  def link(self, srcdir, duplicate):
1424
1550
  """Set this directory as the variant directory for the
1425
1551
  supplied source directory."""
@@ -1452,7 +1578,7 @@ class Dir(Base):
1452
1578
  if fname == '.':
1453
1579
  fname = dir.name
1454
1580
  else:
1455
- fname = dir.name + os.sep + fname
1581
+ fname = dir.name + OS_SEP + fname
1456
1582
  dir = dir.up()
1457
1583
 
1458
1584
  self._memo['get_all_rdirs'] = list(result)
@@ -1466,7 +1592,7 @@ class Dir(Base):
1466
1592
  self.__clearRepositoryCache()
1467
1593
 
1468
1594
  def up(self):
1469
- return self.entries['..']
1595
+ return self.dir
1470
1596
 
1471
1597
  def _rel_path_key(self, other):
1472
1598
  return str(other)
@@ -1514,14 +1640,14 @@ class Dir(Base):
1514
1640
  if dir_rel_path == '.':
1515
1641
  result = other.name
1516
1642
  else:
1517
- result = dir_rel_path + os.sep + other.name
1643
+ result = dir_rel_path + OS_SEP + other.name
1518
1644
  else:
1519
1645
  i = self.path_elements.index(other) + 1
1520
1646
 
1521
1647
  path_elems = ['..'] * (len(self.path_elements) - i) \
1522
1648
  + [n.name for n in other.path_elements[i:]]
1523
1649
 
1524
- result = os.sep.join(path_elems)
1650
+ result = OS_SEP.join(path_elems)
1525
1651
 
1526
1652
  memo_dict[other] = result
1527
1653
 
@@ -1691,16 +1817,16 @@ class Dir(Base):
1691
1817
  return stamp
1692
1818
 
1693
1819
  def entry_abspath(self, name):
1694
- return self.abspath + os.sep + name
1820
+ return self.abspath + OS_SEP + name
1695
1821
 
1696
1822
  def entry_labspath(self, name):
1697
1823
  return self.labspath + '/' + name
1698
1824
 
1699
1825
  def entry_path(self, name):
1700
- return self.path + os.sep + name
1826
+ return self.path + OS_SEP + name
1701
1827
 
1702
1828
  def entry_tpath(self, name):
1703
- return self.tpath + os.sep + name
1829
+ return self.tpath + OS_SEP + name
1704
1830
 
1705
1831
  def entry_exists_on_disk(self, name):
1706
1832
  try:
@@ -1721,7 +1847,7 @@ class Dir(Base):
1721
1847
  if result is None:
1722
1848
  # Belt-and-suspenders for Windows: check directly for
1723
1849
  # 8.3 file names that don't show up in os.listdir().
1724
- result = os.path.exists(self.abspath + os.sep + name)
1850
+ result = os.path.exists(self.abspath + OS_SEP + name)
1725
1851
  d[name] = result
1726
1852
  return result
1727
1853
  else:
@@ -1742,7 +1868,7 @@ class Dir(Base):
1742
1868
  while dir:
1743
1869
  if dir.srcdir:
1744
1870
  result.append(dir.srcdir.Dir(dirname))
1745
- dirname = dir.name + os.sep + dirname
1871
+ dirname = dir.name + OS_SEP + dirname
1746
1872
  dir = dir.up()
1747
1873
 
1748
1874
  self._memo['srcdir_list'] = result
@@ -1986,7 +2112,7 @@ class RootDir(Dir):
1986
2112
  add a separator when creating the path names of entries within
1987
2113
  this directory.
1988
2114
  """
1989
- def __init__(self, name, fs):
2115
+ def __init__(self, drive, fs):
1990
2116
  if __debug__: logInstanceCreation(self, 'Node.FS.RootDir')
1991
2117
  # We're going to be our own parent directory (".." entry and .dir
1992
2118
  # attribute) so we have to set up some values so Base.__init__()
@@ -1998,29 +2124,47 @@ class RootDir(Dir):
1998
2124
  self.path_elements = []
1999
2125
  self.duplicate = 0
2000
2126
  self.root = self
2127
+
2128
+ # Handle all the types of drives:
2129
+ if drive == '':
2130
+ # No drive, regular UNIX root or Windows default drive.
2131
+ name = OS_SEP
2132
+ dirname = OS_SEP
2133
+ elif drive == '//':
2134
+ # UNC path
2135
+ name = UNC_PREFIX
2136
+ dirname = UNC_PREFIX
2137
+ else:
2138
+ # Windows drive letter
2139
+ name = drive
2140
+ dirname = drive + OS_SEP
2141
+
2001
2142
  Base.__init__(self, name, self, fs)
2002
2143
 
2003
- # Now set our paths to what we really want them to be: the
2004
- # initial drive letter (the name) plus the directory separator,
2005
- # except for the "lookup abspath," which does not have the
2006
- # drive letter.
2007
- self.abspath = name + os.sep
2144
+ # Now set our paths to what we really want them to be. The
2145
+ # name should already contain any necessary separators, such
2146
+ # as the initial drive letter (the name) plus the directory
2147
+ # separator, except for the "lookup abspath," which does not
2148
+ # have the drive letter.
2149
+ self.abspath = dirname
2008
2150
  self.labspath = ''
2009
- self.path = name + os.sep
2010
- self.tpath = name + os.sep
2151
+ self.path = dirname
2152
+ self.tpath = dirname
2011
2153
  self._morph()
2012
2154
 
2155
+ # Must be reset after Dir._morph() is invoked...
2156
+ self.dirname = dirname
2157
+
2013
2158
  self._lookupDict = {}
2014
2159
 
2015
- # The // and os.sep + os.sep entries are necessary because
2016
- # os.path.normpath() seems to preserve double slashes at the
2017
- # beginning of a path (presumably for UNC path names), but
2018
- # collapses triple slashes to a single slash.
2019
2160
  self._lookupDict[''] = self
2020
2161
  self._lookupDict['/'] = self
2021
- self._lookupDict['//'] = self
2022
- self._lookupDict[os.sep] = self
2023
- self._lookupDict[os.sep + os.sep] = self
2162
+
2163
+ # The // entry is necessary because os.path.normpath()
2164
+ # preserves double slashes at the beginning of a path on Posix
2165
+ # platforms.
2166
+ if not has_unc:
2167
+ self._lookupDict['//'] = self
2024
2168
 
2025
2169
  def must_be_same(self, klass):
2026
2170
  if klass is Dir:
@@ -2039,7 +2183,7 @@ class RootDir(Dir):
2039
2183
  normalized absolute path; we merely let Python's dictionary look
2040
2184
  up and return the One True Node.FS object for the path.
2041
2185
 
2042
- If no Node for the specified "p" doesn't already exist, and
2186
+ If a Node for the specified "p" doesn't already exist, and
2043
2187
  "create" is specified, the Node may be created after recursive
2044
2188
  invocation to find or create the parent directory or directories.
2045
2189
  """
@@ -2052,7 +2196,17 @@ class RootDir(Dir):
2052
2196
  raise SCons.Errors.UserError(msg)
2053
2197
  # There is no Node for this path name, and we're allowed
2054
2198
  # to create it.
2055
- dir_name, file_name = os.path.split(p)
2199
+ # (note: would like to use p.rsplit('/',1) here but
2200
+ # that's not in python 2.3)
2201
+ # e.g.: dir_name, file_name = p.rsplit('/',1)
2202
+ last_slash = p.rindex('/')
2203
+ if (last_slash >= 0):
2204
+ dir_name = p[:last_slash]
2205
+ file_name = p[last_slash+1:]
2206
+ else:
2207
+ dir_name = p # shouldn't happen, just in case
2208
+ file_name = ''
2209
+
2056
2210
  dir_node = self._lookup_abs(dir_name, Dir)
2057
2211
  result = klass(file_name, dir_node, self.fs)
2058
2212
 
@@ -2111,7 +2265,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase):
2111
2265
  top = self.fs.Top
2112
2266
  root = top.root
2113
2267
  if do_splitdrive:
2114
- drive, s = os.path.splitdrive(s)
2268
+ drive, s = _my_splitdrive(s)
2115
2269
  if drive:
2116
2270
  root = self.fs.get_root(drive)
2117
2271
  if not os.path.isabs(s):
@@ -2129,7 +2283,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
2129
2283
  usual string representation: relative to the top-level SConstruct
2130
2284
  directory, or an absolute path if it's outside.
2131
2285
  """
2132
- if os.sep == '/':
2286
+ if os_sep_is_slash:
2133
2287
  node_to_str = str
2134
2288
  else:
2135
2289
  def node_to_str(n):
@@ -2138,7 +2292,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase):
2138
2292
  except AttributeError:
2139
2293
  s = str(n)
2140
2294
  else:
2141
- s = s.replace(os.sep, '/')
2295
+ s = s.replace(OS_SEP, '/')
2142
2296
  return s
2143
2297
  for attr in ['bsources', 'bdepends', 'bimplicit']:
2144
2298
  try:
@@ -2638,6 +2792,8 @@ class File(Base):
2638
2792
 
2639
2793
  def _rmv_existing(self):
2640
2794
  self.clear_memoized_values()
2795
+ if print_duplicate:
2796
+ print "dup: removing existing target %s"%self
2641
2797
  e = Unlink(self, [], None)
2642
2798
  if isinstance(e, SCons.Errors.BuildError):
2643
2799
  raise e
@@ -2678,6 +2834,8 @@ class File(Base):
2678
2834
 
2679
2835
  def do_duplicate(self, src):
2680
2836
  self._createDir()
2837
+ if print_duplicate:
2838
+ print "dup: relinking variant '%s' from '%s'"%(self, src)
2681
2839
  Unlink(self, None, None)
2682
2840
  e = Link(self, src, None)
2683
2841
  if isinstance(e, SCons.Errors.BuildError):
@@ -2711,6 +2869,8 @@ class File(Base):
2711
2869
  else:
2712
2870
  # The source file does not exist. Make sure no old
2713
2871
  # copy remains in the variant directory.
2872
+ if print_duplicate:
2873
+ print "dup: no src for %s, unlinking old variant copy"%self
2714
2874
  if Base.exists(self) or self.islink():
2715
2875
  self.fs.unlink(self.path)
2716
2876
  # Return None explicitly because the Base.exists() call
@@ -2982,8 +3142,8 @@ class FileFinder(object):
2982
3142
  if fd is None:
2983
3143
  fd = self.default_filedir
2984
3144
  dir, name = os.path.split(fd)
2985
- drive, d = os.path.splitdrive(dir)
2986
- if not name and d[:1] in ('/', os.sep):
3145
+ drive, d = _my_splitdrive(dir)
3146
+ if not name and d[:1] in ('/', OS_SEP):
2987
3147
  #return p.fs.get_root(drive).dir_on_disk(name)
2988
3148
  return p.fs.get_root(drive)
2989
3149
  if dir: