mercurial/HGCommand.st
changeset 459 f46adbbf4138
parent 453 09a9ccac8aba
child 463 3ba85719b2a3
--- a/mercurial/HGCommand.st	Tue Aug 12 22:15:22 2014 +0100
+++ b/mercurial/HGCommand.st	Thu Oct 16 01:53:23 2014 +0000
@@ -774,20 +774,19 @@
     environment at:'LANG' put:'C'.
     environment at:'LC_MESSAGES' put:'C'.
 
-        exe := self executable.
+    exe := self executable.
     args := self arguments.
 
     OperatingSystem isMSWINDOWSlike ifTrue:[
-            (exe endsWith:'.bat') ifTrue:[
+        (exe endsWith:'.bat') ifTrue:[
             | cmd |
             cmd := OperatingSystem pathOfCommand:'cmd'.
             args := #( '/C' ) , args.
             exe := cmd.
-
         ].
         args := String streamContents:[:s|
             args
-                do:[:each | s nextPut:$"; nextPutAll: each; nextPut: $"]
+                do:[:each | self quoteShellCommandParameter: each asForCmdOn: s ]
                 separatedBy: [ s space ]
         ]
     ].
@@ -876,6 +875,48 @@
     ^self execute.
 
     "Created: / 03-03-2013 / 20:34:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+quoteShellCommandParameter: parameter asForCmdOn: stream
+    "Quotes the parameter as neccesary on Windows"
+
+    "/ Adapted version of ArgvQuote,
+    "/ see http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
+
+    | parameterS |
+
+    stream nextPut: $".
+    parameterS := parameter readStream.
+    [ parameterS atEnd ] whileFalse:[
+        | numBackSlashes |
+
+        numBackSlashes := 0.
+
+        [ parameterS atEnd not and:[ parameterS peek == $\ ] ] whileTrue:[
+            numBackSlashes := numBackSlashes + 1.
+            parameterS next.
+        ].
+        parameterS atEnd ifTrue:[
+            "/ Escape all backslashes, but let the terminating
+            "/ double quotation mark we add below be interpreted
+            "/ as a metacharacter.
+            stream next: numBackSlashes * 2 put: $\
+        ] ifFalse:[
+            parameterS peek == $" ifTrue:[
+                "/ Escape all backslashes and the following
+                "/ double quotation mark.
+                stream next: numBackSlashes * 2 put: $\.
+                stream nextPut: $\.
+                stream nextPut: $".
+            ] ifFalse:[
+                "/ Backslashes aren't special here.
+                stream next: numBackSlashes put: $\.               
+                stream nextPut: parameterS peek.
+            ].
+            parameterS next.
+        ].
+    ].
+    stream nextPut: $".
 ! !
 
 !HGCommand methodsFor:'initialization'!