1 /* 2 * This file is part of gtkD. 3 * 4 * gtkD 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, with 8 * some exceptions, please read the COPYING file. 9 * 10 * gtkD is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with gtkD; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA 18 */ 19 20 module utils.GtkEnum; 21 22 import std.algorithm; 23 import std.string : splitLines, strip, toUpper; 24 25 import utils.GtkPackage; 26 import utils.GtkWrapper; 27 import utils.XML; 28 29 final class GtkEnum 30 { 31 string name; 32 string cName; 33 string libVersion; 34 string doc; 35 36 GtkEnumMember[] members; 37 GtkWrapper wrapper; 38 GtkPackage pack; 39 40 this(GtkWrapper wrapper, GtkPackage pack) 41 { 42 this.wrapper = wrapper; 43 this.pack = pack; 44 } 45 46 void parse(T)(XMLReader!T reader) 47 { 48 name = reader.front.attributes["name"]; 49 cName = reader.front.attributes["c:type"]; 50 51 if ( "version" in reader.front.attributes ) 52 libVersion = reader.front.attributes["version"]; 53 reader.popFront(); 54 55 while ( !reader.empty && !reader.endTag("bitfield", "enumeration") ) 56 { 57 switch (reader.front.value) 58 { 59 case "doc": 60 reader.popFront(); 61 doc ~= reader.front.value; 62 reader.popFront(); 63 break; 64 case "doc-deprecated": 65 reader.popFront(); 66 doc ~= "\n\nDeprecated: "~ reader.front.value; 67 reader.popFront(); 68 break; 69 case "member": 70 if ( reader.front.attributes["name"].startsWith("2bu", "2bi", "3bu") ) 71 { 72 reader.skipTag(); 73 break; 74 } 75 76 GtkEnumMember member = GtkEnumMember(wrapper); 77 member.parse(reader); 78 members ~= member; 79 break; 80 case "function": 81 //Skip these functions for now 82 //as they are also availabe as global functions. 83 //pack.parseFunction(reader); 84 reader.skipTag(); 85 break; 86 default: 87 throw new XMLException(reader, "Unexpected tag: "~ reader.front.value ~" in GtkEnum: "~ name); 88 } 89 reader.popFront(); 90 } 91 } 92 93 string[] getEnumDeclaration() 94 { 95 string[] buff; 96 if ( doc !is null && wrapper.includeComments ) 97 { 98 buff ~= "/**"; 99 foreach ( line; doc.splitLines() ) 100 buff ~= " * "~ line.strip(); 101 102 if ( libVersion ) 103 { 104 buff ~= " *"; 105 buff ~= " * Since: "~ libVersion; 106 } 107 108 buff ~= " */"; 109 } 110 111 buff ~= "public enum "~ cName ~(name.among("ParamFlags", "MessageType") ? " : uint" : ""); 112 buff ~= "{"; 113 114 foreach ( member; members ) 115 { 116 buff ~= member.getEnumMemberDeclaration(); 117 } 118 119 buff ~= "}"; 120 if ( name !is null && pack.name.among("glgdk", "glgtk") ) 121 buff ~= "alias "~ cName ~" GL"~ name ~";"; 122 else if ( name !is null && pack.name != "pango" ) 123 buff ~= "alias "~ cName ~" "~ name ~";"; 124 125 return buff; 126 } 127 } 128 129 struct GtkEnumMember 130 { 131 string name; 132 string value; 133 string doc; 134 135 GtkWrapper wrapper; 136 137 @disable this(); 138 139 this(GtkWrapper wrapper) 140 { 141 this.wrapper = wrapper; 142 } 143 144 void parse(T)(XMLReader!T reader) 145 { 146 name = reader.front.attributes["name"]; 147 value = reader.front.attributes["value"]; 148 149 if ( reader.front.type == XMLNodeType.EmptyTag ) 150 return; 151 152 reader.popFront(); 153 154 while ( !reader.empty && !reader.endTag("member", "constant") ) 155 { 156 switch (reader.front.value) 157 { 158 case "doc": 159 reader.popFront(); 160 doc ~= reader.front.value; 161 reader.popFront(); 162 break; 163 case "doc-deprecated": 164 reader.popFront(); 165 doc ~= "\n\nDeprecated: "~ reader.front.value; 166 reader.popFront(); 167 break; 168 case "type": 169 if ( reader.front.attributes["name"] == "utf8" ) 170 value = "\""~ value ~"\""; 171 break; 172 default: 173 throw new XMLException(reader, "Unexpected tag: "~ reader.front.value ~" in GtkEnumMember: "~ name); 174 } 175 reader.popFront(); 176 } 177 } 178 179 string[] getEnumMemberDeclaration() 180 { 181 string[] buff; 182 if ( doc !is null && wrapper.includeComments ) 183 { 184 buff ~= "/**"; 185 foreach ( line; doc.splitLines() ) 186 buff ~= " * "~ line.strip(); 187 buff ~= " */"; 188 } 189 190 buff ~= tokenToGtkD(name.toUpper(), wrapper.aliasses, false) ~" = "~ value ~","; 191 192 return buff; 193 } 194 }