@@ -133,86 +133,6 @@ final class newMain extends MainAnnotation[FromString, Any]:
133
133
val helpIsOverridden = namesToCanonicalName.exists((name, _) => name == helpArg)
134
134
val shortHelpIsOverridden = shortNamesToCanonicalName.exists((name, _) => name == shortHelpArg)
135
135
136
- val (positionalArgs, byNameArgs, invalidByNameArgs) = {
137
- def getCanonicalArgName (arg : String ): Option [String ] =
138
- if arg.startsWith(argMarker) && arg.length > argMarker.length then
139
- namesToCanonicalName.get(arg.drop(argMarker.length))
140
- else if arg.startsWith(shortArgMarker) && arg.length == shortArgMarker.length + 1 then
141
- shortNamesToCanonicalName.get(arg(shortArgMarker.length))
142
- else
143
- None
144
-
145
- def isArgName (arg : String ): Boolean =
146
- val isFullName = arg.startsWith(argMarker)
147
- val isShortName = arg.startsWith(shortArgMarker) && arg.length == shortArgMarker.length + 1 && shortNameIsValidChar(arg(shortArgMarker.length))
148
- isFullName || isShortName
149
-
150
- def recurse (remainingArgs : Seq [String ], pa : mutable.Queue [String ], bna : Seq [(String , String )], ia : Seq [String ]): (mutable.Queue [String ], Seq [(String , String )], Seq [String ]) =
151
- remainingArgs match {
152
- case Seq () =>
153
- (pa, bna, ia)
154
- case argName +: argValue +: rest if isArgName(argName) =>
155
- getCanonicalArgName(argName) match {
156
- case Some (canonicalName) => recurse(rest, pa, bna :+ (canonicalName -> argValue), ia)
157
- case None => recurse(rest, pa, bna, ia :+ argName)
158
- }
159
- case arg +: rest =>
160
- recurse(rest, pa :+ arg, bna, ia)
161
- }
162
-
163
- val (pa, bna, ia) = recurse(args.toSeq, mutable.Queue .empty, Vector (), Vector ())
164
- val nameToArgValues : Map [String , Seq [String ]] = if bna.isEmpty then Map .empty else bna.groupMapReduce(_._1)(p => List (p._2))(_ ++ _)
165
- (pa, nameToArgValues, ia)
166
- }
167
-
168
- val argStrings : Seq [Seq [String ]] =
169
- for paramInfo <- info.parameters yield {
170
- if (paramInfo.isVarargs) {
171
- val byNameGetters = byNameArgs.getOrElse(paramInfo.name, Seq ())
172
- val positionalGetters = positionalArgs.removeAll()
173
- // First take arguments passed by name, then those passed by position
174
- byNameGetters ++ positionalGetters
175
- } else {
176
- byNameArgs.get(paramInfo.name) match
177
- case Some (Nil ) =>
178
- throw AssertionError (s " ${paramInfo.name} present in byNameArgs, but it has no argument value " )
179
- case Some (argValues) =>
180
- if argValues.length > 1 then
181
- // Do not accept multiple values
182
- // Remove this test to take last given argument
183
- error(s " more than one value for ${paramInfo.name}: ${argValues.mkString(" , " )}" )
184
- Nil
185
- else
186
- List (argValues.last)
187
- case None =>
188
- if positionalArgs.length > 0 then
189
- List (positionalArgs.dequeue())
190
- else if paramInfo.hasDefault then
191
- List (" " )
192
- else
193
- error(s " missing argument for ${paramInfo.name}" )
194
- Nil
195
- }
196
- }
197
-
198
- // Check aliases unicity
199
- val nameAndCanonicalName = info.parameters.flatMap {
200
- case paramInfo => (paramInfo.name +: getAlternativeNames(paramInfo) ++: getShortNames(paramInfo)).map(_ -> paramInfo.name)
201
- }
202
- val nameToCanonicalNames = nameAndCanonicalName.groupMap(_._1)(_._2)
203
-
204
- for (name, canonicalNames) <- nameToCanonicalNames if canonicalNames.length > 1 do
205
- throw IllegalArgumentException (s " $name is used for multiple parameters: ${canonicalNames.mkString(" , " )}" )
206
-
207
- // Check aliases validity
208
- val problematicNames = info.parameters.flatMap(getInvalidNames)
209
- if problematicNames.length > 0 then
210
- throw IllegalArgumentException (s " The following aliases are invalid: ${problematicNames.mkString(" , " )}" )
211
-
212
- // Handle unused and invalid args
213
- for (remainingArg <- positionalArgs) error(s " unused argument: $remainingArg" )
214
- for (invalidArg <- invalidByNameArgs) error(s " unknown argument name: $invalidArg" )
215
-
216
136
val displayHelp =
217
137
(! helpIsOverridden && args.contains(getNameWithMarker(helpArg))) ||
218
138
(! shortHelpIsOverridden && args.contains(getNameWithMarker(shortHelpArg)))
@@ -222,12 +142,94 @@ final class newMain extends MainAnnotation[FromString, Any]:
222
142
println()
223
143
explain()
224
144
None
225
- else if errors.nonEmpty then
226
- for msg <- errors do println(s " Error: $msg" )
227
- usage()
228
- None
229
145
else
230
- Some (argStrings.flatten)
146
+ val (positionalArgs, byNameArgs, invalidByNameArgs) = {
147
+ def getCanonicalArgName (arg : String ): Option [String ] =
148
+ if arg.startsWith(argMarker) && arg.length > argMarker.length then
149
+ namesToCanonicalName.get(arg.drop(argMarker.length))
150
+ else if arg.startsWith(shortArgMarker) && arg.length == shortArgMarker.length + 1 then
151
+ shortNamesToCanonicalName.get(arg(shortArgMarker.length))
152
+ else
153
+ None
154
+
155
+ def isArgName (arg : String ): Boolean =
156
+ val isFullName = arg.startsWith(argMarker)
157
+ val isShortName = arg.startsWith(shortArgMarker) && arg.length == shortArgMarker.length + 1 && shortNameIsValidChar(arg(shortArgMarker.length))
158
+ isFullName || isShortName
159
+
160
+ def recurse (remainingArgs : Seq [String ], pa : mutable.Queue [String ], bna : Seq [(String , String )], ia : Seq [String ]): (mutable.Queue [String ], Seq [(String , String )], Seq [String ]) =
161
+ remainingArgs match {
162
+ case Seq () =>
163
+ (pa, bna, ia)
164
+ case argName +: argValue +: rest if isArgName(argName) =>
165
+ getCanonicalArgName(argName) match {
166
+ case Some (canonicalName) => recurse(rest, pa, bna :+ (canonicalName -> argValue), ia)
167
+ case None => recurse(rest, pa, bna, ia :+ argName)
168
+ }
169
+ case arg +: rest =>
170
+ recurse(rest, pa :+ arg, bna, ia)
171
+ }
172
+
173
+ val (pa, bna, ia) = recurse(args.toSeq, mutable.Queue .empty, Vector (), Vector ())
174
+ val nameToArgValues : Map [String , Seq [String ]] = if bna.isEmpty then Map .empty else bna.groupMapReduce(_._1)(p => List (p._2))(_ ++ _)
175
+ (pa, nameToArgValues, ia)
176
+ }
177
+
178
+ val argStrings : Seq [Seq [String ]] =
179
+ for paramInfo <- info.parameters yield {
180
+ if (paramInfo.isVarargs) {
181
+ val byNameGetters = byNameArgs.getOrElse(paramInfo.name, Seq ())
182
+ val positionalGetters = positionalArgs.removeAll()
183
+ // First take arguments passed by name, then those passed by position
184
+ byNameGetters ++ positionalGetters
185
+ } else {
186
+ byNameArgs.get(paramInfo.name) match
187
+ case Some (Nil ) =>
188
+ throw AssertionError (s " ${paramInfo.name} present in byNameArgs, but it has no argument value " )
189
+ case Some (argValues) =>
190
+ if argValues.length > 1 then
191
+ // Do not accept multiple values
192
+ // Remove this test to take last given argument
193
+ error(s " more than one value for ${paramInfo.name}: ${argValues.mkString(" , " )}" )
194
+ Nil
195
+ else
196
+ List (argValues.last)
197
+ case None =>
198
+ if positionalArgs.length > 0 then
199
+ List (positionalArgs.dequeue())
200
+ else if paramInfo.hasDefault then
201
+ List (" " )
202
+ else
203
+ error(s " missing argument for ${paramInfo.name}" )
204
+ Nil
205
+ }
206
+ }
207
+
208
+ // Check aliases unicity
209
+ val nameAndCanonicalName = info.parameters.flatMap {
210
+ case paramInfo => (paramInfo.name +: getAlternativeNames(paramInfo) ++: getShortNames(paramInfo)).map(_ -> paramInfo.name)
211
+ }
212
+ val nameToCanonicalNames = nameAndCanonicalName.groupMap(_._1)(_._2)
213
+
214
+ for (name, canonicalNames) <- nameToCanonicalNames if canonicalNames.length > 1 do
215
+ throw IllegalArgumentException (s " $name is used for multiple parameters: ${canonicalNames.mkString(" , " )}" )
216
+
217
+ // Check aliases validity
218
+ val problematicNames = info.parameters.flatMap(getInvalidNames)
219
+ if problematicNames.length > 0 then
220
+ throw IllegalArgumentException (s " The following aliases are invalid: ${problematicNames.mkString(" , " )}" )
221
+
222
+ // Handle unused and invalid args
223
+ for (remainingArg <- positionalArgs) error(s " unused argument: $remainingArg" )
224
+ for (invalidArg <- invalidByNameArgs) error(s " unknown argument name: $invalidArg" )
225
+
226
+ if errors.nonEmpty then
227
+ for msg <- errors do println(s " Error: $msg" )
228
+ usage()
229
+ None
230
+ else
231
+ Some (argStrings.flatten)
232
+ end if
231
233
end command
232
234
233
235
private def usage (): Unit =
0 commit comments