1 module libssh.mix; 2 3 package: 4 5 import std.array : appender; 6 import std.algorithm : map; 7 import std.string : lineSplitter, strip, startsWith; 8 import std.range : put; 9 10 string appendToAllLines(string lines, string suffix, string g_prefix, string g_suffix) 11 { 12 auto buf = appender!string; 13 14 if (g_prefix.length) 15 { 16 put(buf, g_prefix); 17 put(buf, "\n"); 18 } 19 20 foreach (line; lines.lineSplitter.map!strip) 21 { 22 if (line.startsWith("//")) // comment 23 { 24 put(buf, line); 25 } 26 else if (line.startsWith("%")) // not append 27 { 28 put(buf, line[1..$]); 29 } 30 else if (line.length) 31 { 32 put(buf, line); 33 put(buf, suffix); 34 } 35 put(buf, "\n"); 36 } 37 38 put(buf, g_suffix); 39 40 return buf.data; 41 } 42 43 unittest 44 { 45 enum src = ` 46 int foo(int a, int b) 47 48 // comment 49 50 %version (Windows) {} 51 %else { 52 int bar(some / random % string) 53 %} 54 `; 55 56 enum r1 = appendToAllLines(src, ";", "{", "}"); 57 enum e1 = `{ 58 59 int foo(int a, int b); 60 61 // comment 62 63 version (Windows) {} 64 else { 65 int bar(some / random % string); 66 } 67 68 }`; 69 70 static assert(r1 == e1); 71 72 enum r2 = appendToAllLines(src, "{ mixin(rtLib); }", "", ""); 73 enum e2 = ` 74 int foo(int a, int b){ mixin(rtLib); } 75 76 // comment 77 78 version (Windows) {} 79 else { 80 int bar(some / random % string){ mixin(rtLib); } 81 } 82 83 `; 84 85 static assert(r2 == e2); 86 } 87 88 string pastFunctions(string input, string libname="lib") 89 { 90 version (libssh_rtload) 91 return appendToAllLines(input, "{ mixin(SSLL_CALL); }", 92 `mixin SSLL_INIT; @api("`~libname~`") {`, `}`); 93 else 94 return appendToAllLines(input, ";", "extern (C) {", "}"); 95 }