v2 / vlib / v / gen / c / text_manipulation.v
164 lines · 141 sloc · 4.19 KB · 2332ecff4811b8c97dfda8e825170e9397962519
Raw
1// Copyright (c) 2019-2024 Alexander Medvednikov. All rights reserved.
2// Use of this source code is governed by an MIT license
3// that can be found in the LICENSE file.
4module c
5
6import v.util
7
8const trace_gen_wanted_value = $d('trace_gen_wanted_value', '')
9
10@[if trace_gen_wanted ?]
11fn (mut g Gen) trace_gen_wanted_context(last_character_len int, s string) {
12 last_n := g.out.last_n(last_character_len)
13 eprintln('> trace_gen_wanted, last characters:\n${last_n}\n')
14 eprintln("> trace_gen_wanted, found wanted cgen string `${trace_gen_wanted_value}` in generated string: \"${s}\"")
15 print_backtrace()
16}
17
18@[if trace_gen_wanted ?]
19fn (mut g Gen) trace_gen_wanted(s string) {
20 if s.contains(trace_gen_wanted_value) {
21 g.trace_gen_wanted_context(256, s)
22 }
23}
24
25@[if trace_gen_wanted ?]
26fn (mut g Gen) trace_gen_wanted2(s1 string, s2 string) {
27 if s1.contains(trace_gen_wanted_value) || s2.contains(trace_gen_wanted_value) {
28 g.trace_gen_wanted_context(256, s1 + s2)
29 }
30}
31
32@[if trace_gen ?]
33fn (mut g Gen) trace_gen(reason string, s string) {
34 if g.file == unsafe { nil } {
35 eprintln('gen file: <nil> | last_fn_c_name: ${g.last_fn_c_name:-45} | ${reason}: ${s}')
36 } else {
37 eprintln('gen file: ${g.file.path:-30} | last_fn_c_name: ${g.last_fn_c_name:-45} | ${reason}: ${s}')
38 }
39}
40
41@[expand_simple_interpolation]
42fn (mut g Gen) write(s string) {
43 g.trace_gen_wanted(s)
44 g.trace_gen('write', s)
45 if g.indent > 0 && g.empty_line {
46 g.out.write_string(util.tabs(g.indent))
47 }
48 g.out.write_string(s)
49 g.empty_line = false
50}
51
52fn (mut g Gen) write2(s1 string, s2 string) {
53 g.trace_gen_wanted2(s1, s2)
54 g.trace_gen('write2 s1', s1)
55 if g.indent > 0 && g.empty_line {
56 g.out.write_string(util.tabs(g.indent))
57 }
58 g.out.write_string(s1)
59 g.empty_line = false
60
61 g.trace_gen('write2 s2', s2)
62 if g.indent > 0 && g.empty_line {
63 g.out.write_string(util.tabs(g.indent))
64 }
65 g.out.write_string(s2)
66 g.empty_line = false
67}
68
69fn (mut g Gen) write_decimal(x i64) {
70 g.trace_gen('write_decimal', x.str())
71 if g.indent > 0 && g.empty_line {
72 g.out.write_string(util.tabs(g.indent))
73 }
74 g.out.write_decimal(x)
75 g.empty_line = false
76}
77
78fn (mut g Gen) writeln(s string) {
79 g.trace_gen_wanted(s)
80 g.trace_gen('writeln', s)
81 if g.indent > 0 && g.empty_line {
82 g.out.write_string(util.tabs(g.indent))
83 // g.out_parallel[g.out_idx].write_string(util.tabs(g.indent))
84 }
85 // println('w len=${g.out_parallel.len}')
86 g.out.writeln(s)
87 // g.out_parallel[g.out_idx].writeln(s)
88 g.empty_line = true
89 // g.line_nr++
90}
91
92fn (mut g Gen) writeln2(s1 string, s2 string) {
93 g.trace_gen_wanted2(s1, s2)
94 g.trace_gen('writeln2 s1', s1)
95 // expansion for s1
96 if g.indent > 0 && g.empty_line {
97 g.out.write_string(util.tabs(g.indent))
98 }
99 g.out.writeln(s1)
100 g.empty_line = true
101
102 // expansion for s2
103 g.trace_gen('writeln2 s2', s2)
104 if g.indent > 0 && g.empty_line {
105 g.out.write_string(util.tabs(g.indent))
106 }
107 g.out.writeln(s2)
108 g.empty_line = true
109}
110
111// Below are hacks that should be removed at some point.
112
113fn (mut g Gen) go_back(n int) {
114 g.out.go_back(n)
115 // g.out_parallel[g.out_idx].go_back(n)
116}
117
118fn (mut g Gen) go_back_to(n int) {
119 g.out.go_back_to(n)
120 // g.out_parallel[g.out_idx].go_back_to(n)
121}
122
123@[inline]
124fn (g &Gen) nth_stmt_pos(n int) int {
125 return g.stmt_path_pos[g.stmt_path_pos.len - (1 + n)]
126}
127
128@[inline]
129fn (mut g Gen) set_current_pos_as_last_stmt_pos() {
130 g.stmt_path_pos << g.out.len
131}
132
133@[inline]
134fn (mut g Gen) go_before_last_stmt() string {
135 return g.out.cut_to(g.nth_stmt_pos(0))
136}
137
138@[inline]
139fn (mut g Gen) go_before_ternary() string {
140 return g.out.cut_to(g.nth_stmt_pos(g.inside_ternary))
141}
142
143fn (mut g Gen) insert_before_stmt(s string) {
144 cur_line := g.out.cut_to(g.nth_stmt_pos(g.inside_ternary))
145 g.writeln(s)
146 g.write(cur_line)
147}
148
149fn (mut g Gen) insert_at(pos int, s string) {
150 cur_line := g.out.cut_to(pos)
151 // g.out_parallel[g.out_idx].cut_to(pos)
152 g.writeln(s)
153 g.write(cur_line)
154
155 // After modifying the code in the buffer, we need to adjust the positions of the statements
156 // to account for the added line of code.
157 // This is necessary to ensure that autofree can properly insert string declarations
158 // in the correct positions, considering the surgically made changes.
159 for index, stmt_pos in g.stmt_path_pos {
160 if stmt_pos >= pos {
161 g.stmt_path_pos[index] += s.len + 1
162 }
163 }
164}
165