]> git.draconx.ca Git - gob-dx.git/blobdiff - src/util.c
Release 0.93.1
[gob-dx.git] / src / util.c
index 2eda8b036fb260c4f342bc3d67ec33789c49c947..a6cff4e8bfa8f5baeaf3f98ba1f03fd34e6bf47f 100644 (file)
 #include <stdio.h>
 #include <glib.h>
 
+#include "tree.h"
 #include "main.h"
 
 #include "util.h"
 
 void
-print_error(int is_warn, char *error,int line)
+print_error(gboolean is_warn, char *error, int line)
 {
        char *w;
        if(is_warn)
@@ -39,9 +40,9 @@ print_error(int is_warn, char *error,int line)
                got_error = TRUE;
        }
        if(line>0)
-               fprintf(stderr,"%s:%d: %s %s\n",filename,line,w,error);
+               fprintf(stderr, "%s:%d: %s %s\n", filename, line, w, error);
        else
-               fprintf(stderr,"%s: %s %s\n",filename,w,error);
+               fprintf(stderr, "%s: %s %s\n", filename, w, error);
        if((!is_warn || exit_on_warn) && exit_on_error)
                exit(1);
 }
@@ -120,48 +121,119 @@ make_pre_macro(char *base, char *pre)
 /* here we will find out how inconsistent gtk really is :) */
 /* the commented out types mean that these types don't actually
    exist. so we "emulate them" with an equivalent */
-const struct {
+typedef struct _OurGtkType OurGtkType;
+struct _OurGtkType {
        gboolean simple;
        char *gtkname;
        char *typename;
-} our_gtk_type_table[] = {
-       { TRUE, "NONE", "void " },
-       { TRUE, "CHAR", "gchar " },
-       { TRUE, "UCHAR",        "guchar " },
-       { TRUE, "BOOL", "gboolean " },
-       { TRUE, "INT",  "gint " },
-       { TRUE, "UINT", "guint " },
-       { TRUE, "LONG", "glong " },
-       { TRUE, "ULONG",        "gulong " },
-       { TRUE, "FLOAT",        "gfloat " },
-       { TRUE, "DOUBLE",       "gdouble " },
-       { TRUE, "STRING",       /*"GtkString"*/"gchar *" },
-       { TRUE, "ENUM", /*"GtkEnum"*/"gint " },
-       { TRUE, "FLAGS",        /*"GtkFlags"*/"guint " },
-       { TRUE, "BOXED",        /*"GtkBoxed"*/"gpointer " },
-       { TRUE, "POINTER",      "gpointer " },
-       { TRUE, "OBJECT",       "GtkObject *" },
-       { FALSE, "SIGNAL",      /*"GtkSignal"*/"___twopointertype " },
-       { FALSE, "ARGS",        /*"GtkArgs"*/"___twopointertype " },
-       { FALSE, "CALLBACK",    /*"GtkCallback"*/"___threepointertype " },
-       { FALSE, "C_CALLBACK",  /*"GtkCCallback"*/"___twopointertype " },
-       { FALSE, "FOREIGN",     /*"GtkForeign"*/"___twopointertype " },
+       int special;
+};
+const OurGtkType our_gtk_type_table[] = {
+       { TRUE, "NONE",         "void ", -1 },
+       { TRUE, "CHAR",         "gchar ", -1 },
+       { TRUE, "UCHAR",        "guchar ", -1 },
+       { TRUE, "BOOL",         "gboolean ", -1 },
+       { TRUE, "INT",          "gint ", -1 },
+       { TRUE, "UINT",         "guint ", -1 },
+       { TRUE, "LONG",         "glong ", -1 },
+       { TRUE, "ULONG",        "gulong ", -1 },
+       { TRUE, "FLOAT",        "gfloat ", -1 },
+       { TRUE, "DOUBLE",       "gdouble ", -1 },
+       { TRUE, "STRING",       /*"GtkString"*/"gchar *", -1 },
+       { TRUE, "ENUM",         /*"GtkEnum"*/"gint ", -1 },
+       { TRUE, "FLAGS",        /*"GtkFlags"*/"guint ", -1 },
+       { TRUE, "BOXED",        /*"GtkBoxed"*/"gpointer ", -1 },
+       { TRUE, "POINTER",      "gpointer ", -1 },
+       { TRUE, "OBJECT",       "GtkObject *", -1 },
+       { FALSE, "SIGNAL",      /*"GtkSignal"*/"___twopointertype ",
+               SPECIAL_2POINTER },
+       { FALSE, "ARGS",        /*"GtkArgs"*/"___intpointertype ",
+               SPECIAL_INT_POINTER },
+       { FALSE, "CALLBACK",    /*"GtkCallback"*/"___threepointertype ",
+               SPECIAL_3POINTER },
+       { FALSE, "C_CALLBACK",  /*"GtkCCallback"*/"___twopointertype ",
+               SPECIAL_2POINTER },
+       { FALSE, "FOREIGN",     /*"GtkForeign"*/"___twopointertype ",
+               SPECIAL_2POINTER },
 
        { FALSE, NULL, NULL }
 };
 
+static GHashTable *type_hash = NULL;
+
+static void
+init_type_hash(void)
+{
+       int i;
+
+       if(type_hash) return;
+
+       type_hash = g_hash_table_new(g_str_hash, g_str_equal);
+
+       for(i=0; our_gtk_type_table[i].gtkname; i++)
+               g_hash_table_insert(type_hash,
+                                   our_gtk_type_table[i].gtkname,
+                                   (gpointer)&our_gtk_type_table[i]);
+}
+
 const char *
 get_cast(char *type, gboolean simple_only)
 {
-       int i;
-       for(i=0;our_gtk_type_table[i].gtkname;i++) {
-               if(strcmp(our_gtk_type_table[i].gtkname,type)==0) {
-                       if(simple_only &&
-                          !our_gtk_type_table[i].simple)
-                               return NULL;
-                       return our_gtk_type_table[i].typename;
-               }
+       OurGtkType *gtype;
+
+       init_type_hash();
+
+       gtype = g_hash_table_lookup(type_hash, type);
+
+       if(!gtype ||
+          (simple_only &&
+           !gtype->simple))
+               return NULL;
+
+       return gtype->typename;
+}
+
+static void
+mask_special_array(char *type, gboolean *special_array, gboolean *any_special)
+{
+       OurGtkType *gtype;
+
+       init_type_hash();
+
+       gtype = g_hash_table_lookup(type_hash, type);
+
+       if(gtype && gtype->special >= 0) {
+               special_array[gtype->special] = TRUE;
+               *any_special = TRUE;
        }
-       return NULL;
 }
 
+gboolean
+setup_special_array(Class *c, gboolean *special_array)
+{
+       GList *li;
+       gboolean any_special = FALSE;
+
+       memset(special_array, 0, sizeof(gboolean)*SPECIAL_LAST);
+
+       for(li=c->nodes; li; li=g_list_next(li)) {
+               Node *n = li->data;
+               if(n->type == METHOD_NODE) {
+                       Method *m = (Method *)n;
+                       GList *l;
+                       if(m->method != SIGNAL_LAST_METHOD &&
+                          m->method != SIGNAL_FIRST_METHOD)
+                               continue;
+
+                       for(l=m->gtktypes; l; l=l->next)
+                               mask_special_array(l->data, special_array,
+                                                  &any_special);
+               } else if(n->type == ARGUMENT_NODE) {
+                       Argument *a = (Argument *)n;
+                       mask_special_array(a->gtktype, special_array,
+                                          &any_special);
+               }
+       }
+
+       return any_special;
+}