2 * Copyright (C) 1999,2000 the Free Software Foundation.
3 * Copyright (C) 2000 Eazel, Inc.
4 * Copyright (C) 2001-2011 George (Jiri) Lebl
5 * Copyright © 2019-2021 Nick Bowler
7 * Author: George (Jiri) Lebl
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
37 #include "treefuncs.h"
47 static const char sopts[] = SOPT_STRING;
48 static const struct option lopts[] = {
53 char *filename = NULL;
63 extern GList *include_files;
65 extern GHashTable *gtk_doc_hash;
69 static char *outfilebase;
70 static char *outfilehbase;
71 static char *outfilephbase;
72 static char *funcbase;
73 static char *pfuncbase;
74 static char *macrobase;
76 static char *pmacrois;
77 static char *macrotype;
78 static char *pmacrotype;
79 static char *typebase;
80 static char *ptypebase;
82 char *output_dir = NULL;
86 static int signals = 0; /* number of signals */
87 static int set_properties = 0; /* number of named (set) properties */
88 static int get_properties = 0; /* number of named (get) properties */
89 static int overrides = 0; /* number of override methods */
90 static int privates = 0; /* number of private data members */
91 static int protecteds = 0; /* number of protected methods */
92 static int unreftors = 0; /* number of variable unreffing destructors */
93 static int destructors = 0; /* number of variable non-unreffing destructors */
94 static int initializers = 0; /* number of variable initializers */
95 static int glade_widgets = 0; /* number of glade widgets */
96 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
98 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
99 and need the REALLY UGLY HACK to
102 /* the special variable types we need to define */
103 static gboolean special_array[SPECIAL_LAST] = {0};
104 static gboolean any_special = FALSE;
106 static gboolean need_constructor = FALSE;
107 static Method * user_constructor = NULL;
109 static gboolean need_dispose = FALSE;
110 static Method * dispose_handler = NULL;
111 static Method * user_dispose_method = NULL;
113 static gboolean need_finalize = FALSE;
114 static Method * finalize_handler = NULL;
115 static Method * user_finalize_method = NULL;
121 gboolean no_touch = FALSE;
122 gboolean no_touch_headers = FALSE;
123 gboolean for_cpp = FALSE;
124 gboolean no_gnu = FALSE;
125 gboolean exit_on_warn = FALSE;
126 gboolean exit_on_error = TRUE;
127 gboolean got_error = FALSE;
128 gint private_header = PRIVATE_HEADER_ONDEMAND;
129 gboolean no_extern_c = FALSE;
130 gboolean no_write = FALSE;
131 gboolean no_lines = FALSE;
132 gboolean no_self_alias = FALSE;
133 gboolean always_private_struct = FALSE;
134 gboolean gtk3_ok = FALSE;
140 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
141 char *m4_commandline = NULL;
142 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
143 #define M4_BASE_FILENAME "gobm4.m4"
144 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
145 #define M4_COMMANDLINE "m4"
147 int method_unique_id = 1;
152 filebase = replace_sep (((Class *)class)->otype, file_sep);
153 gob_strdown (filebase);
155 if (output_dir != NULL &&
156 output_dir[0] != '\0') {
157 fullfilebase = g_build_filename (output_dir, filebase, NULL);
159 fullfilebase = g_strdup (filebase);
162 funcbase = replace_sep (((Class *)class)->otype, '_');
163 gob_strdown (funcbase);
165 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
166 gob_strdown (pfuncbase);
168 macrobase = replace_sep (((Class *)class)->otype, '_');
169 gob_strup (macrobase);
171 macrois = make_pre_macro (((Class *)class)->otype, "IS");
172 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
174 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
175 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
177 typebase = remove_sep (((Class *)class)->otype);
179 ptypebase = remove_sep (((Class *)class)->ptype);
183 get_gtk_doc (const char *id)
190 val = g_hash_table_lookup(gtk_doc_hash, id);
192 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
194 val = g_hash_table_lookup(gtk_doc_hash, id);
196 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
202 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
206 s = get_type(t, postfix_to_stars);
207 out_printf(fp, "%s", s);
213 print_method (FILE *fp,
214 const char *typeprefix,
215 const char *nameprefix,
216 const char *subnameprefix,
217 const char *namepostfix,
218 const char *afterargs,
221 gboolean print_funcattrs,
222 gboolean one_arg_per_line,
223 gboolean no_funcbase,
224 gboolean kill_underscore,
225 gboolean first_unused,
231 out_printf(fp, "%s", typeprefix);
232 print_type(fp, m->mtype, TRUE);
237 out_printf(fp, "%s%s%s%s(",
238 nameprefix, subnameprefix, id, namepostfix);
240 out_printf(fp, "%s%s_%s%s%s(",
241 nameprefix, funcbase, subnameprefix, id,
245 for(li=m->args; li; li=g_list_next(li)) {
246 FuncArg *arg = li->data;
247 const char *unused = "";
250 ! for_cpp && /* g++ has a cow with this */
253 unused = " G_GNUC_UNUSED";
256 print_type(fp, arg->atype, FALSE);
258 out_printf (fp, "___fake___");
260 out_printf(fp, "%s%s%s,%s", arg->name,
261 arg->atype->postfix ?
262 arg->atype->postfix : "",
264 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
266 out_printf(fp, "%s%s%s", arg->name,
267 arg->atype->postfix ?
268 arg->atype->postfix : "",
272 out_printf(fp, ",%s...",
273 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
275 out_printf(fp, "void");
277 /* Slightly icky: sometimes we are called st m->funcattrs
278 hasn't been set, but if so it should be NULL since its been
280 if(print_funcattrs && m->funcattrs != NULL
281 && strlen(m->funcattrs) > 0) {
282 /* To keep the output neat, we trim off the trailing '\n'
283 from the end of funcattrs for a moment. */
284 size_t funcattrs_len = strlen(m->funcattrs);
285 gboolean funcattrs_chomped = FALSE;
286 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
287 m->funcattrs[funcattrs_len - 1] = '\0';
288 funcattrs_chomped = TRUE;
290 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
291 /* Put it back like it was (though it shouldn't matter). */
292 if (funcattrs_chomped) {
293 (m->funcattrs)[funcattrs_len - 1] = '\n';
297 out_printf(fp, "%s)%s", afterargs, postfix);
302 any_method_to_alias(Class *c)
306 for(li=c->nodes;li;li=g_list_next(li)) {
307 Node *node = li->data;
308 if(node->type == METHOD_NODE) {
309 Method *m = (Method *)node;
311 if(m->method == INIT_METHOD ||
312 m->method == CLASS_INIT_METHOD ||
313 m->method == CONSTRUCTOR_METHOD ||
314 m->method == DISPOSE_METHOD ||
315 m->method == FINALIZE_METHOD ||
316 m->method == OVERRIDE_METHOD)
327 make_method_aliases (Class *c)
331 for(li = c->nodes; li != NULL; li = li->next) {
332 Node *node = li->data;
333 if(node->type == METHOD_NODE) {
334 Method *m = (Method *)node;
336 if(m->method == INIT_METHOD ||
337 m->method == CLASS_INIT_METHOD ||
338 m->method == CONSTRUCTOR_METHOD ||
339 m->method == DISPOSE_METHOD ||
340 m->method == FINALIZE_METHOD ||
341 m->method == OVERRIDE_METHOD)
344 out_printf (out, "#define self_%s %s_%s\n",
353 add_bad_hack_to_avoid_unused_warnings(const Class *c)
357 /* if we haven't had any methods, just return */
362 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
364 "/*REALLY BAD HACK\n"
365 " This is to avoid unused warnings if you don't call\n"
366 " some method. I need to find a better way to do\n"
367 " this, not needed in GCC since we use some gcc\n"
368 " extentions to make saner, faster code */\n"
370 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
372 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
373 for(li=c->nodes;li;li=g_list_next(li)) {
374 Node *node = li->data;
375 if(node->type == METHOD_NODE) {
376 Method *m = (Method *)node;
378 if(m->method == INIT_METHOD ||
379 m->method == CLASS_INIT_METHOD ||
380 m->method == CONSTRUCTOR_METHOD ||
381 m->method == DISPOSE_METHOD ||
382 m->method == FINALIZE_METHOD ||
383 m->method == OVERRIDE_METHOD)
386 /* in C++ mode we don't alias new */
387 if(for_cpp && strcmp(m->id, "new")==0)
390 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
393 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
396 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
398 out_printf(out, "}\n\n");
402 put_variable(const Variable *v, FILE *fp)
404 out_printf(fp, "\t");
405 print_type(fp, v->vtype, FALSE);
406 out_printf(fp, "%s%s;", v->id,
408 v->vtype->postfix:"");
409 if(v->scope == PROTECTED_SCOPE)
410 out_printf(fp, " /* protected */");
411 out_printf(fp, "\n");
415 put_vs_method(const Method *m)
417 if(m->method != SIGNAL_LAST_METHOD &&
418 m->method != SIGNAL_FIRST_METHOD &&
419 m->method != VIRTUAL_METHOD)
422 /* if a signal mark it as such */
423 if(m->method != VIRTUAL_METHOD)
424 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
425 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
427 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
428 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
433 put_pub_method(const Method *m)
435 if(m->scope != PUBLIC_SCOPE)
438 out_addline_infile(outh, m->line_no);
439 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
440 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
441 out_addline_outfile(outh);
445 put_signal_macro (const Method *m, gboolean gnu)
447 if(m->method != SIGNAL_LAST_METHOD &&
448 m->method != SIGNAL_FIRST_METHOD)
453 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
454 "g_signal_connect(%s(object),\"%s\","
455 "(GCallback)(func),(data))\n",
456 funcbase, m->id, macrobase, m->id);
459 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
460 "g_signal_connect_after(%s(object),\"%s\","
461 "(GCallback)(func),(data))\n",
462 funcbase, m->id, macrobase, m->id);
465 out_printf (outh, "#define %s_connect_data__%s"
466 "(object,func,data,destroy_data,flags)\t"
467 "g_signal_connect_data(%s(object),\"%s\","
468 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
469 funcbase, m->id, macrobase, m->id);
472 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
474 "%s(__extension__ ({%s *___object = (object); ___object; })),"
476 "(GCallback) __extension__ ({",
477 funcbase, m->id, macrobase, typebase, m->id);
478 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
479 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
480 out_printf (outh, "___%s; }), (data))\n", m->id);
483 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
484 "g_signal_connect_after("
485 "%s(__extension__ ({%s *___object = (object); ___object; })),"
487 "(GCallback) __extension__ ({",
488 funcbase, m->id, macrobase, typebase, m->id);
489 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
490 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
491 out_printf (outh, "___%s; }), (data))\n", m->id);
494 out_printf (outh, "#define %s_connect_data__%s"
495 "(object,func,data,destroy_data,flags)\t"
496 "g_signal_connect_data("
497 "%s(__extension__ ({%s *___object = (object); ___object; })),"
499 "(GCallback) __extension__ ({",
500 funcbase, m->id, macrobase, typebase, m->id);
501 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
502 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
503 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
508 put_signal_macros (const Class *c, gboolean gnu)
515 for (li = c->nodes; li != NULL; li = li->next) {
516 const Node *n = li->data;
517 if (n->type == METHOD_NODE)
518 put_signal_macro ((Method *)n, gnu);
523 put_local_signal_macro (const Method *m)
525 if(m->method != SIGNAL_LAST_METHOD &&
526 m->method != SIGNAL_FIRST_METHOD)
530 out_printf (out, "#define self_connect__%s(object,func,data)\t"
531 "%s_connect__%s((object),(func),(data))\n",
532 m->id, funcbase, m->id);
535 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
536 "%s_connect_after__%s((object),(func),(data))\n",
537 m->id, funcbase, m->id);
540 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
541 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
542 m->id, funcbase, m->id);
546 put_local_signal_macros (const Class *c)
553 for (li = c->nodes; li != NULL; li = li->next) {
554 const Node *n = li->data;
555 if (n->type == METHOD_NODE)
556 put_local_signal_macro ((Method *)n);
562 put_prot_method(const Method *m)
566 if(m->scope != PROTECTED_SCOPE)
569 f = outph ? outph : out;
571 out_addline_infile(f, m->line_no);
572 print_method(f, "", "\t", "", "\t", "", ";\n",
573 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
574 out_addline_outfile(f);
578 put_priv_method_prot(const Method *m)
580 if(m->method == SIGNAL_LAST_METHOD ||
581 m->method == SIGNAL_FIRST_METHOD ||
582 m->method == VIRTUAL_METHOD) {
585 "static ", "___real_", "", " ", "", ";\n",
586 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
588 /* no else, here, it might still have a private prototype, it's not
591 if((m->method == OVERRIDE_METHOD &&
594 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
596 out_addline_infile(out, m->line_no);
597 print_method(out, "static ", s, "", " ", "",
598 no_gnu?";\n":" G_GNUC_UNUSED;\n",
599 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
601 out_addline_outfile(out);
603 } else if(m->scope == PRIVATE_SCOPE ||
604 m->method == INIT_METHOD ||
605 m->method == CLASS_INIT_METHOD ||
606 m->method == CONSTRUCTOR_METHOD ||
607 m->method == DISPOSE_METHOD ||
608 m->method == FINALIZE_METHOD) {
610 out_addline_infile(out, m->line_no);
611 print_method(out, "static ", "", "", " ", "",
612 no_gnu?";\n":" G_GNUC_UNUSED;\n",
613 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
615 out_addline_outfile(out);
620 make_func_arg (const char *typename, gboolean is_class, const char *name)
627 tn = g_strconcat (typename, ":Class", NULL);
629 tn = g_strdup (typename);
631 type = node_new (TYPE_NODE,
635 node = node_new (FUNCARG_NODE,
636 "atype:steal", (Type *)type,
639 return g_list_prepend (NULL, node);
643 make_inits(Class *cl)
645 int got_class_init = FALSE;
646 int got_init = FALSE;
649 for(li=cl->nodes;li;li=g_list_next(li)) {
651 if(n->type == METHOD_NODE) {
652 Method *m = (Method *)n;
653 if(m->method == INIT_METHOD) {
655 error_print(GOB_ERROR, m->line_no, "init defined more then once");
657 } else if(m->method == CLASS_INIT_METHOD) {
659 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
660 got_class_init = TRUE;
664 if(!got_class_init) {
665 Type *type = (Type *)node_new (TYPE_NODE,
668 node = node_new (METHOD_NODE,
670 "method", CLASS_INIT_METHOD,
673 "args:steal", make_func_arg (cl->otype,
676 "unique_id", method_unique_id++,
678 cl->nodes = g_list_prepend(cl->nodes, node);
681 Type *type = (Type *)node_new (TYPE_NODE,
684 node = node_new (METHOD_NODE,
686 "method", INIT_METHOD,
689 "args:steal", make_func_arg (cl->otype,
690 FALSE /* is_class */,
692 "unique_id", method_unique_id++,
694 cl->nodes = g_list_prepend(cl->nodes, node);
699 find_method(const Class *cl, int method, const char *id)
703 for(li=cl->nodes;li;li=g_list_next(li)) {
705 if(n->type == METHOD_NODE) {
706 Method *m = (Method *)n;
707 if (m->method == method
708 && (id == NULL || strcmp(m->id, id)==0))
717 find_constructor(const Class *cl)
719 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
723 find_dispose(const Class *cl)
725 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
726 if (dispose_handler != NULL) {
727 if(strcmp(dispose_handler->otype, "G:Object") != 0)
728 error_print(GOB_ERROR, dispose_handler->line_no,
729 "dispose method override "
730 "of class other then "
732 if(g_list_length(dispose_handler->args) != 1)
733 error_print(GOB_ERROR, dispose_handler->line_no,
734 "dispose method override "
735 "with more then one "
739 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
743 find_finalize(const Class *cl)
745 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
746 if (finalize_handler != NULL) {
747 if(strcmp(finalize_handler->otype, "G:Object") != 0)
748 error_print(GOB_ERROR, finalize_handler->line_no,
749 "finalize method override "
750 "of class other then "
752 if(g_list_length(finalize_handler->args) != 1)
753 error_print(GOB_ERROR, finalize_handler->line_no,
754 "finalize method override "
755 "with more then one "
759 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
763 /* hash of method -> name of signal prototype */
764 static GHashTable *marsh = NULL;
766 /* list of methods with different signal prototypes,
767 we check this list if we can use a signal prototype of a
768 previous signal method, there are only uniques here */
769 static GList *eq_signal_methods = NULL;
771 /* compare a list of strings */
773 is_list_equal(const GList *a, const GList *b)
775 for(;a && b; a=a->next, b=b->next) {
776 if(strcmp(a->data, b->data)!=0) {
780 /* the the lists were different length */
787 find_same_type_signal(const Method *m)
790 for(li=eq_signal_methods;li;li=li->next) {
791 Method *mm = li->data;
792 if(is_list_equal(mm->gtktypes, m->gtktypes))
799 print_signal_marsal_args (const Method *m)
801 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
804 for (i = 0, li = m->gtktypes->next;
806 i++, li = li->next) {
809 if (strcmp (li->data, "UNICHAR") == 0)
810 /* hack because glib is braindamaged */
811 get_func = g_strdup ("g_value_get_uint");
812 else if (strncmp(li->data, "BOXED_", 6) == 0)
813 get_func = g_strdup ("g_value_get_boxed");
815 get_func = g_strdup_printf
816 ("g_value_get_%s", (char *)li->data);
818 gob_strdown (get_func);
819 out_printf (out, ",\n\t\t(%s) "
820 "%s (param_values + %d)",
821 get_cast (li->data, FALSE),
826 out_printf (out, ",\n\t\tdata2);\n");
831 add_signal_prots(Method *m)
837 gboolean ret_none = FALSE;
838 gboolean arglist_none = FALSE;
840 const char *unused = "";
842 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
843 unused = " G_GNUC_UNUSED";
846 if (m->method != SIGNAL_LAST_METHOD &&
847 m->method != SIGNAL_FIRST_METHOD)
851 marsh = g_hash_table_new(NULL, NULL);
853 g_assert (m->gtktypes->next != NULL);
855 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
856 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
858 if (ret_none && arglist_none)
861 /* if we already did a signal prototype just use that */
862 mm = find_same_type_signal (m);
864 s = g_hash_table_lookup (marsh, mm);
865 g_hash_table_insert (marsh, m, s);
872 retcast = get_cast (m->gtktypes->data, FALSE);
874 s = g_strdup_printf("Sig%d", sig++);
876 g_hash_table_insert(marsh, m, s);
877 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
879 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
880 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
881 get_cast(m->gtktypes->data, FALSE), s, typebase);
883 if ( ! arglist_none) {
884 for (li = m->gtktypes->next; li != NULL; li = li->next)
885 out_printf (out, "%s, ", get_cast (li->data, FALSE));
887 out_printf (out, "gpointer);\n");
889 out_printf (out, "\nstatic void\n"
890 "___marshal_%s (GClosure *closure,\n"
891 "\tGValue *return_value%s,\n"
892 "\tguint n_param_values,\n"
893 "\tconst GValue *param_values,\n"
894 "\tgpointer invocation_hint%s,\n"
895 "\tgpointer marshal_data)\n"
902 out_printf (out, "\t%s v_return;\n", retcast);
904 out_printf (out, "\tregister ___%s callback;\n"
905 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
906 "\tregister gpointer data1, data2;\n\n",
909 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
910 arglist_none ? 1 : g_list_length (m->gtktypes));
913 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
914 "\t\tdata1 = closure->data;\n"
915 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
917 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
918 "\t\tdata2 = closure->data;\n"
921 out_printf (out, "\tcallback = (___%s) "
922 "(marshal_data != NULL ? marshal_data : cc->callback);"
926 out_printf (out, "\tcallback ((%s *)data1", typebase);
928 out_printf (out, "\tv_return = callback ((%s *)data1",
932 print_signal_marsal_args (m);
935 /* FIXME: This code is so fucking ugly it hurts */
936 gboolean take_ownership =
937 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
938 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
942 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
943 /* hack because glib is braindamaged */
944 set_func = g_strdup ("g_value_set_uint");
946 set_func = g_strdup_printf ("g_value_%s_%s",
949 (char *)m->gtktypes->data);
950 gob_strdown (set_func);
952 out_printf (out, "\n\t%s (return_value, v_return);\n",
957 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
959 out_printf (out, "\n\treturn_value = NULL;\n");
960 out_printf (out, "\tinvocation_hint = NULL;\n");
963 out_printf (out, "}\n\n");
967 interface_type(const char *if_name)
969 char *rawtype = remove_sep(if_name);
970 char *end = "", *typename;
974 * EEEK! evil, we should have some sort of option
975 * to force this for arbitrary interfaces, since
976 * some are Class and some are Iface. Glib is shite
980 if (strcmp (rawtype, "GtkEditable") == 0
981 || strcmp (rawtype, "GTypePlugin") == 0)
985 /* We'll assume Iface is the standard ending */
989 /* GTK3 doesn't need Iface end */
993 typename = g_strconcat(rawtype, end, (char *)NULL);
1000 define_parent_interface_refs(Class *c)
1007 out_printf(out, "\n/* parent class interface implementations */\n");
1008 for (li = c->interfaces; li != NULL; li = li->next) {
1009 char *name = replace_sep(li->data, '_');
1010 char *type = interface_type(li->data);
1012 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1023 out_printf(out, "\n");
1025 out_printf(out, "enum {\n");
1026 for(li=c->nodes;li;li=g_list_next(li)) {
1028 if(n->type == METHOD_NODE) {
1029 Method *m = (Method *)n;
1030 if(m->method == SIGNAL_LAST_METHOD ||
1031 m->method == SIGNAL_FIRST_METHOD) {
1032 char *s = g_strdup(m->id);
1034 out_printf(out, "\t%s_SIGNAL,\n", s);
1039 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1041 if (set_properties > 0 ||
1042 get_properties > 0) {
1043 out_printf(out, "enum {\n\tPROP_0");
1044 for(li=c->nodes;li;li=g_list_next(li)) {
1046 if (n->type == PROPERTY_NODE) {
1047 Property *p = (Property *)n;
1048 char *s = g_strdup (p->name);
1050 out_printf (out, ",\n\tPROP_%s", s);
1052 } else if (n->type == ARGUMENT_NODE) {
1053 Argument *a = (Argument *)n;
1054 char *s = g_strdup(a->name);
1056 out_printf(out, ",\n\tPROP_%s", s);
1060 out_printf(out, "\n};\n\n");
1065 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1067 out_printf(out, "/* pointer to the class of our parent */\n");
1068 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1069 define_parent_interface_refs(c);
1070 out_printf(out, "\n");
1074 add_interface_methods (Class *c, const char *interface)
1077 gboolean added_line = FALSE;
1079 for (li = c->nodes; li != NULL; li = li->next) {
1081 Method *m = (Method *)n;
1082 if (n->type != METHOD_NODE ||
1083 m->method == OVERRIDE_METHOD ||
1084 m->interface == NULL ||
1085 strcmp (m->interface, interface) != 0)
1088 if (m->line_no > 0) {
1089 out_addline_infile (out, m->line_no);
1091 } else if (m->line_no == 0 &&
1093 out_addline_outfile (out);
1096 out_printf (out, "\tiface->%s = self_%s;\n",
1100 out_addline_outfile (out);
1104 add_interface_inits(Class *c)
1108 if (c->interfaces == NULL)
1111 out_printf(out, "\n");
1113 for (li = c->interfaces; li != NULL; li = li->next) {
1114 char *name = replace_sep(li->data, '_');
1115 char *type = interface_type(li->data);
1117 out_printf(out, "static void\n"
1118 "___%s_init (%s *iface)\n"
1121 add_interface_methods(c, li->data);
1123 out_printf(out, "\t%s_parent_iface\n", name);
1124 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1125 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1134 add_interface_infos(Class *c, gboolean static_storage)
1138 for (li = c->interfaces; li; li = li->next) {
1139 char *name = replace_sep(li->data, '_');
1140 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1141 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1145 static_storage ? "static " : "",
1150 out_printf(out, "\n");
1154 define_add_interfaces(Class *c)
1161 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1162 add_interface_infos(c, TRUE);
1164 for (li = c->interfaces; li; li = li->next) {
1165 char *type = make_pre_macro(li->data, "TYPE");
1166 char *name = replace_sep(li->data, '_');
1168 out_printf(out, "\tg_type_add_interface_static\n"
1179 out_printf(out, "}\n\n");
1183 define_dynamic_add_interfaces(Class *c)
1190 out_printf(out, "static void ___add_interfaces"
1191 "(GTypeModule *type_module, GType type)\n"
1193 add_interface_infos(c, FALSE);
1196 * Hack to work around bug in g_type_module_add_interface,
1197 * which will fail to add an interface to types that derive
1198 * from something that also implements the same interface.
1200 * The actual GType system does not have any such problem,
1201 * and the GTypeModule implementation details relied upon
1202 * here have not changed once since the feature was first
1203 * implemented almost 20 years ago.
1205 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1206 "\t\tgboolean loaded;\n"
1207 "\t\tGType instance_type;\n"
1208 "\t\tGType interface_type;\n"
1209 "\t\tGInterfaceInfo info;\n"
1212 for (li = c->interfaces; li; li = li->next) {
1213 char *type = make_pre_macro(li->data, "TYPE");
1214 char *name = replace_sep(li->data, '_');
1216 out_printf(out, "\n"
1217 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1218 "\tmodinfo->loaded = TRUE;\n"
1219 "\tmodinfo->instance_type = type;\n"
1220 "\tmodinfo->interface_type = %s;\n"
1221 "\tmodinfo->info = %s_info;\n"
1222 "\tg_type_add_interface_dynamic\n"
1223 "\t\t( modinfo->instance_type\n"
1224 "\t\t, modinfo->interface_type\n"
1225 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1227 "\ttype_module->interface_infos = g_slist_prepend\n"
1228 "\t\t( type_module->interface_infos\n"
1237 out_printf(out, "}\n\n");
1240 static void define_add_privates(Class *c)
1242 const char *addprivate = c->dynamic
1243 ? "G_ADD_PRIVATE_DYNAMIC"
1249 out_printf(out, "#ifdef %s\n"
1250 "#define ___add_privates() %s(%s)\n"
1252 "#define ___add_privates()\n"
1254 addprivate, addprivate, typebase);
1257 static void add_type_info(void)
1259 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1260 "\t\tsizeof (%sClass),\n"
1261 "\t\t(GBaseInitFunc) NULL,\n"
1262 "\t\t(GBaseFinalizeFunc) NULL,\n"
1263 "\t\t(GClassInitFunc) %s_class_init,\n"
1264 "\t\t(GClassFinalizeFunc) NULL,\n"
1265 "\t\tNULL /* class_data */,\n"
1266 "\t\tsizeof (%s),\n"
1267 "\t\t%d /* n_preallocs */,\n"
1268 "\t\t(GInstanceInitFunc) %s_init,\n"
1271 typebase, funcbase, typebase, prealloc, funcbase);
1277 Class *c = (Class *)class;
1279 define_add_interfaces(c);
1280 define_add_privates(c);
1282 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1283 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1284 "\t(GTypeFlags)%s,\n",
1285 typebase, funcbase, pmacrotype,
1286 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1289 out_printf(out, "\t___add_privates();\n");
1292 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1294 /* Fallback for GLib < 2.4 */
1295 out_printf(out, ");\n\n"
1297 "GType %s_get_type(void)\n"
1299 "\tstatic GType type = 0;\n",
1304 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1305 "\t\ttype = g_type_register_static\n"
1309 "\t\t\t, (GTypeFlags)%s\n"
1311 pmacrotype, typebase,
1312 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1315 out_printf(out, "\t\t___add_interfaces(type);\n");
1317 out_printf(out, "\t}\n\n"
1324 add_dynamic_get_type(void)
1326 Class *c = (Class *)class;
1328 define_dynamic_add_interfaces(c);
1329 define_add_privates(c);
1332 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1333 * some reason it defines an xxx_register_type function with internal
1334 * linkage. This is kind of weird so we have to work around that.
1336 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1337 "static void %s_class_finalize(%sClass *c) { }\n\n"
1338 "#define %s_register_type ___register_type\n",
1339 funcbase, typebase, funcbase);
1341 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1342 "\t(GTypeFlags)%s,\n",
1343 typebase, funcbase, pmacrotype,
1344 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1347 out_printf(out, "\t___add_privates();\n");
1349 if (c->interfaces) {
1350 out_printf(out, "\t___add_interfaces"
1351 "(type_module, %s_type_id);\n", funcbase);
1354 out_printf(out, ");\n"
1355 "#undef %s_register_type\n\n"
1356 "void %s_register_type(GTypeModule *type_module)\n"
1358 "\t___register_type(type_module);\n"
1360 funcbase, funcbase);
1362 /* Fallback for GLib < 2.14 */
1363 out_printf(out, "#else\n\n"
1364 "static GType %s_type_id;\n\n"
1365 "GType %s_get_type(void)\n"
1367 "\treturn %s_type_id;\n"
1369 funcbase, funcbase, funcbase);
1371 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1377 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1378 "\t\t( type_module\n"
1382 "\t\t, (GTypeFlags)%s\n"
1384 funcbase, pmacrotype, typebase,
1385 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1387 if (c->interfaces) {
1388 out_printf(out, "\t___add_interfaces"
1389 "(type_module, %s_type_id);\n",
1393 out_printf(out, "}\n\n"
1398 add_bonobo_object_get_type(void)
1400 Class *c = (Class *)class;
1402 define_add_interfaces(c);
1404 out_printf (out, "GType %s_get_type(void)\n"
1406 "\tstatic GType type = 0;\n",
1411 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1412 "\t\ttype = bonobo_type_unique\n"
1413 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1414 "\t\t\t, POA_%s__init, NULL\n"
1415 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1419 c->bonobo_object_class, typebase, typebase);
1421 if (((Class *)class)->interfaces)
1422 out_printf(out, "\t\t___add_interfaces(type);\n");
1424 out_printf(out, "\t}\n\n"
1430 add_overrides(Class *c, const char *oname,
1431 gboolean did_base_obj)
1437 done = g_hash_table_new (g_str_hash, g_str_equal);
1439 s = g_strdup ("GObject");
1440 g_hash_table_insert (done, s, s);
1442 for (li = c->nodes; li != NULL; li = li->next) {
1445 Method *m = (Method *)n;
1446 if(n->type != METHOD_NODE ||
1447 m->method != OVERRIDE_METHOD)
1450 s = remove_sep(m->otype);
1452 if(g_hash_table_lookup(done, s)) {
1456 g_hash_table_insert(done, s, s);
1458 f = replace_sep(m->otype, '_');
1461 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1466 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1467 g_hash_table_destroy (done);
1471 make_run_signal_flags(Method *m, gboolean last)
1486 gs = g_string_new(NULL);
1489 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1491 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1493 if(m->scope == PUBLIC_SCOPE)
1494 g_string_append(gs, " | G_SIGNAL_ACTION");
1496 for(li = m->flags; li; li = li->next) {
1497 char *flag = li->data;
1499 for(i=0;flags[i];i++) {
1500 if(strcmp(flags[i], flag)==0)
1503 /* if we haven't found it in our list */
1505 error_printf(GOB_WARN, m->line_no,
1506 "Unknown flag '%s' used, "
1507 "perhaps it was misspelled",
1510 g_string_sprintfa(gs, " | G_SIGNAL_%s", flag);
1514 char *ret = gs->str;
1515 g_string_free(gs, FALSE);
1522 add_signals(Class *c)
1526 out_printf(out, "\n");
1527 for(li=c->nodes;li;li=g_list_next(li)) {
1529 char *mar, *sig, *flags;
1530 gboolean is_none, last = FALSE;
1531 Method *m = (Method *)n;
1533 if(n->type != METHOD_NODE ||
1534 (m->method != SIGNAL_FIRST_METHOD &&
1535 m->method != SIGNAL_LAST_METHOD))
1538 if(m->method == SIGNAL_FIRST_METHOD)
1543 if(g_hash_table_lookup(marsh, m))
1544 mar = g_strconcat("___marshal_",
1545 (char *)g_hash_table_lookup(marsh, m),
1548 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1550 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1552 sig = g_strdup (m->id);
1554 flags = make_run_signal_flags (m, last);
1555 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1556 "\t\tg_signal_new (%s,\n"
1557 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1558 "\t\t\t(GSignalFlags)(%s),\n"
1559 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1560 "\t\t\tNULL, NULL,\n"
1562 "\t\t\tG_TYPE_%s, %d",
1563 sig, m->signal_name /*m->id* if not given signal_name*/,
1565 typebase, m->id, mar,
1566 (char *)m->gtktypes->data,
1567 is_none ? 0 : g_list_length(m->gtktypes->next));
1575 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1576 char *str = l->data;
1577 if (strncmp (str, "BOXED_", 6) == 0)
1578 t = g_strdup (&(str[6]));
1580 t = g_strconcat ("G_TYPE_", str, NULL);
1581 out_printf (out, ",\n\t\t\t%s", t);
1586 out_printf(out, ");\n");
1588 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1591 out_printf(out, "\tif ___GOB_UNLIKELY(");
1592 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1593 out_printf(out, "sizeof(");
1594 print_type(out, m->mtype, FALSE);
1595 out_printf(out, "%s",
1597 m->mtype->postfix : "");
1598 out_printf(out, ") != sizeof(%s) || ",
1599 get_cast(m->gtktypes->data, FALSE));
1602 for(al = m->args->next, gl = m->gtktypes->next;
1603 al != NULL && gl != NULL;
1604 al = al->next, gl = gl->next) {
1605 FuncArg *arg = al->data;
1606 char *gtkarg = gl->data;
1608 out_printf(out, "sizeof(");
1609 print_type(out, arg->atype, FALSE);
1610 out_printf(out, "%s",
1611 arg->atype->postfix ?
1612 arg->atype->postfix : "");
1613 out_printf(out, ") != sizeof(%s) || ",
1614 get_cast(gtkarg, FALSE));
1618 "parent_class == NULL /* avoid warning */");
1620 out_printf(out, ") {\n"
1621 "\t\tg_error(\"%s line %d: Type mismatch "
1622 "of \\\"%s\\\" signal signature\");\n"
1624 filename, m->line_no, m->id);
1631 set_def_handlers(Class *c, const char *oname)
1634 gboolean set_line = FALSE;
1636 out_printf(out, "\n");
1637 for(li = c->nodes; li; li = g_list_next(li)) {
1639 Method *m = (Method *)n;
1641 if(n->type != METHOD_NODE ||
1642 (m->method != SIGNAL_FIRST_METHOD &&
1643 m->method != SIGNAL_LAST_METHOD &&
1644 m->method != VIRTUAL_METHOD &&
1645 m->method != OVERRIDE_METHOD))
1648 if(m->line_no > 0 && m->cbuf) {
1649 out_addline_infile(out, m->line_no);
1651 } else if(set_line) {
1652 out_addline_outfile(out);
1657 if (m->method == OVERRIDE_METHOD) {
1659 s = replace_sep (m->otype, '_');
1663 dispose_handler != NULL &&
1664 strcmp (m->id, "dispose") == 0)
1665 out_printf (out, "\tg_object_class->dispose "
1667 else if (need_finalize &&
1669 strcmp(m->id, "finalize") == 0)
1671 "\tg_object_class->finalize = ___finalize;\n");
1672 else if (m->cbuf != NULL)
1674 "\t%s_class->%s = ___%x_%s_%s;\n",
1675 s, m->id, (guint)m->unique_id,
1678 out_printf(out, "\t%s_class->%s = NULL;\n",
1682 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1686 out_printf(out, "\t%s->%s = NULL;\n",
1691 out_addline_outfile(out);
1695 make_argument (Argument *a)
1700 char *argflags[] = {
1708 flags = g_string_new ("(GParamFlags)(");
1710 if(a->get && a->set)
1711 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1713 g_string_append (flags, "G_PARAM_READABLE");
1715 g_string_append (flags, "G_PARAM_WRITABLE");
1717 g_assert(a->get || a->set);
1719 for (l = a->flags; l != NULL; l = l->next) {
1720 char *flag = l->data;
1722 if(strcmp (flag, "READABLE") == 0 ||
1723 strcmp (flag, "WRITABLE") == 0) {
1724 error_print(GOB_WARN, a->line_no,
1726 "WRITABLE argument flags are "
1727 "set automatically");
1730 for(i = 0; argflags[i]; i++) {
1731 if(strcmp(argflags[i], flag)==0)
1734 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1737 g_string_append (flags, ")");
1739 s = g_strdup(a->name);
1741 if (!strcmp (a->gtktype, "ENUM"))
1742 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1743 "\t\tG_TYPE_ENUM, 0,\n"
1745 a->name, flags->str);
1746 if (!strcmp (a->gtktype, "FLAGS"))
1747 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1748 "\t\tG_TYPE_FLAGS, 0,\n"
1750 a->name, flags->str);
1751 else if (!strcmp (a->gtktype, "OBJECT"))
1752 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1753 "\t\tG_TYPE_OBJECT,\n"
1755 a->name, flags->str);
1756 else if (!strcmp (a->gtktype, "STRING"))
1757 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1760 a->name, flags->str);
1761 else if (!strcmp (a->gtktype, "INT"))
1762 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1763 "\t\tG_MININT, G_MAXINT,\n"
1766 a->name, flags->str);
1767 else if (!strcmp (a->gtktype, "UINT"))
1768 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1769 "\t\t0, G_MAXUINT,\n"
1772 a->name, flags->str);
1773 else if (!strcmp (a->gtktype, "INT"))
1774 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1775 "\t\tG_MININT, G_MAXINT,\n"
1778 a->name, flags->str);
1779 else if (!strcmp (a->gtktype, "CHAR"))
1780 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1784 a->name, flags->str);
1785 else if (!strcmp (a->gtktype, "UCHAR"))
1786 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1790 a->name, flags->str);
1791 else if (!strcmp (a->gtktype, "BOOL") ||
1792 !strcmp (a->gtktype, "BOOLEAN"))
1793 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1796 a->name, flags->str);
1797 else if (!strcmp (a->gtktype, "LONG"))
1798 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1799 "\t\tG_MINLONG, G_MAXLONG,\n"
1802 a->name, flags->str);
1803 else if (!strcmp (a->gtktype, "ULONG"))
1804 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1805 "\t\t0, G_MAXULONG,\n"
1808 a->name, flags->str);
1809 else if (!strcmp (a->gtktype, "INT64"))
1810 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1811 "\t\tG_MININT64, G_MAXINT64,\n"
1814 a->name, flags->str);
1815 else if (!strcmp (a->gtktype, "UINT64"))
1816 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1817 "\t\t0, G_MAXUINT64,\n"
1820 a->name, flags->str);
1821 else if (!strcmp (a->gtktype, "FLOAT"))
1822 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1823 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1826 a->name, flags->str);
1827 else if (!strcmp (a->gtktype, "DOUBLE"))
1828 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1829 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1832 a->name, flags->str);
1833 else if (!strcmp (a->gtktype, "POINTER"))
1834 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1836 a->name, flags->str);
1838 error_printf (GOB_ERROR, a->line_no,
1839 "%s type is not supported for arguments, try using properties",
1842 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1843 "\t\tPROP_%s, param_spec);\n", s);
1847 g_string_free(flags, TRUE);
1850 #define value_for_print(str, alt) (str != NULL ? str : alt)
1853 make_property (Property *p)
1857 if (p->get == NULL && p->set == NULL) {
1858 error_print (GOB_ERROR, p->line_no,
1859 "Property has no getter nor setter");
1863 if (p->flags != NULL)
1864 error_print (GOB_WARN, p->line_no,
1865 "Overridden property, flags ignored");
1866 if (p->nick != NULL)
1867 error_print (GOB_WARN, p->line_no,
1868 "Overridden property, nick ignored");
1869 if (p->blurb != NULL)
1870 error_print (GOB_WARN, p->line_no,
1871 "Overridden property, blurb ignored");
1872 if (p->minimum != NULL)
1873 error_print (GOB_WARN, p->line_no,
1874 "Overridden property, minimum ignored");
1875 if (p->maximum != NULL)
1876 error_print (GOB_WARN, p->line_no,
1877 "Overridden property, maximum ignored");
1878 if (p->default_value != NULL)
1879 error_print (GOB_WARN, p->line_no,
1880 "Overridden property, default_value ignored");
1882 s = g_strdup (p->name);
1884 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1886 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1891 char *argflags[] = {
1899 flags = g_string_new ("(GParamFlags)(");
1901 if (p->get != NULL && p->set != NULL)
1902 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1903 else if (p->get != NULL)
1904 g_string_append (flags, "G_PARAM_READABLE");
1906 g_string_append (flags, "G_PARAM_WRITABLE");
1909 for (l = p->flags; l != NULL; l = l->next) {
1910 char *flag = l->data;
1912 if(strcmp (flag, "READABLE") == 0 ||
1913 strcmp (flag, "WRITABLE") == 0) {
1914 error_print(GOB_WARN, p->line_no,
1916 "WRITABLE argument flags are "
1917 "set automatically");
1920 for(i = 0; argflags[i]; i++) {
1921 if(strcmp(argflags[i], flag)==0)
1924 g_string_sprintfa(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1927 g_string_append (flags, ")");
1929 if (strcmp (p->gtktype, "CHAR") == 0) {
1930 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1931 "\t\t(\"%s\" /* name */,\n"
1932 "\t\t %s /* nick */,\n"
1933 "\t\t %s /* blurb */,\n"
1934 "\t\t %s /* minimum */,\n"
1935 "\t\t %s /* maximum */,\n"
1936 "\t\t %s /* default_value */,\n"
1938 value_for_print (p->canonical_name, p->name),
1939 value_for_print (p->nick, "NULL"),
1940 value_for_print (p->blurb, "NULL"),
1941 value_for_print (p->minimum, "-128"),
1942 value_for_print (p->maximum, "127"),
1943 value_for_print (p->default_value, "0"),
1945 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1946 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1947 "\t\t(\"%s\" /* name */,\n"
1948 "\t\t %s /* nick */,\n"
1949 "\t\t %s /* blurb */,\n"
1950 "\t\t %s /* minimum */,\n"
1951 "\t\t %s /* maximum */,\n"
1952 "\t\t %s /* default_value */,\n"
1954 value_for_print (p->canonical_name, p->name),
1955 value_for_print (p->nick, "NULL"),
1956 value_for_print (p->blurb, "NULL"),
1957 value_for_print (p->minimum, "0"),
1958 value_for_print (p->maximum, "0xFF"),
1959 value_for_print (p->default_value, "0"),
1961 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1962 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1963 "\t\t(\"%s\" /* name */,\n"
1964 "\t\t %s /* nick */,\n"
1965 "\t\t %s /* blurb */,\n"
1966 "\t\t %s /* default_value */,\n"
1968 value_for_print (p->canonical_name, p->name),
1969 value_for_print (p->nick, "NULL"),
1970 value_for_print (p->blurb, "NULL"),
1971 value_for_print (p->default_value, "FALSE"),
1973 } else if (strcmp (p->gtktype, "INT") == 0) {
1974 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1975 "\t\t(\"%s\" /* name */,\n"
1976 "\t\t %s /* nick */,\n"
1977 "\t\t %s /* blurb */,\n"
1978 "\t\t %s /* minimum */,\n"
1979 "\t\t %s /* maximum */,\n"
1980 "\t\t %s /* default_value */,\n"
1982 value_for_print (p->canonical_name, p->name),
1983 value_for_print (p->nick, "NULL"),
1984 value_for_print (p->blurb, "NULL"),
1985 value_for_print (p->minimum, "G_MININT"),
1986 value_for_print (p->maximum, "G_MAXINT"),
1987 value_for_print (p->default_value, "0"),
1989 } else if (strcmp (p->gtktype, "UINT") == 0) {
1990 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1991 "\t\t(\"%s\" /* name */,\n"
1992 "\t\t %s /* nick */,\n"
1993 "\t\t %s /* blurb */,\n"
1994 "\t\t %s /* minimum */,\n"
1995 "\t\t %s /* maximum */,\n"
1996 "\t\t %s /* default_value */,\n"
1998 value_for_print (p->canonical_name, p->name),
1999 value_for_print (p->nick, "NULL"),
2000 value_for_print (p->blurb, "NULL"),
2001 value_for_print (p->minimum, "0"),
2002 value_for_print (p->maximum, "G_MAXUINT"),
2003 value_for_print (p->default_value, "0"),
2005 } else if (strcmp (p->gtktype, "LONG") == 0) {
2006 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2007 "\t\t(\"%s\" /* name */,\n"
2008 "\t\t %s /* nick */,\n"
2009 "\t\t %s /* blurb */,\n"
2010 "\t\t %s /* minimum */,\n"
2011 "\t\t %s /* maximum */,\n"
2012 "\t\t %s /* default_value */,\n"
2014 value_for_print (p->canonical_name, p->name),
2015 value_for_print (p->nick, "NULL"),
2016 value_for_print (p->blurb, "NULL"),
2017 value_for_print (p->minimum, "G_MINLONG"),
2018 value_for_print (p->maximum, "G_MAXLONG"),
2019 value_for_print (p->default_value, "0"),
2021 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2022 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2023 "\t\t(\"%s\" /* name */,\n"
2024 "\t\t %s /* nick */,\n"
2025 "\t\t %s /* blurb */,\n"
2026 "\t\t %s /* minimum */,\n"
2027 "\t\t %s /* maximum */,\n"
2028 "\t\t %s /* default_value */,\n"
2030 value_for_print (p->canonical_name, p->name),
2031 value_for_print (p->nick, "NULL"),
2032 value_for_print (p->blurb, "NULL"),
2033 value_for_print (p->minimum, "0"),
2034 value_for_print (p->maximum, "G_MAXULONG"),
2035 value_for_print (p->default_value, "0"),
2037 } else if (strcmp (p->gtktype, "INT64") == 0) {
2038 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2039 "\t\t(\"%s\" /* name */,\n"
2040 "\t\t %s /* nick */,\n"
2041 "\t\t %s /* blurb */,\n"
2042 "\t\t %s /* minimum */,\n"
2043 "\t\t %s /* maximum */,\n"
2044 "\t\t %s /* default_value */,\n"
2046 value_for_print (p->canonical_name, p->name),
2047 value_for_print (p->nick, "NULL"),
2048 value_for_print (p->blurb, "NULL"),
2049 value_for_print (p->minimum, "G_MININT64"),
2050 value_for_print (p->maximum, "G_MAXINT64"),
2051 value_for_print (p->default_value, "0"),
2053 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2054 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2055 "\t\t(\"%s\" /* name */,\n"
2056 "\t\t %s /* nick */,\n"
2057 "\t\t %s /* blurb */,\n"
2058 "\t\t %s /* minimum */,\n"
2059 "\t\t %s /* maximum */,\n"
2060 "\t\t %s /* default_value */,\n"
2062 value_for_print (p->canonical_name, p->name),
2063 value_for_print (p->nick, "NULL"),
2064 value_for_print (p->blurb, "NULL"),
2065 value_for_print (p->minimum, "0"),
2066 value_for_print (p->maximum, "G_MAXUINT64"),
2067 value_for_print (p->default_value, "0"),
2069 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2070 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2071 "\t\t(\"%s\" /* name */,\n"
2072 "\t\t %s /* nick */,\n"
2073 "\t\t %s /* blurb */,\n"
2074 "\t\t %s /* default_value */,\n"
2076 value_for_print (p->canonical_name, p->name),
2077 value_for_print (p->nick, "NULL"),
2078 value_for_print (p->blurb, "NULL"),
2079 value_for_print (p->default_value, "0"),
2081 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2082 char *type = make_me_type (p->extra_gtktype,
2084 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2085 "\t\t(\"%s\" /* name */,\n"
2086 "\t\t %s /* nick */,\n"
2087 "\t\t %s /* blurb */,\n"
2088 "\t\t %s /* enum_type */,\n"
2089 "\t\t %s /* default_value */,\n"
2091 value_for_print (p->canonical_name, p->name),
2092 value_for_print (p->nick, "NULL"),
2093 value_for_print (p->blurb, "NULL"),
2095 value_for_print (p->default_value, "0"),
2098 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2099 char *type = make_me_type (p->extra_gtktype,
2101 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2102 "\t\t(\"%s\" /* name */,\n"
2103 "\t\t %s /* nick */,\n"
2104 "\t\t %s /* blurb */,\n"
2105 "\t\t %s /* flags_type */,\n"
2106 "\t\t %s /* default_value */,\n"
2108 value_for_print (p->canonical_name, p->name),
2109 value_for_print (p->nick, "NULL"),
2110 value_for_print (p->blurb, "NULL"),
2112 value_for_print (p->default_value, "0"),
2115 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2116 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2117 "\t\t(\"%s\" /* name */,\n"
2118 "\t\t %s /* nick */,\n"
2119 "\t\t %s /* blurb */,\n"
2120 "\t\t %s /* minimum */,\n"
2121 "\t\t %s /* maximum */,\n"
2122 "\t\t %s /* default_value */,\n"
2124 value_for_print (p->canonical_name, p->name),
2125 value_for_print (p->nick, "NULL"),
2126 value_for_print (p->blurb, "NULL"),
2127 value_for_print (p->minimum, "-G_MAXFLOAT"),
2128 value_for_print (p->maximum, "G_MAXFLOAT"),
2129 value_for_print (p->default_value, "0.0"),
2131 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2132 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2133 "\t\t(\"%s\" /* name */,\n"
2134 "\t\t %s /* nick */,\n"
2135 "\t\t %s /* blurb */,\n"
2136 "\t\t %s /* minimum */,\n"
2137 "\t\t %s /* maximum */,\n"
2138 "\t\t %s /* default_value */,\n"
2140 value_for_print (p->canonical_name, p->name),
2141 value_for_print (p->nick, "NULL"),
2142 value_for_print (p->blurb, "NULL"),
2143 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2144 value_for_print (p->maximum, "G_MAXDOUBLE"),
2145 value_for_print (p->default_value, "0.0"),
2147 } else if (strcmp (p->gtktype, "STRING") == 0) {
2148 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2149 "\t\t(\"%s\" /* name */,\n"
2150 "\t\t %s /* nick */,\n"
2151 "\t\t %s /* blurb */,\n"
2152 "\t\t %s /* default_value */,\n"
2154 value_for_print (p->canonical_name, p->name),
2155 value_for_print (p->nick, "NULL"),
2156 value_for_print (p->blurb, "NULL"),
2157 value_for_print (p->default_value, "NULL"),
2159 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2160 char *type = make_me_type (p->extra_gtktype,
2162 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2163 "\t\t(\"%s\" /* name */,\n"
2164 "\t\t %s /* nick */,\n"
2165 "\t\t %s /* blurb */,\n"
2166 "\t\t %s /* param_type */,\n"
2168 value_for_print (p->canonical_name, p->name),
2169 value_for_print (p->nick, "NULL"),
2170 value_for_print (p->blurb, "NULL"),
2174 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2175 char *type = make_me_type (p->extra_gtktype,
2177 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2178 "\t\t(\"%s\" /* name */,\n"
2179 "\t\t %s /* nick */,\n"
2180 "\t\t %s /* blurb */,\n"
2181 "\t\t %s /* boxed_type */,\n"
2183 value_for_print (p->canonical_name, p->name),
2184 value_for_print (p->nick, "NULL"),
2185 value_for_print (p->blurb, "NULL"),
2189 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2190 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2191 "\t\t(\"%s\" /* name */,\n"
2192 "\t\t %s /* nick */,\n"
2193 "\t\t %s /* blurb */,\n"
2195 value_for_print (p->canonical_name, p->name),
2196 value_for_print (p->nick, "NULL"),
2197 value_for_print (p->blurb, "NULL"),
2199 /* FIXME: VALUE_ARRAY */
2200 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2201 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2202 "\t\t(\"%s\" /* name */,\n"
2203 "\t\t %s /* nick */,\n"
2204 "\t\t %s /* blurb */,\n"
2206 value_for_print (p->canonical_name, p->name),
2207 value_for_print (p->nick, "NULL"),
2208 value_for_print (p->blurb, "NULL"),
2210 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2211 char *type = make_me_type (p->extra_gtktype,
2213 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2214 "\t\t(\"%s\" /* name */,\n"
2215 "\t\t %s /* nick */,\n"
2216 "\t\t %s /* blurb */,\n"
2217 "\t\t %s /* object_type */,\n"
2219 value_for_print (p->canonical_name, p->name),
2220 value_for_print (p->nick, "NULL"),
2221 value_for_print (p->blurb, "NULL"),
2226 error_printf (GOB_ERROR, p->line_no,
2227 "%s type is not supported by properties",
2231 s = g_strdup (p->name);
2233 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2235 "\t\tparam_spec);\n", s);
2238 g_string_free (flags, TRUE);
2243 make_arguments(Class *c)
2246 if (get_properties > 0)
2247 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2248 if (set_properties > 0)
2249 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2250 out_printf (out, " {\n");
2251 for (li = c->nodes; li != NULL; li = li->next) {
2253 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2254 || n->type == ARGUMENT_NODE) {
2255 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2260 for (li = c->nodes; li != NULL; li = li->next) {
2262 if (n->type == PROPERTY_NODE)
2263 make_property ((Property *)n);
2264 else if (n->type == ARGUMENT_NODE)
2265 make_argument ((Argument *)n);
2267 out_printf(out, " }\n");
2271 print_initializer(Method *m, Variable *v)
2278 if(v->initializer == NULL)
2281 if(v->scope == PRIVATE_SCOPE)
2282 root = g_strconcat(((FuncArg *)m->args->data)->name,
2285 root = g_strdup(((FuncArg *)m->args->data)->name);
2287 if(v->initializer_line > 0)
2288 out_addline_infile(out, v->initializer_line);
2290 if (v->initializer_simple)
2291 out_printf(out, "\t%s->%s = %s;\n",
2292 root, v->id, v->initializer);
2293 else if (strcmp(v->id, "_glade_xml") == 0)
2294 /* This is OK, this v->initializer string is set internally
2295 and it will eat exactly one string! */
2296 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2298 out_printf(out, "%s", v->initializer);
2300 if(v->initializer_line > 0)
2301 out_addline_outfile(out);
2307 print_glade_widget(Method *m, Variable *v)
2312 if(!v->glade_widget)
2315 if(v->scope == PRIVATE_SCOPE)
2316 root = g_strconcat(((FuncArg *)m->args->data)->name,
2319 root = g_strdup(((FuncArg *)m->args->data)->name);
2321 cast = get_type(v->vtype, FALSE);
2322 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2323 root, v->id, cast, root, v->id);
2329 print_destructor (Variable *v)
2333 if(v->destructor == NULL)
2336 if(v->scope == PRIVATE_SCOPE)
2337 root = "self->_priv";
2341 if(v->destructor_simple) {
2342 if(v->destructor_line > 0)
2343 out_addline_infile(out, v->destructor_line);
2346 out_printf(out, "\tif(%s->%s) { "
2347 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2348 "%s->%s = NULL; }\n",
2349 root, v->id, v->destructor, root, v->id,
2352 out_printf(out, "\tif(%s->%s) { "
2353 "%s ((gpointer) %s->%s); "
2354 "%s->%s = NULL; }\n",
2355 root, v->id, v->destructor, root, v->id,
2359 if(v->destructor_line > 0)
2360 out_addline_outfile(out);
2362 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2363 out_printf(out, "#define VAR %s\n", v->id);
2364 out_printf(out, "\t{\n");
2365 if(v->destructor_line > 0)
2366 out_addline_infile(out, v->destructor_line);
2368 out_printf(out, "\t%s}\n", v->destructor);
2370 if(v->destructor_line > 0)
2371 out_addline_outfile(out);
2372 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2374 out_printf(out, "#undef VAR\n");
2375 out_printf(out, "#undef %s\n", v->id);
2380 add_constructor (Class *c)
2382 out_printf(out, "\nstatic GObject *\n"
2383 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2386 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2389 out_printf(out, "\tGObject *obj_self;\n");
2390 out_printf(out, "\t%s *self;\n", typebase);
2392 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2393 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2395 if (user_constructor->line_no > 0)
2396 out_addline_infile (out, user_constructor->line_no);
2397 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2398 if (user_constructor->line_no > 0)
2399 out_addline_outfile (out);
2401 out_printf(out, "\treturn obj_self;\n");
2402 out_printf(out, "}\n"
2403 "#undef __GOB_FUNCTION__\n\n");
2407 print_unreftors (Class *c)
2410 for(li = ((Class *)class)->nodes;
2414 Variable *v = (Variable *)n;
2415 if (n->type == VARIABLE_NODE &&
2416 v->scope != CLASS_SCOPE &&
2417 v->destructor_unref)
2418 print_destructor (v);
2423 add_dispose (Class *c)
2425 out_printf(out, "\nstatic void\n"
2426 "___dispose (GObject *obj_self)\n"
2429 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2432 if (unreftors > 0 || user_dispose_method != NULL) {
2433 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2435 ! no_gnu ? " G_GNUC_UNUSED" : "",
2439 if (dispose_handler != NULL) {
2440 if (unreftors > 0) {
2441 print_unreftors (c);
2444 /* so we get possible bad argument warning */
2445 if (dispose_handler->line_no > 0)
2446 out_addline_infile (out, dispose_handler->line_no);
2447 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2448 (guint)dispose_handler->unique_id, funcbase);
2449 if (dispose_handler->line_no > 0)
2450 out_addline_outfile (out);
2452 if (user_dispose_method != NULL) {
2453 if (user_dispose_method->line_no > 0)
2454 out_addline_infile (out, user_dispose_method->line_no);
2455 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2456 if (user_dispose_method->line_no > 0)
2457 out_addline_outfile (out);
2460 if (unreftors > 0) {
2461 print_unreftors (c);
2465 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2466 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2469 out_printf(out, "}\n"
2470 "#undef __GOB_FUNCTION__\n\n");
2474 print_destructors (Class *c)
2477 for (li = ((Class *)class)->nodes;
2481 Variable *v = (Variable *)n;
2482 if (n->type == VARIABLE_NODE &&
2483 v->scope != CLASS_SCOPE &&
2484 ! v->destructor_unref)
2485 print_destructor (v);
2490 add_finalize (Class *c)
2494 "___finalize(GObject *obj_self)\n"
2497 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2502 user_finalize_method != NULL) {
2503 const char *unused = "";
2505 unused = " G_GNUC_UNUSED";
2506 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2507 typebase, unused, macrobase);
2510 const char *unused = "";
2512 unused = " G_GNUC_UNUSED";
2513 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2517 if(finalize_handler) {
2518 if (destructors > 0) {
2519 print_destructors (c);
2522 /* so we get possible bad argument warning */
2523 if(finalize_handler->line_no > 0)
2524 out_addline_infile(out, finalize_handler->line_no);
2525 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2526 (guint)finalize_handler->unique_id, funcbase);
2527 if(finalize_handler->line_no > 0)
2528 out_addline_outfile(out);
2530 if (user_finalize_method != NULL) {
2531 if (user_finalize_method->line_no > 0)
2532 out_addline_infile (out, user_finalize_method->line_no);
2533 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2534 if (user_finalize_method->line_no > 0)
2535 out_addline_outfile (out);
2538 if (destructors > 0) {
2539 print_destructors (c);
2543 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2544 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2547 out_printf(out, "}\n"
2548 "#undef __GOB_FUNCTION__\n\n");
2552 make_bonobo_object_epv (Class *c, const char *classname)
2555 gboolean added_line = FALSE;
2557 for (li = c->nodes; li != NULL; li = li->next) {
2559 Method *m = (Method *)n;
2560 if(n->type != METHOD_NODE ||
2561 m->method == OVERRIDE_METHOD)
2564 if (m->bonobo_object_func) {
2565 if(m->line_no > 0) {
2566 out_addline_infile(out, m->line_no);
2568 } else if (m->line_no == 0 &&
2570 out_addline_outfile(out);
2573 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2574 classname, m->id, m->id);
2578 out_addline_outfile(out);
2581 static void add_class_private(Class *c, Method *m)
2583 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2588 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2589 " || !defined(G_ADD_PRIVATE%s)\n"
2590 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2593 ((FuncArg *)m->args->data)->name, typebase);
2596 static void get_instance_private(Class *c, Method *m)
2598 const char *self = ((FuncArg *)m->args->data)->name;
2599 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2602 if (always_private_struct) {
2603 out_printf(out, "\t%s->_priv = NULL;\n", self);
2609 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2610 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2611 " && defined(G_ADD_PRIVATE%s)\n"
2612 "\t\t%s_get_instance_private(%s);\n"
2614 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2617 "\t\t\t, %sPrivate\n"
2623 self, macrotype, typebase);
2629 const char *unused = "";
2633 unused = " G_GNUC_UNUSED";
2635 for(li=c->nodes;li;li=g_list_next(li)) {
2639 if(n->type != METHOD_NODE)
2642 if(m->method == INIT_METHOD) {
2644 out_addline_infile(out, m->line_no);
2645 print_method(out, "static ", "\n", "", " ", "", "\n",
2646 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2648 out_printf(out, "{\n");
2650 out_addline_outfile(out);
2652 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2655 get_instance_private(c, m);
2657 if(initializers > 0) {
2659 for(li = ((Class *)class)->nodes;
2663 Variable *v = (Variable *)n;
2664 if(n->type != VARIABLE_NODE ||
2665 v->scope == CLASS_SCOPE)
2667 print_initializer(m, v);
2670 if(glade_widgets > 0) {
2672 for(li = ((Class *)class)->nodes;
2676 Variable *v = (Variable *)n;
2677 if(n->type != VARIABLE_NODE ||
2678 v->scope == CLASS_SCOPE)
2680 print_glade_widget(m, v);
2683 } else if(m->method == CLASS_INIT_METHOD) {
2684 gboolean did_base_obj = FALSE;
2687 out_addline_infile(out, m->line_no);
2688 print_method(out, "static ", "\n", "", " ", "", "\n",
2689 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2691 out_printf(out, "{\n");
2693 out_addline_outfile(out);
2695 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2697 if (set_properties > 0 ||
2698 get_properties > 0 ||
2705 "g_object_class%s = "
2706 "(GObjectClass*) %s;\n",
2708 ((FuncArg *)m->args->data)->name);
2709 did_base_obj = TRUE;
2714 ((FuncArg *)m->args->data)->name,
2717 add_class_private(c, m);
2719 if (initializers > 0) {
2721 for(li = ((Class *)class)->nodes;
2725 Variable *v = (Variable *)n;
2726 if(n->type == VARIABLE_NODE &&
2727 v->scope == CLASS_SCOPE)
2728 print_initializer(m, v);
2732 out_printf(out, "\n\tparent_class = ");
2734 out_printf(out, "(%sClass *)", ptypebase);
2735 out_printf(out, "g_type_class_ref (%s);\n",
2741 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2743 /* if there are no handlers for these things, we
2744 * need to set them up here */
2745 if(need_constructor)
2746 out_printf(out, "\tg_object_class->constructor "
2747 "= ___constructor;\n");
2748 if(need_dispose && !dispose_handler)
2749 out_printf(out, "\tg_object_class->dispose "
2751 if(need_finalize && !finalize_handler)
2752 out_printf(out, "\tg_object_class->finalize = "
2755 if(get_properties > 0 || set_properties > 0)
2758 if (c->bonobo_object_class != NULL) {
2759 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2765 out_printf(out, " {\n");
2766 out_addline_infile(out, m->ccode_line);
2767 out_printf(out, "%s\n", m->cbuf);
2768 out_addline_outfile(out);
2769 out_printf(out, " }\n");
2771 out_printf(out, "}\n"
2772 "#undef __GOB_FUNCTION__\n");
2777 add_argument (Argument *a, gboolean is_set)
2781 char *the_type_lower;
2786 line_no = a->set_line;
2789 line_no = a->get_line;
2793 s = g_strdup(a->name);
2795 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2797 the_type_lower = g_strdup (a->gtktype);
2798 gob_strdown (the_type_lower);
2800 /* HACK because there is no g_value_set/get for unichar */
2801 if (strcmp (the_type_lower, "unichar") == 0) {
2802 g_free (the_type_lower);
2803 the_type_lower = g_strdup ("uint");
2808 const char *unused = "";
2810 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2811 unused = " G_GNUC_UNUSED";
2814 if (a->atype != NULL &&
2815 /* gcc -Wbad-function-cast is wanking stupid, moronic
2816 and otherwise evil so we should just use a (gint)
2817 or (guint) cast, not the specific type cast */
2819 (strcmp (a->gtktype, "ENUM") != 0 &&
2820 strcmp (a->gtktype, "FLAGS") != 0)))
2821 cast = get_type (a->atype, TRUE);
2823 cast = g_strdup (get_cast (a->gtktype, FALSE));
2825 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2826 cast, unused, cast, the_type_lower);
2829 } else if ( ! is_set) {
2832 if (a->atype != NULL)
2833 cast = get_type (a->atype, TRUE);
2835 cast = g_strdup (get_cast (a->gtktype, FALSE));
2836 out_printf (out, "\t%s ARG;\n"
2837 "\tmemset (&ARG, 0, sizeof (%s));\n",
2843 out_printf(out, "\t\t{\n");
2845 out_addline_infile (out, line_no);
2846 out_printf (out, "%s\n", cbuf);
2848 out_addline_outfile (out);
2849 out_printf (out, "\t\t}\n");
2851 if (strcmp (a->gtktype, "OBJECT") == 0)
2852 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2855 out_printf (out, "\t\t"
2856 "g_value_set_%s (VAL, ARG);\n",
2859 g_free (the_type_lower);
2862 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2863 out_printf (out, "\t\tif (&ARG) break;\n");
2866 out_printf (out, "\t\tbreak;\n");
2868 out_printf (out, "\t}\n");
2872 add_property (Property *p, gboolean is_set)
2875 char *the_type_lower;
2881 line_no = p->set_line;
2884 line_no = p->get_line;
2889 name_upper = g_strdup (p->name);
2890 gob_strup (name_upper);
2891 the_type_lower = g_strdup (p->gtktype);
2892 gob_strdown (the_type_lower);
2894 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2896 out_printf(out, "\t\t{\n");
2898 out_addline_infile (out, line_no);
2899 out_printf (out, "%s\n", cbuf);
2901 out_addline_outfile (out);
2902 out_printf (out, "\t\t}\n");
2904 g_free (name_upper);
2905 g_free (the_type_lower);
2907 out_printf (out, "\t\tbreak;\n");
2911 add_getset_arg(Class *c, gboolean is_set)
2914 const char *unused = "";
2915 const char *hack_unused = "";
2917 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2918 unused = " G_GNUC_UNUSED";
2920 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2923 out_printf(out, "\nstatic void\n"
2924 "___object_%s_property (GObject *object,\n"
2925 "\tguint property_id,\n"
2926 "\t%sGValue *VAL%s,\n"
2927 "\tGParamSpec *pspec%s)\n"
2928 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2931 "\tself = %s (object);\n\n"
2932 "\tswitch (property_id) {\n",
2933 is_set ? "set" : "get",
2934 is_set ? "const " : "",
2938 is_set ? "set" : "get",
2943 for (li = c->nodes; li != NULL; li = li->next) {
2945 if (n->type == PROPERTY_NODE)
2946 add_property ((Property *)n, is_set);
2947 else if (n->type == ARGUMENT_NODE)
2948 add_argument ((Argument *)n, is_set);
2950 out_printf (out, "\tdefault:\n"
2951 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2952 "#ifndef __PRETTY_FUNCTION__\n"
2953 "# undef G_STRLOC\n"
2954 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2956 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2957 "\t\t%sbreak;\n\t}\n"
2959 "#undef __GOB_FUNCTION__\n", hack_unused);
2963 print_checks (Method *m, FuncArg *fa)
2967 gboolean checked_null = FALSE;
2968 is_void = (strcmp(m->mtype->name, "void")==0 &&
2969 m->mtype->pointer == NULL);
2971 for(li = fa->checks; li != NULL; li = li->next) {
2972 Check *ch = li->data;
2974 /* point to the method prot in .gob for failed checks */
2976 out_addline_infile(out, m->line_no);
2978 out_printf(out, "\tg_return_if_fail (");
2980 out_printf(out, "\tg_return_val_if_fail (");
2981 switch(ch->chtype) {
2983 out_printf(out, "%s != NULL", fa->name);
2984 checked_null = TRUE;
2987 s = make_pre_macro(fa->atype->name, "IS");
2989 out_printf(out, "%s (%s)", s, fa->name);
2991 /* if not check null, null may be valid */
2992 out_printf(out, "!(%s) || %s (%s)", fa->name,
2997 out_printf(out, "%s < %s", fa->name, ch->number);
3000 out_printf(out, "%s > %s", fa->name, ch->number);
3003 out_printf(out, "%s <= %s", fa->name, ch->number);
3006 out_printf(out, "%s >= %s", fa->name, ch->number);
3009 out_printf(out, "%s == %s", fa->name, ch->number);
3012 out_printf(out, "%s != %s", fa->name, ch->number);
3016 out_printf(out, ");\n");
3018 out_printf(out, ", (");
3019 print_type(out, m->mtype, TRUE);
3020 out_printf(out, ")%s);\n",
3021 m->onerror?m->onerror:"0");
3027 print_preconditions(Method *m)
3031 for(li=m->args;li;li=g_list_next(li)) {
3032 FuncArg *fa = li->data;
3034 print_checks(m, fa);
3037 out_addline_outfile(out);
3041 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3043 out_printf(out, "{\n");
3045 out_addline_outfile(out);
3046 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3047 ((Class *)class)->otype,
3050 print_preconditions(m);
3054 (no_gnu || for_cpp) &&
3056 ((FuncArg *)(m->args->data))->name != NULL &&
3057 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3058 out_printf (out, "\tif (&self) { ; }\n");
3061 /* Note: the trailing }'s are on one line, this is so
3062 that we get the no return warning correctly and point to
3063 the correct line in the .gob file, yes this is slightly
3064 ugly in the .c file, but that is not supposed to be
3065 human readable anyway. */
3067 out_printf(out, "{\n");
3069 out_addline_infile(out, m->ccode_line);
3070 out_printf(out, "\t%s}", m->cbuf);
3073 /* Note, there is no \n between the last } and this } so that
3074 * errors/warnings reported on the end of the body get pointed to the
3075 * right line in the .gob source */
3076 out_printf(out, "}\n");
3079 out_addline_outfile(out);
3080 out_printf(out, "#undef __GOB_FUNCTION__\n");
3084 put_signal_args (Method *m)
3090 if (m->args->next == NULL)
3093 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3094 li != NULL && ali != NULL;
3095 li = li->next, ali = ali->next, i++) {
3096 FuncArg *fa = li->data;
3097 char *str = ali->data;
3098 char *cast = g_strdup (get_cast (str, FALSE));
3099 /* FIXME: This code is so fucking ugly it hurts */
3100 gboolean do_static =
3101 (strcmp (str, "STRING") == 0 ||
3102 strcmp (str, "BOXED") == 0 ||
3103 strncmp (str, "BOXED_", 6) == 0);
3108 cast = get_type (fa->atype, TRUE);
3110 /* we should have already proved before that
3111 the we know all the types */
3112 g_assert (cast != NULL);
3114 if (strncmp (str, "BOXED_", 6) == 0)
3115 t = g_strdup (&(str[6]));
3117 t = g_strconcat ("G_TYPE_", str, NULL);
3120 "\t___param_values[%d].g_type = 0;\n"
3121 "\tg_value_init (&___param_values[%d], %s);\n",
3125 if (strcmp (str, "UNICHAR") == 0)
3126 /* hack because glib is braindamaged */
3127 set_func = g_strdup ("g_value_set_uint");
3128 else if (strncmp (str, "BOXED_", 6) == 0)
3129 set_func = g_strdup ("g_value_set_static_boxed");
3131 set_func = g_strdup_printf ("g_value_set%s_%s",
3132 do_static ? "_static" : "",
3134 gob_strdown (set_func);
3136 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3137 set_func, i, cast, fa->name);
3145 clear_signal_args (Method *m)
3150 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3152 if (m->args->next == NULL)
3155 for (li = m->args->next, i = 1;
3157 li = li->next, i++) {
3159 "\tg_value_unset (&___param_values[%d]);\n", i);
3164 get_arg_names_for_macro (Method *m)
3168 GString *gs = g_string_new(NULL);
3170 for(li=m->args;li;li=g_list_next(li)) {
3171 FuncArg *arg = li->data;
3172 g_string_sprintfa (gs, "%s___%s", sep, arg->name);
3175 return g_string_free (gs, FALSE);
3178 static gboolean method_is_void(Method *m)
3180 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3183 static const char *method_err_retval(Method *m)
3185 if (method_is_void(m))
3193 put_interface_parent_handler(Method *m)
3195 const char *errval = method_err_retval(m);
3196 char *name = replace_sep(m->interface, '_');
3197 char *args = get_arg_names_for_macro(m);
3199 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3200 "\t? %s_parent_iface->%s(%s) \\\n"
3201 "\t: %s)\n", args, name, name, m->id, args, errval);
3208 put_method(Method *m)
3210 char *s, *args, *doc;
3212 is_void = (strcmp(m->mtype->name, "void")==0 &&
3213 m->mtype->pointer == NULL);
3214 out_printf(out, "\n");
3215 if(m->method != OVERRIDE_METHOD) {
3216 doc = get_gtk_doc(m->id);
3218 out_printf(out, "%s", doc);
3224 case REGULAR_METHOD:
3226 out_addline_infile(out, m->line_no);
3227 if(m->scope == PRIVATE_SCOPE)
3228 print_method(out, "static ", "\n", "", " ", "", "\n",
3229 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3230 else /* PUBLIC, PROTECTED */
3231 print_method(out, "", "\n", "", " ", "", "\n",
3232 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3235 out_addline_outfile(out);
3236 put_interface_parent_handler(m);
3239 print_method_body(m, TRUE, TRUE);
3242 out_printf(out, "#undef PARENT_HANDLER\n");
3245 /* the outfile line was added above */
3247 case SIGNAL_FIRST_METHOD:
3248 case SIGNAL_LAST_METHOD:
3250 out_addline_infile(out, m->line_no);
3251 if(m->scope == PRIVATE_SCOPE)
3252 print_method(out, "static ", "\n", "", " ", "", "\n",
3253 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3254 else /* PUBLIC, PROTECTED */
3255 print_method(out, "", "\n", "", " ", "", "\n",
3256 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3257 out_printf (out, "{\n");
3259 out_addline_outfile (out);
3262 "\tGValue ___param_values[%d];\n"
3263 "\tGValue ___return_val;\n\n"
3264 "memset (&___return_val, 0, "
3265 "sizeof (___return_val));\n"
3266 "memset (&___param_values, 0, "
3267 "sizeof (___param_values));\n\n",
3268 g_list_length (m->args));
3270 print_preconditions (m);
3273 "\n\t___param_values[0].g_type = 0;\n"
3274 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3275 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3276 ((FuncArg *)m->args->data)->name,
3277 ((FuncArg *)m->args->data)->name);
3279 put_signal_args (m);
3281 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3282 const char *defret = NULL;
3284 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3285 (char *)m->gtktypes->data);
3287 if (m->defreturn != NULL)
3288 defret = m->defreturn;
3289 else if (m->onerror != NULL)
3290 defret = m->onerror;
3292 if (defret != NULL) {
3294 /* FIXME: This code is so fucking ugly it hurts */
3295 gboolean do_static =
3296 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3297 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3298 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3300 cast = get_type (m->mtype, TRUE);
3302 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3303 /* hack because glib is braindamaged */
3304 set_func = g_strdup ("g_value_set_uint");
3306 set_func = g_strdup_printf ("g_value_set%s_%s",
3307 do_static ? "_static" : "",
3308 (char *)m->gtktypes->data);
3309 gob_strdown (set_func);
3311 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3312 set_func, cast, defret);
3317 out_printf (out, "\n");
3320 s = g_strdup (m->id);
3323 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3324 "\t\tobject_signals[%s_SIGNAL],\n"
3325 "\t\t0 /* detail */,\n"
3326 "\t\t&___return_val);\n", s);
3330 clear_signal_args (m);
3332 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3333 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3335 /* Hack because glib is very very braindead */
3337 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3338 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3339 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3340 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3342 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3343 /* hack because glib is braindamaged */
3344 getfunc = g_strdup ("g_value_get_uint");
3346 getfunc = g_strdup_printf ("g_value_%s_%s",
3347 do_dup ? "dup" : "get",
3348 (char *)m->gtktypes->data);
3349 gob_strdown (getfunc);
3352 cast = get_type (m->mtype, TRUE);
3357 print_type (out, m->mtype, TRUE);
3359 " ___ret = (%s) %s (&___return_val);\n"
3360 "\t\tg_value_unset (&___return_val);\n"
3361 "\t\treturn ___ret;\n"
3368 out_printf(out, "}\n");
3373 out_addline_infile(out, m->line_no);
3374 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3375 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3376 print_method_body(m, FALSE, TRUE);
3377 /* the outfile line was added above */
3379 case VIRTUAL_METHOD:
3381 out_addline_infile(out, m->line_no);
3382 if(m->scope==PRIVATE_SCOPE)
3383 print_method(out, "static ", "\n", "", " ", "", "\n",
3384 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3385 else /* PUBLIC, PROTECTED */
3386 print_method(out, "", "\n", "", " ", "", "\n",
3387 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3388 out_printf(out, "{\n");
3389 out_addline_outfile(out);
3390 out_printf(out, "\t%sClass *klass;\n", typebase);
3391 print_preconditions(m);
3392 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3393 "\tif(klass->%s)\n",
3394 macrobase, ((FuncArg *)m->args->data)->name,
3396 if(strcmp(m->mtype->name, "void") == 0 &&
3397 m->mtype->pointer == NULL) {
3399 out_printf(out, "\t\t(*klass->%s)(%s",
3401 ((FuncArg *)m->args->data)->name);
3402 for(li=m->args->next;li;li=g_list_next(li)) {
3403 FuncArg *fa = li->data;
3404 out_printf(out, ",%s", fa->name);
3406 out_printf(out, ");\n}\n");
3409 out_printf(out, "\t\treturn (*klass->%s)(%s",
3411 ((FuncArg *)m->args->data)->name);
3412 for(li=m->args->next;li;li=g_list_next(li)) {
3413 FuncArg *fa = li->data;
3414 out_printf(out, ",%s", fa->name);
3416 out_printf(out, ");\n"
3419 print_type(out, m->mtype, TRUE);
3421 out_printf(out, ")(%s);\n}\n", m->defreturn);
3423 out_printf(out, ")(%s);\n}\n", m->onerror);
3425 out_printf(out, ")(0);\n}\n");
3431 out_addline_infile(out, m->line_no);
3432 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3433 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3434 print_method_body(m, FALSE, TRUE);
3435 /* the outfile line was added above */
3437 case OVERRIDE_METHOD:
3441 out_addline_infile(out, m->line_no);
3442 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3443 print_method(out, "static ", s, "", " ", "", "\n",
3444 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3446 out_addline_outfile(out);
3447 s = replace_sep(m->otype, '_');
3449 args = get_arg_names_for_macro(m);
3451 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3452 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3453 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3454 args, s, m->id, s, m->id, args);
3456 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3457 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3458 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3460 args, s, m->id, s, m->id, args);
3461 out_printf(out, "(");
3462 print_type(out, m->mtype, TRUE);
3463 out_printf(out, ")%s))\n",
3464 m->onerror?m->onerror:"0");
3468 print_method_body(m, TRUE, TRUE);
3469 /* the outfile line was added above */
3470 out_printf(out, "#undef PARENT_HANDLER\n");
3472 case CONSTRUCTOR_METHOD:
3473 case DISPOSE_METHOD:
3474 case FINALIZE_METHOD:
3476 out_addline_infile(out, m->line_no);
3477 print_method(out, "static ", "\n", "", " ", "", "\n",
3478 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3479 print_method_body(m, TRUE, TRUE);
3480 /* the outfile line was added above */
3489 char *outfile, *outfileh, *outfileph;
3491 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3492 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3494 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3495 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3497 if ((privates > 0 || protecteds > 0 ||
3498 private_header == PRIVATE_HEADER_ALWAYS) &&
3499 private_header != PRIVATE_HEADER_NEVER) {
3500 char sep[2] = {0,0};
3503 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3504 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3506 outfilephbase = NULL;
3512 out = fopen (outfile, "w");
3514 error_printf (GOB_ERROR, 0,
3515 "Cannot open outfile: %s", outfile);
3517 outh = fopen (outfileh, "w");
3519 error_printf (GOB_ERROR, 0,
3520 "Cannot open outfile: %s", outfileh);
3522 if (outfileph != NULL) {
3523 outph = fopen (outfileph, "w");
3524 if (outph == NULL) {
3525 error_printf (GOB_ERROR, 0,
3526 "Cannot open outfile: %s",
3534 put_argument_nongnu_wrappers (Class *c)
3538 if (get_properties < 0 && set_properties < 0)
3541 for (li = c->nodes; li != NULL; li = li->next) {
3543 const char *name, *gtktype;
3549 if (n->type == ARGUMENT_NODE) {
3550 Argument *a = (Argument *)n;
3552 gtktype = a->gtktype;
3554 get = a->get != NULL;
3555 set = a->set != NULL;
3556 } else if (n->type == PROPERTY_NODE) {
3557 Property *p = (Property *)n;
3559 gtktype = p->gtktype;
3561 get = p->get != NULL;
3562 set = p->set != NULL;
3567 aname = g_strdup (name);
3571 cast = get_type (atype, TRUE);
3573 cast = g_strdup (get_cast (gtktype, TRUE));
3577 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3578 "\"%s\",(%s)(arg)\n",
3579 macrobase, aname, name, cast);
3581 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3582 "\"%s\",(%s*)(arg)\n",
3583 macrobase, aname, name, cast);
3586 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3588 macrobase, aname, name);
3590 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3592 macrobase, aname, name);
3600 put_argument_gnu_wrappers(Class *c)
3604 if(get_properties < 0 && set_properties < 0)
3607 for (li = c->nodes; li != NULL; li = li->next) {
3609 const char *name, *gtktype;
3615 if (n->type == ARGUMENT_NODE) {
3616 Argument *a = (Argument *)n;
3618 gtktype = a->gtktype;
3620 get = a->get != NULL;
3621 set = a->set != NULL;
3622 } else if (n->type == PROPERTY_NODE) {
3623 Property *p = (Property *)n;
3625 gtktype = p->gtktype;
3627 get = p->get != NULL;
3628 set = p->set != NULL;
3633 aname = g_strdup (name);
3637 cast = get_type (atype, TRUE);
3639 cast = g_strdup (get_cast (gtktype, TRUE));
3643 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3644 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3645 macrobase, aname, name, cast);
3647 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3648 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3649 macrobase, aname, name, cast);
3652 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3654 macrobase, aname, name);
3656 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3658 macrobase, aname, name);
3666 print_ccode_block(CCode *cc)
3669 switch(cc->cctype) {
3671 /* HT code is printed exactly like normal header
3672 code but is printed before */
3675 out_printf(fp, "\n");
3678 /* AT code is printed exactly like normal 'all'
3679 code but is printed before */
3682 out_printf(outph, "\n");
3683 out_printf(outph, "%s\n", cc->cbuf);
3684 out_addline_infile(outph, cc->line_no);
3685 out_addline_outfile(outph);
3687 out_printf(outh, "\n");
3688 out_printf(outh, "%s\n", cc->cbuf);
3690 out_printf(fp, "\n");
3691 out_addline_infile(fp, cc->line_no);
3697 out_printf(fp, "\n");
3698 out_addline_infile(fp, cc->line_no);
3705 out_printf(fp, "\n");
3706 out_addline_infile(fp, cc->line_no);
3709 out_printf(fp, "%s\n", cc->cbuf);
3710 if(cc->cctype == C_CCODE ||
3711 cc->cctype == AD_CCODE ||
3712 cc->cctype == A_CCODE ||
3713 cc->cctype == AT_CCODE ||
3714 cc->cctype == PH_CCODE)
3715 out_addline_outfile(fp);
3719 print_class_block(Class *c)
3723 gboolean printed_private = FALSE;
3727 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3728 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3732 out_printf(out, "/* utility types we may need */\n");
3733 if(special_array[SPECIAL_2POINTER])
3734 out_printf(out, "typedef struct { "
3735 "gpointer a; gpointer b; "
3736 "} ___twopointertype;\n");
3737 if(special_array[SPECIAL_3POINTER])
3738 out_printf(out, "typedef struct { "
3739 "gpointer a; gpointer b; "
3741 "} ___threepointertype;\n");
3742 if(special_array[SPECIAL_INT_POINTER])
3743 out_printf(out, "typedef struct { "
3744 "gint a; gpointer b; "
3745 "} ___intpointertype;\n");
3746 out_printf(out, "\n");
3749 out_printf(outh, "\n/*\n"
3750 " * Type checking and casting macros\n"
3752 out_printf(outh, "#define %s\t"
3753 "(%s_get_type())\n",
3754 macrotype, funcbase);
3755 out_printf(outh, "#define %s(obj)\t"
3756 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3757 macrobase, funcbase, typebase);
3758 out_printf(outh, "#define %s_CONST(obj)\t"
3759 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3760 macrobase, funcbase, typebase);
3761 out_printf(outh, "#define %s_CLASS(klass)\t"
3762 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3763 macrobase, funcbase, typebase);
3764 out_printf(outh, "#define %s(obj)\t"
3765 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3768 "#define %s_GET_CLASS(obj)\t"
3769 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3770 macrobase, funcbase, typebase);
3772 if ( ! no_self_alias) {
3773 out_printf(out, "/* self casting macros */\n");
3774 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3775 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3776 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3777 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3778 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3780 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3783 out_printf(out, "/* self typedefs */\n");
3784 out_printf(out, "typedef %s Self;\n", typebase);
3785 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3789 always_private_struct) {
3790 out_printf (outh, "\n/* Private structure type */\n");
3791 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3792 typebase, typebase);
3794 out_printf (outh, "/* There are no privates, this "
3795 "structure is thus never defined */\n");
3798 out_printf (outh, "\n/*\n"
3799 " * Main object structure\n"
3801 s = replace_sep (c->otype, '_');
3803 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3804 "#define __TYPEDEF_%s__\n", s, s);
3806 out_printf (outh, "typedef struct _%s %s;\n"
3807 "#endif\n", typebase, typebase);
3808 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3809 typebase, ptypebase);
3810 for (li = c->nodes; li; li=li->next) {
3811 static gboolean printed_public = FALSE;
3813 Variable *v = (Variable *)n;
3814 if(n->type == VARIABLE_NODE &&
3815 v->scope == PUBLIC_SCOPE) {
3816 if( ! printed_public) {
3817 out_printf(outh, "\t/*< public >*/\n");
3818 printed_public = TRUE;
3820 put_variable((Variable *)n, outh);
3823 /* put protecteds always AFTER publics */
3824 for (li = c->nodes; li != NULL; li = li->next) {
3826 Variable *v = (Variable *)n;
3827 if (n->type == VARIABLE_NODE &&
3828 v->scope == PROTECTED_SCOPE) {
3829 if ( ! printed_private) {
3830 out_printf (outh, "\t/*< private >*/\n");
3831 printed_private = TRUE;
3833 put_variable ((Variable *)n, outh);
3837 always_private_struct) {
3838 if ( ! printed_private)
3839 out_printf (outh, "\t/*< private >*/\n");
3840 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3842 out_printf (outh, "};\n");
3847 /* if we are to stick this into the private
3848 header, if not stick it directly into the
3855 out_printf (outfp, "struct _%sPrivate {\n",
3859 for(li=c->nodes; li; li=li->next) {
3861 Variable *v = (Variable *)n;
3862 if(n->type == VARIABLE_NODE &&
3863 v->scope == PRIVATE_SCOPE) {
3864 out_addline_infile(outfp, v->line_no);
3865 put_variable(v, outfp);
3868 out_addline_outfile(outfp);
3870 out_printf(outfp, "};\n");
3873 out_printf(outh, "\n/*\n"
3874 " * Class definition\n"
3876 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3877 typebase, typebase);
3879 "struct _%sClass {\n\t%sClass __parent__;\n",
3880 typebase, ptypebase);
3881 for(li = c->nodes; li != NULL; li = li->next) {
3883 if(n->type == METHOD_NODE)
3884 put_vs_method((Method *)n);
3886 /* If BonoboX type class put down the epv */
3887 if (c->bonobo_object_class != NULL) {
3889 "\t/* Bonobo object epv */\n"
3890 "\tPOA_%s__epv _epv;\n",
3891 c->bonobo_object_class);
3893 /* put class scope variables */
3894 for (li = c->nodes; li != NULL; li = li->next) {
3896 Variable *v = (Variable *)n;
3897 if (n->type == VARIABLE_NODE &&
3898 v->scope == CLASS_SCOPE)
3899 put_variable ((Variable *)n, outh);
3901 out_printf (outh, "};\n\n");
3903 out_printf (out, "/* here are local prototypes */\n");
3904 if (set_properties > 0) {
3905 out_printf (out, "static void ___object_set_property "
3906 "(GObject *object, guint property_id, "
3907 "const GValue *value, GParamSpec *pspec);\n");
3909 if (get_properties > 0) {
3910 out_printf (out, "static void ___object_get_property "
3911 "(GObject *object, guint property_id, "
3912 "GValue *value, GParamSpec *pspec);\n");
3915 out_printf (outh, "\n/*\n"
3916 " * Public methods\n"
3919 if (!overrode_get_type && !no_gnu) {
3921 * For ordinary "static" types it should be safe to mark the
3922 * get_type implementation as const, since the get_type
3923 * function return really is constant at the call boundary
3924 * (even though there is an initial setup on the first call).
3925 * But for dynamic types, since the registration is explicitly
3926 * separated, we need to settle for "pure" as the results of
3927 * get_type differ before and after type registration.
3929 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3930 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3934 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3938 for(li = c->nodes; li != NULL; li = li->next) {
3940 if(n->type == METHOD_NODE) {
3941 put_pub_method((Method *)n);
3942 put_prot_method((Method *)n);
3943 put_priv_method_prot((Method *)n);
3947 /* this idea is less and less apealing to me */
3949 out_printf (outh, "\n/*\n"
3950 " * Signal connection wrapper macros\n"
3953 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3954 put_signal_macros (c, TRUE);
3955 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3956 put_signal_macros (c, FALSE);
3957 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3959 put_signal_macros (c, FALSE);
3960 out_printf(outh, "\n");
3963 out_printf (out, "\n/*\n"
3964 " * Signal connection wrapper macro shortcuts\n"
3966 put_local_signal_macros (c);
3967 out_printf(outh, "\n");
3970 /* argument wrapping macros */
3971 if(get_properties > 0 || set_properties > 0) {
3972 out_printf(outh, "\n/*\n"
3973 " * Argument wrapping macros\n"
3976 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3977 put_argument_gnu_wrappers(c);
3978 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3979 put_argument_nongnu_wrappers(c);
3980 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3982 put_argument_nongnu_wrappers(c);
3987 for(li = c->nodes; li != NULL; li = li->next) {
3989 if(n->type == METHOD_NODE)
3990 add_signal_prots((Method *)n);
3996 if(any_method_to_alias(c)) {
3997 out_printf (out, "/* Short form macros */\n");
3998 make_method_aliases (c);
4001 add_interface_inits (c);
4003 if (!overrode_get_type) {
4004 if (c->bonobo_object_class != NULL)
4005 add_bonobo_object_get_type();
4006 else if (c->dynamic)
4007 add_dynamic_get_type();
4012 out_printf (out, "/* a macro for creating a new object of our type */\n");
4014 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4015 typebase, funcbase);
4017 out_printf (out, "/* a function for creating a new object of our type */\n");
4018 out_printf (out, "#include <stdarg.h>\n");
4020 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4021 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4022 "{\n\t%s *ret;\n\tva_list ap;\n"
4023 "\tva_start (ap, first);\n"
4024 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4027 "\treturn ret;\n}\n\n",
4029 no_gnu ? "" : " G_GNUC_UNUSED",
4030 typebase, typebase, typebase, funcbase);
4034 out_printf (out, "/* a function to connect glade callback */\n");
4035 out_printf (out,"static void\n"
4036 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4037 "GObject *object,\n"
4038 "const gchar *signal_name,\n"
4039 "const gchar *signal_data,\n"
4040 "GObject *connect_object,\n"
4042 "gpointer user_data)\n"
4044 "\tstatic GModule * allsymbols = NULL;\n"
4046 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4047 "\tif (allsymbols) {\n"
4048 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4049 "\t\tGCallback func;\n"
4051 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4052 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4053 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4054 "\t\t\t\tg_free(func_name);\n"
4059 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4061 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4062 "\t\tg_free(func_name);\n"
4069 for (li = nodes; li != NULL; li = li->next) {
4070 Node *node = li->data;
4071 if (node->type == CCODE_NODE) {
4072 CCode *cc = (CCode *)node;
4073 if (cc->cctype == AD_CCODE)
4074 print_ccode_block (cc);
4078 if (need_constructor)
4079 add_constructor (c);
4089 if(set_properties > 0) {
4090 add_getset_arg(c, TRUE);
4093 if(get_properties > 0) {
4094 add_getset_arg(c, FALSE);
4097 for(li = c->nodes; li != NULL; li = li->next) {
4099 if(n->type == METHOD_NODE)
4100 put_method((Method *)n);
4103 add_bad_hack_to_avoid_unused_warnings(c);
4107 print_useful_macros(void)
4109 int major = 0, minor = 0, pl = 0;
4112 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4113 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4114 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4115 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4117 /* Useful priv macro thingie */
4118 /* FIXME: this should be done the same way that priv is, as a var,
4120 out_printf (out, "#define selfp (self->_priv)\n\n");
4124 print_more_useful_macros (void)
4127 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4128 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4130 out_printf (out, "#ifdef G_LIKELY\n");
4131 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4132 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4133 out_printf (out, "#else /* ! G_LIKELY */\n");
4134 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4135 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4136 out_printf (out, "#endif /* G_LIKELY */\n");
4141 print_file_comments(void)
4143 out_printf(outh, "/* Generated by GOB (v%s)"
4144 " (do not edit directly) */\n\n", VERSION);
4146 out_printf(outph, "/* Generated by GOB (v%s)"
4147 " (do not edit directly) */\n\n", VERSION);
4148 out_printf(out, "/* Generated by GOB (v%s)"
4149 " (do not edit directly) */\n\n", VERSION);
4151 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4155 print_includes(void)
4157 gboolean found_header;
4160 /* We may need string.h for memset */
4161 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4162 out_printf(out, "#include <string.h> /* memset() */\n\n");
4165 p = g_strconcat(filebase, ".h", NULL);
4166 found_header = TRUE;
4167 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4168 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4169 found_header = FALSE;
4173 /* if we are creating a private header see if it was included */
4175 char sep[2] = {0,0};
4178 p = g_strconcat(filebase, sep, "private.h", NULL);
4179 if( ! g_list_find_custom(include_files, p,
4180 (GCompareFunc)strcmp)) {
4181 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4185 error_printf(GOB_WARN, 0,
4186 "Implicit private header include "
4188 "\tsource file, while public "
4189 "header is at a custom location, "
4191 "\texplicitly include "
4192 "the private header below the "
4200 print_header_prefixes(void)
4204 p = replace_sep(((Class *)class)->otype, '_');
4206 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4208 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4209 "#define __%s_PRIVATE_H__\n\n"
4210 "#include \"%s.h\"\n\n", p, p, filebase);
4213 if( ! no_extern_c) {
4214 out_printf(outh, "#ifdef __cplusplus\n"
4216 "#endif /* __cplusplus */\n\n");
4218 out_printf(outph, "#ifdef __cplusplus\n"
4220 "#endif /* __cplusplus */\n\n");
4225 print_header_postfixes(void)
4228 out_printf(outh, "\n#ifdef __cplusplus\n"
4230 "#endif /* __cplusplus */\n");
4231 out_printf(outh, "\n#endif\n");
4234 out_printf(outph, "\n#ifdef __cplusplus\n"
4236 "#endif /* __cplusplus */\n");
4237 out_printf(outph, "\n#endif\n");
4246 /* print the AT_CCODE and CT_CCODE blocks */
4247 for(li = nodes; li != NULL; li = li->next) {
4248 Node *node = li->data;
4249 if(node->type == CCODE_NODE) {
4250 CCode *cc = (CCode *)node;
4251 if (cc->cctype == AT_CCODE ||
4252 cc->cctype == CT_CCODE)
4253 print_ccode_block((CCode *)node);
4259 print_header_top(void)
4263 /* mandatory includes */
4264 out_printf (outh, "#include <glib.h>\n");
4265 out_printf (outh, "#include <glib-object.h>\n");
4267 /* print the HT_CCODE blocks */
4268 for (li = nodes; li != NULL; li = li->next) {
4269 Node *node = li->data;
4270 if (node->type == CCODE_NODE) {
4271 CCode *cc = (CCode *)node;
4272 if (cc->cctype == HT_CCODE)
4273 print_ccode_block ((CCode *)node);
4279 print_enum (EnumDef *enode)
4286 funcprefix = replace_sep (enode->etype, '_');
4287 gob_strdown (funcprefix);
4288 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4290 type = remove_sep (enode->etype);
4292 out_printf (outh, "\ntypedef enum {\n");
4294 for (li = enode->values; li != NULL; li = li->next) {
4295 EnumValue *value = li->data;
4297 char *sname = gob_strdown (g_strdup (value->name));
4299 while ((p = strchr (sname, '_')) != NULL)
4302 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4303 if (value->value != NULL)
4304 out_printf (outh, " = %s", value->value);
4305 if (li->next != NULL)
4306 out_printf (outh, ",\n");
4308 out_printf (outh, "\n");
4310 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4311 enode->prefix, value->name,
4312 enode->prefix, value->name,
4318 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4320 out_printf (outh, "} %s;\n", type);
4322 str = make_pre_macro (enode->etype, "TYPE");
4323 out_printf (outh, "#define %s ", str);
4326 out_printf (outh, "%s_get_type()\n", funcprefix);
4327 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4328 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4331 "GType\n%s_get_type (void)\n"
4333 "\tstatic GType type = 0;\n"
4334 "\tif ___GOB_UNLIKELY(type == 0)\n"
4335 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4338 funcprefix, type, funcprefix);
4340 g_free (funcprefix);
4345 print_flags (Flags *fnode)
4353 funcprefix = replace_sep (fnode->ftype, '_');
4354 gob_strdown (funcprefix);
4355 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4357 type = remove_sep (fnode->ftype);
4359 out_printf (outh, "\ntypedef enum {\n");
4361 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4362 const char *name = li->data;
4364 char *sname = gob_strdown (g_strdup (name));
4366 while ((p = strchr (sname, '_')) != NULL)
4369 out_printf (outh, "\t%s_%s = 1<<%d",
4370 fnode->prefix, name, i);
4371 if (li->next != NULL)
4372 out_printf (outh, ",\n");
4374 out_printf (outh, "\n");
4376 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4377 fnode->prefix, name,
4378 fnode->prefix, name,
4384 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4386 out_printf (outh, "} %s;\n", type);
4388 str = make_pre_macro (fnode->ftype, "TYPE");
4389 out_printf (outh, "#define %s ", str);
4392 out_printf (outh, "%s_get_type()\n", funcprefix);
4393 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4394 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4397 "GType\n%s_get_type (void)\n"
4399 "\tstatic GType type = 0;\n"
4400 "\tif ___GOB_UNLIKELY(type == 0)\n"
4401 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4404 funcprefix, type, funcprefix);
4406 g_free (funcprefix);
4411 print_error (Error *enode)
4418 funcprefix = replace_sep (enode->etype, '_');
4419 gob_strdown (funcprefix);
4420 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4422 type = remove_sep (enode->etype);
4424 out_printf (outh, "\ntypedef enum {\n");
4426 for (li = enode->values; li != NULL; li = li->next) {
4427 const char *name = li->data;
4429 char *sname = gob_strdown (g_strdup (name));
4431 while ((p = strchr (sname, '_')) != NULL)
4434 out_printf (outh, "\t%s_%s", enode->prefix, name);
4435 if (li->next != NULL)
4436 out_printf (outh, ",\n");
4438 out_printf (outh, "\n");
4440 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4441 enode->prefix, name,
4442 enode->prefix, name,
4448 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4450 out_printf (outh, "} %s;\n", type);
4452 str = make_pre_macro (enode->etype, "TYPE");
4453 out_printf (outh, "#define %s ", str);
4456 out_printf (outh, "%s_get_type ()\n", funcprefix);
4457 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4458 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4461 "GType\n%s_get_type (void)\n"
4463 "\tstatic GType type = 0;\n"
4464 "\tif ___GOB_UNLIKELY(type == 0)\n"
4465 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4468 funcprefix, type, funcprefix);
4470 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4471 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4473 str = replace_sep (enode->etype, '-');
4477 "GQuark\n%s_quark (void)\n"
4479 "\tstatic GQuark q = 0;\n"
4481 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4488 g_free (funcprefix);
4493 generate_outfiles(void)
4497 print_file_comments();
4503 print_header_prefixes();
4505 print_useful_macros();
4509 print_more_useful_macros ();
4511 for (li = nodes; li != NULL; li = li->next) {
4512 Node *node = li->data;
4513 if (node->type == CCODE_NODE) {
4514 CCode *cc = (CCode *)node;
4515 if (cc->cctype != HT_CCODE &&
4516 cc->cctype != AT_CCODE &&
4517 cc->cctype != AD_CCODE)
4518 print_ccode_block ((CCode *)node);
4519 } else if (node->type == CLASS_NODE) {
4520 print_class_block ((Class *)node);
4521 } else if (node->type == ENUMDEF_NODE) {
4522 print_enum ((EnumDef *)node);
4523 } else if (node->type == FLAGS_NODE) {
4524 print_flags ((Flags *)node);
4525 } else if (node->type == ERROR_NODE) {
4526 print_error ((Error *)node);
4528 g_assert_not_reached();
4532 print_header_postfixes();
4535 static void print_version(void)
4537 printf("%s (%s) %s\n", PACKAGE_NAME, PACKAGE_TARNAME, PACKAGE_VERSION);
4539 puts("Copyright (C) 2013 George (Jiri) Lebl et al.");
4540 puts("Copyright (C) 2020 Nick Bowler");
4541 puts("License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl.html>.");
4542 puts("This is free software: you are free to change and redistribute it.");
4543 puts("There is NO WARRANTY, to the extent permitted by law.");
4547 static void print_usage(FILE *f)
4549 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4551 fprintf(f, "Try '%s --help' for more information.\n",
4557 * Given a long option, return the corresponding short option character,
4558 * or 0 if there is no such character.
4560 static char lopt_to_sopt(const char *sopts, const struct option *opt)
4565 if (val <= 0 || val > CHAR_MAX)
4568 if (val == ':' || val == '+' || val == '-')
4571 c = strchr(sopts, opt->val);
4578 * Print a string, with each line indented by i spaces. The first line
4579 * will be indented by w fewer spaces (to account for the cursor being in
4580 * some other column).
4582 static void print_block(const char *s, int i, int w)
4585 const char *nl = strchr(s, '\n');
4586 int n = (nl ? nl-s : -1);
4588 printf("%*s%.*s\n", i-w, "", n, s);
4596 static void print_help(void)
4598 const struct option *opt;
4600 print_usage(stdout);
4602 puts("This is \"GObject Builder\": a simple preprocessor to help with\n"
4603 "implementing GObject types in C.");
4606 for (opt = lopts; opt->name; opt++) {
4607 struct lopt_help help;
4611 /* Don't display obsolete options that don't do anything */
4612 if (!opt->flag && !opt->val)
4615 if (!lopt_get_help(opt, &help))
4618 if ((sopt = lopt_to_sopt(sopts, opt))) {
4619 w = printf(opt->has_arg == 0 ? " -%c, --%s"
4620 : opt->has_arg == 1 ? " -%c, --%s=%s"
4621 : " -%c, --%s[=%s]",
4622 sopt, opt->name, help.arg);
4624 w = printf(opt->has_arg == 0 ? " --%s"
4625 : opt->has_arg == 1 ? " --%s=%s"
4627 opt->name, help.arg);
4630 if (w < 0 || w > 18) {
4635 print_block(help.desc, 20, w);
4639 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4643 * Called after getopt_long receives an --m4 argument. Immediately stop
4644 * processing options. Then all non-option arguments seen so far together
4645 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4646 * is false, then M4_FLAGS is inserted before the first non-option argument,
4649 * The resulting string is returned, which should be freed by the caller.
4651 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4653 char **nonopt = NULL, *save_argv0, *ret;
4656 /* First, conclude getopt run and reset with remaining args */
4657 getopt_long(optind, argv, sopts, lopts, NULL);
4662 save_argv0 = argv[0];
4663 argv[0] = M4_COMMANDLINE;
4666 ret = g_strjoinv(" ", argv);
4667 argv[0] = save_argv0;
4671 /* Locate first non-option argument, if any. */
4672 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4674 nonopt = &argv[optind-2];
4679 /* If there is a non-option but the above didn't see it, must be "--" */
4680 if (!nonopt && argv[optind])
4681 nonopt = &argv[optind-2];
4684 /* Found non-option, insert M4_FLAGS just before it. */
4685 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4687 nonopt[1] = M4_FLAGS;
4689 nonopt[0] = g_strjoinv(" ", argv);
4691 nonopt[1] = save_argv[1];
4692 nonopt[2] = save_argv[2];
4693 ret = g_strjoinv(" ", nonopt);
4696 nonopt[0] = save_argv[0];
4698 /* Only options, not inserting M4_FLAGS. */
4699 ret = g_strjoinv(" ", argv);
4702 argv[0] = save_argv0;
4706 static int parse_options(int argc, char **argv)
4708 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4709 char *raw_file_sep = "-";
4713 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4719 output_dir = optarg;
4722 exit_on_warn = TRUE;
4725 raw_file_sep = optarg ? optarg : "";
4731 no_touch = no_touch_headers = TRUE;
4737 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4743 if (optopt == '?') {
4749 /* Rewind getopt to get internal error messages. */
4750 optind = 0, opterr = 1;
4751 while (getopt_long(argc, argv, sopts, lopts, NULL)
4754 case 0: /* no-op or option set by flag */;
4758 filename = argv[optind];
4759 if (argc > optind+1) {
4760 char *s = g_strjoinv(" ", argv+optind+1);
4761 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4762 g_get_prgname(), s);
4768 file_sep = raw_file_sep[0];
4769 if (raw_file_sep[0] && raw_file_sep[1]) {
4770 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4777 printf("%s\n", M4_INCLUDE_DIR);
4785 compare_and_move (const char *old_filename)
4787 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4789 gboolean equal = FALSE;
4791 old_f = fopen (old_filename, "r");
4794 gboolean error = FALSE;
4796 new_f = fopen (new_filename, "r");
4805 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4806 if (ferror (new_f)) {
4808 error_printf (GOB_ERROR, 0,
4809 "Can't read %s: %s",
4811 g_strerror (errno));
4815 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4817 || feof (new_f) != feof (old_f)
4819 || memcmp (new_buf, old_buf, new_n) != 0)
4828 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4829 new_filename, g_strerror (errno));
4837 if (! equal && unlink (old_filename) != 0) {
4838 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4839 old_filename, g_strerror (errno));
4845 if (unlink (new_filename) != 0)
4846 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4847 new_filename, g_strerror (errno));
4849 if (rename (new_filename, old_filename) != 0)
4850 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4851 new_filename, old_filename,
4852 g_strerror (errno));
4856 g_free (new_filename);
4860 main(int argc, char *argv[])
4864 g_set_prgname(argc > 0 ? argv[0] : "gob2");
4866 rc = parse_options(argc, argv);
4868 print_usage(stderr);
4869 return EXIT_FAILURE;
4870 } else if (rc > 0) {
4871 return EXIT_SUCCESS;
4875 yyin = popen(m4_commandline, "r");
4877 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4881 } else if(filename) {
4882 yyin = fopen(filename, "r");
4884 fprintf(stderr, "Error: can't open file '%s'\n",
4893 /* This is where parsing is done */
4896 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4898 /* close input file */
4899 if(use_m4) pclose(yyin);
4904 error_print (GOB_ERROR, 0, "no class defined");
4907 exit_on_error = FALSE;
4909 signals = count_signals ((Class *)class);
4910 set_properties = count_set_properties ((Class *)class) +
4911 count_set_arguments ((Class *)class);
4912 get_properties = count_get_properties ((Class *)class) +
4913 count_get_arguments ((Class *)class);
4914 overrides = count_overrides ((Class *)class);
4915 privates = count_privates ((Class *)class);
4916 protecteds = count_protecteds ((Class *)class);
4917 unreftors = count_unreftors ((Class *)class);
4918 destructors = count_destructors ((Class *)class);
4919 initializers = count_initializers ((Class *)class);
4920 glade_widgets = count_glade_widgets ((Class *)class);
4921 overrode_get_type = find_get_type ((Class *)class);
4924 make_inits ((Class *)class);
4926 find_constructor ((Class *)class);
4927 if (user_constructor != NULL)
4928 need_constructor = TRUE;
4930 find_dispose ((Class *)class);
4931 if (unreftors > 0 ||
4932 dispose_handler != NULL ||
4933 user_dispose_method != NULL)
4934 need_dispose = TRUE;
4936 find_finalize ((Class *)class);
4937 if (destructors > 0 ||
4939 user_finalize_method != NULL) {
4940 need_finalize = TRUE;
4943 check_bad_symbols ((Class *)class);
4944 check_duplicate_symbols ((Class *)class);
4945 check_duplicate_overrides ((Class *)class);
4946 check_duplicate_signals_args ((Class *)class);
4947 check_public_new ((Class *)class);
4948 check_vararg ((Class *)class);
4949 check_firstarg ((Class *)class);
4950 check_nonvoidempty ((Class *)class);
4951 check_signal_args ((Class *)class);
4952 check_property_types ((Class *)class);
4953 check_argument_types ((Class *)class);
4954 check_func_arg_checks ((Class *)class);
4955 check_func_attrs ((Class *)class);
4956 check_for_class_destructors ((Class *)class);
4958 exit_on_error = TRUE;
4963 any_special = setup_special_array ((Class *)class, special_array);
4967 generate_outfiles ();
4978 compare_and_move(outfilebase);
4980 if (no_touch_headers) {
4981 compare_and_move(outfilehbase);
4983 compare_and_move(outfilephbase);