]> git.draconx.ca Git - gob-dx.git/blobdiff - src/main.c
Release 2.0.1
[gob-dx.git] / src / main.c
index 7613bc090bf8fda44806689646600a526789f291..fce8cb00774037ef6ae82508204a0648832462d0 100644 (file)
@@ -142,42 +142,6 @@ make_bases (void)
        ptypebase = remove_sep (((Class *)class)->ptype);
 }
 
-static char *
-get_type (const Type *t, gboolean postfix_to_stars)
-{
-       char *s;
-       int i;
-       int extra;
-       GString *gs;
-
-       s = remove_sep(t->name);
-       gs = g_string_new(s);
-       g_free(s);
-
-       extra = 0;
-       if (postfix_to_stars) {
-               const char *p;
-               /*XXX: this is ugly perhaps we can do this whole postfix thing
-                 in a nicer way, we just count the number of '[' s and from
-                 that we deduce the number of dimensions, so that we can print
-                 that many stars */
-               for (p = t->postfix; p && *p; p++)
-                       if(*p == '[') extra++;
-       }
-       g_string_append_c(gs, ' ');
-
-       if (t->pointer != NULL) {
-               g_string_append (gs, t->pointer);
-               for (i=0; i < extra; i++)
-                       g_string_append_c (gs, '*');
-               g_string_append_c (gs, ' ');
-       }
-       
-       s = gs->str;
-       g_string_free (gs, FALSE);
-       return s;
-}
-
 static char *
 get_gtk_doc (const char *id)
 {
@@ -454,7 +418,7 @@ put_signal_macro (const Method *m, gboolean gnu)
                out_printf (outh, "#define %s_connect_data__%s"
                            "(object,func,data,destroy_data,flags)\t"
                            "g_signal_connect_data(%s(object),\"%s\","
-                           "(GCallback)(func),(data),(destroy_data),(flags))\n",
+                           "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
                            funcbase, m->id, macrobase, m->id);
        } else {
                /* connect */
@@ -489,7 +453,7 @@ put_signal_macro (const Method *m, gboolean gnu)
                            funcbase, m->id, macrobase, typebase, m->id);
                print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
                              " = (func); ", m, FALSE, TRUE, TRUE);
-               out_printf (outh, "___%s; }), (data), (destroy_data), (flags))\n", m->id);
+               out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
        }
 }
 
@@ -1001,13 +965,25 @@ add_interface_inits (Class *c)
 
        for (li = c->interfaces; li != NULL; li = li->next) {
                const char *interface = li->data;
+               const char *end;
                char *name = replace_sep (interface, '_');
                char *type = remove_sep (interface);
 
+               /* EEEK! evil, we should have some sort of option
+                * to force this for arbitrary interfaces, since
+                * some are Class and some are Iface.  Glib is shite
+                * in consistency. */
+               if (strcmp (type, "GtkEditable") == 0 ||
+                   strcmp (type, "GTypePlugin") == 0)
+                       end = "Class";
+               else
+                       /* We'll assume Iface is the standard ending */
+                       end = "Iface";
+
                out_printf (out, "\nstatic void\n"
-                           "___%s_init (%sIface *iface)\n"
+                           "___%s_init (%s%s *iface)\n"
                            "{\n",
-                           name, type);
+                           name, type, end);
 
                add_interface_methods (c, interface);
 
@@ -1579,6 +1555,21 @@ make_argument (Argument *a)
 
 #define value_for_print(str, alt) (str != NULL ? str : alt)
 
+static char *
+make_me_type (const char *type, const char *alt)
+{
+       if (type == NULL)
+               return g_strdup (alt);
+       /* HACK!  just in case someone made this
+        * work with 2.0.0 by using the TYPE
+        * macro directly */
+       if ((strstr (type, "_TYPE_") != NULL ||
+            strstr (type, "TYPE_") == type) &&
+           strchr (type, ':') == NULL)
+               return g_strdup (type);
+       return make_pre_macro (type, "TYPE");
+}
+
 static void
 make_property (Property *p)
 {
@@ -1633,7 +1624,7 @@ make_property (Property *p)
 
        g_string_append (flags, ")");
 
-       if (strcmp (p->gtktype, "CHAR") == 0)
+       if (strcmp (p->gtktype, "CHAR") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_char\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1649,7 +1640,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "127"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "UCHAR") == 0)
+       } else if (strcmp (p->gtktype, "UCHAR") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1665,7 +1656,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "0xFF"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "BOOLEAN") == 0)
+       } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1677,7 +1668,7 @@ make_property (Property *p)
                            value_for_print (p->blurb, "NULL"),
                            value_for_print (p->default_value, "FALSE"),
                            flags->str);
-       else if (strcmp (p->gtktype, "INT") == 0)
+       } else if (strcmp (p->gtktype, "INT") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_int\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1693,7 +1684,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXINT"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "UINT") == 0)
+       } else if (strcmp (p->gtktype, "UINT") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_uint\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1709,7 +1700,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXUINT"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "LONG") == 0)
+       } else if (strcmp (p->gtktype, "LONG") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_long\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1725,7 +1716,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXLONG"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "ULONG") == 0)
+       } else if (strcmp (p->gtktype, "ULONG") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1741,7 +1732,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXULONG"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "UNICHAR") == 0)
+       } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1753,7 +1744,9 @@ make_property (Property *p)
                            value_for_print (p->blurb, "NULL"),
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "ENUM") == 0)
+       } else if (strcmp (p->gtktype, "ENUM") == 0) {
+               char *type = make_me_type (p->extra_gtktype,
+                                          "G_TYPE_ENUM");
                out_printf (out, "\tparam_spec = g_param_spec_enum\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1764,10 +1757,13 @@ make_property (Property *p)
                            p->name,
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
-                           value_for_print (p->extra_gtktype, "G_TYPE_ENUM"),
+                           type,
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "FLAGS") == 0)
+               g_free (type);
+       } else if (strcmp (p->gtktype, "FLAGS") == 0) {
+               char *type = make_me_type (p->extra_gtktype,
+                                          "G_TYPE_FLAGS");
                out_printf (out, "\tparam_spec = g_param_spec_flags\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1778,10 +1774,11 @@ make_property (Property *p)
                            p->name,
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
-                           value_for_print (p->extra_gtktype, "G_TYPE_FLAGS"),
+                           type,
                            value_for_print (p->default_value, "0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "FLOAT") == 0)
+               g_free (type);
+       } else if (strcmp (p->gtktype, "FLOAT") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_float\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1797,7 +1794,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXFLOAT"),
                            value_for_print (p->default_value, "0.0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "DOUBLE") == 0)
+       } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_double\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1813,7 +1810,7 @@ make_property (Property *p)
                            value_for_print (p->maximum, "G_MAXDOUBLE"),
                            value_for_print (p->default_value, "0.0"),
                            flags->str);
-       else if (strcmp (p->gtktype, "STRING") == 0)
+       } else if (strcmp (p->gtktype, "STRING") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_string\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1825,7 +1822,9 @@ make_property (Property *p)
                            value_for_print (p->blurb, "NULL"),
                            value_for_print (p->default_value, "NULL"),
                            flags->str);
-       else if (strcmp (p->gtktype, "PARAM") == 0)
+       } else if (strcmp (p->gtktype, "PARAM") == 0) {
+               char *type = make_me_type (p->extra_gtktype,
+                                          "G_TYPE_PARAM");
                out_printf (out, "\tparam_spec = g_param_spec_param\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1835,9 +1834,12 @@ make_property (Property *p)
                            p->name,
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
-                           value_for_print (p->extra_gtktype, "G_TYPE_PARAM"),
+                           type,
                            flags->str);
-       else if (strcmp (p->gtktype, "BOXED") == 0)
+               g_free (type);
+       } else if (strcmp (p->gtktype, "BOXED") == 0) {
+               char *type = make_me_type (p->extra_gtktype,
+                                          "G_TYPE_BOXED");
                out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1847,9 +1849,10 @@ make_property (Property *p)
                            p->name,
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
-                           value_for_print (p->extra_gtktype, "G_TYPE_BOXED"),
+                           type,
                            flags->str);
-       else if (strcmp (p->gtktype, "POINTER") == 0)
+               g_free (type);
+       } else if (strcmp (p->gtktype, "POINTER") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1860,7 +1863,7 @@ make_property (Property *p)
                            value_for_print (p->blurb, "NULL"),
                            flags->str);
        /* FIXME: VALUE_ARRAY */
-       else if (strcmp (p->gtktype, "CLOSURE") == 0)
+       } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
                out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1870,7 +1873,9 @@ make_property (Property *p)
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
                            flags->str);
-       else if (strcmp (p->gtktype, "OBJECT") == 0)
+       } else if (strcmp (p->gtktype, "OBJECT") == 0) {
+               char *type = make_me_type (p->extra_gtktype,
+                                          "G_TYPE_BOXED");
                out_printf (out, "\tparam_spec = g_param_spec_object\n"
                            "\t\t(\"%s\" /* name */,\n"
                            "\t\t %s /* nick */,\n"
@@ -1880,12 +1885,14 @@ make_property (Property *p)
                            p->name,
                            value_for_print (p->nick, "NULL"),
                            value_for_print (p->blurb, "NULL"),
-                           value_for_print (p->extra_gtktype, "G_TYPE_OBJECT"),
+                           type,
                            flags->str);
-       else
+               g_free (type);
+       } else {
                error_printf (GOB_ERROR, p->line_no,
                              "%s type is not supported by properties",
                              p->gtktype);
+       }
 
        s = g_strdup (p->name);
        g_strup (s);
@@ -2535,11 +2542,21 @@ put_signal_args (Method *m)
 {
        GList *li;
        GList *ali;
-       for (ali = m->gtktypes->next, li=m->args->next;
+       int i;
+
+       if (m->args->next == NULL)
+               return;
+
+       for (ali = m->gtktypes->next, li = m->args->next, i = 1;
             li != NULL && ali != NULL;
-            li = li->next, ali = ali->next) {
+            li = li->next, ali = ali->next, i++) {
                FuncArg *fa = li->data;
                char *cast = g_strdup (get_cast (ali->data, FALSE));
+               /* FIXME: This code is so fucking ugly it hurts */
+               gboolean do_static = 
+                       (strcmp ((char *)ali->data, "STRING") == 0 ||
+                        strcmp ((char *)ali->data, "BOXED") == 0);
+               char *set_func;
 
                if (cast == NULL) {
                        cast = get_type (fa->atype, TRUE);
@@ -2548,9 +2565,20 @@ put_signal_args (Method *m)
                   the we know all the types */
                g_assert (cast != NULL);
 
-               out_printf (out, ",\n\t\t(%s)%s", cast,
-                           fa->name);
+               out_printf (out,
+                           "\t___param_values[%d].g_type = 0;\n"
+                           "\tg_value_init (&___param_values[%d], G_TYPE_%s);\n",
+                           i, i, (char *)ali->data);
+
+               set_func = g_strdup_printf ("g_value_set%s_%s",
+                                           do_static ? "_static" : "",
+                                           (char *)ali->data);
+               g_strdown (set_func);
 
+               out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
+                           set_func, i, cast, fa->name);
+
+               g_free (set_func);
                g_free (cast);
        }
 }
@@ -2610,38 +2638,87 @@ put_method(Method *m)
                else /* PUBLIC, PROTECTED */
                        print_method(out, "", "\n", "", " ", "", "\n",
                                     m, FALSE, FALSE, TRUE);
-               out_addline_outfile(out);
-               out_printf(out, "{\n");
-               s = g_strdup(m->id);
-               g_strup(s);
-               if(strcmp(m->mtype->name, "void") == 0 &&
-                  m->mtype->pointer == NULL) {
-                       print_preconditions(m);
-                       if(((FuncArg *)m->args->data)->name)
-                       out_printf(out, "\tg_signal_emit (G_OBJECT (%s),\n"
-                               "\t\tobject_signals[%s_SIGNAL], 0",
-                               ((FuncArg *)m->args->data)->name, s);
-                       put_signal_args (m);
-                       out_printf(out, ");\n}\n");
-               } else {
-                       out_printf(out, "\t");
-                       print_type(out, m->mtype, TRUE);
-                       out_printf(out, "return_val = (");
-                       print_type(out, m->mtype, TRUE);
-                       if(m->defreturn)
-                               out_printf(out, ")(%s);\n", m->defreturn);
-                       else if(m->onerror)
-                               out_printf(out, ")(%s);\n", m->onerror);
-                       else
-                               out_printf(out, ")(0);\n");
-                       print_preconditions(m);
-                       out_printf(out, "\tg_signal_emit (G_OBJECT (%s),\n"
-                               "\t\tobject_signals[%s_SIGNAL], 0",
-                               ((FuncArg *)m->args->data)->name, s);
-                       put_signal_args(m);
-                       out_printf(out, ",\n\t\t&return_val);\n"
-                               "\treturn return_val;\n}\n");
+               out_addline_outfile (out);
+
+               out_printf (out, "{\n");
+
+               out_printf (out,
+                           "\tGValue ___param_values[%d];\n"
+                           "\tGValue ___return_val = {0};\n\n",
+                           g_list_length (m->args));
+
+               print_preconditions (m);
+
+               out_printf (out,
+                           "\n\t___param_values[0].g_type = 0;\n"
+                           "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
+                           "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
+                           ((FuncArg *)m->args->data)->name,
+                           ((FuncArg *)m->args->data)->name);
+
+               put_signal_args (m);
+
+               if (strcmp (m->gtktypes->data, "NONE") != 0) {
+                       const char *defret = NULL;
+
+                       out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
+                                   (char *)m->gtktypes->data);
+
+                       if (m->defreturn != NULL)
+                               defret = m->defreturn;
+                       else if (m->onerror != NULL)
+                               defret = m->onerror;
+
+                       if (defret != NULL) {
+                               char *set_func;
+                               /* FIXME: This code is so fucking ugly it hurts */
+                               gboolean do_static = 
+                                       (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
+                                        strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
+                               char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
+                               if (cast == NULL)
+                                       cast = get_type (m->mtype, TRUE);
+
+                               set_func = g_strdup_printf ("g_value_set%s_%s",
+                                                           do_static ? "_static" : "",
+                                                           (char *)m->gtktypes->data);
+                               g_strdown (set_func);
+
+                               out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
+                                           set_func, cast, defret);
+
+                               g_free (set_func);
+                               g_free (cast);
+                       }
+                       out_printf (out, "\n");
+               }
+
+               s = g_strdup (m->id);
+               g_strup (s);
+
+               out_printf(out, "\tg_signal_emitv (___param_values,\n"
+                          "\t\tobject_signals[%s_SIGNAL],\n"
+                          "\t\t0 /* detail */,\n"
+                          "\t\t&___return_val);\n", s);
+
+               g_free (s);
+
+               if (strcmp (m->gtktypes->data, "NONE") != 0) {
+                       char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
+                       char *getfunc = g_strdup_printf ("g_value_get_%s",
+                                                        (char *)m->gtktypes->data);
+                       g_strdown (getfunc);
+
+                       if (cast == NULL)
+                               cast = get_type (m->mtype, TRUE);
+
+                       out_printf (out, "\n\treturn (%s) %s (&___return_val);\n",
+                                   cast, getfunc);
+
+                       g_free (cast);
+                       g_free (getfunc);
                }
+               out_printf(out, "}\n");
 
                if(!m->cbuf)
                        break;