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 try 68 { 69 //Read in the GIR and API files. 70 if ( wrapper.inputDir.extension == ".gir" ) 71 { 72 wrapper.proccessGIR(wrapper.inputDir); 73 } 74 else 75 { 76 if ( wrapper.inputDir.exists && wrapper.inputDir.isFile() ) 77 { 78 lookupFile = wrapper.inputDir.baseName(); 79 wrapper.inputDir = wrapper.inputDir.dirName(); 80 } 81 wrapper.proccess(lookupFile); 82 } 83 84 if ( printFree ) 85 wrapper.printFreeFunctions(); 86 87 //Generate the D binding 88 foreach(pack; wrapper.packages) 89 { 90 if ( pack.name == "cairo" ) 91 continue; 92 93 if ( wrapper.useRuntimeLinker ) 94 pack.writeLoaderTable(); 95 else 96 pack.writeExternalFunctions(); 97 98 pack.writeTypes(); 99 pack.writeClasses(); 100 } 101 } 102 catch (WrapException ex) 103 { 104 error(ex); 105 } 106 } 107 108 void handlePrintFiles(string[] args, GirWrapper wrapper) 109 { 110 string value; 111 112 args.popFront(); 113 114 if ( args.front.startsWith("--print-files") ) 115 { 116 if ( args.front.findSkip("=") ) 117 { 118 value = args.front; 119 } 120 121 args.popFront(); 122 123 if ( value.empty && !args.empty && !args.front.startsWith("--") ) 124 { 125 value = args.front; 126 args.popFront(); 127 } 128 } 129 130 if ( !args.empty ) 131 { 132 writeln("Unable to parse parameters: Unrecognized option ", args.front); 133 exit(0); 134 } 135 136 wrapper.printFiles = true; 137 138 if ( value == "absolute" || value == "full" ) 139 { 140 wrapper.printFileMethod = PrintFileMethod.Absolute; 141 } 142 else if ( value.startsWith("relative") ) 143 { 144 wrapper.printFileMethod = PrintFileMethod.Relative; 145 146 if ( value.findSkip(",") ) 147 wrapper.cwdOrBaseDirectory = value; 148 149 if ( !isAbsolute(wrapper.cwdOrBaseDirectory) ) 150 error("The base directory passed to relative must be absolute."); 151 } 152 else if ( !value.empty ) 153 { 154 error("Unknown option: '", value, "' for print-files."); 155 } 156 }