1 /** 2 * Generate the tcod.functions module from a flat list of functions, 3 * given on stdin. Output to stdout. 4 * 5 * This is not particularly general purpose; it makes a lot of 6 * assumptions about the function list that it will be given. 7 */ 8 module genfunctionsmod; 9 10 import std.algorithm : sort; 11 import std.conv : to; 12 import std.stdio; 13 import std.ascii : isWhite; 14 import std.string; 15 16 17 void main() 18 { 19 string[string] functions; 20 21 foreach (line; stdin.byLine) { 22 if (line.emptyOrWhitespace()) continue; 23 24 string[] functionParts = split(to!string(line), " "); 25 string functionDefinition = functionParts[0 .. $ - 1].join(" "); 26 string functionName = chop(functionParts[$ - 1]); 27 if (functionName.length == 0) { 28 throw new Exception("Malformed function line."); 29 } 30 31 functions[functionName] = functionDefinition; 32 } 33 34 stdout.write(`/// This module has been automatically generated. 35 36 module tcod.c.functions; 37 38 import core.runtime : Runtime; 39 import std.algorithm.iteration : map; 40 import std.path : dirName, dirSeparator; 41 import std.range : array; 42 import std.string: join, toStringz; 43 44 import derelict.util.loader; 45 import derelict.util.system; 46 47 import tcod.c.all; 48 import tcod.c.types; 49 50 extern(C) @nogc nothrow { 51 `); 52 53 // Okay, first declare the function variables. 54 foreach (func; sort(functions.keys)) { 55 stdout.writeln(" alias da_", func, " = ", functions[func], ";"); 56 } 57 58 stdout.write(`} 59 60 __gshared { 61 `); 62 63 foreach (functionName; sort(functions.keys)) { 64 stdout.writeln(" da_", functionName, " ", functionName, ";"); 65 } 66 67 stdout.write(`} 68 69 class DerelictTCODLoader : SharedLibLoader { 70 this(string libNames) { 71 super(libNames); 72 } 73 74 ~this() { 75 unload(); 76 } 77 78 override void loadSymbols() 79 { 80 `); 81 82 // Now load the functions from the shared object, asserting each time. 83 foreach (functionName; sort(functions.keys)) { 84 stdout.writeln(" bindFunc(cast(void**)&", functionName, ", \"", functionName, "\");"); 85 } 86 87 stdout.write(` } 88 } 89 90 __gshared DerelictTCODLoader DerelictTCOD; 91 92 shared static this() 93 { 94 string[] libNames; 95 if(Derelict_OS_Windows) { 96 libNames = ["libtcod_debug.dll", "libtcod.dll"]; 97 } else if(Derelict_OS_Linux) { 98 libNames = ["libtcod_debug.so", "libtcod.so"]; 99 100 // prepend executable path to library names 101 string path = dirName(Runtime.args[0]); 102 libNames = array(map!(e => path ~ dirSeparator ~ e)(libNames)); 103 } else 104 assert(0, "libtcod-d is not supported on this operating system."); 105 106 DerelictTCOD = new DerelictTCODLoader(join(libNames, ',')); 107 DerelictTCOD.load(); 108 } 109 `); 110 } 111 112 /** 113 * Returns: true if string `s` is comprised entirely of whitespace 114 * or is completely empty. 115 */ 116 bool emptyOrWhitespace(T)(T s) 117 { 118 bool emptyOrWhite = true; 119 foreach (c; s) { 120 if (!isWhite(c)) { 121 emptyOrWhite = false; 122 break; 123 } 124 } 125 126 return emptyOrWhite; 127 } 128 129 unittest 130 { 131 assert(emptyOrWhitespace("")); 132 assert(emptyOrWhitespace(" \t\n \t \n")); 133 assert(!emptyOrWhitespace(" a ")); 134 }