2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2009 George (Jiri) Lebl
6 * Author: George (Jiri) Lebl
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
34 #include "treefuncs.h"
42 char *filename = NULL;
52 extern GList *include_files;
54 extern GHashTable *gtk_doc_hash;
58 static char *outfilebase;
59 static char *outfilehbase;
60 static char *outfilephbase;
61 static char *funcbase;
62 static char *pfuncbase;
63 static char *macrobase;
65 static char *pmacrois;
66 static char *macrotype;
67 static char *pmacrotype;
68 static char *typebase;
69 static char *ptypebase;
71 char *output_dir = NULL;
75 static int signals = 0; /* number of signals */
76 static int set_properties = 0; /* number of named (set) properties */
77 static int get_properties = 0; /* number of named (get) properties */
78 static int overrides = 0; /* number of override methods */
79 static int privates = 0; /* number of private data members */
80 static int protecteds = 0; /* number of protected methods */
81 static int unreftors = 0; /* number of variable unreffing destructors */
82 static int destructors = 0; /* number of variable non-unreffing destructors */
83 static int initializers = 0; /* number of variable initializers */
84 static int glade_widgets = 0; /* number of glade widgets */
85 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
87 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
88 and need the REALLY UGLY HACK to
91 /* the special variable types we need to define */
92 static gboolean special_array[SPECIAL_LAST] = {0};
93 static gboolean any_special = FALSE;
95 static gboolean need_constructor = FALSE;
96 static Method * user_constructor = NULL;
98 static gboolean need_dispose = FALSE;
99 static Method * dispose_handler = NULL;
100 static Method * user_dispose_method = NULL;
102 static gboolean need_finalize = FALSE;
103 static Method * finalize_handler = NULL;
104 static Method * user_finalize_method = NULL;
110 gboolean no_touch = FALSE;
111 gboolean no_touch_headers = FALSE;
112 gboolean for_cpp = FALSE;
113 gboolean no_gnu = FALSE;
114 gboolean exit_on_warn = FALSE;
115 gboolean exit_on_error = TRUE;
116 gboolean got_error = FALSE;
117 gint private_header = PRIVATE_HEADER_ONDEMAND;
118 gboolean no_extern_c = FALSE;
119 gboolean no_write = FALSE;
120 gboolean no_lines = FALSE;
121 gboolean no_self_alias = FALSE;
122 gboolean always_private_struct = FALSE;
125 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
126 gboolean use_m4_clean = FALSE; /* preprocess sources with m4, no m4 flags */
127 char *m4_commandline = NULL;
128 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
129 #define M4_BASE_FILENAME "gobm4.m4"
130 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
131 #define M4_COMMANDLINE "m4"
133 int method_unique_id = 1;
138 filebase = replace_sep (((Class *)class)->otype, file_sep);
139 gob_strdown (filebase);
141 if (output_dir != NULL &&
142 output_dir[0] != '\0') {
143 fullfilebase = g_build_filename (output_dir, filebase, NULL);
145 fullfilebase = g_strdup (filebase);
148 funcbase = replace_sep (((Class *)class)->otype, '_');
149 gob_strdown (funcbase);
151 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
152 gob_strdown (pfuncbase);
154 macrobase = replace_sep (((Class *)class)->otype, '_');
155 gob_strup (macrobase);
157 macrois = make_pre_macro (((Class *)class)->otype, "IS");
158 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
160 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
161 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
163 typebase = remove_sep (((Class *)class)->otype);
165 ptypebase = remove_sep (((Class *)class)->ptype);
169 get_gtk_doc (const char *id)
176 val = g_hash_table_lookup(gtk_doc_hash, id);
178 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
180 val = g_hash_table_lookup(gtk_doc_hash, id);
182 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
188 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
192 s = get_type(t, postfix_to_stars);
193 out_printf(fp, "%s", s);
199 print_method (FILE *fp,
200 const char *typeprefix,
201 const char *nameprefix,
202 const char *subnameprefix,
203 const char *namepostfix,
204 const char *afterargs,
207 gboolean print_funcattrs,
208 gboolean one_arg_per_line,
209 gboolean no_funcbase,
210 gboolean kill_underscore,
211 gboolean first_unused,
217 out_printf(fp, "%s", typeprefix);
218 print_type(fp, m->mtype, TRUE);
223 out_printf(fp, "%s%s%s%s(",
224 nameprefix, subnameprefix, id, namepostfix);
226 out_printf(fp, "%s%s_%s%s%s(",
227 nameprefix, funcbase, subnameprefix, id,
231 for(li=m->args; li; li=g_list_next(li)) {
232 FuncArg *arg = li->data;
233 const char *unused = "";
236 ! for_cpp && /* g++ has a cow with this */
239 unused = " G_GNUC_UNUSED";
242 print_type(fp, arg->atype, FALSE);
244 out_printf (fp, "___fake___");
246 out_printf(fp, "%s%s%s,%s", arg->name,
247 arg->atype->postfix ?
248 arg->atype->postfix : "",
250 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
252 out_printf(fp, "%s%s%s", arg->name,
253 arg->atype->postfix ?
254 arg->atype->postfix : "",
258 out_printf(fp, ",%s...",
259 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
261 out_printf(fp, "void");
263 /* Slightly icky: sometimes we are called st m->funcattrs
264 hasn't been set, but if so it should be NULL since its been
266 if(print_funcattrs && m->funcattrs != NULL
267 && strlen(m->funcattrs) > 0) {
268 /* To keep the output neat, we trim off the trailing '\n'
269 from the end of funcattrs for a moment. */
270 size_t funcattrs_len = strlen(m->funcattrs);
271 gboolean funcattrs_chomped = FALSE;
272 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
273 m->funcattrs[funcattrs_len - 1] = '\0';
274 funcattrs_chomped = TRUE;
276 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
277 /* Put it back like it was (though it shouldn't matter). */
278 if (funcattrs_chomped) {
279 (m->funcattrs)[funcattrs_len - 1] = '\n';
283 out_printf(fp, "%s)%s", afterargs, postfix);
288 any_method_to_alias(Class *c)
292 for(li=c->nodes;li;li=g_list_next(li)) {
293 Node *node = li->data;
294 if(node->type == METHOD_NODE) {
295 Method *m = (Method *)node;
297 if(m->method == INIT_METHOD ||
298 m->method == CLASS_INIT_METHOD ||
299 m->method == CONSTRUCTOR_METHOD ||
300 m->method == DISPOSE_METHOD ||
301 m->method == FINALIZE_METHOD ||
302 m->method == OVERRIDE_METHOD)
313 make_method_aliases (Class *c)
317 for(li = c->nodes; li != NULL; li = li->next) {
318 Node *node = li->data;
319 if(node->type == METHOD_NODE) {
320 Method *m = (Method *)node;
322 if(m->method == INIT_METHOD ||
323 m->method == CLASS_INIT_METHOD ||
324 m->method == CONSTRUCTOR_METHOD ||
325 m->method == DISPOSE_METHOD ||
326 m->method == FINALIZE_METHOD ||
327 m->method == OVERRIDE_METHOD)
330 out_printf (out, "#define self_%s %s_%s\n",
339 add_bad_hack_to_avoid_unused_warnings(const Class *c)
343 /* if we haven't had any methods, just return */
348 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
350 "/*REALLY BAD HACK\n"
351 " This is to avoid unused warnings if you don't call\n"
352 " some method. I need to find a better way to do\n"
353 " this, not needed in GCC since we use some gcc\n"
354 " extentions to make saner, faster code */\n"
356 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
358 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
359 for(li=c->nodes;li;li=g_list_next(li)) {
360 Node *node = li->data;
361 if(node->type == METHOD_NODE) {
362 Method *m = (Method *)node;
364 if(m->method == INIT_METHOD ||
365 m->method == CLASS_INIT_METHOD ||
366 m->method == CONSTRUCTOR_METHOD ||
367 m->method == DISPOSE_METHOD ||
368 m->method == FINALIZE_METHOD ||
369 m->method == OVERRIDE_METHOD)
372 /* in C++ mode we don't alias new */
373 if(for_cpp && strcmp(m->id, "new")==0)
376 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
379 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
382 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
384 out_printf(out, "}\n\n");
388 put_variable(const Variable *v, FILE *fp)
390 out_printf(fp, "\t");
391 print_type(fp, v->vtype, FALSE);
392 out_printf(fp, "%s%s;", v->id,
394 v->vtype->postfix:"");
395 if(v->scope == PROTECTED_SCOPE)
396 out_printf(fp, " /* protected */");
397 out_printf(fp, "\n");
401 put_vs_method(const Method *m)
403 if(m->method != SIGNAL_LAST_METHOD &&
404 m->method != SIGNAL_FIRST_METHOD &&
405 m->method != VIRTUAL_METHOD)
408 /* if a signal mark it as such */
409 if(m->method != VIRTUAL_METHOD)
410 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
411 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
413 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
414 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
419 put_pub_method(const Method *m)
421 if(m->scope != PUBLIC_SCOPE)
424 out_addline_infile(outh, m->line_no);
425 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
426 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
427 out_addline_outfile(outh);
431 put_signal_macro (const Method *m, gboolean gnu)
433 if(m->method != SIGNAL_LAST_METHOD &&
434 m->method != SIGNAL_FIRST_METHOD)
439 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
440 "g_signal_connect(%s(object),\"%s\","
441 "(GCallback)(func),(data))\n",
442 funcbase, m->id, macrobase, m->id);
445 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
446 "g_signal_connect_after(%s(object),\"%s\","
447 "(GCallback)(func),(data))\n",
448 funcbase, m->id, macrobase, m->id);
451 out_printf (outh, "#define %s_connect_data__%s"
452 "(object,func,data,destroy_data,flags)\t"
453 "g_signal_connect_data(%s(object),\"%s\","
454 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
455 funcbase, m->id, macrobase, m->id);
458 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
460 "%s(__extension__ ({%s *___object = (object); ___object; })),"
462 "(GCallback) __extension__ ({",
463 funcbase, m->id, macrobase, typebase, m->id);
464 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
465 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
466 out_printf (outh, "___%s; }), (data))\n", m->id);
469 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
470 "g_signal_connect_after("
471 "%s(__extension__ ({%s *___object = (object); ___object; })),"
473 "(GCallback) __extension__ ({",
474 funcbase, m->id, macrobase, typebase, m->id);
475 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
476 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
477 out_printf (outh, "___%s; }), (data))\n", m->id);
480 out_printf (outh, "#define %s_connect_data__%s"
481 "(object,func,data,destroy_data,flags)\t"
482 "g_signal_connect_data("
483 "%s(__extension__ ({%s *___object = (object); ___object; })),"
485 "(GCallback) __extension__ ({",
486 funcbase, m->id, macrobase, typebase, m->id);
487 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
488 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
489 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
494 put_signal_macros (const Class *c, gboolean gnu)
501 for (li = c->nodes; li != NULL; li = li->next) {
502 const Node *n = li->data;
503 if (n->type == METHOD_NODE)
504 put_signal_macro ((Method *)n, gnu);
509 put_local_signal_macro (const Method *m)
511 if(m->method != SIGNAL_LAST_METHOD &&
512 m->method != SIGNAL_FIRST_METHOD)
516 out_printf (out, "#define self_connect__%s(object,func,data)\t"
517 "%s_connect__%s((object),(func),(data))\n",
518 m->id, funcbase, m->id);
521 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
522 "%s_connect_after__%s((object),(func),(data))\n",
523 m->id, funcbase, m->id);
526 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
527 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
528 m->id, funcbase, m->id);
532 put_local_signal_macros (const Class *c)
539 for (li = c->nodes; li != NULL; li = li->next) {
540 const Node *n = li->data;
541 if (n->type == METHOD_NODE)
542 put_local_signal_macro ((Method *)n);
548 put_prot_method(const Method *m)
552 if(m->scope != PROTECTED_SCOPE)
555 f = outph ? outph : out;
557 out_addline_infile(f, m->line_no);
558 print_method(f, "", "\t", "", "\t", "", ";\n",
559 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
560 out_addline_outfile(f);
564 put_priv_method_prot(const Method *m)
566 if(m->method == SIGNAL_LAST_METHOD ||
567 m->method == SIGNAL_FIRST_METHOD ||
568 m->method == VIRTUAL_METHOD) {
571 "static ", "___real_", "", " ", "", ";\n",
572 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
574 /* no else, here, it might still have a private prototype, it's not
577 if((m->method == OVERRIDE_METHOD &&
580 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
581 out_addline_infile(out, m->line_no);
582 print_method(out, "static ", s, "", " ", "",
583 no_gnu?";\n":" G_GNUC_UNUSED;\n",
584 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
585 out_addline_outfile(out);
587 } else if(m->scope == PRIVATE_SCOPE ||
588 m->method == INIT_METHOD ||
589 m->method == CLASS_INIT_METHOD ||
590 m->method == CONSTRUCTOR_METHOD ||
591 m->method == DISPOSE_METHOD ||
592 m->method == FINALIZE_METHOD) {
593 out_addline_infile(out, m->line_no);
594 print_method(out, "static ", "", "", " ", "",
595 no_gnu?";\n":" G_GNUC_UNUSED;\n",
596 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
597 out_addline_outfile(out);
602 make_func_arg (const char *typename, gboolean is_class, const char *name)
609 tn = g_strconcat (typename, ":Class", NULL);
611 tn = g_strdup (typename);
613 type = node_new (TYPE_NODE,
617 node = node_new (FUNCARG_NODE,
618 "atype:steal", (Type *)type,
621 return g_list_prepend (NULL, node);
625 make_inits(Class *cl)
627 int got_class_init = FALSE;
628 int got_init = FALSE;
631 for(li=cl->nodes;li;li=g_list_next(li)) {
633 if(n->type == METHOD_NODE) {
634 Method *m = (Method *)n;
635 if(m->method == INIT_METHOD) {
637 error_print(GOB_ERROR, m->line_no, "init defined more then once");
639 } else if(m->method == CLASS_INIT_METHOD) {
641 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
642 got_class_init = TRUE;
646 if(!got_class_init) {
647 Type *type = (Type *)node_new (TYPE_NODE,
650 node = node_new (METHOD_NODE,
652 "method", CLASS_INIT_METHOD,
655 "args:steal", make_func_arg (cl->otype,
658 "unique_id", method_unique_id++,
660 cl->nodes = g_list_prepend(cl->nodes, node);
663 Type *type = (Type *)node_new (TYPE_NODE,
666 node = node_new (METHOD_NODE,
668 "method", INIT_METHOD,
671 "args:steal", make_func_arg (cl->otype,
672 FALSE /* is_class */,
674 "unique_id", method_unique_id++,
676 cl->nodes = g_list_prepend(cl->nodes, node);
681 find_method(const Class *cl, int method, const char *id)
685 for(li=cl->nodes;li;li=g_list_next(li)) {
687 if(n->type == METHOD_NODE) {
688 Method *m = (Method *)n;
689 if (m->method == method
690 && (id == NULL || strcmp(m->id, id)==0))
699 find_constructor(const Class *cl)
701 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
705 find_dispose(const Class *cl)
707 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
708 if (dispose_handler != NULL) {
709 if(strcmp(dispose_handler->otype, "G:Object") != 0)
710 error_print(GOB_ERROR, dispose_handler->line_no,
711 "dispose method override "
712 "of class other then "
714 if(g_list_length(dispose_handler->args) != 1)
715 error_print(GOB_ERROR, dispose_handler->line_no,
716 "dispose method override "
717 "with more then one "
721 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
725 find_finalize(const Class *cl)
727 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
728 if (finalize_handler != NULL) {
729 if(strcmp(finalize_handler->otype, "G:Object") != 0)
730 error_print(GOB_ERROR, finalize_handler->line_no,
731 "finalize method override "
732 "of class other then "
734 if(g_list_length(finalize_handler->args) != 1)
735 error_print(GOB_ERROR, finalize_handler->line_no,
736 "finalize method override "
737 "with more then one "
741 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
745 /* hash of method -> name of signal prototype */
746 static GHashTable *marsh = NULL;
748 /* list of methods with different signal prototypes,
749 we check this list if we can use a signal prototype of a
750 previous signal method, there are only uniques here */
751 static GList *eq_signal_methods = NULL;
753 /* compare a list of strings */
755 is_list_equal(const GList *a, const GList *b)
757 for(;a && b; a=a->next, b=b->next) {
758 if(strcmp(a->data, b->data)!=0) {
762 /* the the lists were different length */
769 find_same_type_signal(const Method *m)
772 for(li=eq_signal_methods;li;li=li->next) {
773 Method *mm = li->data;
774 if(is_list_equal(mm->gtktypes, m->gtktypes))
781 print_signal_marsal_args (const Method *m)
783 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
786 for (i = 0, li = m->gtktypes->next;
788 i++, li = li->next) {
791 if (strcmp (li->data, "UNICHAR") == 0)
792 /* hack because glib is braindamaged */
793 get_func = g_strdup ("g_value_get_uint");
794 else if (strncmp(li->data, "BOXED_", 6) == 0)
795 get_func = g_strdup ("g_value_get_boxed");
797 get_func = g_strdup_printf
798 ("g_value_get_%s", (char *)li->data);
800 gob_strdown (get_func);
801 out_printf (out, ",\n\t\t(%s) "
802 "%s (param_values + %d)",
803 get_cast (li->data, FALSE),
808 out_printf (out, ",\n\t\tdata2);\n");
813 add_signal_prots(Method *m)
819 gboolean ret_none = FALSE;
820 gboolean arglist_none = FALSE;
822 const char *unused = "";
824 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
825 unused = " G_GNUC_UNUSED";
828 if (m->method != SIGNAL_LAST_METHOD &&
829 m->method != SIGNAL_FIRST_METHOD)
833 marsh = g_hash_table_new(NULL, NULL);
835 g_assert (m->gtktypes->next != NULL);
837 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
838 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
840 if (ret_none && arglist_none)
843 /* if we already did a signal prototype just use that */
844 mm = find_same_type_signal (m);
846 s = g_hash_table_lookup (marsh, mm);
847 g_hash_table_insert (marsh, m, s);
854 retcast = get_cast (m->gtktypes->data, FALSE);
856 s = g_strdup_printf("Sig%d", sig++);
858 g_hash_table_insert(marsh, m, s);
859 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
861 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
862 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
863 get_cast(m->gtktypes->data, FALSE), s, typebase);
865 if ( ! arglist_none) {
866 for (li = m->gtktypes->next; li != NULL; li = li->next)
867 out_printf (out, "%s, ", get_cast (li->data, FALSE));
869 out_printf (out, "gpointer);\n");
871 out_printf (out, "\nstatic void\n"
872 "___marshal_%s (GClosure *closure,\n"
873 "\tGValue *return_value%s,\n"
874 "\tguint n_param_values,\n"
875 "\tconst GValue *param_values,\n"
876 "\tgpointer invocation_hint%s,\n"
877 "\tgpointer marshal_data)\n"
884 out_printf (out, "\t%s v_return;\n", retcast);
886 out_printf (out, "\tregister ___%s callback;\n"
887 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
888 "\tregister gpointer data1, data2;\n\n",
891 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
892 arglist_none ? 1 : g_list_length (m->gtktypes));
895 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
896 "\t\tdata1 = closure->data;\n"
897 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
899 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
900 "\t\tdata2 = closure->data;\n"
903 out_printf (out, "\tcallback = (___%s) "
904 "(marshal_data != NULL ? marshal_data : cc->callback);"
908 out_printf (out, "\tcallback ((%s *)data1", typebase);
910 out_printf (out, "\tv_return = callback ((%s *)data1",
914 print_signal_marsal_args (m);
917 /* FIXME: This code is so fucking ugly it hurts */
918 gboolean take_ownership =
919 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
920 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
924 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
925 /* hack because glib is braindamaged */
926 set_func = g_strdup ("g_value_set_uint");
928 set_func = g_strdup_printf ("g_value_set_%s%s",
929 (char *)m->gtktypes->data,
931 "_take_ownership" : "");
932 gob_strdown (set_func);
934 out_printf (out, "\n\t%s (return_value, v_return);\n",
939 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
941 out_printf (out, "\n\treturn_value = NULL;\n");
942 out_printf (out, "\tinvocation_hint = NULL;\n");
945 out_printf (out, "}\n\n");
952 out_printf(out, "\n");
954 out_printf(out, "enum {\n");
955 for(li=c->nodes;li;li=g_list_next(li)) {
957 if(n->type == METHOD_NODE) {
958 Method *m = (Method *)n;
959 if(m->method == SIGNAL_LAST_METHOD ||
960 m->method == SIGNAL_FIRST_METHOD) {
961 char *s = g_strdup(m->id);
963 out_printf(out, "\t%s_SIGNAL,\n", s);
968 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
970 if (set_properties > 0 ||
971 get_properties > 0) {
972 out_printf(out, "enum {\n\tPROP_0");
973 for(li=c->nodes;li;li=g_list_next(li)) {
975 if (n->type == PROPERTY_NODE) {
976 Property *p = (Property *)n;
977 char *s = g_strdup (p->name);
979 out_printf (out, ",\n\tPROP_%s", s);
981 } else if (n->type == ARGUMENT_NODE) {
982 Argument *a = (Argument *)n;
983 char *s = g_strdup(a->name);
985 out_printf(out, ",\n\tPROP_%s", s);
989 out_printf(out, "\n};\n\n");
994 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
996 out_printf(out, "/* pointer to the class of our parent */\n");
997 out_printf(out, "static %sClass *parent_class = NULL;\n\n", ptypebase);
1001 add_interface_methods (Class *c, const char *interface)
1004 gboolean added_line = FALSE;
1006 for (li = c->nodes; li != NULL; li = li->next) {
1008 Method *m = (Method *)n;
1009 if (n->type != METHOD_NODE ||
1010 m->method == OVERRIDE_METHOD ||
1011 m->interface == NULL ||
1012 strcmp (m->interface, interface) != 0)
1015 if (m->line_no > 0) {
1016 out_addline_infile (out, m->line_no);
1018 } else if (m->line_no == 0 &&
1020 out_addline_outfile (out);
1023 out_printf (out, "\tiface->%s = self_%s;\n",
1027 out_addline_outfile (out);
1031 add_interface_inits (Class *c)
1035 if (c->interfaces == NULL)
1038 out_printf(out, "\n");
1040 for (li = c->interfaces; li != NULL; li = li->next) {
1041 const char *interface = li->data;
1043 char *name = replace_sep (interface, '_');
1044 char *type = remove_sep (interface);
1046 /* EEEK! evil, we should have some sort of option
1047 * to force this for arbitrary interfaces, since
1048 * some are Class and some are Iface. Glib is shite
1049 * in consistency. */
1050 if (strcmp (type, "GtkEditable") == 0 ||
1051 strcmp (type, "GTypePlugin") == 0)
1054 /* We'll assume Iface is the standard ending */
1057 out_printf (out, "\nstatic void\n"
1058 "___%s_init (%s%s *iface)\n"
1062 add_interface_methods (c, interface);
1064 out_printf (out, "}\n\n");
1072 add_interface_infos (void)
1075 for (li = ((Class *)class)->interfaces;
1078 char *name = replace_sep (li->data, '_');
1080 "\t\tstatic const GInterfaceInfo %s_info = {\n"
1081 "\t\t\t(GInterfaceInitFunc) ___%s_init,\n"
1091 add_interfaces (void)
1094 for (li = ((Class *)class)->interfaces;
1097 char *name = replace_sep (li->data, '_');
1098 char *type = make_pre_macro (li->data, "TYPE");
1101 "\t\tg_type_add_interface_static (type,\n"
1103 "\t\t\t&%s_info);\n",
1115 /*char *chunk_size = ((Class*)class)->chunk_size;*/
1119 "%s_get_type (void)\n"
1121 "\tstatic GType type = 0;\n\n"
1122 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1123 "\t\tstatic const GTypeInfo info = {\n"
1124 "\t\t\tsizeof (%sClass),\n"
1125 "\t\t\t(GBaseInitFunc) NULL,\n"
1126 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1127 "\t\t\t(GClassInitFunc) %s_class_init,\n"
1128 "\t\t\t(GClassFinalizeFunc) NULL,\n"
1129 "\t\t\tNULL /* class_data */,\n"
1130 "\t\t\tsizeof (%s),\n"
1131 "\t\t\t%d /* n_preallocs */,\n"
1132 "\t\t\t(GInstanceInitFunc) %s_init,\n"
1135 funcbase, typebase, funcbase, typebase, prealloc, funcbase);
1137 add_interface_infos ();
1140 "\t\ttype = g_type_register_static (%s, \"%s\", &info, (GTypeFlags)%s);\n",
1141 pmacrotype, typebase, ((Class *)class)->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1149 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1151 chunk_size, chunk_size);
1161 add_bonobo_object_get_type (void)
1163 /* char *chunk_size = ((Class*)class)->chunk_size; */
1164 /* _vicious_ spanks seth with a rusty nail
1166 "\n#warning \"Bonobo isn't fully ported to glib 2.0 and "
1167 "gob2 doesn't officially support it yet. It'd be safer "
1168 "and a lot more fun to blow goats.\"\n");
1173 "%s_get_type (void)\n" /* 1 */
1175 "\tstatic GType type = 0;\n\n"
1176 "\tif ___GOB_UNLIKELY(type == 0) {\n"
1177 "\t\tstatic const GTypeInfo info = {\n"
1178 "\t\t\tsizeof (%sClass),\n" /* 2 */
1179 "\t\t\t(GBaseInitFunc) NULL,\n"
1180 "\t\t\t(GBaseFinalizeFunc) NULL,\n"
1181 "\t\t\t(GClassInitFunc) %s_class_init,\n" /* 3 */
1182 "\t\t\tNULL, /* class_finalize */\n"
1183 "\t\t\tNULL, /* class_data */\n"
1184 "\t\t\tsizeof (%s),\n" /* 4 */
1185 "\t\t\t0, /* n_preallocs */\n"
1186 "\t\t\t(GInstanceInitFunc) %s_init,\n" /* 5 */
1195 add_interface_infos ();
1198 "\t\ttype = bonobo_type_unique (\n"
1199 "\t\t\tBONOBO_OBJECT_TYPE,\n"
1200 "\t\t\tPOA_%s__init, NULL,\n" /* 1 */
1201 "\t\t\tG_STRUCT_OFFSET (%sClass, _epv),\n" /* 2 */
1202 "\t\t\t&info, \"%s\");\n", /* 3 */
1203 ((Class*)class)->bonobo_object_class /* 1 */,
1212 "\t\tgtk_type_set_chunk_alloc(type, %s);\n"
1214 chunk_size, chunk_size);
1223 add_overrides(Class *c, const char *oname,
1224 gboolean did_base_obj)
1230 done = g_hash_table_new (g_str_hash, g_str_equal);
1232 s = g_strdup ("GObject");
1233 g_hash_table_insert (done, s, s);
1235 for (li = c->nodes; li != NULL; li = li->next) {
1238 Method *m = (Method *)n;
1239 if(n->type != METHOD_NODE ||
1240 m->method != OVERRIDE_METHOD)
1243 s = remove_sep(m->otype);
1245 if(g_hash_table_lookup(done, s)) {
1249 g_hash_table_insert(done, s, s);
1251 f = replace_sep(m->otype, '_');
1254 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1259 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1260 g_hash_table_destroy (done);
1264 make_run_signal_flags(Method *m, gboolean last)
1279 gs = g_string_new(NULL);
1282 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1284 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1286 if(m->scope == PUBLIC_SCOPE)
1287 g_string_append(gs, " | G_SIGNAL_ACTION");
1289 for(li = m->flags; li; li = li->next) {
1290 char *flag = li->data;
1292 for(i=0;flags[i];i++) {
1293 if(strcmp(flags[i], flag)==0)
1296 /* if we haven't found it in our list */
1298 error_printf(GOB_WARN, m->line_no,
1299 "Unknown flag '%s' used, "
1300 "perhaps it was misspelled",
1303 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1307 char *ret = gs->str;
1308 g_string_free(gs, FALSE);
1315 add_signals(Class *c)
1319 out_printf(out, "\n");
1320 for(li=c->nodes;li;li=g_list_next(li)) {
1322 char *mar, *sig, *flags;
1323 gboolean is_none, last = FALSE;
1324 Method *m = (Method *)n;
1326 if(n->type != METHOD_NODE ||
1327 (m->method != SIGNAL_FIRST_METHOD &&
1328 m->method != SIGNAL_LAST_METHOD))
1331 if(m->method == SIGNAL_FIRST_METHOD)
1336 if(g_hash_table_lookup(marsh, m))
1337 mar = g_strconcat("___marshal_",
1338 (char *)g_hash_table_lookup(marsh, m),
1341 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1343 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1345 sig = g_strdup (m->id);
1347 flags = make_run_signal_flags (m, last);
1348 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1349 "\t\tg_signal_new (\"%s\",\n"
1350 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1351 "\t\t\t(GSignalFlags)(%s),\n"
1352 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1353 "\t\t\tNULL, NULL,\n"
1355 "\t\t\tG_TYPE_%s, %d",
1358 typebase, m->id, mar,
1359 (char *)m->gtktypes->data,
1360 is_none ? 0 : g_list_length(m->gtktypes->next));
1368 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1369 char *str = l->data;
1370 if (strncmp (str, "BOXED_", 6) == 0)
1371 t = g_strdup (&(str[6]));
1373 t = g_strconcat ("G_TYPE_", str, NULL);
1374 out_printf (out, ",\n\t\t\t%s", t);
1379 out_printf(out, ");\n");
1381 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1384 out_printf(out, "\tif ___GOB_UNLIKELY(");
1385 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1386 out_printf(out, "sizeof(");
1387 print_type(out, m->mtype, FALSE);
1388 out_printf(out, "%s",
1390 m->mtype->postfix : "");
1391 out_printf(out, ") != sizeof(%s) || ",
1392 get_cast(m->gtktypes->data, FALSE));
1395 for(al = m->args->next, gl = m->gtktypes->next;
1396 al != NULL && gl != NULL;
1397 al = al->next, gl = gl->next) {
1398 FuncArg *arg = al->data;
1399 char *gtkarg = gl->data;
1401 out_printf(out, "sizeof(");
1402 print_type(out, arg->atype, FALSE);
1403 out_printf(out, "%s",
1404 arg->atype->postfix ?
1405 arg->atype->postfix : "");
1406 out_printf(out, ") != sizeof(%s) || ",
1407 get_cast(gtkarg, FALSE));
1411 "parent_class == NULL /* avoid warning */");
1413 out_printf(out, ") {\n"
1414 "\t\tg_error(\"%s line %d: Type mismatch "
1415 "of \\\"%s\\\" signal signature\");\n"
1417 filename, m->line_no, m->id);
1424 set_def_handlers(Class *c, const char *oname)
1427 gboolean set_line = FALSE;
1429 out_printf(out, "\n");
1430 for(li = c->nodes; li; li = g_list_next(li)) {
1432 Method *m = (Method *)n;
1434 if(n->type != METHOD_NODE ||
1435 (m->method != SIGNAL_FIRST_METHOD &&
1436 m->method != SIGNAL_LAST_METHOD &&
1437 m->method != VIRTUAL_METHOD &&
1438 m->method != OVERRIDE_METHOD))
1441 if(m->line_no > 0 && m->cbuf) {
1442 out_addline_infile(out, m->line_no);
1444 } else if(set_line) {
1445 out_addline_outfile(out);
1450 if (m->method == OVERRIDE_METHOD) {
1452 s = replace_sep (m->otype, '_');
1456 dispose_handler != NULL &&
1457 strcmp (m->id, "dispose") == 0)
1458 out_printf (out, "\tg_object_class->dispose "
1460 else if (need_finalize &&
1462 strcmp(m->id, "finalize") == 0)
1464 "\tg_object_class->finalize = ___finalize;\n");
1465 else if (m->cbuf != NULL)
1467 "\t%s_class->%s = ___%x_%s_%s;\n",
1468 s, m->id, (guint)m->unique_id,
1471 out_printf(out, "\t%s_class->%s = NULL;\n",
1475 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1479 out_printf(out, "\t%s->%s = NULL;\n",
1484 out_addline_outfile(out);
1488 make_argument (Argument *a)
1493 char *argflags[] = {
1501 flags = g_string_new ("(GParamFlags)(");
1503 if(a->get && a->set)
1504 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1506 g_string_append (flags, "G_PARAM_READABLE");
1508 g_string_append (flags, "G_PARAM_WRITABLE");
1510 g_assert(a->get || a->set);
1512 for (l = a->flags; l != NULL; l = l->next) {
1513 char *flag = l->data;
1515 if(strcmp (flag, "READABLE") == 0 ||
1516 strcmp (flag, "WRITABLE") == 0) {
1517 error_print(GOB_WARN, a->line_no,
1519 "WRITABLE argument flags are "
1520 "set automatically");
1523 for(i = 0; argflags[i]; i++) {
1524 if(strcmp(argflags[i], flag)==0)
1527 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1530 g_string_append (flags, ")");
1532 s = g_strdup(a->name);
1534 if (!strcmp (a->gtktype, "ENUM"))
1535 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1536 "\t\tG_TYPE_ENUM, 0,\n"
1538 a->name, flags->str);
1539 if (!strcmp (a->gtktype, "FLAGS"))
1540 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1541 "\t\tG_TYPE_FLAGS, 0,\n"
1543 a->name, flags->str);
1544 else if (!strcmp (a->gtktype, "OBJECT"))
1545 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1546 "\t\tG_TYPE_OBJECT,\n"
1548 a->name, flags->str);
1549 else if (!strcmp (a->gtktype, "STRING"))
1550 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1553 a->name, flags->str);
1554 else if (!strcmp (a->gtktype, "INT"))
1555 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1556 "\t\tG_MININT, G_MAXINT,\n"
1559 a->name, flags->str);
1560 else if (!strcmp (a->gtktype, "UINT"))
1561 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1562 "\t\t0, G_MAXUINT,\n"
1565 a->name, flags->str);
1566 else if (!strcmp (a->gtktype, "INT"))
1567 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1568 "\t\tG_MININT, G_MAXINT,\n"
1571 a->name, flags->str);
1572 else if (!strcmp (a->gtktype, "CHAR"))
1573 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1577 a->name, flags->str);
1578 else if (!strcmp (a->gtktype, "UCHAR"))
1579 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1583 a->name, flags->str);
1584 else if (!strcmp (a->gtktype, "BOOL") ||
1585 !strcmp (a->gtktype, "BOOLEAN"))
1586 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1589 a->name, flags->str);
1590 else if (!strcmp (a->gtktype, "LONG"))
1591 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1592 "\t\tG_MINLONG, G_MAXLONG,\n"
1595 a->name, flags->str);
1596 else if (!strcmp (a->gtktype, "ULONG"))
1597 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1598 "\t\t0, G_MAXULONG,\n"
1601 a->name, flags->str);
1602 else if (!strcmp (a->gtktype, "INT64"))
1603 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1604 "\t\tG_MININT64, G_MAXINT64,\n"
1607 a->name, flags->str);
1608 else if (!strcmp (a->gtktype, "UINT64"))
1609 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1610 "\t\t0, G_MAXUINT64,\n"
1613 a->name, flags->str);
1614 else if (!strcmp (a->gtktype, "FLOAT"))
1615 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1616 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1619 a->name, flags->str);
1620 else if (!strcmp (a->gtktype, "DOUBLE"))
1621 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1622 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1625 a->name, flags->str);
1626 else if (!strcmp (a->gtktype, "POINTER"))
1627 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1629 a->name, flags->str);
1631 error_printf (GOB_ERROR, a->line_no,
1632 "%s type is not supported for arguments, try using properties",
1635 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1636 "\t\tPROP_%s, param_spec);\n", s);
1640 g_string_free(flags, TRUE);
1643 #define value_for_print(str, alt) (str != NULL ? str : alt)
1646 make_property (Property *p)
1650 if (p->get == NULL && p->set == NULL) {
1651 error_print (GOB_ERROR, p->line_no,
1652 "Property has no getter nor setter");
1656 if (p->flags != NULL)
1657 error_print (GOB_WARN, p->line_no,
1658 "Overriden property, flags ignored");
1659 if (p->nick != NULL)
1660 error_print (GOB_WARN, p->line_no,
1661 "Overriden property, nick ignored");
1662 if (p->blurb != NULL)
1663 error_print (GOB_WARN, p->line_no,
1664 "Overriden property, blurb ignored");
1665 if (p->minimum != NULL)
1666 error_print (GOB_WARN, p->line_no,
1667 "Overriden property, minimum ignored");
1668 if (p->maximum != NULL)
1669 error_print (GOB_WARN, p->line_no,
1670 "Overriden property, maximum ignored");
1671 if (p->default_value != NULL)
1672 error_print (GOB_WARN, p->line_no,
1673 "Overriden property, default_value ignored");
1675 s = g_strdup (p->name);
1677 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1679 "\t\t\"%s\");\n", s, p->name);
1684 char *argflags[] = {
1692 flags = g_string_new ("(GParamFlags)(");
1694 if (p->get != NULL && p->set != NULL)
1695 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1696 else if (p->get != NULL)
1697 g_string_append (flags, "G_PARAM_READABLE");
1699 g_string_append (flags, "G_PARAM_WRITABLE");
1702 for (l = p->flags; l != NULL; l = l->next) {
1703 char *flag = l->data;
1705 if(strcmp (flag, "READABLE") == 0 ||
1706 strcmp (flag, "WRITABLE") == 0) {
1707 error_print(GOB_WARN, p->line_no,
1709 "WRITABLE argument flags are "
1710 "set automatically");
1713 for(i = 0; argflags[i]; i++) {
1714 if(strcmp(argflags[i], flag)==0)
1717 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1720 g_string_append (flags, ")");
1722 if (strcmp (p->gtktype, "CHAR") == 0) {
1723 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1724 "\t\t(\"%s\" /* name */,\n"
1725 "\t\t %s /* nick */,\n"
1726 "\t\t %s /* blurb */,\n"
1727 "\t\t %s /* minimum */,\n"
1728 "\t\t %s /* maximum */,\n"
1729 "\t\t %s /* default_value */,\n"
1732 value_for_print (p->nick, "NULL"),
1733 value_for_print (p->blurb, "NULL"),
1734 value_for_print (p->minimum, "-128"),
1735 value_for_print (p->maximum, "127"),
1736 value_for_print (p->default_value, "0"),
1738 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1739 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1740 "\t\t(\"%s\" /* name */,\n"
1741 "\t\t %s /* nick */,\n"
1742 "\t\t %s /* blurb */,\n"
1743 "\t\t %s /* minimum */,\n"
1744 "\t\t %s /* maximum */,\n"
1745 "\t\t %s /* default_value */,\n"
1748 value_for_print (p->nick, "NULL"),
1749 value_for_print (p->blurb, "NULL"),
1750 value_for_print (p->minimum, "0"),
1751 value_for_print (p->maximum, "0xFF"),
1752 value_for_print (p->default_value, "0"),
1754 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1755 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1756 "\t\t(\"%s\" /* name */,\n"
1757 "\t\t %s /* nick */,\n"
1758 "\t\t %s /* blurb */,\n"
1759 "\t\t %s /* default_value */,\n"
1762 value_for_print (p->nick, "NULL"),
1763 value_for_print (p->blurb, "NULL"),
1764 value_for_print (p->default_value, "FALSE"),
1766 } else if (strcmp (p->gtktype, "INT") == 0) {
1767 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1768 "\t\t(\"%s\" /* name */,\n"
1769 "\t\t %s /* nick */,\n"
1770 "\t\t %s /* blurb */,\n"
1771 "\t\t %s /* minimum */,\n"
1772 "\t\t %s /* maximum */,\n"
1773 "\t\t %s /* default_value */,\n"
1776 value_for_print (p->nick, "NULL"),
1777 value_for_print (p->blurb, "NULL"),
1778 value_for_print (p->minimum, "G_MININT"),
1779 value_for_print (p->maximum, "G_MAXINT"),
1780 value_for_print (p->default_value, "0"),
1782 } else if (strcmp (p->gtktype, "UINT") == 0) {
1783 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1784 "\t\t(\"%s\" /* name */,\n"
1785 "\t\t %s /* nick */,\n"
1786 "\t\t %s /* blurb */,\n"
1787 "\t\t %s /* minimum */,\n"
1788 "\t\t %s /* maximum */,\n"
1789 "\t\t %s /* default_value */,\n"
1792 value_for_print (p->nick, "NULL"),
1793 value_for_print (p->blurb, "NULL"),
1794 value_for_print (p->minimum, "0"),
1795 value_for_print (p->maximum, "G_MAXUINT"),
1796 value_for_print (p->default_value, "0"),
1798 } else if (strcmp (p->gtktype, "LONG") == 0) {
1799 out_printf (out, "\tparam_spec = g_param_spec_long\n"
1800 "\t\t(\"%s\" /* name */,\n"
1801 "\t\t %s /* nick */,\n"
1802 "\t\t %s /* blurb */,\n"
1803 "\t\t %s /* minimum */,\n"
1804 "\t\t %s /* maximum */,\n"
1805 "\t\t %s /* default_value */,\n"
1808 value_for_print (p->nick, "NULL"),
1809 value_for_print (p->blurb, "NULL"),
1810 value_for_print (p->minimum, "G_MINLONG"),
1811 value_for_print (p->maximum, "G_MAXLONG"),
1812 value_for_print (p->default_value, "0"),
1814 } else if (strcmp (p->gtktype, "ULONG") == 0) {
1815 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
1816 "\t\t(\"%s\" /* name */,\n"
1817 "\t\t %s /* nick */,\n"
1818 "\t\t %s /* blurb */,\n"
1819 "\t\t %s /* minimum */,\n"
1820 "\t\t %s /* maximum */,\n"
1821 "\t\t %s /* default_value */,\n"
1824 value_for_print (p->nick, "NULL"),
1825 value_for_print (p->blurb, "NULL"),
1826 value_for_print (p->minimum, "0"),
1827 value_for_print (p->maximum, "G_MAXULONG"),
1828 value_for_print (p->default_value, "0"),
1830 } else if (strcmp (p->gtktype, "INT64") == 0) {
1831 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
1832 "\t\t(\"%s\" /* name */,\n"
1833 "\t\t %s /* nick */,\n"
1834 "\t\t %s /* blurb */,\n"
1835 "\t\t %s /* minimum */,\n"
1836 "\t\t %s /* maximum */,\n"
1837 "\t\t %s /* default_value */,\n"
1840 value_for_print (p->nick, "NULL"),
1841 value_for_print (p->blurb, "NULL"),
1842 value_for_print (p->minimum, "G_MININT64"),
1843 value_for_print (p->maximum, "G_MAXINT64"),
1844 value_for_print (p->default_value, "0"),
1846 } else if (strcmp (p->gtktype, "UINT64") == 0) {
1847 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
1848 "\t\t(\"%s\" /* name */,\n"
1849 "\t\t %s /* nick */,\n"
1850 "\t\t %s /* blurb */,\n"
1851 "\t\t %s /* minimum */,\n"
1852 "\t\t %s /* maximum */,\n"
1853 "\t\t %s /* default_value */,\n"
1856 value_for_print (p->nick, "NULL"),
1857 value_for_print (p->blurb, "NULL"),
1858 value_for_print (p->minimum, "0"),
1859 value_for_print (p->maximum, "G_MAXUINT64"),
1860 value_for_print (p->default_value, "0"),
1862 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
1863 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
1864 "\t\t(\"%s\" /* name */,\n"
1865 "\t\t %s /* nick */,\n"
1866 "\t\t %s /* blurb */,\n"
1867 "\t\t %s /* default_value */,\n"
1870 value_for_print (p->nick, "NULL"),
1871 value_for_print (p->blurb, "NULL"),
1872 value_for_print (p->default_value, "0"),
1874 } else if (strcmp (p->gtktype, "ENUM") == 0) {
1875 char *type = make_me_type (p->extra_gtktype,
1877 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
1878 "\t\t(\"%s\" /* name */,\n"
1879 "\t\t %s /* nick */,\n"
1880 "\t\t %s /* blurb */,\n"
1881 "\t\t %s /* enum_type */,\n"
1882 "\t\t %s /* default_value */,\n"
1885 value_for_print (p->nick, "NULL"),
1886 value_for_print (p->blurb, "NULL"),
1888 value_for_print (p->default_value, "0"),
1891 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
1892 char *type = make_me_type (p->extra_gtktype,
1894 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
1895 "\t\t(\"%s\" /* name */,\n"
1896 "\t\t %s /* nick */,\n"
1897 "\t\t %s /* blurb */,\n"
1898 "\t\t %s /* flags_type */,\n"
1899 "\t\t %s /* default_value */,\n"
1902 value_for_print (p->nick, "NULL"),
1903 value_for_print (p->blurb, "NULL"),
1905 value_for_print (p->default_value, "0"),
1908 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
1909 out_printf (out, "\tparam_spec = g_param_spec_float\n"
1910 "\t\t(\"%s\" /* name */,\n"
1911 "\t\t %s /* nick */,\n"
1912 "\t\t %s /* blurb */,\n"
1913 "\t\t %s /* minimum */,\n"
1914 "\t\t %s /* maximum */,\n"
1915 "\t\t %s /* default_value */,\n"
1918 value_for_print (p->nick, "NULL"),
1919 value_for_print (p->blurb, "NULL"),
1920 value_for_print (p->minimum, "-G_MAXFLOAT"),
1921 value_for_print (p->maximum, "G_MAXFLOAT"),
1922 value_for_print (p->default_value, "0.0"),
1924 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
1925 out_printf (out, "\tparam_spec = g_param_spec_double\n"
1926 "\t\t(\"%s\" /* name */,\n"
1927 "\t\t %s /* nick */,\n"
1928 "\t\t %s /* blurb */,\n"
1929 "\t\t %s /* minimum */,\n"
1930 "\t\t %s /* maximum */,\n"
1931 "\t\t %s /* default_value */,\n"
1934 value_for_print (p->nick, "NULL"),
1935 value_for_print (p->blurb, "NULL"),
1936 value_for_print (p->minimum, "-G_MAXDOUBLE"),
1937 value_for_print (p->maximum, "G_MAXDOUBLE"),
1938 value_for_print (p->default_value, "0.0"),
1940 } else if (strcmp (p->gtktype, "STRING") == 0) {
1941 out_printf (out, "\tparam_spec = g_param_spec_string\n"
1942 "\t\t(\"%s\" /* name */,\n"
1943 "\t\t %s /* nick */,\n"
1944 "\t\t %s /* blurb */,\n"
1945 "\t\t %s /* default_value */,\n"
1948 value_for_print (p->nick, "NULL"),
1949 value_for_print (p->blurb, "NULL"),
1950 value_for_print (p->default_value, "NULL"),
1952 } else if (strcmp (p->gtktype, "PARAM") == 0) {
1953 char *type = make_me_type (p->extra_gtktype,
1955 out_printf (out, "\tparam_spec = g_param_spec_param\n"
1956 "\t\t(\"%s\" /* name */,\n"
1957 "\t\t %s /* nick */,\n"
1958 "\t\t %s /* blurb */,\n"
1959 "\t\t %s /* param_type */,\n"
1962 value_for_print (p->nick, "NULL"),
1963 value_for_print (p->blurb, "NULL"),
1967 } else if (strcmp (p->gtktype, "BOXED") == 0) {
1968 char *type = make_me_type (p->extra_gtktype,
1970 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
1971 "\t\t(\"%s\" /* name */,\n"
1972 "\t\t %s /* nick */,\n"
1973 "\t\t %s /* blurb */,\n"
1974 "\t\t %s /* boxed_type */,\n"
1977 value_for_print (p->nick, "NULL"),
1978 value_for_print (p->blurb, "NULL"),
1982 } else if (strcmp (p->gtktype, "POINTER") == 0) {
1983 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1984 "\t\t(\"%s\" /* name */,\n"
1985 "\t\t %s /* nick */,\n"
1986 "\t\t %s /* blurb */,\n"
1989 value_for_print (p->nick, "NULL"),
1990 value_for_print (p->blurb, "NULL"),
1992 /* FIXME: VALUE_ARRAY */
1993 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
1994 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
1995 "\t\t(\"%s\" /* name */,\n"
1996 "\t\t %s /* nick */,\n"
1997 "\t\t %s /* blurb */,\n"
2000 value_for_print (p->nick, "NULL"),
2001 value_for_print (p->blurb, "NULL"),
2003 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2004 char *type = make_me_type (p->extra_gtktype,
2006 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2007 "\t\t(\"%s\" /* name */,\n"
2008 "\t\t %s /* nick */,\n"
2009 "\t\t %s /* blurb */,\n"
2010 "\t\t %s /* object_type */,\n"
2013 value_for_print (p->nick, "NULL"),
2014 value_for_print (p->blurb, "NULL"),
2019 error_printf (GOB_ERROR, p->line_no,
2020 "%s type is not supported by properties",
2024 s = g_strdup (p->name);
2026 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2028 "\t\tparam_spec);\n", s);
2031 g_string_free (flags, TRUE);
2036 make_arguments(Class *c)
2039 if (get_properties > 0)
2040 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2041 if (set_properties > 0)
2042 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2043 out_printf (out, " {\n");
2044 for (li = c->nodes; li != NULL; li = li->next) {
2046 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2047 || n->type == ARGUMENT_NODE) {
2048 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2053 for (li = c->nodes; li != NULL; li = li->next) {
2055 if (n->type == PROPERTY_NODE)
2056 make_property ((Property *)n);
2057 else if (n->type == ARGUMENT_NODE)
2058 make_argument ((Argument *)n);
2060 out_printf(out, " }\n");
2064 print_initializer(Method *m, Variable *v)
2071 if(v->initializer == NULL)
2074 if(v->scope == PRIVATE_SCOPE)
2075 root = g_strconcat(((FuncArg *)m->args->data)->name,
2078 root = g_strdup(((FuncArg *)m->args->data)->name);
2080 if(v->initializer_line > 0)
2081 out_addline_infile(out, v->initializer_line);
2083 if (v->initializer_simple)
2084 out_printf(out, "\t%s->%s = %s;\n",
2085 root, v->id, v->initializer);
2086 else if (strcmp(v->id, "_glade_xml") == 0)
2087 /* This is OK, this v->initializer string is set internally
2088 and it will eat exactly one string! */
2089 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2091 out_printf(out, "%s", v->initializer);
2093 if(v->initializer_line > 0)
2094 out_addline_outfile(out);
2100 print_glade_widget(Method *m, Variable *v)
2105 if(!v->glade_widget)
2108 if(v->scope == PRIVATE_SCOPE)
2109 root = g_strconcat(((FuncArg *)m->args->data)->name,
2112 root = g_strdup(((FuncArg *)m->args->data)->name);
2114 cast = get_type(v->vtype, FALSE);
2115 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2116 root, v->id, cast, root, v->id);
2122 print_destructor (Variable *v)
2126 if(v->destructor == NULL)
2129 if(v->scope == PRIVATE_SCOPE)
2130 root = "self->_priv";
2134 if(v->destructor_simple) {
2135 if(v->destructor_line > 0)
2136 out_addline_infile(out, v->destructor_line);
2139 out_printf(out, "\tif(%s->%s) { "
2140 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2141 "%s->%s = NULL; }\n",
2142 root, v->id, v->destructor, root, v->id,
2145 out_printf(out, "\tif(%s->%s) { "
2146 "%s ((gpointer) %s->%s); "
2147 "%s->%s = NULL; }\n",
2148 root, v->id, v->destructor, root, v->id,
2152 if(v->destructor_line > 0)
2153 out_addline_outfile(out);
2155 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2156 out_printf(out, "#define VAR %s\n", v->id);
2157 out_printf(out, "\t{\n");
2158 if(v->destructor_line > 0)
2159 out_addline_infile(out, v->destructor_line);
2161 out_printf(out, "\t%s}\n", v->destructor);
2163 if(v->destructor_line > 0)
2164 out_addline_outfile(out);
2165 out_printf(out, "\tmemset(&%s, 0, sizeof(%s));\n",
2167 out_printf(out, "#undef VAR\n");
2168 out_printf(out, "#undef %s\n", v->id);
2173 add_constructor (Class *c)
2175 out_printf(out, "\nstatic GObject *\n"
2176 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2179 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2182 out_printf(out, "\tGObject *obj_self;\n");
2183 out_printf(out, "\t%s *self;\n", typebase);
2185 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2186 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2188 if (user_constructor->line_no > 0)
2189 out_addline_infile (out, user_constructor->line_no);
2190 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2191 if (user_constructor->line_no > 0)
2192 out_addline_outfile (out);
2194 out_printf(out, "\treturn obj_self;\n");
2195 out_printf(out, "}\n"
2196 "#undef __GOB_FUNCTION__\n\n");
2200 add_dispose (Class *c)
2202 out_printf(out, "\nstatic void\n"
2203 "___dispose (GObject *obj_self)\n"
2206 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2209 if (unreftors > 0 || user_dispose_method != NULL) {
2210 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2212 ! no_gnu ? " G_GNUC_UNUSED" : "",
2216 if (dispose_handler != NULL) {
2217 /* so we get possible bad argument warning */
2218 if (dispose_handler->line_no > 0)
2219 out_addline_infile (out, dispose_handler->line_no);
2220 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2221 (guint)dispose_handler->unique_id, funcbase);
2222 if (dispose_handler->line_no > 0)
2223 out_addline_outfile (out);
2225 if (user_dispose_method != NULL) {
2226 if (user_dispose_method->line_no > 0)
2227 out_addline_infile (out, user_dispose_method->line_no);
2228 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2229 if (user_dispose_method->line_no > 0)
2230 out_addline_outfile (out);
2234 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2235 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2238 if (unreftors > 0) {
2240 for(li = ((Class *)class)->nodes;
2244 Variable *v = (Variable *)n;
2245 if (n->type == VARIABLE_NODE &&
2246 v->scope != CLASS_SCOPE &&
2247 v->destructor_unref)
2248 print_destructor (v);
2252 out_printf(out, "}\n"
2253 "#undef __GOB_FUNCTION__\n\n");
2257 add_finalize (Class *c)
2261 "___finalize(GObject *obj_self)\n"
2264 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2269 user_finalize_method != NULL) {
2270 const char *unused = "";
2272 unused = " G_GNUC_UNUSED";
2273 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2274 typebase, unused, macrobase);
2277 const char *unused = "";
2279 unused = " G_GNUC_UNUSED";
2280 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2284 if(finalize_handler) {
2285 /* so we get possible bad argument warning */
2286 if(finalize_handler->line_no > 0)
2287 out_addline_infile(out, finalize_handler->line_no);
2288 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2289 (guint)finalize_handler->unique_id, funcbase);
2290 if(finalize_handler->line_no > 0)
2291 out_addline_outfile(out);
2293 if (user_finalize_method != NULL) {
2294 if (user_finalize_method->line_no > 0)
2295 out_addline_infile (out, user_finalize_method->line_no);
2296 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2297 if (user_finalize_method->line_no > 0)
2298 out_addline_outfile (out);
2302 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2303 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2306 if (destructors > 0) {
2308 for (li = ((Class *)class)->nodes;
2312 Variable *v = (Variable *)n;
2313 if (n->type == VARIABLE_NODE &&
2314 v->scope != CLASS_SCOPE &&
2315 ! v->destructor_unref)
2316 print_destructor (v);
2320 out_printf(out, "}\n"
2321 "#undef __GOB_FUNCTION__\n\n");
2325 make_bonobo_object_epv (Class *c, const char *classname)
2328 gboolean added_line = FALSE;
2330 for (li = c->nodes; li != NULL; li = li->next) {
2332 Method *m = (Method *)n;
2333 if(n->type != METHOD_NODE ||
2334 m->method == OVERRIDE_METHOD)
2337 if (m->bonobo_object_func) {
2338 if(m->line_no > 0) {
2339 out_addline_infile(out, m->line_no);
2341 } else if (m->line_no == 0 &&
2343 out_addline_outfile(out);
2346 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2347 classname, m->id, m->id);
2351 out_addline_outfile(out);
2357 const char *unused = "";
2361 unused = " G_GNUC_UNUSED";
2363 for(li=c->nodes;li;li=g_list_next(li)) {
2367 if(n->type != METHOD_NODE)
2370 if(m->method == INIT_METHOD) {
2372 out_addline_infile(out, m->line_no);
2373 print_method(out, "static ", "\n", "", " ", "", "\n",
2374 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2376 out_printf(out, "{\n");
2378 out_addline_outfile(out);
2380 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2383 out_printf(out, "\t%s->_priv = "
2384 "G_TYPE_INSTANCE_GET_PRIVATE(%s,%s,%sPrivate);\n",
2385 ((FuncArg *)m->args->data)->name,
2386 ((FuncArg *)m->args->data)->name,
2389 } else if(always_private_struct) {
2390 out_printf(out, "\t%s->_priv = NULL;\n",
2391 ((FuncArg *)m->args->data)->name);
2393 if(initializers > 0) {
2395 for(li = ((Class *)class)->nodes;
2399 Variable *v = (Variable *)n;
2400 if(n->type != VARIABLE_NODE ||
2401 v->scope == CLASS_SCOPE)
2403 print_initializer(m, v);
2406 if(glade_widgets > 0) {
2408 for(li = ((Class *)class)->nodes;
2412 Variable *v = (Variable *)n;
2413 if(n->type != VARIABLE_NODE ||
2414 v->scope == CLASS_SCOPE)
2416 print_glade_widget(m, v);
2419 } else if(m->method == CLASS_INIT_METHOD) {
2420 gboolean did_base_obj = FALSE;
2423 out_addline_infile(out, m->line_no);
2424 print_method(out, "static ", "\n", "", " ", "", "\n",
2425 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2427 out_printf(out, "{\n");
2429 out_addline_outfile(out);
2431 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2433 if (set_properties > 0 ||
2434 get_properties > 0 ||
2441 "g_object_class%s = "
2442 "(GObjectClass*) %s;\n",
2444 ((FuncArg *)m->args->data)->name);
2445 did_base_obj = TRUE;
2450 ((FuncArg *)m->args->data)->name,
2455 "\n\tg_type_class_add_private(%s,sizeof(%sPrivate));\n",
2456 ((FuncArg *)m->args->data)->name,
2459 if (initializers > 0) {
2461 for(li = ((Class *)class)->nodes;
2465 Variable *v = (Variable *)n;
2466 if(n->type == VARIABLE_NODE &&
2467 v->scope == CLASS_SCOPE)
2468 print_initializer(m, v);
2472 out_printf(out, "\n\tparent_class = ");
2474 out_printf(out, "(%sClass *)", ptypebase);
2475 out_printf(out, "g_type_class_ref (%s);\n",
2481 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2483 /* if there are no handlers for these things, we
2484 * need to set them up here */
2485 if(need_constructor)
2486 out_printf(out, "\tg_object_class->constructor "
2487 "= ___constructor;\n");
2488 if(need_dispose && !dispose_handler)
2489 out_printf(out, "\tg_object_class->dispose "
2491 if(need_finalize && !finalize_handler)
2492 out_printf(out, "\tg_object_class->finalize = "
2495 if(get_properties > 0 || set_properties > 0)
2498 if (c->bonobo_object_class != NULL) {
2499 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2505 out_printf(out, " {\n");
2506 out_addline_infile(out, m->ccode_line);
2507 out_printf(out, "%s\n", m->cbuf);
2508 out_addline_outfile(out);
2509 out_printf(out, " }\n");
2511 out_printf(out, "}\n"
2512 "#undef __GOB_FUNCTION__\n");
2517 add_argument (Argument *a, gboolean is_set)
2521 char *the_type_lower;
2526 line_no = a->set_line;
2529 line_no = a->get_line;
2533 s = g_strdup(a->name);
2535 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2537 the_type_lower = g_strdup (a->gtktype);
2538 gob_strdown (the_type_lower);
2540 /* HACK because there is no g_value_set/get for unichar */
2541 if (strcmp (the_type_lower, "unichar") == 0) {
2542 g_free (the_type_lower);
2543 the_type_lower = g_strdup ("uint");
2548 const char *unused = "";
2550 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2551 unused = " G_GNUC_UNUSED";
2554 if (a->atype != NULL &&
2555 /* gcc -Wbad-function-cast is wanking stupid, moronic
2556 and otherwise evil so we should just use a (gint)
2557 or (guint) cast, not the specific type cast */
2559 (strcmp (a->gtktype, "ENUM") != 0 &&
2560 strcmp (a->gtktype, "FLAGS") != 0)))
2561 cast = get_type (a->atype, TRUE);
2563 cast = g_strdup (get_cast (a->gtktype, FALSE));
2565 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2566 cast, unused, cast, the_type_lower);
2569 } else if ( ! is_set) {
2572 if (a->atype != NULL)
2573 cast = get_type (a->atype, TRUE);
2575 cast = g_strdup (get_cast (a->gtktype, FALSE));
2576 out_printf (out, "\t%s ARG;\n"
2577 "\tmemset (&ARG, 0, sizeof (%s));\n",
2583 out_printf(out, "\t\t{\n");
2585 out_addline_infile (out, line_no);
2586 out_printf (out, "%s\n", cbuf);
2588 out_addline_outfile (out);
2589 out_printf (out, "\t\t}\n");
2591 if (strcmp (a->gtktype, "OBJECT") == 0)
2592 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2595 out_printf (out, "\t\t"
2596 "g_value_set_%s (VAL, ARG);\n",
2599 g_free (the_type_lower);
2602 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2603 out_printf (out, "\t\tif (&ARG) break;\n");
2606 out_printf (out, "\t\tbreak;\n");
2608 out_printf (out, "\t}\n");
2612 add_property (Property *p, gboolean is_set)
2615 char *the_type_lower;
2621 line_no = p->set_line;
2624 line_no = p->get_line;
2629 name_upper = g_strdup (p->name);
2630 gob_strup (name_upper);
2631 the_type_lower = g_strdup (p->gtktype);
2632 gob_strdown (the_type_lower);
2634 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2636 out_printf(out, "\t\t{\n");
2638 out_addline_infile (out, line_no);
2639 out_printf (out, "%s\n", cbuf);
2641 out_addline_outfile (out);
2642 out_printf (out, "\t\t}\n");
2644 g_free (name_upper);
2645 g_free (the_type_lower);
2647 out_printf (out, "\t\tbreak;\n");
2651 add_getset_arg(Class *c, gboolean is_set)
2654 const char *unused = "";
2655 const char *hack_unused = "";
2657 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2658 unused = " G_GNUC_UNUSED";
2660 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2663 out_printf(out, "\nstatic void\n"
2664 "___object_%s_property (GObject *object,\n"
2665 "\tguint property_id,\n"
2666 "\t%sGValue *VAL%s,\n"
2667 "\tGParamSpec *pspec%s)\n"
2668 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2671 "\tself = %s (object);\n\n"
2672 "\tswitch (property_id) {\n",
2673 is_set ? "set" : "get",
2674 is_set ? "const " : "",
2678 is_set ? "set" : "get",
2683 for (li = c->nodes; li != NULL; li = li->next) {
2685 if (n->type == PROPERTY_NODE)
2686 add_property ((Property *)n, is_set);
2687 else if (n->type == ARGUMENT_NODE)
2688 add_argument ((Argument *)n, is_set);
2690 out_printf (out, "\tdefault:\n"
2691 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2692 "#ifndef __PRETTY_FUNCTION__\n"
2693 "# undef G_STRLOC\n"
2694 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2696 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2697 "\t\t%sbreak;\n\t}\n"
2699 "#undef __GOB_FUNCTION__\n", hack_unused);
2703 print_checks (Method *m, FuncArg *fa)
2707 gboolean checked_null = FALSE;
2708 is_void = (strcmp(m->mtype->name, "void")==0 &&
2709 m->mtype->pointer == NULL);
2711 for(li = fa->checks; li != NULL; li = li->next) {
2712 Check *ch = li->data;
2714 /* point to the method prot in .gob for failed checks */
2716 out_addline_infile(out, m->line_no);
2718 out_printf(out, "\tg_return_if_fail (");
2720 out_printf(out, "\tg_return_val_if_fail (");
2721 switch(ch->chtype) {
2723 out_printf(out, "%s != NULL", fa->name);
2724 checked_null = TRUE;
2727 s = make_pre_macro(fa->atype->name, "IS");
2729 out_printf(out, "%s (%s)", s, fa->name);
2731 /* if not check null, null may be valid */
2732 out_printf(out, "!(%s) || %s (%s)", fa->name,
2737 out_printf(out, "%s < %s", fa->name, ch->number);
2740 out_printf(out, "%s > %s", fa->name, ch->number);
2743 out_printf(out, "%s <= %s", fa->name, ch->number);
2746 out_printf(out, "%s >= %s", fa->name, ch->number);
2749 out_printf(out, "%s == %s", fa->name, ch->number);
2752 out_printf(out, "%s != %s", fa->name, ch->number);
2756 out_printf(out, ");\n");
2758 out_printf(out, ", (");
2759 print_type(out, m->mtype, TRUE);
2760 out_printf(out, ")%s);\n",
2761 m->onerror?m->onerror:"0");
2767 print_preconditions(Method *m)
2771 for(li=m->args;li;li=g_list_next(li)) {
2772 FuncArg *fa = li->data;
2774 print_checks(m, fa);
2777 out_addline_outfile(out);
2781 print_method_body (Method *m, gboolean pre, gboolean unused_self)
2783 out_printf(out, "{\n");
2785 out_addline_outfile(out);
2786 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
2787 ((Class *)class)->otype,
2790 print_preconditions(m);
2794 (no_gnu || for_cpp) &&
2796 ((FuncArg *)(m->args->data))->name != NULL &&
2797 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
2798 out_printf (out, "\tif (&self) { ; }\n");
2801 /* Note: the trailing }'s are on one line, this is so
2802 that we get the no return warning correctly and point to
2803 the correct line in the .gob file, yes this is slightly
2804 ugly in the .c file, but that is not supposed to be
2805 human readable anyway. */
2807 out_printf(out, "{\n");
2809 out_addline_infile(out, m->ccode_line);
2810 out_printf(out, "\t%s}", m->cbuf);
2813 /* Note, there is no \n between the last } and this } so that
2814 * errors/warnings reported on the end of the body get pointed to the
2815 * right line in the .gob source */
2816 out_printf(out, "}\n");
2819 out_addline_outfile(out);
2820 out_printf(out, "#undef __GOB_FUNCTION__\n");
2824 put_signal_args (Method *m)
2830 if (m->args->next == NULL)
2833 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
2834 li != NULL && ali != NULL;
2835 li = li->next, ali = ali->next, i++) {
2836 FuncArg *fa = li->data;
2837 char *str = ali->data;
2838 char *cast = g_strdup (get_cast (str, FALSE));
2839 /* FIXME: This code is so fucking ugly it hurts */
2840 gboolean do_static =
2841 (strcmp (str, "STRING") == 0 ||
2842 strcmp (str, "BOXED") == 0 ||
2843 strncmp (str, "BOXED_", 6) == 0);
2848 cast = get_type (fa->atype, TRUE);
2850 /* we should have already proved before that
2851 the we know all the types */
2852 g_assert (cast != NULL);
2854 if (strncmp (str, "BOXED_", 6) == 0)
2855 t = g_strdup (&(str[6]));
2857 t = g_strconcat ("G_TYPE_", str, NULL);
2860 "\t___param_values[%d].g_type = 0;\n"
2861 "\tg_value_init (&___param_values[%d], %s);\n",
2865 if (strcmp (str, "UNICHAR") == 0)
2866 /* hack because glib is braindamaged */
2867 set_func = g_strdup ("g_value_set_uint");
2868 else if (strncmp (str, "BOXED_", 6) == 0)
2869 set_func = g_strdup ("g_value_set_static_boxed");
2871 set_func = g_strdup_printf ("g_value_set%s_%s",
2872 do_static ? "_static" : "",
2874 gob_strdown (set_func);
2876 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
2877 set_func, i, cast, fa->name);
2885 clear_signal_args (Method *m)
2890 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
2892 if (m->args->next == NULL)
2895 for (li = m->args->next, i = 1;
2897 li = li->next, i++) {
2899 "\tg_value_unset (&___param_values[%d]);\n", i);
2904 get_arg_names_for_macro (Method *m)
2908 GString *gs = g_string_new(NULL);
2910 for(li=m->args;li;li=g_list_next(li)) {
2911 FuncArg *arg = li->data;
2912 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
2915 return g_string_free (gs, FALSE);
2919 put_method(Method *m)
2921 char *s, *args, *doc;
2923 is_void = (strcmp(m->mtype->name, "void")==0 &&
2924 m->mtype->pointer == NULL);
2925 out_printf(out, "\n");
2926 if(m->method != OVERRIDE_METHOD) {
2927 doc = get_gtk_doc(m->id);
2929 out_printf(out, "%s", doc);
2934 case REGULAR_METHOD:
2936 out_addline_infile(out, m->line_no);
2937 if(m->scope == PRIVATE_SCOPE)
2938 print_method(out, "static ", "\n", "", " ", "", "\n",
2939 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2940 else /* PUBLIC, PROTECTED */
2941 print_method(out, "", "\n", "", " ", "", "\n",
2942 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2943 print_method_body(m, TRUE, TRUE);
2944 /* the outfile line was added above */
2946 case SIGNAL_FIRST_METHOD:
2947 case SIGNAL_LAST_METHOD:
2949 out_addline_infile(out, m->line_no);
2950 if(m->scope == PRIVATE_SCOPE)
2951 print_method(out, "static ", "\n", "", " ", "", "\n",
2952 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2953 else /* PUBLIC, PROTECTED */
2954 print_method(out, "", "\n", "", " ", "", "\n",
2955 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
2956 out_printf (out, "{\n");
2958 out_addline_outfile (out);
2961 "\tGValue ___param_values[%d];\n"
2962 "\tGValue ___return_val;\n\n"
2963 "memset (&___return_val, 0, "
2964 "sizeof (___return_val));\n"
2965 "memset (&___param_values, 0, "
2966 "sizeof (___param_values));\n\n",
2967 g_list_length (m->args));
2969 print_preconditions (m);
2972 "\n\t___param_values[0].g_type = 0;\n"
2973 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
2974 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
2975 ((FuncArg *)m->args->data)->name,
2976 ((FuncArg *)m->args->data)->name);
2978 put_signal_args (m);
2980 if (strcmp (m->gtktypes->data, "NONE") != 0) {
2981 const char *defret = NULL;
2983 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
2984 (char *)m->gtktypes->data);
2986 if (m->defreturn != NULL)
2987 defret = m->defreturn;
2988 else if (m->onerror != NULL)
2989 defret = m->onerror;
2991 if (defret != NULL) {
2993 /* FIXME: This code is so fucking ugly it hurts */
2994 gboolean do_static =
2995 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
2996 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
2997 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
2999 cast = get_type (m->mtype, TRUE);
3001 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3002 /* hack because glib is braindamaged */
3003 set_func = g_strdup ("g_value_set_uint");
3005 set_func = g_strdup_printf ("g_value_set%s_%s",
3006 do_static ? "_static" : "",
3007 (char *)m->gtktypes->data);
3008 gob_strdown (set_func);
3010 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3011 set_func, cast, defret);
3016 out_printf (out, "\n");
3019 s = g_strdup (m->id);
3022 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3023 "\t\tobject_signals[%s_SIGNAL],\n"
3024 "\t\t0 /* detail */,\n"
3025 "\t\t&___return_val);\n", s);
3029 clear_signal_args (m);
3031 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3032 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3034 /* Hack because glib is very very braindead */
3036 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3037 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3038 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3039 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3041 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3042 /* hack because glib is braindamaged */
3043 getfunc = g_strdup ("g_value_get_uint");
3045 getfunc = g_strdup_printf ("g_value_%s_%s",
3046 do_dup ? "dup" : "get",
3047 (char *)m->gtktypes->data);
3048 gob_strdown (getfunc);
3051 cast = get_type (m->mtype, TRUE);
3056 print_type (out, m->mtype, TRUE);
3058 " ___ret = (%s) %s (&___return_val);\n"
3059 "\t\tg_value_unset (&___return_val);\n"
3060 "\t\treturn ___ret;\n"
3067 out_printf(out, "}\n");
3072 out_addline_infile(out, m->line_no);
3073 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3074 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3075 print_method_body(m, FALSE, TRUE);
3076 /* the outfile line was added above */
3078 case VIRTUAL_METHOD:
3080 out_addline_infile(out, m->line_no);
3081 if(m->scope==PRIVATE_SCOPE)
3082 print_method(out, "static ", "\n", "", " ", "", "\n",
3083 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3084 else /* PUBLIC, PROTECTED */
3085 print_method(out, "", "\n", "", " ", "", "\n",
3086 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3087 out_printf(out, "{\n");
3088 out_addline_outfile(out);
3089 out_printf(out, "\t%sClass *klass;\n", typebase);
3090 print_preconditions(m);
3091 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3092 "\tif(klass->%s)\n",
3093 macrobase, ((FuncArg *)m->args->data)->name,
3095 if(strcmp(m->mtype->name, "void") == 0 &&
3096 m->mtype->pointer == NULL) {
3098 out_printf(out, "\t\t(*klass->%s)(%s",
3100 ((FuncArg *)m->args->data)->name);
3101 for(li=m->args->next;li;li=g_list_next(li)) {
3102 FuncArg *fa = li->data;
3103 out_printf(out, ",%s", fa->name);
3105 out_printf(out, ");\n}\n");
3108 out_printf(out, "\t\treturn (*klass->%s)(%s",
3110 ((FuncArg *)m->args->data)->name);
3111 for(li=m->args->next;li;li=g_list_next(li)) {
3112 FuncArg *fa = li->data;
3113 out_printf(out, ",%s", fa->name);
3115 out_printf(out, ");\n"
3118 print_type(out, m->mtype, TRUE);
3120 out_printf(out, ")(%s);\n}\n", m->defreturn);
3122 out_printf(out, ")(%s);\n}\n", m->onerror);
3124 out_printf(out, ")(0);\n}\n");
3130 out_addline_infile(out, m->line_no);
3131 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3132 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3133 print_method_body(m, FALSE, TRUE);
3134 /* the outfile line was added above */
3136 case OVERRIDE_METHOD:
3140 out_addline_infile(out, m->line_no);
3141 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3142 print_method(out, "static ", s, "", " ", "", "\n",
3143 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3145 out_addline_outfile(out);
3146 s = replace_sep(m->otype, '_');
3148 args = get_arg_names_for_macro(m);
3150 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3151 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3152 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3153 args, s, m->id, s, m->id, args);
3155 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3156 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3157 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3159 args, s, m->id, s, m->id, args);
3160 out_printf(out, "(");
3161 print_type(out, m->mtype, TRUE);
3162 out_printf(out, ")%s))\n",
3163 m->onerror?m->onerror:"0");
3167 print_method_body(m, TRUE, TRUE);
3168 /* the outfile line was added above */
3169 out_printf(out, "#undef PARENT_HANDLER\n");
3171 case CONSTRUCTOR_METHOD:
3172 case DISPOSE_METHOD:
3173 case FINALIZE_METHOD:
3175 out_addline_infile(out, m->line_no);
3176 print_method(out, "static ", "\n", "", " ", "", "\n",
3177 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3178 print_method_body(m, TRUE, TRUE);
3179 /* the outfile line was added above */
3188 char *outfile, *outfileh, *outfileph;
3190 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3191 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3193 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3194 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3196 if ((privates > 0 || protecteds > 0 ||
3197 private_header == PRIVATE_HEADER_ALWAYS) &&
3198 private_header != PRIVATE_HEADER_NEVER) {
3199 char sep[2] = {0,0};
3202 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3203 outfileph = g_strconcat (outfilephbase, no_touch ? "#gob#" : "", NULL);
3205 outfilephbase = NULL;
3211 out = fopen (outfile, "w");
3213 error_printf (GOB_ERROR, 0,
3214 "Cannot open outfile: %s", outfile);
3216 outh = fopen (outfileh, "w");
3218 error_printf (GOB_ERROR, 0,
3219 "Cannot open outfile: %s", outfileh);
3221 if (outfileph != NULL) {
3222 outph = fopen (outfileph, "w");
3223 if (outph == NULL) {
3224 error_printf (GOB_ERROR, 0,
3225 "Cannot open outfile: %s",
3233 put_argument_nongnu_wrappers (Class *c)
3237 if (get_properties < 0 && set_properties < 0)
3240 for (li = c->nodes; li != NULL; li = li->next) {
3242 const char *name, *gtktype;
3248 if (n->type == ARGUMENT_NODE) {
3249 Argument *a = (Argument *)n;
3251 gtktype = a->gtktype;
3253 get = a->get != NULL;
3254 set = a->set != NULL;
3255 } else if (n->type == PROPERTY_NODE) {
3256 Property *p = (Property *)n;
3258 gtktype = p->gtktype;
3260 get = p->get != NULL;
3261 set = p->set != NULL;
3266 aname = g_strdup (name);
3270 cast = get_type (atype, TRUE);
3272 cast = g_strdup (get_cast (gtktype, TRUE));
3276 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3277 "\"%s\",(%s)(arg)\n",
3278 macrobase, aname, name, cast);
3280 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3281 "\"%s\",(%s*)(arg)\n",
3282 macrobase, aname, name, cast);
3285 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3287 macrobase, aname, name);
3289 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3291 macrobase, aname, name);
3299 put_argument_gnu_wrappers(Class *c)
3303 if(get_properties < 0 && set_properties < 0)
3306 for (li = c->nodes; li != NULL; li = li->next) {
3308 const char *name, *gtktype;
3314 if (n->type == ARGUMENT_NODE) {
3315 Argument *a = (Argument *)n;
3317 gtktype = a->gtktype;
3319 get = a->get != NULL;
3320 set = a->set != NULL;
3321 } else if (n->type == PROPERTY_NODE) {
3322 Property *p = (Property *)n;
3324 gtktype = p->gtktype;
3326 get = p->get != NULL;
3327 set = p->set != NULL;
3332 aname = g_strdup (name);
3336 cast = get_type (atype, TRUE);
3338 cast = g_strdup (get_cast (gtktype, TRUE));
3342 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3343 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3344 macrobase, aname, name, cast);
3346 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3347 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3348 macrobase, aname, name, cast);
3351 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3353 macrobase, aname, name);
3355 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3357 macrobase, aname, name);
3365 print_ccode_block(CCode *cc)
3368 switch(cc->cctype) {
3370 /* HT code is printed exactly like normal header
3371 code but is printed before */
3374 out_printf(fp, "\n");
3377 /* AT code is printed exactly like normal 'all'
3378 code but is printed before */
3381 out_printf(outph, "\n");
3382 out_printf(outph, "%s\n", cc->cbuf);
3383 out_addline_infile(outph, cc->line_no);
3384 out_addline_outfile(outph);
3386 out_printf(outh, "\n");
3387 out_printf(outh, "%s\n", cc->cbuf);
3389 out_printf(fp, "\n");
3390 out_addline_infile(fp, cc->line_no);
3395 out_printf(fp, "\n");
3396 out_addline_infile(fp, cc->line_no);
3403 out_printf(fp, "\n");
3404 out_addline_infile(fp, cc->line_no);
3407 out_printf(fp, "%s\n", cc->cbuf);
3408 if(cc->cctype == C_CCODE ||
3409 cc->cctype == AD_CCODE ||
3410 cc->cctype == A_CCODE ||
3411 cc->cctype == AT_CCODE ||
3412 cc->cctype == PH_CCODE)
3413 out_addline_outfile(fp);
3417 print_class_block(Class *c)
3421 gboolean printed_private = FALSE;
3425 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3426 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3430 out_printf(out, "/* utility types we may need */\n");
3431 if(special_array[SPECIAL_2POINTER])
3432 out_printf(out, "typedef struct { "
3433 "gpointer a; gpointer b; "
3434 "} ___twopointertype;\n");
3435 if(special_array[SPECIAL_3POINTER])
3436 out_printf(out, "typedef struct { "
3437 "gpointer a; gpointer b; "
3439 "} ___threepointertype;\n");
3440 if(special_array[SPECIAL_INT_POINTER])
3441 out_printf(out, "typedef struct { "
3442 "gint a; gpointer b; "
3443 "} ___intpointertype;\n");
3444 out_printf(out, "\n");
3447 out_printf(outh, "\n/*\n"
3448 " * Type checking and casting macros\n"
3450 out_printf(outh, "#define %s\t"
3451 "(%s_get_type())\n",
3452 macrotype, funcbase);
3453 out_printf(outh, "#define %s(obj)\t"
3454 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3455 macrobase, funcbase, typebase);
3456 out_printf(outh, "#define %s_CONST(obj)\t"
3457 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3458 macrobase, funcbase, typebase);
3459 out_printf(outh, "#define %s_CLASS(klass)\t"
3460 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3461 macrobase, funcbase, typebase);
3462 out_printf(outh, "#define %s(obj)\t"
3463 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3466 "#define %s_GET_CLASS(obj)\t"
3467 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3468 macrobase, funcbase, typebase);
3470 if ( ! no_self_alias) {
3471 out_printf(out, "/* self casting macros */\n");
3472 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3473 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3474 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3475 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3476 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3478 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3481 out_printf(out, "/* self typedefs */\n");
3482 out_printf(out, "typedef %s Self;\n", typebase);
3483 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3487 always_private_struct) {
3488 out_printf (outh, "\n/* Private structure type */\n");
3489 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3490 typebase, typebase);
3492 out_printf (outh, "/* There are no privates, this "
3493 "structure is thus never defined */\n");
3496 out_printf (outh, "\n/*\n"
3497 " * Main object structure\n"
3499 s = replace_sep (c->otype, '_');
3501 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3502 "#define __TYPEDEF_%s__\n", s, s);
3504 out_printf (outh, "typedef struct _%s %s;\n"
3505 "#endif\n", typebase, typebase);
3506 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3507 typebase, ptypebase);
3508 for (li = c->nodes; li; li=li->next) {
3509 static gboolean printed_public = FALSE;
3511 Variable *v = (Variable *)n;
3512 if(n->type == VARIABLE_NODE &&
3513 v->scope == PUBLIC_SCOPE) {
3514 if( ! printed_public) {
3515 out_printf(outh, "\t/*< public >*/\n");
3516 printed_public = TRUE;
3518 put_variable((Variable *)n, outh);
3521 /* put protecteds always AFTER publics */
3522 for (li = c->nodes; li != NULL; li = li->next) {
3524 Variable *v = (Variable *)n;
3525 if (n->type == VARIABLE_NODE &&
3526 v->scope == PROTECTED_SCOPE) {
3527 if ( ! printed_private) {
3528 out_printf (outh, "\t/*< private >*/\n");
3529 printed_private = TRUE;
3531 put_variable ((Variable *)n, outh);
3535 always_private_struct) {
3536 if ( ! printed_private)
3537 out_printf (outh, "\t/*< private >*/\n");
3538 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3540 out_printf (outh, "};\n");
3545 /* if we are to stick this into the private
3546 header, if not stick it directly into the
3553 out_printf (outfp, "struct _%sPrivate {\n",
3557 for(li=c->nodes; li; li=li->next) {
3559 Variable *v = (Variable *)n;
3560 if(n->type == VARIABLE_NODE &&
3561 v->scope == PRIVATE_SCOPE) {
3562 out_addline_infile(outfp, v->line_no);
3563 put_variable(v, outfp);
3566 out_addline_outfile(outfp);
3568 out_printf(outfp, "};\n");
3571 out_printf(outh, "\n/*\n"
3572 " * Class definition\n"
3574 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3575 typebase, typebase);
3577 "struct _%sClass {\n\t%sClass __parent__;\n",
3578 typebase, ptypebase);
3579 for(li = c->nodes; li != NULL; li = li->next) {
3581 if(n->type == METHOD_NODE)
3582 put_vs_method((Method *)n);
3584 /* If BonoboX type class put down the epv */
3585 if (c->bonobo_object_class != NULL) {
3587 "\t/* Bonobo object epv */\n"
3588 "\tPOA_%s__epv _epv;\n",
3589 c->bonobo_object_class);
3591 /* put class scope variables */
3592 for (li = c->nodes; li != NULL; li = li->next) {
3594 Variable *v = (Variable *)n;
3595 if (n->type == VARIABLE_NODE &&
3596 v->scope == CLASS_SCOPE)
3597 put_variable ((Variable *)n, outh);
3599 out_printf (outh, "};\n\n");
3601 out_printf (out, "/* here are local prototypes */\n");
3602 if (set_properties > 0) {
3603 out_printf (out, "static void ___object_set_property "
3604 "(GObject *object, guint property_id, "
3605 "const GValue *value, GParamSpec *pspec);\n");
3607 if (get_properties > 0) {
3608 out_printf (out, "static void ___object_get_property "
3609 "(GObject *object, guint property_id, "
3610 "GValue *value, GParamSpec *pspec);\n");
3613 out_printf (outh, "\n/*\n"
3614 " * Public methods\n"
3617 if ( ! overrode_get_type) {
3618 out_printf (outh, "GType\t%s_get_type\t(void) G_GNUC_CONST;\n", funcbase);
3621 for(li = c->nodes; li != NULL; li = li->next) {
3623 if(n->type == METHOD_NODE) {
3624 put_pub_method((Method *)n);
3625 put_prot_method((Method *)n);
3626 put_priv_method_prot((Method *)n);
3630 /* this idea is less and less apealing to me */
3632 out_printf (outh, "\n/*\n"
3633 " * Signal connection wrapper macros\n"
3636 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3637 put_signal_macros (c, TRUE);
3638 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3639 put_signal_macros (c, FALSE);
3640 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3642 put_signal_macros (c, FALSE);
3643 out_printf(outh, "\n");
3646 out_printf (out, "\n/*\n"
3647 " * Signal connection wrapper macro shortcuts\n"
3649 put_local_signal_macros (c);
3650 out_printf(outh, "\n");
3653 /* argument wrapping macros */
3654 if(get_properties > 0 || set_properties > 0) {
3655 out_printf(outh, "\n/*\n"
3656 " * Argument wrapping macros\n"
3659 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3660 put_argument_gnu_wrappers(c);
3661 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3662 put_argument_nongnu_wrappers(c);
3663 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3665 put_argument_nongnu_wrappers(c);
3670 for(li = c->nodes; li != NULL; li = li->next) {
3672 if(n->type == METHOD_NODE)
3673 add_signal_prots((Method *)n);
3679 if(any_method_to_alias(c)) {
3680 out_printf (out, "/* Short form macros */\n");
3681 make_method_aliases (c);
3684 add_interface_inits (c);
3686 if ( ! overrode_get_type) {
3687 if (c->bonobo_object_class != NULL)
3688 add_bonobo_object_get_type ();
3693 out_printf (out, "/* a macro for creating a new object of our type */\n");
3695 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
3696 typebase, funcbase);
3698 out_printf (out, "/* a function for creating a new object of our type */\n");
3699 out_printf (out, "#include <stdarg.h>\n");
3701 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
3702 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
3703 "{\n\t%s *ret;\n\tva_list ap;\n"
3704 "\tva_start (ap, first);\n"
3705 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
3708 "\treturn ret;\n}\n\n",
3710 no_gnu ? "" : " G_GNUC_UNUSED",
3711 typebase, typebase, typebase, funcbase);
3715 out_printf (out, "/* a function to connect glade callback */\n");
3716 out_printf (out,"static void\n"
3717 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
3718 "GObject *object,\n"
3719 "const gchar *signal_name,\n"
3720 "const gchar *signal_data,\n"
3721 "GObject *connect_object,\n"
3723 "gpointer user_data)\n"
3725 "\tstatic GModule * allsymbols = NULL;\n"
3727 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
3728 "\tif (allsymbols) {\n"
3729 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
3730 "\t\tGCallback func;\n"
3732 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
3733 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
3734 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
3735 "\t\t\t\tg_free(func_name);\n"
3740 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
3742 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
3743 "\t\tg_free(func_name);\n"
3750 for (li = nodes; li != NULL; li = li->next) {
3751 Node *node = li->data;
3752 if (node->type == CCODE_NODE) {
3753 CCode *cc = (CCode *)node;
3754 if (cc->cctype == AD_CCODE)
3755 print_ccode_block (cc);
3759 if (need_constructor)
3760 add_constructor (c);
3770 if(set_properties > 0) {
3771 add_getset_arg(c, TRUE);
3774 if(get_properties > 0) {
3775 add_getset_arg(c, FALSE);
3778 for(li = c->nodes; li != NULL; li = li->next) {
3780 if(n->type == METHOD_NODE)
3781 put_method((Method *)n);
3784 add_bad_hack_to_avoid_unused_warnings(c);
3788 print_useful_macros(void)
3790 int major = 0, minor = 0, pl = 0;
3793 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
3794 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
3795 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
3796 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
3798 /* Useful priv macro thingie */
3799 /* FIXME: this should be done the same way that priv is, as a var,
3801 out_printf (out, "#define selfp (self->_priv)\n\n");
3805 print_more_useful_macros (void)
3808 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3809 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3811 out_printf (out, "#ifdef G_LIKELY\n");
3812 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
3813 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
3814 out_printf (out, "#else /* ! G_LIKELY */\n");
3815 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
3816 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
3817 out_printf (out, "#endif /* G_LIKELY */\n");
3822 print_file_comments(void)
3824 out_printf(outh, "/* Generated by GOB (v%s)"
3825 " (do not edit directly) */\n\n", VERSION);
3827 out_printf(outph, "/* Generated by GOB (v%s)"
3828 " (do not edit directly) */\n\n", VERSION);
3829 out_printf(out, "/* Generated by GOB (v%s)"
3830 " (do not edit directly) */\n\n", VERSION);
3832 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
3836 print_includes(void)
3838 gboolean found_header;
3841 /* We may need string.h for memset */
3842 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
3843 out_printf(out, "#include <string.h> /* memset() */\n\n");
3846 p = g_strconcat(filebase, ".h", NULL);
3847 found_header = TRUE;
3848 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
3849 out_printf(out, "#include \"%s.h\"\n\n", filebase);
3850 found_header = FALSE;
3854 /* if we are creating a private header see if it was included */
3856 char sep[2] = {0,0};
3859 p = g_strconcat(filebase, sep, "private.h", NULL);
3860 if( ! g_list_find_custom(include_files, p,
3861 (GCompareFunc)strcmp)) {
3862 out_printf(out, "#include \"%s%cprivate.h\"\n\n",
3866 error_printf(GOB_WARN, 0,
3867 "Implicit private header include "
3869 "\tsource file, while public "
3870 "header is at a custom location, "
3872 "\texplicitly include "
3873 "the private header below the "
3881 print_header_prefixes(void)
3885 p = replace_sep(((Class *)class)->otype, '_');
3887 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
3889 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
3890 "#define __%s_PRIVATE_H__\n\n"
3891 "#include \"%s.h\"\n\n", p, p, filebase);
3894 if( ! no_extern_c) {
3895 out_printf(outh, "#ifdef __cplusplus\n"
3897 "#endif /* __cplusplus */\n\n");
3899 out_printf(outph, "#ifdef __cplusplus\n"
3901 "#endif /* __cplusplus */\n\n");
3906 print_header_postfixes(void)
3909 out_printf(outh, "\n#ifdef __cplusplus\n"
3911 "#endif /* __cplusplus */\n");
3912 out_printf(outh, "\n#endif\n");
3915 out_printf(outph, "\n#ifdef __cplusplus\n"
3917 "#endif /* __cplusplus */\n");
3918 out_printf(outph, "\n#endif\n");
3927 /* print the AT_CCODE blocks */
3928 for(li = nodes; li != NULL; li = li->next) {
3929 Node *node = li->data;
3930 if(node->type == CCODE_NODE) {
3931 CCode *cc = (CCode *)node;
3932 if(cc->cctype == AT_CCODE)
3933 print_ccode_block((CCode *)node);
3939 print_header_top(void)
3943 /* mandatory includes */
3944 out_printf (outh, "#include <glib.h>\n");
3945 out_printf (outh, "#include <glib-object.h>\n");
3947 /* print the HT_CCODE blocks */
3948 for (li = nodes; li != NULL; li = li->next) {
3949 Node *node = li->data;
3950 if (node->type == CCODE_NODE) {
3951 CCode *cc = (CCode *)node;
3952 if (cc->cctype == HT_CCODE)
3953 print_ccode_block ((CCode *)node);
3959 print_enum (EnumDef *enode)
3966 funcprefix = replace_sep (enode->etype, '_');
3967 gob_strdown (funcprefix);
3968 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
3970 type = remove_sep (enode->etype);
3972 out_printf (outh, "\ntypedef enum {\n");
3974 for (li = enode->values; li != NULL; li = li->next) {
3975 EnumValue *value = li->data;
3977 char *sname = gob_strdown (g_strdup (value->name));
3979 while ((p = strchr (sname, '_')) != NULL)
3982 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
3983 if (value->value != NULL)
3984 out_printf (outh, " = %s", value->value);
3985 if (li->next != NULL)
3986 out_printf (outh, ",\n");
3988 out_printf (outh, "\n");
3990 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
3991 enode->prefix, value->name,
3992 enode->prefix, value->name,
3998 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4000 out_printf (outh, "} %s;\n", type);
4002 str = make_pre_macro (enode->etype, "TYPE");
4003 out_printf (outh, "#define %s ", str);
4006 out_printf (outh, "%s_get_type()\n", funcprefix);
4007 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4010 "GType\n%s_get_type (void)\n"
4012 "\tstatic GType type = 0;\n"
4013 "\tif ___GOB_UNLIKELY(type == 0)\n"
4014 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4017 funcprefix, type, funcprefix);
4019 g_free (funcprefix);
4024 print_flags (Flags *fnode)
4032 funcprefix = replace_sep (fnode->ftype, '_');
4033 gob_strdown (funcprefix);
4034 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4036 type = remove_sep (fnode->ftype);
4038 out_printf (outh, "\ntypedef enum {\n");
4040 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4041 const char *name = li->data;
4043 char *sname = gob_strdown (g_strdup (name));
4045 while ((p = strchr (sname, '_')) != NULL)
4048 out_printf (outh, "\t%s_%s = 1<<%d",
4049 fnode->prefix, name, i);
4050 if (li->next != NULL)
4051 out_printf (outh, ",\n");
4053 out_printf (outh, "\n");
4055 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4056 fnode->prefix, name,
4057 fnode->prefix, name,
4063 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4065 out_printf (outh, "} %s;\n", type);
4067 str = make_pre_macro (fnode->ftype, "TYPE");
4068 out_printf (outh, "#define %s ", str);
4071 out_printf (outh, "%s_get_type()\n", funcprefix);
4072 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4075 "GType\n%s_get_type (void)\n"
4077 "\tstatic GType type = 0;\n"
4078 "\tif ___GOB_UNLIKELY(type == 0)\n"
4079 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4082 funcprefix, type, funcprefix);
4084 g_free (funcprefix);
4089 print_error (Error *enode)
4096 funcprefix = replace_sep (enode->etype, '_');
4097 gob_strdown (funcprefix);
4098 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4100 type = remove_sep (enode->etype);
4102 out_printf (outh, "\ntypedef enum {\n");
4104 for (li = enode->values; li != NULL; li = li->next) {
4105 const char *name = li->data;
4107 char *sname = gob_strdown (g_strdup (name));
4109 while ((p = strchr (sname, '_')) != NULL)
4112 out_printf (outh, "\t%s_%s", enode->prefix, name);
4113 if (li->next != NULL)
4114 out_printf (outh, ",\n");
4116 out_printf (outh, "\n");
4118 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4119 enode->prefix, name,
4120 enode->prefix, name,
4126 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4128 out_printf (outh, "} %s;\n", type);
4130 str = make_pre_macro (enode->etype, "TYPE");
4131 out_printf (outh, "#define %s ", str);
4134 out_printf (outh, "%s_get_type ()\n", funcprefix);
4135 out_printf (outh, "GType %s_get_type (void) G_GNUC_CONST;\n\n", funcprefix);
4138 "GType\n%s_get_type (void)\n"
4140 "\tstatic GType type = 0;\n"
4141 "\tif ___GOB_UNLIKELY(type == 0)\n"
4142 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4145 funcprefix, type, funcprefix);
4147 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4148 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4150 str = replace_sep (enode->etype, '-');
4154 "GQuark\n%s_quark (void)\n"
4156 "\tstatic GQuark q = 0;\n"
4158 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4165 g_free (funcprefix);
4170 generate_outfiles(void)
4174 print_file_comments();
4180 print_header_prefixes();
4182 print_useful_macros();
4186 print_more_useful_macros ();
4188 for (li = nodes; li != NULL; li = li->next) {
4189 Node *node = li->data;
4190 if (node->type == CCODE_NODE) {
4191 CCode *cc = (CCode *)node;
4192 if (cc->cctype != HT_CCODE &&
4193 cc->cctype != AT_CCODE &&
4194 cc->cctype != AD_CCODE)
4195 print_ccode_block ((CCode *)node);
4196 } else if (node->type == CLASS_NODE) {
4197 print_class_block ((Class *)node);
4198 } else if (node->type == ENUMDEF_NODE) {
4199 print_enum ((EnumDef *)node);
4200 } else if (node->type == FLAGS_NODE) {
4201 print_flags ((Flags *)node);
4202 } else if (node->type == ERROR_NODE) {
4203 print_error ((Error *)node);
4205 g_assert_not_reached();
4209 print_header_postfixes();
4215 fprintf(stderr, "Gob version %s\n\n", VERSION);
4216 fprintf(stderr, "gob [options] file.gob\n\n");
4217 fprintf(stderr, "Options:\n"
4218 "\t--help,-h,-? Display this help\n"
4219 "\t--version Display version\n"
4220 "\t--exit-on-warn,-w Exit with an error on warnings\n"
4221 "\t--no-exit-on-warn Don't exit on warnings [default]\n"
4222 "\t--for-cpp Create C++ files\n"
4223 "\t--no-extern-c Never print extern \"C\" into the "
4225 "\t--no-gnu Never use GNU extentions\n"
4226 "\t--no-touch Don't touch output files unless they "
4228 "\t changed (implies --no-touch-headers)\n"
4229 "\t--no-touch-headers Don't touch headers unless they "
4231 "\t--always-private-header Always create a private header "
4233 "\t even if it would be empty\n"
4234 "\t--ondemand-private-header Create private header only when "
4237 "\t--no-private-header Don't create a private header, "
4239 "\t structure and protected "
4240 "prototypes inside c file\n"
4241 "\t--always-private-struct Always create a private pointer "
4243 "\t the object structure\n"
4244 "\t--m4 Preprocess source with m4. "
4245 "Following args will\n"
4246 "\t be passed to m4\n"
4247 "\t--m4-dir Print directory that will be "
4250 "\t--no-write,-n Don't write output files, just "
4252 "\t--no-lines Don't print '#line' to output\n"
4253 "\t--no-self-alias Don't create self type and macro "
4255 "\t--no-kill-underscores Ignored for compatibility\n"
4256 "\t-o,--output-dir The directory where output "
4257 "should be placed\n"
4258 "\t--file-sep[=c] replace default \'-\' file "
4259 "name separator\n\n");
4260 fprintf(stderr, "End world hunger, donate to the World Food Programme, http://www.wfp.org\n");
4264 parse_options(int argc, char *argv[])
4267 int got_file = FALSE;
4268 int no_opts = FALSE;
4269 int m4_opts = FALSE; /* if we are just passing on args to m4 */
4273 for(i = 1 ; i < argc; i++) {
4275 char *new_commandline;
4276 g_assert(m4_commandline!=NULL);
4278 /* check whether this one looks like the filename */
4279 if((!strcmp(argv[i],"-") || argv[i][0] != '-')
4281 const gchar *m4_flags=use_m4_clean?"":M4_FLAGS;
4285 /* insert flags before the filename */
4286 new_commandline=g_strconcat(m4_commandline,
4294 /* just an ordinary option */
4296 new_commandline=g_strconcat(m4_commandline,
4301 /* free old commandline */
4302 g_free(m4_commandline);
4303 m4_commandline=new_commandline;
4305 } else if(no_opts ||
4306 argv[i][0] != '-') {
4309 fprintf(stderr, "Specify only one file!\n");
4315 } else if(strcmp(argv[i], "--help")==0) {
4318 } else if(strcmp(argv[i], "--version")==0) {
4319 fprintf(stderr, "Gob version %s\n", VERSION);
4321 } else if(strcmp(argv[i], "--exit-on-warn")==0) {
4322 exit_on_warn = TRUE;
4323 } else if(strcmp(argv[i], "--no-exit-on-warn")==0) {
4324 exit_on_warn = FALSE;
4325 } else if(strcmp(argv[i], "--for-cpp")==0) {
4327 } else if(strcmp(argv[i], "--no-touch")==0) {
4329 no_touch_headers = TRUE;
4330 } else if(strcmp(argv[i], "--no-touch-headers")==0) {
4331 no_touch_headers = TRUE;
4332 } else if(strcmp(argv[i], "--ondemand-private-header")==0) {
4333 private_header = PRIVATE_HEADER_ONDEMAND;
4334 } else if(strcmp(argv[i], "--always-private-header")==0) {
4335 private_header = PRIVATE_HEADER_ALWAYS;
4336 } else if(strcmp(argv[i], "--no-private-header")==0) {
4337 private_header = PRIVATE_HEADER_NEVER;
4338 } else if(strcmp(argv[i], "--no-gnu")==0) {
4340 } else if(strcmp(argv[i], "--no-extern-c")==0) {
4342 } else if(strcmp(argv[i], "--no-write")==0) {
4344 } else if(strcmp(argv[i], "--no-lines")==0) {
4346 } else if(strcmp(argv[i], "--no-self-alias")==0) {
4347 no_self_alias = TRUE;
4348 } else if(strcmp(argv[i], "--no-kill-underscores")==0) {
4350 } else if(strcmp(argv[i], "--always-private-struct")==0) {
4351 always_private_struct = TRUE;
4352 } else if(strcmp(argv[i], "--m4-dir")==0) {
4353 printf("%s\n",M4_INCLUDE_DIR);
4355 } else if(strcmp(argv[i], "--m4")==0) {
4359 m4_commandline=g_strdup(M4_COMMANDLINE);
4360 } else if(strcmp(argv[i], "--m4-clean")==0) {
4364 m4_commandline=g_strdup(M4_COMMANDLINE);
4365 } else if (strcmp (argv[i], "-o") == 0 ||
4366 strcmp (argv[i], "--output-dir") == 0) {
4368 output_dir = g_strdup (argv[i+1]);
4373 } else if (strncmp (argv[i], "-o=", strlen ("-o=")) == 0 ||
4376 strlen ("--output-dir=")) == 0) {
4377 char *p = strchr (argv[i], '=');
4378 g_assert (p != NULL);
4379 output_dir = g_strdup (p+1);
4380 } else if (strncmp (argv[i], "--file-sep=",
4381 strlen ("--file-sep=")) == 0) {
4382 char *p = strchr (argv[i], '=');
4383 g_assert (p != NULL);
4385 } else if (strncmp (argv[i], "--file-sep",
4386 strlen ("--file-sep")) == 0) {
4388 file_sep = (argv[i+1])[0];
4393 } else if(strcmp(argv[i], "--")==0) {
4394 /*further arguments are files*/
4396 } else if(strncmp(argv[i], "--", 2)==0) {
4397 /*unknown long option*/
4398 fprintf(stderr, "Unknown option '%s'!\n", argv[i]);
4402 /*by now we know we have a string starting with
4403 - which is a short option string*/
4405 for(p = argv[i] + 1; *p; p++) {
4419 "Unknown option '%c'!\n", *p);
4428 /* if we are using m4, and got no filename, append m4 flags now */
4429 if(!got_file && use_m4 && !use_m4_clean) {
4430 char *new_commandline;
4431 new_commandline=g_strconcat(m4_commandline,
4435 g_free(m4_commandline);
4436 m4_commandline=new_commandline;
4442 compare_and_move (const char *old_filename)
4444 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4446 gboolean equal = FALSE;
4448 old_f = fopen (old_filename, "r");
4451 gboolean error = FALSE;
4453 new_f = fopen (new_filename, "r");
4462 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4463 if (ferror (new_f)) {
4465 error_printf (GOB_ERROR, 0,
4466 "Can't read %s: %s",
4468 g_strerror (errno));
4472 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4474 || feof (new_f) != feof (old_f)
4476 || memcmp (new_buf, old_buf, new_n) != 0)
4485 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4486 new_filename, g_strerror (errno));
4494 if (! equal && unlink (old_filename) != 0) {
4495 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4496 old_filename, g_strerror (errno));
4502 if (unlink (new_filename) != 0)
4503 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4504 new_filename, g_strerror (errno));
4506 if (rename (new_filename, old_filename) != 0)
4507 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4508 new_filename, old_filename,
4509 g_strerror (errno));
4513 g_free (new_filename);
4517 main(int argc, char *argv[])
4519 parse_options(argc, argv);
4522 yyin = popen(m4_commandline, "r");
4524 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4528 } else if(filename) {
4529 yyin = fopen(filename, "r");
4531 fprintf(stderr, "Error: can't open file '%s'\n",
4540 /* This is where parsing is done */
4543 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4545 /* close input file */
4546 if(use_m4) pclose(yyin);
4551 error_print (GOB_ERROR, 0, "no class defined");
4554 exit_on_error = FALSE;
4556 signals = count_signals ((Class *)class);
4557 set_properties = count_set_properties ((Class *)class) +
4558 count_set_arguments ((Class *)class);
4559 get_properties = count_get_properties ((Class *)class) +
4560 count_get_arguments ((Class *)class);
4561 overrides = count_overrides ((Class *)class);
4562 privates = count_privates ((Class *)class);
4563 protecteds = count_protecteds ((Class *)class);
4564 unreftors = count_unreftors ((Class *)class);
4565 destructors = count_destructors ((Class *)class);
4566 initializers = count_initializers ((Class *)class);
4567 glade_widgets = count_glade_widgets ((Class *)class);
4568 overrode_get_type = find_get_type ((Class *)class);
4571 make_inits ((Class *)class);
4573 find_constructor ((Class *)class);
4574 if (user_constructor != NULL)
4575 need_constructor = TRUE;
4577 find_dispose ((Class *)class);
4578 if (unreftors > 0 ||
4579 dispose_handler != NULL ||
4580 user_dispose_method != NULL)
4581 need_dispose = TRUE;
4583 find_finalize ((Class *)class);
4584 if (destructors > 0 ||
4586 user_finalize_method != NULL) {
4587 need_finalize = TRUE;
4590 check_bad_symbols ((Class *)class);
4591 check_duplicate_symbols ((Class *)class);
4592 check_duplicate_overrides ((Class *)class);
4593 check_duplicate_signals_args ((Class *)class);
4594 check_public_new ((Class *)class);
4595 check_vararg ((Class *)class);
4596 check_firstarg ((Class *)class);
4597 check_nonvoidempty ((Class *)class);
4598 check_signal_args ((Class *)class);
4599 check_property_types ((Class *)class);
4600 check_argument_types ((Class *)class);
4601 check_func_arg_checks ((Class *)class);
4602 check_func_attrs ((Class *)class);
4603 check_for_class_destructors ((Class *)class);
4605 exit_on_error = TRUE;
4610 any_special = setup_special_array ((Class *)class, special_array);
4614 generate_outfiles ();
4625 compare_and_move (outfilebase);
4627 compare_and_move (outfilephbase);
4629 if (no_touch_headers)
4630 compare_and_move (outfilehbase);