2002-02-02 Mike Kestner <mkestner@speakeasy.net>
* generator/ObjectGen.cs : Add IntPtr constructor generation. Pass a ctor signature hash around to use in clash resolution. Generate a void ctor if none is present which just calls the parent ctor. * generator/StructBase.cs : Add non-void signature ctor generation, including collision handling logic. Collisions are implemented as static methods. * generator/SymbolTable.cs : Map GSList to GLib.SList. Add type trimming to remove trailing *'s. Need to suppress leading const yet. * glib/Object.cs : Add default ctor for void and IntPtr ctors. * glib/SList.cs : Implementation of a wrapper class for GSLists. Lots of FIXMEs. * parser/gapi2xml.pl : Handle ** and array params. svn path=/trunk/gtk-sharp/; revision=2232
This commit is contained in:
parent
2a29390caf
commit
2918e60a50
8 changed files with 451 additions and 21 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
|||
2002-02-02 Mike Kestner <mkestner@speakeasy.net>
|
||||
|
||||
* generator/ObjectGen.cs : Add IntPtr constructor generation. Pass a
|
||||
ctor signature hash around to use in clash resolution. Generate a
|
||||
void ctor if none is present which just calls the parent ctor.
|
||||
* generator/StructBase.cs : Add non-void signature ctor generation,
|
||||
including collision handling logic. Collisions are implemented as
|
||||
static methods.
|
||||
* generator/SymbolTable.cs : Map GSList to GLib.SList. Add type
|
||||
trimming to remove trailing *'s. Need to suppress leading const yet.
|
||||
* glib/Object.cs : Add default ctor for void and IntPtr ctors.
|
||||
* glib/SList.cs : Implementation of a wrapper class for GSLists. Lots
|
||||
of FIXMEs.
|
||||
* parser/gapi2xml.pl : Handle ** and array params.
|
||||
|
||||
2002-01-17 Mike Kestner <mkestner@speakeasy.net>
|
||||
|
||||
* generator/BoxedGen.cs : Removed Name, CName, and QualifiedName.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
namespace GtkSharp.Generation {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Xml;
|
||||
|
||||
|
@ -59,6 +60,11 @@ namespace GtkSharp.Generation {
|
|||
}
|
||||
sw.WriteLine ();
|
||||
|
||||
sw.WriteLine("\t\tpublic " + Name + "(IntPtr raw) : base(raw) {}");
|
||||
sw.WriteLine();
|
||||
|
||||
Hashtable clash_map = new Hashtable();
|
||||
|
||||
foreach (XmlNode node in elem.ChildNodes) {
|
||||
|
||||
XmlElement member = (XmlElement) node;
|
||||
|
@ -74,7 +80,7 @@ namespace GtkSharp.Generation {
|
|||
break;
|
||||
|
||||
case "constructor":
|
||||
if (!GenCtor(member, table, sw)) {
|
||||
if (!GenCtor(member, table, sw, clash_map)) {
|
||||
Console.WriteLine("in object " + CName);
|
||||
}
|
||||
break;
|
||||
|
@ -97,6 +103,11 @@ namespace GtkSharp.Generation {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
if (!clash_map.ContainsKey("")) {
|
||||
sw.WriteLine("\t\tpublic " + Name + "() : base(){}");
|
||||
sw.WriteLine();
|
||||
}
|
||||
|
||||
sw.WriteLine ("\t}");
|
||||
sw.WriteLine ();
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
namespace GtkSharp.Generation {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
|
||||
public class StructBase {
|
||||
|
@ -43,33 +45,48 @@ namespace GtkSharp.Generation {
|
|||
}
|
||||
|
||||
|
||||
protected bool GenCtor(XmlElement ctor, SymbolTable table, StreamWriter sw)
|
||||
protected bool GenCtor(XmlElement ctor, SymbolTable table, StreamWriter sw, Hashtable clash_map)
|
||||
{
|
||||
String sig, isig, call;
|
||||
String sig, isig, call, sigtypes;
|
||||
XmlElement parms = ctor["parameters"];
|
||||
|
||||
if (parms == null) {
|
||||
sig = "()";
|
||||
isig = call = "();";
|
||||
//} else if (!GetSignature(parms, table, out sig) ||
|
||||
// !GetImportSig(parms, table, out isig) ||
|
||||
// !GetCallString(parms, table, out call)) {
|
||||
// Console.Write("ctor ");
|
||||
// return false;
|
||||
} else {
|
||||
Console.Write("ctor with parms ");
|
||||
return false;
|
||||
sigtypes = "";
|
||||
} else if (!GetSignature(parms, table, out sig, out sigtypes) ||
|
||||
!GetImportSig(parms, table, out isig) ||
|
||||
!GetCallString(parms, table, out call)) {
|
||||
Console.Write("ctor ");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool clash = false;
|
||||
if (clash_map.ContainsKey(sigtypes)) {
|
||||
clash = true;
|
||||
} else {
|
||||
clash_map[sigtypes] = ctor;
|
||||
}
|
||||
|
||||
String cname = ctor.GetAttribute("cname");
|
||||
|
||||
sw.WriteLine("\t\t[DllImport(\"" + table.GetDllName(ns) +
|
||||
"\", CallingConvention=CallingConvention.Cdecl)]");
|
||||
sw.WriteLine("\t\tstatic extern IntPtr " + cname + isig);
|
||||
sw.WriteLine();
|
||||
sw.WriteLine("\t\tpublic " + Name + sig);
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\tRawObject = " + cname + call);
|
||||
|
||||
if (clash) {
|
||||
String mname = cname.Substring(cname.IndexOf("new"));
|
||||
// mname = Regex.Replace(mname, "_(\\w)", "\\u\\1");
|
||||
sw.WriteLine("\t\tpublic static " + Name + " " + mname + sig);
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\treturn new " + Name + "(" + cname + call + ");");
|
||||
} else {
|
||||
sw.WriteLine("\t\tpublic " + Name + sig);
|
||||
sw.WriteLine("\t\t{");
|
||||
sw.WriteLine("\t\t\tRawObject = " + cname + call + ";");
|
||||
}
|
||||
|
||||
sw.WriteLine("\t\t}");
|
||||
sw.WriteLine();
|
||||
|
||||
|
@ -106,6 +123,8 @@ namespace GtkSharp.Generation {
|
|||
{
|
||||
call = "(";
|
||||
|
||||
bool need_comma = false;
|
||||
|
||||
foreach (XmlNode parm in parms.ChildNodes) {
|
||||
if (parm.Name != "parameter") {
|
||||
continue;
|
||||
|
@ -114,7 +133,7 @@ namespace GtkSharp.Generation {
|
|||
XmlElement elem = (XmlElement) parm;
|
||||
}
|
||||
|
||||
call += ");";
|
||||
call += ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -134,21 +153,55 @@ namespace GtkSharp.Generation {
|
|||
return true;
|
||||
}
|
||||
|
||||
private bool GetSignature(XmlElement parms, SymbolTable table, out String sig)
|
||||
private bool GetSignature(XmlElement parms, SymbolTable table, out String sig, out String sigtypes)
|
||||
{
|
||||
sig = "(";
|
||||
|
||||
bool need_comma = false;
|
||||
sigtypes = "";
|
||||
|
||||
foreach (XmlNode parm in parms.ChildNodes) {
|
||||
if (parm.Name != "parameter") {
|
||||
continue;
|
||||
}
|
||||
|
||||
XmlElement elem = (XmlElement) parm;
|
||||
String type = elem.GetAttribute("type");
|
||||
String cs_type = table.GetCSType(type);
|
||||
String name = elem.GetAttribute("name");
|
||||
name = MangleName(name);
|
||||
|
||||
if ((cs_type == "") || (name == "")) {
|
||||
Console.Write("Name: " + name + " Type: " + type + " ");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (elem.HasAttribute("array")) {
|
||||
cs_type += "[]";
|
||||
}
|
||||
|
||||
if (need_comma) {
|
||||
sig += ", ";
|
||||
sigtypes += ":";
|
||||
} else {
|
||||
need_comma = true;
|
||||
}
|
||||
sig += (cs_type + " " + name);
|
||||
sigtypes += cs_type;
|
||||
}
|
||||
|
||||
sig += ")";
|
||||
return true;
|
||||
}
|
||||
|
||||
private String MangleName(String name)
|
||||
{
|
||||
if (name == "string") {
|
||||
return "str1ng";
|
||||
} else {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace GtkSharp.Generation {
|
|||
simple_types.Add ("GArray", "IntPtr");
|
||||
simple_types.Add ("GData", "IntPtr");
|
||||
simple_types.Add ("GTypeModule", "GLib.Object");
|
||||
simple_types.Add ("GSList", "IntPtr");
|
||||
simple_types.Add ("GSList", "GLib.SList");
|
||||
simple_types.Add ("GHashTable", "IntPtr");
|
||||
simple_types.Add ("va_list", "IntPtr");
|
||||
simple_types.Add ("GParamSpec", "IntPtr");
|
||||
|
@ -88,8 +88,16 @@ namespace GtkSharp.Generation {
|
|||
return complex_types.GetEnumerator();
|
||||
}
|
||||
|
||||
private String Trim(String type)
|
||||
{
|
||||
char[] ast = {'*'};
|
||||
String trim_type = type.TrimEnd(ast);
|
||||
return trim_type;
|
||||
}
|
||||
|
||||
public String GetCSType(String c_type)
|
||||
{
|
||||
c_type = Trim(c_type);
|
||||
if (simple_types.ContainsKey(c_type)) {
|
||||
return (String) simple_types[c_type];
|
||||
} else if (complex_types.ContainsKey(c_type)) {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -51,6 +51,28 @@ namespace GLib {
|
|||
return null; //FIXME: Call TypeParser here eventually.
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Object Constructor
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Dummy constructor needed for derived classes.
|
||||
/// </remarks>
|
||||
|
||||
public Object () {}
|
||||
|
||||
/// <summary>
|
||||
/// Object Constructor
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Creates an object from a raw object reference.
|
||||
/// </remarks>
|
||||
|
||||
public Object (IntPtr raw)
|
||||
{
|
||||
RawObject = raw;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RawObject Property
|
||||
|
|
316
glib/SList.cs
Normal file
316
glib/SList.cs
Normal file
|
@ -0,0 +1,316 @@
|
|||
// SList.cs - GSList class wrapper implementation
|
||||
//
|
||||
// Authors: Mike Kestner <mkestner@speakeasy.net>
|
||||
//
|
||||
// (c) 2002 Mike Kestner
|
||||
|
||||
namespace GLib {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
/// <summary>
|
||||
/// SList Class
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Wrapper class for GSList.
|
||||
/// </remarks>
|
||||
|
||||
public class SList : IList {
|
||||
|
||||
// Private class and instance members
|
||||
IntPtr _list;
|
||||
int rev_cnt;
|
||||
|
||||
/// <summary>
|
||||
/// Object Constructor
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Dummy constructor needed for derived classes.
|
||||
/// </remarks>
|
||||
|
||||
public SList ()
|
||||
{
|
||||
_list = IntPtr.Zero;
|
||||
rev_cnt = 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handle Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// The raw GSList reference. There should be no need to
|
||||
/// use this other than marshaling situations.
|
||||
/// </remarks>
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return _list;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// ICollection Interface Implementation
|
||||
// ------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// Count Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// The number of elements in the SList.
|
||||
/// </remarks>
|
||||
|
||||
[DllImport("glib-1.3.dll", CallingConvention=CallingConvention.Cdecl)]
|
||||
static extern int g_slist_length(IntPtr raw);
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
return g_slist_length(_list);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IsSynchronized Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Returns false. GSLists are not threadsafe.
|
||||
/// </remarks>
|
||||
|
||||
public bool IsSynchronized {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SyncRoot Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Throws not implemented exception. GSLists are not
|
||||
/// thread safe.
|
||||
/// </remarks>
|
||||
|
||||
public object SyncRoot {
|
||||
get {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// CopyTo Method
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Copies the list to an Array.
|
||||
/// </remarks>
|
||||
|
||||
public void CopyTo(Array target, int index)
|
||||
{
|
||||
foreach (IntPtr item in this) {
|
||||
target.SetValue(item, index++);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// IEnumerable Interface Implementation
|
||||
// ------------------------------
|
||||
|
||||
public IEnumerator GetEnumerator()
|
||||
{
|
||||
return new SListEnumerator(this);
|
||||
}
|
||||
|
||||
// ------------------------------
|
||||
// IList Interface Implementation
|
||||
// ------------------------------
|
||||
|
||||
/// <summary>
|
||||
/// IsFixedSize Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Returns false. Items can be added and removed from
|
||||
/// an SList.
|
||||
/// </remarks>
|
||||
|
||||
public bool IsFixedSize {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IsReadOnly Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Returns false. Items of an SList can be modified.
|
||||
/// </remarks>
|
||||
|
||||
public bool IsReadOnly {
|
||||
get {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Item Property
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Indexer to access members of the SList.
|
||||
/// </remarks>
|
||||
|
||||
[DllImport("glib-1.3.dll", CallingConvention=CallingConvention.Cdecl)]
|
||||
static extern IntPtr g_slist_nth_data(IntPtr raw, int index);
|
||||
|
||||
public object this[int index] {
|
||||
get {
|
||||
return g_slist_nth_data(_list, index);
|
||||
}
|
||||
set {
|
||||
// FIXME: Set a data element.
|
||||
rev_cnt++;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public int Add(object o)
|
||||
{
|
||||
rev_cnt++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public void Clear()
|
||||
{
|
||||
rev_cnt++;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public bool Contains(object o)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public int IndexOf(object o)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public void Insert(int index, object o)
|
||||
{
|
||||
rev_cnt++;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public void Remove(object o)
|
||||
{
|
||||
rev_cnt++;
|
||||
}
|
||||
|
||||
// FIXME: Just a stub
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
rev_cnt++;
|
||||
}
|
||||
|
||||
// --------------
|
||||
// object methods
|
||||
// --------------
|
||||
|
||||
/// <summary>
|
||||
/// Equals Method
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Checks equivalence of two SLists.
|
||||
/// </remarks>
|
||||
|
||||
public override bool Equals (object o)
|
||||
{
|
||||
if (!(o is SList))
|
||||
return false;
|
||||
|
||||
return (Handle == ((SList) o).Handle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GetHashCode Method
|
||||
/// </summary>
|
||||
///
|
||||
/// <remarks>
|
||||
/// Calculates a hashing value.
|
||||
/// </remarks>
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return Handle.GetHashCode ();
|
||||
}
|
||||
|
||||
// Internal enumerator class
|
||||
|
||||
public class SListEnumerator : IEnumerator {
|
||||
|
||||
IntPtr _cursor;
|
||||
int i_rev;
|
||||
SList _list;
|
||||
bool virgin;
|
||||
|
||||
public SListEnumerator (SList list)
|
||||
{
|
||||
_list = list;
|
||||
i_rev = list.rev_cnt;
|
||||
virgin = true;
|
||||
}
|
||||
|
||||
public object Current {
|
||||
get {
|
||||
if (virgin || (i_rev != _list.rev_cnt)) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (_cursor == IntPtr.Zero) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Marshal.ReadIntPtr(_cursor);
|
||||
}
|
||||
}
|
||||
|
||||
public bool MoveNext()
|
||||
{
|
||||
if (i_rev != _list.rev_cnt) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
if (virgin) {
|
||||
_cursor = _list.Handle;
|
||||
} else if (_cursor != IntPtr.Zero) {
|
||||
_cursor = Marshal.ReadIntPtr(_cursor, IntPtr.Size);
|
||||
}
|
||||
|
||||
return (_cursor != IntPtr.Zero);
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
if (i_rev != _list.rev_cnt) {
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
virgin = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -418,11 +418,16 @@ sub addParamsElem
|
|||
foreach $parm (@params) {
|
||||
$parm_elem = $doc->createElement('parameter');
|
||||
$parms_elem->appendChild($parm_elem);
|
||||
$parm =~ s/\s+\*/\* /g;
|
||||
$parm =~ s/\s+(\*+)/\1 /g;
|
||||
$parm =~ s/const\s+/const-/g;
|
||||
$parm =~ /(\S+)\s+(\S+)/;
|
||||
$parm_elem->setAttribute('type', "$1");
|
||||
$parm_elem->setAttribute('name', "$2");
|
||||
$parm_elem->setAttribute('type', $1);
|
||||
my $name = $2;
|
||||
if ($name =~ /(\w+)\[\]/) {
|
||||
$name = $1;
|
||||
$parm_elem->setAttribute('array', "true");
|
||||
}
|
||||
$parm_elem->setAttribute('name', $name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue