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 gtd.GirConstant; 19 20 import std.algorithm : among, canFind; 21 import std.array : replace; 22 import std.string : splitLines, strip; 23 24 import gtd.GirPackage; 25 import gtd.GirType; 26 import gtd.GirWrapper; 27 import gtd.Log; 28 import gtd.XMLReader; 29 30 final class GirConstant 31 { 32 string name; 33 string cType; 34 string value; 35 string doc; 36 37 GirType type; 38 GirPackage pack; 39 GirWrapper wrapper; 40 41 this(GirWrapper wrapper, GirPackage pack) 42 { 43 this.wrapper = wrapper; 44 this.pack = pack; 45 } 46 47 void parse(T)(XMLReader!T reader) 48 { 49 name = reader.front.attributes["name"]; 50 value = reader.front.attributes["value"]; 51 if ( "c:type" in reader.front.attributes ) 52 cType = reader.front.attributes["c:type"]; 53 else 54 cType = reader.front.attributes["c:identifier"]; 55 56 reader.popFront(); 57 58 while( !reader.empty && !reader.endTag("constant") ) 59 { 60 switch(reader.front.value) 61 { 62 case "type": 63 case "array": 64 type = new GirType(wrapper); 65 type.parse(reader); 66 break; 67 case "doc": 68 reader.popFront(); 69 doc ~= reader.front.value; 70 reader.popFront(); 71 break; 72 case "doc-deprecated": 73 reader.popFront(); 74 doc ~= "\n\nDeprecated: "~ reader.front.value; 75 reader.popFront(); 76 break; 77 case "source-position": 78 reader.skipTag(); 79 break; 80 default: 81 error("Unexpected tag: ", reader.front.value, " in GirConstant: ", name, reader); 82 } 83 reader.popFront(); 84 } 85 86 if ( value.canFind("\\") ) 87 value = value.replace("\\", "\\\\"); 88 89 if ( type.cType.among("gint64", "guint64") ) 90 // See dmd issue 8929 for why we use UL for signed longs. https://issues.dlang.org/show_bug.cgi?id=8929#c7 91 value ~= "UL"; 92 } 93 94 string[] getConstantDeclaration() 95 { 96 string[] buff; 97 if ( doc !is null && wrapper.includeComments ) 98 { 99 buff ~= "/**"; 100 foreach ( line; doc.splitLines() ) 101 buff ~= " * "~ line.strip(); 102 buff ~= " */"; 103 } 104 105 if ( type.name in pack.collectedAliases && pack.collectedAliases[type.name].baseType.cType.among("gint64", "guint64") ) 106 value ~= "UL"; 107 108 if ( type.isString() ) 109 buff ~= "enum "~ name ~" = \""~ value ~"\";"; 110 else 111 buff ~= "enum "~ name ~" = "~ value ~";"; 112 113 buff ~= "alias "~ cType ~" = "~ name ~";"; 114 115 return buff; 116 } 117 }