--- a/CmdLineParser.st Tue Jun 28 07:34:09 2016 +0100
+++ b/CmdLineParser.st Wed Jun 29 00:18:22 2016 +0100
@@ -14,7 +14,7 @@
"{ NameSpace: Smalltalk }"
Object subclass:#CmdLineParser
- instanceVariableNames:'options argv'
+ instanceVariableNames:'options ignoreUnknownOptions'
classVariableNames:''
poolDictionaries:''
category:'System-Support-Command line'
@@ -36,6 +36,14 @@
"
! !
+!CmdLineParser class methodsFor:'instance creation'!
+
+new
+ "return an initialized instance"
+
+ ^ self basicNew initialize.
+! !
+
!CmdLineParser class methodsFor:'parsing'!
parse: argv for: object
@@ -47,17 +55,6 @@
!CmdLineParser methodsFor:'accessing'!
-args
- ^ argv
-!
-
-args:aCollection
-
- argv := aCollection
-
- "Modified: / 08-06-2009 / 13:24:02 / Jan Vrany <vranyj1@fel.cvut.cz>"
-!
-
cmdlineOptionHelp
^CmdLineOption new
@@ -69,6 +66,21 @@
"Created: / 08-06-2009 / 14:54:11 / Jan Vrany <vranyj1@fel.cvut.cz>"
!
+ignoreUnknownOptions
+ ^ ignoreUnknownOptions
+!
+
+ignoreUnknownOptions:aBoolean
+ "When set to true, unknown options are silently ignored and added to
+ a list of positional arguments returned by #parse:.
+ When set to false, an error is triggered when an unknown option is
+ encountered (this is the default behaviour)"
+
+ ignoreUnknownOptions := aBoolean.
+
+ "Modified (comment): / 29-06-2016 / 00:03:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
options
^ options
!
@@ -130,45 +142,55 @@
"Created: / 08-06-2009 / 13:06:23 / Jan Vrany <vranyj1@fel.cvut.cz>"
"Modified: / 06-11-2011 / 21:40:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+initialize
+ "Invoked when a new instance is created."
+
+ "/ please change as required (and remove this comment)
+ "/ options := nil.
+ ignoreUnknownOptions := false.
+
+ "/ super initialize. -- commented since inherited method does nothing
+
+ "Modified: / 29-06-2016 / 00:04:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!CmdLineParser methodsFor:'parsing'!
-parse
+parse: argv
"
- Parses argv array.
- Returns array of unparsed (i.e. non-option) arguments
+ Parses argv array. Returns array of unparsed (i.e. non-options / unknown options) arguments
"
- | i |
- i := 1.
- [i <= argv size] whileTrue:
- [|arg option |
- arg := argv at:i.
- "arg is not an option"
- arg first ~= $-
- ifTrue:
- [^argv copyFrom: i].
- i := self parseArg: i
- ].
- ^#()
+ | unparsed current |
+
+ unparsed := OrderedCollection new.
+ current := 1.
+ [current <= argv size] whileTrue: [
+ | arg next |
- "Created: / 08-06-2009 / 13:26:22 / Jan Vrany <vranyj1@fel.cvut.cz>"
- "Modified: / 08-06-2009 / 14:38:33 / Jan Vrany <vranyj1@fel.cvut.cz>"
-!
-
-parse:aCollection
- "
- Parses argv array. Returns array of unparsed (i.e. non-option)
- arguments
- "
-
- ^self
- args: aCollection;
- parse.
+ arg := argv at:current.
+ arg first == $- ifTrue:[
+ "/ maybe an option
+ next := self parse: argv argAt: current.
+ next == 0 ifTrue:[
+ "/ Option has not been recognized
+ unparsed add: arg.
+ next := current + 1.
+ ]
+ ] ifFalse:[
+ "/ not an option
+ unparsed addAll: (argv copyFrom: current).
+ next := argv size + 1.
+ ].
+ current := next.
+ ].
+ ^ unparsed
"Created: / 28-01-2009 / 12:08:29 / Jan Vrany <vranyj1@fel.cvut.cz>"
"Modified: / 08-06-2009 / 13:26:26 / Jan Vrany <vranyj1@fel.cvut.cz>"
+ "Modified: / 29-06-2016 / 00:15:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
parse: argv for: object
@@ -224,10 +246,11 @@
ifNone:[
longName = 'help'
ifTrue:[self cmdlineOptionHelp]
- ifFalse:[CmdLineOptionError raiseErrorString:'Unknown option: ' , longName ]]
+ ifFalse:[ignoreUnknownOptions ifTrue:[nil] ifFalse:[CmdLineOptionError raiseErrorString:'Unknown option: ' , longName ]]]
"Created: / 30-01-2009 / 09:15:24 / Jan Vrany <vranyj1@fel.cvut.cz>"
"Modified: / 08-06-2009 / 14:57:42 / Jan Vrany <vranyj1@fel.cvut.cz>"
+ "Modified: / 29-06-2016 / 00:05:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
optionByShort:shortName
@@ -236,64 +259,71 @@
ifNone:
[ shortName == $h
ifTrue:[self cmdlineOptionHelp]
- ifFalse:[CmdLineOptionError raiseErrorString:'Unknown option: ' , shortName ]]
+ ifFalse:[ignoreUnknownOptions ifTrue:[nil] ifFalse:[CmdLineOptionError raiseErrorString:'Unknown option: ' , shortName ]]]
"Created: / 30-01-2009 / 09:16:51 / Jan Vrany <vranyj1@fel.cvut.cz>"
"Modified: / 08-06-2009 / 14:58:14 / Jan Vrany <vranyj1@fel.cvut.cz>"
+ "Modified: / 29-06-2016 / 00:05:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-parseArg:index
- "
- Parses arg at index. Returns an index of
- next arg to be parsed."
+parse:argv argAt: index
+ "Parses arg at index. Returns an index of next arg to be parsed. If the options
+ is not recognized (i.e., is unknown), then either an error is triggered
+ (when ignoreInknownOptions is false) or 0 is returned (when ignoreInknownOptions
+ is true)"
|arg option param|
arg := argv at:index.
- arg second ~= $-
- ifTrue:
- ["/ short option or bunch of those
+ arg second ~= $- ifTrue:[
+ "/ short option or bunch of those
2 to:arg size do:[:subIndex |
option := self optionByShort:(arg at:subIndex).
- option ifNotNil:
- [option hasParam
- ifFalse:[option process]
- ifTrue:
- ["Do additional check, if this short option
- is last."
- ((subIndex ~= arg size) or:[ (argv size) < (index + 1) ]) ifTrue:[
- self errorOptionRequiresArgument:option
- ].
- param := (argv at:index + 1).
- option process:param.
- ^ index + 2
- ]]].
- ^ index + 1]
- ifFalse:
- ["/ long option starting with --
+ option notNil ifTrue: [
+ option hasParam ifFalse:[
+ option process
+ ] ifTrue:[
+ "Do additional check, if this short option is last."
+ ((subIndex ~= arg size) or:[ (argv size) < (index + 1) ]) ifTrue:[
+ self errorOptionRequiresArgument:option
+ ].
+ param := (argv at:index + 1).
+ option process:param.
+ ^ index + 2
+ ]
+ ] ifFalse:[
+ ^ 0
+ ].
+ ].
+ ^ index + 1
+ ] ifFalse: [
+ "/ long option starting with --
| equalPos |
(equalPos := arg indexOf:$=) == 0 ifTrue:[
"/no arg specified
- (option := self optionByLong:(arg copyFrom:3))
- ifNotNil:[
+ (option := self optionByLong:(arg copyFrom:3)) notNil ifTrue:[
option hasParam ifTrue:[self errorOptionRequiresArgument:option].
- option process].
- ^index + 1.
+ option process
+ ] ifFalse:[
+ ^ 0
+ ].
+ ^ index + 1.
] ifFalse: [
option := self optionByLong:(arg copyFrom:3 to: equalPos - 1).
param := arg copyFrom: equalPos + 1.
- option ifNotNil:
- [option hasParam
- ifTrue:
- [option process: param]
- ifFalse:
- [self errorOptionHasNoArgument: option]]
- ].
- ^index + 2
- ]
+ option notNil ifTrue:[
+ option hasParam
+ ifTrue: [option process: param]
+ ifFalse: [self errorOptionHasNoArgument: option]
+ ] ifFalse:[
+ ^ 0
+ ].
+ ].
+ ^ index + 2
+ ]
- "Created: / 08-06-2009 / 14:38:53 / Jan Vrany <vranyj1@fel.cvut.cz>"
+ "Created: / 28-06-2016 / 23:55:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!CmdLineParser class methodsFor:'documentation'!