1 | /*============================================================================= |
2 | Copyright (c) 2019-2023 Dario Deledda. All rights reserved. |
3 | Use of this source code is governed by an MIT license |
4 | that can be found in the LICENSE file. |
5 | |
6 | This file contains string interpolation V functions |
7 | =============================================================================*/ |
8 | module strconv |
9 | |
10 | import strings |
11 | |
12 | enum Char_parse_state { |
13 | start |
14 | norm_char |
15 | field_char |
16 | pad_ch |
17 | len_set_start |
18 | len_set_in |
19 | check_type |
20 | check_float |
21 | check_float_in |
22 | reset_params |
23 | } |
24 | |
25 | // v_printf prints a sprintf-like formated `string` to the terminal. |
26 | // The format string `str` can be constructed at runtime. |
27 | // Note, that this function is unsafe. |
28 | // In most cases, you are better off using V's string interpolation, |
29 | // when your format string is known at compile time. |
30 | [unsafe] |
31 | pub fn v_printf(str string, pt ...voidptr) { |
32 | print(unsafe { v_sprintf(str, ...pt) }) |
33 | } |
34 | |
35 | // v_sprintf returns a sprintf-like formated `string`. |
36 | // The format string `str` can be constructed at runtime. |
37 | // Note, that this function is unsafe. |
38 | // In most cases, you are better off using V's string interpolation, |
39 | // when your format string is known at compile time. |
40 | // Example: |
41 | // ```v |
42 | // x := 3.141516 |
43 | // assert strconv.v_sprintf('aaa %G', x) == 'aaa 3.141516' |
44 | // ``` |
45 | [direct_array_access; manualfree; unsafe] |
46 | pub fn v_sprintf(str string, pt ...voidptr) string { |
47 | mut res := strings.new_builder(pt.len * 16) |
48 | defer { |
49 | unsafe { res.free() } |
50 | } |
51 | |
52 | mut i := 0 // main string index |
53 | mut p_index := 0 // parameter index |
54 | mut sign := false // sign flag |
55 | mut allign := Align_text.right |
56 | mut len0 := -1 // forced length, if -1 free length |
57 | mut len1 := -1 // decimal part for floats |
58 | def_len1 := 6 // default value for len1 |
59 | mut pad_ch := u8(` `) // pad char |
60 | |
61 | // prefix chars for Length field |
62 | mut ch1 := `0` // +1 char if present else `0` |
63 | mut ch2 := `0` // +2 char if present else `0` |
64 | |
65 | mut status := Char_parse_state.norm_char |
66 | for i < str.len { |
67 | if status == .reset_params { |
68 | sign = false |
69 | allign = .right |
70 | len0 = -1 |
71 | len1 = -1 |
72 | pad_ch = ` ` |
73 | status = .norm_char |
74 | ch1 = `0` |
75 | ch2 = `0` |
76 | continue |
77 | } |
78 | |
79 | ch := str[i] |
80 | if ch != `%` && status == .norm_char { |
81 | res.write_u8(ch) |
82 | i++ |
83 | continue |
84 | } |
85 | if ch == `%` && status == .field_char { |
86 | status = .norm_char |
87 | res.write_u8(ch) |
88 | i++ |
89 | continue |
90 | } |
91 | if ch == `%` && status == .norm_char { |
92 | status = .field_char |
93 | i++ |
94 | continue |
95 | } |
96 | |
97 | // single char, manage it here |
98 | if ch == `c` && status == .field_char { |
99 | v_sprintf_panic(p_index, pt.len) |
100 | d1 := unsafe { *(&u8(pt[p_index])) } |
101 | res.write_u8(d1) |
102 | status = .reset_params |
103 | p_index++ |
104 | i++ |
105 | continue |
106 | } |
107 | |
108 | // pointer, manage it here |
109 | if ch == `p` && status == .field_char { |
110 | v_sprintf_panic(p_index, pt.len) |
111 | res.write_string('0x') |
112 | res.write_string(ptr_str(unsafe { pt[p_index] })) |
113 | status = .reset_params |
114 | p_index++ |
115 | i++ |
116 | continue |
117 | } |
118 | |
119 | if status == .field_char { |
120 | mut fc_ch1 := `0` |
121 | mut fc_ch2 := `0` |
122 | if (i + 1) < str.len { |
123 | fc_ch1 = str[i + 1] |
124 | if (i + 2) < str.len { |
125 | fc_ch2 = str[i + 2] |
126 | } |
127 | } |
128 | if ch == `+` { |
129 | sign = true |
130 | i++ |
131 | continue |
132 | } else if ch == `-` { |
133 | allign = .left |
134 | i++ |
135 | continue |
136 | } else if ch in [`0`, ` `] { |
137 | if allign == .right { |
138 | pad_ch = ch |
139 | } |
140 | i++ |
141 | continue |
142 | } else if ch == `'` { |
143 | i++ |
144 | continue |
145 | } else if ch == `.` && fc_ch1 >= `1` && fc_ch1 <= `9` { |
146 | status = .check_float |
147 | i++ |
148 | continue |
149 | } |
150 | // manage "%.*s" precision field |
151 | else if ch == `.` && fc_ch1 == `*` && fc_ch2 == `s` { |
152 | v_sprintf_panic(p_index, pt.len) |
153 | len := unsafe { *(&int(pt[p_index])) } |
154 | p_index++ |
155 | v_sprintf_panic(p_index, pt.len) |
156 | mut s := unsafe { *(&string(pt[p_index])) } |
157 | s = s[..len] |
158 | p_index++ |
159 | res.write_string(s) |
160 | status = .reset_params |
161 | i += 3 |
162 | continue |
163 | } |
164 | status = .len_set_start |
165 | continue |
166 | } |
167 | |
168 | if status == .len_set_start { |
169 | if ch >= `1` && ch <= `9` { |
170 | len0 = int(ch - `0`) |
171 | status = .len_set_in |
172 | i++ |
173 | continue |
174 | } |
175 | if ch == `.` { |
176 | status = .check_float |
177 | i++ |
178 | continue |
179 | } |
180 | status = .check_type |
181 | continue |
182 | } |
183 | |
184 | if status == .len_set_in { |
185 | if ch >= `0` && ch <= `9` { |
186 | len0 *= 10 |
187 | len0 += int(ch - `0`) |
188 | i++ |
189 | continue |
190 | } |
191 | if ch == `.` { |
192 | status = .check_float |
193 | i++ |
194 | continue |
195 | } |
196 | status = .check_type |
197 | continue |
198 | } |
199 | |
200 | if status == .check_float { |
201 | if ch >= `0` && ch <= `9` { |
202 | len1 = int(ch - `0`) |
203 | status = .check_float_in |
204 | i++ |
205 | continue |
206 | } |
207 | status = .check_type |
208 | continue |
209 | } |
210 | |
211 | if status == .check_float_in { |
212 | if ch >= `0` && ch <= `9` { |
213 | len1 *= 10 |
214 | len1 += int(ch - `0`) |
215 | i++ |
216 | continue |
217 | } |
218 | status = .check_type |
219 | continue |
220 | } |
221 | |
222 | if status == .check_type { |
223 | if ch == `l` { |
224 | if ch1 == `0` { |
225 | ch1 = `l` |
226 | i++ |
227 | continue |
228 | } else { |
229 | ch2 = `l` |
230 | i++ |
231 | continue |
232 | } |
233 | } else if ch == `h` { |
234 | if ch1 == `0` { |
235 | ch1 = `h` |
236 | i++ |
237 | continue |
238 | } else { |
239 | ch2 = `h` |
240 | i++ |
241 | continue |
242 | } |
243 | } |
244 | // signed integer |
245 | else if ch in [`d`, `i`] { |
246 | mut d1 := u64(0) |
247 | mut positive := true |
248 | |
249 | // println("$ch1 $ch2") |
250 | match ch1 { |
251 | // h for 16 bit int |
252 | // hh fot 8 bit int |
253 | `h` { |
254 | if ch2 == `h` { |
255 | v_sprintf_panic(p_index, pt.len) |
256 | x := unsafe { *(&i8(pt[p_index])) } |
257 | positive = if x >= 0 { true } else { false } |
258 | d1 = if positive { u64(x) } else { u64(-x) } |
259 | } else { |
260 | x := unsafe { *(&i16(pt[p_index])) } |
261 | positive = if x >= 0 { true } else { false } |
262 | d1 = if positive { u64(x) } else { u64(-x) } |
263 | } |
264 | } |
265 | // l i64 |
266 | // ll i64 for now |
267 | `l` { |
268 | // placeholder for future 128bit integer code |
269 | /* |
270 | if ch2 == `l` { |
271 | v_sprintf_panic(p_index, pt.len) |
272 | x := *(&i128(pt[p_index])) |
273 | positive = if x >= 0 { true } else { false } |
274 | d1 = if positive { u128(x) } else { u128(-x) } |
275 | } else { |
276 | v_sprintf_panic(p_index, pt.len) |
277 | x := *(&i64(pt[p_index])) |
278 | positive = if x >= 0 { true } else { false } |
279 | d1 = if positive { u64(x) } else { u64(-x) } |
280 | } |
281 | */ |
282 | v_sprintf_panic(p_index, pt.len) |
283 | x := unsafe { *(&i64(pt[p_index])) } |
284 | positive = if x >= 0 { true } else { false } |
285 | d1 = if positive { u64(x) } else { u64(-x) } |
286 | } |
287 | // default int |
288 | else { |
289 | v_sprintf_panic(p_index, pt.len) |
290 | x := unsafe { *(&int(pt[p_index])) } |
291 | positive = if x >= 0 { true } else { false } |
292 | d1 = if positive { u64(x) } else { u64(-x) } |
293 | } |
294 | } |
295 | tmp := format_dec_old(d1, |
296 | pad_ch: pad_ch |
297 | len0: len0 |
298 | len1: 0 |
299 | positive: positive |
300 | sign_flag: sign |
301 | allign: allign |
302 | ) |
303 | res.write_string(tmp) |
304 | unsafe { tmp.free() } |
305 | status = .reset_params |
306 | p_index++ |
307 | i++ |
308 | ch1 = `0` |
309 | ch2 = `0` |
310 | continue |
311 | } |
312 | // unsigned integer |
313 | else if ch == `u` { |
314 | mut d1 := u64(0) |
315 | positive := true |
316 | v_sprintf_panic(p_index, pt.len) |
317 | match ch1 { |
318 | // h for 16 bit unsigned int |
319 | // hh fot 8 bit unsigned int |
320 | `h` { |
321 | if ch2 == `h` { |
322 | d1 = u64(unsafe { *(&u8(pt[p_index])) }) |
323 | } else { |
324 | d1 = u64(unsafe { *(&u16(pt[p_index])) }) |
325 | } |
326 | } |
327 | // l u64 |
328 | // ll u64 for now |
329 | `l` { |
330 | // placeholder for future 128bit integer code |
331 | /* |
332 | if ch2 == `l` { |
333 | d1 = u128(*(&u128(pt[p_index]))) |
334 | } else { |
335 | d1 = u64(*(&u64(pt[p_index]))) |
336 | } |
337 | */ |
338 | d1 = u64(unsafe { *(&u64(pt[p_index])) }) |
339 | } |
340 | // default int |
341 | else { |
342 | d1 = u64(unsafe { *(&u32(pt[p_index])) }) |
343 | } |
344 | } |
345 | |
346 | tmp := format_dec_old(d1, |
347 | pad_ch: pad_ch |
348 | len0: len0 |
349 | len1: 0 |
350 | positive: positive |
351 | sign_flag: sign |
352 | allign: allign |
353 | ) |
354 | res.write_string(tmp) |
355 | unsafe { tmp.free() } |
356 | status = .reset_params |
357 | p_index++ |
358 | i++ |
359 | continue |
360 | } |
361 | // hex |
362 | else if ch in [`x`, `X`] { |
363 | v_sprintf_panic(p_index, pt.len) |
364 | mut s := '' |
365 | match ch1 { |
366 | // h for 16 bit int |
367 | // hh fot 8 bit int |
368 | `h` { |
369 | if ch2 == `h` { |
370 | x := unsafe { *(&i8(pt[p_index])) } |
371 | s = x.hex() |
372 | } else { |
373 | x := unsafe { *(&i16(pt[p_index])) } |
374 | s = x.hex() |
375 | } |
376 | } |
377 | // l i64 |
378 | // ll i64 for now |
379 | `l` { |
380 | // placeholder for future 128bit integer code |
381 | /* |
382 | if ch2 == `l` { |
383 | x := *(&i128(pt[p_index])) |
384 | s = x.hex() |
385 | } else { |
386 | x := *(&i64(pt[p_index])) |
387 | s = x.hex() |
388 | } |
389 | */ |
390 | x := unsafe { *(&i64(pt[p_index])) } |
391 | s = x.hex() |
392 | } |
393 | else { |
394 | x := unsafe { *(&int(pt[p_index])) } |
395 | s = x.hex() |
396 | } |
397 | } |
398 | |
399 | if ch == `X` { |
400 | tmp := s |
401 | s = s.to_upper() |
402 | unsafe { tmp.free() } |
403 | } |
404 | |
405 | tmp := format_str(s, |
406 | pad_ch: pad_ch |
407 | len0: len0 |
408 | len1: 0 |
409 | positive: true |
410 | sign_flag: false |
411 | allign: allign |
412 | ) |
413 | res.write_string(tmp) |
414 | unsafe { tmp.free() } |
415 | unsafe { s.free() } |
416 | status = .reset_params |
417 | p_index++ |
418 | i++ |
419 | continue |
420 | } |
421 | |
422 | // float and double |
423 | if ch in [`f`, `F`] { |
424 | $if !nofloat ? { |
425 | v_sprintf_panic(p_index, pt.len) |
426 | x := unsafe { *(&f64(pt[p_index])) } |
427 | positive := x >= f64(0.0) |
428 | len1 = if len1 >= 0 { len1 } else { def_len1 } |
429 | s := format_fl_old(f64(x), |
430 | pad_ch: pad_ch |
431 | len0: len0 |
432 | len1: len1 |
433 | positive: positive |
434 | sign_flag: sign |
435 | allign: allign |
436 | ) |
437 | if ch == `F` { |
438 | tmp := s.to_upper() |
439 | res.write_string(tmp) |
440 | unsafe { tmp.free() } |
441 | } else { |
442 | res.write_string(s) |
443 | } |
444 | unsafe { s.free() } |
445 | } |
446 | status = .reset_params |
447 | p_index++ |
448 | i++ |
449 | continue |
450 | } else if ch in [`e`, `E`] { |
451 | $if !nofloat ? { |
452 | v_sprintf_panic(p_index, pt.len) |
453 | x := unsafe { *(&f64(pt[p_index])) } |
454 | positive := x >= f64(0.0) |
455 | len1 = if len1 >= 0 { len1 } else { def_len1 } |
456 | s := format_es_old(f64(x), |
457 | pad_ch: pad_ch |
458 | len0: len0 |
459 | len1: len1 |
460 | positive: positive |
461 | sign_flag: sign |
462 | allign: allign |
463 | ) |
464 | if ch == `E` { |
465 | tmp := s.to_upper() |
466 | res.write_string(tmp) |
467 | unsafe { tmp.free() } |
468 | } else { |
469 | res.write_string(s) |
470 | } |
471 | unsafe { s.free() } |
472 | } |
473 | status = .reset_params |
474 | p_index++ |
475 | i++ |
476 | continue |
477 | } else if ch in [`g`, `G`] { |
478 | $if !nofloat ? { |
479 | v_sprintf_panic(p_index, pt.len) |
480 | x := unsafe { *(&f64(pt[p_index])) } |
481 | positive := x >= f64(0.0) |
482 | mut s := '' |
483 | tx := fabs(x) |
484 | if tx < 999_999.0 && tx >= 0.00001 { |
485 | // println("Here g format_fl [$tx]") |
486 | len1 = if len1 >= 0 { len1 + 1 } else { def_len1 } |
487 | tmp := s |
488 | s = format_fl_old(x, |
489 | pad_ch: pad_ch |
490 | len0: len0 |
491 | len1: len1 |
492 | positive: positive |
493 | sign_flag: sign |
494 | allign: allign |
495 | rm_tail_zero: true |
496 | ) |
497 | unsafe { tmp.free() } |
498 | } else { |
499 | len1 = if len1 >= 0 { len1 + 1 } else { def_len1 } |
500 | tmp := s |
501 | s = format_es_old(x, |
502 | pad_ch: pad_ch |
503 | len0: len0 |
504 | len1: len1 |
505 | positive: positive |
506 | sign_flag: sign |
507 | allign: allign |
508 | rm_tail_zero: true |
509 | ) |
510 | unsafe { tmp.free() } |
511 | } |
512 | if ch == `G` { |
513 | tmp := s.to_upper() |
514 | res.write_string(tmp) |
515 | unsafe { tmp.free() } |
516 | } else { |
517 | res.write_string(s) |
518 | } |
519 | unsafe { s.free() } |
520 | } |
521 | status = .reset_params |
522 | p_index++ |
523 | i++ |
524 | continue |
525 | } |
526 | // string |
527 | else if ch == `s` { |
528 | v_sprintf_panic(p_index, pt.len) |
529 | s1 := unsafe { *(&string(pt[p_index])) } |
530 | pad_ch = ` ` |
531 | tmp := format_str(s1, |
532 | pad_ch: pad_ch |
533 | len0: len0 |
534 | len1: 0 |
535 | positive: true |
536 | sign_flag: false |
537 | allign: allign |
538 | ) |
539 | res.write_string(tmp) |
540 | unsafe { tmp.free() } |
541 | status = .reset_params |
542 | p_index++ |
543 | i++ |
544 | continue |
545 | } |
546 | } |
547 | |
548 | status = .reset_params |
549 | p_index++ |
550 | i++ |
551 | } |
552 | |
553 | if p_index != pt.len { |
554 | panic('${p_index} % conversion specifiers, but given ${pt.len} args') |
555 | } |
556 | |
557 | return res.str() |
558 | } |
559 | |
560 | [inline] |
561 | fn v_sprintf_panic(idx int, len int) { |
562 | if idx >= len { |
563 | panic('${idx + 1} % conversion specifiers, but given only ${len} args') |
564 | } |
565 | } |
566 | |
567 | fn fabs(x f64) f64 { |
568 | if x < 0.0 { |
569 | return -x |
570 | } |
571 | return x |
572 | } |
573 | |
574 | // strings.Builder version of format_fl |
575 | [direct_array_access; manualfree] |
576 | pub fn format_fl_old(f f64, p BF_param) string { |
577 | unsafe { |
578 | mut s := '' |
579 | // mut fs := "1.2343" |
580 | mut fs := f64_to_str_lnd1(if f >= 0.0 { f } else { -f }, p.len1) |
581 | // println("Dario") |
582 | // println(fs) |
583 | |
584 | // error!! |
585 | if fs[0] == `[` { |
586 | s.free() |
587 | return fs |
588 | } |
589 | |
590 | if p.rm_tail_zero { |
591 | tmp := fs |
592 | fs = remove_tail_zeros_old(fs) |
593 | tmp.free() |
594 | } |
595 | mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len }) |
596 | defer { |
597 | res.free() |
598 | } |
599 | |
600 | mut sign_len_diff := 0 |
601 | if p.pad_ch == `0` { |
602 | if p.positive { |
603 | if p.sign_flag { |
604 | res.write_u8(`+`) |
605 | sign_len_diff = -1 |
606 | } |
607 | } else { |
608 | res.write_u8(`-`) |
609 | sign_len_diff = -1 |
610 | } |
611 | tmp := s |
612 | s = fs.clone() |
613 | tmp.free() |
614 | } else { |
615 | if p.positive { |
616 | if p.sign_flag { |
617 | tmp := s |
618 | s = '+' + fs |
619 | tmp.free() |
620 | } else { |
621 | tmp := s |
622 | s = fs.clone() |
623 | tmp.free() |
624 | } |
625 | } else { |
626 | tmp := s |
627 | s = '-' + fs |
628 | tmp.free() |
629 | } |
630 | } |
631 | |
632 | dif := p.len0 - s.len + sign_len_diff |
633 | |
634 | if p.allign == .right { |
635 | for i1 := 0; i1 < dif; i1++ { |
636 | res.write_u8(p.pad_ch) |
637 | } |
638 | } |
639 | res.write_string(s) |
640 | if p.allign == .left { |
641 | for i1 := 0; i1 < dif; i1++ { |
642 | res.write_u8(p.pad_ch) |
643 | } |
644 | } |
645 | |
646 | s.free() |
647 | fs.free() |
648 | return res.str() |
649 | } |
650 | } |
651 | |
652 | [manualfree] |
653 | fn format_es_old(f f64, p BF_param) string { |
654 | unsafe { |
655 | mut s := '' |
656 | mut fs := f64_to_str_pad(if f > 0 { f } else { -f }, p.len1) |
657 | if p.rm_tail_zero { |
658 | tmp := fs |
659 | fs = remove_tail_zeros_old(fs) |
660 | tmp.free() |
661 | } |
662 | mut res := strings.new_builder(if p.len0 > fs.len { p.len0 } else { fs.len }) |
663 | defer { |
664 | res.free() |
665 | fs.free() |
666 | s.free() |
667 | } |
668 | |
669 | mut sign_len_diff := 0 |
670 | if p.pad_ch == `0` { |
671 | if p.positive { |
672 | if p.sign_flag { |
673 | res.write_u8(`+`) |
674 | sign_len_diff = -1 |
675 | } |
676 | } else { |
677 | res.write_u8(`-`) |
678 | sign_len_diff = -1 |
679 | } |
680 | tmp := s |
681 | s = fs.clone() |
682 | tmp.free() |
683 | } else { |
684 | if p.positive { |
685 | if p.sign_flag { |
686 | tmp := s |
687 | s = '+' + fs |
688 | tmp.free() |
689 | } else { |
690 | tmp := s |
691 | s = fs.clone() |
692 | tmp.free() |
693 | } |
694 | } else { |
695 | tmp := s |
696 | s = '-' + fs |
697 | tmp.free() |
698 | } |
699 | } |
700 | |
701 | dif := p.len0 - s.len + sign_len_diff |
702 | if p.allign == .right { |
703 | for i1 := 0; i1 < dif; i1++ { |
704 | res.write_u8(p.pad_ch) |
705 | } |
706 | } |
707 | res.write_string(s) |
708 | if p.allign == .left { |
709 | for i1 := 0; i1 < dif; i1++ { |
710 | res.write_u8(p.pad_ch) |
711 | } |
712 | } |
713 | return res.str() |
714 | } |
715 | } |
716 | |
717 | fn remove_tail_zeros_old(s string) string { |
718 | mut i := 0 |
719 | mut last_zero_start := -1 |
720 | mut dot_pos := -1 |
721 | mut in_decimal := false |
722 | mut prev_ch := u8(0) |
723 | for i < s.len { |
724 | ch := unsafe { s.str[i] } |
725 | if ch == `.` { |
726 | in_decimal = true |
727 | dot_pos = i |
728 | } else if in_decimal { |
729 | if ch == `0` && prev_ch != `0` { |
730 | last_zero_start = i |
731 | } else if ch >= `1` && ch <= `9` { |
732 | last_zero_start = -1 |
733 | } else if ch == `e` { |
734 | break |
735 | } |
736 | } |
737 | prev_ch = ch |
738 | i++ |
739 | } |
740 | |
741 | mut tmp := '' |
742 | if last_zero_start > 0 { |
743 | if last_zero_start == dot_pos + 1 { |
744 | tmp = s[..dot_pos] + s[i..] |
745 | } else { |
746 | tmp = s[..last_zero_start] + s[i..] |
747 | } |
748 | } else { |
749 | tmp = s.clone() |
750 | } |
751 | if unsafe { tmp.str[tmp.len - 1] } == `.` { |
752 | return tmp[..tmp.len - 1] |
753 | } |
754 | return tmp |
755 | } |
756 | |
757 | // max int64 9223372036854775807 |
758 | [manualfree] |
759 | pub fn format_dec_old(d u64, p BF_param) string { |
760 | mut s := '' |
761 | mut res := strings.new_builder(20) |
762 | defer { |
763 | unsafe { res.free() } |
764 | unsafe { s.free() } |
765 | } |
766 | mut sign_len_diff := 0 |
767 | if p.pad_ch == `0` { |
768 | if p.positive { |
769 | if p.sign_flag { |
770 | res.write_u8(`+`) |
771 | sign_len_diff = -1 |
772 | } |
773 | } else { |
774 | res.write_u8(`-`) |
775 | sign_len_diff = -1 |
776 | } |
777 | tmp := s |
778 | s = d.str() |
779 | unsafe { tmp.free() } |
780 | } else { |
781 | if p.positive { |
782 | if p.sign_flag { |
783 | tmp := s |
784 | s = '+' + d.str() |
785 | unsafe { tmp.free() } |
786 | } else { |
787 | tmp := s |
788 | s = d.str() |
789 | unsafe { tmp.free() } |
790 | } |
791 | } else { |
792 | tmp := s |
793 | s = '-' + d.str() |
794 | unsafe { tmp.free() } |
795 | } |
796 | } |
797 | dif := p.len0 - s.len + sign_len_diff |
798 | |
799 | if p.allign == .right { |
800 | for i1 := 0; i1 < dif; i1++ { |
801 | res.write_u8(p.pad_ch) |
802 | } |
803 | } |
804 | res.write_string(s) |
805 | if p.allign == .left { |
806 | for i1 := 0; i1 < dif; i1++ { |
807 | res.write_u8(p.pad_ch) |
808 | } |
809 | } |
810 | return res.str() |
811 | } |