summaryrefslogtreecommitdiff
path: root/src/source_manifest.zig
blob: e2cc312c7b92ae9c842dc0bd70d22785dc97e852 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//! The virtual filesystem: pardes's own source, embedded, as an ALLOWLIST.
//!
//! This is the default filesystem — what a host that implements no file method
//! reads and writes, and the only one the browser has ever had. It replaced a
//! build-time generator that embedded every tracked `.zig` file: 64 files and
//! 2.4 MB of generated Zig, rediscovered on every consumer build because the
//! tracked set can change without any known input changing.
//!
//! An allowlist instead, for the reason the generator's own comment gave away:
//! nothing needs all of them. What earns a place here is a file that explains
//! how pardes works to someone reading it inside pardes — the core, the host
//! seam, the keymap, the build. `src/pardes.zig` alone is 722 KB of the total,
//! and it is the one file worth that: it IS the program.
//!
//! Paths are as a user would type them, repo-root-relative, which is what
//! `look` resolves a click against.

//! ON THE P4 the allowlist is EMPTY, and that is the whole difference: the
//! table is ~0.95 MiB of rodata against a 1.5 MiB flash partition, and the
//! firmware's filesystem is the serial host's, reached through the Host
//! vtable. The API is unchanged — `all` is a zero-length array and `find`
//! answers null — so every caller compiles identically and simply finds
//! nothing embedded.

pub const Source = struct { path: []const u8, contents: []const u8 };

/// A slice, not an array: the P4 table is empty and every consumer only ever
/// iterates or takes `.len`.
pub const all: []const Source = if (@import("pardes_config").platform == .p4) &.{} else &allowlist;

const allowlist = [_]Source{
    .{ .path = "build.zig", .contents = @embedFile("root-build.zig") },
    .{ .path = "build.zig.zon", .contents = @embedFile("root-build.zig.zon") },
    .{ .path = "src/pardes.zig", .contents = @embedFile("pardes.zig") },
    .{ .path = "src/host.zig", .contents = @embedFile("host.zig") },
    .{ .path = "src/config.zig", .contents = @embedFile("config.zig") },
    .{ .path = "src/main.zig", .contents = @embedFile("main.zig") },
    .{ .path = "src/builtins.zig", .contents = @embedFile("builtins.zig") },
    .{ .path = "src/grammar_manifest.zig", .contents = @embedFile("grammar_manifest.zig") },
    .{ .path = "src/source_manifest.zig", .contents = @embedFile("source_manifest.zig") },
    .{ .path = "src/CHANGELOG.md", .contents = @embedFile("CHANGELOG.md") },
};

/// The written-file override wins, then the allowlist. Callers own no memory
/// here: every byte is static or lives in the Fallback that answered.
pub fn find(path: []const u8) ?[]const u8 {
    for (all) |s| if (eql(s.path, path)) return s.contents;
    return null;
}

fn eql(a: []const u8, b: []const u8) bool {
    if (a.len != b.len) return false;
    for (a, b) |x, y| if (x != y) return false;
    return true;
}