1 /* 2 * This file is part of gir-to-d. 3 * 4 * gir-to-d is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License 6 * as published by the Free Software Foundation, either version 3 7 * of the License, or (at your option) any later version. 8 * 9 * gir-to-d is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public License 15 * along with gir-to-d. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 module girtod; 19 20 import std.algorithm: canFind, find, findSkip, startsWith; 21 import std.array; 22 import std.file : exists, getcwd, isFile; 23 import std.getopt; 24 import std.path; 25 import std.stdio; 26 import core.stdc.stdlib; 27 28 import gtd.GirWrapper; 29 import gtd.Log; 30 import gtd.WrapException; 31 32 void main(string[] args) 33 { 34 bool printFree; 35 string lookupFile = "APILookup.txt"; 36 37 GirWrapper wrapper = new GirWrapper("./", "./out"); 38 Option printFilesOption; 39 40 wrapper.cwdOrBaseDirectory = getcwd(); 41 42 printFilesOption.optLong = "--print-files"; 43 printFilesOption.help = "Write a newline separated list of generated files to stdout. Optionally you can pass 'relative[,/base/path] or 'full' to force printing the relative or full paths of the files."; 44 45 auto helpInformation = getopt( 46 args, 47 std.getopt.config.passThrough, 48 "input|i", "Directory containing the API description. Or a lookup file (Default: ./)", &wrapper.inputDir, 49 "output|o", "Output directory for the generated binding. (Default: ./out)", &wrapper.outputDir, 50 "use-runtime-linker", "Link the gtk functions with the runtime linker.", &wrapper.useRuntimeLinker, 51 "gir-directory|g", "Directory to search for gir files before the system directory.", &wrapper.commandlineGirPath, 52 "print-free", "Print functions that don't have a parent module.", &printFree, 53 "use-bind-dir", "Include public imports for the old gtkc package.", &wrapper.useBindDir, 54 "version", "Print the version and exit", (){ writeln("GIR to D ", import("VERSION")); exit(0); } 55 ); 56 57 if (helpInformation.helpWanted) 58 { 59 defaultGetoptPrinter("girtod is an utility that generates D bindings using the GObject introspection files.\n\nOptions:", 60 helpInformation.options ~ printFilesOption); 61 exit(0); 62 } 63 64 if ( args.length > 1 ) 65 handlePrintFiles(args, wrapper); 66 67 if ( wrapper.inputDir.exists && wrapper.inputDir.isFile() ) 68 { 69 lookupFile = wrapper.inputDir.baseName(); 70 wrapper.inputDir = wrapper.inputDir.dirName(); 71 } 72 73 try 74 { 75 //Read in the GIR and API files. 76 if ( lookupFile.extension == ".gir" ) 77 wrapper.proccessGIR(lookupFile); 78 else 79 wrapper.proccess(lookupFile); 80 81 if ( printFree ) 82 wrapper.printFreeFunctions(); 83 84 //Generate the D binding 85 foreach(pack; wrapper.packages) 86 { 87 if ( pack.name == "cairo" ) 88 continue; 89 90 if ( wrapper.useRuntimeLinker ) 91 pack.writeLoaderTable(); 92 else 93 pack.writeExternalFunctions(); 94 95 pack.writeTypes(); 96 pack.writeClasses(); 97 } 98 } 99 catch (WrapException ex) 100 { 101 error(ex); 102 } 103 } 104 105 void handlePrintFiles(string[] args, GirWrapper wrapper) 106 { 107 string value; 108 109 args.popFront(); 110 111 if ( args.front.startsWith("--print-files") ) 112 { 113 if ( args.front.findSkip("=") ) 114 { 115 value = args.front; 116 } 117 118 args.popFront(); 119 120 if ( value.empty && !args.empty && !args.front.startsWith("--") ) 121 { 122 value = args.front; 123 args.popFront(); 124 } 125 } 126 127 if ( !args.empty ) 128 { 129 writeln("Unable to parse parameters: Unrecognized option ", args.front); 130 exit(0); 131 } 132 133 wrapper.printFiles = true; 134 135 if ( value == "absolute" || value == "full" ) 136 { 137 wrapper.printFileMethod = PrintFileMethod.Absolute; 138 } 139 else if ( value.startsWith("relative") ) 140 { 141 wrapper.printFileMethod = PrintFileMethod.Relative; 142 143 if ( value.findSkip(",") ) 144 wrapper.cwdOrBaseDirectory = value; 145 146 if ( !isAbsolute(wrapper.cwdOrBaseDirectory) ) 147 error("The base directory passed to relative must be absolute."); 148 } 149 else if ( !value.empty ) 150 { 151 error("Unknown option: '", value, "' for print-files."); 152 } 153 }