diff -r 53ccffa236ed -r f46adbbf4138 mercurial/HGCommand.st --- 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 " +! + +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'!