/home/i/wrk/d/dfilt/dfilt.d
private import std.cstream;
private import std.regexp;
private import std.string;
private import std.ctype;
private import std.conv;
class Demangle {
this() {
simpleMangle['v'] = "void";
simpleMangle['g'] = "byte";
simpleMangle['h'] = "ubyte";
simpleMangle['s'] = "short";
simpleMangle['t'] = "ushort";
simpleMangle['i'] = "int";
simpleMangle['k'] = "uint";
simpleMangle['l'] = "long";
simpleMangle['m'] = "ulong";
simpleMangle['f'] = "float";
simpleMangle['d'] = "double";
simpleMangle['e'] = "real";
simpleMangle['o'] = "ifloat";
simpleMangle['p'] = "idouble";
simpleMangle['j'] = "ireal";
simpleMangle['q'] = "cfloat";
simpleMangle['r'] = "cdouble";
simpleMangle['c'] = "creal";
simpleMangle['b'] = "bit";
simpleMangle['a'] = "char";
simpleMangle['u'] = "wchar";
simpleMangle['w'] = "dchar";
simpleMangle['@'] = "???ERROR???";
}
void run(Stream ins, Stream outs) {
char[] all = "";
try {
int c;
while ((c = ins.getc()) != char.init) {
all ~= cast(char)c;
}
}
catch (Error e) {}
char[][] lines = std.string.split(all, "\n");
foreach (char[] line; lines) {
for (int i = 0; i < line.length-1; i++) {
if (line[i..i+2] == `_D` && (i == 0 || !issym(line[i-1]))) {
int j;
for (j = i+2; j < line.length; j++) {
if (!issym(line[j])) break;
}
int end = 0;
char[] d = demangle(line[i+2..j], end);
line = line[0..i] ~ d ~ line[j..line.length];
}
if (i < line.length - 7 &&
line[i..i+7] == `_Class_` &&
(i == 0 || !issym(line[i-1])))
{
int j;
for (j = i+7; j < line.length; j++) {
if (!issym(line[j])) break;
}
int end = 0;
char[] d = demangle(line[i+7..j], end);
line = line[0..i] ~ "class " ~ d ~ line[j..line.length];
}
}
outs.writeLine(line);
}
}
char[] demangle(char[] sym, inout int i) {
if (sym.length > i+2 && sym[i..i+2] == "_D") i += 2;
char[][] names;
while (i < sym.length && std.ctype.isdigit(sym[i])) {
int num = getNum(sym, i);
char[] now = sym[i..i+num];
if (now == "__anonymous") {
}
else {
int sep = std.string.rfind(now, "_");
if (sep > 0) {
try {
int dummy = 0;
char[] type = demangle(now[sep+1..now.length], dummy);
now = now[0..sep] ~ "!(" ~ type ~ ")";
}
catch (Object o) {}
}
names ~= now;
}
i += num;
}
char[] name = join(names, ".");
if (sym.length == i) return name;
char[] type;
TYPE:
switch (sym[i]) {
case 'A': {
i++;
char[] t = demangle(sym, i);
type = t ~ "[]";
break TYPE;
}
case 'G': {
i++;
char[] num = getNumStr(sym, i);
char[] t = demangle(sym, i);
type = t ~ "[" ~ num ~ "]";
break TYPE;
}
case 'H': {
i++;
char[] t1 = demangle(sym, i);
char[] t2 = demangle(sym, i);
type = t2 ~ "[" ~ t1 ~ "]";
break TYPE;
}
case 'P': {
i++;
char[] t = demangle(sym, i);
type = t ~ "*";
break TYPE;
}
case 'R': {
assert(false);
i++;
char[] t = demangle(sym, i);
type = "inout " ~ t;
break TYPE;
}
case 'F':
case 'U': {
bool isStatic = sym[i] == 'U';
i++;
char[][] args;
bool nowRet = false;
while (1) {
char[] t = demangle(sym, i);
if (nowRet) {
if (isStatic) t = "static " ~ t;
return t ~ " " ~ name ~ "(" ~ join(args, ",") ~ ")";
}
if (i == sym.length) {
args ~= "...";
if (isStatic) t = "static " ~ t;
return t ~ " " ~ name ~ "(" ~ join(args, ",") ~ ")";
}
args ~= t;
if (sym[i] == 'Z') {
nowRet = true;
i++;
}
if (sym[i] == 'Y') {
i++;
}
}
assert(false);
}
case 'I': {
assert(false);
}
case 'C': {
i++;
char[] t = demangle(sym, i);
type = "class " ~ t;
break TYPE;
}
case 'S': {
i++;
char[] t = demangle(sym, i);
type = "struct " ~ t;
break TYPE;
}
case 'E': {
i++;
char[] t = demangle(sym, i);
type = "enum " ~ t;
break TYPE;
}
case 'T': {
i++;
char[] t = demangle(sym, i);
type = "typedef " ~ t;
break TYPE;
}
case 'D': {
i++;
char[] t = demangle(sym, i);
type = "delegate " ~ t;
break TYPE;
}
case 'K': {
i++;
char[] t = demangle(sym, i);
type = "inout " ~ t;
break TYPE;
}
case 'J': {
i++;
char[] t = demangle(sym, i);
type = "out " ~ t;
break TYPE;
}
case 'Y':
case 'Z': {
break TYPE;
}
default:
if (sym[i] in simpleMangle) {
type = simpleMangle[sym[i]];
i++;
break TYPE;
}
assert(false);
break TYPE;
}
if (type) {
if (name && name.length > 0) {
return type ~ " " ~ name;
}
else {
return type;
}
}
else {
return name;
}
}
private:
bool issym(char c) {
return isalnum(c) || c == '_';
}
int getNum(char[] str, inout int i) {
return toInt(getNumStr(str, i));
}
char[] getNumStr(char[] str, inout int i) {
char[] numStr = "";
while (std.ctype.isdigit(str[i])) {
numStr ~= str[i];
i++;
}
return numStr;
}
private:
char[][char] simpleMangle;
}
version (DFILT_NOMAIN) {
}
else {
int main(char[][] args) {
Demangle d = new Demangle();
d.run(din, dout);
return 0;
}
}