X-Git-Url: https://git.draconx.ca/gitweb/gob-dx.git/blobdiff_plain/4f09fcd75bb0057d90c7431f7db57ca2c5a6c028..5cfe51ee2287165feb0cf006901bbbc2b961f3b8:/src/main.c diff --git a/src/main.c b/src/main.c index f601757..526408b 100644 --- a/src/main.c +++ b/src/main.c @@ -94,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; @@ -102,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 @@ -298,6 +306,16 @@ make_method_gnu_aliases(Class *c) 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)); } } } @@ -332,6 +350,13 @@ make_method_nongnu_aliases(Class *c) out_printf(out, " = %s_%s;\n", funcbase, get_real_id(m->id)); + /* 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; } } @@ -677,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; @@ -698,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) @@ -730,44 +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); - 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", - s, retcast, s, - (char *)m->gtktypes->data, - g_list_length(m->gtktypes) - (is_none ? 2 : 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 @@ -1087,8 +1231,10 @@ 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 @@ -2249,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", @@ -2707,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" @@ -2723,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) { @@ -2771,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; @@ -2804,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 */ @@ -2842,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 */ @@ -2857,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");