D patches
Lars Ivar Igesund <[email protected]> Thu, 21 Oct 2004 18:14:17 +0100
| Newsgroups | gmane.comp.tools.aap.devel |
|---|---|
| Message-ID | <[email protected]> |
A previous patch of mine was subtly changed upon inclusion in CVS, resulting in a non-functional CVS (and latest release). d.diff should repair that (apply to d.aap). ddepcheck has been through a major overhaul, making it more robust and more efficient (apply ddepcheck.diff). The dmd tool has gotten better support for dlls (didn't I post this patch previously?) Lars Ivar Igesund
d.diff
(text/plain, 793 B)
Index: d.aap
===================================================================
RCS file: /cvsroot/a-a-p/Exec/modules/d.aap,v
retrieving revision 1.16
diff -u -r1.16 d.aap
--- d.aap 10 Sep 2004 18:58:43 -0000 1.16
+++ d.aap 21 Oct 2004 15:56:32 -0000
@@ -91,9 +91,9 @@
@if _no.targettype == "object":
:attr {buildaction = d_build} $target
@elif _no.targettype == "libobject":
- :attr {buillibdaction = d_buildlib} $target
+ :attr {buildlibaction = d_buildlib} $target
@elif _no.targettype == "dllobject":
- :attr {buildlldaction = d_builddll} $target
+ :attr {builddllaction = d_builddll} $target
@if DEFER_ACTION_NAME:
:do $DEFER_ACTION_NAME {target = $target} $source
@else:
ddepcheck.diff
(text/plain, 32.5 KB)
Index: ddepcheck.d
===================================================================
RCS file: /cvsroot/a-a-p/Exec/tools/ddepcheck.d,v
retrieving revision 1.5
diff -u -r1.5 ddepcheck.d
--- ddepcheck.d 19 Apr 2004 08:53:47 -0000 1.5
+++ ddepcheck.d 21 Oct 2004 16:00:35 -0000
@@ -1,7 +1,7 @@
/*
* ddepcheck.d
- * Version 0.9.6
- * Last modified 18th of April 2004
+ * Version 1.0.1
+ * Last modified 24th of August 2004
*
* Dependency walker for D source files.
* Copyright 2003-2004 Lars Ivar Igesund <larsivar'at'igesund.net>
@@ -14,23 +14,39 @@
* or implied warranty.
*/
+/*
+ * TODO:
+ * - Audit code, some of it is hairy as hell.
+ * - Exchange ctype with utype when it shows up
+ * - Document better, especially code
+ * - Long term; With multiple input files, cache import results.
+ */
+
+import std.conv;
+import std.ctype;
import std.file;
import std.path;
import std.stream;
import std.string;
import std.c.stdio;
+import std.stdio;
+
+alias std.ctype.isdigit isdigit;
version (Win32) {
import std.c.windows.windows;
}
-bool helpcalled = false;
-bool versioncalled = false;
-bool write = false;
-bool makesyntax = false;
-bool comment = false;
-bool runtime = false;
-bool checkprivate = false;
+bit helpcalled = false;
+bit versioncalled = false;
+bit write = false;
+bit makesyntax = false;
+bit comment = false;
+bit runtime = false;
+bit checkprivate = false;
+bit fulldebug = false;
+bit disableversion = false;
+bit disabledebug = false;
int curopt = 1;
int numpaths = 0;
int allpaths = 10;
@@ -44,6 +60,51 @@
char [][] depdepths;
char [][] paths;
char [][] argslist;
+char [][] dbgidentsstr;
+char [][] veridentsstr;
+int [][] privatearr;
+int dbgidentsnum;
+int veridentsnum;
+
+/*!
+ * Static constructor.
+ * Adds version identifier strings to the list used by ddepcheck based on what
+ * is defined by the compiler.
+ */
+
+static this()
+{
+version (DigitalMars) {
+ veridentsstr ~= "DigitalMars";
+}
+version (X86) {
+ veridentsstr ~= "X86";
+}
+version (AMD64) {
+ veridentsstr ~= "AMD64";
+}
+version (Windows) {
+ veridentsstr ~= "Windows";
+}
+version (Win32) {
+ veridentsstr ~= "Win32";
+}
+version (Win64) {
+ veridentsstr ~= "Win64";
+}
+version (linux) {
+ veridentsstr ~= "linux";
+}
+version (LittleEndian) {
+ veridentsstr ~= "LittleEndian";
+}
+version (BigEndian) {
+ veridentsstr ~= "BigEndian";
+}
+version (D_InlineAsm) {
+ veridentsstr ~= "D_InlineAsm";
+}
+}
/*
* Function called when the "help" option is specified.
@@ -53,20 +114,29 @@
{
optVersion();
if (!helpcalled) {
- printf(toStringz("\n" ~
- "Syntax: ddepcheck [options] [src ...]\n" ~
- " -I[path] Add a path to be searched.\n" ~
- " -h/--help Prints this help table.\n" ~
- " -d=[num]/--depth=[num] Limit the depth searched \n" ~
- " for dependencies.\n" ~
- " -m/--make-syntax Print the dependencies using the make\n" ~
- " syntax. \"objectfile : src deps\"\n" ~
- " -V/--version Prints the version.\n" ~
- " -w/--writetofile Prints the dependencies to the file\n" ~
- " 'depfile' instead of to the console.\n" ~
- " -l/--checkruntimelib Tries to add runtimelib dependencies.\n" ~
- " Note that the path must be added \n" ~
- " explicitly."));
+ writefln();
+ writefln("Syntax: ddepcheck [options] [src ...]");
+ writefln(" -I[path] Add a path to be searched.");
+ writefln(" -h/--help Prints this help table.");
+ writefln(" -d=[num]/--depth=[num] Limit the depth searched");
+ writefln(" for dependencies.");
+ writefln(" -m/--make-syntax Print the dependencies using the make");
+ writefln(" syntax. \"objectfile : src deps\"");
+ writefln(" -V/--version Prints the version.");
+ writefln(" -w/--writetofile Prints the dependencies to the file");
+ writefln(" 'depfile' instead of to the console.");
+ writefln(" -l/--checkruntimelib Tries to add runtimelib dependencies.");
+ writefln(" Note that the path must be added ");
+ writefln(" explicitly.");
+ writefln(" --checkprivate Ignore private if it affects the import");
+ writefln(" -debug=[ident/num] Uses the same switch as the compiler");
+ writefln(" to remove/include debug codeblocks.");
+ writefln(" -version=[ident/num] Uses the same switch as the compiler");
+ writefln(" to remove/include version codeblocks.");
+ writefln(" -disableVersion Don't check for version statements.");
+ writefln(" (All imports are checked.)");
+ writefln(" -disableDebug Don't check for debug statements.");
+ writefln(" (All imports are checked.)");
}
helpcalled = true;
}
@@ -80,7 +150,7 @@
runtime = true;
}
-/*
+/*!
* Function called when the "checkprivate" option is specified.
*/
@@ -89,21 +159,21 @@
checkprivate = true;
}
-/*
+/*!
* Function called if the "version" option is used.
*/
void optVersion()
{
if (!versioncalled) {
- printf(toStringz("ddepcheck\n" ~
- "Dependency walker for D source files.\n" ~
- "Version 0.9.4 Copyright Lars Ivar Igesund 2003\n"));
+ writefln("ddepcheck");
+ writefln("Dependency walker for D source files.");
+ writefln("Version 1.0.1 Copyright Lars Ivar Igesund 2003 - 2004");
}
versioncalled = true;
}
-/*
+/*!
* Function called if the "writetofile" option is used.
*/
@@ -112,22 +182,22 @@
write = true;
}
-/*
+/*!
* Function called if the "depth" option is used to decide the maximum
* depth for recursion.
*/
-void optDepth(int arg, bool doubledash)
+void optDepth(int arg, bit doubledash)
{
if (doubledash) {
- depthlimit = (int)atoi(argslist[arg][8..argslist[arg].length]);
+ depthlimit = cast(int)atoi(argslist[arg][8..argslist[arg].length]);
}
else {
- depthlimit = (int)atoi(argslist[arg][3..argslist[arg].length]);
+ depthlimit = cast(int)atoi(argslist[arg][3..argslist[arg].length]);
}
}
-/*
+/*!
* Function called for all the "-I" import options used.
*/
@@ -139,7 +209,47 @@
addPath(argslist[arg][2..argslist[arg].length]);
}
-/*
+/*!
+ * Function called for all the "-debug" options used.
+ */
+
+void optDebug(int arg)
+{
+ if (argslist[arg].length == 6) {
+ fulldebug = true;
+ }
+ else {
+ char [] ident = argslist[arg][7..argslist[arg].length];
+ bit num = isNumber(ident);
+ if (num) {
+ dbgidentsnum = toInt(ident);
+ }
+ else {
+ dbgidentsstr ~= ident;
+ }
+ }
+}
+
+/*!
+ * Function called for all the "-version" options used.
+ */
+
+void optVersion(int arg)
+{
+ if (argslist[arg].length == 2) {
+ return;
+ }
+ char [] ident = argslist[arg][9..argslist[arg].length];
+ bit num = isNumber(ident);
+ if (num) {
+ veridentsnum = toInt(ident);
+ }
+ else {
+ veridentsstr ~= ident;
+ }
+}
+
+/*!
* Function called when the "-m"/"--make-syntax" option is used.
*/
@@ -148,11 +258,29 @@
makesyntax = true;
}
-/*
+/*!
+ * Function called when the "-disableVersion" option is used.
+ */
+
+void optDisableVersion()
+{
+ disableversion = true;
+}
+
+/*!
+ * Function called when the "-disableDebug" option is used.
+ */
+
+void optDisableDebug()
+{
+ disabledebug = true;
+}
+
+/*!
* Function that checks if an argument is an option.
*/
-bool checkOption(int arg)
+bit checkOption(int arg)
{
switch (argslist[arg]) {
case "--version":
@@ -185,10 +313,19 @@
optCheckPrivate();
return true;
break;
+ case "--disableVersion":
+ optDisableVersion();
+ return true;
+ break;
+ case "--disableDebug":
+ optDisableDebug();
+ return true;
+ break;
default:
break;
}
- if (cmp(argslist[arg][0..3], "-d=") == 0) {
+ if (argslist[arg].length > 3 &&
+ cmp(argslist[arg][0..3], "-d=") == 0) {
optDepth(arg, false);
return true;
}
@@ -197,14 +334,25 @@
optDepth(arg, true);
return true;
}
- if (cmp(argslist[arg][0..2], "-I") == 0) {
+ if (argslist[arg].length > 2 &&
+ cmp(argslist[arg][0..2], "-I") == 0) {
optImport(arg);
return true;
}
+ if (argslist[arg].length > 5 &&
+ cmp(argslist[arg][0..6], "-debug") == 0) {
+ optDebug(arg);
+ return true;
+ }
+ if (argslist[arg].length > 8 &&
+ cmp(argslist[arg][0..8], "-version") == 0) {
+ optVersion(arg);
+ return true;
+ }
return false;
}
-/*
+/*!
* Function that starts the dependency walking for base source files.
*/
@@ -214,85 +362,669 @@
depWalk(argslist[arg], "", true);
}
-/*
+/*!
* Function that do the main dependency walking recursively. If it find
* files that has been walked before, it skips it to avoid infinite
* cyclic dependencies.
*/
-void depWalk(char [] file, char [] mod, bool base)
+void depWalk(char [] file,char [] mod, bit base)
{
+ debug writefln("Filename: ", file);
+
char [] filepath = file;
- int i = 0;
- while (i < numpaths && !fileExist(filepath)) {
- filepath = std.path.join(paths[i], file);
- i++;
+ char [] src;
+ int pathnum = 0;
+ int [] importpos;
+ importpos.length = 0;
+ int nextimport = -1;
+ char [][] verspecstrings;
+ char [][] dbgspecstrings;
+
+ while (pathnum < numpaths && !fileExist(filepath)) {
+ filepath = std.path.join(paths[pathnum], file);
+ pathnum++;
}
+
+ try {
+ src = (new File(filepath)).toString();
+ }
+ catch (Error e) {
+ return;
+ }
+
if (!base) {
if (!addDep(filepath, mod, depth)) {
return;
}
}
- File src = new File(filepath);
- while (!src.eof()) {
- char [] line = src.readLine();
- if (stripComment(line)) {
- continue;
+
+ stripComment(src);
+
+
+ bit useVersion(int pos)
+ {
+ int i = pos + 7;
+ int j;
+ while (src[i] != '(') {
+ i++;
+ }
+ j = i + 1;
+ while (src[j] != ')') {
+ j++;
+ }
+ char [] ident = src[i + 1..j];
+ if (ident.length == 0) {
+ return true;
+ }
+ bit num = true;
+ foreach (char c; ident) {
+ if (!isdigit(c)) {
+ num = false;
+ break;
+ }
+ }
+ if (num) {
+ int identnum = toInt(ident);
+ if (veridentsnum >= identnum) {
+ return true;
+ }
+ }
+ else {
+ foreach (char [] id; veridentsstr) {
+ if (id == ident) {
+ return true;
+ }
+ else if (id == "none") {
+ return false;
+ }
+ }
}
- char [][] statements = split(line, ";");
- for (int i = 0; i < statements.length; i++ ) {
- int pos = find(statements[i], "import");
- if (pos == -1) {
- continue;
+ return false;
+ }
+
+ void search(int a, int z)
+ {
+ int dbgfound = -1;
+ int verfound = -1;
+ int impfound = -1;
+ int privfound = -1;
+
+ int dbgend = -1;
+ int verend = -1;
+ int i = a;
+
+ bit moreimports = false;
+ bit keepprivate = false;
+
+ bit useDebug(int pos)
+ {
+ int i = pos + 5;
+ int j;
+ if (i >= src.length) {
+ return false;
+ }
+ while (i < (src.length - 1) && isspace(src[i])) {
+ i++;
+ }
+ if (src[i] == '(') {
+ j = i + 1;
+ while (j < (src.length - 1) && src[j] != ')') {
+ j++;
+ }
+ char [] ident = src[i + 1..j];
+ bit num = true;
+ foreach (char c; ident) {
+ if (!isdigit(c)) {
+ num = false;
+ break;
+ }
+ }
+ if (num) {
+ int identnum = toInt(ident);
+ if (dbgidentsnum <= identnum) {
+ return true;
+ }
+ }
+ else {
+ foreach (char [] id; dbgidentsstr ~ dbgspecstrings) {
+ if (id == ident) {
+ return true;
+ }
+ }
+ }
+ if (fulldebug) {
+ return false;
+ }
}
else {
- if (!base && !checkprivate) {
- int privpos = rfind(statements[i], "private");
- if (privpos > -1 && privpos < pos) {
- char [] impstmt = statements[i][privpos..pos+7];
- char [][] words = split(impstmt);
- if (words.length == 2) {
- continue;
+ if (fulldebug) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bit isKeyword(int startpos, int length)
+ {
+ if (startpos < 0) {
+ debug writefln("- isKeyword startpos < 0.");
+ return false;
+ }
+ if (startpos + length >= src.length) {
+ return false;
+ }
+ debug writefln("- Checking keyword ", src[startpos..(startpos + length)]);
+ if (startpos == 0 || isspace(src[startpos - 1]) ||
+ src[startpos] == ';') {
+ debug writefln("- isKeyword: inside first nested if.");
+ if (((startpos + length) == src.length) ||
+ isspace(src[startpos + length]) ||
+ (src[startpos..startpos + length] == "debug" &&
+ src[startpos + length] == ':')) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ int findBlockEnd(int pos)
+ {
+ int levels = 0;
+ debug writefln("- Finding block end after pos ", pos);
+
+ int j = pos;
+ if (pos >= src.length) {
+ return 0;
+ }
+ while (j < (src.length - 1) && isspace(src[j])) {
+ j++;
+ }
+
+ int findEnd()
+ {
+ while (isspace(src[j])) {
+ j++;
+ }
+ if (src[j] == '{') {
+ levels++;
+ while (levels) {
+ j++;
+ if (src[j] == '{') {
+ levels++;
+ }
+ else if (src[j] == '}') {
+ levels--;
}
}
+ return j;
+ }
+ else {
+ return 0;
+ }
+ }
+
+ int retval = -1;
+ if (src[j] != '(') {
+ retval = findEnd();
+ debug writefln("- Found end at pos ", retval);
+ return retval;
+ }
+ else {
+ j++;
+ while (src[j] != ')') {
+ j++;
+ }
+ j++;
+ }
+
+ retval = findEnd();
+ debug writefln("- Found end at pos ", retval);
+ return retval;
+ }
+
+ int findAttrEnd(int pos, bit priv = false)
+ {
+ int j = pos;
+ if (pos >= src.length) {
+ return 0;
+ }
+ while (j < (src.length - 1) && isspace(src[j])) {
+ j++;
+ }
+ if (src[j] == ':') {
+ while (j < (src.length - 1) && src[j] != '}') {
+ j++;
}
- char [] mod = strip(statements[i][pos+7..statements[i].length]);
- if (statements[i][pos+6..pos+7] == r" ") {
- if (!checkIfModule(mod)) {
- continue;
+ int pub = find(src[pos..j], "public");
+ int prot = find(src[pos..j], "protected");
+ int best = -1;
+ if (isKeyword(pub, 6)) {
+ best = pub;
+ }
+ if (prot > -1 && prot < pub) {
+ if (isKeyword(prot, 9)) {
+ best = prot;
}
}
+ if (best > -1) {
+ return best;
+ }
else {
- continue;
+ return j;
+ }
+ }
+ else {
+ return 0;
+ }
+ }
+
+ int findDebugAndVersionEnd(int pos, bit ver, bit other)
+ {
+ int findSpecEnd(int pos)
+ {
+ if (other) {
+ return 0;
+ }
+
+ int j = pos;
+ if (pos >= src.length) {
+ return 0;
+ }
+ while (j < (src.length - 1) && isspace(src[j])) {
+ j++;
+ }
+ if (src[j] == '=') {
+ int startidx = -1;
+ j++;
+ while (j < (src.length - 1) && src[j] != ';') {
+ if (startidx == -1 && isalnum(src[j])) {
+ startidx = j;
+ }
+ j++;
+ }
+ char [] ident = src[startidx..j];
+ if (ident.length > 0) {
+ bit num = isNumber(ident);
+ if (ver) {
+ if (num) {
+ try {
+ veridentsnum = toInt(ident);
+ }
+ catch (Exception e) {
+ // Catching top exception here due to strange naming
+ // conventions in Phobos. larsivi 20040724
+ return j;
+ }
+ }
+ else {
+ verspecstrings ~= ident;
+ }
+ }
+ else {
+ if (num) {
+ try {
+ dbgidentsnum = toInt(ident);
+ }
+ catch (Exception e) {
+ // Catching top exception here due to strange naming
+ // conventions in Phobos. larsivi 20040724
+ return j;
+ }
+ }
+ else {
+ dbgspecstrings ~= ident;
+ }
+ }
+ }
+ return j;
+ }
+ return 0;
+ }
+
+ int findStmntEnd(int pos)
+ {
+ int j = pos;
+ if (pos >= src.length) {
+ return 0;
+ }
+ while (j < (src.length - 1) && src[j] != ';') {
+ j++;
}
- char [] fp;
- if (!runtime) {
- if (checkPhobos(mod)) {
- continue;
+ return j;
+ }
+
+ int i = pos;
+ int res = 0;
+
+ if (i >= src.length) {
+ return -1;
+ }
+
+ if (other) {
+ i += 4;
+ }
+ else if (ver) {
+ i += 7;
+ }
+ else {
+ i += 5;
+ }
+
+ if (cast(bit)(res = findSpecEnd(i))) {
+ return res;
+ }
+ else if (cast(bit)(res = findBlockEnd(i))) {
+ return res;
+ }
+ else if (cast(bit)(res = findAttrEnd(i))) {
+ return res;
+ }
+ else if (cast(bit)(res = findStmntEnd(i))) {
+ return res;
+ }
+ else {
+ return -1;
+ }
+ }
+
+ int findElse(int pos, bit ver, inout bit elseif)
+ {
+ int i = pos;
+ while (isspace(src[i++])) { }
+ if (src[i..i + 4] == "else") {
+ i += 4;
+ while (isspace(src[i++])) { }
+ if (ver) {
+ if (src[i..i + 7] == "version") {
+ elseif = true;
}
}
- fp = createFilePath(mod);
- depth++;
- if (depthlimit == -1 || depth <= depthlimit) {
- depWalk(fp, mod, false);
+ else {
+ if (src[i..i + 5] == "debug") {
+ elseif = true;
+ }
}
- depth--;
+ return findDebugAndVersionEnd(i, ver, true);
+ }
+ else {
+ return -1;
}
}
+
+ int checkDebugAndVersion(int pos, bit ver)
+ {
+ int i = pos + (ver ? 7 : 5);
+
+ int findElseifStart(int pos)
+ {
+ int i = pos;
+ while (isspace(src[i++])) { }
+ if (src[i..i + 4] == "else") {
+ i += 4;
+ while (isspace(src[i++])) { }
+ }
+ else {
+ return -1;
+ }
+ return i;
+ }
+
+ debug {
+ if (ver) {
+ writefln("- Checking if version identifier at ", pos, " is set.");
+ }
+ else {
+ writefln("- Checking if debug identifier at ", pos, " is set.");
+ }
+ }
+
+ int elseend = -1;
+ int end = findDebugAndVersionEnd(pos, ver, false);
+ int found = -1;
+ bit elseif = false;
+
+ if (end == -1) {
+ debug writefln("- No end found.");
+ return i;
+ }
+
+ elseend = findElse(end, ver, elseif);
+ debug writefln("- Value of elsend is ", elseend);
+ debug {
+ if (elseif) {
+ writefln("- Value of elseif is true");
+ }
+ }
+
+ if (ver ? useVersion(pos) : useDebug(pos)) {
+ debug writefln("- Using primary debug/version part.");
+ search(i, end);
+ while (elseif) {
+ elseend = findElse(elseend, ver, elseif);
+ }
+ if (elseend > -1) {
+ return elseend + 1;
+ }
+ else {
+ debug writefln("- Ending checkDebugAndVersion with value ", end + 1);
+ return end + 1;
+ }
+ }
+ else if (elseend > -1) {
+ while (elseif) {
+ int elseifstart = findElseifStart(end);
+ debug writefln("- Found elseif start at pos ", elseifstart);
+ if (ver ? useVersion(elseifstart) : useDebug(elseifstart)) {
+ search(elseifstart, elseend);
+ while (elseif) {
+ elseend = findElse(elseend, ver, elseif);
+ }
+ return elseend + 1;
+ }
+ end = elseifstart;
+ elseend = findElse(elseend, ver, elseif);
+ }
+ search(end + 1, elseend);
+ return elseend + 1;
+ }
+
+ debug writefln("- Version identifier not set.");
+
+ return i + 1;
+ }
+
+ int handleDebug(int pos)
+ {
+ return checkDebugAndVersion(pos, false);
+ }
+
+ int handleVersion(int pos)
+ {
+ return checkDebugAndVersion(pos, true);
+ }
+
+ int handleImport(int pos)
+ {
+ bit checkPrivate(int pos)
+ {
+ foreach (int [] positions; privatearr) {
+ if (pos > positions[0] && pos < positions[1]) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ debug writefln("- Handling import at position ", pos);
+ int endpos;
+ int i = pos + 8;
+ while (true) {
+ if (src[i] == ',') { // several imports following an 'import' keyword
+ moreimports = true;
+ break;
+ }
+ else if (src[i] == ';') { // last import in a list
+ moreimports = false;
+ break;
+ }
+ i++;
+ if (i == src.length) {
+ return i;
+ }
+ }
+ endpos = i;
+ if (!base && !checkprivate) {
+ if (pos > 7) {
+ if (keepprivate) {
+ debug writefln("- Ending due to private import");
+ return endpos + 1;
+ }
+ else if (checkPrivate(pos)) {
+ debug writefln("- Ending due to private import");
+ return endpos + 1;
+ }
+ i = pos - 1;
+ while (isspace(src[i]) && i > 7) {
+ i--;
+ }
+ if (i >= 7 && src[i - 6..i + 1] == "private") {
+ keepprivate = moreimports ? true : false;
+ debug writefln("- Ending due to private import");
+ return endpos + 1;
+ }
+ }
+ }
+ char [] mod = strip(src[pos + 6..endpos]);
+ debug writefln("- Handling import ", mod);
+ if (!checkIfModule(mod)) {
+ return endpos + 1;
+ }
+ if (!runtime) {
+ if (checkPhobos(mod)) {
+ return endpos + 1;
+ }
+ }
+ char [] fp = createFilePath(mod);
+ depth++;
+ if (depthlimit == -1 || depth <= depthlimit) {
+ depWalk(fp, mod, false);
+ }
+ depth--;
+ debug writefln("- Ending handling import ", mod, " at pos ", endpos);
+ return endpos + 1;
+ }
+
+ int delegate(int) handler;
+ int best;
+
+ do {
+ handler = null;
+ best = z + 1;
+ uint belowz = z;
+
+ if (!checkprivate) {
+ int privstart = -1;
+ do {
+ int privend = 0;
+ debug writefln("- Searching for private from ", i, " to ", z);
+ privfound = find(src[i..z], "private");
+ if (privfound > -1) {
+ int privstart = privfound + i;
+ if (isKeyword(privstart, 7)) {
+ privend = findBlockEnd(privstart);
+ if (!privend) {
+ privend = findAttrEnd(privstart, true);
+ }
+ if (privend) {
+ privatearr[privatearr.length][0] = privstart;
+ privatearr[privatearr.length][1] = privend;
+ }
+ }
+ }
+ } while (privstart > -1);
+ }
+
+ debug writefln("- Searching for import from ", i, " to ", z);
+ impfound = find(src[i..z], "import");
+ if (impfound > -1) {
+ impfound += i;
+ belowz = impfound;
+ }
+ if (!disabledebug) {
+ debug writefln("- Searching for debug from ", i, " to ", belowz);
+ dbgfound = find(src[i..belowz], "debug");
+ if (dbgfound > -1) {
+ dbgfound += i;
+ belowz = dbgfound < belowz ? dbgfound : belowz;
+ }
+ }
+ if (!disableversion) {
+ debug writefln("- Searching for version from ", i, " to ", belowz);
+ verfound = find(src[i..belowz], "version");
+ if (verfound > -1) {
+ verfound += i;
+ }
+ }
+
+ if (impfound > -1) {
+ debug writefln("- Value of impfound is ", impfound, " and i is ", i);
+ if (isKeyword(impfound, 6)) {
+ best = impfound;
+ debug writefln("- Import found at pos ", best);
+ handler = &handleImport;
+ }
+ }
+ if (!disabledebug) {
+ if (dbgfound > -1 && (dbgfound) < best) {
+ if (isKeyword(dbgfound, 5)) {
+ best = dbgfound;
+ debug writefln("- Debug found at pos ", best);
+ handler = &handleDebug;
+ }
+ }
+ }
+ if (!disableversion) {
+ if (verfound > -1 && (verfound) < best) {
+ if (isKeyword(verfound, 7)) {
+ best = verfound;
+ debug writefln("- Version found at pos ", best);
+ handler = &handleVersion;
+ }
+ }
+ }
+ if (!(handler is null)) {
+ i = handler(best);
+ while (moreimports) {
+ i = handler(i);
+ }
+ }
+ else {
+ break;
+ }
+ } while (i < z);
}
+
+ int pos = 0;
+ int found = -1;
+
+ search(0, src.length);
+
+ dbgidentsstr ~= dbgspecstrings;
+ veridentsstr ~= verspecstrings;
}
-/*
+/*!
* Function that adds a dependency to the list when it is verified.
* A path and the depth where it was found is also added. If the
* dependency has been found before, the new depth is added to the
* same entry.
*/
-bool addDep(char [] filepath, char [] mod, int depth)
+bit addDep(char [] filepath, char [] mod, int depth)
{
for (int i = 0; i < numdeps; i++) {
- if (cmp(depmods[i], mod) == 0) {
+ if (depmods[i] == mod) {
depdepths[i] ~= ",";
depdepths[i] ~= toString(depth);
return false;
@@ -306,14 +1038,14 @@
depfiles.length = alldeps;
depdepths.length = alldeps;
}
- depmods[numdeps-1] = mod;
- depfiles[numdeps-1] = filepath;
- depdepths[numdeps-1] = toString(depth);
+ depmods[numdeps - 1] = mod;
+ depfiles[numdeps - 1] = filepath;
+ depdepths[numdeps - 1] = toString(depth);
return true;
}
-/*
+/*!
* Function that adds the filename of the current checked file to
* the printout.
*/
@@ -334,50 +1066,58 @@
depdepths[numdeps-3] = depdepths[numdeps-2] = depdepths[numdeps-1] = "";
}
-/*
+/*!
* Function that takes a module name and creates a real path.
*/
char [] createFilePath(char [] mod)
{
- char [] tempmode;
- tempmode = replace(mod, ".", sep);
- tempmode ~= ".d";
- return tempmode;
+ char [] tempmod;
+ tempmod = replace(mod, ".", sep);
+ tempmod ~= ".d";
+ return tempmod;
}
-/*
+/*!
* Checks if the found dependency is a part of phobos in which case
* it is ignored.
*/
-bool checkPhobos(char [] mod)
+bit checkPhobos(char [] mod)
{
- if (cmp(mod, "Object") == 0) return true;
- else if (cmp(mod[0..4], "std.") == 0) return true;
- else return false;
+ if (mod == "Object") {
+ return true;
+ }
+ else if (mod.length < 4) {
+ return false;
+ }
+ else if (cmp(mod[0..4], "std.") == 0) {
+ return true;
+ }
+ else {
+ return false;
+ }
}
-/*
+/*!
* Checks if the found module really can be a module since the parsing
* is a bit hackish.
*/
-bool checkIfModule(char [] mod)
+bit checkIfModule(char [] mod)
{
- char [] illchars = ")([]/,+?";
- if (find(letters, mod[0]) == -1) {
+ if (!isalpha(mod[0])) {
return false;
}
- for (int i = 1; i < mod.length; i++) {
- if (find(illchars, mod[i]) > -1) {
+ foreach (char c; mod[1..mod.length]) {
+ if (!(isalnum(c) || c == '.')) {
return false;
}
}
return true;
}
-/*
+/*!
* Adds a path given with "-I" to the path list.
*/
@@ -391,18 +1131,18 @@
paths[numpaths - 1] = path;
}
-/*
+/*!
* Checks if a file exist.
*/
-bool fileExist(char [] file)
+bit fileExist(char [] file)
{
version (Win32) {
return (GetFileAttributesA(toStringz(file)) != 0xFFFFFFFF);
}
version (Linux) {
// FIXME: I guess there is a better way to do this. larsivi 18042004
- bool result = true;
+ bit result = true;
try {
read(file);
}
@@ -413,56 +1153,103 @@
}
}
-/*
- * Strip of the comments.
- * Returns true if the whole line is a comment.
+/*!
+ * Checks if the string is a number. Returns true if it is.
*/
-bool stripComment(inout char[] line)
+bit isNumber(char [] ident)
{
- int res = -1;
- bool startascomment = comment;
-
- void toWhiteSpace(inout char[] line, int start, int stop)
- {
- for (int i = start; i < stop; i++) {
- line[i] = ' ';
+ foreach (char c; ident) {
+ if (!isdigit(c)) {
+ return false;
}
}
+ return true;
+}
- void endStarComment(inout char[] line)
- {
- if (comment) {
- res = find(line, "*/");
- if (res > -1) {
- comment = false;
- toWhiteSpace(line, 0, res);
- }
- }
- }
- endStarComment(line);
+/*!
+ * Convert a substring in src to whitespace.
+ */
- res = find(line, "//");
- if (res > - 1) {
- toWhiteSpace(line, res, line.length);
- if (res < 1) {
- return false;
- }
- }
+void toWhiteSpace(inout char [] src, int start, int end)
+in {
+ assert (end > start);
+ assert (start >= 0);
+ assert (end <= src.length);
+}
+body {
+ src[start..end] = ' ';
+}
- res = find(line, "/*");
- if (res > -1) {
- comment = true;
- toWhiteSpace(line, res, line.length);
- }
+/*!
+ * Strip off the comments.
+ */
- endStarComment(line);
+void stripComment(inout char[] src)
+{
+ int len = src.length;
+ int doubleslash = -1;
+ int star = -1;
+ int plus = 0;
+ int plusstart = -1;
+
+ for (int i = 0; i < len; i++) {
+ if (doubleslash > -1) {
+ if (src[i] == '\\') {
+ if (src[i + 1] == 'n') {
+ toWhiteSpace(src, doubleslash, i + 2);
+ i++;
+ doubleslash = -1;
+ continue;
+ }
+ }
+ continue;
+ }
+ else if (star > -1) {
+ if (src[i] == '*') {
+ if (src[i + 1] == '/') {
+ toWhiteSpace(src, star, i + 2);
+ i++;
+ star = -1;
+ continue;
+ }
+ }
+ continue;
+ }
+ else if (plus) {
+ if (src[i] == '+') {
+ if (src[i + 1] == '/') {
+ i++;
+ plus--;
+ if (!plus) {
+ toWhiteSpace(src, plusstart, i + 1);
+ plusstart = -1;
+ }
+ continue;
+ }
+ }
+ }
- return startascomment && comment;
+ if (src[i] == '/') {
+ i++;
+ if (src[i] == '/') {
+ doubleslash = i - 1;
+ }
+ else if (src[i] == '*') {
+ star = i - 1;
+ }
+ else if (src[i] == '+') {
+ if (!plus) {
+ plusstart = i - 1;
+ }
+ plus++;
+ }
+ }
+ }
}
-/*
+/*!
* Writes dependencies to file.
*/
@@ -475,7 +1262,7 @@
depfile.close();
}
-/*
+/*!
* Prints dependencies to stdout.
*/
@@ -489,19 +1276,18 @@
version (linux) {
objsuf = ".o";
}
- printf(toStringz(replace(argslist[firstfile], ".d", objsuf) ~ " : "));
- printf(toStringz(argslist[firstfile]));
+ writef(replace(argslist[firstfile], ".d", objsuf), " : ");
+ writef(argslist[firstfile]);
if (numdeps > 3) {
- printf(toStringz(" "));
+ writef(" ");
for (int i = 3; i < numdeps; i++) {
- printf(toStringz(depfiles[i] ~ " "));
+ writef(depfiles[i], " ");
}
}
}
else {
for (int i = 0; i < numdeps; i++) {
- printf(toStringz(depmods[i] ~ " " ~ depfiles[i] ~ " " ~
- depdepths[i] ~ "\n"));
+ writefln(depmods[i], " ", depfiles[i], " ", depdepths[i]);
}
}
}
@@ -526,12 +1312,18 @@
if (curopt < args.length) {
firstfile = curopt;
for (int i = curopt; i < args.length; i++) {
+ // FIXME: Handle multiple input files better
+ // larsivi 20040715
depBase(i);
}
}
- if (write) printToFile();
- else printToStdout();
+ if (write) {
+ printToFile();
+ }
+ else {
+ printToStdout();
+ }
return 0;
}
dmd.diff
(text/plain, 4.2 KB)
Index: dmd.py
===================================================================
RCS file: /cvsroot/a-a-p/Exec/tools/dmd.py,v
retrieving revision 1.11
diff -u -r1.11 dmd.py
--- dmd.py 26 Aug 2004 15:29:36 -0000 1.11
+++ dmd.py 21 Oct 2004 15:59:33 -0000
@@ -51,6 +51,11 @@
outtypes = ["object", "libobject", "dllobject"],
intypes = ["d"])
+ define_action("compile_dmd", 0, """
+ DLINKFLAGS += source
+ """,
+ intypes = ["def"])
+
# Build a program from object files
define_action("build_dmd", 0, """
DLINKFLAGS += /DELEXECUTABLE
@@ -81,22 +86,29 @@
# Build a dll from object files
define_action("builddll_dmd", 0, """
DLINKFLAGS += /DELEXECUTABLE
- @exec "import tools.dmd"
@if os.name == "nt":
DIMPLIB ?=
- @if DIMPLIB and DIMPLIB == "yes":
+ @exec "import tools.dmd"
+ @if _no.DIMPLIB and _no.DIMPLIB == "yes":
DLINKFLAGS += /implib
- @if not tools.dmd.find_dll_main_object(source):
- @f = file("aap_dllmain.d", 'w')
- @f.write(tools.dmd.dll_main_source())
- @f.close()
- :do compile {target = aap_dllmain.obj} aap_dllmain.d
- source += aap_dllmain.obj
+ @if not tools.dmd.find_dll_main_object(source):
+ @f = file("aap_dllmain.d", 'w')
+ @f.write(tools.dmd.dll_main_source())
+ @f.close()
+ :do compile {target = aap_dllmain.obj} aap_dllmain.d
+ source += aap_dllmain.obj
+ @if not tools.dmd.find_def_file(source):
+ @f = file("aap_dll.def", 'w')
+ @f.write(tools.dmd.dll_def_file(target))
+ @f.close()
+ source += aap_dll.def
:sys $DMD -L$*?DLINKFLAGS -L+$*?LIBS -of$target $source
- :del {f} {q} aap_dllmain.*
+ @if os.name == "nt":
+ :del {f} {q} aap_dllmain.*
+ :del {f} {q} aap_dll.def
""",
outtypes = ["default"],
- intypes = ["dllobject"])
+ intypes = ["dllobject", "def"])
# Build a program directly from source
define_action("buildonestep_dmd", 0, """
@@ -149,19 +161,26 @@
DIMPLIB ?=
@if DIMPLIB and DIMPLIB == "yes":
DLINKFLAGS += -L/implib
- @exec "import tools.dmd"
- @if not tools.dmd.find_dll_main_source(source):
- @f = file("aap_dllmain.d", 'w')
- @f.write(tools.dmd.dll_main_source())
- @f.close()
- source += aap_dllmain.d
+ @exec "import tools.dmd"
+ @if not tools.dmd.find_dll_main_source(source):
+ @f = file("aap_dllmain.d", 'w')
+ @f.write(tools.dmd.dll_main_source())
+ @f.close()
+ source += aap_dllmain.d
+ @if not tools.dmd.find_def_file(source):
+ @f = file("aap_dll.def", 'w')
+ @f.write(tools.dmd.dll_def_file(target))
+ @f.close()
+ source += aap_dll.def
:sys $DMD $?DFLAGS $?DVERSION $opt $dbg $?DDEBUG $?DIMPORT
-L$*?DLINKFLAGS -L+$*?LIBS -of$target $source
- :del {f} {q} aap_dllmain.d
+ @if os.name == "nt":
+ :del {f} {q} aap_dllmain.d
+ :del {f} {q} aap_dll.def
:del {q} *.obj
""",
outtypes = ["default"],
- intypes = ["d"])
+ intypes = ["d", "def"])
if not rd["_top"].get("DMD"):
rd["_top"]["DMD"] = "dmd"
@@ -206,6 +225,15 @@
return None
+def find_def_file(sourcestr):
+ print sourcestr
+ for si in var2list(sourcestr):
+ from string import find
+ if (find(si, ".def") > -1):
+ return 1
+
+ return None
+
def dll_main_source():
source = """
import std.c.windows.windows;
@@ -248,4 +276,16 @@
"""
return source
+def dll_def_file(target):
+ from string import find
+ idx = find(target, ".dll")
+ source = "LIBRARY \"" + target[0:idx+4] + "\""
+ source = source + """
+EXETYPE NT
+SUBSYSTEM WINDOWS
+CODE SHARED EXECUTE
+DATA WRITE
+ """
+ return source
+
# vim: set sw=4 et sts=4 tw=79 fo+=l: