|
2 | 2 |
|
3 | 3 | import v.util
|
4 | 4 | import v.ast
|
| 5 | +import strings |
| 6 | + |
| 7 | +pub const reset_dbg_line = '#line 999999999' |
5 | 8 |
|
6 | 9 | pub fn (mut g Gen) gen_c_main() {
|
7 | 10 | if !g.has_main {
|
@@ -38,18 +41,56 @@ fn (mut g Gen) gen_vlines_reset() {
|
38 | 41 | // At this point, the v files are transpiled.
|
39 | 42 | // The rest is auto generated code, which will not have
|
40 | 43 | // different .v source file/line numbers.
|
41 |
| - // |
42 |
| - // TODO: calculate the proper line here, based on |
43 |
| - // the actual C lines in all the buffers |
44 |
| - lines_so_far := 1000000 |
45 | 44 | g.vlines_path = util.vlines_escape_path(g.pref.out_name_c, g.pref.ccompiler)
|
46 | 45 | g.writeln('')
|
47 |
| - g.writeln('\n// Reset the file/line numbers') |
48 |
| - g.writeln('\n#line ${lines_so_far} "${g.vlines_path}"') |
| 46 | + g.writeln('// Reset the C file/line numbers') |
| 47 | + g.writeln('${c.reset_dbg_line} "${g.vlines_path}"') |
49 | 48 | g.writeln('')
|
50 | 49 | }
|
51 | 50 | }
|
52 | 51 |
|
| 52 | +pub fn fix_reset_dbg_line(src string, out_file string) string { |
| 53 | + util.timing_start(@FN) |
| 54 | + defer { |
| 55 | + util.timing_measure(@FN) |
| 56 | + } |
| 57 | + // Note: using src.index() + a line counting loop + src.replace() here is slower, |
| 58 | + // since it has to iterate over pretty much the entire src string several times. |
| 59 | + // The loop below, does it just once, combining counting the lines, and finding the reset line: |
| 60 | + mut dbg_reset_line_idx := 0 |
| 61 | + mut lines := 1 |
| 62 | + for idx, ob in src { |
| 63 | + if ob == `\n` { |
| 64 | + lines++ |
| 65 | + if unsafe { vmemcmp(src.str + idx + 1, c.reset_dbg_line.str, c.reset_dbg_line.len) } == 0 { |
| 66 | + dbg_reset_line_idx = idx + 1 |
| 67 | + break |
| 68 | + } |
| 69 | + } |
| 70 | + } |
| 71 | + // find the position of the "..\..\..\src.tmp.c": |
| 72 | + mut first_quote_idx := 0 |
| 73 | + for idx := dbg_reset_line_idx; idx < src.len; idx++ { |
| 74 | + if unsafe { src.str[idx] } == `"` { |
| 75 | + first_quote_idx = idx |
| 76 | + break |
| 77 | + } |
| 78 | + } |
| 79 | + // replace the reset line with the fixed line counter, keeping everything |
| 80 | + // before and after it unchanged: |
| 81 | + mut sb := strings.new_builder(src.len) |
| 82 | + unsafe { |
| 83 | + sb.write_ptr(src.str, dbg_reset_line_idx) |
| 84 | + sb.write_string('#line ') |
| 85 | + sb.write_decimal(lines) |
| 86 | + sb.write_ptr(src.str + first_quote_idx - 1, src.len - first_quote_idx) |
| 87 | + } |
| 88 | + $if trace_reset_dbg_line ? { |
| 89 | + eprintln('> reset_dbg_line: ${out_file}:${lines} | first_quote_idx: ${first_quote_idx} | src.len: ${src.len} | sb.len: ${sb.len} | sb.cap: ${sb.cap}') |
| 90 | + } |
| 91 | + return sb.str() |
| 92 | +} |
| 93 | + |
53 | 94 | fn (mut g Gen) gen_c_main_function_only_header() {
|
54 | 95 | if g.pref.cmain != '' {
|
55 | 96 | g.writeln('int ${g.pref.cmain}(int ___argc, char** ___argv){')
|
|
0 commit comments