import file, ctype; /* A find identifier that skips comments. */ int findBody (char [] data, char [] text) { assert (text.length); for (char *c = data, e = c + data.length - text.length + 1; c < e; c ++) { int n = (int) (e - c) + text.length; if (n > 1 && c [0] == "/" && c [1] == "/") { for (c += 2; c < e; c ++) if (*c == "\n") break; } else if (n > 1 && c [0] == "/" && c [1] == "*") { for (c += 2; c < e - 1; c ++) if (c [0] == "*" && c [1] == "/") { printf ("%p\n", c); c += 1; break; } } else if (n > 1 && c [0] == "/" && c [1] == "+") { int depth = 1; for (c += 2; c < e - 1; c ++) if (c [0] == "/" && c [1] == "+") { depth += 1; c += 2; } else if (c [0] == "+" && c [1] == "/") { depth -= 1; c += 2; if (depth == 0) { c --; break; } } } else if (c [0 .. text.length] == text) { if (c > (char *) data && (isalnum (c [-1]) || c [-1] == "_")) continue; if (c + text.length < (char *) data + data.length && (isalnum (c [text.length]) || c [text.length] == "_")) continue; return (int) (c - (char *) data); } } return -1; } /* A replace that skips comments. */ char [] replaceBody (char [] data, char [] from, char [] to) { int offset = 0, base = 0; int second = 0; while ((offset = findBody (data [base .. data.length], from)) != -1) { offset += base; base = offset + to.length; data = data [0 .. offset] ~ to ~ data [offset + from.length .. data.length]; } return data; } /* Identify "name { ... }" form and remove it. */ char [] removeBlock (char [] data, char [] name) { int offset, base = 0; while ((offset = findBody (data [base .. data.length], name)) != -1) { offset += base; base = offset + name.length; for (int c = base; c < data.length; c ++) { if (data [c] == "{") { int count = 1; for (c ++; c < data.length; c ++) if (data [c] == "{") count ++; else if (data [c] == "}") { count --; if (count == 0) break; } data = data [0 .. offset] ~ data [c + 1 .. data.length]; base -= name.length; break; } else if (data [c] == "(") { for (c ++; c < data.length; c ++) if (data [c] == ")") break; } else if (!isspace (data [c])) break; } } return data; } void main (char [] [] args) { char [] data = (char[]) read (args [1]); int length = data.length; int offset = 0, next, base; /* Transform "template x (y)" into "template class x ". */ while (1) { next = findBody (data [offset .. data.length], "template"); if (next == -1) break; next += offset; offset = next + 1; for (int c = next + 8; c < length; c ++) if (!isspace (data [c])) { data = data [0 .. c] ~ "class " ~ data [c .. data.length]; for (c += 6; c < length; c ++) if (data [c] == "(") { data [c ++] = "<"; break; } for ( ; c < length; c ++) if (data [c] == ")") { data [c] = ">"; break; } break; } } /* Transform "class {" into "class { public:". */ base = 0; while ((offset = findBody (data [base .. data.length], "class")) != -1) { offset += base; base = offset + 5; for (int c = base; c < data.length; c ++) if (data [c] == "{") { data = data [0 .. c + 1] ~ " public:" ~ data [c + 1 .. data.length]; break; } else if (data [c] == ";") break; } data = removeBlock (data, "extern"); /* Remove "extern (XXX)". */ base = 0; while ((offset = findBody (data [base .. data.length], "extern")) != -1) { offset += base; base = offset + 6; for (int c = base; c < data.length; c ++) if (data [c] == "(") { for (c ++; c < data.length; c ++) if (data [c] == ")") { data = data [0 .. offset] ~ data [c + 1 .. data.length]; break; } break; } } data = replaceBody (data, "body", ""); data = replaceBody (data, "alias", "typedef"); data = removeBlock (data, "unittest"); data = removeBlock (data, "invariant"); data = replaceBody (data, "in", ""); data = replaceBody (data, "out", ""); data = replaceBody (data, "}", "};"); printf ("%.*s", data); }