code wiki / _hdl_build / nx_vizsla_segment.nx
nx_vizsla_segment.nx source
↩ module page · 461 lines · 18147 B
1// nx_vizsla_segment.nx -- NISHI VIZSLA: SAVED SEGMENTS / SMART VIEWS (PRM/CRM depth). Operator 2026-06-23:
2// real-system depth. A real CRM lets you NAME and SAVE a multi-criteria filter ("Dallas leads", "colleagues
3// I haven't talked to") and re-run it as the data changes. This stores named segment definitions as ADDITIVE
4// CID records on the sovereign seg_store plane (latest-by-date wins per name; history kept, tamper-evident,
5// idempotent) and APPLIES them against the live "fld:" contact-field store (the same store nx_vizsla_contact
6// writes) with AND semantics over up to 3 criteria, latest-value-per-(contact,key) wins. Computed locally; no
7// cloud, no data sale. Deterministic (no clock in stdout).
8// define <prefix> <name> <date> <k1> <v1> [<k2> <v2> [<k3> <v3>]] -> "seg:" record {name,date,crit}
9// apply <prefix> <name> contacts whose CURRENT fields match ALL criteria of the latest def of <name>
10// list <prefix> every saved segment (latest def per name) + its criteria
11// crit packed "k1=v1|k2=v2|k3=v3" (keys/values are single tokens). license_tier: ORIGINAL
12import "nx_syscalls.nx"
13import "nx_canon_cid.nx"
14import "nx_seg_store.nx"
15const K_MAGIC_1970: i64 = 1970
16const K_MAGIC_146097: i64 = 146097
17const K_MAGIC_719468: i64 = 719468
18const K_MAGIC_4096: i64 = 4096
19const K_MAGIC_2048: i64 = 2048
20const K_MAGIC_1024: i64 = 1024
21const K_MAGIC_65536: i64 = 65536
22
23func vg_slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n }
24func vg_p(s: *u8) -> i64 { sys_write(1, s, vg_slen(s)); return 0 }
25
26func vg_eq(a: *u8, b: *u8) -> i64 {
27 var i: i64 = 0
28 var go: i64 = 1
29 while go == 1 { if a[i] != b[i] { return 0 } if a[i] == (0 as u8) { return 1 } i = i + 1 }
30 return 0
31}
32
33func vg_dup(s: *u8) -> *u8 {
34 let n: i64 = vg_slen(s)
35 let d: *u8 = sys_mmap(n + 2)
36 var i: i64 = 0
37 while i <= n { d[i] = s[i]; i = i + 1 }
38 return d
39}
40
41func vg_atoi(s: *u8) -> i64 {
42 var v: i64 = 0
43 var i: i64 = 0
44 while s[i] != (0 as u8) { let d: i64 = (s[i] as i64) - 48; if d >= 0 { if d <= 9 { v = v * 10 + d } } i = i + 1 }
45 return v
46}
47
48func vg_cat(dst: *u8, off: i64, s: *u8) -> i64 {
49 var i: i64 = 0
50 while s[i] != (0 as u8) { dst[off + i] = s[i]; i = i + 1 }
51 return off + i
52}
53
54func vg_catn(dst: *u8, off: i64, v: i64) -> i64 {
55 var o: i64 = off
56 var m: i64 = v
57 if m < 0 { dst[o] = 45 as u8; o = o + 1; m = 0 - m }
58 let t: *u8 = sys_mmap(28)
59 var k: i64 = 0
60 if m == 0 { t[0] = 48 as u8; k = 1 }
61 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
62 var i: i64 = 0
63 while i < k { dst[o + i] = t[k - 1 - i]; i = i + 1 }
64 return o + k
65}
66
67func vg_kmemeq(b: *u8, off: i64, n: i64, s: *u8) -> i64 {
68 if vg_slen(s) != n { return 0 }
69 var i: i64 = 0
70 while i < n { if b[off + i] != s[i] { return 0 } i = i + 1 }
71 return 1
72}
73
74func vg_iskind(b: *u8, koff: i64, kl: i64, pfx: *u8) -> i64 {
75 let pl: i64 = vg_slen(pfx)
76 if kl <= pl { return 0 }
77 return vg_kmemeq(b, koff, pl, pfx)
78}
79
80func vg_field(rec: *u8, rl: i64, want: *u8, out: *u8, cap: i64) -> i64 {
81 if rl < 8 { return 0 }
82 let nf: i64 = ss_r32(rec, 4)
83 var off: i64 = 8
84 var fi: i64 = 0
85 while fi < nf {
86 if off + 8 > rl { return 0 }
87 let kl: i64 = ss_r32(rec, off)
88 let koff: i64 = off + 4
89 let vl: i64 = ss_r32(rec, koff + kl)
90 let voff: i64 = koff + kl + 4
91 if vg_kmemeq(rec, koff, kl, want) == 1 {
92 var t: i64 = 0
93 while t < vl { if t < cap - 1 { out[t] = rec[voff + t] } t = t + 1 }
94 if t > cap - 1 { t = cap - 1 }
95 out[t] = 0 as u8
96 return 1
97 }
98 off = voff + vl
99 fi = fi + 1
100 }
101 return 0
102}
103
104func vg_datedays(s: *u8) -> i64 {
105 let nums: *i64 = sys_mmap(8 * 4) as *i64
106 var nn: i64 = 0
107 var cur: i64 = 0
108 var indig: i64 = 0
109 var i: i64 = 0
110 var go: i64 = 1
111 while go == 1 {
112 let c: i64 = s[i] as i64
113 var isd: i64 = 0
114 if c >= 48 { if c <= 57 { isd = 1 } }
115 if isd == 1 { cur = cur * 10 + (c - 48); indig = 1 }
116 if isd == 0 { if indig == 1 { if nn < 4 { nums[nn] = cur; nn = nn + 1 } cur = 0; indig = 0 } }
117 if c == 0 { go = 0 }
118 i = i + 1
119 }
120 if nn != 3 { return 0 - 1 }
121 var y: i64 = nums[0]
122 let m: i64 = nums[1]
123 let d: i64 = nums[2]
124 if y < K_MAGIC_1970 { return 0 - 1 }
125 if m < 1 { return 0 - 1 }
126 if m > 12 { return 0 - 1 }
127 if d < 1 { return 0 - 1 }
128 if d > 31 { return 0 - 1 }
129 if m <= 2 { y = y - 1 }
130 let era: i64 = y / 400
131 let yoe: i64 = y - era * 400
132 var mp: i64 = m - 3
133 if m <= 2 { mp = m + 9 }
134 let doy: i64 = (153 * mp + 2) / 5 + d - 1
135 let doe: i64 = yoe * 365 + yoe / 4 - yoe / 100 + doy
136 return era * K_MAGIC_146097 + doe - K_MAGIC_719468
137}
138
139// ----- crit packing / parsing -----
140func vg_flush(kb: *u8, ko: i64, vb: *u8, vo: i64, ck: *i64, cv: *i64, ncp: *i64) -> i64 {
141 kb[ko] = 0 as u8
142 vb[vo] = 0 as u8
143 if ko > 0 { if ncp[0] < 8 { ck[ncp[0]] = vg_dup(kb) as i64; cv[ncp[0]] = vg_dup(vb) as i64; ncp[0] = ncp[0] + 1 } }
144 return 0
145}
146
147// parse "k1=v1|k2=v2" -> ck[],cv[]; returns count
148func vg_parse_crit(crit: *u8, ck: *i64, cv: *i64) -> i64 {
149 let kb: *u8 = sys_mmap(256)
150 let vb: *u8 = sys_mmap(512)
151 let ncp: *i64 = sys_mmap(16) as *i64
152 ncp[0] = 0
153 var ko: i64 = 0
154 var vo: i64 = 0
155 var ineq: i64 = 0
156 var i: i64 = 0
157 var go: i64 = 1
158 while go == 1 {
159 let c: i64 = crit[i] as i64
160 if c == 0 { go = 0 }
161 else {
162 if c == 124 { vg_flush(kb, ko, vb, vo, ck, cv, ncp); ko = 0; vo = 0; ineq = 0 }
163 else {
164 if c == 61 { ineq = 1 }
165 else { if ineq == 0 { kb[ko] = c as u8; ko = ko + 1 } else { vb[vo] = c as u8; vo = vo + 1 } }
166 }
167 }
168 i = i + 1
169 }
170 vg_flush(kb, ko, vb, vo, ck, cv, ncp)
171 return ncp[0]
172}
173
174// ----- the seg-store fld: collection (composes nx_vizsla_contact's data plane) -----
175func vg_collect(prefix: *u8, rct: *i64, rkey: *i64, rval: *i64, rdate: *i64) -> i64 {
176 var n: i64 = 0
177 let segs: *i64 = sys_mmap(8 * 260) as *i64
178 let nseg: i64 = ss_manifest(prefix, segs)
179 let fa: *u8 = sys_mmap(128)
180 let fb: *u8 = sys_mmap(128)
181 let fc: *u8 = sys_mmap(256)
182 let fdt: *u8 = sys_mmap(128)
183 var s: i64 = 0
184 while s < nseg {
185 let path: *u8 = sys_mmap(512)
186 var po: i64 = 0
187 po = vg_cat(path, po, prefix); po = vg_cat(path, po, segs[s] as *u8); po = vg_cat(path, po, ".docs" as *u8)
188 path[po] = 0 as u8
189 let szp: *i64 = sys_mmap(16) as *i64
190 let b: *u8 = ss_readall(path, szp)
191 let sz: i64 = szp[0]
192 var j: i64 = 0
193 while j + 9 <= sz {
194 let kind: i64 = b[j]
195 let kl: i64 = ss_r32(b, j + 1)
196 let koff: i64 = j + 5
197 let vl: i64 = ss_r32(b, koff + kl)
198 let voff: i64 = koff + kl + 4
199 var take: i64 = 0
200 if kind == 1 { take = vg_iskind(b, koff, kl, "fld:" as *u8) }
201 if take == 1 {
202 let rec: *u8 = (b as i64 + voff) as *u8
203 if vg_field(rec, vl, "contact" as *u8, fa, 128) == 1 {
204 vg_field(rec, vl, "key" as *u8, fb, 128)
205 vg_field(rec, vl, "value" as *u8, fc, 256)
206 vg_field(rec, vl, "date" as *u8, fdt, 128)
207 if n < K_MAGIC_4096 { rct[n] = vg_dup(fa) as i64; rkey[n] = vg_dup(fb) as i64; rval[n] = vg_dup(fc) as i64; rdate[n] = vg_datedays(fdt); n = n + 1 }
208 }
209 }
210 j = voff + vl
211 }
212 s = s + 1
213 }
214 return n
215}
216
217func vg_latest(rct: *i64, rkey: *i64, rval: *i64, rdate: *i64, n: i64, contact: *u8, key: *u8, out: *u8, cap: i64) -> i64 {
218 var best: i64 = 0 - 1
219 var found: i64 = 0
220 var i: i64 = 0
221 while i < n {
222 if vg_eq(rct[i] as *u8, contact) == 1 { if vg_eq(rkey[i] as *u8, key) == 1 { if rdate[i] > best {
223 best = rdate[i]
224 var t: i64 = 0
225 let v: *u8 = rval[i] as *u8
226 while v[t] != (0 as u8) { if t < cap - 1 { out[t] = v[t] } t = t + 1 }
227 out[t] = 0 as u8
228 found = 1
229 } } }
230 i = i + 1
231 }
232 return found
233}
234
235// contact matches ALL criteria (latest value per key == criterion value) ?
236func vg_matches(rct: *i64, rkey: *i64, rval: *i64, rdate: *i64, n: i64, contact: *u8, ck: *i64, cv: *i64, nc: i64) -> i64 {
237 let lv: *u8 = sys_mmap(256)
238 var j: i64 = 0
239 while j < nc {
240 let got: i64 = vg_latest(rct, rkey, rval, rdate, n, contact, ck[j] as *u8, lv, 256)
241 if got == 0 { return 0 }
242 if vg_eq(lv, cv[j] as *u8) == 0 { return 0 }
243 j = j + 1
244 }
245 return 1
246}
247
248// ----- the seg: definition store (latest def per name) -----
249// find latest-dated crit for <name>; returns 1 + fills critout, else 0
250func vg_seg_latest(prefix: *u8, name: *u8, critout: *u8, cap: i64) -> i64 {
251 var best: i64 = 0 - 1
252 var found: i64 = 0
253 let segs: *i64 = sys_mmap(8 * 260) as *i64
254 let nseg: i64 = ss_manifest(prefix, segs)
255 let fn: *u8 = sys_mmap(128)
256 let fd: *u8 = sys_mmap(128)
257 let fcr: *u8 = sys_mmap(512)
258 var s: i64 = 0
259 while s < nseg {
260 let path: *u8 = sys_mmap(512)
261 var po: i64 = 0
262 po = vg_cat(path, po, prefix); po = vg_cat(path, po, segs[s] as *u8); po = vg_cat(path, po, ".docs" as *u8)
263 path[po] = 0 as u8
264 let szp: *i64 = sys_mmap(16) as *i64
265 let b: *u8 = ss_readall(path, szp)
266 let sz: i64 = szp[0]
267 var j: i64 = 0
268 while j + 9 <= sz {
269 let kind: i64 = b[j]
270 let kl: i64 = ss_r32(b, j + 1)
271 let koff: i64 = j + 5
272 let vl: i64 = ss_r32(b, koff + kl)
273 let voff: i64 = koff + kl + 4
274 var take: i64 = 0
275 if kind == 1 { take = vg_iskind(b, koff, kl, "seg:" as *u8) }
276 if take == 1 {
277 let rec: *u8 = (b as i64 + voff) as *u8
278 if vg_field(rec, vl, "name" as *u8, fn, 128) == 1 { if vg_eq(fn, name) == 1 {
279 vg_field(rec, vl, "date" as *u8, fd, 128)
280 let dd: i64 = vg_datedays(fd)
281 if dd > best { best = dd; vg_field(rec, vl, "crit" as *u8, fcr, 512); var t: i64 = 0; while fcr[t] != (0 as u8) { if t < cap - 1 { critout[t] = fcr[t] } t = t + 1 } critout[t] = 0 as u8; found = 1 }
282 } }
283 }
284 j = voff + vl
285 }
286 s = s + 1
287 }
288 return found
289}
290
291// ---------------- DEFINE ----------------
292func vg_cmd_define(argc: i64, argv: *i64) -> i64 {
293 if argc < 7 { vg_p("VIZSLA-SEGMENT define needs <prefix> <name> <date> <k> <v> [...] -- fail loud\n" as *u8); return 1 }
294 let np: i64 = argc - 5
295 if np - (np / 2) * 2 != 0 { vg_p("VIZSLA-SEGMENT define: criteria must be key/value pairs -- fail loud\n" as *u8); return 1 }
296 let nc: i64 = np / 2
297 if nc > 3 { vg_p("VIZSLA-SEGMENT define: at most 3 criteria -- fail loud\n" as *u8); return 1 }
298 let prefix: *u8 = argv[2] as *u8
299 let name: *u8 = argv[3] as *u8
300 let date: *u8 = argv[4] as *u8
301 if vg_datedays(date) < 0 { vg_p("VIZSLA-SEGMENT define: bad date (YYYY-MM-DD) -- fail loud\n" as *u8); return 1 }
302
303 // pack crit "k=v|k=v"
304 let crit: *u8 = sys_mmap(512)
305 var co: i64 = 0
306 var ci: i64 = 0
307 while ci < nc {
308 if ci > 0 { crit[co] = 124 as u8; co = co + 1 }
309 co = vg_cat(crit, co, argv[5 + ci * 2] as *u8)
310 crit[co] = 61 as u8; co = co + 1
311 co = vg_cat(crit, co, argv[6 + ci * 2] as *u8)
312 ci = ci + 1
313 }
314 crit[co] = 0 as u8
315
316 let keys: *i64 = sys_mmap(8 * 8) as *i64
317 let vals: *i64 = sys_mmap(8 * 8) as *i64
318 keys[0] = "kind" as *u8 as i64; keys[1] = "name" as *u8 as i64; keys[2] = "date" as *u8 as i64; keys[3] = "crit" as *u8 as i64
319 vals[0] = "seg" as *u8 as i64; vals[1] = name as i64; vals[2] = date as i64; vals[3] = crit as i64
320
321 let enc: *u8 = sys_mmap(K_MAGIC_2048)
322 let el: i64 = canon_encode(keys, vals, 4, enc)
323 let cid: *u8 = sys_mmap(96)
324 cid_of(enc, el, cid)
325 let kbuf: *u8 = sys_mmap(160)
326 var ko: i64 = 0
327 ko = vg_cat(kbuf, ko, "seg:" as *u8); ko = vg_cat(kbuf, ko, cid); kbuf[ko] = 0 as u8
328
329 var new: i64 = 1
330 let pp: *i64 = sys_mmap(16) as *i64
331 let ll: *i64 = sys_mmap(16) as *i64
332 if ss_get_idx(prefix, kbuf, pp, ll) == 1 { new = 0 }
333 var committed: i64 = 0
334 let segid: i64 = sys_now_us()
335 if new == 1 {
336 let wr: *i64 = ss_begin()
337 if ss_add(wr, 1, kbuf, enc, el) != 0 { vg_p("VIZSLA-SEGMENT define: writer full -- fail loud\n" as *u8); return 1 }
338 if ss_commit(prefix, wr, segid) != 0 { vg_p("VIZSLA-SEGMENT define: commit FAILED -- fail loud\n" as *u8); return 1 }
339 committed = 1
340 }
341
342 let rep: *u8 = sys_mmap(K_MAGIC_1024)
343 var o: i64 = 0
344 o = vg_cat(rep, o, "VIZSLA-SEGMENT-DEFINE name=" as *u8); o = vg_cat(rep, o, name)
345 o = vg_cat(rep, o, " criteria=" as *u8); o = vg_cat(rep, o, crit)
346 o = vg_cat(rep, o, " new=" as *u8); o = vg_catn(rep, o, new)
347 o = vg_cat(rep, o, " segment=" as *u8)
348 if committed == 1 { o = vg_cat(rep, o, "seg-" as *u8); o = vg_catn(rep, o, segid) } else { o = vg_cat(rep, o, "none" as *u8) }
349 o = vg_cat(rep, o, "\n" as *u8)
350 sys_write(1, rep, o)
351 return 0
352}
353
354// ---------------- APPLY ----------------
355func vg_cmd_apply(argc: i64, argv: *i64) -> i64 {
356 if argc < 4 { vg_p("VIZSLA-SEGMENT apply needs <prefix> <name> -- fail loud\n" as *u8); return 1 }
357 let prefix: *u8 = argv[2] as *u8
358 let name: *u8 = argv[3] as *u8
359 let crit: *u8 = sys_mmap(512)
360 if vg_seg_latest(prefix, name, crit, 512) == 0 { vg_p("VIZSLA-SEGMENT apply: segment not defined -- fail loud\n" as *u8); return 1 }
361 let ck: *i64 = sys_mmap(8 * 8) as *i64
362 let cv: *i64 = sys_mmap(8 * 8) as *i64
363 let nc: i64 = vg_parse_crit(crit, ck, cv)
364
365 let rct: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
366 let rkey: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
367 let rval: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
368 let rdate: *i64 = sys_mmap(8 * K_MAGIC_4096) as *i64
369 let n: i64 = vg_collect(prefix, rct, rkey, rval, rdate)
370
371 let seen: *i64 = sys_mmap(8 * K_MAGIC_1024) as *i64
372 var nseen: i64 = 0
373 let rep: *u8 = sys_mmap(K_MAGIC_65536)
374 var o: i64 = 0
375 var matched: i64 = 0
376 var i: i64 = 0
377 while i < n {
378 var dup: i64 = 0
379 var k: i64 = 0
380 while k < nseen { if vg_eq(seen[k] as *u8, rct[i] as *u8) == 1 { dup = 1; k = nseen } k = k + 1 }
381 if dup == 0 {
382 if nseen < K_MAGIC_1024 { seen[nseen] = rct[i]; nseen = nseen + 1 }
383 if vg_matches(rct, rkey, rval, rdate, n, rct[i] as *u8, ck, cv, nc) == 1 {
384 o = vg_cat(rep, o, "VIZSLA-SEGMENT-MATCH name=" as *u8); o = vg_cat(rep, o, name)
385 o = vg_cat(rep, o, " contact=" as *u8); o = vg_cat(rep, o, rct[i] as *u8); o = vg_cat(rep, o, "\n" as *u8)
386 matched = matched + 1
387 }
388 }
389 i = i + 1
390 }
391 o = vg_cat(rep, o, "VIZSLA-SEGMENT-VERDICT name=" as *u8); o = vg_cat(rep, o, name)
392 o = vg_cat(rep, o, " criteria=" as *u8); o = vg_cat(rep, o, crit)
393 o = vg_cat(rep, o, " matched=" as *u8); o = vg_catn(rep, o, matched); o = vg_cat(rep, o, "\n" as *u8)
394 sys_write(1, rep, o)
395 return 0
396}
397
398// ---------------- LIST ----------------
399func vg_cmd_list(argc: i64, argv: *i64) -> i64 {
400 if argc < 3 { vg_p("VIZSLA-SEGMENT list needs <prefix> -- fail loud\n" as *u8); return 1 }
401 let prefix: *u8 = argv[2] as *u8
402 let segs: *i64 = sys_mmap(8 * 260) as *i64
403 let nseg: i64 = ss_manifest(prefix, segs)
404 let names: *i64 = sys_mmap(8 * 512) as *i64
405 var nn: i64 = 0
406 let fn: *u8 = sys_mmap(128)
407 var s: i64 = 0
408 while s < nseg {
409 let path: *u8 = sys_mmap(512)
410 var po: i64 = 0
411 po = vg_cat(path, po, prefix); po = vg_cat(path, po, segs[s] as *u8); po = vg_cat(path, po, ".docs" as *u8)
412 path[po] = 0 as u8
413 let szp: *i64 = sys_mmap(16) as *i64
414 let b: *u8 = ss_readall(path, szp)
415 let sz: i64 = szp[0]
416 var j: i64 = 0
417 while j + 9 <= sz {
418 let kind: i64 = b[j]
419 let kl: i64 = ss_r32(b, j + 1)
420 let koff: i64 = j + 5
421 let vl: i64 = ss_r32(b, koff + kl)
422 let voff: i64 = koff + kl + 4
423 var take: i64 = 0
424 if kind == 1 { take = vg_iskind(b, koff, kl, "seg:" as *u8) }
425 if take == 1 {
426 let rec: *u8 = (b as i64 + voff) as *u8
427 if vg_field(rec, vl, "name" as *u8, fn, 128) == 1 {
428 var dup: i64 = 0
429 var k: i64 = 0
430 while k < nn { if vg_eq(names[k] as *u8, fn) == 1 { dup = 1; k = nn } k = k + 1 }
431 if dup == 0 { if nn < 512 { names[nn] = vg_dup(fn) as i64; nn = nn + 1 } }
432 }
433 }
434 j = voff + vl
435 }
436 s = s + 1
437 }
438 let rep: *u8 = sys_mmap(K_MAGIC_65536)
439 var o: i64 = 0
440 let crit: *u8 = sys_mmap(512)
441 var ii: i64 = 0
442 while ii < nn {
443 vg_seg_latest(prefix, names[ii] as *u8, crit, 512)
444 o = vg_cat(rep, o, "VIZSLA-SEGMENT name=" as *u8); o = vg_cat(rep, o, names[ii] as *u8)
445 o = vg_cat(rep, o, " criteria=" as *u8); o = vg_cat(rep, o, crit); o = vg_cat(rep, o, "\n" as *u8)
446 ii = ii + 1
447 }
448 o = vg_cat(rep, o, "VIZSLA-SEGMENT-LIST segments=" as *u8); o = vg_catn(rep, o, nn); o = vg_cat(rep, o, "\n" as *u8)
449 sys_write(1, rep, o)
450 return 0
451}
452
453func main(argc: i64, argv: *i64) -> i64 {
454 if argc < 2 { vg_p("VIZSLA-SEGMENT usage: define|apply|list -- fail loud\n" as *u8); return 1 }
455 let cmd: *u8 = argv[1] as *u8
456 if vg_eq(cmd, "define" as *u8) == 1 { return vg_cmd_define(argc, argv) }
457 if vg_eq(cmd, "apply" as *u8) == 1 { return vg_cmd_apply(argc, argv) }
458 if vg_eq(cmd, "list" as *u8) == 1 { return vg_cmd_list(argc, argv) }
459 vg_p("VIZSLA-SEGMENT unknown command (define|apply|list) -- fail loud\n" as *u8)
460 return 1
461}