101 lines
3.4 KiB
C
101 lines
3.4 KiB
C
// Part of JoeyLib, Copyright (c) 2026 Scott Duensing, under the MIT License.
|
|
// See LICENSE.md for license information.
|
|
// SPDX-License-Identifier: MIT
|
|
//
|
|
// diffUberHashes.c - compare two UBER logs (joeylog.txt) op by op, by the
|
|
// surface hash each op left.
|
|
//
|
|
// diffUberHashes <reference-log> <test-log>
|
|
//
|
|
// The golden gates hold each port's UBER run to tests/goldens/uber with it
|
|
// (scripts/verify-all.sh), and a port's rewrite of a primitive is checked
|
|
// with it: it names every op whose pixels came out different, which "looks
|
|
// right" misses until the mismatch cascades into corruption that is hard
|
|
// to trace.
|
|
//
|
|
// Both the timed ops' hashes and the UBER-CHK correctness checks' count, a
|
|
// check's under "chk:<op>" so it can never meet a timed op's name; the last
|
|
// hash a log gives an op is the one compared (toolUberLog.h). Prints a line
|
|
// for each op MISSING from the test log, each MISMATCH, and each EXTRA op
|
|
// only the test log has, then the tally.
|
|
//
|
|
// Exit: 0 every hash matches, 1 at least one does not (or an op is missing
|
|
// or extra), 2 a usage error or a log that cannot be read or has no UBER
|
|
// hash lines.
|
|
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
#include "toolFile.h"
|
|
#include "toolUberLog.h"
|
|
|
|
#define TOOL_NAME "diffUberHashes"
|
|
#define ARG_COUNT 3
|
|
#define MATCH_EXIT 0
|
|
#define FAIL_EXIT 1
|
|
#define USAGE_EXIT 2
|
|
|
|
|
|
int main(int argc, char **argv) {
|
|
ToolUberLogT ref;
|
|
ToolUberLogT test;
|
|
const ToolUberOpT *op;
|
|
const ToolUberOpT *other;
|
|
size_t matches;
|
|
size_t mismatches;
|
|
size_t extras;
|
|
size_t i;
|
|
|
|
toolFileName(TOOL_NAME);
|
|
if (argc != ARG_COUNT) {
|
|
fprintf(stderr, "usage: %s <reference-log> <test-log>\n", TOOL_NAME);
|
|
return USAGE_EXIT;
|
|
}
|
|
if (!toolUberRead(TOOL_NAME, argv[1], TOOL_UBER_HASH, &ref) || !toolUberRead(TOOL_NAME, argv[2], TOOL_UBER_HASH, &test)) {
|
|
return USAGE_EXIT;
|
|
}
|
|
if (ref.count == 0u) {
|
|
fprintf(stderr, "%s: no UBER hash lines in %s\n", TOOL_NAME, argv[1]);
|
|
return USAGE_EXIT;
|
|
}
|
|
if (test.count == 0u) {
|
|
fprintf(stderr, "%s: no UBER hash lines in %s\n", TOOL_NAME, argv[2]);
|
|
return USAGE_EXIT;
|
|
}
|
|
matches = 0u;
|
|
mismatches = 0u;
|
|
extras = 0u;
|
|
for (i = 0; i < ref.count; i++) {
|
|
op = &ref.ops[i];
|
|
other = toolUberFind(&test, op->name, op->nameLen);
|
|
if (other == NULL) {
|
|
fputs(" MISSING in test: ", stdout);
|
|
toolUberNamePrint(stdout, op);
|
|
printf(" (ref=%s)\n", op->hash);
|
|
mismatches++;
|
|
} else if (strcmp(other->hash, op->hash) != 0) {
|
|
fputs(" MISMATCH ", stdout);
|
|
toolUberNamePrint(stdout, op);
|
|
printf(": ref=%s test=%s\n", op->hash, other->hash);
|
|
mismatches++;
|
|
} else {
|
|
matches++;
|
|
}
|
|
}
|
|
for (i = 0; i < test.count; i++) {
|
|
op = &test.ops[i];
|
|
if (toolUberFind(&ref, op->name, op->nameLen) == NULL) {
|
|
fputs(" EXTRA in test: ", stdout);
|
|
toolUberNamePrint(stdout, op);
|
|
printf(" (test=%s)\n", op->hash);
|
|
extras++;
|
|
}
|
|
}
|
|
putchar('\n');
|
|
if (mismatches == 0u && extras == 0u) {
|
|
printf("OK: %zu/%zu ops match\n", matches, ref.count + extras);
|
|
return MATCH_EXIT;
|
|
}
|
|
printf("FAIL: %zu match, %zu mismatch, %zu extras\n", matches, mismatches, extras);
|
|
return FAIL_EXIT;
|
|
}
|