Schrödinger's file: it's superposition between existent and nonexistent, file and directory. Tried java.nio.file but it seems it's just Java that is broken like vittupää

Former-commit-id: ec938b81d8c4a1385295846b7b3d5178652d93ad
Former-commit-id: 0ff4806c81c94ec5a126894f8d41ca6891bcb1d2
This commit is contained in:
Song Minjae
2016-10-04 02:05:52 +09:00
parent e5bc967ade
commit 862034b6c1
5 changed files with 65 additions and 52 deletions

View File

@@ -21,8 +21,8 @@ class StateVTTest : BasicGameState() {
// HiRes: 100x64, LoRes: 80x25
val computerInside = BaseTerrarumComputer(8)
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 80, 25,
computerInside, colour = false, hires = false)
val vt = SimpleTextTerminal(SimpleTextTerminal.AMETHYST_NOVELTY, 100, 64,
computerInside, colour = true, hires = true)
val vtUI = Image(vt.displayW, vt.displayH)

View File

@@ -91,12 +91,12 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
computerValue["processor"] = -1 // do.
// as in "dev/hda"; refers hard disk drive (and no partitioning)
computerValue["hda"] = "testhda" // 'UUID rendered as String' or "none"
computerValue["hdb"] = "none"
computerValue["hda"] = "uuid_testhda" // 'UUID rendered as String' or "none"
computerValue["hdb"] = "uuid_testhdb"
computerValue["hdc"] = "none"
computerValue["hdd"] = "none"
// as in "dev/fd1"; refers floppy disk drive
computerValue["fd1"] = "none"
computerValue["fd1"] = "uuid_testfd1"
computerValue["fd2"] = "none"
computerValue["fd3"] = "none"
computerValue["fd4"] = "none"
@@ -159,7 +159,7 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
// secure the sandbox
luaJ_globals["io"] = LuaValue.NIL
//luaJ_globals["io"] = LuaValue.NIL
// dubug should be sandboxed in BOOT.lua (use OpenComputers code)
//val sethook = luaJ_globals["debug"]["sethook"]
//luaJ_globals["debug"] = LuaValue.NIL
@@ -207,12 +207,13 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
unsetThreadRun()
}
driveBeepQueueManager(delta)
}
if (isHalted) {
if (!isHalted) {
driveBeepQueueManager(delta)
}
else {
currentExecutionThread.interrupt()
}
}
@@ -326,7 +327,6 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
// complete emitTone queue
if (beepCursor >= beepQueue.size) {
clearBeepQueue()
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
}
// actually play queue
@@ -350,6 +350,8 @@ class BaseTerrarumComputer(peripheralSlots: Int) {
beepQueueLineExecTimer = 0
//AL.destroy()
if (DEBUG) println("[BaseTerrarumComputer] !! Beep queue clear")
}
fun enqueueBeep(duration: Int, freq: Double) {

View File

@@ -10,6 +10,7 @@ import net.torvald.terrarum.virtualcomputer.luaapi.Term.Companion.checkIBM437
import java.io.*
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.*
/**
@@ -20,7 +21,9 @@ import java.util.*
* Created by minjaesong on 16-09-17.
*
*
* NOTE: Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible!
* NOTES:
* Don't convert '\' to '/'! Rev-slash is used for escape character in sh, and we're sh-compatible!
* Use .absoluteFile whenever possible; there's fuckin oddity! (http://bugs.java.com/bugdatabase/view_bug.do;:YfiG?bug_id=4483097)
*/
internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
@@ -40,7 +43,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
globals["fs"]["concat"] = ConcatPath(computer) // OC compliant
globals["fs"]["open"] = OpenFile(computer) //CC compliant
globals["fs"]["parent"] = GetParentDir(computer)
// fs.dofile defined in ROMLIB
// fs.dofile defined in BOOT
// fs.fetchText defined in ROMLIB
}
@@ -48,29 +51,34 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
fun ensurePathSanity(path: LuaValue) {
if (path.checkIBM437().contains(Regex("""\.\.""")))
throw LuaError("'..' on path is not supported.")
if (!isValidFilename(path.checkIBM437()))
throw IOException("path contains invalid characters")
}
val isCaseInsensitive: Boolean
get() {
// TODO add: force case insensitive in config
try {
val uuid = UUID.randomUUID().toString()
val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox")
val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX")
// This should NEVER happen but could also lead to VERY weird bugs, so we
// make sure the files don't exist.
lowerCase.exists() && lowerCase.delete()
upperCase.exists() && upperCase.delete()
lowerCase.createNewFile()
val insensitive = upperCase.exists()
lowerCase.delete()
return insensitive
}
catch (e: IOException) {
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
return true
}
init {
try {
val uuid = UUID.randomUUID().toString()
val lowerCase = File(Terrarum.currentSaveDir, uuid + "oc_rox")
val upperCase = File(Terrarum.currentSaveDir, uuid + "OC_ROX")
// This should NEVER happen but could also lead to VERY weird bugs, so we
// make sure the files don't exist.
if (lowerCase.exists()) lowerCase.delete()
if (upperCase.exists()) upperCase.delete()
lowerCase.createNewFile()
val insensitive = upperCase.exists()
lowerCase.delete()
isCaseInsensitive = insensitive
}
catch (e: IOException) {
println("[Filesystem] Couldn't determine if file system is case sensitive, falling back to insensitive.")
isCaseInsensitive = true
}
}
// Worst-case: we're on Windows or using a FAT32 partition mounted in *nix.
// Note: we allow / as the path separator and expect all \s to be converted
@@ -79,11 +87,11 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
fun isValidFilename(name: String) = !name.contains(invalidChars)
fun validatePath(path: String) : String {
if (!isValidFilename(path)) {
fun String.validatePath() : String {
if (!isValidFilename(this)) {
throw IOException("path contains invalid characters")
}
return path
return this
}
/** actual directory: <appdata>/Saves/<savename>/computers/<drivename>/
@@ -103,7 +111,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
*/
// remove first '/' in path
var path = luapath.checkIBM437()
var path = luapath.checkIBM437().validatePath()
if (path.startsWith('/')) path = path.substring(1)
if (path.startsWith("media/")) {
@@ -131,7 +139,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
Filesystem.ensurePathSanity(path)
val table = LuaTable()
val file = File(computer.getRealPath(path))
val file = File(computer.getRealPath(path)).absoluteFile
file.list().forEachIndexed { i, s -> table.insert(i, LuaValue.valueOf(s)) }
return table
}
@@ -141,7 +149,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(File(computer.getRealPath(path)).exists())
return LuaValue.valueOf(Files.exists(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
}
}
@@ -149,7 +157,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(File(computer.getRealPath(path)).isDirectory)
return LuaValue.valueOf(Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
}
}
@@ -157,7 +165,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(File(computer.getRealPath(path)).isFile)
return LuaValue.valueOf(!Files.isDirectory(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
}
}
@@ -165,7 +173,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(!File(computer.getRealPath(path)).canWrite())
return LuaValue.valueOf(!Files.isWritable(Paths.get(computer.getRealPath(path)).toAbsolutePath()))
}
}
@@ -174,7 +182,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(File(computer.getRealPath(path)).length().toInt())
return LuaValue.valueOf(Files.size(Paths.get(computer.getRealPath(path)).toAbsolutePath()).toInt())
}
}
@@ -187,7 +195,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
override fun call(path: LuaValue) : LuaValue {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(File(computer.getRealPath(path)).mkdir())
return LuaValue.valueOf(File(computer.getRealPath(path)).absoluteFile.mkdir())
}
}
@@ -199,11 +207,12 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
Filesystem.ensurePathSanity(from)
Filesystem.ensurePathSanity(to)
val fromFile = File(computer.getRealPath(from))
val fromFile = File(computer.getRealPath(from)).absoluteFile
var success = fromFile.copyRecursively(
File(computer.getRealPath(to)), overwrite = true
) // ignore IntelliJ's observation; it's opposite from redundant
success = fromFile.deleteRecursively()
File(computer.getRealPath(to)).absoluteFile, overwrite = true
)
if (success) success = fromFile.deleteRecursively()
else return LuaValue.valueOf(false)
return LuaValue.valueOf(success)
}
}
@@ -218,8 +227,8 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
Filesystem.ensurePathSanity(to)
return LuaValue.valueOf(
File(computer.getRealPath(from)).copyRecursively(
File(computer.getRealPath(to)), overwrite = true
File(computer.getRealPath(from)).absoluteFile.copyRecursively(
File(computer.getRealPath(to)).absoluteFile, overwrite = true
)
)
}
@@ -233,7 +242,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
Filesystem.ensurePathSanity(path)
return LuaValue.valueOf(
File(computer.getRealPath(path)).deleteRecursively()
File(computer.getRealPath(path)).absoluteFile.deleteRecursively()
)
}
}
@@ -243,7 +252,7 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
Filesystem.ensurePathSanity(base)
Filesystem.ensurePathSanity(local)
val combinedPath = combinePath(base.checkIBM437(), local.checkIBM437())
val combinedPath = combinePath(base.checkIBM437().validatePath(), local.checkIBM437().validatePath())
return LuaValue.valueOf(combinedPath)
}
}
@@ -282,9 +291,9 @@ internal class Filesystem(globals: Globals, computer: BaseTerrarumComputer) {
val mode = mode.checkIBM437().toLowerCase()
val luaClass = LuaTable()
val file = File(computer.getRealPath(path))
val file = File(computer.getRealPath(path)).absoluteFile
if (mode.contains("[aw]") && !file.canWrite())
if (mode.contains(Regex("""[aw]""")) && !file.canWrite())
throw LuaError("Cannot open file for " +
"${if (mode.startsWith('w')) "read" else "append"} mode" +
": is readonly.")

View File

@@ -15,6 +15,7 @@ class Input(globals: Globals, computer: BaseTerrarumComputer) {
init {
globals["input"] = LuaTable()
globals["input"]["isKeyDown"] = IsKeyDown(computer)
// input.readLine defined in ROMLIB
}
companion object {

View File

@@ -118,6 +118,7 @@ internal class Term(globals: Globals, term: Teletype) {
}
}
// emitchar
class Emit(val term: Terminal) : ThreeArgFunction() {
override fun call(p0: LuaValue, x: LuaValue, y: LuaValue): LuaValue {
term.emitChar(p0.checkint().toChar(), x.checkint() - 1, y.checkint() - 1)