v2 / vlib / builtin / autostr.v
87 lines · 75 sloc · 1.78 KB · 742895e2290c6c20c135b0b1e571a2920f6d661f
Raw
1module builtin
2
3import strings
4
5const autostr_type_stack_max_depth = 64
6
7__global g_autostr_type_stack = [autostr_type_stack_max_depth]int{}
8__global g_autostr_type_stack_len = 0
9
10@[markused]
11fn autostr_type_in_stack(typ int) bool {
12 for i := 0; i < g_autostr_type_stack_len; i++ {
13 if g_autostr_type_stack[i] == typ {
14 return true
15 }
16 }
17 return false
18}
19
20@[markused]
21fn autostr_type_push(typ int) {
22 if g_autostr_type_stack_len >= autostr_type_stack_max_depth {
23 return
24 }
25 g_autostr_type_stack[g_autostr_type_stack_len] = typ
26 g_autostr_type_stack_len++
27}
28
29@[markused]
30fn autostr_type_pop() {
31 if g_autostr_type_stack_len > 0 {
32 g_autostr_type_stack_len--
33 }
34}
35
36// Address-based circular reference detection.
37// Tracks visited struct addresses to detect actual circular references
38// (same instance reached again) without false positives from same-type
39// different instances.
40
41__global g_autostr_addr_stack = [autostr_type_stack_max_depth]voidptr{}
42__global g_autostr_addr_stack_len = 0
43
44@[markused]
45fn autostr_addr_in_stack(addr voidptr) bool {
46 for i := 0; i < g_autostr_addr_stack_len; i++ {
47 if g_autostr_addr_stack[i] == addr {
48 return true
49 }
50 }
51 return false
52}
53
54@[markused]
55fn autostr_addr_push(addr voidptr) {
56 if g_autostr_addr_stack_len >= autostr_type_stack_max_depth {
57 return
58 }
59 g_autostr_addr_stack[g_autostr_addr_stack_len] = addr
60 g_autostr_addr_stack_len++
61}
62
63@[markused]
64fn autostr_addr_pop() {
65 if g_autostr_addr_stack_len > 0 {
66 g_autostr_addr_stack_len--
67 }
68}
69
70@[markused]
71fn autostr_array_circular(len int) string {
72 if len <= 0 {
73 return '[]'
74 }
75 mut sb := strings.new_builder(2 + len * 12)
76 sb.write_string('[')
77 for i in 0 .. len {
78 if i > 0 {
79 sb.write_string(', ')
80 }
81 sb.write_string('<circular>')
82 }
83 sb.write_string(']')
84 res := sb.str()
85 unsafe { sb.free() }
86 return res
87}
88