1 module test; 2 3 import std.algorithm; 4 import std.array; 5 import std.conv; 6 import std.file; 7 import std.path; 8 import std.exception; 9 import std.process; 10 import std..string; 11 import std.stdio; 12 import std.typetuple; 13 import std.typecons; 14 import std.traits; 15 import std.range; 16 import std.regex; 17 18 /** 19 Helper script which translates header files into D modules. 20 21 Unsupported: 22 - typedefs and inline function definitions, these need to be manually ported 23 - #define's are not translated 24 */ 25 26 string translate(string input) 27 { 28 input = input.replace(regex(`GIT_EXTERN\(([^)]+)\)`, "g"), "$1"); 29 30 input = input.replace("GIT_BEGIN_DECL", ""); 31 input = input.replace(`#include "`, "import git.c."); 32 input = input.replace(`.h"`, ";"); 33 input = input.replace("import git.c.object;", "import git.c.object_;"); 34 input = input.replace("import git.c.version;", "import git.c.version_;"); 35 36 input = input.replace(`/** @} */`, ""); 37 38 input = input.replace("#ifndef", "// #ifndef"); 39 input = input.replace("#define", "// #define"); 40 41 input = input.replace("(void)", "()"); 42 input = input.replace("const void *", "const(void)* "); 43 input = input.replace("unsigned short", "ushort"); 44 input = input.replace("unsigned char", "ubyte"); 45 input = input.replace("unsigned int", "uint"); 46 input = input.replace("unsigned", "uint"); 47 input = input.replace("**out,", "**out_,"); 48 input = input.replace("*out,", "*out_,"); 49 input = input.replace("**out)", "**out_)"); 50 input = input.replace("*out)", "*out_)"); 51 input = input.replace(" version;", " version_;"); 52 input = input.replace(" ref,", "ref_,"); 53 input = input.replace("*ref)", "*ref_)"); 54 input = input.replace(" *ref, ", " *ref_, "); 55 input = input.replace(" *ref,", " *ref_,"); 56 57 input = input.replace("const char **", "const(char)** "); 58 input = input.replace("const char *", "const(char)* "); 59 input = input.replace("const char*", "const(char)*"); 60 input = input.replace("const git_config *", "const(git_config)* "); 61 input = input.replace("const git_commit *", "const(git_commit)* "); 62 input = input.replace("const git_indexer_stream *", "const(git_indexer_stream)* "); 63 input = input.replace("const git_diff_file *", "const(git_diff_file)* "); 64 input = input.replace("const git_oid *", "const(git_oid)* "); 65 input = input.replace("const git_blob *", "const(git_blob)* "); 66 input = input.replace("const git_object *", "const(git_object)* "); 67 input = input.replace("const git_clone_options *", "const(git_clone_options)* "); 68 input = input.replace("const git_signature *", "const(git_signature)* "); 69 input = input.replace("const git_tree *", "const(git_tree)* "); 70 input = input.replace("const git_cvar_map *", "const(git_cvar_map)* "); 71 input = input.replace("const git_config_entry *", "const(git_config_entry)* "); 72 input = input.replace("const git_error *", "const(git_error)* "); 73 input = input.replace("const git_note *", "const(git_note)* "); 74 input = input.replace("const git_remote *", "const(git_remote)* "); 75 input = input.replace("const git_reference *", "const(git_reference)* "); 76 input = input.replace("const git_reflog_entry *", "const(git_reflog_entry)* "); 77 input = input.replace("const git_refspec *", "const(git_refspec)* "); 78 input = input.replace("const git_strarray *", "const(git_strarray)* "); 79 input = input.replace("const git_tree_entry *", "const(git_tree_entry)* "); 80 input = input.replace("const git_tag *", "const(git_tag)* "); 81 input = input.replace("const git_index *", "const(git_index)* "); 82 input = input.replace("const git_index_entry **", "const(git_index_entry)** "); 83 input = input.replace("const git_index_entry *", "const(git_index_entry)* "); 84 input = input.replace("const git_transfer_progress *", "const(git_transfer_progress)* "); 85 input = input.replace("const git_status_options *", "const(git_status_options)* "); 86 input = input.replace("const git_merge_tree_opts *", "const(git_merge_tree_opts)* "); 87 input = input.replace("const git_status_entry *", "const(git_status_entry)* "); 88 input = input.replace("const git_index_name_entry *", "const(git_index_name_entry)* "); 89 input = input.replace("const git_index_reuc_entry *", "const(git_index_reuc_entry)* "); 90 91 input = input.replace("struct git_odb *", "git_odb* "); 92 93 input = input.replace("GIT_END_DECL", ""); 94 input = input.replace("#endif", "//#endif"); 95 96 input = input.replace("typedef enum", "enum"); 97 input = input.replace("typedef struct", "struct"); 98 input = input.replace("};", "}"); 99 100 return input; 101 } 102 103 void main(string[] args) 104 { 105 args.popFront(); 106 107 bool force; 108 string name; 109 110 foreach (arg; args) 111 { 112 if (arg == "-force" || arg == "--force") 113 force = true; 114 else 115 name = arg; 116 } 117 118 auto str = cast(string)std.file.read(name); 119 120 auto res = str.translate; 121 122 auto app = appender!string(); 123 app ~= format("module git.c.%s;\n\n", name.stripExtension.baseName); 124 app ~= "extern (C):\n\n"; 125 app ~= res; 126 127 string path = buildPath(".", name.stripExtension.baseName.setExtension(".d")) 128 .absolutePath.buildNormalizedPath; 129 //~ writeln(path); 130 131 if (!force) 132 enforce(!path.exists, format("Won't overwrite file '%s'", path)); 133 134 std.file.write(path, app.data); 135 136 executeShell(format("scite %s", path)); 137 } 138