[Gtk-sharp-list] Gtk# audit

Rachel Hestilow hestilow@ximian.com
24 Dec 2002 02:53:19 -0600


--=-xU4xFh+KKVYkqArtcBXt
Content-Type: multipart/mixed; boundary="=-nmkq0FbJMpLT2uK7BT4g"


--=-nmkq0FbJMpLT2uK7BT4g
Content-Type: text/plain
Content-Transfer-Encoding: quoted-printable

So, this is mainly for Duncan's benefit, who wanted to do this while he
was on vacation. Basically, I've written up a set of guidelines for
auditing the correctness of the Gtk# API. This is an easy way to
contribute to Gtk#, that doesn't really require anything in the way of
coding. If you're interested in contributing, you probably will want to
coordinate over the list or IRC as to what classes you will be tackling,
lest you duplicate someone else's work...although for auditing,
duplication of effort sometimes helps, rather than hinders. Be sure to
post any metadata patches to the list, and if you have any questions,
feel free to ask.

Thanks!
Rachel



--=-nmkq0FbJMpLT2uK7BT4g
Content-Disposition: inline; filename=gtksharp-audit.txt
Content-Type: text/plain; name=gtksharp-audit.txt; charset=ANSI_X3.4-1968
Content-Transfer-Encoding: quoted-printable

Auditing the Gtk# sources
-------------------------

For the most part, the Gtk# generator is capable of generating correct .NET
APIs without any help at all. However, sometimes there are certain semantic=
s
that it is incapable of inferring from the C sources. In these cases,
metadata is required.

The best way to audit Gtk# is to go through it, class-by-class, and compare
the C# source with the C source and with the C documentation. For each
method in the class, apply the following criteria. If you find the method
needs a metadata addition, either add the metadata before you go on to the
next, or write down the details of what you have found, and then add the
metadata later. Metadata files live in sources/, and are divided up
according to namespace. For example, metadata additions to the Gtk
namespace should go into sources/Gtk.metadata. Remember, many methods are
reexpressed in Gtk# as properties. If you see a property calling a
DllImported method, the same criteria apply to it as for a method.

Things that need metadata
-------------------------

* Array parameters and return values
 =20
  These are often indistinguishable from pointers. One hint that it may
  be an array is that it is a double-pointer (**). However,
  some struct arrays may only have one pointer (*). The best way to find
  out is to check the documentation.

  To tag an array parameter, insert the following metadata rule:
 =20
  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"param">
        <filter level=3D"name">PARAMETERNAME</filter>
        <name>array</name>
        <value>1</value>
      </attribute>
    </data>
  </rule>

  To tag an array return value, insert the following metadata rule:

  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"return">
        <name>array</name>
        <value>1</value>
      </attribute>
    </data>
  </rule>

* GList and GSList return values.

  These are easy to identify: Their C type will be either GList* or GSList*=
.
  To marshal these, the generator must know what type of data the list
  is holding. For parameters, the generator can infer the types
  automatically. However, the generator cannot know what type of data
  the list is holding if it is a return value. Check the documentation
  and sources to determine the data type.

  If the list is holding a GObject (or anything derived from a GObject),
  Gtk# can infer the type automatically even for return values, and
  no metadata is required. However, for structs and basic types,
  you need to explicitly specify the equivalent C# type. This should be
  a fully qualified typename, including the namespace if it is a class.
  For example, a list of PangoLayoutLine* has an element_type of
  Pango.LayoutLine, while a list of ints has an element_type of int.

  To tag a list return value, insert the following metadata rule:

  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"return">
        <name>element_type</name>
        <value>CSHARPTYPE</value>
      </attribute>
    </data>
  </rule>

* Ref-counting return values

  Sometimes, methods return GObjects without first increasing their
  reference count. This will break Gtk#'s garbage collection. In order
  to work around this, Gtk# must manually increase the reference count.

  It's difficult to determine whether or not a method needs an extra
  reference count. Sometimes the documentation will mention who owns the
  returned value. The best indicator is if a method returns the object
  directly from a struct field. For example, the source code for
  gtk_widget_get_style is as follows:

  GtkStyle*
  gtk_widget_get_style (GtkWidget *widget)
  {
    g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL);
     =20
    return widget->style;
  }

  The reference count is not increased on the returned style, so it
  needs a metadata directive.
 =20
  To tag a return value for reference counting, insert the following
  metadata rule:

  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"return">
        <name>needs_ref</name>
        <value>1</value>
      </attribute>
    </data>
  </rule>

* Parameters where NULL pointers are allowed

  Sometimes, a method allows a parameter to be NULL. Usually it has
  a special significance that cannot be worked around. The best way
  to determine if a method allows a specific parameter is to make sure
  it is not checking for it with a g_return_if_fail or g_return_val_if_fail=
.

  For example, if a function checks a parameter like this:
   g_return_if_fail (foo !=3D NULL);

  Or like this:
   g_return_if_fail (GTK_IS_FOO (foo));

  Then NULL is NOT allowed, and the default Gtk# behavior is fine. But if
  the documentation says NULL is allowed, or if Gtk+ doesn't check for
  it, it's probably allowed.

  To tag a parameter as allowing NULL, insert the following
  metadata rule:

  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"param">
        <filter level=3D"name">PARAMETERNAME</filter>
        <name>null_ok</name>
        <value>1</value>
      </attribute>
    </data>
  </rule>

* "Out" parameters

  If a C function needs to return multiple values, or if it wants to
  return a struct without having to allocate the struct itself, it
  will use pointer arguments as return values. These often have the
  same signatures as array parameters. Check the documentation, or
  check the sources to see if the parameter is being deferenced
  and assigned to.
 =20
  To tag an out parameter, insert the following metadata rule.

  <rule>
    <class name=3D"CLASSNAME">
      <method>METHODNAME</method>
    </class>
    <data>
      <attribute target=3D"param">
        <filter level=3D"name">PARAMETERNAME</filter>
        <name>pass_as</name>
        <value>out</value>
      </attribute>
    </data>
  </rule>



--=-nmkq0FbJMpLT2uK7BT4g--

--=-xU4xFh+KKVYkqArtcBXt
Content-Type: application/pgp-signature; name=signature.asc
Content-Description: This is a digitally signed message part

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

iD8DBQA+CCB/apOJdUj74F4RAug0AJ9P6lQtWXl5iZQhP8gLPAbBw9JqiACfULMv
HvILX2iN2D5SJD0+EBums+k=
=lzWq
-----END PGP SIGNATURE-----

--=-xU4xFh+KKVYkqArtcBXt--