Reputation: 4681
I'm trying to use getopt with command line arguments in Swift 3. I have from Michele Dall'Agata's nice stackoverflow contribution:
let pattern = "abc:"
var buffer = Array( pattern.utf8 ).map { Int8($0) }
When I then use this code:
let option = Int( getopt( CommandLine.argc, CommandLine.arguments, buffer ) )
I get this error:
Cannot convert value of type '[String]' to expected argument type 'UnsafePointer<UnsafeMutablePointer<Int8>?>!'
for CommandLine.arguments, which I am trying to use as argv
. Does anyone know the proper syntax for the 2nd argument for getopt
? Thanks in advance!
Upvotes: 3
Views: 1791
Reputation: 539815
@Hamish already answered the question and explained how to pass CommandLine.unsafeArgv
to getopt()
in Swift (and why).
Here is a complete self-contained example how a typical getopt loop can be implemented in Swift 3:
var aFlag = false
var bFlag = false
var cValue: String?
while case let option = getopt(CommandLine.argc, CommandLine.unsafeArgv, "abc:"), option != -1 {
switch UnicodeScalar(CUnsignedChar(option)) {
case "a":
aFlag = true
case "b":
bFlag = true
case "c":
cValue = String(cString: optarg)
default:
fatalError("Unknown option")
}
}
print(aFlag, bFlag, cValue ?? "?")
Remarks:
"abc:"
) directly to a C
function expecting a (constant) C string, the compiler will automatically
generate a temporary UTF-8 representation.getopt()
return either -1
(if the argument list is exhausted) or an unsigned char
converted to an int
. Therefore it is safe to
convert the return value to CUnsignedChar
(which is UInt8
in Swift).while
is used (abused?) with pattern matching plus an additional
boolean condition to implement the typical C pattern
while ((option = getopt(argc, argv, "abc:")) != -1) { ... }
in Swift.
Upvotes: 8
Reputation: 80821
CommandLine.arguments
gives you a friendly Swift [String]
of the arguments passed – however you're looking to send the arguments straight back to C. Therefore you can simply use CommandLine.unsafeArgv
instead, which will give you the actual raw value of argv
passed to your program.
let option = Int( getopt( CommandLine.argc, CommandLine.unsafeArgv, buffer ) )
Upvotes: 6