15120c | 2005-01-03 | Henrik Grubbström (Grubba) | |
constant default_headers = ({
"global.h",
"pike_embed.h",
});
class C_Include_Handler(array(string) search_path)
{
string handle_include(string f, string current_file, int local_include)
{
if (!local_include) {
return "";
} else {
foreach(search_path, string path) {
path = combine_path(path, f);
if (file_stat(path)) {
return path;
}
}
}
return 0;
}
string read_include(string f)
{
if (!sizeof(f)) return "";
return Stdio.read_file(f);
}
}
mapping(string:array(array(Parser.C.Token))) parse(array(Parser.C.Token) tokens)
{
mapping(string:array(array(Parser.C.Token))) res = ([]);
int i;
int start;
for (start=i=0; i < sizeof(tokens); i++) {
array(Parser.C.Token)|object(Parser.C.Token) token = tokens[i];
if ((objectp(token)) && (token->text == ";")) {
if (i > start + 2) {
if (objectp(tokens[start]) && (tokens[start]->text == "typedef")) {
} else {
array(Parser.C.Token)|Parser.C.Token last;
if (arrayp(last = tokens[i-1]) && sizeof(last)) {
if (last[0]->text == "(") {
res[(string)tokens[i-2]] = ({
tokens[start..i-3],
last,
});
} else {
}
}
}
} else {
}
start = i+1;
}
}
return res;
}
int main(int argc, array(string) argv)
{
array(string) headers = default_headers;
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | array(string) srcdirs = ({ "." });
array(string) symbols = ({ });
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | |
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | string out_name;
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | |
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | foreach(Getopt.find_all_options(argv, ({
({ "help", Getopt.NO_ARG, ({ "-h", "--help" }) }),
({ "header", Getopt.HAS_ARG, ({ "-i", "--include" }) }),
({ "dir", Getopt.HAS_ARG, ({ "-I", "--include-dir" }) }),
({ "out", Getopt.HAS_ARG, ({ "-o", "--out" }) }),
({ "sym", Getopt.HAS_ARG, ({ "-s", "--sym" }) }),
({ "sym-file", Getopt.HAS_ARG, ({ "-S", "--sym-file" }) }),
}), 1), [string key, string val]) {
switch(key) {
case "help":
werror("Usage:\n"
" %s [ -I <include directory> ... ] \\\n"
" [ -i <header-file> ... ] \\\n"
" [ -s <symbol> ... ] \\\n"
" [ -S <symbol-file> ... ] \\\n"
" [ -o <output-file> ]\n",
argv[0]);
exit(0);
break;
case "header":
headers += ({ val });
break;
case "dir":
srcdirs += ({ val });
break;
case "out":
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | if (out_name) {
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | werror("Output file specified multiple times.\n");
exit(1);
}
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | out_name = val;
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | break;
case "sym":
symbols += ({ val });
break;
case "sym-file":
string raw_syms = Stdio.read_file(val);
if (!raw_syms) {
werror("Failed to open symbol file %O.\n", val);
exit(1);
}
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | symbols += String.trim_whites((replace(raw_syms, "\r", "")/"\n")[*]) -
({""});
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | break;
}
}
argv = Getopt.get_args(argv, 1);
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | |
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | if (sizeof(argv) != 1) {
werror("Too many arguments to %s.\n", argv[0]);
exit(1);
}
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | |
string raw = cpp(sprintf("%{#include \"%s\"\n%}", headers), "include_all.c",
0,
C_Include_Handler(srcdirs));
array(Parser.C.Token|array) tokens =
Parser.C.strip_line_statements(
Parser.C.hide_whitespaces(
Parser.C.group(Parser.C.tokenize(Parser.C.split(raw)))
)
);
mapping(string:array(array(Parser.C.Token))) symbol_info = parse(tokens);
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | Stdio.File out = Stdio.stdout;
if (out_name) {
out = Stdio.File();
if (!out->open(out_name, "wct")) {
werror("Failed to open %O for writing.\n", out_name);
exit(1);
}
}
out->write("/*\n"
" * Automatically generated by " __FILE__ "\n"
" * on " __DATE__ ". Do NOT edit.\n"
" */\n"
"\n"
"%{#include \"%s\"\n%}\n"
"\n",
headers);
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | | int fail;
|
10b706 | 2005-01-03 | Henrik Grubbström (Grubba) | | foreach(Array.uniq(sort(symbols)), string sym) {
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | | array(array(Parser.C.Token)) info = symbol_info[sym];
if (!info) {
werror("Symbol %O not found!\n", sym);
fail = 1;
continue;
}
string rettype = String.trim_whites(Parser.C.simple_reconstitute(info[0]));
string params = Parser.C.simple_reconstitute(info[1]);
|
30c061 | 2008-06-29 | Martin Stjernholm | | out->write("protected %s (*vec_%s)%s;\n"
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | | "%s %s%s\n"
"{\n"
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | |
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | | " %svec_%s(",
rettype, sym, params,
rettype, sym, params,
(rettype=="void")?"":"return ", sym);
array(array(Parser.C.Token)) args = info[1][1..sizeof(info[1])-2]/({","});
foreach(args; int n; array(Parser.C.Token) arg) {
|
3a543a | 2005-01-03 | Henrik Grubbström (Grubba) | | if (sizeof(arg) == 1) continue;
|
b59562 | 2005-01-03 | Henrik Grubbström (Grubba) | | array(Parser.C.Token)|Parser.C.Token name = arg[-1];
if (arrayp(name)) {
if (name[0]->text == "(") {
name = arg[-2];
if (arrayp(name)) {
name = name[2];
} else {
werror("Failed to find variable name in %s\n",
Parser.C.simple_reconstitute(arg));
fail = 1;
}
} else {
werror("Failed to find variable name in %s\n",
Parser.C.simple_reconstitute(arg));
fail = 1;
}
}
out->write("%s%s", n?", ":"", name->text);
|
15120c | 2005-01-03 | Henrik Grubbström (Grubba) | | }
out->write(");\n"
"}\n\n");
}
return fail;
}
|