Skip to content

Instantly share code, notes, and snippets.

@uliwitness
Last active December 10, 2019 19:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uliwitness/f44d4b473ef5e9a601d4b04960aa2386 to your computer and use it in GitHub Desktop.
Save uliwitness/f44d4b473ef5e9a601d4b04960aa2386 to your computer and use it in GitHub Desktop.
Command line argument parsing function
import Foundation
extension Array where Array.Element == String {
func parseKeyValue(prefix: String = "--", suffix: String = "", valueSeparator: String = "=", removePrefix: Bool = true, removeSuffix: Bool = true, separateArguments: Bool = true, endIndicator: String = "--") -> Dictionary<String, String> {
var unlabeled = [String]()
return parseKeyValue(prefix: prefix, suffix: suffix, valueSeparator: valueSeparator, removePrefix: removePrefix, removeSuffix: removeSuffix, separateArguments: separateArguments, endIndicator: endIndicator, unlabeled: &unlabeled)
}
func parseKeyValue(prefix: String = "--", suffix: String = "", valueSeparator: String = "=", removePrefix: Bool = true, removeSuffix: Bool = true, separateArguments: Bool = true, endIndicator: String = "--", unlabeled: inout [String]) -> Dictionary<String, String> {
var result = Dictionary<String, String>()
var i = startIndex
while i < count {
var arg = self[i]
if !endIndicator.isEmpty && arg == endIndicator {
i += 1
unlabeled.append(contentsOf: self[i ..< count])
break
}
i += 1
let key: String
let value: String?
var isArg = true
if !prefix.isEmpty && !arg.hasPrefix(prefix) {
isArg = false
}
if !suffix.isEmpty && !arg.hasSuffix(suffix) {
isArg = false
}
if isArg {
if removePrefix {
arg.removeFirst(prefix.count)
}
if removeSuffix {
arg.removeLast(suffix.count)
}
}
if !isArg {
unlabeled.append(arg)
} else if !valueSeparator.isEmpty {
let parts = arg.split(separator: valueSeparator.first!, maxSplits: 1, omittingEmptySubsequences: false)
if parts.count > 1 {
key = String(parts[0])
value = String(parts[1])
} else {
key = arg
let possibleParam = (i < count) ? self[i] : ""
if separateArguments && (i < count) && (prefix.isEmpty || !possibleParam.hasPrefix(prefix)) {
value = possibleParam
i += 1
} else {
value = ""
}
}
result[key] = value
} else {
key = arg
let possibleParam = (i < count) ? self[i] : ""
if separateArguments && (i < count) && (prefix.isEmpty || !possibleParam.hasPrefix(prefix)) {
value = possibleParam
i += 1
} else {
value = ""
}
result[key] = value
}
}
return result
}
}
print(CommandLine.arguments.parseKeyValue())
print("\(["--flag", "--key", "value", "--key2=value", "--flag2", "george"].parseKeyValue()) - [\"flag\": \"\", \"key\": \"value\", \"key2\": \"value\", \"flag2\": \"george\"]")
print("\(["--flag", "--key", "value", "--key2=value", "--flag2", "--george"].parseKeyValue()) - [\"flag\": \"\", \"key\": \"value\", \"key2\": \"value\", \"flag2\": \"\", \"george\": \"\"]")
var unlabeled = [String]()
print("\(["file.txt", "--flag", "--foo=bar=baz", "heyooo!", "--", "--notParam"].parseKeyValue(unlabeled: &unlabeled)) • \(unlabeled) - [\"flag\": \"\", \"foo\": \"bar=baz\"] • [\"file.txt\", \"heyooo!\", \"--notParam\"]")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment