module mime.util.sharedlib; public import tango.sys.SharedLib; import mime.util.meta; version(Windows) public const char[] SHARED_LIB_EXT = ".dll"; else version(Posix) public const char[] SHARED_LIB_EXT = ".so"; else static assert(false); public char[] shared_mixin(char[] libFile, char[][] functions) { assert(functions.length % 2 == 0); char[] r = "private SharedLib _lib;"; int numFuncs = functions.length / 2; for(int i = 0; i < numFuncs; i++) { char[] type = functions[i * 2]; char[] name = functions[i * 2 + 1]; r ~= "public static " ~ type ~ " " ~ name ~ ";"; } r ~= "public void _loadLib() {if(_lib)return; scope(failure){_unloadLib();}"; r ~= "_lib = SharedLib.load(\"" ~ libFile ~ "\");"; for(int i = 0; i < numFuncs; i++) { char[] name = functions[i * 2 + 1]; r ~= name ~ " = " ~ "cast(typeof(" ~ name ~ ")) _lib.getSymbol(\"" ~ name ~ "\");"; } r ~= "}"; r ~= "public void _unloadLib() { if(_lib){_lib.unload();}"; for(int i = 0; i < numFuncs; i++) { char[] name = functions[i * 2 + 1]; r ~= name ~ "=null;"; } r ~= "}"; return r; } private char[] convertCppTypes(char[] line) { line = line.ctfeReplace("_VOID", "void"); line = line.ctfeReplace("_LUINT", "uint"); line = line.ctfeReplace("_LINT", "int"); line = line.ctfeReplace("_INT", "int"); line = line.ctfeReplace("_UINT", "uint"); line = line.ctfeReplace("_LONG", "long"); line = line.ctfeReplace("_ULONG", "ulong"); line = line.ctfeReplace("_CHAR", "char"); line = line.ctfeReplace("_CONST", ""); return line; } public char[] sharedFromHeader_mixin(char[] headerFile)(char[] libFile) { char[] h = import(headerFile); int lineStart = 0; bool inCopy = false; bool inFunctions = false; char[] r; char[][] functions; for(int i = 0; i < h.length; i++) { if(h[i] == '\n') { char[] line = h[lineStart .. i]; lineStart = i + 1; if(line.ctfeStartsWith("//@")) { if(line.ctfeStartsWith("//@END")) { inCopy = false; inFunctions = false; } else if(line.ctfeStartsWith("//@FUNCTIONS")) inFunctions = true; else if(line.ctfeStartsWith("//@COPY")) inCopy = true; } else if(inCopy) { r ~= convertCppTypes(line); } else if(inFunctions) { if(!line.ctfeStartsWith("FUN(")) continue; int s = 4; int j; for(j = 4; j < line.length; j++) if(line[j] == ',') break; if (j == line.length) continue; char[] fname = line[s .. j]; s = j + 1; for(j = j + 1; j < line.length; j++) if(line[j] == ',') break; if (j == line.length) continue; char[] retTy = line[s .. j]; s = j + 1; for(j = j + 1; j < line.length; j++) if(line[j] == ';') break; if(line[j - 1] != ')') continue; char[] params = line[s .. j - 1]; functions ~= convertCppTypes(retTy ~ " function " ~ params); functions ~= fname; } } } return r ~ shared_mixin(libFile, functions); }