X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/3b10bbd3a88d6e16146414d91d06bb2f36347bfc..5b42e9400440d86723a27747b2191ab8cd59c2ee:/src/util.c diff --git a/src/util.c b/src/util.c index 2eda8b0..a6cff4e 100644 --- a/src/util.c +++ b/src/util.c @@ -24,12 +24,13 @@ #include #include +#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; +}