Zusätzliche Kommandozeilen-Parameter via Pipe

This commit is contained in:
Hartmut Bauer committed 2026-01-19 00:31:17 +01:00
1 parent 9df3e0701d
commit b580e64e76
16 files changed
+127 -39

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="util-js-0.3.0-beta.4">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="util-js-0.3.0-beta.4.jar">
<element id="module-output" name="util.jsMain" />
</root>
</artifact>
</component>
+8
View File
@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="util-jvm-0.3.0-beta.4">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="util-jvm-0.3.0-beta.4.jar">
<element id="module-output" name="util.jvmMain" />
</root>
</artifact>
</component>
+8
View File
@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="util-wasm-js-0.3.0-beta.4">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="util-wasm-js-0.3.0-beta.4.jar">
<element id="module-output" name="util.wasmJsMain" />
</root>
</artifact>
</component>
+8
View File
@@ -0,0 +1,8 @@
<component name="ArtifactManager">
<artifact type="jar" name="util-wasm-wasi-0.3.0-beta.4">
<output-path>$PROJECT_DIR$/build/libs</output-path>
<root id="archive" name="util-wasm-wasi-0.3.0-beta.4.jar">
<element id="module-output" name="util.wasmWasiMain" />
</root>
</artifact>
</component>
+2 -2
View File
@@ -1,3 +1,3 @@
#auto generated #auto generated
#Sun Jan 18 17:59:47 CET 2026 #Sun Jan 18 23:38:13 CET 2026
build.number=111 build.number=114
+1 -1
View File
@@ -19,7 +19,7 @@ dependencyResolutionManagement {
versionCatalogs { versionCatalogs {
create("masterLibs") { create("masterLibs") {
// from(files("gradle/masterlibs.versions.toml")) // from(files("gradle/masterlibs.versions.toml"))
from("net.keinekekse:version-catalog:110") from("net.keinekekse:version-catalog:113")
} }
} }
} }
@@ -2,8 +2,28 @@ package net.keinekekse.args
import net.keinekekse.version.Version import net.keinekekse.version.Version
/**
* Terminates the currently running application with the specified exit code.
* This function does not return as it stops the application process.
*
* Works only for JVM and macOS-/Linux-native targets.
*
* @param rc The exit code to return when the application terminates. Defaults to 0,
* indicating normal termination.
* @return This function does not return as the application is terminated.
*/
expect fun exitApplication(rc: Int = 0): Nothing expect fun exitApplication(rc: Int = 0): Nothing
/**
* Checks if standard input is ready for reading.
* This function is used to determine if there is data available to be read from standard input.
*
* Works only for JVM and macOS-/Linux-native targets.
*
* @return True if standard input is ready for reading, false otherwise.
*/
expect fun isStdInputReady(): Boolean
class VerifyParameterException(message: String) : RuntimeException(message) class VerifyParameterException(message: String) : RuntimeException(message)
fun showParsingError(msg: String): Nothing { fun showParsingError(msg: String): Nothing {
@@ -196,7 +216,12 @@ class CommandLine(
val resultSubCommand = parseSubCommand(remaining) val resultSubCommand = parseSubCommand(remaining)
validateMandatoryParameters(resultSubCommand) validateMandatoryParameters(resultSubCommand)
if (resultSubCommand.additionalParameters.isNotEmpty() && remainingDescription == null) { if (remainingDescription != null) {
val additionalFromPipe = getRemainingParametersFromPipe()
if (additionalFromPipe.isNotEmpty()) {
resultSubCommand.additionalParameters += additionalFromPipe
}
} else if (resultSubCommand.additionalParameters.isNotEmpty()) {
throw ArgumentParserException.noMoreOptions() throw ArgumentParserException.noMoreOptions()
} }
@@ -261,6 +286,19 @@ class CommandLine(
} }
} }
private fun getRemainingParametersFromPipe(): List<String> {
if (isStdInputReady()) {
var input: String?
val pipe = mutableListOf<String>()
do {
input = readlnOrNull()
input?.let { pipe.add(it) }
} while (!input.isNullOrEmpty())
return pipe
}
return emptyList()
}
private fun checkExecutors() { private fun checkExecutors() {
globalSubCommand.obj.checkExecutors() globalSubCommand.obj.checkExecutors()
subCommands.values.forEach { it.checkExecutors() } subCommands.values.forEach { it.checkExecutors() }
@@ -282,7 +320,7 @@ class CommandLine(
val globalParam = globalSubCommand.obj.params.isNotEmpty() val globalParam = globalSubCommand.obj.params.isNotEmpty()
val remain = remainingDescription != null val remain = remainingDescription != null
println("${programVersion.displayName} ${programVersion.version}, ${programVersion.copyright}\n") println("${programVersion.displayName} ${programVersion.version} ${programVersion.copyright}\n")
println(programVersion.description) println(programVersion.description)
println() println()
println( println(
@@ -346,7 +384,7 @@ class CommandLine(
} }
private fun showVersion(): Nothing { private fun showVersion(): Nothing {
println("${programVersion.displayName} ${programVersion.fullVersion}, ${programVersion.copyright}\n") println("${programVersion.displayName} ${programVersion.fullVersion} ${programVersion.copyright}\n")
exitApplication(0) exitApplication(0)
} }
@@ -3,14 +3,14 @@ package net.keinekekse.util
import net.keinekekse.version.Version import net.keinekekse.version.Version
object VERSION: Version { object VERSION: Version {
override val version = "0.3.0-beta.2+build.111" override val version = "0.3.0-beta.5+build.114"
override val fullVersion = "0.3.0-beta.2+build.111" override val fullVersion = "0.3.0-beta.5+build.114"
override val major = 0 override val major = 0
override val minor = 3 override val minor = 3
override val patch = 0 override val patch = 0
override val preRelease = "beta.2" override val preRelease = "beta.5"
override val buildMetadata = "build.111" override val buildMetadata = "build.114"
override val buildDate = "2026-01-18T16:59:47.995114Z" override val buildDate = "2026-01-18T22:38:13.309402Z"
override val displayName = "Utility Library" override val displayName = "Utility Library"
override val copyright = "Copyright (c) 2025-2026 Hartmut Bauer" override val copyright = "Copyright (c) 2025-2026 Hartmut Bauer"
override val name = "util" override val name = "util"
@@ -0,0 +1,9 @@
package net.keinekekse.args
import kotlin.system.exitProcess
actual fun isStdInputReady(): Boolean =
(System.`in`.available() > 0)
actual fun exitApplication(rc: Int): Nothing =
exitProcess(rc)
@@ -1,7 +0,0 @@
package net.keinekekse.args
import kotlin.system.exitProcess
actual fun exitApplication(rc: Int): Nothing {
exitProcess(rc)
}
@@ -1,8 +0,0 @@
package net.keinekekse.args
import platform.posix.exit
actual fun exitApplication(rc: Int): Nothing {
exit(rc)
return Unit as Nothing
}
@@ -1,8 +0,0 @@
package net.keinekekse.args
import platform.posix.exit
actual fun exitApplication(rc: Int): Nothing {
exit(rc)
return Unit as Nothing
}
@@ -0,0 +1,22 @@
package net.keinekekse.args
import kotlinx.cinterop.*
import platform.posix.*
// macOS + Linux
@OptIn(ExperimentalForeignApi::class, UnsafeNumber::class)
actual fun isStdInputReady(): Boolean {
return memScoped {
val pfd = alloc<pollfd>()
pfd.fd = STDIN_FILENO
pfd.events = POLLIN.toShort()
// timeout 0 means return immediately
poll(pfd.ptr.reinterpret(), 1u, 10) > 0
}
}
actual fun exitApplication(rc: Int): Nothing {
exit(rc)
return Unit as Nothing
}
@@ -1,5 +1,9 @@
package net.keinekekse.args package net.keinekekse.args
actual fun isStdInputReady(): Boolean {
TODO("Not implemented on this platform")
}
actual fun exitApplication(rc: Int): Nothing { actual fun exitApplication(rc: Int): Nothing {
TODO("Not implemented on this platform") TODO("Not implemented on this platform")
} }
@@ -0,0 +1,11 @@
package net.keinekekse.args
// js + wasmJs
actual fun isStdInputReady(): Boolean {
TODO("Not implemented for this platform")
}
actual fun exitApplication(rc: Int): Nothing {
TODO("Not implemented for this platform")
}
@@ -1,5 +0,0 @@
package net.keinekekse.args
actual fun exitApplication(rc: Int): Nothing {
TODO("Not yet implemented") // js + wasmJs
}