]> git.draconx.ca Git - gob-dx.git/commitdiff
Release 0.93.0 v0.93.0
authorGeorge Lebl <jirka@5z.com>
Mon, 28 Feb 2000 20:15:00 +0000 (12:15 -0800)
committerNick Bowler <nbowler@draconx.ca>
Tue, 19 Feb 2019 17:19:20 +0000 (12:19 -0500)
18 files changed:
ChangeLog
NEWS
configure
configure.in
doc/gob.1.in
examples/README
examples/my-person.gob
gob.spec
src/checks.c
src/checks.h
src/main.c
src/main.h
src/out.c
src/parse.c
src/parse.y
src/test.gob
src/tree.c
src/tree.h

index f95e8ed2f8f8136c4a459cfb52daca506a55294b..7a85c7d373d206a1ada40742e758794366593887 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+Mon Feb 28 02:45:27 2000  George Lebl <jirka@5z.com>
+
+       * Release 0.93.0
+
+Sun Feb 27 20:59:45 2000  George Lebl <jirka@5z.com>
+
+       * src/parse.y,doc/gob.1.in: For stringlink, just return a pointer on
+         get rather then strduping as that is 1) consistent with objectlink
+         and 2) more flexible.
+
+Sun Feb 27 20:38:19 2000  George Lebl <jirka@5z.com>
+
+       * src/{main.c,tree.[ch],parse.y}: add the arbitrary destruction handler
+         for data members
+
+       * doc/gob.1.in: updated and fixed up
+
+       * configure.in,NEWS,examples/{README,my-person2.gob}: change version
+         to 0.93.0
+
+Sun Feb 27 18:37:57 2000  George Lebl <jirka@5z.com>
+
+       * NEWS,doc/gob.1.in,examples/{README,my-person.gob,my-person2.gob}:
+         update of docs and examples to include the new features and minor
+         fixups
+
+Sun Feb 27 04:41:41 2000  George Lebl <jirka@5z.com>
+
+       * src/main.c: make the output nicer for classes with no methods
+         better typechecking in get/set_arg, fix a couple of C++ issues,
+
+       * src/{main.c,parse.y,tree.[ch]}: automatic linking of arguments to
+         data members.  Also alow empty statements inside a class.  Also
+         add automatic data member destruction for pointer data, and
+         automatic initialization for any data member.
+
+       * src/main.[ch],src/out.c: add --no-lines which inhibits printing
+         of #line things to output files
+
+       * doc/gob.1.in: update for the above
+
 Fri Feb 25 15:21:47 2000  George Lebl <jirka@5z.com>
 
        * Release 0.92.4
 Fri Feb 25 15:21:47 2000  George Lebl <jirka@5z.com>
 
        * Release 0.92.4
diff --git a/NEWS b/NEWS
index ed9b415737c94c59b4fc13f3031766361d78ef93..8d1df7bded9beea77910293b2ff8e38ec8f36f95 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,11 @@
+0.93.0
+       * data member initialization
+       * pointer data member destruction
+       * automatic argument to data member linking for simple cases
+       * other minor fixes/improvements
+
 0.92.4
 0.92.4
-        * -n flag (Dave Dunkin)
+       * -n flag (Dave Dunkin)
        * all and alltop code sections (Dave Dunkin)
        * GTK_RUN_ flags for signals
        * self casting macros
        * all and alltop code sections (Dave Dunkin)
        * GTK_RUN_ flags for signals
        * self casting macros
index 31319a1bc9e65c7c439ade15dd129b3c5f07e319..dc43560e7f303a9d5328f9b357643c4e7bc73dbf 100755 (executable)
--- a/configure
+++ b/configure
@@ -703,7 +703,7 @@ fi
 
 PACKAGE=gob
 
 
 PACKAGE=gob
 
-VERSION=0.92.4
+VERSION=0.93.0
 
 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
 
 if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
   { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
index 22d78a16db73b3f83505df4e7d97e72e83033fea..96aa7c94c1c1903f754c21b63d443fa3f45a8561 100644 (file)
@@ -2,7 +2,7 @@ dnl Process this file with autoconf to produce a configure script.
 AC_PREREQ(2.2)
 AC_INIT(src/tree.h)
 AM_CONFIG_HEADER(config.h)
 AC_PREREQ(2.2)
 AC_INIT(src/tree.h)
 AM_CONFIG_HEADER(config.h)
-AM_INIT_AUTOMAKE(gob,0.92.4)
+AM_INIT_AUTOMAKE(gob,0.93.0)
 
 if test -f ../NOINST_GOB ; then
   DOINSTGOB=
 
 if test -f ../NOINST_GOB ; then
   DOINSTGOB=
index 6717d3e2a89cbeace89fe7367c710e33217d0f1a..df1472bb2635388ea692b713549c6bf2c9b71e02 100644 (file)
@@ -230,14 +230,86 @@ In case you use the \fB--no-private-header\fR option, no
 private header file is created and you can only access the _priv pointer
 below the class definition in the .gob file.
 .PP
 private header file is created and you can only access the _priv pointer
 below the class definition in the .gob file.
 .PP
-The fourth type is an argument type.  It is a named data member which
-is one of the features of the GTK+ object system.  You need to define a get
-and a set handler.  They are fragments of C code that will be used to 
-get the value or set the value of the argument.  Inside them you can use the
-define ARG to which you assign the data or get the data.  You can also use
-the identifier "self" as pointer to the object instance.  The type is
-defined as one of the gtk type enums, but without the GTK_TYPE_ prefix.
-For example:
+Automatic Initialization (0.93.0 and higher only):
+.PP
+You can automatically initialize the public private and protected data members
+without having to add an init method.  The advantage here is that
+initialization is kept close to the definition of the data member and thus
+it's easier to check.  To do this, just add a '=' followed by a number or
+a token.  It is also possible to include arbitrary C code for more elaborate
+initializations by putting it all in curly braces.  Note that the curly braces
+will not be printed into the output, but since gob does not C parsing it needs
+them to figure out where the C code ends.  The code will be inserted into the
+init method, above the user defined body.  So for example the following
+will initialize an integer to -1 and a string with a newly allocated string
+of "hello".
+.nf
+
+  public int foo = -1;
+  private char *bar = {g_strdup("hello")};
+
+.fi
+.PP
+Automatic Destruction (0.93.0 and higher only):
+.PP
+Most data stored as pointers needs to have a function called when the object
+is destroyed, to either free it or give up a reference.  Gob will let you
+define a function to be called on the data the object is destroyed.  This is
+achieved by putting 'destroywith' followed by a function name after the
+variable definition.  It is only called if the data you defined this on
+is not NULL, so you cans specify functions which do not handle NULL.  It
+is very much like the GDestroyNotify function used in GTK+ and glib in many
+places.  Unlike many other places, gob will not enforce any kind of type
+safety here so be a little bit more careful.  Any function you give it will
+be called as a "void function(void *)".  It will in fact be cast into such
+a form before called.  This is to avoid spurious warnings for gtk calls to
+subclass methods.  The function needs not be of that form, it just has to
+take one argument which is the pointer to the data.  You should also not
+define this on any non-pointer data as the results may be undefined.
+Example:
+.nf
+
+  public Gtk:Widget *window = NULL
+          destroywith gtk_widget_destroy;
+  public char *foo = {g_strdup("bar")}
+          destroywith g_free;
+
+.fi
+Note that the function name you give must be a real function and not macro.
+Also note that this is always called in the "finalize" method of GtkObject.
+.PP
+Sometimes you may want to run arbitrary code on destruction.  While this can
+be perfectly well done in the destroy handler.  Depending on the style you
+may want to include all destruction/initialization code together with the
+definition of the data member.  Thus you may want to put arbitrary code which
+will then be inserted into the "finalize" method of GtkObject.  This can be
+done with the "destroy" keyword followed by arbitrary code in curly braces.  
+Inside this code a macro called VAR will be define which refers to your
+variable.  So for example destroying a GString can be either done with
+a helper routine or the following code:
+.nf
+
+  public GString *string = {g_string_new(NULL)}
+          destroy {
+                 if(VAR) g_string_free(VAR, TRUE);
+         };
+
+.fi
+The thing to remember with these is that there are many ways to do this
+and you'd better be consistent in your code in how you use the above things.
+Also defining a helper routine that will do the destruction will be a nicer
+thing to do if that's a possibility.  The "destroy" keyword with code does
+take up more space in the file and it may become more cluttered.
+.PP
+GTK+ Arguments:
+.PP
+The fourth type of a data member an argument type.  It is a named data member
+which is one of the features of the GTK+ object system.  You need to define a
+get and a set handler.  They are fragments of C code that will be used to get
+the value or set the value of the argument.  Inside them you can use the define
+ARG to which you assign the data or get the data.  You can also use the
+identifier "self" as pointer to the object instance.  The type is defined as
+one of the gtk type enums, but without the GTK_TYPE_ prefix.  For example:
 .nf
 
   public int height;
 .nf
 
   public int height;
@@ -294,6 +366,79 @@ right after the GTK+ type.  Example:
 
 .fi
 .PP
 
 .fi
 .PP
+Sometimes it can become tiresome to type in the set and get handlers if
+they are trivial.  So gob since version 0.93.0 provides automatic argument
+linking to data members.  There are three different cases it handles, direct
+link (keyword 'link'), string linking (keyword 'stringlink') and object
+linking (keyword 'objectlink').  You just place the keyword after the argument
+name instead of the get/set handlers.  It will link to a data member of the
+same name that was defined earlier in the input file.  Best is to see examples:
+.nf
+
+  public int foo;
+  argument INT foo link;
+
+.fi
+is just like
+.nf
+
+  public int foo;
+  argument INT (type int) foo
+  get { ARG = self->foo; }
+  set { self->foo = ARG; };
+
+.fi
+Similiarly,
+.nf
+
+  private char * foo;
+  argument POINTER foo stringlink;
+
+.fi
+is just like
+.nf
+
+  private char * foo;
+  argument POINTER (type char *) foo
+  get {
+        ARG = self->_priv->foo;
+  } set {
+       g_free(self->_priv->foo);
+        self->_priv->foo = g_strdup(ARG);
+  }
+
+.fi
+And for the objectlink we would have:
+.nf
+
+  public Gtk:Object * foo;
+  argument POINTER foo objectlink;
+
+.fi
+is just like
+.nf
+
+  protected Gtk:Object * foo;
+  argument POINTER (type Gtk:Object *) foo
+  get {
+        ARG = self->foo;
+  } set {
+        if(self->foo)
+                gtk_object_unref(self->foo);
+        self->foo = ARG;
+        if(self->foo)
+                gtk_object_ref(self->foo);
+  }
+
+.fi
+.PP
+As you see it will handle NULLs correctly (for the string, g_free and g_strdup
+handle NULLs).  And it will also handle private, protected and public members.
+Also you should notice that when the get is used, only a pointer is always
+returned for both objectlink and strinklink.  So you should treat the returned
+value with care and never free it (and notice that it will only be around
+until you set the argument to something else or destroy the object).
+.PP
 Methods:
 .PP
 There is a whole array of possible methods.  The three normal,
 Methods:
 .PP
 There is a whole array of possible methods.  The three normal,
@@ -312,7 +457,7 @@ body.  This will define an empty function.  You can't do this for non-void
 regular public, private or protected methods, however it is acceptable for
 non-void virtual, signal and override methods.
 .PP
 regular public, private or protected methods, however it is acceptable for
 non-void virtual, signal and override methods.
 .PP
-Argument lists:
+Function argument lists:
 .PP
 For all but the init and class_init methods, you use the
 following syntax for arguments.  The first argument can be just "self",
 .PP
 For all but the init and class_init methods, you use the
 following syntax for arguments.  The first argument can be just "self",
@@ -575,6 +720,11 @@ methods.  You shouldn't generally use 3 underscores even in override method
 argument lists and virtual and signal method names as it might confuse the
 PARENT_HANDLER macro.  In fact avoiding all names with three underscores is
 the best policy when working with gob.
 argument lists and virtual and signal method names as it might confuse the
 PARENT_HANDLER macro.  In fact avoiding all names with three underscores is
 the best policy when working with gob.
+.PP
+There are a couple of defines which you shouldn't be redefining in the code
+or other headers.  These are SELF, IS_SELF, SELF_CLASS, ARG, VAR,
+PARENT_HANDLER, GET_NEW, GOB_VERSION_MAJOR, GOB_VERSION_MINOR and
+GOB_VERSION_PATCHLEVEL.
 
 .SH USING GTK-DOC STYLE INLINE DOCUMENTATION
 .PP
 
 .SH USING GTK-DOC STYLE INLINE DOCUMENTATION
 .PP
index d5be66583e83893726fab703c5cb9212041f4837..1eebe5533d180299a5f4ac7b39c2ca8e70ed5692 100644 (file)
@@ -12,3 +12,6 @@ gtk-button-count.gob  An example showing how simple it is to derive
 my-person.gob          A simple file which can store some identity
                        information about a person, it shows arguments,
                        signals and others.
 my-person.gob          A simple file which can store some identity
                        information about a person, it shows arguments,
                        signals and others.
+
+my-person2.gob         The same as above but using automatic initialization,
+                       destruction and argument linking features of 0.93.0+
index f09b1511ae205a005ecbc213e18a892284389736..06a0aaaa5608534fd186b1803167632e47df0c90 100644 (file)
@@ -1,4 +1,8 @@
-require 0.92.1
+requires 0.92.1
+
+/* This will work with an older version (0.92.1 specifically), if you want
+ * to see a version with automatic argument<->datamember linking, automatic
+ * initialization and destruction, look at my-person2.gob */
 
 %{
 #include <time.h>
 
 %{
 #include <time.h>
@@ -15,17 +19,13 @@ class My:Person from Gtk:Object {
 
        argument POINTER (type char *) name
        get {
 
        argument POINTER (type char *) name
        get {
-               if(self->name)
-                       ARG = g_strdup(self->name);
-               else
-                       ARG = NULL;
+               /* note that strdup handles NULL correctly */
+               ARG = g_strdup(self->name);
        }
        set {
        }
        set {
+               /* note that strdup handles NULL correctly */
                g_free(self->name);
                g_free(self->name);
-               if(ARG)
-                       self->name = g_strdup(ARG);
-               else
-                       self->name = NULL;
+               self->name = g_strdup(ARG);
        };
 
        argument LONG dob get { ARG = self->dob; } set { self->dob = ARG; };
        };
 
        argument LONG dob get { ARG = self->dob; } set { self->dob = ARG; };
@@ -80,6 +80,15 @@ class My:Person from Gtk:Object {
                self->_priv->rounds_in_shotgun--;
 
                /* death is imminent if we shoot oneself in the head */
                self->_priv->rounds_in_shotgun--;
 
                /* death is imminent if we shoot oneself in the head */
-               death(self,(long)time(NULL));
+               death(self, (long)time(NULL));
+       }
+
+       /* override the destroy signal where we destroy data we need to free */
+       override (Gtk:Object)
+       void
+       destroy (Gtk:Object *self (check null type))
+       {
+               g_free(MY_PERSON(self)->name);
+               PARENT_HANDLER(self);
        }
 }
        }
 }
index 886cfc4dc6ce667f1b8d49179a4508ad8247c166..ad826609cf6d743705534bb5251855c615e39d24 100644 (file)
--- a/gob.spec
+++ b/gob.spec
@@ -1,4 +1,4 @@
-%define  ver     0.92.4
+%define  ver     0.93.0
 %define  rel     1
 %define  prefix  /usr
 
 %define  rel     1
 %define  prefix  /usr
 
index 73b10d88b3aa20beb1f3f05fdfa5064a20da8a97..80602d1f16b189aba043b6ab6844371aa6be3b7a 100644 (file)
@@ -396,3 +396,35 @@ count_protecteds(Class *c)
        }
        return num;
 }
        }
        return num;
 }
+
+int
+count_destructors(Class *c)
+{
+       int num = 0;
+       GList *l;
+       for(l=c->nodes;l;l=g_list_next(l)) {
+               Node *n = l->data;
+               if(n->type == VARIABLE_NODE) {
+                       Variable *v = (Variable *)n;
+                       if(v->destructor)
+                               num++;
+               }
+       }
+       return num;
+}
+
+int
+count_initializers(Class *c)
+{
+       int num = 0;
+       GList *l;
+       for(l=c->nodes;l;l=g_list_next(l)) {
+               Node *n = l->data;
+               if(n->type == VARIABLE_NODE) {
+                       Variable *v = (Variable *)n;
+                       if(v->initializer)
+                               num++;
+               }
+       }
+       return num;
+}
index 53d19d504e55f744c696357492c57e287c965b8b..b6e9171f261ee8e6521b649490cfc8a561e150a1 100644 (file)
@@ -39,5 +39,7 @@ int count_arguments(Class *c);
 int count_overrides(Class *c);
 int count_privates(Class *c);
 int count_protecteds(Class *c);
 int count_overrides(Class *c);
 int count_privates(Class *c);
 int count_protecteds(Class *c);
+int count_destructors(Class *c);
+int count_initializers(Class *c);
 
 #endif
 
 #endif
index dedf432f1e327c2e2f19f0c5564586fa61e3a87e..226e8211265b90627b0dee0826271225ee984bce 100644 (file)
@@ -63,6 +63,8 @@ static int arguments = 0; /* number of named arguments */
 static int overrides = 0; /* number of override methods */
 static int privates = 0; /* number of private data members */
 static int protecteds = 0; /* number of protected methods */
 static int overrides = 0; /* number of override methods */
 static int privates = 0; /* number of private data members */
 static int protecteds = 0; /* number of protected methods */
+static int destructors = 0; /* number of variable destructors */
+static int initializers = 0; /* number of variable initializers */
 
 static gboolean made_aliases = FALSE;  /* if we made any shorthand aliases
                                          and need the REALLY UGLY HACK to
 
 static gboolean made_aliases = FALSE;  /* if we made any shorthand aliases
                                          and need the REALLY UGLY HACK to
@@ -83,6 +85,7 @@ gboolean always_private_header = FALSE;
 gboolean no_private_header = FALSE;
 gboolean no_extern_c = FALSE;
 gboolean no_write = FALSE;
 gboolean no_private_header = FALSE;
 gboolean no_extern_c = FALSE;
 gboolean no_write = FALSE;
+gboolean no_lines = FALSE;
 
 static void
 make_bases(void)
 
 static void
 make_bases(void)
@@ -214,6 +217,27 @@ print_method(FILE *fp, char *typeprefix, char *nameprefix,
        out_printf(fp, ")%s", postfix); 
 }
 
        out_printf(fp, ")%s", postfix); 
 }
 
+static gboolean
+any_method_to_alias(Class *c)
+{
+       GList *li;
+       
+       for(li=c->nodes;li;li=g_list_next(li)) {
+               Node *node = li->data;
+               if(node->type == METHOD_NODE) {
+                       Method *m = (Method *)node;
+                       
+                       if(m->method == INIT_METHOD ||
+                          m->method == CLASS_INIT_METHOD ||
+                          m->method == OVERRIDE_METHOD)
+                               continue;
+
+                       return TRUE;
+               }
+       }
+       return FALSE;
+}
+
 
 static void
 make_method_gnu_aliases(Class *c)
 
 static void
 make_method_gnu_aliases(Class *c)
@@ -685,6 +709,7 @@ add_enums(Class *c)
                out_printf(out,
                           "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
 
                out_printf(out,
                           "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
 
+       out_printf(out, "/* pointer to the class of our parent */\n");
        out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
 }
 
        out_printf(out, "static %sClass *parent_class = NULL;\n\n",ptypebase);
 }
 
@@ -842,7 +867,7 @@ add_signals(Class *c)
                flags = make_run_signal_flags(m, last);
                out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
                        "\t\tgtk_signal_new (\"%s\",\n"
                flags = make_run_signal_flags(m, last);
                out_printf(out,"\tobject_signals[%s_SIGNAL] =\n"
                        "\t\tgtk_signal_new (\"%s\",\n"
-                       "\t\t\%s,\n"
+                       "\t\t\t(GtkSignalRunType)(%s),\n"
                        "\t\t\tgtk_object_class->type,\n"
                        "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
                        "\t\t\t%s,\n"
                        "\t\t\tgtk_object_class->type,\n"
                        "\t\t\tGTK_SIGNAL_OFFSET (%sClass, %s),\n"
                        "\t\t\t%s,\n"
@@ -970,9 +995,9 @@ make_arguments(Class *c)
                        "\t\tGTK_TYPE_%s,\n"
                        "\t\t%s,\n"
                        "\t\tARG_%s);\n",
                        "\t\tGTK_TYPE_%s,\n"
                        "\t\t%s,\n"
                        "\t\tARG_%s);\n",
-                       typebase,a->name,a->gtktype,flags->str,s);
+                       typebase, a->name, a->gtktype, flags->str, s);
                g_free(s);
                g_free(s);
-               g_string_free(flags,TRUE);
+               g_string_free(flags, TRUE);
        }
        
        out_printf(out,
        }
        
        out_printf(out,
@@ -980,6 +1005,32 @@ make_arguments(Class *c)
                   "\tgtk_object_class->get_arg = ___object_get_arg;\n");
 }
 
                   "\tgtk_object_class->get_arg = ___object_get_arg;\n");
 }
 
+static void
+print_initializer(Method *m, Variable *v)
+{
+       char *root;
+
+       if(v->initializer == NULL)
+               return;
+
+       if(v->scope == PRIVATE_SCOPE)
+               root = g_strconcat(((FuncArg *)m->args->data)->name,
+                                  "->_priv", NULL);
+       else
+               root = g_strdup(((FuncArg *)m->args->data)->name);
+
+       if(v->initializer_line > 0)
+               out_addline_infile(out, v->initializer_line);
+
+       out_printf(out, "\t%s->%s = %s;\n",
+                  root, v->id, v->initializer);
+
+       if(v->initializer_line > 0)
+               out_addline_outfile(out);
+
+       g_free(root);
+}
+
 static void
 add_inits(Class *c)
 {
 static void
 add_inits(Class *c)
 {
@@ -991,25 +1042,36 @@ add_inits(Class *c)
                        continue;
                m = (Method *)n;
                if(m->method == INIT_METHOD) {
                        continue;
                m = (Method *)n;
                if(m->method == INIT_METHOD) {
-                       if(m->line_no>0)
+                       if(m->line_no > 0)
                                out_addline_infile(out,m->line_no);
                        print_method(out, "static ", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
                                out_addline_infile(out,m->line_no);
                        print_method(out, "static ", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
-                       if(m->line_no>0)
+                       if(m->line_no > 0)
                                out_addline_outfile(out);
                        out_printf(out,"{\n");
                                out_addline_outfile(out);
                        out_printf(out,"{\n");
-                       if(privates>0) {
+                       if(privates > 0) {
                                out_printf(out,"\t%s->_priv = "
                                out_printf(out,"\t%s->_priv = "
-                                          "g_new0 (%sPrivate,1);\n",
+                                          "g_new0 (%sPrivate, 1);\n",
                                           ((FuncArg *)m->args->data)->name,
                                           typebase);
                        }
                                           ((FuncArg *)m->args->data)->name,
                                           typebase);
                        }
+                       if(initializers > 0) {
+                               GList *li;
+                               for(li = ((Class *)class)->nodes;
+                                   li != NULL;
+                                   li = li->next) {
+                                       Node *n = li->data;
+                                       if(n->type != VARIABLE_NODE)
+                                               continue;
+                                       print_initializer(m, (Variable *)n);
+                               }
+                       }
                } else if(m->method == CLASS_INIT_METHOD) {
                } else if(m->method == CLASS_INIT_METHOD) {
-                       if(m->line_no>0)
+                       if(m->line_no > 0)
                                out_addline_infile(out, m->line_no);
                        print_method(out, "static ", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
                                out_addline_infile(out, m->line_no);
                        print_method(out, "static ", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
-                       if(m->line_no>0)
+                       if(m->line_no > 0)
                                out_addline_outfile(out);
                        out_printf(out,"{\n");
                        if(signals>0 ||
                                out_addline_outfile(out);
                        out_printf(out,"{\n");
                        if(signals>0 ||
@@ -1056,7 +1118,7 @@ add_inits(Class *c)
 }
 
 static void
 }
 
 static void
-add_getset_arg(Class *c, int is_set)
+add_getset_arg(Class *c, gboolean is_set)
 {
        GList *li;
        out_printf(out,"\nstatic void\n"
 {
        GList *li;
        out_printf(out,"\nstatic void\n"
@@ -1089,14 +1151,39 @@ add_getset_arg(Class *c, int is_set)
                        continue;
                s = g_strdup(a->name);
                g_strup(s);
                        continue;
                s = g_strdup(a->name);
                g_strup(s);
-               out_printf(out,"\tcase ARG_%s:\n"
-                       "#define ARG (GTK_VALUE_%s(*arg))\n"
-                       "\t\t{\n",
-                       s,a->gtktype);
+               if(is_set && a->atype) {
+                       char *cast = get_type(a->atype, TRUE);
+                       out_printf(out, "\tcase ARG_%s:\n", s);
+                       if(no_gnu || for_cpp) {
+                               out_printf(out, "#define ARG "
+                                          "((%s)GTK_VALUE_%s(*arg))\n",
+                                          cast, a->gtktype);
+                       } else {
+                               out_printf(out, "#ifdef __GNUC__\n");
+                               out_printf(out, "#define ARG "
+                                          "({%s foo = GTK_VALUE_%s(*arg); "
+                                            "foo; })\n",
+                                          cast, a->gtktype);
+                               out_printf(out,"#else /* __GNUC__ */\n");
+                               out_printf(out, "#define ARG "
+                                          "((%s)GTK_VALUE_%s(*arg))\n",
+                                          cast, a->gtktype);
+                               out_printf(out,"#endif /* __GNUC__ */\n\n");
+                       }
+                       out_printf(out, "\t\t{\n");
+                       g_free(cast);
+               } else {
+                       out_printf(out, "\tcase ARG_%s:\n"
+                                  "#define ARG (GTK_VALUE_%s(*arg))\n"
+                                  "\t\t{\n",
+                                  s, a->gtktype);
+               }
                g_free(s);
                g_free(s);
-               out_addline_infile(out,line_no);
+               if(line_no > 0)
+                       out_addline_infile(out, line_no);
                out_printf(out,"%s\n",cbuf);
                out_printf(out,"%s\n",cbuf);
-               out_addline_outfile(out);
+               if(line_no > 0)
+                       out_addline_outfile(out);
                out_printf(out,"\t\t}\n\t\tbreak;\n"
                        "#undef ARG\n");
        }
                out_printf(out,"\t\t}\n\t\tbreak;\n"
                        "#undef ARG\n");
        }
@@ -1116,7 +1203,7 @@ print_checks(Method *m, FuncArg *fa)
                Check *ch = li->data;
                char *s;
                /* point to the method prot in .gob for failed checks */
                Check *ch = li->data;
                char *s;
                /* point to the method prot in .gob for failed checks */
-               if(m->line_no>0)
+               if(m->line_no > 0)
                        out_addline_infile(out,m->line_no);
                if(is_void)
                        out_printf(out,"\tg_return_if_fail (");
                        out_addline_infile(out,m->line_no);
                if(is_void)
                        out_printf(out,"\tg_return_if_fail (");
@@ -1157,11 +1244,11 @@ print_checks(Method *m, FuncArg *fa)
                        break;
                }
                if(is_void)
                        break;
                }
                if(is_void)
-                       out_printf(out,");\n");
+                       out_printf(out, ");\n");
                else {
                else {
-                       out_printf(out,", (");
-                       print_type(out,m->mtype,TRUE);
-                       out_printf(out,")%s);\n",
+                       out_printf(out, ", (");
+                       print_type(out, m->mtype, TRUE);
+                       out_printf(out, ")%s);\n",
                                m->onerror?m->onerror:"0");
                }
        }
                                m->onerror?m->onerror:"0");
                }
        }
@@ -1181,20 +1268,76 @@ print_preconditions(Method *m)
                out_addline_outfile(out);
 }
 
                out_addline_outfile(out);
 }
 
+static void
+print_destructor(char *self_id, Variable *v)
+{
+       char *root;
+
+       if(v->destructor == NULL)
+               return;
+
+       if(v->scope == PRIVATE_SCOPE)
+               root = g_strconcat(self_id, "->_priv", NULL);
+       else
+               root = g_strdup(self_id);
+
+       if(v->destructor_simple) {
+               if(v->destructor_line > 0)
+                       out_addline_infile(out, v->destructor_line);
+
+               out_printf(out, "\tif(%s->%s) "
+                          "((*(void (*)(void *))%s)) (%s->%s);\n",
+                          root, v->id, v->destructor, root, v->id);
+
+               if(v->destructor_line > 0)
+                       out_addline_outfile(out);
+       } else {
+               out_printf(out, "#define VAR (%s->%s)\n", root, v->id);
+               out_printf(out, "\t{\n\t%s *self G_GNUC_UNUSED = %s;\n",
+                          typebase, self_id);
+               if(v->destructor_line > 0)
+                       out_addline_infile(out, v->destructor_line);
+
+               out_printf(out, "\t%s}\n", v->destructor);
+
+               if(v->destructor_line > 0)
+                       out_addline_outfile(out);
+               out_printf(out, "#undef VAR\n");
+       }
+
+       g_free(root);
+}
+
 /* put in code if it's needed */
 static void
 put_in_gen_code(Method *m)
 {
 /* put in code if it's needed */
 static void
 put_in_gen_code(Method *m)
 {
-       /* now we only have the freeing of the private structure */
-       if(privates>0 &&
-          m->method == OVERRIDE_METHOD &&
-          strcmp(m->id,"finalize")==0) {
-               out_printf(out,"\tg_free (%s (%s)->_priv);\n"
-                          "\t%s (%s)->_priv = NULL;\n",
-                          macrobase,
-                          ((FuncArg *)m->args->data)->name,
-                          macrobase,
-                          ((FuncArg *)m->args->data)->name);
+       if(m->method == OVERRIDE_METHOD &&
+          strcmp(m->id, "finalize")==0) {
+               if(privates > 0 || destructors > 0) {
+                       out_printf(out,"\t%s *___self = %s (%s);\n",
+                                  typebase, macrobase,
+                                  ((FuncArg *)m->args->data)->name);
+               }
+               if(destructors > 0) {
+                       GList *li;
+                       for(li = ((Class *)class)->nodes;
+                           li != NULL;
+                           li = li->next) {
+                               Node *n = li->data;
+                               if(n->type == VARIABLE_NODE)
+                                       print_destructor("___self",
+                                                        (Variable *)n);
+                       }
+               }
+               if(privates > 0) {
+                       out_printf(out,"\tg_free (___self->_priv);\n"
+                                  "\t___self->_priv = NULL;\n",
+                                  macrobase,
+                                  ((FuncArg *)m->args->data)->name,
+                                  macrobase,
+                                  ((FuncArg *)m->args->data)->name);
+               }
        }
 }
 
        }
 }
 
@@ -1213,13 +1356,13 @@ print_method_body(Method *m, int pre)
           ugly in the .c file, but that is not supposed to be
           human readable anyway. */
        if(m->cbuf) {
           ugly in the .c file, but that is not supposed to be
           human readable anyway. */
        if(m->cbuf) {
-               out_printf(out,"{\n");
+               out_printf(out, "{\n");
                if(m->ccode_line>0)
                if(m->ccode_line>0)
-                       out_addline_infile(out,m->ccode_line);
-               out_printf(out,"\t%s}",m->cbuf);
+                       out_addline_infile(out, m->ccode_line);
+               out_printf(out, "\t%s}", m->cbuf);
        }
 
        }
 
-       out_printf(out,"}\n");
+       out_printf(out, "}\n");
 
        if(m->cbuf)
                out_addline_outfile(out);
 
        if(m->cbuf)
                out_addline_outfile(out);
@@ -1249,7 +1392,7 @@ get_arg_names_for_macro(Method *m)
 {
        char *p;
        GList *li;
 {
        char *p;
        GList *li;
-       GString *gs = g_string_new("");
+       GString *gs = g_string_new(NULL);
        p = "";
        for(li=m->args;li;li=g_list_next(li)) {
                FuncArg *arg = li->data;
        p = "";
        for(li=m->args;li;li=g_list_next(li)) {
                FuncArg *arg = li->data;
@@ -1257,7 +1400,7 @@ get_arg_names_for_macro(Method *m)
                p = ",";
        }
        p = gs->str;
                p = ",";
        }
        p = gs->str;
-       g_string_free(gs,FALSE);
+       g_string_free(gs, FALSE);
        return p;
 }
 
        return p;
 }
 
@@ -1284,7 +1427,7 @@ put_method(Method *m)
                else /* PUBLIC, PROTECTED */
                        print_method(out, "", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
                else /* PUBLIC, PROTECTED */
                        print_method(out, "", "\n", "", " ", "\n",
                                     m, FALSE, FALSE);
-               print_method_body(m,TRUE);
+               print_method_body(m, TRUE);
                break;
        case SIGNAL_FIRST_METHOD:
        case SIGNAL_LAST_METHOD:
                break;
        case SIGNAL_FIRST_METHOD:
        case SIGNAL_LAST_METHOD:
@@ -1480,9 +1623,9 @@ put_argument_nongnu_wrappers(Class *c)
                s = g_strdup(a->name);
                g_strup(s);
                if(a->atype)
                s = g_strdup(a->name);
                g_strup(s);
                if(a->atype)
-                       cast = get_type(a->atype,TRUE);
+                       cast = get_type(a->atype, TRUE);
                else
                else
-                       cast = g_strdup(get_cast(a->gtktype,TRUE));
+                       cast = g_strdup(get_cast(a->gtktype, TRUE));
 
                if(cast) {
                        if(a->set)
 
                if(cast) {
                        if(a->set)
@@ -1804,18 +1947,22 @@ print_class_block(Class *c)
 
        add_get_type();
 
 
        add_get_type();
 
-       if(no_gnu)
-               make_method_nongnu_aliases(c);
-       else {
-               out_printf(out,"\n#ifdef __GNUC__\n");
-               make_method_gnu_aliases(c);
-               out_printf(out,"#else /* __GNUC__ */\n");
-               make_method_nongnu_aliases(c);
-               out_printf(out,"#endif /* __GNUC__ */\n\n");
+       if(any_method_to_alias(c)) {
+               if(no_gnu)
+                       make_method_nongnu_aliases(c);
+               else {
+                       out_printf(out,"\n#ifdef __GNUC__\n");
+                       make_method_gnu_aliases(c);
+                       out_printf(out,"#else /* __GNUC__ */\n");
+                       make_method_nongnu_aliases(c);
+                       out_printf(out,"#endif /* __GNUC__ */\n\n");
+               }
        }
 
        }
 
-       out_printf(out,"#define GET_NEW (gtk_type_new(%s_get_type()))\n",
-                  funcbase);
+       out_printf(out,"/* a macro for creating a new object of our type */\n");
+       out_printf(out,
+                  "#define GET_NEW ((%s *)gtk_type_new(%s_get_type()))\n\n",
+                  typebase, funcbase);
 
        add_inits(c);
 
 
        add_inits(c);
 
@@ -1831,8 +1978,6 @@ print_class_block(Class *c)
                }
        }
 
                }
        }
 
-       out_printf(out,"#undef GET_NEW\n");
-
        add_bad_hack_to_avoid_unused_warnings(c);
 }
 
        add_bad_hack_to_avoid_unused_warnings(c);
 }
 
@@ -1852,13 +1997,14 @@ print_file_comments(void)
 {
        time_t curtime;
        time(&curtime);
 {
        time_t curtime;
        time(&curtime);
-       out_printf(outh,"/* Generated by GOB (v%s)"
-              "   (do not edit directly) */\n\n",VERSION);
+       out_printf(outh, "/* Generated by GOB (v%s)"
+                  "   (do not edit directly) */\n\n", VERSION);
        if(outph)
                out_printf(outph,"/* Generated by GOB (v%s)"
        if(outph)
                out_printf(outph,"/* Generated by GOB (v%s)"
-                          "   (do not edit directly) */\n\n",VERSION);
+                          "   (do not edit directly) */\n\n", VERSION);
        out_printf(out,"/* Generated by GOB (v%s) on %s"
        out_printf(out,"/* Generated by GOB (v%s) on %s"
-              "   (do not edit directly) */\n\n",VERSION,ctime(&curtime));
+                  "   (do not edit directly) */\n\n",
+                  VERSION, ctime(&curtime));
 }
 
 static void
 }
 
 static void
@@ -1867,17 +2013,17 @@ print_includes(void)
        gboolean found_header;
        char *p;
 
        gboolean found_header;
        char *p;
 
-       p = g_strconcat(filebase,".h",NULL);
+       p = g_strconcat(filebase, ".h", NULL);
        found_header = TRUE;
        found_header = TRUE;
-       if(!g_list_find_custom(include_files,p,(GCompareFunc)strcmp)) {
-               out_printf(out,"#include \"%s.h\"\n\n",filebase);
+       if(!g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
+               out_printf(out, "#include \"%s.h\"\n\n", filebase);
                found_header = FALSE;
        }
        g_free(p);
 
        /* if we are creating a private header see if it was included */
        if(outph) {
                found_header = FALSE;
        }
        g_free(p);
 
        /* if we are creating a private header see if it was included */
        if(outph) {
-               p = g_strconcat(filebase,"-private.h",NULL);
+               p = g_strconcat(filebase, "-private.h", NULL);
                if(!g_list_find_custom(include_files,p,(GCompareFunc)strcmp)) {
                        out_printf(out,"#include \"%s-private.h\"\n\n",
                                   filebase);
                if(!g_list_find_custom(include_files,p,(GCompareFunc)strcmp)) {
                        out_printf(out,"#include \"%s-private.h\"\n\n",
                                   filebase);
@@ -1901,21 +2047,21 @@ print_header_prefixes(void)
 {
        char *p;
 
 {
        char *p;
 
-       p = replace_sep(((Class *)class)->otype,'_');
+       p = replace_sep(((Class *)class)->otype, '_');
        g_strup(p);
        g_strup(p);
-       out_printf(outh,"#ifndef __%s_H__\n#define __%s_H__\n\n",p,p);
+       out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
        if(outph)
        if(outph)
-               out_printf(outph,"#ifndef __%s_PRIVATE_H__\n"
+               out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
                           "#define __%s_PRIVATE_H__\n\n"
                           "#define __%s_PRIVATE_H__\n\n"
-                          "#include \"%s.h\"\n\n",p,p,filebase);
+                          "#include \"%s.h\"\n\n", p, p, filebase);
        g_free(p);
 
        if(!no_extern_c) {
        g_free(p);
 
        if(!no_extern_c) {
-               out_printf(outh,"#ifdef __cplusplus\n"
+               out_printf(outh, "#ifdef __cplusplus\n"
                           "extern \"C\" {\n"
                           "#endif /* __cplusplus */\n\n");
                if(outph)
                           "extern \"C\" {\n"
                           "#endif /* __cplusplus */\n\n");
                if(outph)
-                       out_printf(outph,"#ifdef __cplusplus\n"
+                       out_printf(outph, "#ifdef __cplusplus\n"
                                   "extern \"C\" {\n"
                                   "#endif /* __cplusplus */\n\n");
        }
                                   "extern \"C\" {\n"
                                   "#endif /* __cplusplus */\n\n");
        }
@@ -2028,7 +2174,8 @@ print_help(void)
                "\t                        structure and protected "
                                          "prototypes inside c file\n"
                "\t--no-write,-n           Don't write output files, just "
                "\t                        structure and protected "
                                          "prototypes inside c file\n"
                "\t--no-write,-n           Don't write output files, just "
-                                         "check syntax\n");
+                                         "check syntax\n"
+               "\t--no-lines              Don't print '#line' to output\n");
 }
 
 static void
 }
 
 static void
@@ -2076,6 +2223,8 @@ parse_options(int argc, char *argv[])
                        no_extern_c = TRUE;
                } else if(strcmp(argv[i], "--no-write")==0) {
                        no_write = TRUE;
                        no_extern_c = TRUE;
                } else if(strcmp(argv[i], "--no-write")==0) {
                        no_write = TRUE;
+               } else if(strcmp(argv[i], "--no-lines")==0) {
+                       no_lines = TRUE;
                } else if(strcmp(argv[i], "--")==0) {
                        /*further arguments are files*/
                        no_opts = TRUE;
                } else if(strcmp(argv[i], "--")==0) {
                        /*further arguments are files*/
                        no_opts = TRUE;
@@ -2169,6 +2318,8 @@ main(int argc, char *argv[])
        overrides = count_overrides((Class *)class);
        privates = count_privates((Class *)class);
        protecteds = count_protecteds((Class *)class);
        overrides = count_overrides((Class *)class);
        privates = count_privates((Class *)class);
        protecteds = count_protecteds((Class *)class);
+       destructors = count_destructors((Class *)class);
+       initializers = count_initializers((Class *)class);
 
        make_bases();
        make_inits((Class *)class);
 
        make_bases();
        make_inits((Class *)class);
index b9f2c838d61222f48fb207166f3d0fe9004c8a22..05d20b3b5ca9190ba4f4f55186674e18b4e72f63 100644 (file)
@@ -10,6 +10,8 @@ extern gboolean got_error;
 extern gboolean always_private_header;
 extern gboolean no_private_header;
 extern gboolean no_extern_c;
 extern gboolean always_private_header;
 extern gboolean no_private_header;
 extern gboolean no_extern_c;
+extern gboolean no_write;
+extern gboolean no_lines;
 
 extern char *filename;
 extern char *filebase;
 
 extern char *filename;
 extern char *filebase;
index 77dabd1b752be2e049878612fa2bc3ae72afabbb..0803893528be99d0e6ac14a90b05a2b77fa0f11c 100644 (file)
--- a/src/out.c
+++ b/src/out.c
@@ -24,31 +24,34 @@ strchrcnt(char *s, char c)
 }
 
 void
 }
 
 void
-out_printf(FILE *fp,char *format,...)
+out_printf(FILE *fp, char *format,...)
 {
        va_list ap;
        char *s;
 
 {
        va_list ap;
        char *s;
 
-       va_start(ap,format);
-       s = g_strdup_vprintf(format,ap);
+       va_start(ap, format);
+       s = g_strdup_vprintf(format, ap);
        va_end(ap);
 
        if(fp == out)
        va_end(ap);
 
        if(fp == out)
-               outline += strchrcnt(s,'\n');
+               outline += strchrcnt(s, '\n');
        else if(fp == outh)
        else if(fp == outh)
-               outhline += strchrcnt(s,'\n');
+               outhline += strchrcnt(s, '\n');
        else if(fp == outph)
        else if(fp == outph)
-               outphline += strchrcnt(s,'\n');
+               outphline += strchrcnt(s, '\n');
        else
                g_assert_not_reached();
 
        else
                g_assert_not_reached();
 
-       fprintf(fp,"%s",s);
+       fprintf(fp, "%s", s);
        g_free(s);
 }
 
 void
 out_addline_infile(FILE *fp, int line)
 {
        g_free(s);
 }
 
 void
 out_addline_infile(FILE *fp, int line)
 {
+       if(no_lines)
+               return;
+
        if(fp == out) {
                outline++;
                in_out = FALSE;
        if(fp == out) {
                outline++;
                in_out = FALSE;
@@ -61,12 +64,15 @@ out_addline_infile(FILE *fp, int line)
        } else
                g_assert_not_reached();
 
        } else
                g_assert_not_reached();
 
-       fprintf(fp,"#line %d \"%s\"\n",line,filename);
+       fprintf(fp, "#line %d \"%s\"\n", line, filename);
 }
 
 void
 out_addline_outfile(FILE *fp)
 {
 }
 
 void
 out_addline_outfile(FILE *fp)
 {
+       if(no_lines)
+               return;
+
        if(fp == out) {
                if(in_out) return;
                outline++;
        if(fp == out) {
                if(in_out) return;
                outline++;
index b70b55019420779aac7e0079e5bd948848c33f7f..4e7592d66eb1926b2a8d3bbc9edc1bca51a1e620 100644 (file)
@@ -65,6 +65,13 @@ static GList *checks = NULL;
 static int has_self = FALSE;
 static int vararg = FALSE;
 
 static int has_self = FALSE;
 static int vararg = FALSE;
 
+/* destructor and initializer for variables */
+static char *destructor = NULL;
+static int destructor_line = 0;
+static gboolean destructor_simple = TRUE;
+static char *initializer = NULL;
+static int initializer_line = 0;
+
 static GList *gtktypes = NULL;
 
 /* this can be a global as we will only do one function at a time
 static GList *gtktypes = NULL;
 
 /* this can be a global as we will only do one function at a time
@@ -120,7 +127,10 @@ push_variable(char *name, int scope, int line_no, char *postfix)
 
        type->postfix = postfix;
        
 
        type->postfix = postfix;
        
-       var = new_variable(scope,type,name,line_no);
+       var = new_variable(scope, type, name, line_no,
+                          destructor, destructor_line,
+                          destructor_simple,
+                          initializer, initializer_line);
        class_nodes = g_list_append(class_nodes, var);
 }
 
        class_nodes = g_list_append(class_nodes, var);
 }
 
@@ -220,8 +230,31 @@ push_self(char *id)
        funcargs = g_list_prepend(funcargs, node);
 }
 
        funcargs = g_list_prepend(funcargs, node);
 }
 
+static Variable *
+find_var_or_die(const char *id, int line)
+{
+       GList *li;
+       char *s;
+
+       for(li = class_nodes; li != NULL; li = li->next) {
+               Variable *var;
+               Node *node = li->data;
+               if(node->type != VARIABLE_NODE)
+                       continue;
+               var = li->data;
+               if(strcmp(var->id, id)==0)
+                       return var;
+       }
+
+       s = g_strdup_printf(_("Variable %s not defined here"), id);
+       print_error(FALSE, s, line);
+
+       g_assert_not_reached();
+       return NULL;
+}
+
 
 
-#line 203 "parse.y"
+#line 236 "parse.y"
 typedef union {
        char *id;
        GString *cbuf;
 typedef union {
        char *id;
        GString *cbuf;
@@ -243,26 +276,26 @@ typedef union {
 
 
 
 
 
 
-#define        YYFINAL         225
+#define        YYFINAL         239
 #define        YYFLAG          -32768
 #define        YYNTBASE        50
 
 #define        YYFLAG          -32768
 #define        YYNTBASE        50
 
-#define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 82)
+#define YYTRANSLATE(x) ((unsigned)(x) <= 290 ? yytranslate[x] : 86)
 
 static const char yytranslate[] = {     0,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
 
 static const char yytranslate[] = {     0,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    48,     2,     2,     2,     2,     2,     2,    40,
-    41,    43,     2,    44,    49,     2,     2,     2,     2,     2,
-     2,     2,     2,     2,     2,     2,     2,     2,    39,    46,
-    47,    45,     2,     2,     2,     2,     2,     2,     2,     2,
+     2,     2,    48,     2,     2,     2,     2,     2,     2,    41,
+    42,    44,     2,    45,    49,     2,     2,     2,     2,     2,
+     2,     2,     2,     2,     2,     2,     2,     2,    39,    47,
+    40,    46,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
-     2,     2,    37,    42,    38,     2,     2,     2,     2,     2,
+     2,     2,    37,    43,    38,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
      2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
@@ -284,16 +317,17 @@ static const char yytranslate[] = {     0,
 #if YYDEBUG != 0
 static const short yyprhs[] = {     0,
      0,     4,     7,    10,    12,    14,    16,    18,    20,    22,
 #if YYDEBUG != 0
 static const short yyprhs[] = {     0,
      0,     4,     7,    10,    12,    14,    16,    18,    20,    22,
-    24,    27,    29,    34,    38,    43,    46,    49,    52,    54,
-    56,    58,    60,    62,    64,    69,    75,    87,    96,   102,
-   104,   108,   109,   113,   115,   117,   120,   122,   125,   128,
-   131,   133,   136,   139,   141,   143,   145,   147,   150,   152,
-   154,   157,   159,   162,   164,   166,   168,   170,   172,   175,
-   177,   180,   182,   186,   190,   193,   195,   200,   204,   206,
-   209,   211,   222,   234,   244,   254,   263,   275,   284,   290,
-   293,   297,   298,   300,   302,   306,   308,   312,   314,   318,
-   320,   323,   327,   334,   342,   345,   347,   349,   352,   355,
-   359,   363,   367,   371,   373,   376
+    24,    27,    29,    34,    38,    43,    46,    48,    50,    52,
+    54,    56,    58,    60,    62,    65,    69,    72,    76,    79,
+    82,    84,    86,    87,    93,   100,   112,   121,   127,   133,
+   135,   139,   140,   144,   146,   148,   151,   153,   156,   159,
+   162,   164,   167,   170,   172,   174,   176,   178,   181,   183,
+   185,   188,   190,   193,   195,   197,   199,   201,   203,   206,
+   208,   211,   213,   217,   221,   224,   226,   231,   235,   237,
+   240,   242,   253,   265,   275,   285,   294,   306,   315,   321,
+   324,   328,   329,   331,   333,   337,   339,   343,   345,   349,
+   351,   354,   358,   365,   373,   376,   378,   380,   383,   386,
+   390,   394,   398,   402,   404,   407
 };
 
 static const short yyrhs[] = {    52,
 };
 
 static const short yyrhs[] = {    52,
@@ -301,57 +335,61 @@ static const short yyrhs[] = {    52,
      0,    24,     0,    27,     0,    25,     0,    26,     0,    28,
      0,    29,     0,    52,    51,     0,    51,     0,    54,    37,
     55,    38,     0,    54,    37,    38,     0,     3,    22,     4,
      0,    24,     0,    27,     0,    25,     0,    26,     0,    28,
      0,    29,     0,    52,    51,     0,    51,     0,    54,    37,
     55,    38,     0,    54,    37,    38,     0,     3,    22,     4,
-    22,     0,    55,    73,     0,    55,    57,     0,    55,    58,
-     0,    73,     0,    57,     0,    58,     0,    30,     0,    31,
-     0,    32,     0,    56,    62,    20,    39,     0,    56,    62,
-    20,    23,    39,     0,    33,    60,    59,    20,    20,    37,
-    24,    20,    37,    24,    39,     0,    33,    60,    59,    20,
-    20,    37,    24,    39,     0,    20,    40,    20,    62,    41,
-     0,    20,     0,    40,    61,    41,     0,     0,    20,    42,
-    61,     0,    20,     0,    63,     0,     5,    63,     0,    64,
-     0,    64,    67,     0,    12,    65,     0,    11,    65,     0,
-    65,     0,    12,    18,     0,    11,    18,     0,    18,     0,
-    17,     0,    16,     0,    20,     0,    66,    20,     0,    22,
-     0,     6,     0,    13,    15,     0,    13,     0,    14,    15,
-     0,    14,     0,    15,     0,     9,     0,     8,     0,     7,
-     0,    43,    67,     0,    43,     0,    20,    70,     0,    70,
-     0,    56,    20,    70,     0,    20,    56,    70,     0,    56,
-    70,     0,    68,     0,    20,    40,    71,    41,     0,    71,
-    44,    20,     0,    20,     0,    37,    24,     0,    39,     0,
-    35,    60,    69,    62,    20,    40,    75,    41,    74,    72,
-     0,    56,    35,    60,    68,    62,    20,    40,    75,    41,
-    74,    72,     0,    34,    56,    62,    20,    40,    75,    41,
-    74,    72,     0,    56,    34,    62,    20,    40,    75,    41,
-    74,    72,     0,    34,    62,    20,    40,    75,    41,    74,
-    72,     0,    36,    40,    22,    41,    62,    20,    40,    75,
-    41,    74,    72,     0,    56,    62,    20,    40,    75,    41,
-    74,    72,     0,    20,    40,    20,    41,    72,     0,    19,
-    81,     0,    19,    37,    24,     0,     0,     6,     0,    20,
-     0,    20,    44,    76,     0,    76,     0,    77,    44,    10,
-     0,    77,     0,    77,    44,    78,     0,    78,     0,    62,
-    20,     0,    62,    20,    23,     0,    62,    20,    40,    20,
-    79,    41,     0,    62,    20,    23,    40,    20,    79,    41,
-     0,    79,    80,     0,    80,     0,    20,     0,    45,    81,
-     0,    46,    81,     0,    45,    47,    81,     0,    46,    47,
-    81,     0,    47,    47,    81,     0,    48,    47,    81,     0,
-    21,     0,    49,    21,     0,    20,     0
+    22,     0,    55,    56,     0,    56,     0,    77,     0,    61,
+     0,    62,     0,    39,     0,    30,     0,    31,     0,    32,
+     0,    20,    20,     0,    20,    37,    24,     0,    40,    85,
+     0,    40,    37,    24,     0,    58,    59,     0,    59,    58,
+     0,    59,     0,    58,     0,     0,    57,    66,    20,    60,
+    39,     0,    57,    66,    20,    23,    60,    39,     0,    33,
+    64,    63,    20,    20,    37,    24,    20,    37,    24,    39,
+     0,    33,    64,    63,    20,    20,    37,    24,    39,     0,
+    33,    64,    63,    20,    20,     0,    20,    41,    20,    66,
+    42,     0,    20,     0,    41,    65,    42,     0,     0,    20,
+    43,    65,     0,    20,     0,    67,     0,     5,    67,     0,
+    68,     0,    68,    71,     0,    12,    69,     0,    11,    69,
+     0,    69,     0,    12,    18,     0,    11,    18,     0,    18,
+     0,    17,     0,    16,     0,    20,     0,    70,    20,     0,
+    22,     0,     6,     0,    13,    15,     0,    13,     0,    14,
+    15,     0,    14,     0,    15,     0,     9,     0,     8,     0,
+     7,     0,    44,    71,     0,    44,     0,    20,    74,     0,
+    74,     0,    57,    20,    74,     0,    20,    57,    74,     0,
+    57,    74,     0,    72,     0,    20,    41,    75,    42,     0,
+    75,    45,    20,     0,    20,     0,    37,    24,     0,    39,
+     0,    35,    64,    73,    66,    20,    41,    79,    42,    78,
+    76,     0,    57,    35,    64,    72,    66,    20,    41,    79,
+    42,    78,    76,     0,    34,    57,    66,    20,    41,    79,
+    42,    78,    76,     0,    57,    34,    66,    20,    41,    79,
+    42,    78,    76,     0,    34,    66,    20,    41,    79,    42,
+    78,    76,     0,    36,    41,    22,    42,    66,    20,    41,
+    79,    42,    78,    76,     0,    57,    66,    20,    41,    79,
+    42,    78,    76,     0,    20,    41,    20,    42,    76,     0,
+    19,    85,     0,    19,    37,    24,     0,     0,     6,     0,
+    20,     0,    20,    45,    80,     0,    80,     0,    81,    45,
+    10,     0,    81,     0,    81,    45,    82,     0,    82,     0,
+    66,    20,     0,    66,    20,    23,     0,    66,    20,    41,
+    20,    83,    42,     0,    66,    20,    23,    41,    20,    83,
+    42,     0,    83,    84,     0,    84,     0,    20,     0,    46,
+    85,     0,    47,    85,     0,    46,    40,    85,     0,    47,
+    40,    85,     0,    40,    40,    85,     0,    48,    40,    85,
+     0,    21,     0,    49,    21,     0,    20,     0
 };
 
 #endif
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
 };
 
 #endif
 
 #if YYDEBUG != 0
 static const short yyrline[] = { 0,
-   222,   223,   224,   225,   228,   234,   240,   246,   252,   258,
-   266,   267,   270,   275,   282,   287,   288,   289,   290,   291,
-   292,   295,   296,   297,   300,   303,   307,   342,   372,   381,
-   387,   388,   391,   394,   400,   401,   409,   413,   420,   423,
-   426,   429,   432,   435,   438,   441,   444,   447,   451,   454,
-   459,   462,   465,   468,   471,   476,   479,   482,   487,   488,
-   492,   504,   510,   522,   534,   537,   543,   548,   551,   556,
-   557,   561,   571,   581,   591,   601,   611,   617,   622,   643,
-   644,   648,   651,   652,   663,   673,   676,   677,   680,   681,
-   684,   687,   690,   698,   708,   709,   712,   725,   729,   733,
-   737,   741,   745,   751,   752,   756
+   255,   256,   257,   258,   261,   267,   273,   279,   285,   291,
+   299,   300,   303,   308,   315,   320,   321,   324,   325,   326,
+   327,   330,   331,   332,   335,   348,   364,   368,   376,   377,
+   378,   379,   380,   386,   389,   393,   428,   456,   521,   530,
+   536,   537,   540,   543,   549,   550,   558,   562,   569,   572,
+   575,   578,   581,   584,   587,   590,   593,   596,   600,   603,
+   608,   611,   614,   617,   620,   625,   628,   631,   636,   637,
+   641,   653,   659,   671,   683,   686,   692,   697,   700,   705,
+   706,   710,   720,   730,   740,   750,   760,   766,   771,   792,
+   793,   797,   800,   801,   812,   822,   825,   826,   829,   830,
+   833,   836,   839,   847,   857,   858,   861,   874,   878,   882,
+   886,   890,   894,   900,   901,   905
 };
 #endif
 
 };
 #endif
 
@@ -362,33 +400,36 @@ static const char * const yytname[] = {   "$","error","$undefined.","CLASS",
 "FROM","CONST","VOID","STRUCT","UNION","ENUM","THREEDOTS","SIGNED","UNSIGNED",
 "LONG","SHORT","INT","FLOAT","DOUBLE","CHAR","ONERROR","TOKEN","NUMBER","TYPETOKEN",
 "ARRAY_DIM","CCODE","HTCODE","PHCODE","HCODE","ACODE","ATCODE","PUBLIC","PRIVATE",
 "FROM","CONST","VOID","STRUCT","UNION","ENUM","THREEDOTS","SIGNED","UNSIGNED",
 "LONG","SHORT","INT","FLOAT","DOUBLE","CHAR","ONERROR","TOKEN","NUMBER","TYPETOKEN",
 "ARRAY_DIM","CCODE","HTCODE","PHCODE","HCODE","ACODE","ATCODE","PUBLIC","PRIVATE",
-"PROTECTED","ARGUMENT","VIRTUAL","SIGNAL","OVERRIDE","'{'","'}'","';'","'('",
-"')'","'|'","'*'","','","'>'","'<'","'='","'!'","'-'","prog","ccode","ccodes",
-"class","classdec","classcode","scope","variable","argument","argtype","flags",
-"flaglist","type","type1","type2","integer","tspecifier","stars","simplesigtype",
-"fullsigtype","sigtype","tokenlist","codenocode","method","onerror","funcargs",
-"arglist","arglist1","arg","checklist","check","numtok", NULL
+"PROTECTED","ARGUMENT","VIRTUAL","SIGNAL","OVERRIDE","'{'","'}'","';'","'='",
+"'('","')'","'|'","'*'","','","'>'","'<'","'!'","'-'","prog","ccode","ccodes",
+"class","classdec","classcode","thing","scope","destructor","initializer","varoptions",
+"variable","argument","argtype","flags","flaglist","type","type1","type2","integer",
+"tspecifier","stars","simplesigtype","fullsigtype","sigtype","tokenlist","codenocode",
+"method","onerror","funcargs","arglist","arglist1","arg","checklist","check",
+"numtok", NULL
 };
 #endif
 
 static const short yyr1[] = {     0,
     50,    50,    50,    50,    51,    51,    51,    51,    51,    51,
 };
 #endif
 
 static const short yyr1[] = {     0,
     50,    50,    50,    50,    51,    51,    51,    51,    51,    51,
-    52,    52,    53,    53,    54,    55,    55,    55,    55,    55,
-    55,    56,    56,    56,    57,    57,    58,    58,    59,    59,
-    60,    60,    61,    61,    62,    62,    63,    63,    64,    64,
-    64,    64,    64,    64,    64,    64,    64,    64,    64,    64,
-    65,    65,    65,    65,    65,    66,    66,    66,    67,    67,
-    68,    68,    69,    69,    69,    69,    70,    71,    71,    72,
-    72,    73,    73,    73,    73,    73,    73,    73,    73,    74,
-    74,    74,    75,    75,    75,    75,    76,    76,    77,    77,
-    78,    78,    78,    78,    79,    79,    80,    80,    80,    80,
-    80,    80,    80,    81,    81,    81
+    52,    52,    53,    53,    54,    55,    55,    56,    56,    56,
+    56,    57,    57,    57,    58,    58,    59,    59,    60,    60,
+    60,    60,    60,    61,    61,    62,    62,    62,    63,    63,
+    64,    64,    65,    65,    66,    66,    67,    67,    68,    68,
+    68,    68,    68,    68,    68,    68,    68,    68,    68,    68,
+    69,    69,    69,    69,    69,    70,    70,    70,    71,    71,
+    72,    72,    73,    73,    73,    73,    74,    75,    75,    76,
+    76,    77,    77,    77,    77,    77,    77,    77,    77,    78,
+    78,    78,    79,    79,    79,    79,    80,    80,    81,    81,
+    82,    82,    82,    82,    83,    83,    84,    84,    84,    84,
+    84,    84,    84,    85,    85,    85
 };
 
 static const short yyr2[] = {     0,
      3,     2,     2,     1,     1,     1,     1,     1,     1,     1,
 };
 
 static const short yyr2[] = {     0,
      3,     2,     2,     1,     1,     1,     1,     1,     1,     1,
-     2,     1,     4,     3,     4,     2,     2,     2,     1,     1,
-     1,     1,     1,     1,     4,     5,    11,     8,     5,     1,
+     2,     1,     4,     3,     4,     2,     1,     1,     1,     1,
+     1,     1,     1,     1,     2,     3,     2,     3,     2,     2,
+     1,     1,     0,     5,     6,    11,     8,     5,     5,     1,
      3,     0,     3,     1,     1,     2,     1,     2,     2,     2,
      1,     2,     2,     1,     1,     1,     1,     2,     1,     1,
      2,     1,     2,     1,     1,     1,     1,     1,     2,     1,
      3,     0,     3,     1,     1,     2,     1,     2,     2,     2,
      1,     2,     2,     1,     1,     1,     1,     2,     1,     1,
      2,     1,     2,     1,     1,     1,     1,     1,     2,     1,
@@ -402,143 +443,149 @@ static const short yyr2[] = {     0,
 static const short yydefact[] = {     0,
      0,     5,     7,     8,     6,     9,    10,    12,     0,     4,
      0,     0,    11,     3,     2,     0,     0,     1,     0,    22,
 static const short yydefact[] = {     0,
      0,     5,     7,     8,     6,     9,    10,    12,     0,     4,
      0,     0,    11,     3,     2,     0,     0,     1,     0,    22,
-    23,    24,    32,     0,    32,     0,    14,     0,     0,    20,
-    21,    19,    15,     0,     0,     0,     0,    50,    58,    57,
-    56,     0,     0,    52,    54,    55,    46,    45,    44,    47,
-    49,     0,     0,    35,    37,    41,     0,     0,     0,    13,
-    17,    18,    16,     0,    32,     0,     0,    34,     0,    30,
-     0,    36,    43,    40,    42,    39,    51,    53,     0,     0,
-    60,    38,    48,     0,     0,    66,     0,    62,     0,     0,
-     0,     0,     0,     0,    31,     0,     0,     0,     0,    59,
-     0,     0,     0,    61,     0,    65,     0,     0,     0,     0,
-     0,     0,    25,     0,     0,    71,    79,    33,     0,     0,
-     0,    50,    47,     0,     0,    86,    88,    90,    69,     0,
-    64,    63,     0,     0,     0,     0,    26,     0,    70,     0,
-     0,     0,     0,    91,    82,     0,    67,     0,     0,     0,
-     0,     0,    82,    29,     0,    82,    85,    92,     0,     0,
-     0,    87,    89,    68,     0,     0,    82,     0,     0,     0,
-    28,     0,     0,     0,   106,   104,     0,     0,    80,    76,
-    82,     0,     0,     0,    78,     0,    74,     0,    97,     0,
-     0,     0,     0,     0,    96,    81,   105,     0,    82,    75,
-    82,     0,     0,     0,    98,     0,    99,     0,     0,    93,
-    95,    72,     0,     0,    27,    94,   100,   101,   102,   103,
-    77,    73,     0,     0,     0
+    23,    24,    42,     0,    42,     0,    14,    21,     0,    17,
+     0,    19,    20,    18,    15,     0,     0,     0,     0,    60,
+    68,    67,    66,     0,     0,    62,    64,    65,    56,    55,
+    54,    57,    59,     0,     0,    45,    47,    51,     0,     0,
+     0,    13,    16,     0,    42,     0,     0,    44,     0,    40,
+     0,    46,    53,    50,    52,    49,    61,    63,     0,     0,
+    70,    48,    58,     0,     0,    76,     0,    72,     0,     0,
+     0,    33,     0,     0,    41,     0,     0,     0,     0,    69,
+     0,     0,     0,    71,     0,    75,     0,     0,     0,     0,
+     0,     0,    33,     0,     0,    32,    31,     0,     0,    81,
+    89,    43,     0,    38,     0,    60,    57,     0,     0,    96,
+    98,   100,    79,     0,    74,    73,     0,     0,     0,     0,
+    25,     0,     0,   116,   114,     0,     0,    27,     0,    29,
+    30,    34,    80,     0,     0,     0,     0,   101,    92,     0,
+    77,     0,     0,     0,     0,     0,    26,    35,    28,   115,
+    92,    39,     0,    92,    95,   102,     0,     0,     0,    97,
+    99,    78,     0,     0,    92,     0,     0,     0,    37,     0,
+     0,     0,     0,    90,    86,    92,     0,     0,     0,    88,
+     0,    84,     0,   107,     0,     0,     0,     0,     0,   106,
+    91,     0,    92,    85,    92,     0,     0,     0,     0,   108,
+     0,   109,     0,   103,   105,    82,     0,     0,    36,   104,
+   112,   110,   111,   113,    87,    83,     0,     0,     0
 };
 
 };
 
-static const short yydefgoto[] = {   223,
-     8,     9,    10,    11,    28,    29,    30,    31,    71,    36,
-    69,   124,    54,    55,    56,    57,    82,    86,    87,    88,
-   130,   117,    32,   161,   125,   126,   127,   128,   194,   195,
-   179
+static const short yydefgoto[] = {   237,
+     8,     9,    10,    11,    29,    30,    31,   116,   117,   118,
+    32,    33,    71,    38,    69,   128,    56,    57,    58,    59,
+    82,    86,    87,    88,   134,   121,    34,   179,   129,   130,
+   131,   132,   209,   210,   148
 };
 
 };
 
-static const short yypact[] = {   136,
-     4,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   136,   119,
-    32,    10,-32768,   119,   119,   146,    67,   119,    40,-32768,
--32768,-32768,    57,   120,    57,    68,-32768,   155,    59,-32768,
--32768,-32768,-32768,    78,    95,    96,   242,-32768,-32768,-32768,
--32768,   252,   258,   115,   126,-32768,-32768,-32768,-32768,-32768,
--32768,   207,   129,-32768,   113,-32768,   137,    70,   151,-32768,
--32768,-32768,-32768,   207,    57,   138,   133,   141,   167,   152,
-   190,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   197,   186,
-   113,-32768,-32768,     2,   208,-32768,   207,-32768,   194,   224,
-   226,   -19,   131,    95,-32768,   232,   241,   223,   225,-32768,
-   228,   249,   254,-32768,    -4,-32768,   255,   207,   237,    -4,
-   207,   239,-32768,   225,   256,-32768,-32768,-32768,   207,   244,
-   225,   238,    47,   262,   243,-32768,   245,-32768,-32768,    66,
--32768,-32768,   246,   263,   225,   265,-32768,   247,-32768,   250,
-   266,   251,   207,     7,   268,   189,-32768,   273,   225,   257,
-   253,   259,   268,-32768,    -1,   268,-32768,   260,   275,   -10,
-   131,-32768,-32768,-32768,   261,   225,   268,   225,   131,   264,
--32768,   131,   276,    76,-32768,-32768,   274,   282,-32768,-32768,
-   268,   267,   131,   269,-32768,   280,-32768,    76,-32768,    62,
-    65,   270,   271,    58,-32768,-32768,-32768,   131,   268,-32768,
-   268,   272,    72,    -8,-32768,    -8,-32768,    -8,    -8,-32768,
--32768,-32768,   131,   131,-32768,-32768,-32768,-32768,-32768,-32768,
--32768,-32768,   305,   306,-32768
+static const short yypact[] = {    54,
+   -16,-32768,-32768,-32768,-32768,-32768,-32768,-32768,    54,   156,
+   -19,    38,-32768,   156,   156,   140,    29,   156,    25,-32768,
+-32768,-32768,    35,   137,    35,    47,-32768,-32768,   157,-32768,
+    89,-32768,-32768,-32768,-32768,   102,   127,   142,   245,-32768,
+-32768,-32768,-32768,   261,   267,   150,   151,-32768,-32768,-32768,
+-32768,-32768,-32768,   210,   166,-32768,   167,-32768,   174,    95,
+   191,-32768,-32768,   210,    35,   200,   187,   188,   196,   206,
+   229,-32768,-32768,-32768,-32768,-32768,-32768,-32768,   235,   225,
+   167,-32768,-32768,   -10,   248,-32768,   210,-32768,   227,   251,
+   252,    45,    92,   127,-32768,   257,   258,   242,   228,-32768,
+   243,   266,   268,-32768,   -17,-32768,   269,   210,   246,   -17,
+   210,    34,   -11,     6,   228,   250,   271,   253,   270,-32768,
+-32768,-32768,   210,   256,   228,   254,    -1,   275,   259,-32768,
+   260,-32768,-32768,   119,-32768,-32768,   262,   277,   228,   278,
+-32768,   276,   263,-32768,-32768,   280,   285,-32768,   265,-32768,
+-32768,-32768,-32768,   272,   284,   273,   210,    91,   290,   192,
+-32768,   279,   228,   281,   274,   282,-32768,-32768,-32768,-32768,
+   290,-32768,    -7,   290,-32768,   283,   291,    40,    92,-32768,
+-32768,-32768,   286,   228,   290,   228,    92,   288,-32768,    92,
+   292,    93,   289,-32768,-32768,   290,   287,    92,   293,-32768,
+   294,-32768,    93,-32768,   296,    70,    72,   297,    27,-32768,
+-32768,    92,   290,-32768,   290,   295,    88,    15,    15,-32768,
+    15,-32768,    15,-32768,-32768,-32768,    92,    92,-32768,-32768,
+-32768,-32768,-32768,-32768,-32768,-32768,   310,   317,-32768
 };
 
 static const short yypgoto[] = {-32768,
 };
 
 static const short yypgoto[] = {-32768,
-    37,   145,   298,-32768,-32768,   -23,   281,   284,-32768,   -17,
-   219,   -24,   277,-32768,    15,-32768,   234,   229,-32768,   -60,
--32768,  -154,   288,  -150,  -112,   176,-32768,   175,   134,  -141,
-   -37
+   255,   106,   311,-32768,-32768,   298,   -22,   202,   205,   213,
+-32768,-32768,-32768,    -6,   236,   -24,   299,-32768,    73,-32768,
+   264,   240,-32768,    53,-32768,  -175,-32768,  -157,  -114,   175,
+-32768,   173,   136,  -201,  -173
 };
 
 
 };
 
 
-#define        YYLAST          322
-
-
-static const short yytable[] = {    53,
-    52,   138,   169,   112,    66,   172,   180,    58,   142,   175,
-   176,   175,   176,    17,   185,   101,   183,   187,   170,   113,
-   114,   101,   151,   104,   106,    12,   177,    79,   200,   158,
-   198,    20,    21,    22,    85,   102,   165,   171,   178,    90,
-   178,   102,   131,   212,   132,    13,   159,    91,   213,   104,
-   214,    13,   211,   182,    13,   184,    74,    76,   221,   222,
-   103,   211,   107,    37,    38,    39,    40,    41,    16,    42,
-    43,    44,    45,    46,    47,    48,    49,   189,    50,    34,
-    51,   175,   176,   134,   175,   176,   136,   -84,    33,    84,
-   143,   189,    64,    65,   140,   189,    35,    67,   210,    20,
-    21,    22,   190,   191,   192,   193,   147,    59,   204,   148,
-   178,   206,   216,   178,    68,    70,   190,   191,   192,   193,
-   190,   191,   192,   193,    37,    38,    39,    40,    41,    77,
-    42,    43,    44,    45,    46,    47,    48,    49,     1,    50,
-    78,    51,     2,     3,     4,     5,     6,     7,    80,    20,
-    21,    22,   205,   207,    15,    81,    83,    92,    18,     2,
-     3,     4,     5,     6,     7,    19,   217,   115,   218,   116,
-   219,   220,    89,    93,    19,    20,    21,    22,    23,    24,
-    25,    26,    94,    27,    20,    21,    22,    23,    24,    25,
-    26,    96,    60,    37,    38,    39,    40,    41,   162,    42,
-    43,    44,    45,    46,    47,    48,    49,    95,    50,    97,
-    51,    37,    38,    39,    40,    41,    98,    42,    43,    44,
-    45,    46,    47,    48,    49,    99,    50,   105,    51,    37,
-   122,    39,    40,    41,   108,    42,    43,    44,    45,    46,
-    47,    48,    49,   109,   123,   110,    51,    38,    39,    40,
-    41,   119,    42,    43,    44,    45,    46,    47,    48,    49,
-   120,    50,   121,    51,    44,    45,    46,   102,   129,    73,
-    44,    45,    46,   101,   133,    75,   135,   137,   -83,   139,
-   141,   144,   150,   145,   152,   149,   160,   153,   146,   155,
-   154,   156,   164,   167,   174,   188,   166,   196,   168,   173,
-   186,   181,   197,   202,   224,   225,    14,   199,    61,   201,
-   215,    62,   118,    72,   100,    63,   208,   209,   157,   111,
-   163,   203
+#define        YYLAST          345
+
+
+static const short yytable[] = {    55,
+   149,    54,   101,   195,   194,    12,    66,   225,   112,   101,
+   156,   200,   188,   187,   202,   225,   190,    16,    60,    20,
+    21,    22,   214,   102,   165,   144,   145,   198,   114,    79,
+   102,   189,   220,   222,   144,   145,   226,    85,   212,    90,
+   -94,    17,   146,   157,   231,   232,   204,   233,   183,   234,
+    35,   235,   236,   141,   147,   227,     1,   228,    91,   144,
+   145,   103,   107,   147,   112,    36,   205,   113,   224,   197,
+   142,   199,   206,   207,   208,    37,   193,     2,     3,     4,
+     5,     6,     7,   138,   114,   115,   140,    61,   147,   144,
+   145,   144,   145,    39,    40,    41,    42,    43,   154,    44,
+    45,    46,    47,    48,    49,    50,    51,   204,    52,   219,
+    53,   221,   204,   176,    84,    15,    74,    76,   147,    18,
+   147,    67,    64,    65,    20,    21,    22,   205,   119,   230,
+   120,   177,   205,   206,   207,   208,   104,   106,   206,   207,
+   208,    39,    40,    41,    42,    43,    68,    44,    45,    46,
+    47,    48,    49,    50,    51,   135,    52,   136,    53,    19,
+   161,    70,   104,   162,    77,    78,    20,    21,    22,    20,
+    21,    22,    23,    24,    25,    26,    19,    27,    28,     2,
+     3,     4,     5,     6,     7,    80,    20,    21,    22,    23,
+    24,    25,    26,    83,    62,    28,    39,    40,    41,    42,
+    43,   180,    44,    45,    46,    47,    48,    49,    50,    51,
+    81,    52,    89,    53,    39,    40,    41,    42,    43,    92,
+    44,    45,    46,    47,    48,    49,    50,    51,    93,    52,
+    94,    53,    39,   126,    41,    42,    43,    95,    44,    45,
+    46,    47,    48,    49,    50,    51,    96,   127,    97,    53,
+    40,    41,    42,    43,    98,    44,    45,    46,    47,    48,
+    49,    50,    51,    13,    52,    99,    53,   105,   108,    13,
+   109,   110,    13,    46,    47,    48,   123,   124,    73,    46,
+    47,    48,   125,   102,    75,   133,   139,   101,   137,   114,
+   112,   152,   155,   153,   158,   -93,   164,   166,   182,   167,
+   159,   168,   163,   169,   160,   170,   171,   173,   178,   238,
+   192,   203,   211,   172,   174,   185,   239,   216,   151,    14,
+   150,   184,   186,   191,   201,   143,    63,   196,   213,   122,
+   111,   175,   181,   229,   215,   218,   223,    72,   217,     0,
+     0,     0,     0,     0,   100
 };
 
 static const short yycheck[] = {    24,
 };
 
 static const short yycheck[] = {    24,
-    24,   114,   153,    23,    29,   156,   161,    25,   121,    20,
-    21,    20,    21,     4,   169,    20,   167,   172,    20,    39,
-    40,    20,   135,    84,    85,    22,    37,    52,   183,    23,
-   181,    30,    31,    32,    58,    40,   149,    39,    49,    64,
-    49,    40,   103,   198,   105,     9,    40,    65,   199,   110,
-   201,    15,   194,   166,    18,   168,    42,    43,   213,   214,
-    84,   203,    87,     5,     6,     7,     8,     9,    37,    11,
+   115,    24,    20,   179,   178,    22,    31,   209,    20,    20,
+   125,   187,    20,   171,   190,   217,   174,    37,    25,    30,
+    31,    32,   198,    41,   139,    20,    21,   185,    40,    54,
+    41,    39,   206,   207,    20,    21,   212,    60,   196,    64,
+    42,     4,    37,    45,   218,   219,    20,   221,   163,   223,
+    22,   227,   228,    20,    49,   213,     3,   215,    65,    20,
+    21,    84,    87,    49,    20,    41,    40,    23,    42,   184,
+    37,   186,    46,    47,    48,    41,    37,    24,    25,    26,
+    27,    28,    29,   108,    40,    41,   111,    41,    49,    20,
+    21,    20,    21,     5,     6,     7,     8,     9,   123,    11,
     12,    13,    14,    15,    16,    17,    18,    20,    20,    40,
     12,    13,    14,    15,    16,    17,    18,    20,    20,    40,
-    22,    20,    21,   108,    20,    21,   111,    41,    22,    20,
-    44,    20,    34,    35,   119,    20,    40,    20,    41,    30,
-    31,    32,    45,    46,    47,    48,    41,    40,    47,    44,
-    49,    47,    41,    49,    20,    20,    45,    46,    47,    48,
-    45,    46,    47,    48,     5,     6,     7,     8,     9,    15,
-    11,    12,    13,    14,    15,    16,    17,    18,     3,    20,
-    15,    22,    24,    25,    26,    27,    28,    29,    20,    30,
-    31,    32,   190,   191,    10,    43,    20,    20,    14,    24,
-    25,    26,    27,    28,    29,    20,   204,    37,   206,    39,
-   208,   209,    22,    41,    20,    30,    31,    32,    33,    34,
-    35,    36,    42,    38,    30,    31,    32,    33,    34,    35,
-    36,    40,    38,     5,     6,     7,     8,     9,    10,    11,
-    12,    13,    14,    15,    16,    17,    18,    41,    20,    20,
-    22,     5,     6,     7,     8,     9,    20,    11,    12,    13,
-    14,    15,    16,    17,    18,    40,    20,    20,    22,     5,
-     6,     7,     8,     9,    41,    11,    12,    13,    14,    15,
-    16,    17,    18,    20,    20,    20,    22,     6,     7,     8,
-     9,    20,    11,    12,    13,    14,    15,    16,    17,    18,
-    20,    20,    40,    22,    13,    14,    15,    40,    20,    18,
-    13,    14,    15,    20,    20,    18,    40,    39,    41,    24,
-    37,    20,    20,    41,    20,    40,    19,    41,    44,    24,
-    41,    41,    20,    41,    20,    20,    40,    24,    40,    40,
-    37,    41,    21,    24,     0,     0,     9,    41,    28,    41,
-    39,    28,    94,    37,    81,    28,    47,    47,   143,    91,
-   146,   188
+    22,    40,    20,    23,    20,    10,    44,    45,    49,    14,
+    49,    20,    34,    35,    30,    31,    32,    40,    37,    42,
+    39,    41,    40,    46,    47,    48,    84,    85,    46,    47,
+    48,     5,     6,     7,     8,     9,    20,    11,    12,    13,
+    14,    15,    16,    17,    18,   103,    20,   105,    22,    20,
+    42,    20,   110,    45,    15,    15,    30,    31,    32,    30,
+    31,    32,    33,    34,    35,    36,    20,    38,    39,    24,
+    25,    26,    27,    28,    29,    20,    30,    31,    32,    33,
+    34,    35,    36,    20,    38,    39,     5,     6,     7,     8,
+     9,    10,    11,    12,    13,    14,    15,    16,    17,    18,
+    44,    20,    22,    22,     5,     6,     7,     8,     9,    20,
+    11,    12,    13,    14,    15,    16,    17,    18,    42,    20,
+    43,    22,     5,     6,     7,     8,     9,    42,    11,    12,
+    13,    14,    15,    16,    17,    18,    41,    20,    20,    22,
+     6,     7,     8,     9,    20,    11,    12,    13,    14,    15,
+    16,    17,    18,     9,    20,    41,    22,    20,    42,    15,
+    20,    20,    18,    13,    14,    15,    20,    20,    18,    13,
+    14,    15,    41,    41,    18,    20,    41,    20,    20,    40,
+    20,    39,    37,    24,    20,    42,    20,    20,    20,    24,
+    42,    39,    41,    24,    45,    21,    42,    24,    19,     0,
+    20,    20,    24,    42,    42,    42,     0,    24,   117,     9,
+   116,    41,    41,    41,    37,   113,    29,    42,    42,    94,
+    91,   157,   160,    39,    42,    40,    40,    39,   203,    -1,
+    -1,    -1,    -1,    -1,    81
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
 #line 3 "/usr/lib/bison.simple"
 };
 /* -*-C-*-  Note some compilers choke on comments on `#line' lines.  */
 #line 3 "/usr/lib/bison.simple"
@@ -1084,23 +1131,23 @@ yyreduce:
   switch (yyn) {
 
 case 1:
   switch (yyn) {
 
 case 1:
-#line 222 "parse.y"
+#line 255 "parse.y"
 { ; ;
     break;}
 case 2:
 { ; ;
     break;}
 case 2:
-#line 223 "parse.y"
+#line 256 "parse.y"
 { ; ;
     break;}
 case 3:
 { ; ;
     break;}
 case 3:
-#line 224 "parse.y"
+#line 257 "parse.y"
 { ; ;
     break;}
 case 4:
 { ; ;
     break;}
 case 4:
-#line 225 "parse.y"
+#line 258 "parse.y"
 { ; ;
     break;}
 case 5:
 { ; ;
     break;}
 case 5:
-#line 228 "parse.y"
+#line 261 "parse.y"
 {
                        Node *node = new_ccode(C_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(C_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1109,7 +1156,7 @@ case 5:
                                        ;
     break;}
 case 6:
                                        ;
     break;}
 case 6:
-#line 234 "parse.y"
+#line 267 "parse.y"
 {
                        Node *node = new_ccode(H_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(H_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1118,7 +1165,7 @@ case 6:
                                        ;
     break;}
 case 7:
                                        ;
     break;}
 case 7:
-#line 240 "parse.y"
+#line 273 "parse.y"
 {
                        Node *node = new_ccode(HT_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(HT_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1127,7 +1174,7 @@ case 7:
                                        ;
     break;}
 case 8:
                                        ;
     break;}
 case 8:
-#line 246 "parse.y"
+#line 279 "parse.y"
 {
                        Node *node = new_ccode(PH_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(PH_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1136,7 +1183,7 @@ case 8:
                                        ;
     break;}
 case 9:
                                        ;
     break;}
 case 9:
-#line 252 "parse.y"
+#line 285 "parse.y"
 {
                        Node *node = new_ccode(A_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(A_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1145,7 +1192,7 @@ case 9:
                                        ;
     break;}
 case 10:
                                        ;
     break;}
 case 10:
-#line 258 "parse.y"
+#line 291 "parse.y"
 {
                        Node *node = new_ccode(AT_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
 {
                        Node *node = new_ccode(AT_CCODE,(yyvsp[0].cbuf)->str,
                                               ccode_line);
@@ -1154,15 +1201,15 @@ case 10:
                                        ;
     break;}
 case 11:
                                        ;
     break;}
 case 11:
-#line 266 "parse.y"
+#line 299 "parse.y"
 { ; ;
     break;}
 case 12:
 { ; ;
     break;}
 case 12:
-#line 267 "parse.y"
+#line 300 "parse.y"
 { ; ;
     break;}
 case 13:
 { ; ;
     break;}
 case 13:
-#line 270 "parse.y"
+#line 303 "parse.y"
 {
                        ((Class *)class)->nodes = class_nodes;
                        class_nodes = NULL;
 {
                        ((Class *)class)->nodes = class_nodes;
                        class_nodes = NULL;
@@ -1170,7 +1217,7 @@ case 13:
                                                ;
     break;}
 case 14:
                                                ;
     break;}
 case 14:
-#line 275 "parse.y"
+#line 308 "parse.y"
 {
                        ((Class *)class)->nodes = NULL;
                        class_nodes = NULL;
 {
                        ((Class *)class)->nodes = NULL;
                        class_nodes = NULL;
@@ -1178,61 +1225,132 @@ case 14:
                                                ;
     break;}
 case 15:
                                                ;
     break;}
 case 15:
-#line 282 "parse.y"
+#line 315 "parse.y"
 {
                        class = new_class(yyvsp[-2].id,yyvsp[0].id,NULL);
                                                ;
     break;}
 case 16:
 {
                        class = new_class(yyvsp[-2].id,yyvsp[0].id,NULL);
                                                ;
     break;}
 case 16:
-#line 287 "parse.y"
+#line 320 "parse.y"
 { ; ;
     break;}
 case 17:
 { ; ;
     break;}
 case 17:
-#line 288 "parse.y"
+#line 321 "parse.y"
 { ; ;
     break;}
 case 18:
 { ; ;
     break;}
 case 18:
-#line 289 "parse.y"
+#line 324 "parse.y"
 { ; ;
     break;}
 case 19:
 { ; ;
     break;}
 case 19:
-#line 290 "parse.y"
+#line 325 "parse.y"
 { ; ;
     break;}
 case 20:
 { ; ;
     break;}
 case 20:
-#line 291 "parse.y"
+#line 326 "parse.y"
 { ; ;
     break;}
 case 21:
 { ; ;
     break;}
 case 21:
-#line 292 "parse.y"
+#line 327 "parse.y"
 { ; ;
     break;}
 case 22:
 { ; ;
     break;}
 case 22:
-#line 295 "parse.y"
+#line 330 "parse.y"
 { the_scope = PUBLIC_SCOPE; ;
     break;}
 case 23:
 { the_scope = PUBLIC_SCOPE; ;
     break;}
 case 23:
-#line 296 "parse.y"
+#line 331 "parse.y"
 { the_scope = PRIVATE_SCOPE; ;
     break;}
 case 24:
 { the_scope = PRIVATE_SCOPE; ;
     break;}
 case 24:
-#line 297 "parse.y"
+#line 332 "parse.y"
 { the_scope = PROTECTED_SCOPE; ;
     break;}
 case 25:
 { the_scope = PROTECTED_SCOPE; ;
     break;}
 case 25:
-#line 300 "parse.y"
+#line 335 "parse.y"
 {
 {
-                       push_variable(yyvsp[-1].id,the_scope,yyvsp[-3].line,NULL);
-                                               ;
+                       if(strcmp(yyvsp[-1].id, "destroywith")==0) {
+                               g_free(yyvsp[-1].id);
+                               destructor = yyvsp[0].id;
+                               destructor_line = ccode_line;
+                               destructor_simple = TRUE;
+                       } else {
+                               g_free(yyvsp[-1].id);
+                               g_free(yyvsp[0].id);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                               ;
     break;}
 case 26:
     break;}
 case 26:
-#line 303 "parse.y"
+#line 348 "parse.y"
 {
 {
-                       push_variable(yyvsp[-2].id,the_scope,yyvsp[-4].line,yyvsp[-1].id);
-                                               ;
+                       if(strcmp(yyvsp[-2].id, "destroy")==0) {
+                               g_free(yyvsp[-2].id);
+                               destructor = (yyvsp[0].cbuf)->str;
+                               g_string_free(yyvsp[0].cbuf, FALSE);
+                               destructor_line = ccode_line;
+                               destructor_simple = FALSE;
+                       } else {
+                               g_free(yyvsp[-2].id);
+                               g_string_free(yyvsp[0].cbuf, TRUE);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                                       ;
     break;}
 case 27:
     break;}
 case 27:
-#line 307 "parse.y"
+#line 364 "parse.y"
+{
+                       initializer = yyvsp[0].id;
+                       initializer_line = ccode_line;
+                               ;
+    break;}
+case 28:
+#line 368 "parse.y"
+{
+                       initializer = (yyvsp[0].cbuf)->str;
+                       initializer_line = ccode_line;
+                       g_string_free(yyvsp[0].cbuf, FALSE);
+                               ;
+    break;}
+case 29:
+#line 376 "parse.y"
+{ ; ;
+    break;}
+case 30:
+#line 377 "parse.y"
+{ ; ;
+    break;}
+case 31:
+#line 378 "parse.y"
+{ destructor = NULL; ;
+    break;}
+case 32:
+#line 379 "parse.y"
+{ initializer = NULL; ;
+    break;}
+case 33:
+#line 380 "parse.y"
+{
+                       destructor = NULL;
+                       initializer = NULL;
+                                       ;
+    break;}
+case 34:
+#line 386 "parse.y"
+{
+                       push_variable(yyvsp[-2].id, the_scope,yyvsp[-4].line, NULL);
+                                               ;
+    break;}
+case 35:
+#line 389 "parse.y"
+{
+                       push_variable(yyvsp[-3].id, the_scope, yyvsp[-5].line, yyvsp[-2].id);
+                                               ;
+    break;}
+case 36:
+#line 393 "parse.y"
 {
                        if(strcmp(yyvsp[-6].id,"get")==0 &&
                           strcmp(yyvsp[-3].id,"set")==0) {
 {
                        if(strcmp(yyvsp[-6].id,"get")==0 &&
                           strcmp(yyvsp[-3].id,"set")==0) {
@@ -1269,8 +1387,8 @@ case 27:
                        }
                                                ;
     break;}
                        }
                                                ;
     break;}
-case 28:
-#line 342 "parse.y"
+case 37:
+#line 428 "parse.y"
 {
                        if(strcmp(yyvsp[-3].id,"get")==0) {
                                Node *node;
 {
                        if(strcmp(yyvsp[-3].id,"get")==0) {
                                Node *node;
@@ -1300,8 +1418,74 @@ case 28:
                        }
                                                ;
     break;}
                        }
                                                ;
     break;}
-case 29:
-#line 372 "parse.y"
+case 38:
+#line 456 "parse.y"
+{
+                       Node *node;
+                       char *get, *set;
+                       Variable *var;
+                       Type *type;
+                       char *root;
+                       
+                       if(strcmp(yyvsp[0].id,"link")!=0 &&
+                          strcmp(yyvsp[0].id,"stringlink")!=0 &&
+                          strcmp(yyvsp[0].id,"objectlink")!=0) {
+                               g_free(yyvsp[0].id); g_free(yyvsp[-2].id);
+                               g_free(yyvsp[-1].id);
+                               g_list_foreach(yyvsp[-3].list,(GFunc)g_free,NULL);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+
+                       type = pop_type();
+
+                       var = find_var_or_die(yyvsp[-1].id, yyvsp[-4].line);
+                       if(var->scope == PRIVATE_SCOPE)
+                               root = "self->_priv";
+                       else
+                               root = "self";
+
+                       if(strcmp(yyvsp[0].id,"link")==0) {
+                               set = g_strdup_printf("%s->%s = ARG;",
+                                                     root, yyvsp[-1].id);
+                       } else if(strcmp(yyvsp[0].id,"stringlink")==0) {
+                               set = g_strdup_printf("g_free(%s->%s); "
+                                                     "%s->%s = g_strdup(ARG);",
+                                                     root, yyvsp[-1].id,
+                                                     root, yyvsp[-1].id);
+                       } else if(strcmp(yyvsp[0].id,"objectlink")==0) {
+                               set = g_strdup_printf(
+                                 "if(%s->%s) "
+                                  "gtk_object_unref(GTK_OBJECT(%s->%s)); "
+                                 "%s->%s = ARG; "
+                                 "if(%s->%s) "
+                                  "gtk_object_ref(GTK_OBJECT(%s->%s)); ",
+                                 root, yyvsp[-1].id,
+                                 root, yyvsp[-1].id,
+                                 root, yyvsp[-1].id,
+                                 root, yyvsp[-1].id,
+                                 root, yyvsp[-1].id);
+                       } else {
+                               g_assert_not_reached();
+                       }
+
+                       /* get is the same for everything */
+                       get = g_strdup_printf("ARG = %s->%s;", root, yyvsp[-1].id);
+
+                       g_free(yyvsp[0].id);
+
+
+                       if(!type)
+                               type = copy_type(var->vtype);
+
+                       node = new_argument(yyvsp[-2].id, type, yyvsp[-3].list,
+                                           yyvsp[-1].id, get, yyvsp[-4].line,
+                                           set, yyvsp[-4].line, yyvsp[-4].line);
+                       class_nodes = g_list_append(class_nodes,node);
+                                               ;
+    break;}
+case 39:
+#line 521 "parse.y"
 {
                        if(strcmp(yyvsp[-2].id,"type")!=0) {
                                g_free(yyvsp[-4].id);
 {
                        if(strcmp(yyvsp[-2].id,"type")!=0) {
                                g_free(yyvsp[-4].id);
@@ -1312,39 +1496,39 @@ case 29:
                        yyval.id = yyvsp[-4].id;
                                                ;
     break;}
                        yyval.id = yyvsp[-4].id;
                                                ;
     break;}
-case 30:
-#line 381 "parse.y"
+case 40:
+#line 530 "parse.y"
 {
                        yyval.id = yyvsp[0].id;
                        typestack = g_list_prepend(typestack,NULL);
                                                ;
     break;}
 {
                        yyval.id = yyvsp[0].id;
                        typestack = g_list_prepend(typestack,NULL);
                                                ;
     break;}
-case 31:
-#line 387 "parse.y"
+case 41:
+#line 536 "parse.y"
 { yyval.list = yyvsp[-1].list; ;
     break;}
 { yyval.list = yyvsp[-1].list; ;
     break;}
-case 32:
-#line 388 "parse.y"
+case 42:
+#line 537 "parse.y"
 { yyval.list = NULL; ;
     break;}
 { yyval.list = NULL; ;
     break;}
-case 33:
-#line 391 "parse.y"
+case 43:
+#line 540 "parse.y"
 {
                        yyval.list = g_list_append(yyvsp[0].list,yyvsp[-2].id);
                                                ;
     break;}
 {
                        yyval.list = g_list_append(yyvsp[0].list,yyvsp[-2].id);
                                                ;
     break;}
-case 34:
-#line 394 "parse.y"
+case 44:
+#line 543 "parse.y"
 {
                        yyval.list = g_list_append(NULL,yyvsp[0].id);
                                                ;
     break;}
 {
                        yyval.list = g_list_append(NULL,yyvsp[0].id);
                                                ;
     break;}
-case 35:
-#line 400 "parse.y"
+case 45:
+#line 549 "parse.y"
 { ; ;
     break;}
 { ; ;
     break;}
-case 36:
-#line 401 "parse.y"
+case 46:
+#line 550 "parse.y"
 {
                        Type *type = typestack->data;
                        char *oldname = type->name;
 {
                        Type *type = typestack->data;
                        char *oldname = type->name;
@@ -1352,152 +1536,152 @@ case 36:
                        g_free(oldname);
                                                ;
     break;}
                        g_free(oldname);
                                                ;
     break;}
-case 37:
-#line 409 "parse.y"
+case 47:
+#line 558 "parse.y"
 {
                        Node *node = new_type(0,yyvsp[0].id,NULL);
                        typestack = g_list_prepend(typestack,node);
                                                ;
     break;}
 {
                        Node *node = new_type(0,yyvsp[0].id,NULL);
                        typestack = g_list_prepend(typestack,node);
                                                ;
     break;}
-case 38:
-#line 413 "parse.y"
+case 48:
+#line 562 "parse.y"
 {
                        Node *node = new_type(stars,yyvsp[-1].id,NULL);
                        stars = 0;
                        typestack = g_list_prepend(typestack,node);
                                                ;
     break;}
 {
                        Node *node = new_type(stars,yyvsp[-1].id,NULL);
                        stars = 0;
                        typestack = g_list_prepend(typestack,node);
                                                ;
     break;}
-case 39:
-#line 420 "parse.y"
+case 49:
+#line 569 "parse.y"
 {
                        yyval.id = g_strconcat("unsigned ",yyvsp[0].id,NULL);
                                                ;
     break;}
 {
                        yyval.id = g_strconcat("unsigned ",yyvsp[0].id,NULL);
                                                ;
     break;}
-case 40:
-#line 423 "parse.y"
+case 50:
+#line 572 "parse.y"
 {
                        yyval.id = g_strconcat("signed ",yyvsp[0].id,NULL);
                                                ;
     break;}
 {
                        yyval.id = g_strconcat("signed ",yyvsp[0].id,NULL);
                                                ;
     break;}
-case 41:
-#line 426 "parse.y"
+case 51:
+#line 575 "parse.y"
 {
                        yyval.id = g_strdup(yyvsp[0].id);
                                                ;
     break;}
 {
                        yyval.id = g_strdup(yyvsp[0].id);
                                                ;
     break;}
-case 42:
-#line 429 "parse.y"
+case 52:
+#line 578 "parse.y"
 {
                        yyval.id = g_strdup("unsigned char");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("unsigned char");
                                                ;
     break;}
-case 43:
-#line 432 "parse.y"
+case 53:
+#line 581 "parse.y"
 {
                        yyval.id = g_strdup("signed char");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("signed char");
                                                ;
     break;}
-case 44:
-#line 435 "parse.y"
+case 54:
+#line 584 "parse.y"
 {
                        yyval.id = g_strdup("char");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("char");
                                                ;
     break;}
-case 45:
-#line 438 "parse.y"
+case 55:
+#line 587 "parse.y"
 {
                        yyval.id = g_strdup("double");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("double");
                                                ;
     break;}
-case 46:
-#line 441 "parse.y"
+case 56:
+#line 590 "parse.y"
 {
                        yyval.id = g_strdup("float");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("float");
                                                ;
     break;}
-case 47:
-#line 444 "parse.y"
+case 57:
+#line 593 "parse.y"
 {
                        yyval.id = yyvsp[0].id;
                                                ;
     break;}
 {
                        yyval.id = yyvsp[0].id;
                                                ;
     break;}
-case 48:
-#line 447 "parse.y"
+case 58:
+#line 596 "parse.y"
 {
                        yyval.id = g_strconcat(yyvsp[-1].id,yyvsp[0].id,NULL);
                        g_free(yyvsp[0].id);
                                                ;
     break;}
 {
                        yyval.id = g_strconcat(yyvsp[-1].id,yyvsp[0].id,NULL);
                        g_free(yyvsp[0].id);
                                                ;
     break;}
-case 49:
-#line 451 "parse.y"
+case 59:
+#line 600 "parse.y"
 {
                        yyval.id = yyvsp[0].id;
                                                ;
     break;}
 {
                        yyval.id = yyvsp[0].id;
                                                ;
     break;}
-case 50:
-#line 454 "parse.y"
+case 60:
+#line 603 "parse.y"
 {
                        yyval.id = g_strdup("void");
                                                ;
     break;}
 {
                        yyval.id = g_strdup("void");
                                                ;
     break;}
-case 51:
-#line 459 "parse.y"
+case 61:
+#line 608 "parse.y"
 {
                        yyval.id = "long int";
                                                ;
     break;}
 {
                        yyval.id = "long int";
                                                ;
     break;}
-case 52:
-#line 462 "parse.y"
+case 62:
+#line 611 "parse.y"
 {
                        yyval.id = "long";
                                                ;
     break;}
 {
                        yyval.id = "long";
                                                ;
     break;}
-case 53:
-#line 465 "parse.y"
+case 63:
+#line 614 "parse.y"
 {
                        yyval.id = "short int";
                                                ;
     break;}
 {
                        yyval.id = "short int";
                                                ;
     break;}
-case 54:
-#line 468 "parse.y"
+case 64:
+#line 617 "parse.y"
 {
                        yyval.id = "short";
                                                ;
     break;}
 {
                        yyval.id = "short";
                                                ;
     break;}
-case 55:
-#line 471 "parse.y"
+case 65:
+#line 620 "parse.y"
 {
                        yyval.id = "int";
                                                ;
     break;}
 {
                        yyval.id = "int";
                                                ;
     break;}
-case 56:
-#line 476 "parse.y"
+case 66:
+#line 625 "parse.y"
 {
                        yyval.id = "enum ";
                                                ;
     break;}
 {
                        yyval.id = "enum ";
                                                ;
     break;}
-case 57:
-#line 479 "parse.y"
+case 67:
+#line 628 "parse.y"
 {
                        yyval.id = "union ";
                                                ;
     break;}
 {
                        yyval.id = "union ";
                                                ;
     break;}
-case 58:
-#line 482 "parse.y"
+case 68:
+#line 631 "parse.y"
 {
                        yyval.id = "struct ";
                                                ;
     break;}
 {
                        yyval.id = "struct ";
                                                ;
     break;}
-case 59:
-#line 487 "parse.y"
+case 69:
+#line 636 "parse.y"
 { stars++; ;
     break;}
 { stars++; ;
     break;}
-case 60:
-#line 488 "parse.y"
+case 70:
+#line 637 "parse.y"
 { stars++; ;
     break;}
 { stars++; ;
     break;}
-case 61:
-#line 492 "parse.y"
+case 71:
+#line 641 "parse.y"
 {
                        if(strcmp(yyvsp[-1].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
 {
                        if(strcmp(yyvsp[-1].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
@@ -1511,14 +1695,14 @@ case 61:
                        g_free(yyvsp[-1].id);
                                        ;
     break;}
                        g_free(yyvsp[-1].id);
                                        ;
     break;}
-case 62:
-#line 504 "parse.y"
+case 72:
+#line 653 "parse.y"
 {
                        yyval.sigtype = SIGNAL_LAST_METHOD;
                                        ;
     break;}
 {
                        yyval.sigtype = SIGNAL_LAST_METHOD;
                                        ;
     break;}
-case 63:
-#line 510 "parse.y"
+case 73:
+#line 659 "parse.y"
 {
                        if(strcmp(yyvsp[-1].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
 {
                        if(strcmp(yyvsp[-1].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
@@ -1532,8 +1716,8 @@ case 63:
                        g_free(yyvsp[-1].id);
                                        ;
     break;}
                        g_free(yyvsp[-1].id);
                                        ;
     break;}
-case 64:
-#line 522 "parse.y"
+case 74:
+#line 671 "parse.y"
 {
                        if(strcmp(yyvsp[-2].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
 {
                        if(strcmp(yyvsp[-2].id,"first")==0)
                                yyval.sigtype = SIGNAL_FIRST_METHOD;
@@ -1547,47 +1731,47 @@ case 64:
                        g_free(yyvsp[-2].id);
                                        ;
     break;}
                        g_free(yyvsp[-2].id);
                                        ;
     break;}
-case 65:
-#line 534 "parse.y"
+case 75:
+#line 683 "parse.y"
 {
                        yyval.sigtype = SIGNAL_LAST_METHOD;
                                        ;
     break;}
 {
                        yyval.sigtype = SIGNAL_LAST_METHOD;
                                        ;
     break;}
-case 66:
-#line 537 "parse.y"
+case 76:
+#line 686 "parse.y"
 {
                        /* the_scope was default thus public */
                        the_scope = PUBLIC_SCOPE;
                                        ;
     break;}
 {
                        /* the_scope was default thus public */
                        the_scope = PUBLIC_SCOPE;
                                        ;
     break;}
-case 67:
-#line 543 "parse.y"
+case 77:
+#line 692 "parse.y"
 {
                        gtktypes = g_list_prepend(gtktypes,yyvsp[-3].id);
                                                ;
     break;}
 {
                        gtktypes = g_list_prepend(gtktypes,yyvsp[-3].id);
                                                ;
     break;}
-case 68:
-#line 548 "parse.y"
+case 78:
+#line 697 "parse.y"
 {
                        gtktypes = g_list_append(gtktypes,yyvsp[0].id);
                                                ;
     break;}
 {
                        gtktypes = g_list_append(gtktypes,yyvsp[0].id);
                                                ;
     break;}
-case 69:
-#line 551 "parse.y"
+case 79:
+#line 700 "parse.y"
 { 
                        gtktypes = g_list_append(gtktypes,yyvsp[0].id);
                                                        ;
     break;}
 { 
                        gtktypes = g_list_append(gtktypes,yyvsp[0].id);
                                                        ;
     break;}
-case 70:
-#line 556 "parse.y"
+case 80:
+#line 705 "parse.y"
 { yyval.cbuf = yyvsp[0].cbuf; ;
     break;}
 { yyval.cbuf = yyvsp[0].cbuf; ;
     break;}
-case 71:
-#line 557 "parse.y"
+case 81:
+#line 706 "parse.y"
 { yyval.cbuf = NULL; ;
     break;}
 { yyval.cbuf = NULL; ;
     break;}
-case 72:
-#line 561 "parse.y"
+case 82:
+#line 710 "parse.y"
 {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
 {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
@@ -1599,8 +1783,8 @@ case 72:
                                      ccode_line, vararg, yyvsp[-8].list);
                                                                        ;
     break;}
                                      ccode_line, vararg, yyvsp[-8].list);
                                                                        ;
     break;}
-case 73:
-#line 571 "parse.y"
+case 83:
+#line 720 "parse.y"
 {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
 {
                        if(!has_self) {
                                yyerror(_("signal without 'self' as "
@@ -1612,8 +1796,8 @@ case 73:
                                      ccode_line, vararg, yyvsp[-8].list);
                                                                        ;
     break;}
                                      ccode_line, vararg, yyvsp[-8].list);
                                                                        ;
     break;}
-case 74:
-#line 581 "parse.y"
+case 84:
+#line 730 "parse.y"
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
@@ -1625,8 +1809,8 @@ case 74:
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
-case 75:
-#line 591 "parse.y"
+case 85:
+#line 740 "parse.y"
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
@@ -1638,8 +1822,8 @@ case 75:
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
-case 76:
-#line 601 "parse.y"
+case 86:
+#line 750 "parse.y"
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
 {
                        if(!has_self) {
                                yyerror(_("virtual method without 'self' as "
@@ -1651,8 +1835,8 @@ case 76:
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
                                      ccode_line, vararg, NULL);
                                                                        ;
     break;}
-case 77:
-#line 611 "parse.y"
+case 87:
+#line 760 "parse.y"
 {
                        push_function(NO_SCOPE, OVERRIDE_METHOD, yyvsp[-8].id,
                                      yyvsp[-5].id, yyvsp[-1].id, yyvsp[0].cbuf,
 {
                        push_function(NO_SCOPE, OVERRIDE_METHOD, yyvsp[-8].id,
                                      yyvsp[-5].id, yyvsp[-1].id, yyvsp[0].cbuf,
@@ -1660,16 +1844,16 @@ case 77:
                                      vararg, NULL);
                                                                        ;
     break;}
                                      vararg, NULL);
                                                                        ;
     break;}
-case 78:
-#line 617 "parse.y"
+case 88:
+#line 766 "parse.y"
 {
                        push_function(the_scope, REGULAR_METHOD, NULL, yyvsp[-5].id,
                                      yyvsp[-1].id, yyvsp[0].cbuf, yyvsp[-7].line, ccode_line,
                                      vararg, NULL);
                                                                ;
     break;}
 {
                        push_function(the_scope, REGULAR_METHOD, NULL, yyvsp[-5].id,
                                      yyvsp[-1].id, yyvsp[0].cbuf, yyvsp[-7].line, ccode_line,
                                      vararg, NULL);
                                                                ;
     break;}
-case 79:
-#line 622 "parse.y"
+case 89:
+#line 771 "parse.y"
 {
                        if(strcmp(yyvsp[-4].id,"init")==0) {
                                push_init_arg(yyvsp[-2].id,FALSE);
 {
                        if(strcmp(yyvsp[-4].id,"init")==0) {
                                push_init_arg(yyvsp[-2].id,FALSE);
@@ -1690,27 +1874,27 @@ case 79:
                        }
                                                ;
     break;}
                        }
                                                ;
     break;}
-case 80:
-#line 643 "parse.y"
+case 90:
+#line 792 "parse.y"
 { yyval.id = yyvsp[0].id; ;
     break;}
 { yyval.id = yyvsp[0].id; ;
     break;}
-case 81:
-#line 644 "parse.y"
+case 91:
+#line 793 "parse.y"
 {
                        yyval.id = (yyvsp[0].cbuf)->str;
                        g_string_free(yyvsp[0].cbuf,FALSE);
                                        ;
     break;}
 {
                        yyval.id = (yyvsp[0].cbuf)->str;
                        g_string_free(yyvsp[0].cbuf,FALSE);
                                        ;
     break;}
-case 82:
-#line 648 "parse.y"
+case 92:
+#line 797 "parse.y"
 { yyval.id = NULL; ;
     break;}
 { yyval.id = NULL; ;
     break;}
-case 83:
-#line 651 "parse.y"
+case 93:
+#line 800 "parse.y"
 { vararg = FALSE; has_self = FALSE; ;
     break;}
 { vararg = FALSE; has_self = FALSE; ;
     break;}
-case 84:
-#line 652 "parse.y"
+case 94:
+#line 801 "parse.y"
 {
                        vararg = FALSE;
                        has_self = TRUE;
 {
                        vararg = FALSE;
                        has_self = TRUE;
@@ -1723,8 +1907,8 @@ case 84:
                        }
                                                ;
     break;}
                        }
                                                ;
     break;}
-case 85:
-#line 663 "parse.y"
+case 95:
+#line 812 "parse.y"
 {
                        has_self = TRUE;
                        if(strcmp(yyvsp[-2].id,"self")==0)
 {
                        has_self = TRUE;
                        if(strcmp(yyvsp[-2].id,"self")==0)
@@ -1736,40 +1920,40 @@ case 85:
                        }
                                        ;
     break;}
                        }
                                        ;
     break;}
-case 86:
-#line 673 "parse.y"
+case 96:
+#line 822 "parse.y"
 { has_self = FALSE; ;
     break;}
 { has_self = FALSE; ;
     break;}
-case 87:
-#line 676 "parse.y"
+case 97:
+#line 825 "parse.y"
 { vararg = TRUE; ;
     break;}
 { vararg = TRUE; ;
     break;}
-case 88:
-#line 677 "parse.y"
+case 98:
+#line 826 "parse.y"
 { vararg = FALSE; ;
     break;}
 { vararg = FALSE; ;
     break;}
-case 89:
-#line 680 "parse.y"
+case 99:
+#line 829 "parse.y"
 { ; ;
     break;}
 { ; ;
     break;}
-case 90:
-#line 681 "parse.y"
+case 100:
+#line 830 "parse.y"
 { ; ;
     break;}
 { ; ;
     break;}
-case 91:
-#line 684 "parse.y"
+case 101:
+#line 833 "parse.y"
 {
                        push_funcarg(yyvsp[0].id,NULL);
                                                                ;
     break;}
 {
                        push_funcarg(yyvsp[0].id,NULL);
                                                                ;
     break;}
-case 92:
-#line 687 "parse.y"
+case 102:
+#line 836 "parse.y"
 {
                        push_funcarg(yyvsp[-1].id,yyvsp[0].id);
                                                                ;
     break;}
 {
                        push_funcarg(yyvsp[-1].id,yyvsp[0].id);
                                                                ;
     break;}
-case 93:
-#line 690 "parse.y"
+case 103:
+#line 839 "parse.y"
 {
                        if(strcmp(yyvsp[-2].id,"check")!=0) {
                                yyerror(_("parse error"));
 {
                        if(strcmp(yyvsp[-2].id,"check")!=0) {
                                yyerror(_("parse error"));
@@ -1779,8 +1963,8 @@ case 93:
                        push_funcarg(yyvsp[-4].id,NULL);
                                                                ;
     break;}
                        push_funcarg(yyvsp[-4].id,NULL);
                                                                ;
     break;}
-case 94:
-#line 698 "parse.y"
+case 104:
+#line 847 "parse.y"
 {
                        if(strcmp(yyvsp[-2].id,"check")!=0) {
                                yyerror(_("parse error"));
 {
                        if(strcmp(yyvsp[-2].id,"check")!=0) {
                                yyerror(_("parse error"));
@@ -1790,16 +1974,16 @@ case 94:
                        push_funcarg(yyvsp[-5].id,yyvsp[-4].id);
                                                                ;
     break;}
                        push_funcarg(yyvsp[-5].id,yyvsp[-4].id);
                                                                ;
     break;}
-case 95:
-#line 708 "parse.y"
+case 105:
+#line 857 "parse.y"
 { ; ;
     break;}
 { ; ;
     break;}
-case 96:
-#line 709 "parse.y"
+case 106:
+#line 858 "parse.y"
 { ; ;
     break;}
 { ; ;
     break;}
-case 97:
-#line 712 "parse.y"
+case 107:
+#line 861 "parse.y"
 {
                        if(strcmp(yyvsp[0].id,"type")==0) {
                                Node *node = new_check(TYPE_CHECK,NULL);
 {
                        if(strcmp(yyvsp[0].id,"type")==0) {
                                Node *node = new_check(TYPE_CHECK,NULL);
@@ -1814,61 +1998,61 @@ case 97:
                        g_free(yyvsp[0].id);
                                        ;
     break;}
                        g_free(yyvsp[0].id);
                                        ;
     break;}
-case 98:
-#line 725 "parse.y"
+case 108:
+#line 874 "parse.y"
 {
                        Node *node = new_check(GT_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(GT_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 99:
-#line 729 "parse.y"
+case 109:
+#line 878 "parse.y"
 {
                        Node *node = new_check(LT_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(LT_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 100:
-#line 733 "parse.y"
+case 110:
+#line 882 "parse.y"
 {
                        Node *node = new_check(GE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(GE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 101:
-#line 737 "parse.y"
+case 111:
+#line 886 "parse.y"
 {
                        Node *node = new_check(LE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(LE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 102:
-#line 741 "parse.y"
+case 112:
+#line 890 "parse.y"
 {
                        Node *node = new_check(EQ_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(EQ_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 103:
-#line 745 "parse.y"
+case 113:
+#line 894 "parse.y"
 {
                        Node *node = new_check(NE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
 {
                        Node *node = new_check(NE_CHECK,yyvsp[0].id);
                        checks = g_list_append(checks,node);
                                        ;
     break;}
-case 104:
-#line 751 "parse.y"
+case 114:
+#line 900 "parse.y"
 { yyval.id = yyvsp[0].id; ;
     break;}
 { yyval.id = yyvsp[0].id; ;
     break;}
-case 105:
-#line 752 "parse.y"
+case 115:
+#line 901 "parse.y"
 {
                        yyval.id = g_strconcat("-",yyvsp[0].id,NULL);
                        g_free(yyvsp[0].id);
                                        ;
     break;}
 {
                        yyval.id = g_strconcat("-",yyvsp[0].id,NULL);
                        g_free(yyvsp[0].id);
                                        ;
     break;}
-case 106:
-#line 756 "parse.y"
+case 116:
+#line 905 "parse.y"
 { yyval.id = yyvsp[0].id; ;
     break;}
 }
 { yyval.id = yyvsp[0].id; ;
     break;}
 }
@@ -2093,5 +2277,5 @@ yyerrhandle:
     }
   return 1;
 }
     }
   return 1;
 }
-#line 759 "parse.y"
+#line 908 "parse.y"
 
 
index 63f0a7a1d21e743c9051b6c571785fe2ed23c3a0..d0b56fe85679f1783dec67f2858fddcf61af6841 100644 (file)
@@ -43,6 +43,13 @@ static GList *checks = NULL;
 static int has_self = FALSE;
 static int vararg = FALSE;
 
 static int has_self = FALSE;
 static int vararg = FALSE;
 
+/* destructor and initializer for variables */
+static char *destructor = NULL;
+static int destructor_line = 0;
+static gboolean destructor_simple = TRUE;
+static char *initializer = NULL;
+static int initializer_line = 0;
+
 static GList *gtktypes = NULL;
 
 /* this can be a global as we will only do one function at a time
 static GList *gtktypes = NULL;
 
 /* this can be a global as we will only do one function at a time
@@ -98,7 +105,10 @@ push_variable(char *name, int scope, int line_no, char *postfix)
 
        type->postfix = postfix;
        
 
        type->postfix = postfix;
        
-       var = new_variable(scope,type,name,line_no);
+       var = new_variable(scope, type, name, line_no,
+                          destructor, destructor_line,
+                          destructor_simple,
+                          initializer, initializer_line);
        class_nodes = g_list_append(class_nodes, var);
 }
 
        class_nodes = g_list_append(class_nodes, var);
 }
 
@@ -198,6 +208,29 @@ push_self(char *id)
        funcargs = g_list_prepend(funcargs, node);
 }
 
        funcargs = g_list_prepend(funcargs, node);
 }
 
+static Variable *
+find_var_or_die(const char *id, int line)
+{
+       GList *li;
+       char *s;
+
+       for(li = class_nodes; li != NULL; li = li->next) {
+               Variable *var;
+               Node *node = li->data;
+               if(node->type != VARIABLE_NODE)
+                       continue;
+               var = li->data;
+               if(strcmp(var->id, id)==0)
+                       return var;
+       }
+
+       s = g_strdup_printf(_("Variable %s not defined here"), id);
+       print_error(FALSE, s, line);
+
+       g_assert_not_reached();
+       return NULL;
+}
+
 %}
 
 %union {
 %}
 
 %union {
@@ -284,12 +317,14 @@ classdec: CLASS TYPETOKEN FROM TYPETOKEN  {
                                                }
        ;
        
                                                }
        ;
        
-classcode:     classcode method                { ; }
-       |       classcode variable              { ; }
-       |       classcode argument              { ; }
-       |       method                          { ; }
+classcode:     classcode thing                 { ; }
+       |       thing                           { ; }
+       ;
+
+thing:                 method                          { ; }
        |       variable                        { ; }
        |       argument                        { ; }
        |       variable                        { ; }
        |       argument                        { ; }
+       |       ';'                             { ; }
        ;
 
 scope:         PUBLIC                  { the_scope = PUBLIC_SCOPE; }
        ;
 
 scope:         PUBLIC                  { the_scope = PUBLIC_SCOPE; }
@@ -297,11 +332,62 @@ scope:            PUBLIC                  { the_scope = PUBLIC_SCOPE; }
        |       PROTECTED               { the_scope = PROTECTED_SCOPE; }
        ;
 
        |       PROTECTED               { the_scope = PROTECTED_SCOPE; }
        ;
 
-variable:      scope type TOKEN ';'            {
-                       push_variable($<id>3,the_scope,$<line>1,NULL);
+destructor:    TOKEN TOKEN     {
+                       if(strcmp($<id>1, "destroywith")==0) {
+                               g_free($<id>1);
+                               destructor = $<id>2;
+                               destructor_line = ccode_line;
+                               destructor_simple = TRUE;
+                       } else {
+                               g_free($<id>1);
+                               g_free($<id>2);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                               }
+       |       TOKEN '{' CCODE         {
+                       if(strcmp($<id>1, "destroy")==0) {
+                               g_free($<id>1);
+                               destructor = ($<cbuf>3)->str;
+                               g_string_free($<cbuf>3, FALSE);
+                               destructor_line = ccode_line;
+                               destructor_simple = FALSE;
+                       } else {
+                               g_free($<id>1);
+                               g_string_free($<cbuf>3, TRUE);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+                                       }
+       ;
+
+initializer:   '=' numtok      {
+                       initializer = $<id>2;
+                       initializer_line = ccode_line;
+                               }
+       |       '=' '{' CCODE   {
+                       initializer = ($<cbuf>3)->str;
+                       initializer_line = ccode_line;
+                       g_string_free($<cbuf>3, FALSE);
+                               }
+       ;
+
+
+varoptions:    destructor initializer  { ; }
+       |       initializer destructor  { ; }
+       |       initializer             { destructor = NULL; }
+       |       destructor              { initializer = NULL; }
+       |                               {
+                       destructor = NULL;
+                       initializer = NULL;
+                                       }
+       ;
+
+variable:      scope type TOKEN varoptions ';'         {
+                       push_variable($<id>3, the_scope,$<line>1, NULL);
                                                }
                                                }
-       |       scope type TOKEN ARRAY_DIM ';'  {
-                       push_variable($<id>3,the_scope,$<line>1,$<id>4);
+       |       scope type TOKEN ARRAY_DIM varoptions ';'       {
+                       push_variable($<id>3, the_scope, $<line>1, $<id>4);
                                                }
        ;
 argument:      ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' {
                                                }
        ;
 argument:      ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' {
@@ -367,6 +453,69 @@ argument:  ARGUMENT flags argtype TOKEN TOKEN '{' CCODE TOKEN '{' CCODE ';' {
                                YYERROR;
                        }
                                                }
                                YYERROR;
                        }
                                                }
+       |       ARGUMENT flags argtype TOKEN TOKEN {
+                       Node *node;
+                       char *get, *set;
+                       Variable *var;
+                       Type *type;
+                       char *root;
+                       
+                       if(strcmp($<id>5,"link")!=0 &&
+                          strcmp($<id>5,"stringlink")!=0 &&
+                          strcmp($<id>5,"objectlink")!=0) {
+                               g_free($<id>5); g_free($<id>3);
+                               g_free($<id>4);
+                               g_list_foreach($<list>2,(GFunc)g_free,NULL);
+                               yyerror(_("parse error"));
+                               YYERROR;
+                       }
+
+                       type = pop_type();
+
+                       var = find_var_or_die($<id>4, $<line>1);
+                       if(var->scope == PRIVATE_SCOPE)
+                               root = "self->_priv";
+                       else
+                               root = "self";
+
+                       if(strcmp($<id>5,"link")==0) {
+                               set = g_strdup_printf("%s->%s = ARG;",
+                                                     root, $<id>4);
+                       } else if(strcmp($<id>5,"stringlink")==0) {
+                               set = g_strdup_printf("g_free(%s->%s); "
+                                                     "%s->%s = g_strdup(ARG);",
+                                                     root, $<id>4,
+                                                     root, $<id>4);
+                       } else if(strcmp($<id>5,"objectlink")==0) {
+                               set = g_strdup_printf(
+                                 "if(%s->%s) "
+                                  "gtk_object_unref(GTK_OBJECT(%s->%s)); "
+                                 "%s->%s = ARG; "
+                                 "if(%s->%s) "
+                                  "gtk_object_ref(GTK_OBJECT(%s->%s)); ",
+                                 root, $<id>4,
+                                 root, $<id>4,
+                                 root, $<id>4,
+                                 root, $<id>4,
+                                 root, $<id>4);
+                       } else {
+                               g_assert_not_reached();
+                       }
+
+                       /* get is the same for everything */
+                       get = g_strdup_printf("ARG = %s->%s;", root, $<id>4);
+
+                       g_free($<id>5);
+
+
+                       if(!type)
+                               type = copy_type(var->vtype);
+
+                       node = new_argument($<id>3, type, $<list>2,
+                                           $<id>4, get, $<line>1,
+                                           set, $<line>1, $<line>1);
+                       class_nodes = g_list_append(class_nodes,node);
+                                               }
        ;
 
 argtype:       TOKEN '(' TOKEN type ')'        {
        ;
 
 argtype:       TOKEN '(' TOKEN type ')'        {
index e805824877246dc0155fad9d0777dde70d298ccd..402f69ccb839a18d959c8f2fe814875e436f0764 100644 (file)
@@ -3,7 +3,7 @@
    look in here to see a whole array of different syntax options, but
    don't expect this to be an easy to read file */
 
    look in here to see a whole array of different syntax options, but
    don't expect this to be an easy to read file */
 
-requires 0.92.1
+requires 0.93.0
 
 %headertop{
 /* this should go on the very top of the header */
 
 %headertop{
 /* this should go on the very top of the header */
@@ -46,6 +46,25 @@ void bubu(void);
 class Gtk:Weird:Button from Gtk:Button {
        public int i;
        argument INT i set { self->i = ARG; } get { ARG = self->i; } ;
 class Gtk:Weird:Button from Gtk:Button {
        public int i;
        argument INT i set { self->i = ARG; } get { ARG = self->i; } ;
+
+       public int testing = 1;
+       argument INT testing link;
+
+       public char * testingstring = {g_strdup("test")}
+               destroywith g_free;
+       argument POINTER testingstring stringlink;
+
+       public Gtk:Weird:Button * testingobj
+               destroywith gtk_object_unref;
+       argument POINTER testingobj objectlink;
+
+       public Gtk:Object * testingobj2
+               destroy {
+                       if(VAR)
+                               gtk_object_unref(GTK_OBJECT(VAR));
+               };
+       argument POINTER (type Gtk:Object *) testingobj2 objectlink;
+       
        argument POINTER (type GtkObject *) some_object
                set { /* set some_object */ }
                get { /* get some_object */
        argument POINTER (type GtkObject *) some_object
                set { /* set some_object */ }
                get { /* get some_object */
@@ -258,6 +277,10 @@ class Gtk:Weird:Button from Gtk:Button {
                /*foo*/
                return w;
        }
                /*foo*/
                return w;
        }
+       /* testing empty statements */
+       ;
+       ;
+       ;
 }
 
 %{
 }
 
 %{
index b92f771024fa3e21197f645b1bd039e86fa0a43e..6382d05979e56044c5e4e4161e640ab24ead2514 100644 (file)
@@ -119,7 +119,10 @@ new_argument(char *gtktype, Type *atype, GList *flags, char *name, char *get, in
 }
 
 Node *
 }
 
 Node *
-new_variable(int scope, Type *vtype, char *id, int line_no)
+new_variable(int scope, Type *vtype, char *id, int line_no,
+            char *destructor, int destructor_line,
+            gboolean destructor_simple,
+            char *initializer, int initializer_line)
 {
        Variable *node = (Variable *)g_new(Node,1);
        node->type = VARIABLE_NODE;
 {
        Variable *node = (Variable *)g_new(Node,1);
        node->type = VARIABLE_NODE;
@@ -127,5 +130,24 @@ new_variable(int scope, Type *vtype, char *id, int line_no)
        node->vtype = vtype;
        node->id = id;
        node->line_no = line_no;
        node->vtype = vtype;
        node->id = id;
        node->line_no = line_no;
+       node->destructor = destructor;
+       node->destructor_line = destructor_line;
+       node->destructor_simple = destructor_simple;
+       node->initializer = initializer;
+       node->initializer_line = initializer_line;
        return (Node *)node;
 }
        return (Node *)node;
 }
+
+Type *
+copy_type(Type *type)
+{
+       Node *node;
+
+       if(!type) return NULL;
+
+       node = new_type(type->stars,
+                       g_strdup(type->name),
+                       g_strdup(type->postfix));
+
+       return (Type *)node;
+}
index 9d3638fa2966265ba76521b62d148fdb43f867a0..66d181976c505ba422acf2b5aae09f269890b4fd 100644 (file)
@@ -155,6 +155,11 @@ struct _Variable {
        Type *vtype;
        char *id;
        int line_no;
        Type *vtype;
        char *id;
        int line_no;
+       char *destructor;
+       int destructor_line;
+       gboolean destructor_simple;
+       char *initializer;
+       int initializer_line;
 };
 
 union _Node {
 };
 
 union _Node {
@@ -180,6 +185,11 @@ Node *new_method(int scope, int method, Type *mtype, char *otype,
 Node *new_argument(char *gtktype, Type *atype, GList *flags, char *name,
                   char *get, int get_line, char *set, int set_line,
                   int line_no);
 Node *new_argument(char *gtktype, Type *atype, GList *flags, char *name,
                   char *get, int get_line, char *set, int set_line,
                   int line_no);
-Node *new_variable(int scope, Type *vtype, char *id,int line_no);
+Node *new_variable(int scope, Type *vtype, char *id, int line_no,
+                  char *destructor, int destructor_line,
+                  gboolean destructor_simple,
+                  char *initializer, int initializer_line);
+
+Type *copy_type(Type *type);
 
 #endif
 
 #endif