Posted By

jc001 on 02/29/08


Tagged

parse command args line


Versions (?)

class_CommandLineParser


 / Published in: Visual Basic
 

This is a command line parsing routine I found online. Original comments left in tact.

  1. ' #VBIDEUtils#************************************************************
  2. ' * Programmer Name : Waty Thierry
  3. ' * Web Site : www.geocities.com/ResearchTriangle/6311/
  4. ' * E-Mail : [email protected]
  5. ' * Date : 24/09/98
  6. ' * Time : 14:15
  7. ' * Module Name : class_CommandLineParser
  8. ' * Module Filename : CommandLine.cls
  9. ' **********************************************************************
  10. ' * Comments : COMMAND LINE interpreter
  11. ' *
  12. ' * analyzes command line into arguments, switches, and switch values
  13. ' *** e.g. given command line
  14. ' *** << myprog myfile.txt /user="Thierry Waty" /password=Julie >>
  15. ' ***
  16. ' *** the global object will support the following:
  17. ' *** goArgv.Args.Count = 1
  18. ' *** goArgv.Switches.Count = 2
  19. ' *** goArgv.Args!arg1 = "myfile.txt"
  20. ' *** If goArgv.SwitchUsed("Debugmode") Then ....
  21. ' *** goArgv.Switches!Username = "Thierry Waty"
  22. ' *** goArgv.Switches("password") = "Julie" OR
  23. ' *** goArgv.Switches!password = "Julie"
  24. ' ***
  25. ' *** NOTES:
  26. ' *** 1) Limited support for unix style switches
  27. ' *** << myprog myfile.txt -u"Thierry Waty" -pJulie >>
  28. ' *** will give the same results as above, except the switch is always
  29. ' *** one Character
  30. ' *** goArgv.Switches!u = "Thierry Waty"
  31. ' *** goArgv.Switches!p = "Julie"
  32. ' *** 2) Can't distinguish case for the options: X is the same as x, User is the same as user
  33. ' *
  34. ' *
  35. ' **********************************************************************
  36.  
  37. Option Explicit
  38.  
  39. Public Args As Collection
  40. Public Switches As Collection
  41. Private mcolPairs As Collection 'raw switch pairs before parsed, hold the option/value pairs
  42. Private mcolKeys As Collection 'keys of switch pairs
  43.  
  44. Private Sub Class_Initialize()
  45.  
  46. ' *** creates the collection when this class is created
  47. Dim strCommand As String
  48.  
  49. Set Switches = New Collection
  50. Set mcolKeys = New Collection
  51. Set mcolPairs = New Collection
  52. Set Args = New Collection
  53.  
  54. strCommand = Trim$(Command)
  55. If Len(strCommand) = 0 Then Exit Sub
  56. Call StuffAll(strCommand)
  57.  
  58. End Sub
  59.  
  60. Private Sub Class_Terminate()
  61.  
  62. ' *** destroys collection when this class is terminated
  63. Set Switches = Nothing
  64. Set Args = Nothing
  65. Set mcolPairs = Nothing
  66. Set mcolKeys = Nothing
  67.  
  68. End Sub
  69.  
  70. Private Sub ParseAndAddSwitch(rstrWorkArgs As Variant)
  71.  
  72. 'input: entire option value string come in here, variant so
  73. ' caller can use "for each"
  74. 'output: parse and stuff option and value separately in the
  75. ' member collections
  76.  
  77. Dim intMarker As Integer
  78. Dim intSwitchPos As Integer
  79. Dim strKey As String
  80. Dim strWork As String
  81. Dim strItem As String
  82. Dim colParts As Collection
  83.  
  84. If Left$(rstrWorkArgs, 1) = "-" Then 'unix style
  85. strWork = Mid$(rstrWorkArgs, 2) 'item for stripQuotes
  86.  
  87. If Left$(strWork, 1) = " " Then 'bad unix format, s/b a character here
  88. Err.Raise 41001, TypeName(Me), "Bad UNIX command line format, space after switch symbol"
  89. End If
  90.  
  91. strItem = StripQuotes(Mid$(strWork, 2))
  92. strKey = Mid(rstrWorkArgs, 2, 1)
  93. Call Switches.Add(Item:=strItem, Key:=strKey)
  94. Call mcolKeys.Add(Item:=strKey)
  95. Else 'dos/vms style
  96.  
  97. Call ParseSwitch(rstrWorkArgs)
  98.  
  99. End If
  100.  
  101. End Sub
  102.  
  103. Private Function StripQuotes(rstrIn As String) As String
  104.  
  105. Dim strWork As String
  106.  
  107. strWork = Trim$(rstrIn)
  108.  
  109. If Left$(strWork, 1) <> """" Then 'not a quoted string
  110. StripQuotes = strWork
  111. ElseIf Right$(strWork, 1) <> """" Then 'error no terminating quote
  112. Err.Raise 41003, TypeName(Me), "Bad DOS/VMS command line format, no terminating quote"
  113. Else
  114. StripQuotes = Mid$(strWork, 2, Len(strWork) - 2)
  115. End If
  116.  
  117. End Function
  118.  
  119. Private Sub StuffAll(rstrCommand As String)
  120.  
  121. 'rstrCommand is a working string, gets the chop shop treatment
  122.  
  123. Dim strWorkArg As Variant 'working argument holder
  124. Dim lngEnd As Long
  125. Dim lngStart As Long
  126. Dim strStyle As String
  127.  
  128. Set mcolPairs = CommandToStringArray(rstrCommand)
  129.  
  130. For Each strWorkArg In mcolPairs
  131.  
  132. If Left$(strWorkArg, 1) = "-" Then 'unix style switch
  133. Call ParseAndAddSwitch(strWorkArg)
  134. ElseIf Left$(strWorkArg, 1) = "/" Then 'dos/vms style switch
  135. Call ParseAndAddSwitch(strWorkArg)
  136. Else 'regular argument
  137. Args.Add strWorkArg, "arg" & Args.Count + 1
  138. End If
  139.  
  140. Next strWorkArg
  141. End Sub
  142.  
  143. Public Function CommandToStringArray(rstrInline As String) As Collection
  144. ' *** input: command line as a string
  145. ' *** Takes input of a string containing 0+ spaces and 0+ quotes
  146. ' *** spaces normally delimit substrings, except
  147. ' *** quotes are used to protect spaces from parsing, and are cant
  148. ' *** be part of the substring
  149. ' *** returns collection of strings in a variant
  150. Dim intPos As Integer
  151. Dim intLen As Integer
  152. Dim blnInQuotes As Boolean
  153. Dim strCurrent As String
  154. Dim strChar As String
  155. Dim col As New Collection
  156. Dim i As Integer
  157. 'iterate over string looking for space delimiters NOT within quotes
  158. strCurrent = ""
  159. intLen = Len(rstrInline)
  160. For i = 1 To intLen
  161. strChar = Mid$(rstrInline, i, 1)
  162.  
  163. If strChar = """" Then
  164. blnInQuotes = Not blnInQuotes
  165. ElseIf (strChar = " " And Not blnInQuotes) Then
  166. col.Add strCurrent
  167. strCurrent = ""
  168. Else
  169. strCurrent = strCurrent & strChar
  170. End If
  171.  
  172. Next i 'over each input string character
  173. If Not strCurrent = "" Then
  174. col.Add strCurrent
  175. End If
  176.  
  177. Set CommandToStringArray = col
  178.  
  179. End Function
  180.  
  181. Public Property Get SwitchUsed(strOption As String) As Boolean
  182. ' *** answers the question: was this option used on the command line
  183. ' *** never mind the value supplied, if any
  184.  
  185. SwitchUsed = ItemInArray(strOption, mcolKeys, False)
  186.  
  187. End Property
  188.  
  189. Private Function ItemInArray(InputItem As Variant, InputArray As Variant, Optional CaseSensitive) As Boolean
  190. ' *** default for CaseSensitive = False
  191.  
  192. Dim strInputItem As String
  193. Dim strArrayItem As String
  194. Dim vntLoopItem As Variant
  195. If IsMissing(CaseSensitive) Then
  196. CaseSensitive = False
  197. End If
  198. If CaseSensitive = True Then
  199. strInputItem = InputItem
  200. Else
  201. strInputItem = UCase$(InputItem)
  202. End If
  203.  
  204. ItemInArray = False 'reset before we look
  205. For Each vntLoopItem In InputArray
  206.  
  207. If CaseSensitive = True Then
  208. strArrayItem = vntLoopItem
  209. Else
  210. strArrayItem = UCase$(vntLoopItem)
  211. End If
  212.  
  213.  
  214. If strArrayItem = strInputItem Then
  215. ItemInArray = True
  216. Exit For
  217. End If
  218. Next
  219.  
  220. End Function
  221.  
  222. Public Sub ParseSwitch(rstrSwitchPair As Variant)
  223. 'input: dos style switch/option pair separated by = sign, poss
  224. ' with quotes
  225. ' *** variant so caller can use "for each"
  226. ' *** string containing characters, 0+ spaces and 0+ quotes
  227. ' *** output: returns collection of strings in a variant
  228. ' *** quotes are used to protect spaces from parsing, they are not
  229. ' *** part of the substring
  230.  
  231. Dim intPos As Integer
  232. Dim intLen As Integer
  233. Dim blnInQuotes As Boolean
  234. Dim strCurrent As String
  235. Dim strKey As String
  236. Dim strChar As String
  237. Dim col As New Collection
  238. Dim i As Integer
  239.  
  240. 'iterate over string looking for equal sign NOT within quotes
  241. strCurrent = ""
  242. intLen = Len(rstrSwitchPair)
  243. For i = 1 To intLen
  244. strChar = Mid$(rstrSwitchPair, i, 1)
  245.  
  246. If strChar = """" Then
  247. blnInQuotes = Not blnInQuotes
  248. ElseIf (strChar = "=" And Not blnInQuotes) Then 'preceding is the Key
  249. strKey = Mid$(strCurrent, 2)
  250. strCurrent = ""
  251. Else
  252. strCurrent = strCurrent & strChar
  253. End If
  254.  
  255. Next 'over each input string character
  256. ' *** NOTE: the option value can be the empty string
  257. If strKey = "" Then 'there was no switch value, the string is the Switch alone
  258. Call Switches.Add("", Mid$(strCurrent, 2))
  259. Call mcolKeys.Add(Mid$(strCurrent, 2)) 'trim the "/"
  260. Else 'a typical switch /value pair
  261. Call Switches.Add(strCurrent, strKey)
  262. Call mcolKeys.Add(strKey)
  263. End If
  264.  
  265. End Sub

Report this snippet  

You need to login to post a comment.