From 77a70ddb7b36f74dd1169b90d87820c079e3eed6 Mon Sep 17 00:00:00 2001 From: Alex Brainman Date: Sun, 12 Sep 2010 18:07:13 +1000 Subject: [PATCH] gc: fix symbol table generation on windows gc records full, '/' delimited, filenames now. R=rsc CC=golang-dev https://golang.org/cl/1962042 --- src/cmd/gc/go.h | 1 + src/cmd/gc/obj.c | 107 +++++++++++++++++++++++++++++++++++------------ src/pkg/Makefile | 1 - 3 files changed, 82 insertions(+), 27 deletions(-) diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index c39bfbbc6ab..011cbf1c933 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -918,6 +918,7 @@ char* lexname(int lex); void mkpackage(char* pkgname); void unimportfile(void); int32 yylex(void); +extern int windows; extern int yylast; extern int yyprev; diff --git a/src/cmd/gc/obj.c b/src/cmd/gc/obj.c index ae16f2725cf..0d0d70ac965 100644 --- a/src/cmd/gc/obj.c +++ b/src/cmd/gc/obj.c @@ -73,42 +73,97 @@ Bputname(Biobuf *b, Sym *s) Bwrite(b, s->name, strlen(s->name)+1); } +static void +outzfile(Biobuf *b, char *p) +{ + char *q, *q2; + + while(p) { + q = utfrune(p, '/'); + if(windows) { + q2 = utfrune(p, '\\'); + if(q2 && (!q || q2 < q)) + q = q2; + } + if(!q) { + zfile(b, p, strlen(p)); + return; + } + if(q > p) + zfile(b, p, q-p); + p = q + 1; + } +} + +#define isdelim(c) (c == '/' || c == '\\') + +static void +outwinname(Biobuf *b, Hist *h, char *ds, char *p) +{ + if(isdelim(p[0])) { + // full rooted name + zfile(b, ds, 3); // leading "c:/" + outzfile(b, p+1); + } else { + // relative name + if(h->offset == 0 && pathname && pathname[1] == ':') { + if(tolowerrune(ds[0]) == tolowerrune(pathname[0])) { + // using current drive + zfile(b, pathname, 3); // leading "c:/" + outzfile(b, pathname+3); + } else { + // using drive other then current, + // we don't have any simple way to + // determine current working directory + // there, therefore will output name as is + zfile(b, ds, 2); // leading "c:" + } + } + outzfile(b, p); + } +} + static void outhist(Biobuf *b) { Hist *h; - char *p, *q, *op; - int n; + char *p, ds[] = {'c', ':', '/', 0}; for(h = hist; h != H; h = h->link) { p = h->name; - op = 0; - - if(p && p[0] != '/' && h->offset == 0 && pathname && pathname[0] == '/') { - op = p; - p = pathname; - } - - while(p) { - q = utfrune(p, '/'); - if(q) { - n = q-p; - if(n == 0) - n = 1; // leading "/" - q++; + if(p) { + if(windows) { + // if windows variable is set, then, we know already, + // pathname is started with windows drive specifier + // and all '\' were replaced with '/' (see lex.c) + if(isdelim(p[0]) && isdelim(p[1])) { + // file name has network name in it, + // like \\server\share\dir\file.go + zfile(b, "//", 2); // leading "//" + outzfile(b, p+2); + } else if(p[1] == ':') { + // file name has drive letter in it + ds[0] = p[0]; + outwinname(b, h, ds, p+2); + } else { + // no drive letter in file name + outwinname(b, h, pathname, p); + } } else { - n = strlen(p); - q = 0; - } - if(n) - zfile(b, p, n); - p = q; - if(p == 0 && op) { - p = op; - op = 0; + if(p[0] == '/') { + // full rooted name, like /home/rsc/dir/file.go + zfile(b, "/", 1); // leading "/" + outzfile(b, p+1); + } else { + // relative name, like dir/file.go + if(h->offset == 0 && pathname && pathname[0] == '/') { + zfile(b, "/", 1); // leading "/" + outzfile(b, pathname+1); + } + outzfile(b, p); + } } } - zhist(b, h->line, h->offset); } } diff --git a/src/pkg/Makefile b/src/pkg/Makefile index 3a6491a924c..da44167c347 100644 --- a/src/pkg/Makefile +++ b/src/pkg/Makefile @@ -189,7 +189,6 @@ endif # Disable tests that windows cannot run yet. ifeq ($(GOOS),windows) NOTEST+=exec # no pipe -NOTEST+=log # no runtime.Caller NOTEST+=os # many things unimplemented NOTEST+=os/signal # no signals NOTEST+=path # tree walking does not work