From 11534f39f357a2f422fe55ce4a6e022620d0ba1f Mon Sep 17 00:00:00 2001 From: Curtis Rueden Date: Tue, 7 May 2024 12:05:00 -0500 Subject: [PATCH] WIP: split out mkdir function --- build.gradle.kts | 14 ++++++++++---- src/commonMain/kotlin/file.kt | 9 ++++++++- src/commonMain/kotlin/platform.kt | 2 ++ src/linuxMain/kotlin/platform.kt | 13 +++++++++++++ src/macosMain/kotlin/platform.kt | 14 ++++++++++++++ src/posixMain/kotlin/file.kt | 21 --------------------- src/windowsMain/kotlin/file.kt | 20 -------------------- src/windowsMain/kotlin/platform.kt | 17 +++++++++++++++++ 8 files changed, 64 insertions(+), 46 deletions(-) create mode 100644 src/linuxMain/kotlin/platform.kt create mode 100644 src/macosMain/kotlin/platform.kt diff --git a/build.gradle.kts b/build.gradle.kts index c904937..b2843a8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,17 +39,23 @@ kotlin { val posixMain by creating { dependsOn(commonMain.get()) } + val macosMain by creating { + dependsOn(posixMain) + } + val linuxMain by creating { + dependsOn(posixMain) + } val macosArm64Main by getting { - dependsOn(posixMain) + dependsOn(macosMain) } val macosX64Main by getting { - dependsOn(posixMain) + dependsOn(macosMain) } val linuxArm64Main by getting { - dependsOn(posixMain) + dependsOn(linuxMain) } val linuxX64Main by getting { - dependsOn(posixMain) + dependsOn(linuxMain) } // HACK: Prevent "Variable is never used" warnings. // Unfortunately, @Suppress("UNUSED_PARAMETER") does not do the trick. diff --git a/src/commonMain/kotlin/file.kt b/src/commonMain/kotlin/file.kt index 18699ea..20132b0 100644 --- a/src/commonMain/kotlin/file.kt +++ b/src/commonMain/kotlin/file.kt @@ -16,7 +16,6 @@ expect class File(rawPath: String) { val length : Long fun ls(): List fun lines(): List - fun mkdir(): Boolean fun mv(dest:File): Boolean fun rm() : Boolean fun rmdir() : Boolean @@ -49,6 +48,14 @@ val File.base: File return if (dot < lastSlash(path)) this else File(path.substring(0, dot)) } +fun File.mkdir(): Boolean { + if (exists && !isDirectory) { + warn("Error: '$path' already exists but is not a directory.") + return false + } + return mkdir(path) +} + operator fun File.div(p: String): File = File("$path$SLASH$p") // -- File-related utility functions -- diff --git a/src/commonMain/kotlin/platform.kt b/src/commonMain/kotlin/platform.kt index be405bb..86e22eb 100644 --- a/src/commonMain/kotlin/platform.kt +++ b/src/commonMain/kotlin/platform.kt @@ -16,6 +16,8 @@ expect fun printlnErr(s: String = "") expect fun stdinLines(): Array +expect fun mkdir(path: String): Boolean + data class MemoryInfo(var total: Long? = null, var free: Long? = null) expect fun memInfo(): MemoryInfo diff --git a/src/linuxMain/kotlin/platform.kt b/src/linuxMain/kotlin/platform.kt new file mode 100644 index 0000000..1b79342 --- /dev/null +++ b/src/linuxMain/kotlin/platform.kt @@ -0,0 +1,13 @@ +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.toKString +import platform.posix.* + +@OptIn(ExperimentalForeignApi::class) +actual fun mkdir(path: String): Boolean { + val result = mkdir(path, S_IRWXU.toUInt()) + if (result != 0) { + val errorCode = errno + platform.posix.warn("Error creating directory '$path': ${strerror(errorCode)?.toKString()}") + } + return result == 0 +} diff --git a/src/macosMain/kotlin/platform.kt b/src/macosMain/kotlin/platform.kt new file mode 100644 index 0000000..d8ee5d6 --- /dev/null +++ b/src/macosMain/kotlin/platform.kt @@ -0,0 +1,14 @@ +import kotlinx.cinterop.ExperimentalForeignApi +import kotlinx.cinterop.toKString + +actual val BUILD_TARGET = "linuxX64" + +@OptIn(ExperimentalForeignApi::class) +actual fun mkdir(path: String): Boolean { + val result = mkdir(path, S_IRWXU.toUShort()) + if (result != 0) { + val errorCode = errno + platform.posix.warn("Error creating directory '$path': ${strerror(errorCode)?.toKString()}") + } + return result == 0 +} diff --git a/src/posixMain/kotlin/file.kt b/src/posixMain/kotlin/file.kt index 671c91f..4bf1ff8 100644 --- a/src/posixMain/kotlin/file.kt +++ b/src/posixMain/kotlin/file.kt @@ -75,27 +75,6 @@ actual class File actual constructor(private val rawPath: String) { return path } - @OptIn(ExperimentalForeignApi::class) - actual fun mkdir(): Boolean { - if (exists && ! isDirectory) { - println("Error: '$path' already exists but is not a directory.") - return false - } - memScoped { - // Default permissions for new directories (read/write for owner) - val mode = S_IRWXU.toUInt() // User can read, write, execute - - // Create the directory, returning false if it fails - if (mkdir(path, mode) != 0) { - val errorCode = errno - println("Error creating directory '$path': ${strerror(errorCode)?.toKString()}") - return false - } - - return true // Successful directory creation - } - } - @OptIn(ExperimentalForeignApi::class) actual fun mv(dest: File): Boolean { memScoped { diff --git a/src/windowsMain/kotlin/file.kt b/src/windowsMain/kotlin/file.kt index 3675d77..9a99c20 100644 --- a/src/windowsMain/kotlin/file.kt +++ b/src/windowsMain/kotlin/file.kt @@ -86,26 +86,6 @@ actual class File actual constructor(private val rawPath: String) { return path } - @OptIn(ExperimentalForeignApi::class) - actual fun mkdir(): Boolean { - memScoped { - // Create the directory, returning false if it fails - val result = CreateDirectoryW(path, null) - - if (result == 0) { - val errorCode = GetLastError() - if (errorCode == ERROR_ALREADY_EXISTS.toUInt()) { - return true // The directory already exists - } else { - println("Error creating directory '$path': $errorCode") - return false - } - } - - return true - } - } - @OptIn(ExperimentalForeignApi::class) actual fun mv(dest: File): Boolean { memScoped { diff --git a/src/windowsMain/kotlin/platform.kt b/src/windowsMain/kotlin/platform.kt index 42ef696..ba034e1 100644 --- a/src/windowsMain/kotlin/platform.kt +++ b/src/windowsMain/kotlin/platform.kt @@ -63,6 +63,23 @@ actual fun stdinLines(): Array { return lines } +@OptIn(ExperimentalForeignApi::class) +actual fun mkdir(path: String): Boolean { + memScoped { + val result = CreateDirectoryW(path, null) + if (result == 0) { + val errorCode = GetLastError() + if (errorCode == ERROR_ALREADY_EXISTS.toUInt()) { + return true + } else { + warn("Error creating directory '$path': $errorCode") + return false + } + } + return true + } +} + @OptIn(ExperimentalForeignApi::class) actual fun memInfo(): MemoryInfo { val memInfo = MemoryInfo()