|
From: | Raul Hernandez |
Subject: | [Tinycc-devel] [patch] adding path resolution to #line directives |
Date: | Thu, 5 May 2022 10:50:39 +0200 |
Hi, list. Over at vlang/v, we use #line directives to map line numbers in the generated C to the respective locations in the original code in backtraces, etc. The code we generate looks something like this: #line 29 "../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v" void panic_debug(void) { #line 53 "../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v" tcc_backtrace("Backtrace"); } #line 1 "../../../../../../home/spaceface/git/v/v/test.v" void main__inner(void) { #line 1 "../../../../../../home/spaceface/git/v/v/test.v" panic_debug(); } #line 2 "../../../../../../home/spaceface/git/v/v/test.v" void main__outer(void) { #line 2 "../../../../../../home/spaceface/git/v/v/test.v" main__inner(); } #line 3 "../../../../../../home/spaceface/git/v/v/test.v" int main(void) { #line 3 "../../../../../../home/spaceface/git/v/v/test.v" main__outer(); return 0; } Other C compilers collapse the `../`s in the #line paths, but TCC does not, so currently the backtraces it produces look like this: /tmp/v_1000/../../../../../../home/spaceface/git/v/v/vlib/builtin/builtin.c.v:53: at panic_debug: Backtrace /tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:1: by main__inner /tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:2: by main__outer /tmp/v_1000/../../../../../../home/spaceface/git/v/v/test.v:3: by main I decided to try and fix this, and came up with the following patch: diff --git a/tccpp.c b/tccpp.c index 2ff5d5e..47ac859 100644 --- a/tccpp.c +++ b/tccpp.c @@ -1797,7 +1797,7 @@ ST_FUNC void preprocess(int is_bof) { TCCState *s1 = tcc_state; int i, c, n, saved_parse_flags; - char buf[1024], *q; + char buf[1024], *q, *last_slash; Sym *s; saved_parse_flags = parse_flags; @@ -2042,6 +2042,22 @@ include_done: pstrcpy(buf, sizeof buf, file->true_filename); *tcc_basename(buf) = 0; pstrcat(buf, sizeof buf, (char *)tokc.str.data); + // collapse relative `../`s + while ((q = strstr(buf, "../")) != NULL) { + (q == buf) ? (*q = '\0') : (*(q-1) = '\0'); + last_slash = strrchr(buf, '/'); + if (last_slash == NULL) { + memmove(buf, q + 2, strlen(q + 2) + 1); + } else { + memmove(last_slash + 1, q + 2, strlen(q + 2) + 1); + } + } + // collapse `foo//bar` to `foo/bar` + c = strlen(buf); + while((q = strstr(buf, "//")) != NULL) { + memmove(q, q+1, c - (q - buf)); + c--; + } tcc_debug_putfile(s1, buf); } else if (parse_flags & PARSE_FLAG_ASM_FILE) break; With it, that same backtrace now looks like this: /home/spaceface/git/v/v/vlib/builtin/builtin.c.v:53: at panic_debug: Backtrace /home/spaceface/git/v/v/test.v:1: by main__inner /home/spaceface/git/v/v/test.v:2: by main__outer /home/spaceface/git/v/v/test.v:3: by main Would you be willing to merge something this? We’ve also added a function that returns the backtrace as a char** rather than printing it out, and modified the backtrace functions to replace e.g. main__foo with main.foo in symbol names, but I presume these patches won’t be as useful outside of V. Raul |
[Prev in Thread] | Current Thread | [Next in Thread] |