1#include "internal.h"
2
3#include <console/printf.h>
4#include <math/hash.h>
5#include <nightmare/record.h>
6#include <stdarg.h>
7
8#ifdef TEST_NIGHTMARE_ENABLED
9static uint64_t fnv1a_string(uint64_t hash, const char *str) {
10 const char *value = str ? str : "";
11 return hash_fnv1a_64_update(hash, key: value, len: strlen(str: value));
12}
13
14void nightmare_finding_at(const struct nightmare_finding_site *site,
15 uint64_t discriminator, const char *fmt, ...) {
16 char msg[256];
17 va_list args;
18 va_start(args, fmt);
19 vsnprintf(msg, (int) sizeof(msg), fmt, args);
20 va_end(args);
21
22 uint64_t signature = HASH_FNV1A_64_OFFSET_BASIS;
23 signature = fnv1a_string(hash: signature, str: nightmare_runtime.ctx.nm
24 ? nightmare_runtime.ctx.nm->name
25 : "unknown");
26 signature = fnv1a_string(hash: signature, str: site->kind);
27 signature = fnv1a_string(hash: signature, str: site->file);
28 signature =
29 hash_fnv1a_64_update(hash: signature, key: &site->line, len: sizeof(site->line));
30 signature =
31 hash_fnv1a_64_update(hash: signature, key: &discriminator, len: sizeof(discriminator));
32
33 char sig[24];
34 char location[192];
35 snprintf(sig, (int) sizeof(sig), "%016lx", signature);
36 snprintf(location, (int) sizeof(location), "%s:%u", site->file, site->line);
37
38 nightmare_record_finding(record: &(struct nightmare_finding_record){
39 .kind = site->kind,
40 .tier =
41 site->tier == NIGHTMARE_TIER_CONFIDENT ? "confident" : "ambiguous",
42 .sig = sig,
43 .site = location,
44 .msg = msg,
45 });
46 atomic_inc_rlx(&nightmare_runtime.finding_count);
47}
48
49void nightmare_request_external_fail(const char *kind, uint64_t discriminator,
50 const char *fmt, ...) {
51 if (!atomic_load_acq(&nightmare_runtime.conc.active))
52 return;
53
54 char msg[256];
55 va_list args;
56 va_start(args, fmt);
57 vsnprintf(msg, (int) sizeof(msg), fmt, args);
58 va_end(args);
59
60 nightmare_finding_at(
61 site: &(const struct nightmare_finding_site){
62 .kind = kind,
63 .tier = NIGHTMARE_TIER_CONFIDENT,
64 .file = __RELFILE__,
65 .line = __LINE__,
66 },
67 discriminator, fmt: "%s", msg);
68
69 nightmare_publish_stop(reason: TEST_STOP_FAIL);
70}
71#else
72void nightmare_request_external_fail(const char *kind, uint64_t discriminator,
73 const char *fmt, ...) {
74 cc_ignore(kind, discriminator, fmt);
75}
76#endif
77