-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathybot_dynamic_buffer.xtm
321 lines (262 loc) · 10.2 KB
/
ybot_dynamic_buffer.xtm
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
(sys:load-preload-check 'ybot_dynamic_buffer)
(define *xtmlib-ybot_dynamic_buffer-loaded* #f)
(impc:aot:suppress-aot-do
(sys:load "libs/contrib/ybot/ybot_base.xtm"))
(impc:aot:insert-forms
(sys:load "libs/contrib/ybot/ybot_base.xtm" 'quiet))
;;;;;;;;;;;;;;;;;;;; This section has been moved into ybot_base.xtm ;;;;;;;;;;;;;;;;;;
;; Extra string functions
;; (bind-func cstring:[i8*,i8]*
;; (lambda (c)
;; (let ((p:i8* (zalloc 2)))
;; (pset! p 0 c)
;; (pset! p 1 0)
;; p)))
;; (bind-func to_lower:[i8,i8]*
;; (lambda (c)
;; (if (and (< (i64toi8 64) c) (< c (i64toi8 91)))
;; (+ c (i64toi8 32))
;; c)))
;; (bind-func to_upper:[i8,i8]*
;; (lambda (c)
;; (if (and (< (i64toi8 96) c) (< c (i64toi8 123)))
;; (- c (i64toi8 32))
;; c)))
;; (bind-func lower:[String*,i8*]*
;; (lambda (cstr)
;; (let* ((i:i64 0) (n:i64 (strlen cstr))
;; (buffer:i8* (zalloc (+ n 1))))
;; (dotimes (i n)
;; (pset! buffer i (to_lower (pref cstr i))))
;; (pset! buffer n 0)
;; (String buffer))))
;; (bind-func lower:[String*,String*]*
;; (lambda (str:String*)
;; (let ((cstr:i8* (cstring str)))
;; (lower:[String*,i8*]* cstr))))
;; (bind-func upper:[String*,i8*]*
;; (lambda (cstr)
;; (let* ((i:i64 0) (n:i64 (strlen cstr))
;; (buffer:i8* (zalloc (+ n 1))))
;; (dotimes (i n)
;; (pset! buffer i (to_upper (pref cstr i))))
;; (pset! buffer n 0)
;; (String buffer))))
;; (bind-func upper:[String*,String*]*
;; (lambda (str:String*)
;; (let ((cstr:i8* (cstring str)))
;; (upper:[String*,i8*]* cstr))))
;; (bind-func print_hex:[void,String*]*
;; (lambda (str)
;; (let ((i:i64 0)
;; (n:i64 (length str))
;; (data:i8* (tref str 1)))
;; (dotimes (i (- n 1))
;; (printf "%02X " (pref data i)))
;; (printf "%02X" (pref data (- n 1)))
;; void)))
;; (bind-func print_sanitised:[void,String*]*
;; (lambda (str:String*)
;; (cond
;; ((non-null str)
;; (let ((i:i64 0) (n:i64 (length str))
;; (data:i8* (tref str 1)))
;; (dotimes (i n)
;; (let ((c:i8 (pref data i)))
;; (cond
;; ((< 31:i8 c)
;; (printf "%c" c))
;; (else
;; (printf "[%02X]" c)))))
;; void))
;; (else void))))
;; ;; override base.xtm string comparison, so that it doesn't crash on null
;; (bind-func equal
;; (lambda (s1:String* s2:String*)
;; (if (or (null? s1) (null? s2))
;; 0:i1
;; (if (= (strcmp (tref s1 1) (tref s2 1)) 0)
;; 1:i1 0:i1))))
;; (bind-func safe_cstr:[i8*,String*]*
;; (lambda (str:String*)
;; (cond
;; ((non-null str)
;; (cstring str))
;; (else
;; (zalloc)))))
;; ;;;;;;;;;;;;;;;; String parsing utilities ;;;;;;;;;;;;;
;; (bind-func first_word:[String*,String*]*
;; (lambda (str)
;; (let ((words (regex_split "[^a-zA-Z0-9]+" str)))
;; (if (non-empty words)
;; (car words)
;; null))))
;; (bind-func last_word:[String*,String*]*
;; (lambda (str)
;; (let ((words (regex_split "[^a-zA-Z0-9]+" str)))
;; (if (non-empty words)
;; (car (reverse words))
;; null))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;; Dynamic Buffer ;;;;;;;;;;;;;;;;;
;; StringStreamBuffer: data, length, capacity
(bind-type StringStreamBuffer <i8*,i64,i64> (constructor? . #f) (printer?. #f))
(bind-func StringStreamBuffer:[StringStreamBuffer*,i8*,i64,i64]*
(lambda (data lngth capacity)
(let ((output:StringStreamBuffer* (alloc)))
(tset! output 0 data)
(tset! output 1 lngth)
(tset! output 2 capacity)
output)))
(bind-func StringStreamBuffer:[StringStreamBuffer*,i64]*
(lambda (capacity)
(let ((output:StringStreamBuffer* (alloc))
(data:i8* (zalloc (+ capacity 1))))
(tset! output 0 data)
(tset! output 1 0)
(tset! output 2 capacity)
output)))
(bind-func StringStreamBuffer:[StringStreamBuffer*,StringStreamBuffer*,i64]*
(lambda (buffer:StringStreamBuffer* new_capacity:i64)
(let* ((new_buffer:StringStreamBuffer* (alloc))
(data:i8* (tref buffer 0))
(current_length:i64 (tref buffer 1))
(current_capacity:i64 (tref buffer 2))
(capacity:i64 (if (< current_capacity new_capacity) current_capacity new_capacity))
(new_length:i64 (if (< current_length new_capacity) current_length new_capacity))
(new_data:i8* (zalloc (+ new_capacity 1))))
(memcpy new_data data capacity)
(pset! new_data (+ new_length 1) (i64toi8 0))
(tset! new_buffer 0 new_data)
(tset! new_buffer 1 new_length)
(tset! new_buffer 2 new_capacity)
new_buffer)))
(bind-func SSB:[StringStreamBuffer*,i8*]*
(lambda (cstr)
(let*
((current_length (strlen cstr))
(new_length current_length)
(new_capacity current_length)
(new_data:i8* (zalloc (+ new_capacity 1)))
(new_buffer:StringStreamBuffer* (StringStreamBuffer new_data new_length new_capacity)))
(memcpy new_data cstr new_length)
(pset! new_data (+ new_length 1) (i64toi8 0))
new_buffer)))
(bind-func SSB:[StringStreamBuffer*,i8*,i64]*
(lambda (cstr new_capacity)
(let*
((current_length (strlen cstr))
(new_length (if (< current_length new_capacity) current_length new_capacity))
(new_data:i8* (zalloc (+ new_capacity 1)))
(new_buffer:StringStreamBuffer* (StringStreamBuffer new_data new_length new_capacity)))
(memcpy new_data cstr new_length)
(pset! new_data (+ new_length 1) (i64toi8 0))
new_buffer)))
(bind-func SSB:[StringStreamBuffer*,String*,i64]*
(lambda (str new_capacity)
(let*
((cstr (cstring str))
(current_length (strlen cstr))
(new_length (if (< current_length new_capacity) current_length new_capacity))
(new_data:i8* (zalloc (+ new_capacity 1)))
(new_buffer:StringStreamBuffer* (StringStreamBuffer new_data new_length new_capacity)))
(memcpy new_data cstr new_length)
(pset! new_data (+ new_length 1) (i64toi8 0))
new_buffer)))
(bind-func data:[i8*,StringStreamBuffer*]* (lambda (db:StringStreamBuffer*) (tref db 0)))
(bind-func data:[i8*,StringStreamBuffer*,i8*]* (lambda (db:StringStreamBuffer* data_in:i8*) (tset! db 0 data_in)))
(bind-func length:[i64,StringStreamBuffer*]* (lambda (db:StringStreamBuffer*) (tref db 1)))
(bind-func length:[i64,StringStreamBuffer*,i64]* (lambda (db:StringStreamBuffer* length_in:i64) (tset! db 1 length_in)))
(bind-func capacity:[i64,StringStreamBuffer*]* (lambda (db:StringStreamBuffer*) (tref db 2)))
(bind-func capacity:[i64,StringStreamBuffer*,i64]* (lambda (db:StringStreamBuffer* capacity_in:i64) (tset! db 2 capacity_in)))
(bind-func nth:[i8,StringStreamBuffer*,i64]*
(lambda (db:StringStreamBuffer* index:i64)
(let ((lngth:i64 (length db))
(ptr:i8* (data db)))
(cond
((< index lngth) (pref ptr index))
(else (i64toi8 0))))))
(bind-func write:[StringStreamBuffer*,StringStreamBuffer*,i8]*
(lambda (buffer c)
(let ((data (tref buffer 0))
(current_length (tref buffer 1))
(capacity (tref buffer 2)))
(cond
((< current_length capacity)
(pset! data current_length c)
(pset! data (+ current_length 1) (i64toi8 0))
(tset! buffer 1 (+ current_length 1))
buffer)
(else
(let* ((new_capacity (* capacity 2))
(new_buffer (StringStreamBuffer buffer new_capacity))
(new_data (tref new_buffer 0)))
(pset! new_data current_length c)
(pset! new_data (+ current_length 1) (i64toi8 0))
(tset! new_buffer 1 (+ current_length 1))
new_buffer))))))
(bind-func append:[StringStreamBuffer*,StringStreamBuffer*,StringStreamBuffer*]*
(lambda (a:StringStreamBuffer* b:StringStreamBuffer*)
(let ((i:i64 0)
(n:i64 (tref b 1)))
(dotimes (i n)
(set! a (write a (pref (tref b 0) i))))
a)))
(bind-func toString:[String*,StringStreamBuffer*]*
(lambda (buffer)
(String (tref buffer 0))))
(bind-func cstring:[i8*,StringStreamBuffer*]*
(lambda (buffer)
(tref buffer 0)))
(bind-func nontrivial:[bool,StringStreamBuffer*]*
(lambda (buffer)
(< 0 (tref buffer 1))))
(bind-func reset:[void,StringStreamBuffer*]*
(lambda (buffer)
;(memset (tref buffer 0) 0 (tref buffer 2))
(tset! buffer 1 0)
void))
(bind-func equal:[bool,StringStreamBuffer*,StringStreamBuffer*]*
(lambda (a b)
(= (i64toi32 0) (strcmp (cstring a) (cstring b)))))
(bind-func equal:[bool,StringStreamBuffer*,i8*]*
(lambda (buf cstr)
(= (i64toi32 0) (strcmp (cstring buf) cstr))))
(bind-func equal:[bool,StringStreamBuffer*,String*]*
(lambda (buf str)
(= (i64toi32 0) (strcmp (cstring buf) (cstring str)))))
(bind-func tail:[String*,StringStreamBuffer*,i64]*
(lambda (buffer d)
(String d (pref-ptr (tref buffer 0) (- (tref buffer 1) d)))))
(bind-func tail_match:[bool,StringStreamBuffer*,String*]*
(lambda (buf str)
(equal (tail buf (length str)) str)))
(bind-func tail_match:[bool,StringStreamBuffer*,String*,bool]*
(lambda (buf str ignore_case)
(if ignore_case
(equal (lower (tail buf (length str))) (lower str))
(equal (tail buf (length str)) str))))
(bind-func substring:[String*,StringStreamBuffer*,i64,i64]*
(lambda (buffer start lngth)
(cond
((< 0 lngth)
(let* ((data:i8* (alloc (+ lngth 1))))
(let ((tmp:i8* (strncpy data (pref-ptr (tref buffer 0) start) lngth)))
(cond
((= tmp data)
(pset! data lngth 0:i8)
(String data))
(else null)))))
(else null))))
;; (bind-func test-tail
;; (lambda ()
;; (let ((buffer:StringStreamBuffer* (StringStreamBuffer_c 256)) (i:i64 0))
;; (dotimes (i 26)
;; (set! buffer (write buffer (i64toi8 (+ i 97)))))
;; (let ((squibble:String* (tail buffer 6)))
;; (printf "\n%s\n" (cstring squibble))
;; (print_hex squibble)
;; (println "")
;; void))))
;; (test-tail)
(set! *xtmlib-ybot_dynamic_buffer-loaded* #t)