summaryrefslogtreecommitdiffstats
path: root/qtsharp/src/generator/Converter.cs
diff options
context:
space:
mode:
Diffstat (limited to 'qtsharp/src/generator/Converter.cs')
-rw-r--r--qtsharp/src/generator/Converter.cs464
1 files changed, 464 insertions, 0 deletions
diff --git a/qtsharp/src/generator/Converter.cs b/qtsharp/src/generator/Converter.cs
new file mode 100644
index 00000000..143aa9da
--- /dev/null
+++ b/qtsharp/src/generator/Converter.cs
@@ -0,0 +1,464 @@
+// A Qt to C# binding generator.
+//
+// Copyright (C) 2002 Adam Treat (manyoso@yahoo.com)
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+using System;
+using System.Text;
+using System.Collections;
+using System.Collections.Specialized;
+//using System.Text.RegularExpressions;
+
+namespace QtCSharp {
+
+ public class Converter {
+
+ ArrayList qtypes;
+ QType qtype;
+ QTypeMap qmap;
+ StringCollection sigs;
+ StringBuilder sig;
+
+ public Converter (ArrayList qtypes, QType qtype, QTypeMap qmap)
+ {
+ this.qtypes = qtypes;
+ this.qtype = qtype;
+ this.qmap = qmap;
+ sigs = new StringCollection ();
+ sig = new StringBuilder ();
+ if (!qtype.IsConverted)
+ Convert ();
+ Ancestors ();
+ qtype.IsConverted = true;
+ }
+
+ public QType GetQType ()
+ {
+ return qtype;
+ }
+
+ public void Convert ()
+ {
+ foreach (QCtor qctor in qtype.QCtors) {
+ qctor.Name = qmap.ReservedType (qctor.Name);
+ if (!qctor.Overload) {
+ ConvertCSharpParams (qctor.CSharpParams);
+ ConvertPinvokeCallParams (qctor.PinvokeCallParams);
+ ConvertPinvokeParams (qctor.PinvokeParams);
+ } else {
+ ConvertOverloadParams (qctor.OverloadParams);
+ }
+ CheckSig (qctor);
+ }
+ foreach (QMethod qmethod in qtype.QMethods) {
+ if (qmethod.Name.StartsWith ("protected_"))
+ qmethod.Name = qmethod.Name.Replace ("protected_", "");
+ qmethod.Name = qmap.ReservedType (qmethod.Name);
+ if (!qmethod.Overload) {
+ ConvertCSharpParams (qmethod.CSharpParams);
+ ConvertPinvokeCallParams (qmethod.PinvokeCallParams);
+ ConvertPinvokeParams (qmethod.PinvokeParams);
+ ConvertReturnType (qmethod);
+ } else {
+ ConvertOverloadParams (qmethod.OverloadParams);
+ ConvertReturnType (qmethod);
+ }
+ qmethod.PascalName = ToPascalCase (qmethod.Name);
+ CheckSig (qmethod);
+ }
+ }
+
+ public void CheckSig (QMethod qmethod)
+ {
+ sig.Append (qmethod.PascalName);
+ foreach (QParam qparam in qmethod.CSharpParams) {
+ sig.Append (qparam.Type);
+ }
+ if (!sigs.Contains (sig.ToString ()) && !sigs.Contains ("The"+sig.ToString ())) {
+ sigs.Add (sig.ToString ());
+ } else {
+ Console.WriteLine ("Throttling "+qtype.Name+" "+qmethod.PascalName);
+ qmethod.Throttle = true;
+ }
+ sig.Length = 0;
+ }
+
+ public void CheckSig (QCtor qctor)
+ {
+ sig.Append (qctor.Name);
+ foreach (QParam qparam in qctor.CSharpParams) {
+ //if (qparam.Type == "QWidget" && qparam.Name == "parent")
+ if (qparam.Name == "parent")
+ qctor.Parent = true;
+ sig.Append (qparam.Type);
+ }
+ if (!sigs.Contains (sig.ToString ()))
+ sigs.Add (sig.ToString ());
+ else {
+ Console.WriteLine ("Throttling "+qtype.Name+" "+qctor.Access+" "+qctor.Name);
+ qctor.Throttle = true;
+ }
+ sig.Length = 0;
+ }
+
+ public void ConvertCSharpParams (ArrayList qparams)
+ {
+ foreach (QParam qparam in qparams) {
+ qparam.Type = qmap.ArrayType (qparam.Type);
+ qparam.Type = StripBad (qparam.Type);
+ qparam.Type = qmap.CSharpType (qparam.Type);
+ qparam.Type = ConvertQString (qparam.Type);
+ qparam.Name = qmap.ReservedType (qparam.Name);
+ }
+ }
+
+ public void ConvertPinvokeCallParams (ArrayList qparams)
+ {
+ foreach (QParam qparam in qparams) {
+ qparam.Type = qmap.ArrayType (qparam.Type);
+ qparam.Type = StripBad (qparam.Type);
+ qparam.Type = qmap.CSharpType (qparam.Type);
+ qparam.Name = qmap.ReservedType (qparam.Name);
+ if (IsQObject (qparam.Type))
+ qparam.Name = qparam.Name + ".RawObject";
+ if (IsIQObject (qparam.Type))
+ qparam.Name = qparam.Name + "." + StripInterface (qparam.Type) + " ()";
+ /* if (IsQString (qparam.Type))
+ qparam.Name = "new QString ("+StripPtr(qparam.Name)+").RawObject";*/
+ qparam.Type = "";
+ }
+ }
+
+ public void ConvertPinvokeParams (ArrayList qparams)
+ {
+ foreach (QParam qparam in qparams) {
+ qparam.Type = qmap.ArrayType (qparam.Type);
+ qparam.Type = StripBad (qparam.Type);
+ qparam.Type = qmap.PinvokeType (qparam.Type);
+ qparam.Name = qmap.ReservedType (qparam.Name);
+ if (IsQObject (qparam.Type) || IsIQObject (qparam.Type))
+ qparam.Type = "IntPtr";
+ }
+ }
+
+ public void ConvertOverloadParams (ArrayList qparams)
+ {
+ foreach (QParam qparam in qparams) {
+ qparam.Type = qmap.ArrayType (qparam.Type);
+ qparam.Type = StripBad (qparam.Type);
+ qparam.Type = qmap.CSharpType (qparam.Type);
+ OverloadedLastParam (qparam, qparams);
+ OverloadedNull (qparam);
+ OverloadedQString (qparam);
+ OverloadedQObject (qparam);
+ OverloadedNestedEnum (qparam);
+ OverloadedNullString (qparam);
+ OverloadedBool (qparam);
+ OverloadedEnum (qparam);
+ OverloadedArray (qparam);
+ OverloadedHex (qparam);
+ OverloadedDefault (qparam);
+ }
+ }
+
+ public void OverloadedLastParam (QParam qparam, ArrayList qparams)
+ {
+ if (qparams.IndexOf (qparam) != qparams.Count - 1)
+ qparam.Default = null;
+ }
+
+ public void OverloadedNull (QParam qparam)
+ {
+ if (qparam.Default == null)
+ qparam.Type = "";
+ }
+
+ public void OverloadedQString (QParam qparam)
+ {
+ if (IsQString (qparam.Type)){
+ qparam.Type = "QString";
+ if (qparam.Default == "QString::null")
+ qparam.Default = "null";
+ else if (qparam.Default == "quotquot")
+ qparam.Default = "null";
+ else
+ qparam.Default = "\""+qparam.Default+"\"";
+ }
+ }
+
+ public void OverloadedQObject (QParam qparam)
+ {
+ if (IsQObject (qparam.Type)) {
+ qparam.Name = "new "+qparam.Type+" ()";
+ qparam.Type = "";
+ }
+ }
+
+ public void OverloadedNestedEnum (QParam qparam)
+ {
+ foreach (QEnum qenum in qtype.QEnums) {
+ if (qparam.Type == qenum.Name) {
+ foreach (QItem qitem in qenum.QItems) {
+ if (qparam.Default == qitem.Name) {
+ qparam.Name = qparam.Type+"."+qparam.Default;
+ qparam.Type = "";
+ }
+ }
+ }
+ }
+ }
+
+ public void OverloadedNullString (QParam qparam)
+ {
+ if (qmap.OverloadType (qparam.Type) == "string" && qparam.Default == "0") {
+ qparam.Type = "";
+ qparam.Name = "\"\"";
+ }
+ }
+
+ public void OverloadedBool (QParam qparam)
+ {
+ if (qparam.Default == "TRUE") {
+ qparam.Type = "";
+ qparam.Name = "true";
+ } else if (qparam.Default == "FALSE") {
+ qparam.Type = "";
+ qparam.Name = "false";
+ } else if (qparam.Type == "bool" && qparam.Default == "1") {
+ qparam.Type = "";
+ qparam.Name = "true";
+ } else if (qparam.Type == "bool" && qparam.Default == "0") {
+ qparam.Type = "";
+ qparam.Name = "false";
+ }
+ }
+
+ public void OverloadedEnum (QParam qparam)
+ {
+ if (IsEnum (qparam.Type)) {
+ qparam.Name = qparam.Type + "." + EnumValue (qparam.Type, qparam.Default);
+ qparam.Type = "";
+ }
+ }
+
+ public void OverloadedArray (QParam qparam)
+ {
+ if (IsArray (qparam.Type)) {
+ qparam.Name = "new "+qparam.Type+"{"+qparam.Default+"}";
+ qparam.Type = "";
+ }
+ }
+
+ public void OverloadedHex (QParam qparam)
+ {
+ if (qparam.Default == "0xffffffff")
+ qparam.Default = "1";
+ }
+
+ public void OverloadedDefault (QParam qparam)
+ {
+ if (qparam.Type != "") {
+ qparam.Type = "("+qmap.OverloadType (qparam.Type)+")";
+ qparam.Name = qparam.Default;
+ }
+ }
+
+ public void ConvertReturnType (QMethod qmethod)
+ {
+ qmethod.Return = qmap.ArrayType (qmethod.Return);
+ qmethod.Return = qmap.PinvokeType (StripBad (qmethod.Return));
+ if (IsQObject(qmethod.Return)) {
+ qmethod.Boxer = true;
+ qmethod.PinvokeReturn = "IntPtr";
+ } else {
+ qmethod.PinvokeReturn = qmethod.Return;
+ }
+ if (qmethod.Return == "QString") {
+ qmethod.QStringReturn = true;
+ }
+ }
+
+ public string StripBad (string str)
+ {
+ str = StripPointer (str);
+ str = StripColon (str);
+ return str;
+ }
+
+ public string StripPointer (string str)
+ {
+ str = str.Replace ("*", "");
+ str = str.Replace ("&", "");
+ if (str.StartsWith ("amp"))
+ str = str.Replace ("amp", "");
+ if (str.EndsWith ("amp"))
+ str = str.Replace ("amp", "");
+ return str;
+ }
+
+ public string ConvertQString (string str)
+ {
+ if (IsQString (str))
+ return "QString";
+ else
+ return str;
+ }
+
+ public string StripColon (string str)
+ {
+ return str = str.Replace ("::", ".");
+ }
+
+ public string StripPtr (string str)
+ {
+ return str = str.Replace (".RawObject", "");
+ }
+
+ public string StripInterface (string str)
+ {
+ return str = str.Replace ("I", "");
+ }
+
+ public string StripEnum (string str)
+ {
+ str = StripColon (str);
+ if (str.IndexOf (".") > 0)
+ return str.Substring (str.IndexOf (".")+1);
+ else
+ return str;
+ }
+
+ public string ToPascalCase (string name)
+ {
+ string pascal = System.Char.ToUpper (name[0]).ToString ()+name.Substring (1, name.Length -1);
+ foreach (QEnum qenum in qtype.QEnums) {
+ if (pascal == qenum.Name)
+ pascal = "The"+pascal;
+ }
+ return pascal;
+ }
+
+ public string EnumValue (string type, string value)
+ {
+ bool match = false;
+ string enumname = StripEnum (type);
+ value = StripEnum (value);
+
+ // There _has_ to be a better way, but I'm tired...
+ foreach (QType qtype in qtypes) {
+ foreach (QEnum qenum in qtype.QEnums) {
+ if (enumname == qenum.Name) {
+ foreach (QItem qitem in qenum.QItems) {
+ if (value == qitem.Name) {
+ match = true;
+ }
+ }
+ if (!match) {
+ foreach (QItem qitem in qenum.QItems) {
+ value = qitem.Name;
+ break;
+ }
+ }
+ }
+ }
+ }
+ return value;
+ }
+
+ public void Ancestors ()
+ {
+ if (qtype.IsInterface || qtype.QAncestors.Count < 2)
+ return;
+
+ string iname = "";
+ foreach (QAncestor qancestor in qtype.QAncestors) {
+ iname = qmap.InterfaceType (qancestor.Name);
+ foreach (QType _qtype in qtypes) {
+ if (_qtype.Name == qancestor.Name && iname != qancestor.Name) {
+ if (!_qtype.IsConverted) {
+ Converter converter = new Converter (qtypes, _qtype, qmap);
+ }
+ qtype.AddQMethod (instPointer (qancestor.Name));
+ qancestor.QMethods = _qtype.QMethods;
+ qancestor.IsInterface = true;
+ qancestor.IName = iname;
+ foreach (QMethod qmethod in qancestor.QMethods) {
+ CheckSig (qmethod);
+ }
+ }
+ }
+ }
+ }
+
+ public QMethod instPointer (string name)
+ {
+ QMethod qmethod = new QMethod ();
+ qmethod.Name = name;
+ qmethod.PascalName = name;
+ qmethod.Access = "public";
+ qmethod.PinvokeReturn = "IntPtr";
+ qmethod.Return = "IntPtr";
+ qmethod.Id = "0";
+ return qmethod;
+ }
+
+ public bool IsQString (string str)
+ {
+ if (qtype.Name == "QString")
+ return true;
+ else if (IsQObject (str) && str == "QString")
+ return true;
+ else
+ return false;
+ }
+
+ public bool IsQObject (string str)
+ {
+ //IndexOf is a hack to search for a char ;-)
+ if (str.StartsWith ("Q") && str.IndexOf (".") < 0)
+ return true;
+ else
+ return false;
+ }
+
+ public bool IsIQObject (string str)
+ {
+ //IndexOf is a hack to search for a char ;-)
+ if (str == "IntPtr") return false;
+ if (str.StartsWith ("I") && str.IndexOf (".") < 0)
+ return true;
+ else
+ return false;
+ }
+
+ public bool IsEnum (string str)
+ {
+ //IndexOf is a hack to search for a char ;-)
+ if (str.IndexOf (".") > 0)
+ return true;
+ else
+ return false;
+ }
+
+ public bool IsArray (string str)
+ {
+ if (str.EndsWith ("[]"))
+ return true;
+ else
+ return false;
+ }
+ }
+}