fix path normalization problems,

allow ~ in srcdirs compiler flag
This commit is contained in:
Irmen de Jong 2024-12-26 17:42:20 +01:00
parent 4555edf369
commit 4daa909f32
11 changed files with 39 additions and 20 deletions

View File

@ -4,17 +4,30 @@ import prog8.code.core.Position
import java.nio.file.Path import java.nio.file.Path
import java.util.TreeMap import java.util.TreeMap
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.absolute
// Resource caching "filesystem". // Resource caching "filesystem".
// Note that it leaves the decision to load a resource or an actual disk file to the caller. // Note that it leaves the decision to load a resource or an actual disk file to the caller.
object ImportFileSystem { object ImportFileSystem {
fun expandTilde(path: String): String = if (path.startsWith("~")) {
val userHome = System.getProperty("user.home")
userHome + path.drop(1)
} else {
path
}
fun expandTilde(path: Path): Path = Path(expandTilde(path.toString()))
fun getFile(path: Path): SourceCode { fun getFile(path: Path): SourceCode {
val cached = cache[path.toString()] val normalized = path.absolute().normalize()
if (cached != null) return cached val cached = cache[normalized.toString()]
val file = SourceCode.File(path) if (cached != null)
cache[path.toString()] = file return cached
val file = SourceCode.File(normalized)
cache[normalized.toString()] = file
return file return file
} }
@ -35,7 +48,7 @@ object ImportFileSystem {
val cached = cache[position.file] val cached = cache[position.file]
if(cached != null) if(cached != null)
return getLine(cached, position.line) return getLine(cached, position.line)
val path = Path(position.file).toAbsolutePath().normalize() val path = Path(position.file).absolute().normalize()
val cached2 = cache[path.toString()] val cached2 = cache[path.toString()]
if(cached2 != null) if(cached2 != null)
return getLine(cached2, position.line) return getLine(cached2, position.line)

View File

@ -4,6 +4,7 @@ import java.io.IOException
import java.nio.file.Path import java.nio.file.Path
import java.text.Normalizer import java.text.Normalizer
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.absolute
import kotlin.io.path.readText import kotlin.io.path.readText
/** /**
@ -52,8 +53,8 @@ sealed class SourceCode {
*/ */
private const val LIBRARYFILEPREFIX = "library:" private const val LIBRARYFILEPREFIX = "library:"
private const val STRINGSOURCEPREFIX = "string:" private const val STRINGSOURCEPREFIX = "string:"
val curdir: Path = Path(".").toAbsolutePath() val curdir: Path = Path(".").absolute()
fun relative(path: Path): Path = curdir.relativize(path.toAbsolutePath()) fun relative(path: Path): Path = curdir.relativize(path.absolute())
fun isRegularFilesystemPath(pathString: String) = !isLibraryResource(pathString) && !isStringResource(pathString) fun isRegularFilesystemPath(pathString: String) = !isLibraryResource(pathString) && !isStringResource(pathString)
fun isLibraryResource(path: String) = path.startsWith(LIBRARYFILEPREFIX) fun isLibraryResource(path: String) = path.startsWith(LIBRARYFILEPREFIX)
fun isStringResource(path: String) = path.startsWith(STRINGSOURCEPREFIX) fun isStringResource(path: String) = path.startsWith(STRINGSOURCEPREFIX)

View File

@ -12,6 +12,7 @@ import prog8.code.source.SourceCode
import prog8.code.target.Cx16Target import prog8.code.target.Cx16Target
import prog8.codegen.cpu6502.assignment.* import prog8.codegen.cpu6502.assignment.*
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.absolute
import kotlin.io.path.writeLines import kotlin.io.path.writeLines
@ -1083,8 +1084,8 @@ $repeatLabel""")
val sourcePath = Path(incbin.definingBlock()!!.source.origin) val sourcePath = Path(incbin.definingBlock()!!.source.origin)
val includedPath = sourcePath.resolveSibling(incbin.file) val includedPath = sourcePath.resolveSibling(incbin.file)
val pathForAssembler = options.outputDir // #54: 64tass needs the path *relative to the .asm file* val pathForAssembler = options.outputDir // #54: 64tass needs the path *relative to the .asm file*
.toAbsolutePath() .absolute()
.relativize(includedPath.toAbsolutePath()) .relativize(includedPath.absolute())
.normalize() // avoid assembler warnings (-Wportable; only some, not all) .normalize() // avoid assembler warnings (-Wportable; only some, not all)
.toString().replace('\\', '/') .toString().replace('\\', '/')
out(" .binary \"$pathForAssembler\" $offset $length") out(" .binary \"$pathForAssembler\" $offset $length")

View File

@ -3,6 +3,7 @@ package prog8
import kotlinx.cli.* import kotlinx.cli.*
import prog8.ast.AstException import prog8.ast.AstException
import prog8.code.core.CbmPrgLauncherType import prog8.code.core.CbmPrgLauncherType
import prog8.code.source.ImportFileSystem
import prog8.code.target.CompilationTargets import prog8.code.target.CompilationTargets
import prog8.code.target.Cx16Target import prog8.code.target.Cx16Target
import prog8.code.target.getCompilationTargetByName import prog8.code.target.getCompilationTargetByName
@ -95,8 +96,8 @@ private fun compileMain(args: Array<String>): Boolean {
return false return false
} }
val srcdirs = sourceDirs.toMutableList() val srcdirs = sourceDirs.map { ImportFileSystem.expandTilde(it) }.toMutableList()
if(srcdirs.firstOrNull()!=".") if(sourceDirs.firstOrNull()!=".")
srcdirs.add(0, ".") srcdirs.add(0, ".")
if(startVm==null) { if(startVm==null) {

View File

@ -135,7 +135,7 @@ class ModuleImporter(private val program: Program,
if (importingModule == null) { // <=> imported from library module if (importingModule == null) { // <=> imported from library module
sourcePaths sourcePaths
} else { } else {
val pathFromImportingModule = (Path(importingModule.position.file).parent ?: Path("")).absolute() val pathFromImportingModule = (Path(importingModule.position.file).parent ?: Path("")).absolute().normalize()
listOf(pathFromImportingModule) + sourcePaths listOf(pathFromImportingModule) + sourcePaths
} }

View File

@ -15,6 +15,7 @@ import prog8.code.source.SourceCode
import prog8.compiler.builtinFunctionReturnType import prog8.compiler.builtinFunctionReturnType
import java.io.File import java.io.File
import kotlin.io.path.Path import kotlin.io.path.Path
import kotlin.io.path.absolute
import kotlin.io.path.isRegularFile import kotlin.io.path.isRegularFile
@ -257,10 +258,10 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
val offset: UInt? = if(directive.args.size>=2) directive.args[1].int!! else null val offset: UInt? = if(directive.args.size>=2) directive.args[1].int!! else null
val length: UInt? = if(directive.args.size>=3) directive.args[2].int!! else null val length: UInt? = if(directive.args.size>=3) directive.args[2].int!! else null
val abspath = if(File(filename).isFile) { val abspath = if(File(filename).isFile) {
Path(filename).toAbsolutePath() Path(filename).absolute()
} else { } else {
val sourcePath = Path(directive.definingModule.source.origin) val sourcePath = Path(directive.definingModule.source.origin)
sourcePath.resolveSibling(filename).toAbsolutePath() sourcePath.resolveSibling(filename).absolute()
} }
if(abspath.toFile().isFile) if(abspath.toFile().isFile)
PtIncludeBinary(abspath, offset, length, directive.position) PtIncludeBinary(abspath, offset, length, directive.position)

View File

@ -61,7 +61,7 @@ private fun prepareTestFiles(source: String, optimize: Boolean, target: ICompila
} }
val filepath = searchIn.asSequence() val filepath = searchIn.asSequence()
.map { it.resolve("$source.p8") } .map { it.resolve("$source.p8") }
.map { it.normalize().absolute() } .map { it.absolute().normalize() }
.map { workingDir.relativize(it) } .map { workingDir.relativize(it) }
.first { it.exists() } .first { it.exists() }
val displayName = "${examplesDir.relativize(filepath.absolute())}: ${target.name}, optimize=$optimize" val displayName = "${examplesDir.relativize(filepath.absolute())}: ${target.name}, optimize=$optimize"

View File

@ -11,6 +11,7 @@ import prog8.ast.statements.FunctionCallStatement
import prog8.ast.statements.Label import prog8.ast.statements.Label
import prog8.code.target.Cx16Target import prog8.code.target.Cx16Target
import prog8tests.helpers.* import prog8tests.helpers.*
import kotlin.io.path.absolute
import kotlin.io.path.name import kotlin.io.path.name
@ -97,7 +98,7 @@ class TestCompilerOnImportsAndIncludes: FunSpec({
// the bug we're testing for (#54) was hidden if outputDir == workingDir // the bug we're testing for (#54) was hidden if outputDir == workingDir
withClue("sanity check: workingDir and outputDir should not be the same folder") { withClue("sanity check: workingDir and outputDir should not be the same folder") {
outputDir.normalize().toAbsolutePath() shouldNotBe workingDir.normalize().toAbsolutePath() outputDir.absolute().normalize() shouldNotBe workingDir.absolute().normalize()
} }
withClue("argument to assembler directive .binary " + withClue("argument to assembler directive .binary " +

View File

@ -103,7 +103,7 @@ class TestProg8Parser: FunSpec( {
val nlUnix = "\n" val nlUnix = "\n"
val nlMac = "\r" val nlMac = "\r"
//parseModule(Paths.get("test", "fixtures", "mac_newlines.p8").toAbsolutePath()) //parseModule(Paths.get("test", "fixtures", "mac_newlines.p8").absolute())
// a good mix of all kinds of newlines: // a good mix of all kinds of newlines:
val srcText = val srcText =

View File

@ -7,6 +7,7 @@ import prog8.code.source.ImportFileSystem
import java.nio.file.Path import java.nio.file.Path
import javax.xml.stream.XMLOutputFactory import javax.xml.stream.XMLOutputFactory
import javax.xml.stream.XMLStreamWriter import javax.xml.stream.XMLStreamWriter
import kotlin.io.path.absolute
import kotlin.io.path.bufferedWriter import kotlin.io.path.bufferedWriter
import kotlin.io.path.div import kotlin.io.path.div
@ -198,7 +199,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
} }
xml.writeCharacters("loadAddress=${irProgram.options.loadAddress.toHex()}\n") xml.writeCharacters("loadAddress=${irProgram.options.loadAddress.toHex()}\n")
xml.writeCharacters("optimize=${irProgram.options.optimize}\n") xml.writeCharacters("optimize=${irProgram.options.optimize}\n")
xml.writeCharacters("outputDir=${irProgram.options.outputDir.toAbsolutePath()}\n") xml.writeCharacters("outputDir=${irProgram.options.outputDir.absolute()}\n")
// other options not yet useful here? // other options not yet useful here?
xml.writeEndElement() xml.writeEndElement()
xml.writeCharacters("\n\n") xml.writeCharacters("\n\n")

View File

@ -538,7 +538,7 @@ object SysCalls {
Syscall.DIRECTORY -> { Syscall.DIRECTORY -> {
// no arguments // no arguments
val directory = Path("") val directory = Path("")
println("Directory listing for ${directory.toAbsolutePath().normalize()}") println("Directory listing for ${directory.absolute().normalize()}")
directory.listDirectoryEntries().sorted().forEach { directory.listDirectoryEntries().sorted().forEach {
println("${it.toFile().length()}\t${it.normalize()}") println("${it.toFile().length()}\t${it.normalize()}")
} }
@ -574,7 +574,7 @@ object SysCalls {
} }
Syscall.CURDIR -> { Syscall.CURDIR -> {
val curdir = Path("").toAbsolutePath().toString() val curdir = Path("").absolute().toString()
vm.memory.setString(0xfe00, curdir, true) vm.memory.setString(0xfe00, curdir, true)
return returnValue(callspec.returns.single(), 0xfe00, vm) return returnValue(callspec.returns.single(), 0xfe00, vm)
} }