changeset 1402:1311dabc6a1f

Merged xfBuild patch for dependency tree generation. See #286.
author Christian Kamm <kamm incasoftware de>
date Wed, 20 May 2009 21:13:41 +0200
parents e2cf1f67ca33
children e5c5d354c649
files dmd/import.c dmd/mars.h gen/cl_options.cpp gen/cl_options.h gen/main.cpp
diffstat 5 files changed, 133 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/dmd/import.c	Wed May 20 16:20:59 2009 +0200
+++ b/dmd/import.c	Wed May 20 21:13:41 2009 +0200
@@ -116,6 +116,25 @@
     //printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
 }
 
+char* escapePath(char* fname, char* buffer, int bufLen) {
+    char* res = buffer;
+    bufLen -= 2;    // for \0 and an occasional escape char
+    int dst = 0;
+    for (; dst < bufLen && *fname; ++dst, ++fname) {
+	switch (*fname) {
+	    case '(':
+	    case ')':
+	    case '\\':
+		    buffer[dst++] = '\\';
+		    // fall through
+
+	    default:
+		    buffer[dst] = *fname;
+	}
+    }
+    buffer[dst] = '\0';
+    return buffer;
+}
 
 void Import::semantic(Scope *sc)
 {
@@ -169,6 +188,68 @@
 	sc = sc->pop();
     }
     //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
+
+
+    if (global.params.moduleDeps != NULL) {
+	char fnameBuf[262];		// MAX_PATH+2
+
+	OutBuffer *const ob = global.params.moduleDeps;
+	ob->printf("%s (%s) : ",
+	    sc->module->toPrettyChars(),
+	    escapePath(sc->module->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf))
+	);
+
+	char* protStr = "";
+	switch (sc->protection) {
+	    case PROTpublic: protStr = "public"; break;
+	    case PROTprivate: protStr = "private"; break;
+	    case PROTpackage: protStr = "package"; break;
+	    default: break;
+	}
+	ob->writestring(protStr);
+	if (isstatic) {
+	    ob->writestring(" static");
+	}
+	ob->writestring(" : ");
+
+	if (this->packages) {
+	    for (size_t i = 0; i < this->packages->dim; i++) {
+		Identifier *pid = (Identifier *)this->packages->data[i];
+		ob->printf("%s.", pid->toChars());
+	    }
+	}
+
+	ob->printf("%s (%s)",
+	    this->id->toChars(),
+	    mod ? escapePath(mod->srcfile->toChars(), fnameBuf, sizeof(fnameBuf) / sizeof(*fnameBuf)) : "???"
+	);
+
+	if (aliasId) {
+	    ob->printf(" -> %s", aliasId->toChars());
+	} else {
+	    if (names.dim > 0) {
+		ob->writestring(" : ");
+		for (size_t i = 0; i < names.dim; i++)
+		{
+		    if (i > 0) {
+			ob->writebyte(',');
+		    }
+
+		    Identifier *name = (Identifier *)names.data[i];
+		    Identifier *alias = (Identifier *)aliases.data[i];
+
+		    if (!alias) {
+			ob->printf("%s", name->toChars());
+			alias = name;
+		    } else {
+			ob->printf("%s=%s", alias->toChars(), name->toChars());
+		    }
+		}
+	    }
+	}
+
+	ob->writenl();
+    }
 }
 
 void Import::semantic2(Scope *sc)
@@ -260,7 +341,27 @@
 	    buf->printf("%s.", pid->toChars());
 	}
     }
-    buf->printf("%s;", id->toChars());
+    buf->printf("%s", id->toChars());
+    if (names.dim > 0) {
+	buf->writebyte(':');
+	for (size_t i = 0; i < names.dim; i++)
+	{
+	    if (i > 0) {
+		    buf->writebyte(',');
+	    }
+
+	    Identifier *name = (Identifier *)names.data[i];
+	    Identifier *alias = (Identifier *)aliases.data[i];
+
+	    if (!alias) {
+		buf->printf("%s", name->toChars());
+		alias = name;
+	    } else {
+		buf->printf("%s=%s", alias->toChars(), name->toChars());
+	    }
+	}
+    }
+    buf->writebyte(';');
     buf->writenl();
 }
 
--- a/dmd/mars.h	Wed May 20 16:20:59 2009 +0200
+++ b/dmd/mars.h	Wed May 20 21:13:41 2009 +0200
@@ -117,6 +117,7 @@
 
 
 struct Array;
+struct OutBuffer;
 
 // LDC
 enum ARCH
@@ -204,7 +205,10 @@
     Array *debuglibnames;	// default libraries for debug builds
 
     const char *xmlname;	// filename for XML output
-
+    
+    OutBuffer *moduleDeps;	// buffer and filename for emitting module deps
+    char *moduleDepsFile;
+    
     // Hidden debug switches
     bool debuga;
     bool debugb;
--- a/gen/cl_options.cpp	Wed May 20 16:20:59 2009 +0200
+++ b/gen/cl_options.cpp	Wed May 20 21:13:41 2009 +0200
@@ -200,6 +200,11 @@
     cl::Prefix);
 
 
+cl::opt<std::string> moduleDepsFile("deps",
+    cl::desc("Write module dependencies to filename"),
+    cl::value_desc("filename"));
+    
+
 cl::opt<const llvm::TargetMachineRegistry::entry*, false,
         llvm::RegistryParser<llvm::TargetMachine> > mArch("march",
     cl::desc("Architecture to generate code for:"));
--- a/gen/cl_options.h	Wed May 20 16:20:59 2009 +0200
+++ b/gen/cl_options.h	Wed May 20 21:13:41 2009 +0200
@@ -35,6 +35,7 @@
     extern cl::opt<std::string> hdrFile;
 #endif
     extern cl::list<std::string> versions;
+    extern cl::opt<std::string> moduleDepsFile;
 
     extern cl::opt<const llvm::TargetMachineRegistry::entry*, false,
                     llvm::RegistryParser<llvm::TargetMachine> > mArch;
--- a/gen/main.cpp	Wed May 20 16:20:59 2009 +0200
+++ b/gen/main.cpp	Wed May 20 21:13:41 2009 +0200
@@ -143,7 +143,9 @@
     global.params.libfiles = new Array();
     global.params.objfiles = new Array();
     global.params.ddocfiles = new Array();
-
+    
+    global.params.moduleDeps = NULL;
+    global.params.moduleDepsFile = NULL;
 
     // Set predefined version identifiers
     VersionCondition::addPredefinedGlobalIdent("LLVM");
@@ -222,6 +224,12 @@
         global.params.hdrdir || global.params.hdrname;
 #endif
 
+    initFromString(global.params.moduleDepsFile, moduleDepsFile);
+    if (global.params.moduleDepsFile != NULL) 
+    { 
+         global.params.moduleDeps = new OutBuffer; 
+    }
+
     processVersions(debugArgs, "debug",
         DebugCondition::setGlobalLevel,
         DebugCondition::addGlobalIdent);
@@ -830,6 +838,17 @@
     if (global.errors)
         fatal();
 
+    // write module dependencies to file if requested
+    if (global.params.moduleDepsFile != NULL) 
+    { 
+        assert (global.params.moduleDepsFile != NULL);
+
+        File deps(global.params.moduleDepsFile);
+        OutBuffer* ob = global.params.moduleDeps; 
+        deps.setbuffer((void*)ob->data, ob->offset);
+        deps.write();
+    }
+
     // collects llvm modules to be linked if singleobj is passed
     std::vector<llvm::Module*> llvmModules;