From f5f14dd46973f4650f2e30fa196ca0930ed23fc0 Mon Sep 17 00:00:00 2001 From: Andrei Alexandrescu Date: Sat, 11 Apr 2009 20:37:06 +0000 Subject: [PATCH] tabs --- std/demangle.d | 728 ++++++++++++++++++++++++------------------------- 1 file changed, 364 insertions(+), 364 deletions(-) diff --git a/std/demangle.d b/std/demangle.d index b2749565c..e1f5ee4b5 100644 --- a/std/demangle.d +++ b/std/demangle.d @@ -7,18 +7,18 @@ /**** * Demangle D mangled names. * Macros: - * WIKI = Phobos/StdDemangle + * WIKI = Phobos/StdDemangle */ /* Authors: - * Walter Bright, Digital Mars, www.digitalmars.com - * Thomas Kuehne - * Frits van Bommel + * Walter Bright, Digital Mars, www.digitalmars.com + * Thomas Kuehne + * Frits van Bommel */ module std.demangle; -//debug=demangle; // uncomment to turn on debugging printf's +//debug=demangle; // uncomment to turn on debugging printf's private import std.ctype; private import std.string; @@ -32,7 +32,7 @@ private class MangleException : Exception { this() { - super("MangleException"); + super("MangleException"); } } @@ -41,8 +41,8 @@ private class MangleException : Exception * * If it is not a D mangled name, it returns its argument name. * Example: - * This program reads standard in and writes it to standard out, - * pretty-printing any found D mangled names. + * This program reads standard in and writes it to standard out, + * pretty-printing any found D mangled names. ------------------- import std.stdio; import std.ctype; @@ -55,28 +55,28 @@ int main() while ((c = fgetc(stdin)) != EOF) { - if (inword) - { - if (c == '_' || isalnum(c)) - buffer ~= cast(char) c; - else - { - inword = false; - writef(demangle(buffer), cast(char) c); - } - } - else - { if (c == '_' || isalpha(c)) - { inword = true; - buffer.length = 0; - buffer ~= cast(char) c; - } - else - writef(cast(char) c); - } + if (inword) + { + if (c == '_' || isalnum(c)) + buffer ~= cast(char) c; + else + { + inword = false; + writef(demangle(buffer), cast(char) c); + } + } + else + { if (c == '_' || isalpha(c)) + { inword = true; + buffer.length = 0; + buffer ~= cast(char) c; + } + else + writef(cast(char) c); + } } if (inword) - writef(demangle(buffer)); + writef(demangle(buffer)); return 0; } ------------------- @@ -89,401 +89,401 @@ string demangle(string name) static void error() { - //writefln("error()"); - throw new MangleException(); + //writefln("error()"); + throw new MangleException(); } static ubyte ascii2hex(char c) { - if (!isxdigit(c)) - error(); - return cast(ubyte) - ( (c >= 'a') ? c - 'a' + 10 : - (c >= 'A') ? c - 'A' + 10 : - c - '0' - ); + if (!isxdigit(c)) + error(); + return cast(ubyte) + ( (c >= 'a') ? c - 'a' + 10 : + (c >= 'A') ? c - 'A' + 10 : + c - '0' + ); } size_t parseNumber() { - //writefln("parseNumber() %d", ni); - size_t result; + //writefln("parseNumber() %d", ni); + size_t result; - while (ni < name.length && isdigit(name[ni])) - { int i = name[ni] - '0'; - if (result > (size_t.max - i) / 10) - error(); - result = result * 10 + i; - ni++; - } - return result; + while (ni < name.length && isdigit(name[ni])) + { int i = name[ni] - '0'; + if (result > (size_t.max - i) / 10) + error(); + result = result * 10 + i; + ni++; + } + return result; } string parseSymbolName() { - //writefln("parseSymbolName() %d", ni); - size_t i = parseNumber(); - if (ni + i > name.length) - error(); - string result; - if (i >= 5 && - name[ni] == '_' && - name[ni + 1] == '_' && - name[ni + 2] == 'T') - { - size_t nisave = ni; - bool err; - ni += 3; - try - { - result = fparseTemplateInstanceName(); - if (ni != nisave + i) - err = true; - } - catch (MangleException me) - { - err = true; - } - ni = nisave; - if (err) - goto L1; - goto L2; - } + //writefln("parseSymbolName() %d", ni); + size_t i = parseNumber(); + if (ni + i > name.length) + error(); + string result; + if (i >= 5 && + name[ni] == '_' && + name[ni + 1] == '_' && + name[ni + 2] == 'T') + { + size_t nisave = ni; + bool err; + ni += 3; + try + { + result = fparseTemplateInstanceName(); + if (ni != nisave + i) + err = true; + } + catch (MangleException me) + { + err = true; + } + ni = nisave; + if (err) + goto L1; + goto L2; + } L1: - result = name[ni .. ni + i]; + result = name[ni .. ni + i]; L2: - ni += i; - return result; + ni += i; + return result; } string parseQualifiedName() { - //writefln("parseQualifiedName() %d", ni); - string result; + //writefln("parseQualifiedName() %d", ni); + string result; - while (ni < name.length && isdigit(name[ni])) - { - if (result.length) - result ~= "."; - result ~= parseSymbolName(); - } - return result; + while (ni < name.length && isdigit(name[ni])) + { + if (result.length) + result ~= "."; + result ~= parseSymbolName(); + } + return result; } string parseType(string identifier = null) { - //writefln("parseType() %d", ni); - int isdelegate = 0; - bool hasthisptr = false; /// For function/delegate types: expects a 'this' pointer as last argument + //writefln("parseType() %d", ni); + int isdelegate = 0; + bool hasthisptr = false; /// For function/delegate types: expects a 'this' pointer as last argument Lagain: - if (ni >= name.length) - error(); - string p; - switch (name[ni++]) - { - case 'v': p = "void"; goto L1; - case 'b': p = "bool"; goto L1; - case 'g': p = "byte"; goto L1; - case 'h': p = "ubyte"; goto L1; - case 's': p = "short"; goto L1; - case 't': p = "ushort"; goto L1; - case 'i': p = "int"; goto L1; - case 'k': p = "uint"; goto L1; - case 'l': p = "long"; goto L1; - case 'm': p = "ulong"; goto L1; - case 'f': p = "float"; goto L1; - case 'd': p = "double"; goto L1; - case 'e': p = "real"; goto L1; - case 'o': p = "ifloat"; goto L1; - case 'p': p = "idouble"; goto L1; - case 'j': p = "ireal"; goto L1; - case 'q': p = "cfloat"; goto L1; - case 'r': p = "cdouble"; goto L1; - case 'c': p = "creal"; goto L1; - case 'a': p = "char"; goto L1; - case 'u': p = "wchar"; goto L1; - case 'w': p = "dchar"; goto L1; + if (ni >= name.length) + error(); + string p; + switch (name[ni++]) + { + case 'v': p = "void"; goto L1; + case 'b': p = "bool"; goto L1; + case 'g': p = "byte"; goto L1; + case 'h': p = "ubyte"; goto L1; + case 's': p = "short"; goto L1; + case 't': p = "ushort"; goto L1; + case 'i': p = "int"; goto L1; + case 'k': p = "uint"; goto L1; + case 'l': p = "long"; goto L1; + case 'm': p = "ulong"; goto L1; + case 'f': p = "float"; goto L1; + case 'd': p = "double"; goto L1; + case 'e': p = "real"; goto L1; + case 'o': p = "ifloat"; goto L1; + case 'p': p = "idouble"; goto L1; + case 'j': p = "ireal"; goto L1; + case 'q': p = "cfloat"; goto L1; + case 'r': p = "cdouble"; goto L1; + case 'c': p = "creal"; goto L1; + case 'a': p = "char"; goto L1; + case 'u': p = "wchar"; goto L1; + case 'w': p = "dchar"; goto L1; - case 'A': // dynamic array - p = parseType() ~ "[]"; - goto L1; + case 'A': // dynamic array + p = parseType() ~ "[]"; + goto L1; - case 'P': // pointer - p = parseType() ~ "*"; - goto L1; + case 'P': // pointer + p = parseType() ~ "*"; + goto L1; - case 'G': // static array - { size_t ns = ni; - parseNumber(); - size_t ne = ni; - p = parseType() ~ "[" ~ name[ns .. ne] ~ "]"; - goto L1; - } + case 'G': // static array + { size_t ns = ni; + parseNumber(); + size_t ne = ni; + p = parseType() ~ "[" ~ name[ns .. ne] ~ "]"; + goto L1; + } - case 'H': // associative array - p = parseType(); - p = parseType() ~ "[" ~ p ~ "]"; - goto L1; + case 'H': // associative array + p = parseType(); + p = parseType() ~ "[" ~ p ~ "]"; + goto L1; - case 'D': // delegate - isdelegate = 1; - goto Lagain; + case 'D': // delegate + isdelegate = 1; + goto Lagain; - case 'M': - hasthisptr = true; - goto Lagain; + case 'M': + hasthisptr = true; + goto Lagain; - case 'y': - p = "immutable(" ~ parseType() ~ ")"; - goto L1; + case 'y': + p = "immutable(" ~ parseType() ~ ")"; + goto L1; - case 'x': - p = "const(" ~ parseType() ~ ")"; - goto L1; + case 'x': + p = "const(" ~ parseType() ~ ")"; + goto L1; - case 'O': - p = "shared(" ~ parseType() ~ ")"; - goto L1; + case 'O': + p = "shared(" ~ parseType() ~ ")"; + goto L1; - case 'F': // D function - case 'U': // C function - case 'W': // Windows function - case 'V': // Pascal function - case 'R': // C++ function - { char mc = name[ni - 1]; - string args; + case 'F': // D function + case 'U': // C function + case 'W': // Windows function + case 'V': // Pascal function + case 'R': // C++ function + { char mc = name[ni - 1]; + string args; - while (1) - { - if (ni >= name.length) - error(); - char c = name[ni]; - if (c == 'Z') - break; - if (c == 'X') - { - if (!args.length) error(); - args ~= " ..."; - break; - } - if (args.length) - args ~= ", "; - switch (c) - { - case 'J': - args ~= "out "; - ni++; - goto default; + while (1) + { + if (ni >= name.length) + error(); + char c = name[ni]; + if (c == 'Z') + break; + if (c == 'X') + { + if (!args.length) error(); + args ~= " ..."; + break; + } + if (args.length) + args ~= ", "; + switch (c) + { + case 'J': + args ~= "out "; + ni++; + goto default; - case 'K': - args ~= "inout "; - ni++; - goto default; + case 'K': + args ~= "inout "; + ni++; + goto default; - case 'L': - args ~= "lazy "; - ni++; - goto default; + case 'L': + args ~= "lazy "; + ni++; + goto default; - default: - args ~= parseType(); - continue; + default: + args ~= parseType(); + continue; - case 'Y': - args ~= "..."; - break; - } - break; - } - ni++; - if (!isdelegate && identifier.length) - { - switch (mc) - { - case 'F': p = null; break; // D function - case 'U': p = "extern (C) "; break; // C function - case 'W': p = "extern (Windows) "; break; // Windows function - case 'V': p = "extern (Pascal) "; break; // Pascal function - default: assert(0); - } - p ~= parseType() ~ " " ~ identifier ~ "(" ~ args ~ ")"; - return p; - } - p = parseType() ~ - (isdelegate ? " delegate(" : " function(") ~ - args ~ ")"; - isdelegate = 0; - goto L1; - } + case 'Y': + args ~= "..."; + break; + } + break; + } + ni++; + if (!isdelegate && identifier.length) + { + switch (mc) + { + case 'F': p = null; break; // D function + case 'U': p = "extern (C) "; break; // C function + case 'W': p = "extern (Windows) "; break; // Windows function + case 'V': p = "extern (Pascal) "; break; // Pascal function + default: assert(0); + } + p ~= parseType() ~ " " ~ identifier ~ "(" ~ args ~ ")"; + return p; + } + p = parseType() ~ + (isdelegate ? " delegate(" : " function(") ~ + args ~ ")"; + isdelegate = 0; + goto L1; + } - case 'C': p = "class "; goto L2; - case 'S': p = "struct "; goto L2; - case 'E': p = "enum "; goto L2; - case 'T': p = "typedef "; goto L2; + case 'C': p = "class "; goto L2; + case 'S': p = "struct "; goto L2; + case 'E': p = "enum "; goto L2; + case 'T': p = "typedef "; goto L2; - L2: p ~= parseQualifiedName(); - goto L1; + L2: p ~= parseQualifiedName(); + goto L1; - L1: - if (isdelegate) - error(); // 'D' must be followed by function - if (identifier.length) - p ~= " " ~ identifier; - return p; + L1: + if (isdelegate) + error(); // 'D' must be followed by function + if (identifier.length) + p ~= " " ~ identifier; + return p; - default: - size_t i = ni - 1; - ni = name.length; - p = name[i .. length]; - goto L1; - } + default: + size_t i = ni - 1; + ni = name.length; + p = name[i .. length]; + goto L1; + } } string parseTemplateInstanceName() { - auto result = parseSymbolName() ~ "!("; - int nargs; + auto result = parseSymbolName() ~ "!("; + int nargs; - while (1) - { size_t i; + while (1) + { size_t i; - if (ni >= name.length) - error(); - if (nargs && name[ni] != 'Z') - result ~= ", "; - nargs++; - switch (name[ni++]) - { - case 'T': - result ~= parseType(); - continue; + if (ni >= name.length) + error(); + if (nargs && name[ni] != 'Z') + result ~= ", "; + nargs++; + switch (name[ni++]) + { + case 'T': + result ~= parseType(); + continue; - case 'V': + case 'V': - void getReal() - { real r; - ubyte *p = cast(ubyte *)&r; + void getReal() + { real r; + ubyte *p = cast(ubyte *)&r; - if (ni + 10 * 2 > name.length) - error(); - for (i = 0; i < 10; i++) - { ubyte b; + if (ni + 10 * 2 > name.length) + error(); + for (i = 0; i < 10; i++) + { ubyte b; - b = cast(ubyte) - ( - (ascii2hex(name[ni + i * 2]) << 4) + - ascii2hex(name[ni + i * 2 + 1]) - ); - p[i] = b; - } - result ~= format(r); - ni += 10 * 2; - } + b = cast(ubyte) + ( + (ascii2hex(name[ni + i * 2]) << 4) + + ascii2hex(name[ni + i * 2 + 1]) + ); + p[i] = b; + } + result ~= format(r); + ni += 10 * 2; + } - result ~= parseType() ~ " "; - if (ni >= name.length) - error(); - switch (name[ni++]) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - i = ni - 1; - while (ni < name.length && isdigit(name[ni])) - ni++; - result ~= name[i .. ni]; - break; + result ~= parseType() ~ " "; + if (ni >= name.length) + error(); + switch (name[ni++]) + { + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + i = ni - 1; + while (ni < name.length && isdigit(name[ni])) + ni++; + result ~= name[i .. ni]; + break; - case 'N': - i = ni; - while (ni < name.length && isdigit(name[ni])) - ni++; - if (i == ni) - error(); - result ~= "-" ~ name[i .. ni]; - break; + case 'N': + i = ni; + while (ni < name.length && isdigit(name[ni])) + ni++; + if (i == ni) + error(); + result ~= "-" ~ name[i .. ni]; + break; - case 'n': - result ~= "null"; - break; + case 'n': + result ~= "null"; + break; - case 'e': - getReal(); - break; + case 'e': + getReal(); + break; - case 'c': - getReal(); - result ~= '+'; - getReal(); - result ~= 'i'; - break; + case 'c': + getReal(); + result ~= '+'; + getReal(); + result ~= 'i'; + break; - case 'a': - case 'w': - case 'd': - { char m = name[ni - 1]; - if (m == 'a') - m = 'c'; - size_t n = parseNumber(); - if (ni >= name.length || name[ni++] != '_' || - ni + n * 2 > name.length) - error(); - result ~= '"'; - for (i = 0; i < n; i++) - { char c; + case 'a': + case 'w': + case 'd': + { char m = name[ni - 1]; + if (m == 'a') + m = 'c'; + size_t n = parseNumber(); + if (ni >= name.length || name[ni++] != '_' || + ni + n * 2 > name.length) + error(); + result ~= '"'; + for (i = 0; i < n; i++) + { char c; - c = (ascii2hex(name[ni + i * 2]) << 4) + - ascii2hex(name[ni + i * 2 + 1]); - result ~= c; - } - ni += n * 2; - result ~= '"'; - result ~= m; - break; - } + c = (ascii2hex(name[ni + i * 2]) << 4) + + ascii2hex(name[ni + i * 2 + 1]); + result ~= c; + } + ni += n * 2; + result ~= '"'; + result ~= m; + break; + } - default: - error(); - break; - } - continue; + default: + error(); + break; + } + continue; - case 'S': - result ~= parseSymbolName(); - continue; + case 'S': + result ~= parseSymbolName(); + continue; - case 'Z': - break; + case 'Z': + break; - default: - error(); - } - break; - } - result ~= ")"; - return assumeUnique(result); + default: + error(); + } + break; + } + result ~= ")"; + return assumeUnique(result); } if (name.length < 3 || - name[0] != '_' || - name[1] != 'D' || - !isdigit(name[2])) + name[0] != '_' || + name[1] != 'D' || + !isdigit(name[2])) { - goto Lnot; + goto Lnot; } fparseTemplateInstanceName = &parseTemplateInstanceName; try { - auto result = parseQualifiedName(); - result = parseType(result); - while(ni < name.length){ - result ~= " . " ~ parseType(parseQualifiedName()); - } + auto result = parseQualifiedName(); + result = parseType(result); + while(ni < name.length){ + result ~= " . " ~ parseType(parseQualifiedName()); + } - if (ni != name.length) - goto Lnot; - return result; + if (ni != name.length) + goto Lnot; + return result; } catch (MangleException e) { @@ -501,27 +501,27 @@ unittest static string[2][] table = [ - [ "printf", "printf" ], - [ "_foo", "_foo" ], - [ "_D88", "_D88" ], - [ "_D4test3fooAa", "char[] test.foo"], - [ "_D8demangle8demangleFAaZAa", "char[] demangle.demangle(char[])" ], - [ "_D6object6Object8opEqualsFC6ObjectZi", "int object.Object.opEquals(class Object)" ], - [ "_D4test2dgDFiYd", "double delegate(int, ...) test.dg" ], - [ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ], - [ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ], - [ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ], - [ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"], - [ "_D8demangle4testFAiXi", "int demangle.test(int[] ...)"], - [ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"], - [ "_D6plugin8generateFiiZAya", "immutable(char)[] plugin.generate(int, int)"], - [ "_D6plugin8generateFiiZAxa", "const(char)[] plugin.generate(int, int)"], - [ "_D6plugin8generateFiiZAOa", "shared(char)[] plugin.generate(int, int)"] + [ "printf", "printf" ], + [ "_foo", "_foo" ], + [ "_D88", "_D88" ], + [ "_D4test3fooAa", "char[] test.foo"], + [ "_D8demangle8demangleFAaZAa", "char[] demangle.demangle(char[])" ], + [ "_D6object6Object8opEqualsFC6ObjectZi", "int object.Object.opEquals(class Object)" ], + [ "_D4test2dgDFiYd", "double delegate(int, ...) test.dg" ], + [ "_D4test58__T9factorialVde67666666666666860140VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, char[5] \"hello\"c, void* null).factorial" ], + [ "_D4test101__T9factorialVde67666666666666860140Vrc9a999999999999d9014000000000000000c00040VG5aa5_68656c6c6fVPvnZ9factorialf", "float test.factorial!(double 4.2, cdouble 6.8+3i, char[5] \"hello\"c, void* null).factorial" ], + [ "_D4test34__T3barVG3uw3_616263VG3wd3_646566Z1xi", "int test.bar!(wchar[3] \"abc\"w, dchar[3] \"def\"d).x" ], + [ "_D8demangle4testFLC6ObjectLDFLiZiZi", "int demangle.test(lazy class Object, lazy int delegate(lazy int))"], + [ "_D8demangle4testFAiXi", "int demangle.test(int[] ...)"], + [ "_D8demangle4testFLAiXi", "int demangle.test(lazy int[] ...)"], + [ "_D6plugin8generateFiiZAya", "immutable(char)[] plugin.generate(int, int)"], + [ "_D6plugin8generateFiiZAxa", "const(char)[] plugin.generate(int, int)"], + [ "_D6plugin8generateFiiZAOa", "shared(char)[] plugin.generate(int, int)"] ]; foreach (i, name; table) { - string r = demangle(name[0]); + string r = demangle(name[0]); assert(r == name[1], "table entry #" ~ to!string(i) ~ ": '" ~ name[0] ~ "' demangles as '" ~ r ~ "' but is expected to be '"