Rewrite interop tools command line options to have help messages without crashes (#2672)
This commit is contained in:
@@ -60,7 +60,8 @@ abstract class Descriptor(val type: ArgType,
|
||||
val longName: String,
|
||||
val description: String? = null,
|
||||
val defaultValue: String? = null,
|
||||
val isRequired: Boolean = false) {
|
||||
val isRequired: Boolean = false,
|
||||
val deprecatedWarning: String? = null) {
|
||||
abstract val textDescription: String
|
||||
abstract val helpMessage: String
|
||||
}
|
||||
@@ -72,7 +73,9 @@ class OptionDescriptor(
|
||||
description: String? = null,
|
||||
defaultValue: String? = null,
|
||||
isRequired: Boolean = false,
|
||||
val isMultiple: Boolean = false) : Descriptor (type, longName, description, defaultValue, isRequired) {
|
||||
val isMultiple: Boolean = false,
|
||||
val delimiter: String? = null,
|
||||
deprecatedWarning: String? = null) : Descriptor (type, longName, description, defaultValue, isRequired, deprecatedWarning) {
|
||||
override val textDescription: String
|
||||
get() = "option -$longName"
|
||||
|
||||
@@ -83,8 +86,9 @@ class OptionDescriptor(
|
||||
shortName?.let { result.append(", -$it") }
|
||||
defaultValue?.let { result.append(" [$it]") }
|
||||
description?.let {result.append(" -> ${it}")}
|
||||
if (!isRequired) result.append(" (optional)")
|
||||
if (isRequired) result.append(" (always required)")
|
||||
result.append(" ${type.description}")
|
||||
deprecatedWarning?.let { result.append(" Warning: $it") }
|
||||
result.append("\n")
|
||||
return result.toString()
|
||||
}
|
||||
@@ -95,7 +99,8 @@ class ArgDescriptor(
|
||||
longName: String,
|
||||
description: String? = null,
|
||||
defaultValue: String? = null,
|
||||
isRequired: Boolean = true) : Descriptor (type, longName, description, defaultValue, isRequired) {
|
||||
isRequired: Boolean = true,
|
||||
deprecatedWarning: String? = null) : Descriptor (type, longName, description, defaultValue, isRequired, deprecatedWarning) {
|
||||
override val textDescription: String
|
||||
get() = "argument $longName"
|
||||
|
||||
@@ -107,16 +112,20 @@ class ArgDescriptor(
|
||||
description?.let {result.append(" -> ${it}")}
|
||||
if (!isRequired) result.append(" (optional)")
|
||||
result.append(" ${type.description}")
|
||||
deprecatedWarning?.let { result.append(" Warning: $it") }
|
||||
result.append("\n")
|
||||
return result.toString()
|
||||
}
|
||||
}
|
||||
|
||||
// Arguments parser.
|
||||
class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescriptor> = listOf<ArgDescriptor>()) {
|
||||
private val options = optionsList.union(listOf(OptionDescriptor(ArgType.Boolean(), "help",
|
||||
"h", "Usage info")))
|
||||
.toList()
|
||||
class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescriptor> = listOf<ArgDescriptor>(),
|
||||
useDefaultHelpShortName: Boolean = true) {
|
||||
private val options = optionsList.union(if (useDefaultHelpShortName)
|
||||
listOf(OptionDescriptor(ArgType.Boolean(), "help", "h", "Usage info"))
|
||||
else
|
||||
listOf(OptionDescriptor(ArgType.Boolean(), "help", description = "Usage info"))
|
||||
).toList()
|
||||
private val arguments = argsList
|
||||
private lateinit var parsedValues: MutableMap<String, ParsedArg?>
|
||||
|
||||
@@ -153,7 +162,7 @@ class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescripto
|
||||
}
|
||||
|
||||
// Output error. Also adds help usage information for easy understanding of problem.
|
||||
private fun printError(message: String): Nothing {
|
||||
fun printError(message: String): Nothing {
|
||||
error("$message\n${makeUsage()}")
|
||||
}
|
||||
|
||||
@@ -163,6 +172,7 @@ class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescripto
|
||||
val name = nullArgs.firstOrNull()
|
||||
name?. let {
|
||||
argDescriptors.getValue(name).type.check(arg, name)
|
||||
argDescriptors.getValue(name).deprecatedWarning?.let { println ("Warning: $it") }
|
||||
processedValues.getValue(name).add(arg)
|
||||
return true
|
||||
}
|
||||
@@ -173,8 +183,14 @@ class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescripto
|
||||
if (!descriptor.isMultiple && !processedValues.getValue(descriptor.longName).isEmpty()) {
|
||||
printError("Option ${descriptor.longName} is used more than one time!")
|
||||
}
|
||||
descriptor.type.check(value, descriptor.longName)
|
||||
processedValues.getValue(descriptor.longName).add(value)
|
||||
descriptor.deprecatedWarning?.let { if (processedValues.getValue(descriptor.longName).isEmpty()) println ("Warning: $it") }
|
||||
val savedValues = descriptor.delimiter?.let { value.split(it) } ?: listOf(value)
|
||||
|
||||
savedValues.forEach {
|
||||
descriptor.type.check(it, descriptor.longName)
|
||||
processedValues.getValue(descriptor.longName).add(it)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Parse arguments.
|
||||
@@ -218,7 +234,7 @@ class ArgParser(optionsList: List<OptionDescriptor>, argsList: List<ArgDescripto
|
||||
} else {
|
||||
// Argument is found.
|
||||
if (!saveAsArg(argDescriptors, arg, processedValues)) {
|
||||
printError("Too many arguments!")
|
||||
printError("Too many arguments! Couldn't proccess argument $arg!")
|
||||
}
|
||||
}
|
||||
index++
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ open class CInteropTask @Inject constructor(val settings: CInteropSettingsImpl):
|
||||
addArgIfNotNull("-def", defFile.canonicalPath)
|
||||
addArgIfNotNull("-pkg", packageName)
|
||||
|
||||
addFileArgs("-h", headers)
|
||||
addFileArgs("-header", headers)
|
||||
|
||||
compilerOpts.forEach {
|
||||
addArg("-copt", it)
|
||||
|
||||
+1
-1
@@ -80,7 +80,7 @@ open class KonanInteropTask @Inject constructor(val workerExecutor: WorkerExecut
|
||||
addArgIfNotNull("-def", defFile.canonicalPath)
|
||||
addArgIfNotNull("-pkg", packageName)
|
||||
|
||||
addFileArgs("-h", headers)
|
||||
addFileArgs("-header", headers)
|
||||
|
||||
compilerOpts.forEach {
|
||||
addArg("-copt", it)
|
||||
|
||||
Reference in New Issue
Block a user