One missing patch says one thing
A patch file that could not be read left the name unregistered, so every #Voice naming it failed as well, and then the check that a voice has an instrument failed for each of those. One wrong path produced seven messages and only the first was worth reading. A patch that cannot be read is still a patch that was NAMED. It is registered either way now, with its bytes marked missing, so everything below resolves the name and says nothing. Nothing is written regardless - one problem is enough to stop that - so a patch with no bytes never reaches a file. The damage from the old behaviour was not the extra lines. It is that a compiler which says one thing seven ways teaches people to read the last line, which is the one that matters least. Checked by counting: one missing patch, three voices using it, and the count of messages mentioning it has to be one. break.sh confirms it by putting the old behaviour back on the failure path alone - the first attempt at that break stopped every tune compiling and the disk build failed before any test ran, which is break.sh being right about a break that proved nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
co-authored by
Claude Opus 5
parent
fb672d7761
commit
fee2b1ef10
+23
-5
@@ -62,6 +62,7 @@ typedef struct {
|
|||||||
unsigned char bytes[512];
|
unsigned char bytes[512];
|
||||||
int length;
|
int length;
|
||||||
int line;
|
int line;
|
||||||
|
int bad; // Named, but its bytes could not be had. See doPatch.
|
||||||
} Patch;
|
} Patch;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -215,26 +216,41 @@ static void doPatch(void) {
|
|||||||
complain(name->line, "that patch is named twice", name->text);
|
complain(name->line, "that patch is named twice", name->text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// ---- A PATCH THAT CANNOT BE READ IS STILL A PATCH THAT WAS NAMED ----
|
||||||
|
//
|
||||||
|
// It is registered either way, with its bytes marked missing. Nothing will be written -
|
||||||
|
// one problem is enough to stop that - but everything below can now resolve the name, so
|
||||||
|
// a single missing file says one thing instead of seven.
|
||||||
|
//
|
||||||
|
// It used to return here, and the damage was out of all proportion: the name went
|
||||||
|
// unregistered, so every #Voice naming it failed as well, and then the check that a voice
|
||||||
|
// has an instrument failed for each of those. One wrong path, seven messages, and only
|
||||||
|
// the first of them worth reading. A compiler that says one thing seven ways teaches
|
||||||
|
// people to read the last line, which is the one that matters least.
|
||||||
|
Patch *p = &patches[patchCount];
|
||||||
|
snprintf(p->name, MAX_NAME, "%s", name->text);
|
||||||
|
p->line = name->line;
|
||||||
|
p->length = 0;
|
||||||
|
p->bad = 0;
|
||||||
|
patchCount++;
|
||||||
|
|
||||||
char where[1024];
|
char where[1024];
|
||||||
FILE *in = openPatch(file->text, where, sizeof(where));
|
FILE *in = openPatch(file->text, where, sizeof(where));
|
||||||
if (!in) {
|
if (!in) {
|
||||||
complain(file->line, "cannot find that patch beside the tune or on the -I path",
|
complain(file->line, "cannot find that patch beside the tune or on the -I path",
|
||||||
file->text);
|
file->text);
|
||||||
|
p->bad = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Patch *p = &patches[patchCount];
|
|
||||||
snprintf(p->name, MAX_NAME, "%s", name->text);
|
|
||||||
p->length = (int)fread(p->bytes, 1, sizeof(p->bytes), in);
|
p->length = (int)fread(p->bytes, 1, sizeof(p->bytes), in);
|
||||||
p->line = name->line;
|
|
||||||
fclose(in);
|
fclose(in);
|
||||||
|
|
||||||
// A patch is a count and that many pairs. Anything else is a file that is not one, and
|
// A patch is a count and that many pairs. Anything else is a file that is not one, and
|
||||||
// embedding it would make a tune that writes rubbish at the sound device.
|
// embedding it would make a tune that writes rubbish at the sound device.
|
||||||
if (p->length < 1 || p->length != 1 + p->bytes[0] * 2) {
|
if (p->length < 1 || p->length != 1 + p->bytes[0] * 2) {
|
||||||
complain(file->line, "that is not a patch: SoundPatch --blob writes one", file->text);
|
complain(file->line, "that is not a patch: SoundPatch --blob writes one", file->text);
|
||||||
return;
|
p->bad = 1;
|
||||||
}
|
}
|
||||||
patchCount++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void doVoice(void) {
|
static void doVoice(void) {
|
||||||
@@ -269,6 +285,8 @@ static void doSequence(void) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (findSequence(name->text) >= 0) {
|
if (findSequence(name->text) >= 0) {
|
||||||
|
// The first one keeps the name, so an order list naming it still resolves and the
|
||||||
|
// duplicate is reported once rather than once here and again at every use.
|
||||||
complain(name->line, "that sequence is named twice", name->text);
|
complain(name->line, "that sequence is named twice", name->text);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -862,6 +862,22 @@ PY2
|
|||||||
refuses "a duration is from" \
|
refuses "a duration is from" \
|
||||||
"#Tick 0d125000" "#Patch A low.patch" "#Voice 0d0 A" "#Sequence S" "0d60 0d0" \
|
"#Tick 0d125000" "#Patch A low.patch" "#Voice 0d0 A" "#Sequence S" "0d60 0d0" \
|
||||||
"#Order 0d0" "S"
|
"#Order 0d0" "S"
|
||||||
|
# ---- AND IT SAYS IT ONCE ----
|
||||||
|
#
|
||||||
|
# One missing patch used to be seven messages: the name went unregistered, so every #Voice
|
||||||
|
# naming it failed too, and then the check that a voice has an instrument failed for each
|
||||||
|
# of those. Only the first was worth reading. A compiler that says one thing seven ways
|
||||||
|
# teaches people to read the last line, which is the one that matters least.
|
||||||
|
printf '%s\n' "#Tick 0d125000" "#Patch A nosuch.patch" \
|
||||||
|
"#Voice 0d0 A" "#Voice 0d1 A" "#Voice 0d2 A" \
|
||||||
|
"#Sequence S" "0d60 0d4" \
|
||||||
|
"#Order 0d0" "S" "#Order 0d1" "S" "#Order 0d2" "S" > "$BUILD/cascade.tune.txt"
|
||||||
|
SAID="$("$ROOT/TuneC" "$BUILD/cascade.tune.txt" "$BUILD/cascade.tune" 2>&1 \
|
||||||
|
| grep -c "cannot find\|no patch of that name\|no instrument")"
|
||||||
|
[ "$SAID" = "1" ] \
|
||||||
|
&& result ok "TuneC says a missing patch once" "one message, not one for every use of it" \
|
||||||
|
|| result no "TuneC says a missing patch once" "$SAID messages for one missing file"
|
||||||
|
|
||||||
refuses "no sequence of that name" \
|
refuses "no sequence of that name" \
|
||||||
"#Tick 0d125000" "#Patch A low.patch" "#Voice 0d0 A" "#Sequence S" "0d60 0d4" \
|
"#Tick 0d125000" "#Patch A low.patch" "#Voice 0d0 A" "#Sequence S" "0d60 0d4" \
|
||||||
"#Order 0d0" "Nope"
|
"#Order 0d0" "Nope"
|
||||||
|
|||||||
Reference in New Issue
Block a user