diff options
Diffstat (limited to 'qtsharp/src/generator/Converter.cs')
-rw-r--r-- | qtsharp/src/generator/Converter.cs | 464 |
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; + } + } +} |