import.nx
buildroot/runtime/import.nx
about
import.nx -- sovereign import preprocessor (replaces main.c logic).
Responsibility: given a root source path, return a single null-
terminated buffer containing every imported file's text spliced
inline, recursively, with each file visited at most once. Output
is exactly what parse_module consumes.
Subsystem boundary:
- syscalls.nx : file I/O (sys_read_file)
- str helpers : cstr_len / cstr_eq / u8_copy (below; no external dep)
- import.nx : path ops + import expansion (this file)
- nxc.nx : CLI driver that owns argv and calls expand_imports
Invariants (enforced, not hoped):
I1 Each canonicalised absolute path is expanded at most once --
the `seen` path table dedupes. Repeat imports emit nothing.
I2 Canonicalisation is pure textual (.. pops, . drops,
forward-slashes unified). No realpath(3). Identical output
on Windows and Linux/NishiOS.
I3 Import syntax: exactly `import "relative.nx"` at start-of-
line after optional whitespace. Nothing else parses as an
import; a substring match mid-line passes through.
I4 Buffer overruns fail loudly (negative return). Never
silently truncate -- correctness over convenience.
I5 Fixed capacity: MAX_IMPORTS distinct imports per tree;
paths up to IMPORT_PATH_LEN; output buffer sized by caller.
A build that needs more raises one constant in one place.
Complexity: O(N * F) where N is total source bytes across all
files and F is average imports-per-file. One read per file.
dependencies 1 imports · 2 importers
imports: syscalls.nx
imported by: _offc_nxc_small.nxnxc.nx
structs
| 268 | struct ExpandCtx { |
consts
| 36 | const MAX_IMPORTS: i64 = 64 |
| 37 | const IMPORT_PATH_LEN: i64 = 1024 |
| 40 | const ERR_IMPORTS_FULL: i64 = -1 |
| 41 | const ERR_READ_FAILED: i64 = -2 |
| 42 | const ERR_OUT_OVERFLOW: i64 = -3 |
| 43 | const ERR_BAD_IMPORT: i64 = -4 |
functions
| 47 | func cstr_len(s: *u8) -> i64 { |
| 53 | func cstr_eq(a: *u8, b: *u8) -> i64 {
called by 1: import_already |
| 64 | func u8_copy(dst: *u8, src: *u8, n: i64) -> i64 { |
| 71 | func ptr_at(p: *u8, delta: i64) -> *u8 { |
| 81 | func import_already(paths: *u8, n: i64, path: *u8) -> i64 { |
| 91 | func import_add(paths: *u8, n: i64, path: *u8) -> i64 { |
| 105 | func path_dir(path: *u8, out: *u8) -> i64 { |
| 122 | func join_path(dir: *u8, name: *u8, out: *u8) -> i64 { |
| 154 | func is_sep(b: i64) -> i64 {
called by 1: canonicalise_path |
| 164 | func canonicalise_path(path: *u8, out: *u8, scratch: *u8) -> i64 { |
| 250 | func starts_with_import(src: *u8, p: i64) -> i64 {
called by 1: expand_imports_inner |
| 284 | func expand_ctx_new(out: *u8, out_cap: i64) -> *ExpandCtx { |
| 304 | func out_push(ctx: *ExpandCtx, b: i64) -> i64 {
called by 1: expand_imports_inner |
| 314 | func out_append(ctx: *ExpandCtx, src: *u8, n: i64) -> i64 { |
| 330 | func is_func_main_line(src: *u8, p: i64) -> i64 {
called by 1: expand_imports_inner |
| 350 | func skip_func_main(src: *u8, p: i64) -> i64 {
called by 1: expand_imports_inner |
| 377 | func expand_imports_inner(ctx: *ExpandCtx, path: *u8, is_root: i64) -> i64; |
| 381 | func file_exists(path: *u8) -> i64 {
called by 1: try_subroot |
| 401 | func try_subroot(dir: *u8, subroot: *u8, ipath: *u8, |
| 432 | func try_resolve_import(dir: *u8, ipath: *u8, out: *u8) -> i64 { |
| 470 | func expand_imports(ctx: *ExpandCtx, path: *u8) -> i64 { |
| 474 | func expand_imports_inner(ctx: *ExpandCtx, path: *u8, is_root: i64) -> i64 { |