--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/GDBShellCommandParser.st Thu Dec 13 14:53:48 2018 +0000
@@ -0,0 +1,211 @@
+"
+jv:libgdbs - GNU Debugger Interface Library
+Copyright (C) 2015-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'jv:libgdbs' }"
+
+"{ NameSpace: Smalltalk }"
+
+Object subclass:#GDBShellCommandParser
+ instanceVariableNames:'stream'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'GDB-Private'
+!
+
+!GDBShellCommandParser class methodsFor:'documentation'!
+
+copyright
+"
+jv:libgdbs - GNU Debugger Interface Library
+Copyright (C) 2015-now Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!GDBShellCommandParser class methodsFor:'parsing'!
+
+parse: input
+ "Parses input (stream or string) as a shell command. Returns
+ an array of arguments (main's argv[], actually)"
+
+ ^ self new
+ stream: input;
+ parse
+
+ "
+ GDBShellCommandParser parse: 'gdb'
+ GDBShellCommandParser parse: 'ssh jv@debian-sid-rv64 gdb'
+ "
+
+ "Created: / 12-12-2018 / 16:43:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBShellCommandParser methodsFor:'accessing'!
+
+stream
+ ^ stream
+!
+
+stream:aStringOrStream
+ stream := aStringOrStream readStream.
+
+ "Modified: / 12-12-2018 / 16:39:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBShellCommandParser methodsFor:'parsing'!
+
+parse
+ "Parses input stream as a shell command. Returns
+ an array of arguments (main's argv[], actually)"
+
+ OperatingSystem isMSWINDOWSNTlike ifTrue:[
+ ^ self parseAsForCmd
+ ] ifFalse:[
+ ^ self parseAsForSh
+ ]
+
+ "Created: / 12-12-2018 / 16:40:20 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!GDBShellCommandParser methodsFor:'parsing - private'!
+
+parseAsForCmd
+ ^ Array streamContents:[ :argv |
+ stream skipSeparators.
+ [ stream atEnd ] whileFalse:[
+ argv nextPut: self parseTokenAsForCmd.
+ stream skipSeparators.
+ ].
+ ].
+
+ "Created: / 12-12-2018 / 16:41:26 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseAsForSh
+ ^ Array streamContents:[ :argv |
+ stream skipSeparators.
+ [ stream atEnd ] whileFalse:[
+ argv nextPut: self parseTokenAsForSh.
+ stream skipSeparators.
+ ].
+ ].
+
+ "Created: / 12-12-2018 / 16:40:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseTokenAsForCmd
+ | buffer char done1 done2 |
+
+ buffer := (String new: 10) writeStream.
+ done1 := false.
+ char := stream next.
+ [ done1 ] whileFalse:[
+ char == $" ifTrue:[
+ done2 := false.
+ [ done2 ] whileFalse:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ char == $" ifTrue:[
+ done2 := true.
+ ] ifFalse:[
+ buffer nextPut: char
+ ].
+ ]
+ ] ifFalse:[
+ char == $^ ifTrue:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ char == Character space ifTrue:[
+ buffer nextPut: $^
+ ].
+ ].
+ buffer nextPut: char.
+ ].
+ char := stream atEnd ifTrue:[ nil ] ifFalse:[ stream next ].
+ done1 := char isNil or:[ char isSeparator ].
+ ].
+ ^ buffer contents
+
+ "Created: / 12-12-2018 / 16:41:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseTokenAsForSh
+ | buffer char done1 done2 |
+
+ buffer := (String new: 10) writeStream.
+ done1 := false.
+ char := stream next.
+ [ done1 ] whileFalse:[
+ char == $" ifTrue:[
+ done2 := false.
+ [ done2 ] whileFalse:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ char == $\ ifTrue:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ char == $" ifTrue:[
+ buffer nextPut: $"
+ ] ifFalse:[
+ buffer nextPut: $\; nextPut: char
+ ].
+ ] ifFalse:[ char == $" ifTrue:[
+ done2 := true.
+ ] ifFalse:[
+ buffer nextPut: char
+ ]].
+ ]
+ ] ifFalse:[ char == $' ifTrue:[
+ done2 := false.
+ [ done2 ] whileFalse:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ char == $' ifTrue:[
+ done2 := true.
+ ] ifFalse:[
+ buffer nextPut: char
+ ].
+ ]
+ ] ifFalse:[
+ char == $\ ifTrue:[
+ stream atEnd ifTrue:[ self error:'Unterminated string token'. ^ nil ].
+ char := stream next.
+ ].
+ buffer nextPut: char.
+ ]].
+ char := stream atEnd ifTrue:[ nil ] ifFalse:[ stream next ].
+ done1 := char isNil or:[ char isSeparator ].
+ ].
+ ^ buffer contents
+
+ "Created: / 12-12-2018 / 16:41:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+