Read the exchange boxes a published .udc file actually names

The box names in EntryWindowInfo are N1MM's LogItem.LogItemNameType members.
We read four of them under names that are not in that enum, so a file naming
its section box SectionText got no section box at all, and a zone or a power
box was dropped whatever it was called.

SectionText, CQZoneText and PowerText are now read. SectText stays as well: it
is not one of N1MM's names but files in the wild use it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 23:37:54 +00:00
parent ae48c04e71
commit 0ef12ff8be
2 changed files with 40 additions and 1 deletions

View File

@@ -135,12 +135,19 @@ public sealed class UserDefinedContest : Contest
: [new ExchangeField("RST", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report)]; : [new ExchangeField("RST", ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report)];
} }
/// The names are N1MM's `LogItem.LogItemNameType` members, which is what a
/// published `.udc` file holds. `SectText` is not one of them but files in
/// the wild use it. The sent-side boxes — `SNTText`, `SntNrText` — are not
/// exchange boxes here and fall through.
private static ExchangeField? BoxToField(string box, string label) => box.ToUpperInvariant() switch private static ExchangeField? BoxToField(string box, string label) => box.ToUpperInvariant() switch
{ {
"RCVTEXT" => new ExchangeField(label, ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report), "RCVTEXT" => new ExchangeField(label, ExchangeSlot.ReceivedReport, ExchangeFieldKind.Report),
"RCVNRTEXT" => new ExchangeField(label, ExchangeSlot.SerialNumber, ExchangeFieldKind.Number), "RCVNRTEXT" => new ExchangeField(label, ExchangeSlot.SerialNumber, ExchangeFieldKind.Number),
"EXCHANGE1TEXT" => new ExchangeField(label, ExchangeSlot.Exchange1, ExchangeFieldKind.Text) { Width = 6 }, "EXCHANGE1TEXT" => new ExchangeField(label, ExchangeSlot.Exchange1, ExchangeFieldKind.Text) { Width = 6 },
"SECTTEXT" => new ExchangeField(label, ExchangeSlot.Section, ExchangeFieldKind.ArrlSection), "SECTIONTEXT" or "SECTTEXT" =>
new ExchangeField(label, ExchangeSlot.Section, ExchangeFieldKind.ArrlSection),
"CQZONETEXT" => new ExchangeField(label, ExchangeSlot.Zone, ExchangeFieldKind.CqZone),
"POWERTEXT" => new ExchangeField(label, ExchangeSlot.Power, ExchangeFieldKind.Power),
"GRIDSQUARETEXT" => new ExchangeField(label, ExchangeSlot.GridSquare, ExchangeFieldKind.Grid), "GRIDSQUARETEXT" => new ExchangeField(label, ExchangeSlot.GridSquare, ExchangeFieldKind.Grid),
"NAMETEXT" => new ExchangeField(label, ExchangeSlot.Name, ExchangeFieldKind.Text) { Width = 10 }, "NAMETEXT" => new ExchangeField(label, ExchangeSlot.Name, ExchangeFieldKind.Text) { Width = 10 },
"MISCTEXT" => new ExchangeField(label, ExchangeSlot.MiscText, ExchangeFieldKind.Text) { Width = 8 }, "MISCTEXT" => new ExchangeField(label, ExchangeSlot.MiscText, ExchangeFieldKind.Text) { Width = 8 },

View File

@@ -74,4 +74,36 @@ public class UserDefinedContestTests
log.Add(TestLog.Contact("JA1XYZ")); log.Add(TestLog.Contact("JA1XYZ"));
Assert.False(log.Judge(TestLog.Contact("JA1XYZ")).IsDupe); Assert.False(log.Judge(TestLog.Contact("JA1XYZ")).IsDupe);
} }
/// The box names in a published file are N1MM's `LogItemNameType` members.
[Fact]
public void TheZoneStateAndPowerBoxesAreRead()
{
UserDefinedContest contest = new(UdcFile.Parse("""
[Contest]
Name=BOXTEST
EntryWindowInfo=RCVText, 400, CQZoneText, 300, SectionText, 300, PowerText, 300
FrameText=RST Zone Sect Pwr
"""));
Assert.Equal(
[ExchangeSlot.ReceivedReport, ExchangeSlot.Zone, ExchangeSlot.Section, ExchangeSlot.Power],
contest.ExchangeFieldsFor(TestLog.Germany).Select(f => f.Slot).ToList());
}
/// The sent-side boxes are in the same setting and are not exchange boxes.
[Fact]
public void TheSentBoxesAreLeftOutOfTheExchange()
{
UserDefinedContest contest = new(UdcFile.Parse("""
[Contest]
Name=SENTTEST
EntryWindowInfo=SNTText, 400, SntNrText, 300, RCVText, 400, RcvNrText, 300
FrameText=Snt SntNr RST Nr
"""));
Assert.Equal(
[ExchangeSlot.ReceivedReport, ExchangeSlot.SerialNumber],
contest.ExchangeFieldsFor(TestLog.Germany).Select(f => f.Slot).ToList());
}
} }