X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/853c670e4b839fd435507201f04d16080590a894..5cfe51ee2287165feb0cf006901bbbc2b961f3b8:/src/main.c?ds=sidebyside diff --git a/src/main.c b/src/main.c index e145d64..526408b 100644 --- a/src/main.c +++ b/src/main.c @@ -67,6 +67,7 @@ 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 overrode_get_type = FALSE; /* provided your won _get_type */ static gboolean made_aliases = FALSE; /* if we made any shorthand aliases and need the REALLY UGLY HACK to @@ -93,7 +94,7 @@ gboolean no_gnu = FALSE; gboolean exit_on_warn = FALSE; gboolean exit_on_error = TRUE; gboolean got_error = FALSE; -gint private_header = PRIVATE_HEADER_ALWAYS; +gint private_header = PRIVATE_HEADER_ONDEMAND; gboolean no_extern_c = FALSE; gboolean no_write = FALSE; gboolean no_lines = FALSE; @@ -101,6 +102,14 @@ gboolean no_self_alias = FALSE; gboolean no_kill_underscores = FALSE; gboolean always_private_struct = FALSE; +gboolean use_m4 = FALSE; /* preprocess sources with m4 */ +gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */ +char *m4_commandline = NULL; +#define M4_INCLUDE_DIR PKGDATADIR "/m4" +#define M4_BASE_FILENAME "gobm4.m4" +#define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME +#define M4_COMMANDLINE "m4" + int method_unique_id = 1; static void @@ -127,7 +136,7 @@ make_bases(void) } static char * -get_type(Type *t, gboolean postfix_to_stars) +get_type(const Type *t, gboolean postfix_to_stars) { char *s; int i; @@ -140,7 +149,7 @@ get_type(Type *t, gboolean postfix_to_stars) extra = 0; if(postfix_to_stars) { - char *p; + 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 @@ -163,7 +172,7 @@ get_type(Type *t, gboolean postfix_to_stars) } static char * -get_gtk_doc(char *id) +get_gtk_doc(const char *id) { char *val; @@ -182,7 +191,7 @@ get_gtk_doc(char *id) } static void -print_type(FILE *fp, Type *t, gboolean postfix_to_stars) +print_type(FILE *fp, const Type *t, gboolean postfix_to_stars) { char *s; @@ -193,15 +202,20 @@ print_type(FILE *fp, Type *t, gboolean postfix_to_stars) static void -print_method(FILE *fp, char *typeprefix, char *nameprefix, - char *subnameprefix, - char *namepostfix, char *postfix, Method *m, - gboolean one_arg_per_line, - gboolean no_funcbase, - gboolean kill_underscore) +print_method (FILE *fp, + const char *typeprefix, + const char *nameprefix, + const char *subnameprefix, + const char *namepostfix, + const char *afterargs, + const char *postfix, + const Method *m, + gboolean one_arg_per_line, + gboolean no_funcbase, + gboolean kill_underscore) { GList *li; - char *id; + const char *id; out_printf(fp, "%s", typeprefix); print_type(fp, m->mtype, TRUE); @@ -225,21 +239,21 @@ print_method(FILE *fp, char *typeprefix, char *nameprefix, print_type(fp, arg->atype, FALSE); if(li->next) out_printf(fp, "%s%s,%s", arg->name, - arg->atype->postfix? - arg->atype->postfix:"", - one_arg_per_line?"\n\t\t\t\t\t":" "); + arg->atype->postfix ? + arg->atype->postfix : "", + one_arg_per_line ? "\n\t\t\t\t\t" : " "); else out_printf(fp, "%s%s", arg->name, - arg->atype->postfix? - arg->atype->postfix:""); + arg->atype->postfix ? + arg->atype->postfix : ""); } if(m->vararg) out_printf(fp, ",%s...", - one_arg_per_line?"\n\t\t\t\t\t":" "); + one_arg_per_line ? "\n\t\t\t\t\t" : " "); } else { out_printf(fp, "void"); } - out_printf(fp, ")%s", postfix); + out_printf(fp, "%s)%s", afterargs, postfix); } static gboolean @@ -264,12 +278,13 @@ any_method_to_alias(Class *c) } +/* just the vararg macros, we use the same func pointers for these as in non-gnu */ static void make_method_gnu_aliases(Class *c) { GList *li; - for(li=c->nodes;li;li=g_list_next(li)) { + for(li = c->nodes; li != NULL; li = li->next) { Node *node = li->data; if(node->type == METHOD_NODE) { Method *m = (Method *)node; @@ -283,13 +298,24 @@ make_method_gnu_aliases(Class *c) if(for_cpp && strcmp(m->id, "new")==0) continue; - out_printf(out, "static const typeof(&%s_%s) %s " - "__attribute__ ((__unused__)) " - "= %s_%s;\n", funcbase, get_real_id(m->id), - m->id, funcbase, get_real_id(m->id)); - out_printf(out, "#define %s(args...) " - "%s_%s(##args)\n", m->id, - funcbase, get_real_id(m->id)); + if(m->args != NULL) + out_printf(out, "#define %s(args...) " + "%s_%s(args)\n", m->id, + funcbase, get_real_id(m->id)); + else + out_printf(out, "#define %s() " + "%s_%s()\n", m->id, + funcbase, get_real_id(m->id)); + + /* for compatibility with gob2 */ + if(m->args != NULL) + out_printf(out, "#define self_%s(args...) " + "%s_%s(args)\n", m->id, + funcbase, get_real_id(m->id)); + else + out_printf(out, "#define self_%s() " + "%s_%s()\n", m->id, + funcbase, get_real_id(m->id)); } } } @@ -298,6 +324,8 @@ static void make_method_nongnu_aliases(Class *c) { GList *li; + + gboolean local_made_aliases = FALSE; for(li=c->nodes; li; li=g_list_next(li)) { Node *node = li->data; @@ -313,14 +341,29 @@ make_method_nongnu_aliases(Class *c) if(for_cpp && strcmp(m->id, "new")==0) continue; - print_method(out, "static ", "(* ", "", ") ", "", + if( ! local_made_aliases) + out_printf(out, "\n/* Short form pointers */\n"); + + print_method(out, "static ", "(* const ", "", ") ", + "", "", m, FALSE, TRUE, FALSE); out_printf(out, " = %s_%s;\n", funcbase, get_real_id(m->id)); - made_aliases = TRUE; + /* for compatibility with gob2 */ + print_method(out, "static ", "(* const self_", "", ") ", + "", "", + m, FALSE, TRUE, FALSE); + out_printf(out, " = %s_%s;\n", funcbase, + get_real_id(m->id)); + + local_made_aliases = TRUE; } } + if(local_made_aliases) { + out_printf(out, "\n"); + made_aliases = TRUE; + } } static void @@ -329,10 +372,10 @@ add_bad_hack_to_avoid_unused_warnings(Class *c) GList *li; /* if we haven't had any methods, just return */ - if(!made_aliases) + if( ! made_aliases) return; - if(!no_gnu) + if( ! no_gnu) out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n"); out_printf(out, "/*REALLY BAD HACK\n" @@ -382,7 +425,7 @@ put_variable(Variable *v, FILE *fp) } static void -put_vs_method(Method *m) +put_vs_method(const Method *m) { if(m->method != SIGNAL_LAST_METHOD && m->method != SIGNAL_FIRST_METHOD && @@ -391,71 +434,77 @@ put_vs_method(Method *m) /* if a signal mark it as such */ if(m->method != VIRTUAL_METHOD) - print_method(outh, "\t/*signal*/", "(* ", "", ") ", ";\n", + print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n", m, FALSE, TRUE, TRUE); else - print_method(outh, "\t", "(* ", "", ") ", ";\n", + print_method(outh, "\t", "(* ", "", ") ", "", ";\n", m, FALSE, TRUE, TRUE); } static void -put_pub_method(Method *m) +put_pub_method(const Method *m) { if(m->scope != PUBLIC_SCOPE) return; - print_method(outh, "", "\t", "", "\t", ";\n", m, TRUE, FALSE, TRUE); + print_method(outh, "", "\t", "", "\t", "", ";\n", m, TRUE, FALSE, TRUE); } -/* I'm starting not to like this idea */ -#if 0 static void -put_signal_connect(Method *m) +put_signal_macro (const Method *m, gboolean gnu) { + char *id; + if(m->method != SIGNAL_LAST_METHOD && m->method != SIGNAL_FIRST_METHOD) return; - out_printf(outh, "guint \t%s_%s__connect_full\t(%s *object,\n" - "\t\t\t\t\tconst char *name,\n" - "\t\t\t\t\tGtkSignalFunc func,\n" - "\t\t\t\t\tGtkCallbackMarshal marshal,\n" - "\t\t\t\t\tgpointer data,\n" - "\t\t\t\t\tGtkDestroyNotify destroy_func,\n" - "\t\t\t\t\tgboolean object_signal,\n" - "\t\t\t\t\tgboolean after);\n", - funcbase, m->id, typebase); - - out_printf(outh, "#define %s_%s__connect(object,name,func,data) " - "%s_%s__connect_full((object),(name),(func),NULL," - "(data),NULL,FALSE,FALSE)\n", - funcbase, m->id, funcbase, m->id); - out_printf(outh, "#define %s_%s__connect_after(object,name,func,data) " - "%s__connect_%s_full((object),(name),(func),NULL," - "(data),NULL,FALSE,TRUE)\n", - funcbase, m->id, funcbase, m->id); - - out_printf(outh, "guint \t%s_%s__connect_while_alive\t(%s *object,\n" - "\t\t\t\t\tconst char *name,\n" - "\t\t\t\t\tGtkSignalFunc func,\n" - "\t\t\t\t\tgpointer data,\n" - "\t\t\t\t\tGtkObject *alive_object);\n\n", - funcbase, m->id, typebase); + id = g_strdup (m->id); + g_strup (id); + + if ( ! gnu) { + out_printf (outh, "#define %s_SIGNAL_%s(func)\t" + "\"%s\",GTK_SIGNAL_FUNC(func)\n", + macrobase, id, get_real_id (m->id)); + } else { + out_printf (outh, "#define %s_SIGNAL_%s(func)\t" + "\"%s\",GTK_SIGNAL_FUNC(({", + macrobase, id, get_real_id (m->id)); + print_method (outh, "", "(* ___", "", ") ", ", gpointer data ", + " = func; ", m, FALSE, TRUE, TRUE); + out_printf (outh, "___%s; }))\n", get_real_id (m->id)); + + } + g_free (id); +} + +static void +put_signal_macros (const Class *c, gboolean gnu) +{ + const GList *li; + + if (signals < 0) + return; + + for (li = c->nodes; li != NULL; li = li->next) { + const Node *n = li->data; + if (n->type == METHOD_NODE) + put_signal_macro ((Method *)n, gnu); + } } -#endif static void -put_prot_method(Method *m) +put_prot_method(const Method *m) { if(m->scope != PROTECTED_SCOPE) return; if(outph) - print_method(outph, "", "\t", "", "\t", ";\n", + print_method(outph, "", "\t", "", "\t", "", ";\n", m, FALSE, FALSE, TRUE); else - print_method(out, "", "\t", "", "\t", ";\n", + print_method(out, "", "\t", "", "\t", "", ";\n", m, FALSE, FALSE, TRUE); } @@ -467,7 +516,7 @@ put_priv_method_prot(Method *m) m->method == VIRTUAL_METHOD) { if(m->cbuf) print_method(out, - "static ", "___real_", "", " ", ";\n", + "static ", "___real_", "", " ", "", ";\n", m, FALSE, FALSE, TRUE); } /* no else, here, it might still have a private prototype, it's not @@ -477,14 +526,14 @@ put_priv_method_prot(Method *m) m->cbuf)) { /* add unique ID */ char *s = g_strdup_printf("___%x_", (guint)m->unique_id); - print_method(out, "static ", s, "", " ", + print_method(out, "static ", s, "", " ", "", no_gnu?";\n":" G_GNUC_UNUSED;\n", m, FALSE, FALSE, FALSE); g_free(s); } else if(m->scope == PRIVATE_SCOPE || m->method == INIT_METHOD || m->method == CLASS_INIT_METHOD) - print_method(out, "static ", "", "", " ", + print_method(out, "static ", "", "", " ", "", no_gnu?";\n":" G_GNUC_UNUSED;\n", m, FALSE, FALSE, TRUE); } @@ -535,7 +584,8 @@ make_inits(Class *cl) NULL, NULL, NULL, g_strdup("class_init"), make_func_arg(cl->otype, TRUE, g_strdup("c")), NULL, NULL, NULL, 0, 0, FALSE, - method_unique_id++); + method_unique_id++, + FALSE /*bonobo_x_func*/); cl->nodes = g_list_prepend(cl->nodes, node); } if(!got_init) { @@ -545,7 +595,8 @@ make_inits(Class *cl) NULL, NULL, NULL, g_strdup("init"), make_func_arg(cl->otype, FALSE, g_strdup("o")), NULL, NULL, NULL, 0, 0, FALSE, - method_unique_id++); + method_unique_id++, + FALSE /*bonobo_x_func*/); cl->nodes = g_list_prepend(cl->nodes, node); } } @@ -651,7 +702,7 @@ find_same_type_signal(Method *m) } static void -print_signal_marsal_args(Method *m) +print_signal_marsal_args_gtk1 (Method *m) { if(strcmp(m->gtktypes->next->data, "NONE")!=0) { GList *li; @@ -672,6 +723,146 @@ print_signal_marsal_args(Method *m) out_printf(out, ",\n\t\tfunc_data);\n}\n\n"); } +static void +add_marshal_gtk1 (Method *m, const char *mname) +{ + out_printf(out, "\nstatic void\n" + "___marshal_%s (GtkObject * object,\n" + "\tGtkSignalFunc func,\n" + "\tgpointer func_data,\n" + "\tGtkArg * args)\n" + "{\n", mname); + + if(strcmp(m->gtktypes->data, "NONE")==0) { + out_printf(out, "\t___%s rfunc;\n\n" + "\trfunc = (___%s)func;\n\n" + "\t(*rfunc)((%s *)object", mname, mname, typebase); + } else { + const char *retcast = get_cast(m->gtktypes->data, FALSE); + gboolean is_none = (strcmp(m->gtktypes->next->data, "NONE")==0); + out_printf(out, + "\t___%s rfunc;\n\t" + "%s *retval;\n\n" + "\trfunc = (___%s)func;\n\n" + "\tretval = GTK_RETLOC_%s(args[%d]);\n\n" + "\t*retval = (*rfunc)((%s *)object", + mname, retcast, mname, + (char *)m->gtktypes->data, + g_list_length(m->gtktypes) - (is_none ? 2 : 1), + typebase); + } + print_signal_marsal_args_gtk1 (m); +} + +static const char * +gtk2_debool (const char *s) +{ + if (strcmp (s, "BOOL") == 0) + return "BOOLEAN"; + else + return s; +} + +static void +print_signal_marsal_args_gtk2 (Method *m) +{ + if (strcmp (m->gtktypes->next->data, "NONE") != 0) { + GList *li; + int i; + for (i = 0, li = m->gtktypes->next; + li != NULL; + i++, li = li->next) { + char *get_func = g_strdup_printf + ("g_value_get_%s", + (char *)gtk2_debool (li->data)); + g_strdown (get_func); + out_printf (out, ",\n\t\t(%s) " + "%s (param_values + %d)", + get_cast (li->data, FALSE), + get_func, i + 1); + g_free (get_func); + } + } + out_printf (out, ",\n\t\tdata2);\n"); +} + +static void +add_marshal_gtk2 (Method *m, const char *mname) +{ + gboolean ret_none; + gboolean arglist_none; + const char *retcast; + + ret_none = strcmp (m->gtktypes->data, "NONE") == 0; + arglist_none = strcmp (m->gtktypes->next->data, "NONE") == 0; + + if (ret_none) + retcast = NULL; + else + retcast = get_cast (m->gtktypes->data, FALSE); + + out_printf (out, "\nstatic void\n" + "___marshal_%s (GClosure *closure,\n" + "\tGValue *return_value,\n" + "\tguint n_param_values,\n" + "\tconst GValue *param_values,\n" + "\tgpointer invocation_hint,\n" + "\tgpointer marshal_data)\n" + "{\n", mname); + + if ( ! ret_none) + out_printf (out, "\t%s v_return;\n", retcast); + + out_printf (out, "\tregister ___%s callback;\n" + "\tregister GCClosure *cc = (GCClosure*) closure;\n" + "\tregister gpointer data1, data2;\n\n", + mname); + + out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n", + arglist_none ? 1 : g_list_length (m->gtktypes)); + + out_printf (out, + "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n" + "\t\tdata1 = closure->data;\n" + "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n" + "\t} else {\n" + "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n" + "\t\tdata2 = closure->data;\n" + "\t}\n\n"); + + out_printf (out, "\tcallback = (___%s) " + "(marshal_data != NULL ? marshal_data : cc->callback);" + "\n\n", mname); + + if (ret_none) { + out_printf (out, "\tcallback ((%s *)data1", typebase); + } else { + out_printf (out, "\tv_return = callback ((%s *)data1", + typebase); + } + + print_signal_marsal_args_gtk2 (m); + + if ( ! ret_none) { + /* FIXME: This code is so fucking ugly it hurts */ + gboolean take_ownership = + (strcmp ((char *)m->gtktypes->data, "STRING") == 0 || + strcmp ((char *)m->gtktypes->data, "BOXED") == 0); + char *set_func = g_strdup_printf ("g_value_set_%s%s", + (char *)gtk2_debool (m->gtktypes->data), + take_ownership ? + "_take_ownership" : ""); + g_strdown (set_func); + + out_printf (out, "\n\t%s (return_value, v_return);\n", + set_func); + + g_free (set_func); + } + out_printf (out, "}\n\n"); +} + + static void add_signal_prots(Method *m) @@ -704,41 +895,23 @@ add_signal_prots(Method *m) g_hash_table_insert(marsh, m, s); eq_signal_methods = g_list_prepend(eq_signal_methods, m); - + /* we know that we'll know all the gtktypes (so get_cast can't fail) */ out_printf(out, "\ntypedef %s (*___%s) (%s *, ", get_cast(m->gtktypes->data, FALSE), s, typebase); - if(strcmp(m->gtktypes->next->data, "NONE")!=0) { - for(li=m->gtktypes->next; li; li=g_list_next(li)) + if (strcmp (m->gtktypes->next->data, "NONE") != 0) { + for (li = m->gtktypes->next; li != NULL; li = li->next) out_printf(out, "%s, ", get_cast(li->data, FALSE)); } - out_printf(out, "gpointer);\n"); + out_printf (out, "gpointer);\n"); - out_printf(out, "\nstatic void\n" - "___marshal_%s (GtkObject * object,\n" - "\tGtkSignalFunc func,\n" - "\tgpointer func_data,\n" - "\tGtkArg * args)\n" - "{\n", s); - - if(strcmp(m->gtktypes->data, "NONE")==0) { - out_printf(out, "\t___%s rfunc;\n\n" - "\trfunc = (___%s)func;\n\n" - "\t(*rfunc)((%s *)object", s, s, typebase); - } else { - const char *retcast = get_cast(m->gtktypes->data, FALSE); - out_printf(out, - "\t___%s rfunc;\n\t" - "%s *retval;\n\n" - "\trfunc = (___%s)func;\n\n" - "\tretval = GTK_RETLOC_%s(args[%d]);\n\n" - "\t*retval = (*rfunc)((%s *)object", - s, retcast, s, (char *)m->gtktypes->data, - g_list_length(m->gtktypes)-1, typebase); - } - print_signal_marsal_args(m); + out_printf (out, "\n#ifdef G_OBJECT_CLASS\n"); + add_marshal_gtk2 (m, s); + out_printf (out, "#else /* ! G_OBJECT_CLASS */\n"); + add_marshal_gtk1 (m, s); + out_printf (out, "#endif /* G_OBJECT_CLASS */\n\n"); } static void @@ -791,37 +964,83 @@ add_get_type(void) { char *chunk_size = ((Class*)class)->chunk_size; - out_printf(out, "guint\n" - "%s_get_type (void)\n" - "{\n" - "\tstatic guint type = 0;\n\n" - "\tif (!type) {\n" - "\t\tstatic const GtkTypeInfo info = {\n" - "\t\t\t\"%s\",\n" - "\t\t\tsizeof (%s),\n" - "\t\t\tsizeof (%sClass),\n" - "\t\t\t(GtkClassInitFunc) %s_class_init,\n" - "\t\t\t(GtkObjectInitFunc) %s_init,\n" - "\t\t\t/* reserved_1 */ NULL,\n" - "\t\t\t/* reserved_2 */ NULL,\n" - "\t\t\t(GtkClassInitFunc) NULL\n" - "\t\t};\n\n" - "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n", - funcbase, typebase, typebase, typebase, - funcbase, funcbase, pfuncbase); + out_printf(out, + "GtkType\n" + "%s_get_type (void)\n" + "{\n" + "\tstatic GtkType type = 0;\n\n" + "\tif (type == 0) {\n" + "\t\tstatic const GtkTypeInfo info = {\n" + "\t\t\t\"%s\",\n" + "\t\t\tsizeof (%s),\n" + "\t\t\tsizeof (%sClass),\n" + "\t\t\t(GtkClassInitFunc) %s_class_init,\n" + "\t\t\t(GtkObjectInitFunc) %s_init,\n" + "\t\t\t/* reserved_1 */ NULL,\n" + "\t\t\t/* reserved_2 */ NULL,\n" + "\t\t\t(GtkClassInitFunc) NULL\n" + "\t\t};\n\n" + "\t\ttype = gtk_type_unique (%s_get_type(), &info);\n", + funcbase, typebase, typebase, typebase, + funcbase, funcbase, pfuncbase); + if(chunk_size) { + out_printf(out, + "#if %s > 0\n" + "\t\tgtk_type_set_chunk_alloc(type, %s);\n" + "#endif\n", + chunk_size, chunk_size); + } + out_printf(out, + "\t}\n\n" + "\treturn type;\n" + "}\n\n"); +} + +static void +add_bonobo_x_get_type (void) +{ + char *chunk_size = ((Class*)class)->chunk_size; + + out_printf(out, + "GtkType\n" + "%s_get_type (void)\n" + "{\n" + "\tstatic GtkType type = 0;\n\n" + "\tif (type == 0) {\n" + "\t\tstatic const GtkTypeInfo info = {\n" + "\t\t\t\"%s\",\n" + "\t\t\tsizeof (%s),\n" + "\t\t\tsizeof (%sClass),\n" + "\t\t\t(GtkClassInitFunc) %s_class_init,\n" + "\t\t\t(GtkObjectInitFunc) %s_init,\n" + "\t\t\t/* reserved_1 */ NULL,\n" + "\t\t\t/* reserved_2 */ NULL,\n" + "\t\t\t(GtkClassInitFunc) NULL\n" + "\t\t};\n\n" + "\t\ttype = bonobo_x_type_unique\n" + "\t\t\t(%s_get_type (),\n" + "\t\t\tPOA_%s__init, NULL,\n" + "\t\t\tGTK_STRUCT_OFFSET (%sClass, _epv),\n" + "\t\t\t&info);\n", + funcbase, typebase, typebase, typebase, + funcbase, funcbase, pfuncbase, + ((Class*)class)->bonobo_x_class, + typebase); if(chunk_size) { - out_printf(out, "#if %s > 0\n" - "\t\tgtk_type_set_chunk_alloc(type,%s);\n" - "#endif\n", - chunk_size, chunk_size); + out_printf(out, + "#if %s > 0\n" + "\t\tgtk_type_set_chunk_alloc(type, %s);\n" + "#endif\n", + chunk_size, chunk_size); } - out_printf(out,"\t}\n\n" - "\treturn type;\n" - "}\n\n"); + out_printf(out, + "\t}\n\n" + "\treturn type;\n" + "}\n\n"); } static void -add_overrides(Class *c, char *oname, gboolean did_base_obj) +add_overrides(Class *c, const char *oname, gboolean did_base_obj) { GList *li; GHashTable *done; @@ -1012,12 +1231,14 @@ add_signals(Class *c) } } - out_printf(out, "\tgtk_object_class_add_signals (gtk_object_class,\n" - "\t\tobject_signals, LAST_SIGNAL);\n\n"); + out_printf (out, "#ifndef G_OBJECT_CLASS\n"); + out_printf (out, "\tgtk_object_class_add_signals (gtk_object_class,\n" + "\t\tobject_signals, LAST_SIGNAL);\n"); + out_printf (out, "#endif /* ! G_OBJECT_CLASS */\n\n"); } static void -set_def_handlers(Class *c, char *oname) +set_def_handlers(Class *c, const char *oname) { GList *li; gboolean set_line = FALSE; @@ -1073,11 +1294,11 @@ set_def_handlers(Class *c, char *oname) } else { if(m->cbuf) out_printf(out, "\t%s->%s = ___real_%s_%s;\n", - oname, get_real_id(m->id), - funcbase, get_real_id(m->id)); + oname, get_real_id(m->id), + funcbase, get_real_id(m->id)); else out_printf(out, "\t%s->%s = NULL;\n", - oname, get_real_id(m->id)); + oname, get_real_id(m->id)); } } if(set_line) @@ -1326,6 +1547,36 @@ add_finalize(Class *c) "#undef __GOB_FUNCTION__\n\n"); } +static void +make_bonobo_x_epv (Class *c, const char *classname) +{ + GList *li; + gboolean added_line = FALSE; + + for (li = c->nodes; li != NULL; li = li->next) { + Node *n = li->data; + Method *m = (Method *)n; + if(n->type != METHOD_NODE || + m->method == OVERRIDE_METHOD) + continue; + + if (m->bonobo_x_func) { + if(m->line_no > 0) { + out_addline_infile(out, m->line_no); + added_line = TRUE; + } else if (m->line_no == 0 && + added_line) { + out_addline_outfile(out); + added_line = FALSE; + } + out_printf (out, "\t%s->_epv.%s = %s;\n", + classname, m->id, m->id); + } + } + if (added_line) + out_addline_outfile(out); +} + static void add_inits(Class *c) { @@ -1342,7 +1593,7 @@ add_inits(Class *c) if(m->method == INIT_METHOD) { if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n", "", " ", "\n", + print_method(out, "static ", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); if(m->line_no > 0) out_addline_outfile(out); @@ -1376,7 +1627,7 @@ add_inits(Class *c) if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n", "", " ", "\n", + print_method(out, "static ", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); if(m->line_no > 0) out_addline_outfile(out); @@ -1449,6 +1700,9 @@ add_inits(Class *c) if(get_arguments > 0 || set_arguments > 0) make_arguments(c); + if (c->bonobo_x_class != NULL) { + make_bonobo_x_epv (c, ((FuncArg *)m->args->data)->name); + } } else continue; @@ -1647,6 +1901,8 @@ print_preconditions(Method *m) static void print_method_body(Method *m, int pre) { + if (m->line_no > 0) + out_addline_outfile(out); out_printf(out, "{\n" "#define __GOB_FUNCTION__ \"%s::%s\"\n", ((Class *)class)->otype, @@ -1732,10 +1988,10 @@ put_method(Method *m) if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope == PRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "\n", + print_method(out, "static ", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "\n", + print_method(out, "", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); print_method_body(m, TRUE); /* the outfile line was added above */ @@ -1745,10 +2001,10 @@ put_method(Method *m) if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope == PRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "\n", + print_method(out, "static ", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "\n", + print_method(out, "", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); out_addline_outfile(out); out_printf(out, "{\n"); @@ -1787,7 +2043,7 @@ put_method(Method *m) break; if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n___real_", "", " ", "\n", + print_method(out, "static ", "\n___real_", "", " ", "", "\n", m, FALSE, FALSE, TRUE); print_method_body(m, FALSE); /* the outfile line was added above */ @@ -1796,10 +2052,10 @@ put_method(Method *m) if(m->line_no > 0) out_addline_infile(out, m->line_no); if(m->scope==PRIVATE_SCOPE) - print_method(out, "static ", "\n", "", " ", "\n", + print_method(out, "static ", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); else /* PUBLIC, PROTECTED */ - print_method(out, "", "\n", "", " ", "\n", + print_method(out, "", "\n", "", " ", "", "\n", m, FALSE, FALSE, TRUE); out_addline_outfile(out); out_printf(out, "{\n" @@ -1845,7 +2101,7 @@ put_method(Method *m) break; if(m->line_no > 0) out_addline_infile(out, m->line_no); - print_method(out, "static ", "\n___real_", "", " ", "\n", + print_method(out, "static ", "\n___real_", "", " ", "", "\n", m, FALSE, FALSE, TRUE); print_method_body(m, FALSE); /* the outfile line was added above */ @@ -1856,7 +2112,7 @@ put_method(Method *m) if(m->line_no > 0) out_addline_infile(out, m->line_no); s = g_strdup_printf("\n___%x_", (guint)m->unique_id); - print_method(out, "static ", s, "", " ", "\n", + print_method(out, "static ", s, "", " ", "", "\n", m, FALSE, FALSE, FALSE); g_free(s); out_addline_outfile(out); @@ -2139,6 +2395,7 @@ print_class_block(Class *c) out_printf(out, "#define SELF(x) %s(x)\n", macrobase); out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase); out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois); + out_printf(out, "#define TYPE_SELF %s\n", macrotype); out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n", macrobase); out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n", @@ -2248,6 +2505,13 @@ print_class_block(Class *c) if(n->type == METHOD_NODE) put_vs_method((Method *)n); } + /* If BonoboX type class put down the epv */ + if (c->bonobo_x_class != NULL) { + out_printf (outh, + "\t/* Bonobo object epv */\n" + "\tPOA_%s__epv _epv;\n", + c->bonobo_x_class); + } /* put class scope variables */ for(l = c->nodes; l != NULL; l = l->next) { Node *n = l->data; @@ -2274,7 +2538,15 @@ print_class_block(Class *c) " * Public methods\n" " */\n"); - out_printf(outh, "guint\t%s_get_type\t(void);\n", funcbase); + if ( ! overrode_get_type) { + out_printf(outh, "GtkType\t%s_get_type\t(void)", funcbase); + if ( ! no_gnu) { + out_printf(outh, " G_GNUC_CONST;\n"); + } else { + out_printf(outh, ";\n"); + } + } + for(l = c->nodes; l != NULL; l = l->next) { Node *n = l->data; if(n->type == METHOD_NODE) { @@ -2284,39 +2556,34 @@ print_class_block(Class *c) } } -/* this idea is less and less apealing to me */ -#if 0 - if(!no_signal_connect) { - if(signals>0) { - out_printf(outh, "\n/*\n" - " * Signal connection methods\n" - " */\n"); - } - - for(l=c->nodes;l;l=g_list_next(l)) { - Node *n = l->data; - if(n->type == METHOD_NODE) - put_signal_connect((Method *)n); + /* this idea is less and less apealing to me */ + if (signals > 0) { + out_printf (outh, "\n/*\n" + " * Signal connection wrapper macros\n" + " */\n"); + if( ! no_gnu) { + out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n"); + put_signal_macros (c, TRUE); + out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n"); + put_signal_macros (c, FALSE); + out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n"); + } else { + put_signal_macros (c, FALSE); } } -#endif - /* argument wrapping macros */ if(get_arguments > 0 || set_arguments > 0) { + out_printf(outh, "\n/*\n" + " * Argument wrapping macros\n" + " */\n"); if( ! no_gnu) { - out_printf(outh, "\n/*\n" - " * Argument wrapping macros\n" - " */\n"); out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n"); put_argument_gnu_wrappers(c); out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n"); put_argument_nongnu_wrappers(c); out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n"); } else { - out_printf(outh, "\n/*\n" - " * Argument wrapping macros\n" - " */\n"); put_argument_nongnu_wrappers(c); } } @@ -2331,18 +2598,21 @@ print_class_block(Class *c) add_enums(c); - add_get_type(); + if ( ! overrode_get_type) { + if (c->bonobo_x_class != NULL) + add_bonobo_x_get_type (); + else + add_get_type (); + } if(any_method_to_alias(c)) { - if(no_gnu) - make_method_nongnu_aliases(c); - else { - out_printf(out, "\n#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n"); + if( ! no_gnu) { + out_printf(out, "/* Short form macros */\n"); + out_printf(out, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n"); make_method_gnu_aliases(c); - out_printf(out, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n"); - make_method_nongnu_aliases(c); - out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n"); + out_printf(out, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n"); } + make_method_nongnu_aliases(c); } out_printf(out, "/* a macro for creating a new object of our type */\n"); @@ -2399,6 +2669,8 @@ print_file_comments(void) out_printf(out, "/* Generated by GOB (v%s) on %s" " (do not edit directly) */\n\n", VERSION, ctime(&curtime)); + + out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n"); } static void @@ -2582,6 +2854,12 @@ print_help(void) "\t--always-private-struct Always create a private pointer " "in\n" "\t the object structure\n" + "\t--m4 Preprocess source with m4. " + "Following args will\n" + "\t be passed to m4\n" + "\t--m4-dir Print directory that will be " + "searched for m4\n" + "\t files\n" "\t--no-write,-n Don't write output files, just " "check syntax\n" "\t--no-lines Don't print '#line' to output\n" @@ -2598,11 +2876,43 @@ parse_options(int argc, char *argv[]) int i; int got_file = FALSE; int no_opts = FALSE; + int m4_opts = FALSE; /* if we are just passing on args to m4 */ filename = NULL; for(i = 1 ; i < argc; i++) { - if(no_opts || + if(m4_opts) { + char *new_commandline; + g_assert(m4_commandline!=NULL); + + /* check whether this one looks like the filename */ + if((!strcmp(argv[i],"-") || argv[i][0] != '-') + && !got_file) { + const gchar *m4_flags=use_m4_clean?"":M4_FLAGS; + filename = argv[i]; + got_file = TRUE; + + /* insert flags before the filename */ + new_commandline=g_strconcat(m4_commandline, + " ", + m4_flags, + " ", + argv[i], + NULL); + } + + /* just an ordinary option */ + else + new_commandline=g_strconcat(m4_commandline, + " ", + argv[i], + NULL); + + /* free old commandline */ + g_free(m4_commandline); + m4_commandline=new_commandline; + + } else if(no_opts || argv[i][0] != '-') { /*must be a file*/ if(got_file) { @@ -2646,6 +2956,19 @@ parse_options(int argc, char *argv[]) no_kill_underscores = TRUE; } else if(strcmp(argv[i], "--always-private-struct")==0) { always_private_struct = TRUE; + } else if(strcmp(argv[i], "--m4-dir")==0) { + printf("%s\n",M4_INCLUDE_DIR); + exit(0); + } else if(strcmp(argv[i], "--m4")==0) { + use_m4 = TRUE; + use_m4_clean=FALSE; + m4_opts = TRUE; + m4_commandline=g_strdup(M4_COMMANDLINE); + } else if(strcmp(argv[i], "--m4-clean")==0) { + use_m4 = TRUE; + use_m4_clean=TRUE; + m4_opts = TRUE; + m4_commandline=g_strdup(M4_COMMANDLINE); } else if(strcmp(argv[i], "--")==0) { /*further arguments are files*/ no_opts = TRUE; @@ -2679,6 +3002,19 @@ parse_options(int argc, char *argv[]) } } } + +#if 0 + /* if we are using m4, and got no filename, append m4 flags now */ + if(!got_file && use_m4 && !use_m4_clean) { + char *new_commandline; + new_commandline=g_strconcat(m4_commandline, + " ", + M4_FLAGS, + NULL); + g_free(m4_commandline); + m4_commandline=new_commandline; + } +#endif } /* this is a somewhat ugly hack, but it appears to work */ @@ -2717,14 +3053,23 @@ main(int argc, char *argv[]) { parse_options(argc, argv); - if(filename) { + if(use_m4) { + yyin = popen(m4_commandline, "r"); + if(!yyin) { + fprintf(stderr, "Error: can't open pipe from '%s'\n", + m4_commandline); + exit(1); + } + } else if(filename) { yyin = fopen(filename, "r"); if(!yyin) { fprintf(stderr, "Error: can't open file '%s'\n", filename); exit(1); } - } else + } + + if(filename==NULL) filename = "stdin"; /* This is where parsing is done */ @@ -2732,6 +3077,11 @@ main(int argc, char *argv[]) if(yyparse() != 0) g_error("Parsing errors, quitting"); + /* close input file */ + if(use_m4) pclose(yyin); + else fclose(yyin); + yyin=stdin; + if( ! class) error_print(GOB_ERROR, 0, " no class defined"); @@ -2746,6 +3096,7 @@ main(int argc, char *argv[]) protecteds = count_protecteds((Class *)class); destructors = count_destructors((Class *)class); initializers = count_initializers((Class *)class); + overrode_get_type = find_get_type((Class *)class); make_bases(); make_inits((Class *)class);