nx_dir_test.nx source
↩ module page · 117 lines · 4374 B
1// nx_dir_test.nx -- smoke for nx_dir directory walker.
2//
3// Opens the current working directory and walks every entry,
4// asserting:
5// - verdict == NX_DIR_OK (or TRUNCATED if the directory is huge)
6// - at least one row was emitted
7// - default include_dotlike=0 skipped "." and ".." (n_skipped >= 2)
8// - nx_dir_name_ends_with returns 1 for matching suffix, 0 otherwise
9
10import "syscalls.nx"
11import "nx_dir.nx"
12
13const NX_TEST_DIR_ROWS_CAP: i64 = 4096
14const NX_TEST_DIR_ARENA_BYTES: i64 = 524288 // 512 KiB names arena
15
16func main() -> i64 {
17 // Enumerate the runtime/ directory (relative to whatever cwd the
18 // smoke runner invokes us under -- nxc2/ for bench_l2_smoke).
19 // runtime/ has hundreds of .nx siblings so the suffix-filter
20 // assertion below is well-grounded.
21 let rt: *u8 = sys_mmap(16)
22 rt[0] = 0x72; rt[1] = 0x75; rt[2] = 0x6E; rt[3] = 0x74 // "runt"
23 rt[4] = 0x69; rt[5] = 0x6D; rt[6] = 0x65; rt[7] = 0 // "ime\0"
24
25 let rows_raw: *u8 = sys_mmap(NX_TEST_DIR_ROWS_CAP * NX_DIR_ROW_BYTES)
26 let rows: *NxDirRow = rows_raw as *NxDirRow
27
28 let arena: *u8 = sys_mmap(NX_TEST_DIR_ARENA_BYTES)
29
30 let res_raw: *u8 = sys_mmap(NX_DIR_RESULT_BYTES)
31 let res: *NxDirResult = res_raw as *NxDirResult
32
33 let v: i64 = nx_dir_list(
34 rt, rows, NX_TEST_DIR_ROWS_CAP,
35 arena, NX_TEST_DIR_ARENA_BYTES,
36 0, // include_dotlike = 0 (skip . and ..)
37 res)
38
39 // Accept OK or TRUNCATED; TRUNCATED is normal for a fat dir.
40 if v != NX_DIR_OK {
41 if v != NX_DIR_TRUNCATED { return __syscall(93, 1, 0, 0, 0, 0, 0) }
42 }
43
44 if res.n_filled <= 0 { return __syscall(93, 2, 0, 0, 0, 0, 0) }
45
46 // "." and ".." must have been skipped (or we got TRUNCATED before
47 // them, which is impossible because they're the first entries
48 // returned by getdents64).
49 if res.n_skipped < 2 { return __syscall(93, 3, 0, 0, 0, 0, 0) }
50
51 // Walk the rows once asserting no row has is_dotlike=1 (filter worked).
52 var i: i64 = 0
53 var iter: i64 = 0
54 var verdict: i64 = 0
55 while verdict == 0 && iter < NX_TEST_DIR_ROWS_CAP {
56 if i >= res.n_filled { verdict = 1 }
57 if verdict == 0 {
58 let r: *NxDirRow = nx_dir_row_at(rows, i)
59 if r.is_dotlike == 1 { return __syscall(93, 4, 0, 0, 0, 0, 0) }
60 if r.name_len <= 0 { return __syscall(93, 5, 0, 0, 0, 0, 0) }
61 // names must be NUL-terminated past name_len
62 if r.name_ptr[r.name_len] != 0 { return __syscall(93, 6, 0, 0, 0, 0, 0) }
63 i = i + 1
64 iter = iter + 1
65 }
66 }
67
68 // Test the suffix filter: ".nx" suffix should match if at least
69 // one .nx file exists in the current dir (this test file IS .nx,
70 // so guaranteed at least one).
71 let sfx_nx: *u8 = sys_mmap(8)
72 sfx_nx[0] = 0x2E; sfx_nx[1] = 0x6E; sfx_nx[2] = 0x78; sfx_nx[3] = 0 // ".nx"
73
74 var nx_count: i64 = 0
75 var j: i64 = 0
76 var j_iter: i64 = 0
77 var j_verdict: i64 = 0
78 while j_verdict == 0 && j_iter < NX_TEST_DIR_ROWS_CAP {
79 if j >= res.n_filled { j_verdict = 1 }
80 if j_verdict == 0 {
81 let r: *NxDirRow = nx_dir_row_at(rows, j)
82 if nx_dir_name_ends_with(r.name_ptr, r.name_len, sfx_nx, 3) == 1 {
83 nx_count = nx_count + 1
84 }
85 j = j + 1
86 j_iter = j_iter + 1
87 }
88 }
89
90 // Must find at least nx_dir_test.nx itself + nx_dir.nx + many siblings.
91 if nx_count < 2 { return __syscall(93, 7, 0, 0, 0, 0, 0) }
92
93 // Negative-case suffix: ".xyzpdq" matches nothing.
94 let sfx_neg: *u8 = sys_mmap(16)
95 sfx_neg[0] = 0x2E; sfx_neg[1] = 0x78; sfx_neg[2] = 0x79
96 sfx_neg[3] = 0x7A; sfx_neg[4] = 0x70; sfx_neg[5] = 0x64; sfx_neg[6] = 0x71
97 sfx_neg[7] = 0
98
99 var neg_count: i64 = 0
100 var k: i64 = 0
101 var k_iter: i64 = 0
102 var k_verdict: i64 = 0
103 while k_verdict == 0 && k_iter < NX_TEST_DIR_ROWS_CAP {
104 if k >= res.n_filled { k_verdict = 1 }
105 if k_verdict == 0 {
106 let r: *NxDirRow = nx_dir_row_at(rows, k)
107 if nx_dir_name_ends_with(r.name_ptr, r.name_len, sfx_neg, 7) == 1 {
108 neg_count = neg_count + 1
109 }
110 k = k + 1
111 k_iter = k_iter + 1
112 }
113 }
114 if neg_count != 0 { return __syscall(93, 8, 0, 0, 0, 0, 0) }
115
116 return 0
117}