///|
pub(all) struct NativeStubSourceIncludeFact {
file : String
header : String
} derive(Eq, Debug)
///|
pub(all) struct NativeStubSourceIncludeRule {
file : String
required_includes : Array[String]
forbidden_includes : Array[String]
forbid_source_includes : Bool
} derive(Eq, Debug)
///|
pub(all) struct NativeStubSourceIncludePolicyReport {
rule_count : Int
actual_file_count : Int
missing_file_count : Int
extra_file_count : Int
required_include_count : Int
missing_required_include_count : Int
forbidden_include_count : Int
present_forbidden_include_count : Int
source_include_violation_count : Int
duplicate_include_fact_count : Int
replaces_file_reading : Bool
replaces_include_extraction : Bool
live_io_evidence : Bool
} derive(Eq, Debug)
///|
pub fn NativeStubSourceIncludePolicyReport::passes(
self : NativeStubSourceIncludePolicyReport,
) -> Bool {
self.rule_count > 0 &&
self.actual_file_count == self.rule_count &&
self.missing_file_count == 0 &&
self.extra_file_count == 0 &&
self.required_include_count > 0 &&
self.missing_required_include_count == 0 &&
self.present_forbidden_include_count == 0 &&
self.source_include_violation_count == 0 &&
self.duplicate_include_fact_count == 0 &&
!self.replaces_file_reading &&
!self.replaces_include_extraction &&
!self.live_io_evidence
}
///|
pub fn native_stub_source_include_rules() -> Array[NativeStubSourceIncludeRule] {
let rules : Array[NativeStubSourceIncludeRule] = []
push_source_include_rules(
rules,
[
"stub_common_status.c", "stub_common_handle.c", "stub_common_bytes.c", "stub_clock_windows.c",
"stub_clock_posix.c", "stub_clock_unsupported.c",
],
["stub_common.h"],
[],
)
push_source_include_rules(
rules,
["stub_pcap_common.c", "stub_pcap_writer.c"],
["stub_pcap.h"],
[],
)
push_source_include_rules(
rules,
[
"stub_frame_pool_common.c", "stub_frame_pool_lifecycle.c", "stub_frame_pool_state.c",
"stub_frame_pool_io.c",
],
["stub_frame_pool.h"],
[],
)
push_source_include_rules(
rules,
[
"stub_npcap_windows_loader.c", "stub_npcap_windows_listing.c", "stub_npcap_windows_common.c",
"stub_npcap_windows_live.c", "stub_npcap_windows_live_send.c", "stub_npcap_windows_live_filter.c",
"stub_npcap_windows_live_capture.c",
],
["stub_npcap_windows.h"],
[],
)
rules.push(
source_include_rule("stub_npcap_unsupported.c", ["stub_common.h"], [
"stub_npcap_windows.h", "stub_npcap_windows_loader.c", "stub_npcap_windows_listing.c",
"stub_npcap_windows_common.c", "stub_npcap_windows_live.c", "stub_npcap_windows_live_send.c",
"stub_npcap_windows_live_filter.c", "stub_npcap_windows_live_capture.c",
]),
)
push_source_include_rules(
rules,
[
"stub_raw_socket_linux_adapter.c", "stub_raw_socket_linux_send.c", "stub_raw_socket_linux_capture.c",
"stub_raw_socket_linux_list.c", "stub_raw_socket_linux_common.c",
],
["stub_raw_socket_linux.h"],
[],
)
rules.push(
source_include_rule("stub_raw_socket_unsupported.c", ["stub_common.h"], [
"stub_raw_socket_linux.h", "stub_raw_socket_linux_adapter.c", "stub_raw_socket_linux_common.c",
"stub_raw_socket_linux_send.c", "stub_raw_socket_linux_capture.c", "stub_raw_socket_linux_list.c",
]),
)
push_source_include_rules(
rules,
[
"stub_udp_windows_common.c", "stub_udp_windows_adapter.c", "stub_udp_windows_send.c",
"stub_udp_windows_recv.c",
],
["stub_udp_windows.h"],
[],
)
push_source_include_rules(
rules,
[
"stub_udp_posix_common.c", "stub_udp_posix_adapter.c", "stub_udp_posix_send.c",
"stub_udp_posix_recv.c",
],
["stub_udp_posix.h"],
[],
)
rules.push(
source_include_rule("stub_udp_unsupported.c", ["stub_common.h"], [
"stub_udp_windows.h", "stub_udp_posix.h", "stub_udp_windows_common.c", "stub_udp_windows_adapter.c",
"stub_udp_windows_send.c", "stub_udp_windows_recv.c", "stub_udp_posix_common.c",
"stub_udp_posix_adapter.c", "stub_udp_posix_send.c", "stub_udp_posix_recv.c",
]),
)
push_source_include_rules(
rules,
[
"stub_clock_millis_windows.c", "stub_clock_millis_posix.c", "stub_clock_millis_unsupported.c",
"stub_sleep_windows.c", "stub_sleep_posix.c", "stub_sleep_unsupported.c", "stub_rt_affinity_windows.c",
"stub_rt_affinity_unsupported.c",
],
["stub_common.h"],
[],
)
push_source_include_rules(
rules,
[
"stub_npcap_windows_local_mac.c", "stub_npcap_windows_nonblock.c", "stub_npcap_unsupported_live_ext.c",
],
["stub_npcap_windows.h"],
[],
)
push_source_include_rules(
rules,
[
"stub_raw_socket_linux_local_mac.c", "stub_raw_socket_linux_nonblock.c", "stub_raw_socket_unsupported_live_ext.c",
],
["stub_raw_socket_linux.h"],
[],
)
rules
}
///|
pub fn native_stub_expected_source_include_facts() -> Array[
NativeStubSourceIncludeFact,
] {
let facts : Array[NativeStubSourceIncludeFact] = []
for rule in native_stub_source_include_rules() {
for header in rule.required_includes {
facts.push({ file: rule.file, header })
}
}
facts
}
///|
pub fn native_stub_source_include_policy_report(
actual : Array[NativeStubSourceIncludeFact],
) -> NativeStubSourceIncludePolicyReport {
native_stub_source_include_policy_report_from_rules(
native_stub_source_include_rules(),
actual,
)
}
///|
pub fn native_stub_source_include_policy_report_from_rules(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> NativeStubSourceIncludePolicyReport {
{
rule_count: rules.length(),
actual_file_count: count_actual_include_files(actual),
missing_file_count: count_missing_include_files(rules, actual),
extra_file_count: count_extra_include_files(rules, actual),
required_include_count: count_required_includes(rules),
missing_required_include_count: count_missing_required_includes(
rules, actual,
),
forbidden_include_count: count_forbidden_includes(rules),
present_forbidden_include_count: count_present_forbidden_includes(
rules, actual,
),
source_include_violation_count: count_source_include_violations(
rules, actual,
),
duplicate_include_fact_count: count_duplicate_source_include_facts(actual),
replaces_file_reading: false,
replaces_include_extraction: false,
live_io_evidence: false,
}
}
///|
fn source_include_rule(
file : String,
required_includes : Array[String],
forbidden_includes : Array[String],
) -> NativeStubSourceIncludeRule {
{ file, required_includes, forbidden_includes, forbid_source_includes: true }
}
///|
fn push_source_include_rules(
rules : Array[NativeStubSourceIncludeRule],
files : Array[String],
required_includes : Array[String],
forbidden_includes : Array[String],
) -> Unit {
for file in files {
rules.push(source_include_rule(file, required_includes, forbidden_includes))
}
}
///|
fn count_actual_include_files(
facts : Array[NativeStubSourceIncludeFact],
) -> Int {
let files : Array[String] = []
for fact in facts {
if !source_include_contains_string(files, fact.file) {
files.push(fact.file)
}
}
files.length()
}
///|
fn count_missing_include_files(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> Int {
let mut count = 0
for rule in rules {
if !source_include_contains_file(actual, rule.file) {
count += 1
}
}
count
}
///|
fn count_extra_include_files(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> Int {
let seen : Array[String] = []
let mut count = 0
for fact in actual {
if !source_include_contains_string(seen, fact.file) {
seen.push(fact.file)
if !source_include_contains_rule_file(rules, fact.file) {
count += 1
}
}
}
count
}
///|
fn count_required_includes(rules : Array[NativeStubSourceIncludeRule]) -> Int {
let mut count = 0
for rule in rules {
count += rule.required_includes.length()
}
count
}
///|
fn count_forbidden_includes(rules : Array[NativeStubSourceIncludeRule]) -> Int {
let mut count = 0
for rule in rules {
count += rule.forbidden_includes.length()
}
count
}
///|
fn count_missing_required_includes(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> Int {
let mut count = 0
for rule in rules {
for header in rule.required_includes {
if !source_include_contains_fact(actual, rule.file, header) {
count += 1
}
}
}
count
}
///|
fn count_present_forbidden_includes(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> Int {
let mut count = 0
for rule in rules {
for header in rule.forbidden_includes {
if source_include_contains_fact(actual, rule.file, header) {
count += 1
}
}
}
count
}
///|
fn count_source_include_violations(
rules : Array[NativeStubSourceIncludeRule],
actual : Array[NativeStubSourceIncludeFact],
) -> Int {
let mut count = 0
for fact in actual {
if fact.header.has_suffix(".c") &&
source_include_rule_forbids_source_includes(rules, fact.file) {
count += 1
}
}
count
}
///|
fn count_duplicate_source_include_facts(
facts : Array[NativeStubSourceIncludeFact],
) -> Int {
let unique : Array[NativeStubSourceIncludeFact] = []
let mut count = 0
for fact in facts {
if source_include_contains_exact_fact(unique, fact) {
count += 1
} else {
unique.push(fact)
}
}
count
}
///|
fn source_include_rule_forbids_source_includes(
rules : Array[NativeStubSourceIncludeRule],
file : String,
) -> Bool {
for rule in rules {
if rule.file == file {
return rule.forbid_source_includes
}
}
false
}
///|
fn source_include_contains_rule_file(
rules : Array[NativeStubSourceIncludeRule],
file : String,
) -> Bool {
for rule in rules {
if rule.file == file {
return true
}
}
false
}
///|
fn source_include_contains_file(
facts : Array[NativeStubSourceIncludeFact],
file : String,
) -> Bool {
for fact in facts {
if fact.file == file {
return true
}
}
false
}
///|
fn source_include_contains_fact(
facts : Array[NativeStubSourceIncludeFact],
file : String,
header : String,
) -> Bool {
for fact in facts {
if fact.file == file && fact.header == header {
return true
}
}
false
}
///|
fn source_include_contains_exact_fact(
facts : Array[NativeStubSourceIncludeFact],
fact : NativeStubSourceIncludeFact,
) -> Bool {
for got in facts {
if got == fact {
return true
}
}
false
}
///|
fn source_include_contains_string(items : Array[String], item : String) -> Bool {
for got in items {
if got == item {
return true
}
}
false
}