diff --git a/StarterNG.Tests/ScenerySyntaxTests.cs b/StarterNG.Tests/ScenerySyntaxTests.cs index 3052cd3..39fede4 100644 --- a/StarterNG.Tests/ScenerySyntaxTests.cs +++ b/StarterNG.Tests/ScenerySyntaxTests.cs @@ -273,7 +273,7 @@ public class ScenerySyntaxTests include koniec.scm """; - var scenery = TestScenery.Parser().Parse("scenery/x.scn", scn, _ => new IncludeLookup(true)); + var scenery = TestScenery.Parser().Parse("scenery/x.scn", scn, _ => true); Assert.Empty(scenery.Faults); Assert.Equal("td/rozklad", Assert.Single(scenery.Trainsets).Name); @@ -326,7 +326,7 @@ public class ScenerySyntaxTests endoptional """; - var faults = TestScenery.Parser().Parse("scenery/x.scn", scn, name => new IncludeLookup(name is "tory.scm" or "budynek.inc")).Faults; + var faults = TestScenery.Parser().Parse("scenery/x.scn", scn, name => name is "tory.scm" or "budynek.inc").Faults; Assert.Equal((SceneryFaultKind.MissingInclude, "x.scn", 2, null, "brak.scm"), Seen(Assert.Single(faults))); } @@ -347,9 +347,9 @@ public class ScenerySyntaxTests } [Fact] - public void An_include_on_disk_only_in_other_letter_case_is_what_linux_misses() + public void An_include_on_disk_in_other_letter_case_is_no_fault() { - // The simulator folds the name to lower case and opens it so. + // The simulator finds the file whatever the case of its letters, on Linux too. var files = new InMemoryFileSystem(caseSensitive: true) .WithLegacyFile("game/scenery/braniewo_szeroki.scn", "include braniewo/base.ctr end\ninclude Braniewo/Tory.SCM end\n") @@ -357,21 +357,20 @@ public class ScenerySyntaxTests .WithFile("game/scenery/braniewo/tory.scm", ""); var repository = TestScenery.Repository(files); - var faults = repository.Load("game/scenery/braniewo_szeroki.scn")!.Faults; - - Assert.Equal((SceneryFaultKind.IncludeLetterCase, "braniewo_szeroki.scn", 1, "Braniewo/Base.ctr", "braniewo/base.ctr"), - Seen(Assert.Single(faults))); + Assert.Empty(repository.Load("game/scenery/braniewo_szeroki.scn")!.Faults); } [Theory] - [InlineData(true)] - [InlineData(false)] - public void A_missing_terrain_file_is_no_fault_while_the_scenery_has_its_own_sbt(bool sbt) + [InlineData(null)] + [InlineData("lk2_sandbox.sbt")] + [InlineData("Lk2_Sandbox.SBT")] + public void A_missing_terrain_file_is_no_fault_while_the_scenery_has_its_own_sbt(string? sbtOnDisk) { + bool sbt = sbtOnDisk is not null; var files = new InMemoryFileSystem(caseSensitive: true) .WithLegacyFile("game/scenery/Lk2_Sandbox.scn", "include nmt/nmt100_mazowieckie_ter.scm end\nFirstInit\n"); if (sbt) - files.WithFile("game/scenery/lk2_sandbox.sbt", "EU07"); + files.WithFile("game/scenery/" + sbtOnDisk, "EU07"); var repository = TestScenery.Repository(files); var scenery = repository.Load("game/scenery/Lk2_Sandbox.scn")!; diff --git a/StarterNG/Domain/Sceneries/SceneryFault.cs b/StarterNG/Domain/Sceneries/SceneryFault.cs index 2fd42ef..1b4f5f7 100644 --- a/StarterNG/Domain/Sceneries/SceneryFault.cs +++ b/StarterNG/Domain/Sceneries/SceneryFault.cs @@ -61,13 +61,6 @@ public enum SceneryFaultKind /// An include whose file is not there; names it. MissingInclude, - /// - /// An include whose file is there only under a name in other letter case: the - /// simulator looks for it in lower case, which on Linux misses it. The - /// holds the name on disk. - /// - IncludeLetterCase, - /// An include with no end, which swallows what follows it. IncludeNotClosed, diff --git a/StarterNG/Domain/Sceneries/ScenerySyntax.cs b/StarterNG/Domain/Sceneries/ScenerySyntax.cs index a943d32..87ee063 100644 --- a/StarterNG/Domain/Sceneries/ScenerySyntax.cs +++ b/StarterNG/Domain/Sceneries/ScenerySyntax.cs @@ -5,12 +5,6 @@ using System.Linq; namespace StarterNG.Domain.Sceneries; -/// -/// What the simulator makes of an include: whether it opens the file - and when -/// it does not, the file that is there under a name differing only in letter case. -/// -public readonly record struct IncludeLookup(bool Opens, string? OnDisk = null); - /// /// Goes through a scenery's text for the parts the starter reads - trainsets, /// vehicles, includes - finding where each trainset and loose vehicle is, and @@ -35,17 +29,17 @@ public static class ScenerySyntax /// The scenery's text, its includes put in place. /// The scenery's file name, for faults in its own text. - /// - /// What the simulator makes of an include, named as the include names it; null + /// + /// Whether the simulator opens an include, named as the include names it; null /// leaves includes unchecked. /// - public static Result Scan(string text, string file, Func? findInclude = null) + public static Result Scan(string text, string file, Func? opensInclude = null) { string code = SceneryCode.Mask(text, out int unclosed); var tokens = SceneryCode.Tokens(code); var lines = new SceneryLines(text, file); - var simulator = new Reading(tokens, lines, findInclude, asSimulator: true); + var simulator = new Reading(tokens, lines, opensInclude, asSimulator: true); simulator.Run(); var author = new Reading(tokens, lines, null, asSimulator: false); author.Run(); @@ -116,7 +110,7 @@ public static class ScenerySyntax } private sealed class Reading( - List tokens, SceneryLines lines, Func? findInclude, bool asSimulator) + List tokens, SceneryLines lines, Func? opensInclude, bool asSimulator) { public readonly List<(int Start, int End, string Name)> Trainsets = new(); public readonly List<(int, int)> Loose = new(); @@ -375,13 +369,8 @@ public static class ScenerySyntax return stop < tokens.Count && tokens[stop].Is("end") ? stop : stop - 1; } - if (findInclude is not null && Plain(name) && findInclude(name) is { Opens: false } lookup) - { - if (lookup.OnDisk is { } onDisk) - Fault(SceneryFaultKind.IncludeLetterCase, token.Index, onDisk, name); - else - Fault(SceneryFaultKind.MissingInclude, token.Index, token: name); - } + if (opensInclude is not null && Plain(name) && !opensInclude(name)) + Fault(SceneryFaultKind.MissingInclude, token.Index, token: name); // The simulator takes its parameters up to the word "end", written just so, // whatever comes before it. diff --git a/StarterNG/Infrastructure/Sceneries/SceneryParser.cs b/StarterNG/Infrastructure/Sceneries/SceneryParser.cs index e7d3bac..f8072ba 100644 --- a/StarterNG/Infrastructure/Sceneries/SceneryParser.cs +++ b/StarterNG/Infrastructure/Sceneries/SceneryParser.cs @@ -20,11 +20,11 @@ public sealed class SceneryParser _random = random; } - /// - /// What the simulator makes of an include, as the include names it; null leaves + /// + /// Whether the simulator opens an include, as the include names it; null leaves /// includes unchecked. /// - public Scenery Parse(string path, string content, Func? findInclude = null) + public Scenery Parse(string path, string content, Func? opensInclude = null) { string original = content; @@ -38,7 +38,7 @@ public sealed class SceneryParser // Read from the text with its optional includes blanked, which keeps every // place where it was, so a fault's line is the line in the file. - var syntax = ScenerySyntax.Scan(content, System.IO.Path.GetFileName(path), findInclude); + var syntax = ScenerySyntax.Scan(content, System.IO.Path.GetFileName(path), opensInclude); var faults = syntax.Faults.ToList(); var inlined = SceneryIncludes.Ranges(content); diff --git a/StarterNG/Infrastructure/Sceneries/SceneryRepository.cs b/StarterNG/Infrastructure/Sceneries/SceneryRepository.cs index 62c68ad..229d59a 100644 --- a/StarterNG/Infrastructure/Sceneries/SceneryRepository.cs +++ b/StarterNG/Infrastructure/Sceneries/SceneryRepository.cs @@ -80,10 +80,8 @@ public sealed class SceneryRepository : ISceneryRepository // With its own .sbt the scenery's terrain comes from it, and the simulator // passes its terrain includes over without opening them. bool binaryTerrain = Opens(Path.GetFileNameWithoutExtension(path) + ".sbt"); - IncludeLookup FindInclude(string name) => - Opens(name) || (binaryTerrain && SimulatorNames.Lower(name).Contains("_ter.scm")) - ? new IncludeLookup(true) - : new IncludeLookup(false, ResolveInclude(name)); + bool OpensInclude(string name) => + Opens(name) || (binaryTerrain && SimulatorNames.Lower(name).Contains("_ter.scm")); (string File, string Text)? ReadInclude(string name) { @@ -100,7 +98,7 @@ public sealed class SceneryRepository : ISceneryRepository string own = LegacyText.Decode(_files.ReadAllBytes(path), out var ownEncoding); string text = SceneryIncludes.Inline(own, ReadInclude); - var scenery = _parser.Parse(path, text, FindInclude); + var scenery = _parser.Parse(path, text, OpensInclude); scenery.HasCompanionTimetable = binaryTerrain; scenery.Sources = sources; scenery.TextEncoding = ownEncoding; @@ -115,11 +113,11 @@ public sealed class SceneryRepository : ISceneryRepository } /// - /// Whether the simulator opens a file of the scenery folder named so: by the - /// name in lower case, which on Linux has to be how it is named on disk. + /// Whether the simulator opens a file of the scenery folder named so: whatever the + /// case of its letters, on Linux too. A shade more lenient than eu07 there, which + /// folds only the letters A to Z and of two folders named alike takes the first. /// - private bool Opens(string name) => - _files.FileExists(Path.Combine(_paths.Scenery, SimulatorNames.Lower(name.Replace('\\', '/')))); + private bool Opens(string name) => ResolveInclude(name) is not null; /// /// An include's file as it is named on disk, from the scenery folder, whatever diff --git a/StarterNG/startercfg/lang/cz.xml b/StarterNG/startercfg/lang/cz.xml index 0bb1d32..64df1b5 100644 --- a/StarterNG/startercfg/lang/cz.xml +++ b/StarterNG/startercfg/lang/cz.xml @@ -742,7 +742,6 @@ Vozidlo {0} stojí mimo soupravu: chybí záhlaví trainset? {0}: „{1}“ místo čísla Soubor {1} nenalezen (include) - Soubor {1} je na disku jako {0}: linuxový eu07 ho nenačte include {1} bez end Soupravu {0} se nepodařilo načíst Vozidlo {0} se nepodařilo načíst diff --git a/StarterNG/startercfg/lang/en.xml b/StarterNG/startercfg/lang/en.xml index e0a4ba1..3e1c383 100644 --- a/StarterNG/startercfg/lang/en.xml +++ b/StarterNG/startercfg/lang/en.xml @@ -772,7 +772,6 @@ Vehicle {0} stands outside a trainset: header missing? {0}: “{1}” instead of a number File {1} not found (include) - File {1} is on disk as {0}: the Linux eu07 will not load it include {1} without end Trainset {0} could not be read Vehicle {0} could not be read diff --git a/StarterNG/startercfg/lang/hu.xml b/StarterNG/startercfg/lang/hu.xml index 4c1a4dc..d7286f1 100644 --- a/StarterNG/startercfg/lang/hu.xml +++ b/StarterNG/startercfg/lang/hu.xml @@ -742,7 +742,6 @@ A(z) {0} jármű szerelvényen kívül áll: hiányzik a trainset fejléc? {0}: „{1}” szám helyett A(z) {1} fájl nem található (include) - A(z) {1} fájl a lemezen {0} néven van: a linuxos eu07 nem tölti be include {1} end nélkül A(z) {0} szerelvényt nem sikerült beolvasni A(z) {0} járművet nem sikerült beolvasni diff --git a/StarterNG/startercfg/lang/pl.xml b/StarterNG/startercfg/lang/pl.xml index 3713dd5..7e2df79 100644 --- a/StarterNG/startercfg/lang/pl.xml +++ b/StarterNG/startercfg/lang/pl.xml @@ -769,7 +769,6 @@ Pojazd {0} stoi poza składem: brak nagłówka trainset? {0}: „{1}” zamiast liczby Brak pliku {1} (include) - Plik {1} jest na dysku jako {0}: linuksowy eu07 go nie wczyta include {1} bez end Nie udało się odczytać składu {0} Nie udało się odczytać pojazdu {0} diff --git a/StarterNG/startercfg/lang/ru.xml b/StarterNG/startercfg/lang/ru.xml index c73f842..280351e 100644 --- a/StarterNG/startercfg/lang/ru.xml +++ b/StarterNG/startercfg/lang/ru.xml @@ -742,7 +742,6 @@ Транспорт {0} стоит вне состава: нет заголовка trainset? {0}: «{1}» вместо числа Файл {1} не найден (include) - Файл {1} на диске назван {0}: eu07 на Linux его не загрузит include {1} без end Не удалось прочитать состав {0} Не удалось прочитать единицу {0}