// 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; TQType qtype; TQTypeMap qmap; StringCollection sigs; StringBuilder sig; public Converter (ArrayList qtypes, TQType qtype, TQTypeMap 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 TQType GetTQType () { return qtype; } public void Convert () { foreach (TQCtor qctor in qtype.TQCtors) { 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 (TQMethod qmethod in qtype.TQMethods) { 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 (TQMethod qmethod) { sig.Append (qmethod.PascalName); foreach (TQParam 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 (TQCtor qctor) { sig.Append (qctor.Name); foreach (TQParam qparam in qctor.CSharpParams) { //if (qparam.Type == "TTQWidget" && 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 (TQParam qparam in qparams) { qparam.Type = qmap.ArrayType (qparam.Type); qparam.Type = StripBad (qparam.Type); qparam.Type = qmap.CSharpType (qparam.Type); qparam.Type = ConvertTQString (qparam.Type); qparam.Name = qmap.ReservedType (qparam.Name); } } public void ConvertPinvokeCallParams (ArrayList qparams) { foreach (TQParam 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 (IsTQObject (qparam.Type)) qparam.Name = qparam.Name + ".RawObject"; if (IsITQObject (qparam.Type)) qparam.Name = qparam.Name + "." + StripInterface (qparam.Type) + " ()"; /* if (IsTQString (qparam.Type)) qparam.Name = "new TTQString ("+StripPtr(qparam.Name)+").RawObject";*/ qparam.Type = ""; } } public void ConvertPinvokeParams (ArrayList qparams) { foreach (TQParam 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 (IsTQObject (qparam.Type) || IsITQObject (qparam.Type)) qparam.Type = "IntPtr"; } } public void ConvertOverloadParams (ArrayList qparams) { foreach (TQParam 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); OverloadedTQString (qparam); OverloadedTQObject (qparam); OverloadedNestedEnum (qparam); OverloadedNullString (qparam); OverloadedBool (qparam); OverloadedEnum (qparam); OverloadedArray (qparam); OverloadedHex (qparam); OverloadedDefault (qparam); } } public void OverloadedLastParam (TQParam qparam, ArrayList qparams) { if (qparams.IndexOf (qparam) != qparams.Count - 1) qparam.Default = null; } public void OverloadedNull (TQParam qparam) { if (qparam.Default == null) qparam.Type = ""; } public void OverloadedTQString (TQParam qparam) { if (IsTQString (qparam.Type)){ qparam.Type = "TTQString"; if (qparam.Default == "TTQString::null") qparam.Default = "null"; else if (qparam.Default == "quotquot") qparam.Default = "null"; else qparam.Default = "\""+qparam.Default+"\""; } } public void OverloadedTQObject (TQParam qparam) { if (IsTQObject (qparam.Type)) { qparam.Name = "new "+qparam.Type+" ()"; qparam.Type = ""; } } public void OverloadedNestedEnum (TQParam qparam) { foreach (TQEnum qenum in qtype.TQEnums) { if (qparam.Type == qenum.Name) { foreach (TQItem qitem in qenum.TQItems) { if (qparam.Default == qitem.Name) { qparam.Name = qparam.Type+"."+qparam.Default; qparam.Type = ""; } } } } } public void OverloadedNullString (TQParam qparam) { if (qmap.OverloadType (qparam.Type) == "string" && qparam.Default == "0") { qparam.Type = ""; qparam.Name = "\"\""; } } public void OverloadedBool (TQParam 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 (TQParam qparam) { if (IsEnum (qparam.Type)) { qparam.Name = qparam.Type + "." + EnumValue (qparam.Type, qparam.Default); qparam.Type = ""; } } public void OverloadedArray (TQParam qparam) { if (IsArray (qparam.Type)) { qparam.Name = "new "+qparam.Type+"{"+qparam.Default+"}"; qparam.Type = ""; } } public void OverloadedHex (TQParam qparam) { if (qparam.Default == "0xffffffff") qparam.Default = "1"; } public void OverloadedDefault (TQParam qparam) { if (qparam.Type != "") { qparam.Type = "("+qmap.OverloadType (qparam.Type)+")"; qparam.Name = qparam.Default; } } public void ConvertReturnType (TQMethod qmethod) { qmethod.Return = qmap.ArrayType (qmethod.Return); qmethod.Return = qmap.PinvokeType (StripBad (qmethod.Return)); if (IsTQObject(qmethod.Return)) { qmethod.Boxer = true; qmethod.PinvokeReturn = "IntPtr"; } else { qmethod.PinvokeReturn = qmethod.Return; } if (qmethod.Return == "TTQString") { qmethod.TQStringReturn = 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 ConvertTQString (string str) { if (IsTQString (str)) return "TTQString"; 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 (TQEnum qenum in qtype.TQEnums) { 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 (TQType qtype in qtypes) { foreach (TQEnum qenum in qtype.TQEnums) { if (enumname == qenum.Name) { foreach (TQItem qitem in qenum.TQItems) { if (value == qitem.Name) { match = true; } } if (!match) { foreach (TQItem qitem in qenum.TQItems) { value = qitem.Name; break; } } } } } return value; } public void Ancestors () { if (qtype.IsInterface || qtype.TQAncestors.Count < 2) return; string iname = ""; foreach (TQAncestor qancestor in qtype.TQAncestors) { iname = qmap.InterfaceType (qancestor.Name); foreach (TQType _qtype in qtypes) { if (_qtype.Name == qancestor.Name && iname != qancestor.Name) { if (!_qtype.IsConverted) { Converter converter = new Converter (qtypes, _qtype, qmap); } qtype.AddTQMethod (instPointer (qancestor.Name)); qancestor.TQMethods = _qtype.TQMethods; qancestor.IsInterface = true; qancestor.IName = iname; foreach (TQMethod qmethod in qancestor.TQMethods) { CheckSig (qmethod); } } } } } public TQMethod instPointer (string name) { TQMethod qmethod = new TQMethod (); qmethod.Name = name; qmethod.PascalName = name; qmethod.Access = "public"; qmethod.PinvokeReturn = "IntPtr"; qmethod.Return = "IntPtr"; qmethod.Id = "0"; return qmethod; } public bool IsTQString (string str) { if (qtype.Name == "TTQString") return true; else if (IsTQObject (str) && str == "TTQString") return true; else return false; } public bool IsTQObject (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 IsITQObject (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; } } }