nx_wflow_text_owned_candidate_t278.nx source
↩ module page · 134 lines · 6363 B
1// Owned variable substitution over one immutable ledger snapshot.
2// Allocation follows measured output; compatibility wrappers never return partial success.
3struct WfVarSpan {start:i64,len:i64,found:i64}
4struct WfOwnedText {data:*u8,len:i64,bytes:i64,status:i64}
5const WF_TEXT_I64_MAX:i64=9223372036854775807
6func wf_text_match(buf:*u8,at:i64,end:i64,text:*u8,n:i64)->i64{
7 if at<0{return 0};if n<0{return 0};if at>end{return 0};if n>end-at{return 0}
8 var i:i64=0;while i<n{if buf[at+i]!=text[i]{return 0};i=i+1};return 1
9}
10func wf_var_span(buf:*u8,n:i64,rid:*u8,key:*u8,kn:i64,out:*WfVarSpan)->i64{
11 out.start=0;out.len=0;out.found=0
12 let rn:i64=slen(rid);var ls:i64=0
13 while ls<n{
14 var le:i64=ls;while le<n{if buf[le]==(10 as u8){break};le=le+1}
15 var at:i64=ls
16 var matched:i64=wf_text_match(buf,at,le,"WFVAR rid=",slen("WFVAR rid="))
17 if matched==1{at=at+slen("WFVAR rid=");matched=wf_text_match(buf,at,le,rid,rn)}
18 if matched==1{at=at+rn;matched=wf_text_match(buf,at,le," k=",slen(" k="))}
19 if matched==1{at=at+slen(" k=");matched=wf_text_match(buf,at,le,key,kn)}
20 if matched==1{at=at+kn;matched=wf_text_match(buf,at,le," v=",slen(" v="))}
21 if matched==1{at=at+slen(" v=");out.start=at;out.len=le-at;out.found=1}
22 ls=le+1
23 }
24 return out.found
25}
26func wf_text_new(n:i64,status:i64)->*WfOwnedText{
27 if n<0{return 0 as *WfOwnedText};if n==WF_TEXT_I64_MAX{return 0 as *WfOwnedText}
28 let out:*WfOwnedText=sys_mmap_try(__size_of(WfOwnedText)) as *WfOwnedText
29 if (out as i64)<=0{return 0 as *WfOwnedText}
30 out.data=sys_mmap_try(n+1)
31 if (out.data as i64)<=0{sys_munmap_direct(out as *u8,__size_of(WfOwnedText));return 0 as *WfOwnedText}
32 out.len=n;out.bytes=n+1;out.status=status;out.data[n]=0;return out
33}
34func wf_text_free(out:*WfOwnedText)->i64{
35 if out==(0 as *WfOwnedText){return 0}
36 let rc:i64=sys_munmap_direct(out.data,out.bytes)
37 let rr:i64=sys_munmap_direct(out as *u8,__size_of(WfOwnedText))
38 if rc!=0{return 0-1};return rr
39}
40func wf_var_owned(cx:*i64,rid:*u8,key:*u8)->*WfOwnedText{
41 let sz:*i64=sys_mmap_try(__size_of(i64)) as *i64
42 if (sz as i64)<=0{return 0 as *WfOwnedText}
43 let buf:*u8=wf_readall(cx[2] as *u8,sz)
44 if buf==(0 as *u8){sys_munmap_direct(sz as *u8,__size_of(i64));return 0 as *WfOwnedText}
45 let span:*WfVarSpan=sys_mmap_try(__size_of(WfVarSpan)) as *WfVarSpan
46 if (span as i64)<=0{sys_munmap(buf,WF_LEDCAP);sys_munmap_direct(sz as *u8,__size_of(i64));return 0 as *WfOwnedText}
47 let found:i64=wf_var_span(buf,sz[0],rid,key,slen(key),span)
48 let out:*WfOwnedText=wf_text_new(span.len,found)
49 if out!=(0 as *WfOwnedText){var i:i64=0;while i<span.len{out.data[i]=buf[span.start+i];i=i+1}}
50 sys_munmap_direct(span as *u8,__size_of(WfVarSpan));sys_munmap(buf,WF_LEDCAP);sys_munmap_direct(sz as *u8,__size_of(i64))
51 return out
52}
53func wf_subst_pass(buf:*u8,n:i64,rid:*u8,src:*u8,span:*WfVarSpan,out:*u8,cap:i64)->i64{
54 var i:i64=0;var count:i64=0
55 while src[i]!=(0 as u8){
56 var data:*u8=((src as i64)+i) as *u8
57 var len:i64=1
58 if src[i]==(123 as u8){
59 let start:i64=i+1;var end:i64=start
60 while src[end]!=(0 as u8){if src[end]==(125 as u8){break};end=end+1}
61 if src[end]==(0 as u8){return 0-1}
62 if wf_var_span(buf,n,rid,((src as i64)+start) as *u8,end-start,span)!=1{return 0-1}
63 data=((buf as i64)+span.start) as *u8;len=span.len;i=end+1
64 }else{i=i+1}
65 if len>WF_TEXT_I64_MAX-count{return 0-1}
66 if out!=(0 as *u8){
67 if count>cap{return 0-1};if len>cap-count{return 0-1}
68 var j:i64=0;while j<len{out[count+j]=data[j];j=j+1}
69 }
70 count=count+len
71 }
72 return count
73}
74func wf_subst_owned(cx:*i64,rid:*u8,src:*u8)->*WfOwnedText{
75 let sz:*i64=sys_mmap_try(__size_of(i64)) as *i64
76 if (sz as i64)<=0{return 0 as *WfOwnedText}
77 let buf:*u8=wf_readall(cx[2] as *u8,sz)
78 if buf==(0 as *u8){sys_munmap_direct(sz as *u8,__size_of(i64));return 0 as *WfOwnedText}
79 let span:*WfVarSpan=sys_mmap_try(__size_of(WfVarSpan)) as *WfVarSpan
80 if (span as i64)<=0{sys_munmap(buf,WF_LEDCAP);sys_munmap_direct(sz as *u8,__size_of(i64));return 0 as *WfOwnedText}
81 let n:i64=wf_subst_pass(buf,sz[0],rid,src,span,0 as *u8,0)
82 var out:*WfOwnedText=0 as *WfOwnedText
83 if n>=0{
84 out=wf_text_new(n,1)
85 if out!=(0 as *WfOwnedText){
86 if wf_subst_pass(buf,sz[0],rid,src,span,out.data,n)!=n{wf_text_free(out);out=0 as *WfOwnedText}
87 }
88 }
89 sys_munmap_direct(span as *u8,__size_of(WfVarSpan));sys_munmap(buf,WF_LEDCAP);sys_munmap_direct(sz as *u8,__size_of(i64))
90 if out==(0 as *WfOwnedText){p("WFLOW substitution ERROR unresolved input or allocation; no partial result\n")}
91 return out
92}
93
94func wf_text_slice(src:*u8,start:i64,n:i64)->*WfOwnedText{
95 let out:*WfOwnedText=wf_text_new(n,1)
96 if out==(0 as *WfOwnedText){return out}
97 var i:i64=0;while i<n{out.data[i]=src[start+i];i=i+1};return out
98}
99func wf_text_decimal(v:i64)->*WfOwnedText{
100 if v<0{return 0 as *WfOwnedText}
101 var n:i64=1;var q:i64=v;while q>=10{n=n+1;q=q/10}
102 let out:*WfOwnedText=wf_text_new(n,1)
103 if out==(0 as *WfOwnedText){return out}
104 q=v;var i:i64=n
105 while i>0{i=i-1;out.data[i]=(48+q%10) as u8;q=q/10};return out
106}
107
108struct WfRunFields {fid:*u8,index:*u8,action:*u8,channel:*u8,arg:*u8,retry:*u8,condition:*u8,onfail:*u8}
109struct WfRunScratch {fields:*WfRunFields,cap:i64,prepared:*WfOwnedText}
110func wf_run_scratch_free(s:*WfRunScratch)->i64{
111 if s==(0 as *WfRunScratch){return 0}
112 var rc:i64=wf_text_free(s.prepared)
113 if s.fields!=(0 as *WfRunFields){
114 let slots:*i64=s.fields as *i64;var i:i64=0
115 while i<__size_of(WfRunFields)/__size_of(i64){if slots[i]>0{if sys_munmap_direct(slots[i] as *u8,s.cap)!=0{rc=WF_EVIDENCE_ERROR}};i=i+1}
116 if sys_munmap_direct(s.fields as *u8,__size_of(WfRunFields))!=0{rc=WF_EVIDENCE_ERROR}
117 }
118 if sys_munmap_direct(s as *u8,__size_of(WfRunScratch))!=0{rc=WF_EVIDENCE_ERROR};return rc
119}
120func wf_run_scratch_new(cap:i64)->*WfRunScratch{
121 if cap<=0{return 0 as *WfRunScratch}
122 let s:*WfRunScratch=sys_mmap_try(__size_of(WfRunScratch)) as *WfRunScratch
123 if (s as i64)<=0{return 0 as *WfRunScratch}
124 s.cap=cap;s.prepared=0 as *WfOwnedText
125 s.fields=sys_mmap_try(__size_of(WfRunFields)) as *WfRunFields
126 if (s.fields as i64)<=0{s.fields=0 as *WfRunFields;wf_run_scratch_free(s);return 0 as *WfRunScratch}
127 let slots:*i64=s.fields as *i64;var i:i64=0
128 while i<__size_of(WfRunFields)/__size_of(i64){
129 let buf:*u8=sys_mmap_try(cap)
130 if (buf as i64)<=0{wf_run_scratch_free(s);return 0 as *WfRunScratch}
131 slots[i]=buf as i64;i=i+1
132 }
133 return s
134}