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-2022 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"
48 static const char sopts[] = SOPT_STRING;
49 static const struct option lopts[] = {
54 char *filename = NULL;
64 extern GList *include_files;
66 extern GHashTable *gtk_doc_hash;
70 static char *outfilebase;
71 static char *outfilehbase;
72 static char *outfilephbase;
73 static char *funcbase;
74 static char *pfuncbase;
75 static char *macrobase;
77 static char *pmacrois;
78 static char *macrotype;
79 static char *pmacrotype;
80 static char *typebase;
81 static char *ptypebase;
83 char *output_dir = NULL;
87 static int signals = 0; /* number of signals */
88 static int set_properties = 0; /* number of named (set) properties */
89 static int get_properties = 0; /* number of named (get) properties */
90 static int overrides = 0; /* number of override methods */
91 static int privates = 0; /* number of private data members */
92 static int protecteds = 0; /* number of protected methods */
93 static int unreftors = 0; /* number of variable unreffing destructors */
94 static int destructors = 0; /* number of variable non-unreffing destructors */
95 static int initializers = 0; /* number of variable initializers */
96 static int glade_widgets = 0; /* number of glade widgets */
97 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
99 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
100 and need the REALLY UGLY HACK to
103 /* the special variable types we need to define */
104 static gboolean special_array[SPECIAL_LAST] = {0};
105 static gboolean any_special = FALSE;
107 static gboolean need_constructor = FALSE;
108 static Method * user_constructor = NULL;
110 static gboolean need_dispose = FALSE;
111 static Method * dispose_handler = NULL;
112 static Method * user_dispose_method = NULL;
114 static gboolean need_finalize = FALSE;
115 static Method * finalize_handler = NULL;
116 static Method * user_finalize_method = NULL;
122 gboolean no_touch = FALSE;
123 gboolean no_touch_headers = FALSE;
124 gboolean for_cpp = FALSE;
125 gboolean no_gnu = FALSE;
126 gboolean exit_on_warn = FALSE;
127 gboolean exit_on_error = TRUE;
128 gboolean got_error = FALSE;
129 gint private_header = PRIVATE_HEADER_ONDEMAND;
130 gboolean no_extern_c = FALSE;
131 gboolean no_write = FALSE;
132 gboolean no_lines = FALSE;
133 gboolean no_self_alias = FALSE;
134 gboolean always_private_struct = FALSE;
135 gboolean gtk3_ok = FALSE;
141 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
142 char *m4_commandline = NULL;
143 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
144 #define M4_BASE_FILENAME "gobm4.m4"
145 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
146 #define M4_COMMANDLINE "m4"
148 int method_unique_id = 1;
153 filebase = replace_sep (((Class *)class)->otype, file_sep);
154 gob_strdown (filebase);
156 if (output_dir != NULL &&
157 output_dir[0] != '\0') {
158 fullfilebase = g_build_filename (output_dir, filebase, NULL);
160 fullfilebase = g_strdup (filebase);
163 funcbase = replace_sep (((Class *)class)->otype, '_');
164 gob_strdown (funcbase);
166 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
167 gob_strdown (pfuncbase);
169 macrobase = replace_sep (((Class *)class)->otype, '_');
170 gob_strup (macrobase);
172 macrois = make_pre_macro (((Class *)class)->otype, "IS");
173 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
175 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
176 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
178 typebase = remove_sep (((Class *)class)->otype);
180 ptypebase = remove_sep (((Class *)class)->ptype);
184 get_gtk_doc (const char *id)
191 val = g_hash_table_lookup(gtk_doc_hash, id);
193 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
195 val = g_hash_table_lookup(gtk_doc_hash, id);
197 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
203 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
207 s = get_type(t, postfix_to_stars);
208 out_printf(fp, "%s", s);
214 print_method (FILE *fp,
215 const char *typeprefix,
216 const char *nameprefix,
217 const char *subnameprefix,
218 const char *namepostfix,
219 const char *afterargs,
222 gboolean print_funcattrs,
223 gboolean one_arg_per_line,
224 gboolean no_funcbase,
225 gboolean kill_underscore,
226 gboolean first_unused,
232 out_printf(fp, "%s", typeprefix);
233 print_type(fp, m->mtype, TRUE);
238 out_printf(fp, "%s%s%s%s(",
239 nameprefix, subnameprefix, id, namepostfix);
241 out_printf(fp, "%s%s_%s%s%s(",
242 nameprefix, funcbase, subnameprefix, id,
246 for(li=m->args; li; li=g_list_next(li)) {
247 FuncArg *arg = li->data;
248 const char *unused = "";
251 ! for_cpp && /* g++ has a cow with this */
254 unused = " G_GNUC_UNUSED";
257 print_type(fp, arg->atype, FALSE);
259 out_printf (fp, "___fake___");
261 out_printf(fp, "%s%s%s,%s", arg->name,
262 arg->atype->postfix ?
263 arg->atype->postfix : "",
265 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
267 out_printf(fp, "%s%s%s", arg->name,
268 arg->atype->postfix ?
269 arg->atype->postfix : "",
273 out_printf(fp, ",%s...",
274 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
276 out_printf(fp, "void");
278 /* Slightly icky: sometimes we are called st m->funcattrs
279 hasn't been set, but if so it should be NULL since its been
281 if(print_funcattrs && m->funcattrs != NULL
282 && strlen(m->funcattrs) > 0) {
283 /* To keep the output neat, we trim off the trailing '\n'
284 from the end of funcattrs for a moment. */
285 size_t funcattrs_len = strlen(m->funcattrs);
286 gboolean funcattrs_chomped = FALSE;
287 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
288 m->funcattrs[funcattrs_len - 1] = '\0';
289 funcattrs_chomped = TRUE;
291 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
292 /* Put it back like it was (though it shouldn't matter). */
293 if (funcattrs_chomped) {
294 (m->funcattrs)[funcattrs_len - 1] = '\n';
298 out_printf(fp, "%s)%s", afterargs, postfix);
303 any_method_to_alias(Class *c)
307 for(li=c->nodes;li;li=g_list_next(li)) {
308 Node *node = li->data;
309 if(node->type == METHOD_NODE) {
310 Method *m = (Method *)node;
312 if(m->method == INIT_METHOD ||
313 m->method == CLASS_INIT_METHOD ||
314 m->method == CONSTRUCTOR_METHOD ||
315 m->method == DISPOSE_METHOD ||
316 m->method == FINALIZE_METHOD ||
317 m->method == OVERRIDE_METHOD)
328 make_method_aliases (Class *c)
332 for(li = c->nodes; li != NULL; li = li->next) {
333 Node *node = li->data;
334 if(node->type == METHOD_NODE) {
335 Method *m = (Method *)node;
337 if(m->method == INIT_METHOD ||
338 m->method == CLASS_INIT_METHOD ||
339 m->method == CONSTRUCTOR_METHOD ||
340 m->method == DISPOSE_METHOD ||
341 m->method == FINALIZE_METHOD ||
342 m->method == OVERRIDE_METHOD)
345 out_printf (out, "#define self_%s %s_%s\n",
354 add_bad_hack_to_avoid_unused_warnings(const Class *c)
358 /* if we haven't had any methods, just return */
363 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
365 "/*REALLY BAD HACK\n"
366 " This is to avoid unused warnings if you don't call\n"
367 " some method. I need to find a better way to do\n"
368 " this, not needed in GCC since we use some gcc\n"
369 " extentions to make saner, faster code */\n"
371 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
373 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
374 for(li=c->nodes;li;li=g_list_next(li)) {
375 Node *node = li->data;
376 if(node->type == METHOD_NODE) {
377 Method *m = (Method *)node;
379 if(m->method == INIT_METHOD ||
380 m->method == CLASS_INIT_METHOD ||
381 m->method == CONSTRUCTOR_METHOD ||
382 m->method == DISPOSE_METHOD ||
383 m->method == FINALIZE_METHOD ||
384 m->method == OVERRIDE_METHOD)
387 /* in C++ mode we don't alias new */
388 if(for_cpp && strcmp(m->id, "new")==0)
391 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
394 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
397 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
399 out_printf(out, "}\n\n");
403 put_variable(const Variable *v, FILE *fp)
405 out_printf(fp, "\t");
406 print_type(fp, v->vtype, FALSE);
407 out_printf(fp, "%s%s;", v->id,
409 v->vtype->postfix:"");
410 if(v->scope == PROTECTED_SCOPE)
411 out_printf(fp, " /* protected */");
412 out_printf(fp, "\n");
416 put_vs_method(const Method *m)
418 if(m->method != SIGNAL_LAST_METHOD &&
419 m->method != SIGNAL_FIRST_METHOD &&
420 m->method != VIRTUAL_METHOD)
423 /* if a signal mark it as such */
424 if(m->method != VIRTUAL_METHOD)
425 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
426 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
428 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
429 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
434 put_pub_method(const Method *m)
436 if(m->scope != PUBLIC_SCOPE)
439 out_addline_infile(outh, m->line_no);
440 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
441 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
442 out_addline_outfile(outh);
446 put_signal_macro (const Method *m, gboolean gnu)
448 if(m->method != SIGNAL_LAST_METHOD &&
449 m->method != SIGNAL_FIRST_METHOD)
454 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
455 "g_signal_connect(%s(object),\"%s\","
456 "(GCallback)(func),(data))\n",
457 funcbase, m->id, macrobase, m->id);
460 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
461 "g_signal_connect_after(%s(object),\"%s\","
462 "(GCallback)(func),(data))\n",
463 funcbase, m->id, macrobase, m->id);
466 out_printf (outh, "#define %s_connect_data__%s"
467 "(object,func,data,destroy_data,flags)\t"
468 "g_signal_connect_data(%s(object),\"%s\","
469 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
470 funcbase, m->id, macrobase, m->id);
473 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
475 "%s(__extension__ ({%s *___object = (object); ___object; })),"
477 "(GCallback) __extension__ ({",
478 funcbase, m->id, macrobase, typebase, m->id);
479 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
480 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
481 out_printf (outh, "___%s; }), (data))\n", m->id);
484 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
485 "g_signal_connect_after("
486 "%s(__extension__ ({%s *___object = (object); ___object; })),"
488 "(GCallback) __extension__ ({",
489 funcbase, m->id, macrobase, typebase, m->id);
490 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
491 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
492 out_printf (outh, "___%s; }), (data))\n", m->id);
495 out_printf (outh, "#define %s_connect_data__%s"
496 "(object,func,data,destroy_data,flags)\t"
497 "g_signal_connect_data("
498 "%s(__extension__ ({%s *___object = (object); ___object; })),"
500 "(GCallback) __extension__ ({",
501 funcbase, m->id, macrobase, typebase, m->id);
502 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
503 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
504 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
509 put_signal_macros (const Class *c, gboolean gnu)
516 for (li = c->nodes; li != NULL; li = li->next) {
517 const Node *n = li->data;
518 if (n->type == METHOD_NODE)
519 put_signal_macro ((Method *)n, gnu);
524 put_local_signal_macro (const Method *m)
526 if(m->method != SIGNAL_LAST_METHOD &&
527 m->method != SIGNAL_FIRST_METHOD)
531 out_printf (out, "#define self_connect__%s(object,func,data)\t"
532 "%s_connect__%s((object),(func),(data))\n",
533 m->id, funcbase, m->id);
536 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
537 "%s_connect_after__%s((object),(func),(data))\n",
538 m->id, funcbase, m->id);
541 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
542 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
543 m->id, funcbase, m->id);
547 put_local_signal_macros (const Class *c)
554 for (li = c->nodes; li != NULL; li = li->next) {
555 const Node *n = li->data;
556 if (n->type == METHOD_NODE)
557 put_local_signal_macro ((Method *)n);
563 put_prot_method(const Method *m)
567 if(m->scope != PROTECTED_SCOPE)
570 f = outph ? outph : out;
572 out_addline_infile(f, m->line_no);
573 print_method(f, "", "\t", "", "\t", "", ";\n",
574 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
575 out_addline_outfile(f);
579 put_priv_method_prot(const Method *m)
581 if(m->method == SIGNAL_LAST_METHOD ||
582 m->method == SIGNAL_FIRST_METHOD ||
583 m->method == VIRTUAL_METHOD) {
586 "static ", "___real_", "", " ", "", ";\n",
587 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
589 /* no else, here, it might still have a private prototype, it's not
592 if((m->method == OVERRIDE_METHOD &&
595 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
597 out_addline_infile(out, m->line_no);
598 print_method(out, "static ", s, "", " ", "",
599 no_gnu?";\n":" G_GNUC_UNUSED;\n",
600 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
602 out_addline_outfile(out);
604 } else if(m->scope == PRIVATE_SCOPE ||
605 m->method == INIT_METHOD ||
606 m->method == CLASS_INIT_METHOD ||
607 m->method == CONSTRUCTOR_METHOD ||
608 m->method == DISPOSE_METHOD ||
609 m->method == FINALIZE_METHOD) {
611 out_addline_infile(out, m->line_no);
612 print_method(out, "static ", "", "", " ", "",
613 no_gnu?";\n":" G_GNUC_UNUSED;\n",
614 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
616 out_addline_outfile(out);
621 make_func_arg (const char *typename, gboolean is_class, const char *name)
628 tn = g_strconcat (typename, ":Class", NULL);
630 tn = g_strdup (typename);
632 type = node_new (TYPE_NODE,
636 node = node_new (FUNCARG_NODE,
637 "atype:steal", (Type *)type,
640 return g_list_prepend (NULL, node);
644 make_inits(Class *cl)
646 int got_class_init = FALSE;
647 int got_init = FALSE;
650 for(li=cl->nodes;li;li=g_list_next(li)) {
652 if(n->type == METHOD_NODE) {
653 Method *m = (Method *)n;
654 if(m->method == INIT_METHOD) {
656 error_print(GOB_ERROR, m->line_no, "init defined more then once");
658 } else if(m->method == CLASS_INIT_METHOD) {
660 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
661 got_class_init = TRUE;
665 if(!got_class_init) {
666 Type *type = (Type *)node_new (TYPE_NODE,
669 node = node_new (METHOD_NODE,
671 "method", CLASS_INIT_METHOD,
674 "args:steal", make_func_arg (cl->otype,
677 "unique_id", method_unique_id++,
679 cl->nodes = g_list_prepend(cl->nodes, node);
682 Type *type = (Type *)node_new (TYPE_NODE,
685 node = node_new (METHOD_NODE,
687 "method", INIT_METHOD,
690 "args:steal", make_func_arg (cl->otype,
691 FALSE /* is_class */,
693 "unique_id", method_unique_id++,
695 cl->nodes = g_list_prepend(cl->nodes, node);
700 find_method(const Class *cl, int method, const char *id)
704 for(li=cl->nodes;li;li=g_list_next(li)) {
706 if(n->type == METHOD_NODE) {
707 Method *m = (Method *)n;
708 if (m->method == method
709 && (id == NULL || strcmp(m->id, id)==0))
718 find_constructor(const Class *cl)
720 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
724 find_dispose(const Class *cl)
726 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
727 if (dispose_handler != NULL) {
728 if(strcmp(dispose_handler->otype, "G:Object") != 0)
729 error_print(GOB_ERROR, dispose_handler->line_no,
730 "dispose method override "
731 "of class other then "
733 if(g_list_length(dispose_handler->args) != 1)
734 error_print(GOB_ERROR, dispose_handler->line_no,
735 "dispose method override "
736 "with more then one "
740 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
744 find_finalize(const Class *cl)
746 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
747 if (finalize_handler != NULL) {
748 if(strcmp(finalize_handler->otype, "G:Object") != 0)
749 error_print(GOB_ERROR, finalize_handler->line_no,
750 "finalize method override "
751 "of class other then "
753 if(g_list_length(finalize_handler->args) != 1)
754 error_print(GOB_ERROR, finalize_handler->line_no,
755 "finalize method override "
756 "with more then one "
760 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
764 /* hash of method -> name of signal prototype */
765 static GHashTable *marsh = NULL;
767 /* list of methods with different signal prototypes,
768 we check this list if we can use a signal prototype of a
769 previous signal method, there are only uniques here */
770 static GList *eq_signal_methods = NULL;
772 /* compare a list of strings */
774 is_list_equal(const GList *a, const GList *b)
776 for(;a && b; a=a->next, b=b->next) {
777 if(strcmp(a->data, b->data)!=0) {
781 /* the the lists were different length */
788 find_same_type_signal(const Method *m)
791 for(li=eq_signal_methods;li;li=li->next) {
792 Method *mm = li->data;
793 if(is_list_equal(mm->gtktypes, m->gtktypes))
800 print_signal_marsal_args (const Method *m)
802 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
805 for (i = 0, li = m->gtktypes->next;
807 i++, li = li->next) {
810 if (strcmp (li->data, "UNICHAR") == 0)
811 /* hack because glib is braindamaged */
812 get_func = g_strdup ("g_value_get_uint");
813 else if (strncmp(li->data, "BOXED_", 6) == 0)
814 get_func = g_strdup ("g_value_get_boxed");
816 get_func = g_strdup_printf
817 ("g_value_get_%s", (char *)li->data);
819 gob_strdown (get_func);
820 out_printf (out, ",\n\t\t(%s) "
821 "%s (param_values + %d)",
822 get_cast (li->data, FALSE),
827 out_printf (out, ",\n\t\tdata2);\n");
832 add_signal_prots(Method *m)
838 gboolean ret_none = FALSE;
839 gboolean arglist_none = FALSE;
841 const char *unused = "";
843 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
844 unused = " G_GNUC_UNUSED";
847 if (m->method != SIGNAL_LAST_METHOD &&
848 m->method != SIGNAL_FIRST_METHOD)
852 marsh = g_hash_table_new(NULL, NULL);
854 g_assert (m->gtktypes->next != NULL);
856 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
857 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
859 if (ret_none && arglist_none)
862 /* if we already did a signal prototype just use that */
863 mm = find_same_type_signal (m);
865 s = g_hash_table_lookup (marsh, mm);
866 g_hash_table_insert (marsh, m, s);
873 retcast = get_cast (m->gtktypes->data, FALSE);
875 s = g_strdup_printf("Sig%d", sig++);
877 g_hash_table_insert(marsh, m, s);
878 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
880 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
881 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
882 get_cast(m->gtktypes->data, FALSE), s, typebase);
884 if ( ! arglist_none) {
885 for (li = m->gtktypes->next; li != NULL; li = li->next)
886 out_printf (out, "%s, ", get_cast (li->data, FALSE));
888 out_printf (out, "gpointer);\n");
890 out_printf (out, "\nstatic void\n"
891 "___marshal_%s (GClosure *closure,\n"
892 "\tGValue *return_value%s,\n"
893 "\tguint n_param_values,\n"
894 "\tconst GValue *param_values,\n"
895 "\tgpointer invocation_hint%s,\n"
896 "\tgpointer marshal_data)\n"
903 out_printf (out, "\t%s v_return;\n", retcast);
905 out_printf (out, "\tregister ___%s callback;\n"
906 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
907 "\tregister gpointer data1, data2;\n\n",
910 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
911 arglist_none ? 1 : g_list_length (m->gtktypes));
914 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
915 "\t\tdata1 = closure->data;\n"
916 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
918 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
919 "\t\tdata2 = closure->data;\n"
922 out_printf (out, "\tcallback = (___%s) "
923 "(marshal_data != NULL ? marshal_data : cc->callback);"
927 out_printf (out, "\tcallback ((%s *)data1", typebase);
929 out_printf (out, "\tv_return = callback ((%s *)data1",
933 print_signal_marsal_args (m);
936 /* FIXME: This code is so fucking ugly it hurts */
937 gboolean take_ownership =
938 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
939 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
943 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
944 /* hack because glib is braindamaged */
945 set_func = g_strdup ("g_value_set_uint");
947 set_func = g_strdup_printf ("g_value_%s_%s",
950 (char *)m->gtktypes->data);
951 gob_strdown (set_func);
953 out_printf (out, "\n\t%s (return_value, v_return);\n",
958 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
960 out_printf (out, "\n\treturn_value = NULL;\n");
961 out_printf (out, "\tinvocation_hint = NULL;\n");
964 out_printf (out, "}\n\n");
968 interface_type(const char *if_name)
970 char *rawtype = remove_sep(if_name);
971 char *end = "", *typename;
975 * EEEK! evil, we should have some sort of option
976 * to force this for arbitrary interfaces, since
977 * some are Class and some are Iface. Glib is shite
981 if (strcmp (rawtype, "GtkEditable") == 0
982 || strcmp (rawtype, "GTypePlugin") == 0)
986 /* We'll assume Iface is the standard ending */
990 /* GTK3 doesn't need Iface end */
994 typename = g_strconcat(rawtype, end, (char *)NULL);
1001 define_parent_interface_refs(Class *c)
1008 out_printf(out, "\n/* parent class interface implementations */\n");
1009 for (li = c->interfaces; li != NULL; li = li->next) {
1010 char *name = replace_sep(li->data, '_');
1011 char *type = interface_type(li->data);
1013 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1024 out_printf(out, "\n");
1026 out_printf(out, "enum {\n");
1027 for(li=c->nodes;li;li=g_list_next(li)) {
1029 if(n->type == METHOD_NODE) {
1030 Method *m = (Method *)n;
1031 if(m->method == SIGNAL_LAST_METHOD ||
1032 m->method == SIGNAL_FIRST_METHOD) {
1033 char *s = g_strdup(m->id);
1035 out_printf(out, "\t%s_SIGNAL,\n", s);
1040 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1042 if (set_properties > 0 ||
1043 get_properties > 0) {
1044 out_printf(out, "enum {\n\tPROP_0");
1045 for(li=c->nodes;li;li=g_list_next(li)) {
1047 if (n->type == PROPERTY_NODE) {
1048 Property *p = (Property *)n;
1049 char *s = g_strdup (p->name);
1051 out_printf (out, ",\n\tPROP_%s", s);
1053 } else if (n->type == ARGUMENT_NODE) {
1054 Argument *a = (Argument *)n;
1055 char *s = g_strdup(a->name);
1057 out_printf(out, ",\n\tPROP_%s", s);
1061 out_printf(out, "\n};\n\n");
1066 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1068 out_printf(out, "/* pointer to the class of our parent */\n");
1069 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1070 define_parent_interface_refs(c);
1071 out_printf(out, "\n");
1075 add_interface_methods (Class *c, const char *interface)
1078 gboolean added_line = FALSE;
1080 for (li = c->nodes; li != NULL; li = li->next) {
1082 Method *m = (Method *)n;
1083 if (n->type != METHOD_NODE ||
1084 m->method == OVERRIDE_METHOD ||
1085 m->interface == NULL ||
1086 strcmp (m->interface, interface) != 0)
1089 if (m->line_no > 0) {
1090 out_addline_infile (out, m->line_no);
1092 } else if (m->line_no == 0 &&
1094 out_addline_outfile (out);
1097 out_printf (out, "\tiface->%s = self_%s;\n",
1101 out_addline_outfile (out);
1105 add_interface_inits(Class *c)
1109 if (c->interfaces == NULL)
1112 out_printf(out, "\n");
1114 for (li = c->interfaces; li != NULL; li = li->next) {
1115 char *name = replace_sep(li->data, '_');
1116 char *type = interface_type(li->data);
1118 out_printf(out, "static void\n"
1119 "___%s_init (%s *iface)\n"
1122 add_interface_methods(c, li->data);
1124 out_printf(out, "\t%s_parent_iface\n", name);
1125 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1126 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1135 add_interface_infos(Class *c, gboolean static_storage)
1139 for (li = c->interfaces; li; li = li->next) {
1140 char *name = replace_sep(li->data, '_');
1141 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1142 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1146 static_storage ? "static " : "",
1151 out_printf(out, "\n");
1155 define_add_interfaces(Class *c)
1162 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1163 add_interface_infos(c, TRUE);
1165 for (li = c->interfaces; li; li = li->next) {
1166 char *type = make_pre_macro(li->data, "TYPE");
1167 char *name = replace_sep(li->data, '_');
1169 out_printf(out, "\tg_type_add_interface_static\n"
1180 out_printf(out, "}\n\n");
1184 define_dynamic_add_interfaces(Class *c)
1191 out_printf(out, "static void ___add_interfaces"
1192 "(GTypeModule *type_module, GType type)\n"
1194 add_interface_infos(c, FALSE);
1197 * Hack to work around bug in g_type_module_add_interface,
1198 * which will fail to add an interface to types that derive
1199 * from something that also implements the same interface.
1201 * The actual GType system does not have any such problem,
1202 * and the GTypeModule implementation details relied upon
1203 * here have not changed once since the feature was first
1204 * implemented almost 20 years ago.
1206 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1207 "\t\tgboolean loaded;\n"
1208 "\t\tGType instance_type;\n"
1209 "\t\tGType interface_type;\n"
1210 "\t\tGInterfaceInfo info;\n"
1213 for (li = c->interfaces; li; li = li->next) {
1214 char *type = make_pre_macro(li->data, "TYPE");
1215 char *name = replace_sep(li->data, '_');
1217 out_printf(out, "\n"
1218 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1219 "\tmodinfo->loaded = TRUE;\n"
1220 "\tmodinfo->instance_type = type;\n"
1221 "\tmodinfo->interface_type = %s;\n"
1222 "\tmodinfo->info = %s_info;\n"
1223 "\tg_type_add_interface_dynamic\n"
1224 "\t\t( modinfo->instance_type\n"
1225 "\t\t, modinfo->interface_type\n"
1226 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1228 "\ttype_module->interface_infos = g_slist_prepend\n"
1229 "\t\t( type_module->interface_infos\n"
1238 out_printf(out, "}\n\n");
1241 static void define_add_privates(Class *c)
1243 const char *addprivate = c->dynamic
1244 ? "G_ADD_PRIVATE_DYNAMIC"
1250 out_printf(out, "#ifdef %s\n"
1251 "#define ___add_privates() %s(%s)\n"
1253 "#define ___add_privates()\n"
1255 addprivate, addprivate, typebase);
1258 static void add_type_info(void)
1260 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1261 "\t\tsizeof (%sClass),\n"
1262 "\t\t(GBaseInitFunc) NULL,\n"
1263 "\t\t(GBaseFinalizeFunc) NULL,\n"
1264 "\t\t(GClassInitFunc) %s_class_init,\n"
1265 "\t\t(GClassFinalizeFunc) NULL,\n"
1266 "\t\tNULL /* class_data */,\n"
1267 "\t\tsizeof (%s),\n"
1268 "\t\t%d /* n_preallocs */,\n"
1269 "\t\t(GInstanceInitFunc) %s_init,\n"
1272 typebase, funcbase, typebase, prealloc, funcbase);
1278 Class *c = (Class *)class;
1280 define_add_interfaces(c);
1281 define_add_privates(c);
1283 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1284 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1285 "\t(GTypeFlags)%s,\n",
1286 typebase, funcbase, pmacrotype,
1287 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1290 out_printf(out, "\t___add_privates();\n");
1293 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1295 /* Fallback for GLib < 2.4 */
1296 out_printf(out, ");\n\n"
1298 "GType %s_get_type(void)\n"
1300 "\tstatic GType type = 0;\n",
1305 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1306 "\t\ttype = g_type_register_static\n"
1310 "\t\t\t, (GTypeFlags)%s\n"
1312 pmacrotype, typebase,
1313 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1316 out_printf(out, "\t\t___add_interfaces(type);\n");
1318 out_printf(out, "\t}\n\n"
1325 add_dynamic_get_type(void)
1327 Class *c = (Class *)class;
1329 define_dynamic_add_interfaces(c);
1330 define_add_privates(c);
1333 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1334 * some reason it defines an xxx_register_type function with internal
1335 * linkage. This is kind of weird so we have to work around that.
1337 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1338 "static void %s_class_finalize(%sClass *c) { }\n\n"
1339 "#define %s_register_type ___register_type\n",
1340 funcbase, typebase, funcbase);
1342 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1343 "\t(GTypeFlags)%s,\n",
1344 typebase, funcbase, pmacrotype,
1345 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1348 out_printf(out, "\t___add_privates();\n");
1350 if (c->interfaces) {
1351 out_printf(out, "\t___add_interfaces"
1352 "(type_module, %s_type_id);\n", funcbase);
1355 out_printf(out, ");\n"
1356 "#undef %s_register_type\n\n"
1357 "void %s_register_type(GTypeModule *type_module)\n"
1359 "\t___register_type(type_module);\n"
1361 funcbase, funcbase);
1363 /* Fallback for GLib < 2.14 */
1364 out_printf(out, "#else\n\n"
1365 "static GType %s_type_id;\n\n"
1366 "GType %s_get_type(void)\n"
1368 "\treturn %s_type_id;\n"
1370 funcbase, funcbase, funcbase);
1372 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1378 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1379 "\t\t( type_module\n"
1383 "\t\t, (GTypeFlags)%s\n"
1385 funcbase, pmacrotype, typebase,
1386 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1388 if (c->interfaces) {
1389 out_printf(out, "\t___add_interfaces"
1390 "(type_module, %s_type_id);\n",
1394 out_printf(out, "}\n\n"
1399 add_bonobo_object_get_type(void)
1401 Class *c = (Class *)class;
1403 define_add_interfaces(c);
1405 out_printf (out, "GType %s_get_type(void)\n"
1407 "\tstatic GType type = 0;\n",
1412 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1413 "\t\ttype = bonobo_type_unique\n"
1414 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1415 "\t\t\t, POA_%s__init, NULL\n"
1416 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1420 c->bonobo_object_class, typebase, typebase);
1422 if (((Class *)class)->interfaces)
1423 out_printf(out, "\t\t___add_interfaces(type);\n");
1425 out_printf(out, "\t}\n\n"
1431 add_overrides(Class *c, const char *oname,
1432 gboolean did_base_obj)
1438 done = g_hash_table_new (g_str_hash, g_str_equal);
1440 s = g_strdup ("GObject");
1441 g_hash_table_insert (done, s, s);
1443 for (li = c->nodes; li != NULL; li = li->next) {
1446 Method *m = (Method *)n;
1447 if(n->type != METHOD_NODE ||
1448 m->method != OVERRIDE_METHOD)
1451 s = remove_sep(m->otype);
1453 if(g_hash_table_lookup(done, s)) {
1457 g_hash_table_insert(done, s, s);
1459 f = replace_sep(m->otype, '_');
1462 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1467 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1468 g_hash_table_destroy (done);
1472 make_run_signal_flags(Method *m, gboolean last)
1487 gs = g_string_new(NULL);
1490 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1492 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1494 if(m->scope == PUBLIC_SCOPE)
1495 g_string_append(gs, " | G_SIGNAL_ACTION");
1497 for(li = m->flags; li; li = li->next) {
1498 char *flag = li->data;
1500 for(i=0;flags[i];i++) {
1501 if(strcmp(flags[i], flag)==0)
1504 /* if we haven't found it in our list */
1506 error_printf(GOB_WARN, m->line_no,
1507 "Unknown flag '%s' used, "
1508 "perhaps it was misspelled",
1511 g_string_append_printf(gs, " | G_SIGNAL_%s", flag);
1515 char *ret = gs->str;
1516 g_string_free(gs, FALSE);
1523 add_signals(Class *c)
1527 out_printf(out, "\n");
1528 for(li=c->nodes;li;li=g_list_next(li)) {
1530 char *mar, *sig, *flags;
1531 gboolean is_none, last = FALSE;
1532 Method *m = (Method *)n;
1534 if(n->type != METHOD_NODE ||
1535 (m->method != SIGNAL_FIRST_METHOD &&
1536 m->method != SIGNAL_LAST_METHOD))
1539 if(m->method == SIGNAL_FIRST_METHOD)
1544 if(g_hash_table_lookup(marsh, m))
1545 mar = g_strconcat("___marshal_",
1546 (char *)g_hash_table_lookup(marsh, m),
1549 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1551 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1553 sig = g_strdup (m->id);
1555 flags = make_run_signal_flags (m, last);
1556 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1557 "\t\tg_signal_new (%s,\n"
1558 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1559 "\t\t\t(GSignalFlags)(%s),\n"
1560 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1561 "\t\t\tNULL, NULL,\n"
1563 "\t\t\tG_TYPE_%s, %d",
1564 sig, m->signal_name /*m->id* if not given signal_name*/,
1566 typebase, m->id, mar,
1567 (char *)m->gtktypes->data,
1568 is_none ? 0 : g_list_length(m->gtktypes->next));
1576 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1577 char *str = l->data;
1578 if (strncmp (str, "BOXED_", 6) == 0)
1579 t = g_strdup (&(str[6]));
1581 t = g_strconcat ("G_TYPE_", str, NULL);
1582 out_printf (out, ",\n\t\t\t%s", t);
1587 out_printf(out, ");\n");
1589 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1592 out_printf(out, "\tif ___GOB_UNLIKELY(");
1593 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1594 out_printf(out, "sizeof(");
1595 print_type(out, m->mtype, FALSE);
1596 out_printf(out, "%s",
1598 m->mtype->postfix : "");
1599 out_printf(out, ") != sizeof(%s) || ",
1600 get_cast(m->gtktypes->data, FALSE));
1603 for(al = m->args->next, gl = m->gtktypes->next;
1604 al != NULL && gl != NULL;
1605 al = al->next, gl = gl->next) {
1606 FuncArg *arg = al->data;
1607 char *gtkarg = gl->data;
1609 out_printf(out, "sizeof(");
1610 print_type(out, arg->atype, FALSE);
1611 out_printf(out, "%s",
1612 arg->atype->postfix ?
1613 arg->atype->postfix : "");
1614 out_printf(out, ") != sizeof(%s) || ",
1615 get_cast(gtkarg, FALSE));
1619 "parent_class == NULL /* avoid warning */");
1621 out_printf(out, ") {\n"
1622 "\t\tg_error(\"%s line %d: Type mismatch "
1623 "of \\\"%s\\\" signal signature\");\n"
1625 filename, m->line_no, m->id);
1632 set_def_handlers(Class *c, const char *oname)
1635 gboolean set_line = FALSE;
1637 out_printf(out, "\n");
1638 for(li = c->nodes; li; li = g_list_next(li)) {
1640 Method *m = (Method *)n;
1642 if(n->type != METHOD_NODE ||
1643 (m->method != SIGNAL_FIRST_METHOD &&
1644 m->method != SIGNAL_LAST_METHOD &&
1645 m->method != VIRTUAL_METHOD &&
1646 m->method != OVERRIDE_METHOD))
1649 if(m->line_no > 0 && m->cbuf) {
1650 out_addline_infile(out, m->line_no);
1652 } else if(set_line) {
1653 out_addline_outfile(out);
1658 if (m->method == OVERRIDE_METHOD) {
1660 s = replace_sep (m->otype, '_');
1664 dispose_handler != NULL &&
1665 strcmp (m->id, "dispose") == 0)
1666 out_printf (out, "\tg_object_class->dispose "
1668 else if (need_finalize &&
1670 strcmp(m->id, "finalize") == 0)
1672 "\tg_object_class->finalize = ___finalize;\n");
1673 else if (m->cbuf != NULL)
1675 "\t%s_class->%s = ___%x_%s_%s;\n",
1676 s, m->id, (guint)m->unique_id,
1679 out_printf(out, "\t%s_class->%s = NULL;\n",
1683 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1687 out_printf(out, "\t%s->%s = NULL;\n",
1692 out_addline_outfile(out);
1696 make_argument (Argument *a)
1701 char *argflags[] = {
1709 flags = g_string_new ("(GParamFlags)(");
1711 if(a->get && a->set)
1712 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1714 g_string_append (flags, "G_PARAM_READABLE");
1716 g_string_append (flags, "G_PARAM_WRITABLE");
1718 g_assert(a->get || a->set);
1720 for (l = a->flags; l != NULL; l = l->next) {
1721 char *flag = l->data;
1723 if(strcmp (flag, "READABLE") == 0 ||
1724 strcmp (flag, "WRITABLE") == 0) {
1725 error_print(GOB_WARN, a->line_no,
1727 "WRITABLE argument flags are "
1728 "set automatically");
1731 for(i = 0; argflags[i]; i++) {
1732 if(strcmp(argflags[i], flag)==0)
1735 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1738 g_string_append (flags, ")");
1740 s = g_strdup(a->name);
1742 if (!strcmp (a->gtktype, "ENUM"))
1743 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1744 "\t\tG_TYPE_ENUM, 0,\n"
1746 a->name, flags->str);
1747 if (!strcmp (a->gtktype, "FLAGS"))
1748 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1749 "\t\tG_TYPE_FLAGS, 0,\n"
1751 a->name, flags->str);
1752 else if (!strcmp (a->gtktype, "OBJECT"))
1753 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1754 "\t\tG_TYPE_OBJECT,\n"
1756 a->name, flags->str);
1757 else if (!strcmp (a->gtktype, "STRING"))
1758 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1761 a->name, flags->str);
1762 else if (!strcmp (a->gtktype, "INT"))
1763 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1764 "\t\tG_MININT, G_MAXINT,\n"
1767 a->name, flags->str);
1768 else if (!strcmp (a->gtktype, "UINT"))
1769 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1770 "\t\t0, G_MAXUINT,\n"
1773 a->name, flags->str);
1774 else if (!strcmp (a->gtktype, "INT"))
1775 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1776 "\t\tG_MININT, G_MAXINT,\n"
1779 a->name, flags->str);
1780 else if (!strcmp (a->gtktype, "CHAR"))
1781 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1785 a->name, flags->str);
1786 else if (!strcmp (a->gtktype, "UCHAR"))
1787 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1791 a->name, flags->str);
1792 else if (!strcmp (a->gtktype, "BOOL") ||
1793 !strcmp (a->gtktype, "BOOLEAN"))
1794 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1797 a->name, flags->str);
1798 else if (!strcmp (a->gtktype, "LONG"))
1799 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1800 "\t\tG_MINLONG, G_MAXLONG,\n"
1803 a->name, flags->str);
1804 else if (!strcmp (a->gtktype, "ULONG"))
1805 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1806 "\t\t0, G_MAXULONG,\n"
1809 a->name, flags->str);
1810 else if (!strcmp (a->gtktype, "INT64"))
1811 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1812 "\t\tG_MININT64, G_MAXINT64,\n"
1815 a->name, flags->str);
1816 else if (!strcmp (a->gtktype, "UINT64"))
1817 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1818 "\t\t0, G_MAXUINT64,\n"
1821 a->name, flags->str);
1822 else if (!strcmp (a->gtktype, "FLOAT"))
1823 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1824 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1827 a->name, flags->str);
1828 else if (!strcmp (a->gtktype, "DOUBLE"))
1829 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1830 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1833 a->name, flags->str);
1834 else if (!strcmp (a->gtktype, "POINTER"))
1835 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1837 a->name, flags->str);
1839 error_printf (GOB_ERROR, a->line_no,
1840 "%s type is not supported for arguments, try using properties",
1843 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1844 "\t\tPROP_%s, param_spec);\n", s);
1848 g_string_free(flags, TRUE);
1851 #define value_for_print(str, alt) (str != NULL ? str : alt)
1854 make_property (Property *p)
1858 if (p->get == NULL && p->set == NULL) {
1859 error_print (GOB_ERROR, p->line_no,
1860 "Property has no getter nor setter");
1864 if (p->flags != NULL)
1865 error_print (GOB_WARN, p->line_no,
1866 "Overridden property, flags ignored");
1867 if (p->nick != NULL)
1868 error_print (GOB_WARN, p->line_no,
1869 "Overridden property, nick ignored");
1870 if (p->blurb != NULL)
1871 error_print (GOB_WARN, p->line_no,
1872 "Overridden property, blurb ignored");
1873 if (p->minimum != NULL)
1874 error_print (GOB_WARN, p->line_no,
1875 "Overridden property, minimum ignored");
1876 if (p->maximum != NULL)
1877 error_print (GOB_WARN, p->line_no,
1878 "Overridden property, maximum ignored");
1879 if (p->default_value != NULL)
1880 error_print (GOB_WARN, p->line_no,
1881 "Overridden property, default_value ignored");
1883 s = g_strdup (p->name);
1885 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1887 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1892 char *argflags[] = {
1900 flags = g_string_new ("(GParamFlags)(");
1902 if (p->get != NULL && p->set != NULL)
1903 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1904 else if (p->get != NULL)
1905 g_string_append (flags, "G_PARAM_READABLE");
1907 g_string_append (flags, "G_PARAM_WRITABLE");
1910 for (l = p->flags; l != NULL; l = l->next) {
1911 char *flag = l->data;
1913 if(strcmp (flag, "READABLE") == 0 ||
1914 strcmp (flag, "WRITABLE") == 0) {
1915 error_print(GOB_WARN, p->line_no,
1917 "WRITABLE argument flags are "
1918 "set automatically");
1921 for(i = 0; argflags[i]; i++) {
1922 if(strcmp(argflags[i], flag)==0)
1925 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1928 g_string_append (flags, ")");
1930 if (strcmp (p->gtktype, "CHAR") == 0) {
1931 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1932 "\t\t(\"%s\" /* name */,\n"
1933 "\t\t %s /* nick */,\n"
1934 "\t\t %s /* blurb */,\n"
1935 "\t\t %s /* minimum */,\n"
1936 "\t\t %s /* maximum */,\n"
1937 "\t\t %s /* default_value */,\n"
1939 value_for_print (p->canonical_name, p->name),
1940 value_for_print (p->nick, "NULL"),
1941 value_for_print (p->blurb, "NULL"),
1942 value_for_print (p->minimum, "-128"),
1943 value_for_print (p->maximum, "127"),
1944 value_for_print (p->default_value, "0"),
1946 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1947 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1948 "\t\t(\"%s\" /* name */,\n"
1949 "\t\t %s /* nick */,\n"
1950 "\t\t %s /* blurb */,\n"
1951 "\t\t %s /* minimum */,\n"
1952 "\t\t %s /* maximum */,\n"
1953 "\t\t %s /* default_value */,\n"
1955 value_for_print (p->canonical_name, p->name),
1956 value_for_print (p->nick, "NULL"),
1957 value_for_print (p->blurb, "NULL"),
1958 value_for_print (p->minimum, "0"),
1959 value_for_print (p->maximum, "0xFF"),
1960 value_for_print (p->default_value, "0"),
1962 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1963 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1964 "\t\t(\"%s\" /* name */,\n"
1965 "\t\t %s /* nick */,\n"
1966 "\t\t %s /* blurb */,\n"
1967 "\t\t %s /* default_value */,\n"
1969 value_for_print (p->canonical_name, p->name),
1970 value_for_print (p->nick, "NULL"),
1971 value_for_print (p->blurb, "NULL"),
1972 value_for_print (p->default_value, "FALSE"),
1974 } else if (strcmp (p->gtktype, "INT") == 0) {
1975 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1976 "\t\t(\"%s\" /* name */,\n"
1977 "\t\t %s /* nick */,\n"
1978 "\t\t %s /* blurb */,\n"
1979 "\t\t %s /* minimum */,\n"
1980 "\t\t %s /* maximum */,\n"
1981 "\t\t %s /* default_value */,\n"
1983 value_for_print (p->canonical_name, p->name),
1984 value_for_print (p->nick, "NULL"),
1985 value_for_print (p->blurb, "NULL"),
1986 value_for_print (p->minimum, "G_MININT"),
1987 value_for_print (p->maximum, "G_MAXINT"),
1988 value_for_print (p->default_value, "0"),
1990 } else if (strcmp (p->gtktype, "UINT") == 0) {
1991 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1992 "\t\t(\"%s\" /* name */,\n"
1993 "\t\t %s /* nick */,\n"
1994 "\t\t %s /* blurb */,\n"
1995 "\t\t %s /* minimum */,\n"
1996 "\t\t %s /* maximum */,\n"
1997 "\t\t %s /* default_value */,\n"
1999 value_for_print (p->canonical_name, p->name),
2000 value_for_print (p->nick, "NULL"),
2001 value_for_print (p->blurb, "NULL"),
2002 value_for_print (p->minimum, "0"),
2003 value_for_print (p->maximum, "G_MAXUINT"),
2004 value_for_print (p->default_value, "0"),
2006 } else if (strcmp (p->gtktype, "LONG") == 0) {
2007 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2008 "\t\t(\"%s\" /* name */,\n"
2009 "\t\t %s /* nick */,\n"
2010 "\t\t %s /* blurb */,\n"
2011 "\t\t %s /* minimum */,\n"
2012 "\t\t %s /* maximum */,\n"
2013 "\t\t %s /* default_value */,\n"
2015 value_for_print (p->canonical_name, p->name),
2016 value_for_print (p->nick, "NULL"),
2017 value_for_print (p->blurb, "NULL"),
2018 value_for_print (p->minimum, "G_MINLONG"),
2019 value_for_print (p->maximum, "G_MAXLONG"),
2020 value_for_print (p->default_value, "0"),
2022 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2023 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2024 "\t\t(\"%s\" /* name */,\n"
2025 "\t\t %s /* nick */,\n"
2026 "\t\t %s /* blurb */,\n"
2027 "\t\t %s /* minimum */,\n"
2028 "\t\t %s /* maximum */,\n"
2029 "\t\t %s /* default_value */,\n"
2031 value_for_print (p->canonical_name, p->name),
2032 value_for_print (p->nick, "NULL"),
2033 value_for_print (p->blurb, "NULL"),
2034 value_for_print (p->minimum, "0"),
2035 value_for_print (p->maximum, "G_MAXULONG"),
2036 value_for_print (p->default_value, "0"),
2038 } else if (strcmp (p->gtktype, "INT64") == 0) {
2039 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2040 "\t\t(\"%s\" /* name */,\n"
2041 "\t\t %s /* nick */,\n"
2042 "\t\t %s /* blurb */,\n"
2043 "\t\t %s /* minimum */,\n"
2044 "\t\t %s /* maximum */,\n"
2045 "\t\t %s /* default_value */,\n"
2047 value_for_print (p->canonical_name, p->name),
2048 value_for_print (p->nick, "NULL"),
2049 value_for_print (p->blurb, "NULL"),
2050 value_for_print (p->minimum, "G_MININT64"),
2051 value_for_print (p->maximum, "G_MAXINT64"),
2052 value_for_print (p->default_value, "0"),
2054 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2055 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2056 "\t\t(\"%s\" /* name */,\n"
2057 "\t\t %s /* nick */,\n"
2058 "\t\t %s /* blurb */,\n"
2059 "\t\t %s /* minimum */,\n"
2060 "\t\t %s /* maximum */,\n"
2061 "\t\t %s /* default_value */,\n"
2063 value_for_print (p->canonical_name, p->name),
2064 value_for_print (p->nick, "NULL"),
2065 value_for_print (p->blurb, "NULL"),
2066 value_for_print (p->minimum, "0"),
2067 value_for_print (p->maximum, "G_MAXUINT64"),
2068 value_for_print (p->default_value, "0"),
2070 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2071 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2072 "\t\t(\"%s\" /* name */,\n"
2073 "\t\t %s /* nick */,\n"
2074 "\t\t %s /* blurb */,\n"
2075 "\t\t %s /* default_value */,\n"
2077 value_for_print (p->canonical_name, p->name),
2078 value_for_print (p->nick, "NULL"),
2079 value_for_print (p->blurb, "NULL"),
2080 value_for_print (p->default_value, "0"),
2082 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2083 char *type = make_me_type (p->extra_gtktype,
2085 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2086 "\t\t(\"%s\" /* name */,\n"
2087 "\t\t %s /* nick */,\n"
2088 "\t\t %s /* blurb */,\n"
2089 "\t\t %s /* enum_type */,\n"
2090 "\t\t %s /* default_value */,\n"
2092 value_for_print (p->canonical_name, p->name),
2093 value_for_print (p->nick, "NULL"),
2094 value_for_print (p->blurb, "NULL"),
2096 value_for_print (p->default_value, "0"),
2099 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2100 char *type = make_me_type (p->extra_gtktype,
2102 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2103 "\t\t(\"%s\" /* name */,\n"
2104 "\t\t %s /* nick */,\n"
2105 "\t\t %s /* blurb */,\n"
2106 "\t\t %s /* flags_type */,\n"
2107 "\t\t %s /* default_value */,\n"
2109 value_for_print (p->canonical_name, p->name),
2110 value_for_print (p->nick, "NULL"),
2111 value_for_print (p->blurb, "NULL"),
2113 value_for_print (p->default_value, "0"),
2116 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2117 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2118 "\t\t(\"%s\" /* name */,\n"
2119 "\t\t %s /* nick */,\n"
2120 "\t\t %s /* blurb */,\n"
2121 "\t\t %s /* minimum */,\n"
2122 "\t\t %s /* maximum */,\n"
2123 "\t\t %s /* default_value */,\n"
2125 value_for_print (p->canonical_name, p->name),
2126 value_for_print (p->nick, "NULL"),
2127 value_for_print (p->blurb, "NULL"),
2128 value_for_print (p->minimum, "-G_MAXFLOAT"),
2129 value_for_print (p->maximum, "G_MAXFLOAT"),
2130 value_for_print (p->default_value, "0.0"),
2132 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2133 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2134 "\t\t(\"%s\" /* name */,\n"
2135 "\t\t %s /* nick */,\n"
2136 "\t\t %s /* blurb */,\n"
2137 "\t\t %s /* minimum */,\n"
2138 "\t\t %s /* maximum */,\n"
2139 "\t\t %s /* default_value */,\n"
2141 value_for_print (p->canonical_name, p->name),
2142 value_for_print (p->nick, "NULL"),
2143 value_for_print (p->blurb, "NULL"),
2144 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2145 value_for_print (p->maximum, "G_MAXDOUBLE"),
2146 value_for_print (p->default_value, "0.0"),
2148 } else if (strcmp (p->gtktype, "STRING") == 0) {
2149 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2150 "\t\t(\"%s\" /* name */,\n"
2151 "\t\t %s /* nick */,\n"
2152 "\t\t %s /* blurb */,\n"
2153 "\t\t %s /* default_value */,\n"
2155 value_for_print (p->canonical_name, p->name),
2156 value_for_print (p->nick, "NULL"),
2157 value_for_print (p->blurb, "NULL"),
2158 value_for_print (p->default_value, "NULL"),
2160 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2161 char *type = make_me_type (p->extra_gtktype,
2163 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2164 "\t\t(\"%s\" /* name */,\n"
2165 "\t\t %s /* nick */,\n"
2166 "\t\t %s /* blurb */,\n"
2167 "\t\t %s /* param_type */,\n"
2169 value_for_print (p->canonical_name, p->name),
2170 value_for_print (p->nick, "NULL"),
2171 value_for_print (p->blurb, "NULL"),
2175 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2176 char *type = make_me_type (p->extra_gtktype,
2178 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2179 "\t\t(\"%s\" /* name */,\n"
2180 "\t\t %s /* nick */,\n"
2181 "\t\t %s /* blurb */,\n"
2182 "\t\t %s /* boxed_type */,\n"
2184 value_for_print (p->canonical_name, p->name),
2185 value_for_print (p->nick, "NULL"),
2186 value_for_print (p->blurb, "NULL"),
2190 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2191 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2192 "\t\t(\"%s\" /* name */,\n"
2193 "\t\t %s /* nick */,\n"
2194 "\t\t %s /* blurb */,\n"
2196 value_for_print (p->canonical_name, p->name),
2197 value_for_print (p->nick, "NULL"),
2198 value_for_print (p->blurb, "NULL"),
2200 /* FIXME: VALUE_ARRAY */
2201 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2202 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2203 "\t\t(\"%s\" /* name */,\n"
2204 "\t\t %s /* nick */,\n"
2205 "\t\t %s /* blurb */,\n"
2207 value_for_print (p->canonical_name, p->name),
2208 value_for_print (p->nick, "NULL"),
2209 value_for_print (p->blurb, "NULL"),
2211 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2212 char *type = make_me_type (p->extra_gtktype,
2214 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2215 "\t\t(\"%s\" /* name */,\n"
2216 "\t\t %s /* nick */,\n"
2217 "\t\t %s /* blurb */,\n"
2218 "\t\t %s /* object_type */,\n"
2220 value_for_print (p->canonical_name, p->name),
2221 value_for_print (p->nick, "NULL"),
2222 value_for_print (p->blurb, "NULL"),
2227 error_printf (GOB_ERROR, p->line_no,
2228 "%s type is not supported by properties",
2232 s = g_strdup (p->name);
2234 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2236 "\t\tparam_spec);\n", s);
2239 g_string_free (flags, TRUE);
2244 make_arguments(Class *c)
2247 if (get_properties > 0)
2248 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2249 if (set_properties > 0)
2250 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2251 out_printf (out, " {\n");
2252 for (li = c->nodes; li != NULL; li = li->next) {
2254 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2255 || n->type == ARGUMENT_NODE) {
2256 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2261 for (li = c->nodes; li != NULL; li = li->next) {
2263 if (n->type == PROPERTY_NODE)
2264 make_property ((Property *)n);
2265 else if (n->type == ARGUMENT_NODE)
2266 make_argument ((Argument *)n);
2268 out_printf(out, " }\n");
2272 print_initializer(Method *m, Variable *v)
2279 if(v->initializer == NULL)
2282 if(v->scope == PRIVATE_SCOPE)
2283 root = g_strconcat(((FuncArg *)m->args->data)->name,
2286 root = g_strdup(((FuncArg *)m->args->data)->name);
2288 if(v->initializer_line > 0)
2289 out_addline_infile(out, v->initializer_line);
2291 if (v->initializer_simple)
2292 out_printf(out, "\t%s->%s = %s;\n",
2293 root, v->id, v->initializer);
2294 else if (strcmp(v->id, "_glade_xml") == 0)
2295 /* This is OK, this v->initializer string is set internally
2296 and it will eat exactly one string! */
2297 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2299 out_printf(out, "%s", v->initializer);
2301 if(v->initializer_line > 0)
2302 out_addline_outfile(out);
2308 print_glade_widget(Method *m, Variable *v)
2313 if(!v->glade_widget)
2316 if(v->scope == PRIVATE_SCOPE)
2317 root = g_strconcat(((FuncArg *)m->args->data)->name,
2320 root = g_strdup(((FuncArg *)m->args->data)->name);
2322 cast = get_type(v->vtype, FALSE);
2323 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2324 root, v->id, cast, root, v->id);
2330 print_destructor (Variable *v)
2334 if(v->destructor == NULL)
2337 if(v->scope == PRIVATE_SCOPE)
2338 root = "self->_priv";
2342 if(v->destructor_simple) {
2343 if(v->destructor_line > 0)
2344 out_addline_infile(out, v->destructor_line);
2347 out_printf(out, "\tif(%s->%s) { "
2348 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2349 "%s->%s = NULL; }\n",
2350 root, v->id, v->destructor, root, v->id,
2353 out_printf(out, "\tif(%s->%s) { "
2354 "%s ((gpointer) %s->%s); "
2355 "%s->%s = NULL; }\n",
2356 root, v->id, v->destructor, root, v->id,
2360 if(v->destructor_line > 0)
2361 out_addline_outfile(out);
2363 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2364 out_printf(out, "#define VAR %s\n", v->id);
2365 out_printf(out, "\t{\n");
2366 if(v->destructor_line > 0)
2367 out_addline_infile(out, v->destructor_line);
2369 out_printf(out, "\t%s}\n", v->destructor);
2371 if(v->destructor_line > 0)
2372 out_addline_outfile(out);
2373 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2375 out_printf(out, "#undef VAR\n");
2376 out_printf(out, "#undef %s\n", v->id);
2381 add_constructor (Class *c)
2383 out_printf(out, "\nstatic GObject *\n"
2384 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2387 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2390 out_printf(out, "\tGObject *obj_self;\n");
2391 out_printf(out, "\t%s *self;\n", typebase);
2393 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2394 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2396 if (user_constructor->line_no > 0)
2397 out_addline_infile (out, user_constructor->line_no);
2398 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2399 if (user_constructor->line_no > 0)
2400 out_addline_outfile (out);
2402 out_printf(out, "\treturn obj_self;\n");
2403 out_printf(out, "}\n"
2404 "#undef __GOB_FUNCTION__\n\n");
2408 print_unreftors (Class *c)
2411 for(li = ((Class *)class)->nodes;
2415 Variable *v = (Variable *)n;
2416 if (n->type == VARIABLE_NODE &&
2417 v->scope != CLASS_SCOPE &&
2418 v->destructor_unref)
2419 print_destructor (v);
2424 add_dispose (Class *c)
2426 out_printf(out, "\nstatic void\n"
2427 "___dispose (GObject *obj_self)\n"
2430 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2433 if (unreftors > 0 || user_dispose_method != NULL) {
2434 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2436 ! no_gnu ? " G_GNUC_UNUSED" : "",
2440 if (dispose_handler != NULL) {
2441 if (unreftors > 0) {
2442 print_unreftors (c);
2445 /* so we get possible bad argument warning */
2446 if (dispose_handler->line_no > 0)
2447 out_addline_infile (out, dispose_handler->line_no);
2448 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2449 (guint)dispose_handler->unique_id, funcbase);
2450 if (dispose_handler->line_no > 0)
2451 out_addline_outfile (out);
2453 if (user_dispose_method != NULL) {
2454 if (user_dispose_method->line_no > 0)
2455 out_addline_infile (out, user_dispose_method->line_no);
2456 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2457 if (user_dispose_method->line_no > 0)
2458 out_addline_outfile (out);
2461 if (unreftors > 0) {
2462 print_unreftors (c);
2466 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2467 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2470 out_printf(out, "}\n"
2471 "#undef __GOB_FUNCTION__\n\n");
2475 print_destructors (Class *c)
2478 for (li = ((Class *)class)->nodes;
2482 Variable *v = (Variable *)n;
2483 if (n->type == VARIABLE_NODE &&
2484 v->scope != CLASS_SCOPE &&
2485 ! v->destructor_unref)
2486 print_destructor (v);
2491 add_finalize (Class *c)
2495 "___finalize(GObject *obj_self)\n"
2498 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2503 user_finalize_method != NULL) {
2504 const char *unused = "";
2506 unused = " G_GNUC_UNUSED";
2507 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2508 typebase, unused, macrobase);
2511 const char *unused = "";
2513 unused = " G_GNUC_UNUSED";
2514 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2518 if(finalize_handler) {
2519 if (destructors > 0) {
2520 print_destructors (c);
2523 /* so we get possible bad argument warning */
2524 if(finalize_handler->line_no > 0)
2525 out_addline_infile(out, finalize_handler->line_no);
2526 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2527 (guint)finalize_handler->unique_id, funcbase);
2528 if(finalize_handler->line_no > 0)
2529 out_addline_outfile(out);
2531 if (user_finalize_method != NULL) {
2532 if (user_finalize_method->line_no > 0)
2533 out_addline_infile (out, user_finalize_method->line_no);
2534 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2535 if (user_finalize_method->line_no > 0)
2536 out_addline_outfile (out);
2539 if (destructors > 0) {
2540 print_destructors (c);
2544 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2545 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2548 out_printf(out, "}\n"
2549 "#undef __GOB_FUNCTION__\n\n");
2553 make_bonobo_object_epv (Class *c, const char *classname)
2556 gboolean added_line = FALSE;
2558 for (li = c->nodes; li != NULL; li = li->next) {
2560 Method *m = (Method *)n;
2561 if(n->type != METHOD_NODE ||
2562 m->method == OVERRIDE_METHOD)
2565 if (m->bonobo_object_func) {
2566 if(m->line_no > 0) {
2567 out_addline_infile(out, m->line_no);
2569 } else if (m->line_no == 0 &&
2571 out_addline_outfile(out);
2574 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2575 classname, m->id, m->id);
2579 out_addline_outfile(out);
2582 static void add_class_private(Class *c, Method *m)
2584 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2589 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2590 " || !defined(G_ADD_PRIVATE%s)\n"
2591 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2594 ((FuncArg *)m->args->data)->name, typebase);
2597 static void get_instance_private(Class *c, Method *m)
2599 const char *self = ((FuncArg *)m->args->data)->name;
2600 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2603 if (always_private_struct) {
2604 out_printf(out, "\t%s->_priv = NULL;\n", self);
2610 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2611 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2612 " && defined(G_ADD_PRIVATE%s)\n"
2613 "\t\t%s_get_instance_private(%s);\n"
2615 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2618 "\t\t\t, %sPrivate\n"
2624 self, macrotype, typebase);
2630 const char *unused = "";
2634 unused = " G_GNUC_UNUSED";
2636 for(li=c->nodes;li;li=g_list_next(li)) {
2640 if(n->type != METHOD_NODE)
2643 if(m->method == INIT_METHOD) {
2645 out_addline_infile(out, m->line_no);
2646 print_method(out, "static ", "\n", "", " ", "", "\n",
2647 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2649 out_printf(out, "{\n");
2651 out_addline_outfile(out);
2653 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2656 get_instance_private(c, m);
2658 if(initializers > 0) {
2660 for(li = ((Class *)class)->nodes;
2664 Variable *v = (Variable *)n;
2665 if(n->type != VARIABLE_NODE ||
2666 v->scope == CLASS_SCOPE)
2668 print_initializer(m, v);
2671 if(glade_widgets > 0) {
2673 for(li = ((Class *)class)->nodes;
2677 Variable *v = (Variable *)n;
2678 if(n->type != VARIABLE_NODE ||
2679 v->scope == CLASS_SCOPE)
2681 print_glade_widget(m, v);
2684 } else if(m->method == CLASS_INIT_METHOD) {
2685 gboolean did_base_obj = FALSE;
2688 out_addline_infile(out, m->line_no);
2689 print_method(out, "static ", "\n", "", " ", "", "\n",
2690 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2692 out_printf(out, "{\n");
2694 out_addline_outfile(out);
2696 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2698 if (set_properties > 0 ||
2699 get_properties > 0 ||
2706 "g_object_class%s = "
2707 "(GObjectClass*) %s;\n",
2709 ((FuncArg *)m->args->data)->name);
2710 did_base_obj = TRUE;
2715 ((FuncArg *)m->args->data)->name,
2718 add_class_private(c, m);
2720 if (initializers > 0) {
2722 for(li = ((Class *)class)->nodes;
2726 Variable *v = (Variable *)n;
2727 if(n->type == VARIABLE_NODE &&
2728 v->scope == CLASS_SCOPE)
2729 print_initializer(m, v);
2733 out_printf(out, "\n\tparent_class = ");
2735 out_printf(out, "(%sClass *)", ptypebase);
2736 out_printf(out, "g_type_class_ref (%s);\n",
2742 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2744 /* if there are no handlers for these things, we
2745 * need to set them up here */
2746 if(need_constructor)
2747 out_printf(out, "\tg_object_class->constructor "
2748 "= ___constructor;\n");
2749 if(need_dispose && !dispose_handler)
2750 out_printf(out, "\tg_object_class->dispose "
2752 if(need_finalize && !finalize_handler)
2753 out_printf(out, "\tg_object_class->finalize = "
2756 if(get_properties > 0 || set_properties > 0)
2759 if (c->bonobo_object_class != NULL) {
2760 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2766 out_printf(out, " {\n");
2767 out_addline_infile(out, m->ccode_line);
2768 out_printf(out, "%s\n", m->cbuf);
2769 out_addline_outfile(out);
2770 out_printf(out, " }\n");
2772 out_printf(out, "}\n"
2773 "#undef __GOB_FUNCTION__\n");
2778 add_argument (Argument *a, gboolean is_set)
2782 char *the_type_lower;
2787 line_no = a->set_line;
2790 line_no = a->get_line;
2794 s = g_strdup(a->name);
2796 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2798 the_type_lower = g_strdup (a->gtktype);
2799 gob_strdown (the_type_lower);
2801 /* HACK because there is no g_value_set/get for unichar */
2802 if (strcmp (the_type_lower, "unichar") == 0) {
2803 g_free (the_type_lower);
2804 the_type_lower = g_strdup ("uint");
2809 const char *unused = "";
2811 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2812 unused = " G_GNUC_UNUSED";
2815 if (a->atype != NULL &&
2816 /* gcc -Wbad-function-cast is wanking stupid, moronic
2817 and otherwise evil so we should just use a (gint)
2818 or (guint) cast, not the specific type cast */
2820 (strcmp (a->gtktype, "ENUM") != 0 &&
2821 strcmp (a->gtktype, "FLAGS") != 0)))
2822 cast = get_type (a->atype, TRUE);
2824 cast = g_strdup (get_cast (a->gtktype, FALSE));
2826 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2827 cast, unused, cast, the_type_lower);
2830 } else if ( ! is_set) {
2833 if (a->atype != NULL)
2834 cast = get_type (a->atype, TRUE);
2836 cast = g_strdup (get_cast (a->gtktype, FALSE));
2837 out_printf (out, "\t%s ARG;\n"
2838 "\tmemset (&ARG, 0, sizeof (%s));\n",
2844 out_printf(out, "\t\t{\n");
2846 out_addline_infile (out, line_no);
2847 out_printf (out, "%s\n", cbuf);
2849 out_addline_outfile (out);
2850 out_printf (out, "\t\t}\n");
2852 if (strcmp (a->gtktype, "OBJECT") == 0)
2853 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2856 out_printf (out, "\t\t"
2857 "g_value_set_%s (VAL, ARG);\n",
2860 g_free (the_type_lower);
2863 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2864 out_printf (out, "\t\tif (&ARG) break;\n");
2867 out_printf (out, "\t\tbreak;\n");
2869 out_printf (out, "\t}\n");
2873 add_property (Property *p, gboolean is_set)
2876 char *the_type_lower;
2882 line_no = p->set_line;
2885 line_no = p->get_line;
2890 name_upper = g_strdup (p->name);
2891 gob_strup (name_upper);
2892 the_type_lower = g_strdup (p->gtktype);
2893 gob_strdown (the_type_lower);
2895 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2897 out_printf(out, "\t\t{\n");
2899 out_addline_infile (out, line_no);
2900 out_printf (out, "%s\n", cbuf);
2902 out_addline_outfile (out);
2903 out_printf (out, "\t\t}\n");
2905 g_free (name_upper);
2906 g_free (the_type_lower);
2908 out_printf (out, "\t\tbreak;\n");
2912 add_getset_arg(Class *c, gboolean is_set)
2915 const char *unused = "";
2916 const char *hack_unused = "";
2918 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2919 unused = " G_GNUC_UNUSED";
2921 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2924 out_printf(out, "\nstatic void\n"
2925 "___object_%s_property (GObject *object,\n"
2926 "\tguint property_id,\n"
2927 "\t%sGValue *VAL%s,\n"
2928 "\tGParamSpec *pspec%s)\n"
2929 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2932 "\tself = %s (object);\n\n"
2933 "\tswitch (property_id) {\n",
2934 is_set ? "set" : "get",
2935 is_set ? "const " : "",
2939 is_set ? "set" : "get",
2944 for (li = c->nodes; li != NULL; li = li->next) {
2946 if (n->type == PROPERTY_NODE)
2947 add_property ((Property *)n, is_set);
2948 else if (n->type == ARGUMENT_NODE)
2949 add_argument ((Argument *)n, is_set);
2951 out_printf (out, "\tdefault:\n"
2952 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2953 "#ifndef __PRETTY_FUNCTION__\n"
2954 "# undef G_STRLOC\n"
2955 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2957 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2958 "\t\t%sbreak;\n\t}\n"
2960 "#undef __GOB_FUNCTION__\n", hack_unused);
2964 print_checks (Method *m, FuncArg *fa)
2968 gboolean checked_null = FALSE;
2969 is_void = (strcmp(m->mtype->name, "void")==0 &&
2970 m->mtype->pointer == NULL);
2972 for(li = fa->checks; li != NULL; li = li->next) {
2973 Check *ch = li->data;
2975 /* point to the method prot in .gob for failed checks */
2977 out_addline_infile(out, m->line_no);
2979 out_printf(out, "\tg_return_if_fail (");
2981 out_printf(out, "\tg_return_val_if_fail (");
2982 switch(ch->chtype) {
2984 out_printf(out, "%s != NULL", fa->name);
2985 checked_null = TRUE;
2988 s = make_pre_macro(fa->atype->name, "IS");
2990 out_printf(out, "%s (%s)", s, fa->name);
2992 /* if not check null, null may be valid */
2993 out_printf(out, "!(%s) || %s (%s)", fa->name,
2998 out_printf(out, "%s < %s", fa->name, ch->number);
3001 out_printf(out, "%s > %s", fa->name, ch->number);
3004 out_printf(out, "%s <= %s", fa->name, ch->number);
3007 out_printf(out, "%s >= %s", fa->name, ch->number);
3010 out_printf(out, "%s == %s", fa->name, ch->number);
3013 out_printf(out, "%s != %s", fa->name, ch->number);
3017 out_printf(out, ");\n");
3019 out_printf(out, ", (");
3020 print_type(out, m->mtype, TRUE);
3021 out_printf(out, ")%s);\n",
3022 m->onerror?m->onerror:"0");
3028 print_preconditions(Method *m)
3032 for(li=m->args;li;li=g_list_next(li)) {
3033 FuncArg *fa = li->data;
3035 print_checks(m, fa);
3038 out_addline_outfile(out);
3042 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3044 out_printf(out, "{\n");
3046 out_addline_outfile(out);
3047 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3048 ((Class *)class)->otype,
3051 print_preconditions(m);
3055 (no_gnu || for_cpp) &&
3057 ((FuncArg *)(m->args->data))->name != NULL &&
3058 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3059 out_printf (out, "\tif (&self) { ; }\n");
3062 /* Note: the trailing }'s are on one line, this is so
3063 that we get the no return warning correctly and point to
3064 the correct line in the .gob file, yes this is slightly
3065 ugly in the .c file, but that is not supposed to be
3066 human readable anyway. */
3068 out_printf(out, "{\n");
3070 out_addline_infile(out, m->ccode_line);
3071 out_printf(out, "\t%s}", m->cbuf);
3074 /* Note, there is no \n between the last } and this } so that
3075 * errors/warnings reported on the end of the body get pointed to the
3076 * right line in the .gob source */
3077 out_printf(out, "}\n");
3080 out_addline_outfile(out);
3081 out_printf(out, "#undef __GOB_FUNCTION__\n");
3085 put_signal_args (Method *m)
3091 if (m->args->next == NULL)
3094 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3095 li != NULL && ali != NULL;
3096 li = li->next, ali = ali->next, i++) {
3097 FuncArg *fa = li->data;
3098 char *str = ali->data;
3099 char *cast = g_strdup (get_cast (str, FALSE));
3100 /* FIXME: This code is so fucking ugly it hurts */
3101 gboolean do_static =
3102 (strcmp (str, "STRING") == 0 ||
3103 strcmp (str, "BOXED") == 0 ||
3104 strncmp (str, "BOXED_", 6) == 0);
3109 cast = get_type (fa->atype, TRUE);
3111 /* we should have already proved before that
3112 the we know all the types */
3113 g_assert (cast != NULL);
3115 if (strncmp (str, "BOXED_", 6) == 0)
3116 t = g_strdup (&(str[6]));
3118 t = g_strconcat ("G_TYPE_", str, NULL);
3121 "\t___param_values[%d].g_type = 0;\n"
3122 "\tg_value_init (&___param_values[%d], %s);\n",
3126 if (strcmp (str, "UNICHAR") == 0)
3127 /* hack because glib is braindamaged */
3128 set_func = g_strdup ("g_value_set_uint");
3129 else if (strncmp (str, "BOXED_", 6) == 0)
3130 set_func = g_strdup ("g_value_set_static_boxed");
3132 set_func = g_strdup_printf ("g_value_set%s_%s",
3133 do_static ? "_static" : "",
3135 gob_strdown (set_func);
3137 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3138 set_func, i, cast, fa->name);
3146 clear_signal_args (Method *m)
3151 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3153 if (m->args->next == NULL)
3156 for (li = m->args->next, i = 1;
3158 li = li->next, i++) {
3160 "\tg_value_unset (&___param_values[%d]);\n", i);
3165 get_arg_names_for_macro (Method *m)
3169 GString *gs = g_string_new(NULL);
3171 for(li=m->args;li;li=g_list_next(li)) {
3172 FuncArg *arg = li->data;
3173 g_string_append_printf(gs, "%s___%s", sep, arg->name);
3176 return g_string_free (gs, FALSE);
3179 static gboolean method_is_void(Method *m)
3181 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3184 static const char *method_err_retval(Method *m)
3186 if (method_is_void(m))
3194 put_interface_parent_handler(Method *m)
3196 const char *errval = method_err_retval(m);
3197 char *name = replace_sep(m->interface, '_');
3198 char *args = get_arg_names_for_macro(m);
3200 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3201 "\t? %s_parent_iface->%s(%s) \\\n"
3202 "\t: %s)\n", args, name, name, m->id, args, errval);
3209 put_method(Method *m)
3211 char *s, *args, *doc;
3213 is_void = (strcmp(m->mtype->name, "void")==0 &&
3214 m->mtype->pointer == NULL);
3215 out_printf(out, "\n");
3216 if(m->method != OVERRIDE_METHOD) {
3217 doc = get_gtk_doc(m->id);
3219 out_printf(out, "%s", doc);
3225 case REGULAR_METHOD:
3227 out_addline_infile(out, m->line_no);
3228 if(m->scope == PRIVATE_SCOPE)
3229 print_method(out, "static ", "\n", "", " ", "", "\n",
3230 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3231 else /* PUBLIC, PROTECTED */
3232 print_method(out, "", "\n", "", " ", "", "\n",
3233 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3236 out_addline_outfile(out);
3237 put_interface_parent_handler(m);
3240 print_method_body(m, TRUE, TRUE);
3243 out_printf(out, "#undef PARENT_HANDLER\n");
3246 /* the outfile line was added above */
3248 case SIGNAL_FIRST_METHOD:
3249 case SIGNAL_LAST_METHOD:
3251 out_addline_infile(out, m->line_no);
3252 if(m->scope == PRIVATE_SCOPE)
3253 print_method(out, "static ", "\n", "", " ", "", "\n",
3254 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3255 else /* PUBLIC, PROTECTED */
3256 print_method(out, "", "\n", "", " ", "", "\n",
3257 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3258 out_printf (out, "{\n");
3260 out_addline_outfile (out);
3263 "\tGValue ___param_values[%d];\n"
3264 "\tGValue ___return_val;\n\n"
3265 "memset (&___return_val, 0, "
3266 "sizeof (___return_val));\n"
3267 "memset (&___param_values, 0, "
3268 "sizeof (___param_values));\n\n",
3269 g_list_length (m->args));
3271 print_preconditions (m);
3274 "\n\t___param_values[0].g_type = 0;\n"
3275 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3276 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3277 ((FuncArg *)m->args->data)->name,
3278 ((FuncArg *)m->args->data)->name);
3280 put_signal_args (m);
3282 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3283 const char *defret = NULL;
3285 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3286 (char *)m->gtktypes->data);
3288 if (m->defreturn != NULL)
3289 defret = m->defreturn;
3290 else if (m->onerror != NULL)
3291 defret = m->onerror;
3293 if (defret != NULL) {
3295 /* FIXME: This code is so fucking ugly it hurts */
3296 gboolean do_static =
3297 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3298 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3299 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3301 cast = get_type (m->mtype, TRUE);
3303 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3304 /* hack because glib is braindamaged */
3305 set_func = g_strdup ("g_value_set_uint");
3307 set_func = g_strdup_printf ("g_value_set%s_%s",
3308 do_static ? "_static" : "",
3309 (char *)m->gtktypes->data);
3310 gob_strdown (set_func);
3312 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3313 set_func, cast, defret);
3318 out_printf (out, "\n");
3321 s = g_strdup (m->id);
3324 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3325 "\t\tobject_signals[%s_SIGNAL],\n"
3326 "\t\t0 /* detail */,\n"
3327 "\t\t&___return_val);\n", s);
3331 clear_signal_args (m);
3333 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3334 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3336 /* Hack because glib is very very braindead */
3338 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3339 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3340 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3341 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3343 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3344 /* hack because glib is braindamaged */
3345 getfunc = g_strdup ("g_value_get_uint");
3347 getfunc = g_strdup_printf ("g_value_%s_%s",
3348 do_dup ? "dup" : "get",
3349 (char *)m->gtktypes->data);
3350 gob_strdown (getfunc);
3353 cast = get_type (m->mtype, TRUE);
3358 print_type (out, m->mtype, TRUE);
3360 " ___ret = (%s) %s (&___return_val);\n"
3361 "\t\tg_value_unset (&___return_val);\n"
3362 "\t\treturn ___ret;\n"
3369 out_printf(out, "}\n");
3374 out_addline_infile(out, m->line_no);
3375 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3376 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3377 print_method_body(m, FALSE, TRUE);
3378 /* the outfile line was added above */
3380 case VIRTUAL_METHOD:
3382 out_addline_infile(out, m->line_no);
3383 if(m->scope==PRIVATE_SCOPE)
3384 print_method(out, "static ", "\n", "", " ", "", "\n",
3385 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3386 else /* PUBLIC, PROTECTED */
3387 print_method(out, "", "\n", "", " ", "", "\n",
3388 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3389 out_printf(out, "{\n");
3390 out_addline_outfile(out);
3391 out_printf(out, "\t%sClass *klass;\n", typebase);
3392 print_preconditions(m);
3393 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3394 "\tif(klass->%s)\n",
3395 macrobase, ((FuncArg *)m->args->data)->name,
3397 if(strcmp(m->mtype->name, "void") == 0 &&
3398 m->mtype->pointer == NULL) {
3400 out_printf(out, "\t\t(*klass->%s)(%s",
3402 ((FuncArg *)m->args->data)->name);
3403 for(li=m->args->next;li;li=g_list_next(li)) {
3404 FuncArg *fa = li->data;
3405 out_printf(out, ",%s", fa->name);
3407 out_printf(out, ");\n}\n");
3410 out_printf(out, "\t\treturn (*klass->%s)(%s",
3412 ((FuncArg *)m->args->data)->name);
3413 for(li=m->args->next;li;li=g_list_next(li)) {
3414 FuncArg *fa = li->data;
3415 out_printf(out, ",%s", fa->name);
3417 out_printf(out, ");\n"
3420 print_type(out, m->mtype, TRUE);
3422 out_printf(out, ")(%s);\n}\n", m->defreturn);
3424 out_printf(out, ")(%s);\n}\n", m->onerror);
3426 out_printf(out, ")(0);\n}\n");
3432 out_addline_infile(out, m->line_no);
3433 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3434 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3435 print_method_body(m, FALSE, TRUE);
3436 /* the outfile line was added above */
3438 case OVERRIDE_METHOD:
3442 out_addline_infile(out, m->line_no);
3443 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3444 print_method(out, "static ", s, "", " ", "", "\n",
3445 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3447 out_addline_outfile(out);
3448 s = replace_sep(m->otype, '_');
3450 args = get_arg_names_for_macro(m);
3452 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3453 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3454 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3455 args, s, m->id, s, m->id, args);
3457 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3458 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3459 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3461 args, s, m->id, s, m->id, args);
3462 out_printf(out, "(");
3463 print_type(out, m->mtype, TRUE);
3464 out_printf(out, ")%s))\n",
3465 m->onerror?m->onerror:"0");
3469 print_method_body(m, TRUE, TRUE);
3470 /* the outfile line was added above */
3471 out_printf(out, "#undef PARENT_HANDLER\n");
3473 case CONSTRUCTOR_METHOD:
3474 case DISPOSE_METHOD:
3475 case FINALIZE_METHOD:
3477 out_addline_infile(out, m->line_no);
3478 print_method(out, "static ", "\n", "", " ", "", "\n",
3479 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3480 print_method_body(m, TRUE, TRUE);
3481 /* the outfile line was added above */
3490 char *outfile, *outfileh, *outfileph;
3492 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3493 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3495 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3496 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3498 if ((privates > 0 || protecteds > 0 ||
3499 private_header == PRIVATE_HEADER_ALWAYS) &&
3500 private_header != PRIVATE_HEADER_NEVER) {
3501 char sep[2] = {0,0};
3504 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3505 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3507 outfilephbase = NULL;
3513 out = fopen (outfile, "w");
3515 error_printf (GOB_ERROR, 0,
3516 "Cannot open outfile: %s", outfile);
3518 outh = fopen (outfileh, "w");
3520 error_printf (GOB_ERROR, 0,
3521 "Cannot open outfile: %s", outfileh);
3523 if (outfileph != NULL) {
3524 outph = fopen (outfileph, "w");
3525 if (outph == NULL) {
3526 error_printf (GOB_ERROR, 0,
3527 "Cannot open outfile: %s",
3535 put_argument_nongnu_wrappers (Class *c)
3539 if (get_properties < 0 && set_properties < 0)
3542 for (li = c->nodes; li != NULL; li = li->next) {
3544 const char *name, *gtktype;
3550 if (n->type == ARGUMENT_NODE) {
3551 Argument *a = (Argument *)n;
3553 gtktype = a->gtktype;
3555 get = a->get != NULL;
3556 set = a->set != NULL;
3557 } else if (n->type == PROPERTY_NODE) {
3558 Property *p = (Property *)n;
3560 gtktype = p->gtktype;
3562 get = p->get != NULL;
3563 set = p->set != NULL;
3568 aname = g_strdup (name);
3572 cast = get_type (atype, TRUE);
3574 cast = g_strdup (get_cast (gtktype, TRUE));
3578 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3579 "\"%s\",(%s)(arg)\n",
3580 macrobase, aname, name, cast);
3582 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3583 "\"%s\",(%s*)(arg)\n",
3584 macrobase, aname, name, cast);
3587 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3589 macrobase, aname, name);
3591 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3593 macrobase, aname, name);
3601 put_argument_gnu_wrappers(Class *c)
3605 if(get_properties < 0 && set_properties < 0)
3608 for (li = c->nodes; li != NULL; li = li->next) {
3610 const char *name, *gtktype;
3616 if (n->type == ARGUMENT_NODE) {
3617 Argument *a = (Argument *)n;
3619 gtktype = a->gtktype;
3621 get = a->get != NULL;
3622 set = a->set != NULL;
3623 } else if (n->type == PROPERTY_NODE) {
3624 Property *p = (Property *)n;
3626 gtktype = p->gtktype;
3628 get = p->get != NULL;
3629 set = p->set != NULL;
3634 aname = g_strdup (name);
3638 cast = get_type (atype, TRUE);
3640 cast = g_strdup (get_cast (gtktype, TRUE));
3644 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3645 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3646 macrobase, aname, name, cast);
3648 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3649 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3650 macrobase, aname, name, cast);
3653 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3655 macrobase, aname, name);
3657 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3659 macrobase, aname, name);
3667 print_ccode_block(CCode *cc)
3670 switch(cc->cctype) {
3672 /* HT code is printed exactly like normal header
3673 code but is printed before */
3676 out_printf(fp, "\n");
3679 /* AT code is printed exactly like normal 'all'
3680 code but is printed before */
3683 out_printf(outph, "\n");
3684 out_printf(outph, "%s\n", cc->cbuf);
3685 out_addline_infile(outph, cc->line_no);
3686 out_addline_outfile(outph);
3688 out_printf(outh, "\n");
3689 out_printf(outh, "%s\n", cc->cbuf);
3691 out_printf(fp, "\n");
3692 out_addline_infile(fp, cc->line_no);
3698 out_printf(fp, "\n");
3699 out_addline_infile(fp, cc->line_no);
3706 out_printf(fp, "\n");
3707 out_addline_infile(fp, cc->line_no);
3710 out_printf(fp, "%s\n", cc->cbuf);
3711 if(cc->cctype == C_CCODE ||
3712 cc->cctype == AD_CCODE ||
3713 cc->cctype == A_CCODE ||
3714 cc->cctype == AT_CCODE ||
3715 cc->cctype == PH_CCODE)
3716 out_addline_outfile(fp);
3720 print_class_block(Class *c)
3724 gboolean printed_private = FALSE;
3728 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3729 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3733 out_printf(out, "/* utility types we may need */\n");
3734 if(special_array[SPECIAL_2POINTER])
3735 out_printf(out, "typedef struct { "
3736 "gpointer a; gpointer b; "
3737 "} ___twopointertype;\n");
3738 if(special_array[SPECIAL_3POINTER])
3739 out_printf(out, "typedef struct { "
3740 "gpointer a; gpointer b; "
3742 "} ___threepointertype;\n");
3743 if(special_array[SPECIAL_INT_POINTER])
3744 out_printf(out, "typedef struct { "
3745 "gint a; gpointer b; "
3746 "} ___intpointertype;\n");
3747 out_printf(out, "\n");
3750 out_printf(outh, "\n/*\n"
3751 " * Type checking and casting macros\n"
3753 out_printf(outh, "#define %s\t"
3754 "(%s_get_type())\n",
3755 macrotype, funcbase);
3756 out_printf(outh, "#define %s(obj)\t"
3757 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3758 macrobase, funcbase, typebase);
3759 out_printf(outh, "#define %s_CONST(obj)\t"
3760 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3761 macrobase, funcbase, typebase);
3762 out_printf(outh, "#define %s_CLASS(klass)\t"
3763 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3764 macrobase, funcbase, typebase);
3765 out_printf(outh, "#define %s(obj)\t"
3766 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3769 "#define %s_GET_CLASS(obj)\t"
3770 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3771 macrobase, funcbase, typebase);
3773 if ( ! no_self_alias) {
3774 out_printf(out, "/* self casting macros */\n");
3775 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3776 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3777 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3778 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3779 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3781 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3784 out_printf(out, "/* self typedefs */\n");
3785 out_printf(out, "typedef %s Self;\n", typebase);
3786 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3790 always_private_struct) {
3791 out_printf (outh, "\n/* Private structure type */\n");
3792 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3793 typebase, typebase);
3795 out_printf (outh, "/* There are no privates, this "
3796 "structure is thus never defined */\n");
3799 out_printf (outh, "\n/*\n"
3800 " * Main object structure\n"
3802 s = replace_sep (c->otype, '_');
3804 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3805 "#define __TYPEDEF_%s__\n", s, s);
3807 out_printf (outh, "typedef struct _%s %s;\n"
3808 "#endif\n", typebase, typebase);
3809 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3810 typebase, ptypebase);
3811 for (li = c->nodes; li; li=li->next) {
3812 static gboolean printed_public = FALSE;
3814 Variable *v = (Variable *)n;
3815 if(n->type == VARIABLE_NODE &&
3816 v->scope == PUBLIC_SCOPE) {
3817 if( ! printed_public) {
3818 out_printf(outh, "\t/*< public >*/\n");
3819 printed_public = TRUE;
3821 put_variable((Variable *)n, outh);
3824 /* put protecteds always AFTER publics */
3825 for (li = c->nodes; li != NULL; li = li->next) {
3827 Variable *v = (Variable *)n;
3828 if (n->type == VARIABLE_NODE &&
3829 v->scope == PROTECTED_SCOPE) {
3830 if ( ! printed_private) {
3831 out_printf (outh, "\t/*< private >*/\n");
3832 printed_private = TRUE;
3834 put_variable ((Variable *)n, outh);
3838 always_private_struct) {
3839 if ( ! printed_private)
3840 out_printf (outh, "\t/*< private >*/\n");
3841 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3843 out_printf (outh, "};\n");
3848 /* if we are to stick this into the private
3849 header, if not stick it directly into the
3856 out_printf (outfp, "struct _%sPrivate {\n",
3860 for(li=c->nodes; li; li=li->next) {
3862 Variable *v = (Variable *)n;
3863 if(n->type == VARIABLE_NODE &&
3864 v->scope == PRIVATE_SCOPE) {
3865 out_addline_infile(outfp, v->line_no);
3866 put_variable(v, outfp);
3869 out_addline_outfile(outfp);
3871 out_printf(outfp, "};\n");
3874 out_printf(outh, "\n/*\n"
3875 " * Class definition\n"
3877 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3878 typebase, typebase);
3880 "struct _%sClass {\n\t%sClass __parent__;\n",
3881 typebase, ptypebase);
3882 for(li = c->nodes; li != NULL; li = li->next) {
3884 if(n->type == METHOD_NODE)
3885 put_vs_method((Method *)n);
3887 /* If BonoboX type class put down the epv */
3888 if (c->bonobo_object_class != NULL) {
3890 "\t/* Bonobo object epv */\n"
3891 "\tPOA_%s__epv _epv;\n",
3892 c->bonobo_object_class);
3894 /* put class scope variables */
3895 for (li = c->nodes; li != NULL; li = li->next) {
3897 Variable *v = (Variable *)n;
3898 if (n->type == VARIABLE_NODE &&
3899 v->scope == CLASS_SCOPE)
3900 put_variable ((Variable *)n, outh);
3902 out_printf (outh, "};\n\n");
3904 out_printf (out, "/* here are local prototypes */\n");
3905 if (set_properties > 0) {
3906 out_printf (out, "static void ___object_set_property "
3907 "(GObject *object, guint property_id, "
3908 "const GValue *value, GParamSpec *pspec);\n");
3910 if (get_properties > 0) {
3911 out_printf (out, "static void ___object_get_property "
3912 "(GObject *object, guint property_id, "
3913 "GValue *value, GParamSpec *pspec);\n");
3916 out_printf (outh, "\n/*\n"
3917 " * Public methods\n"
3920 if (!overrode_get_type && !no_gnu) {
3922 * For ordinary "static" types it should be safe to mark the
3923 * get_type implementation as const, since the get_type
3924 * function return really is constant at the call boundary
3925 * (even though there is an initial setup on the first call).
3926 * But for dynamic types, since the registration is explicitly
3927 * separated, we need to settle for "pure" as the results of
3928 * get_type differ before and after type registration.
3930 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3931 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3935 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3939 for(li = c->nodes; li != NULL; li = li->next) {
3941 if(n->type == METHOD_NODE) {
3942 put_pub_method((Method *)n);
3943 put_prot_method((Method *)n);
3944 put_priv_method_prot((Method *)n);
3948 /* this idea is less and less apealing to me */
3950 out_printf (outh, "\n/*\n"
3951 " * Signal connection wrapper macros\n"
3954 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3955 put_signal_macros (c, TRUE);
3956 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3957 put_signal_macros (c, FALSE);
3958 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3960 put_signal_macros (c, FALSE);
3961 out_printf(outh, "\n");
3964 out_printf (out, "\n/*\n"
3965 " * Signal connection wrapper macro shortcuts\n"
3967 put_local_signal_macros (c);
3968 out_printf(outh, "\n");
3971 /* argument wrapping macros */
3972 if(get_properties > 0 || set_properties > 0) {
3973 out_printf(outh, "\n/*\n"
3974 " * Argument wrapping macros\n"
3977 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3978 put_argument_gnu_wrappers(c);
3979 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3980 put_argument_nongnu_wrappers(c);
3981 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3983 put_argument_nongnu_wrappers(c);
3988 for(li = c->nodes; li != NULL; li = li->next) {
3990 if(n->type == METHOD_NODE)
3991 add_signal_prots((Method *)n);
3997 if(any_method_to_alias(c)) {
3998 out_printf (out, "/* Short form macros */\n");
3999 make_method_aliases (c);
4002 add_interface_inits (c);
4004 if (!overrode_get_type) {
4005 if (c->bonobo_object_class != NULL)
4006 add_bonobo_object_get_type();
4007 else if (c->dynamic)
4008 add_dynamic_get_type();
4013 out_printf (out, "/* a macro for creating a new object of our type */\n");
4015 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4016 typebase, funcbase);
4018 out_printf (out, "/* a function for creating a new object of our type */\n");
4019 out_printf (out, "#include <stdarg.h>\n");
4021 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4022 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4023 "{\n\t%s *ret;\n\tva_list ap;\n"
4024 "\tva_start (ap, first);\n"
4025 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4028 "\treturn ret;\n}\n\n",
4030 no_gnu ? "" : " G_GNUC_UNUSED",
4031 typebase, typebase, typebase, funcbase);
4035 out_printf (out, "/* a function to connect glade callback */\n");
4036 out_printf (out,"static void\n"
4037 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4038 "GObject *object,\n"
4039 "const gchar *signal_name,\n"
4040 "const gchar *signal_data,\n"
4041 "GObject *connect_object,\n"
4043 "gpointer user_data)\n"
4045 "\tstatic GModule * allsymbols = NULL;\n"
4047 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4048 "\tif (allsymbols) {\n"
4049 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4050 "\t\tGCallback func;\n"
4052 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4053 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4054 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4055 "\t\t\t\tg_free(func_name);\n"
4060 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4062 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4063 "\t\tg_free(func_name);\n"
4070 for (li = nodes; li != NULL; li = li->next) {
4071 Node *node = li->data;
4072 if (node->type == CCODE_NODE) {
4073 CCode *cc = (CCode *)node;
4074 if (cc->cctype == AD_CCODE)
4075 print_ccode_block (cc);
4079 if (need_constructor)
4080 add_constructor (c);
4090 if(set_properties > 0) {
4091 add_getset_arg(c, TRUE);
4094 if(get_properties > 0) {
4095 add_getset_arg(c, FALSE);
4098 for(li = c->nodes; li != NULL; li = li->next) {
4100 if(n->type == METHOD_NODE)
4101 put_method((Method *)n);
4104 add_bad_hack_to_avoid_unused_warnings(c);
4108 print_useful_macros(void)
4110 int major = 0, minor = 0, pl = 0;
4113 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4114 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4115 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4116 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4118 /* Useful priv macro thingie */
4119 /* FIXME: this should be done the same way that priv is, as a var,
4121 out_printf (out, "#define selfp (self->_priv)\n\n");
4125 print_more_useful_macros (void)
4128 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4129 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4131 out_printf (out, "#ifdef G_LIKELY\n");
4132 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4133 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4134 out_printf (out, "#else /* ! G_LIKELY */\n");
4135 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4136 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4137 out_printf (out, "#endif /* G_LIKELY */\n");
4142 print_file_comments(void)
4144 out_printf(outh, "/* Generated by GOB (v%s)"
4145 " (do not edit directly) */\n\n", VERSION);
4147 out_printf(outph, "/* Generated by GOB (v%s)"
4148 " (do not edit directly) */\n\n", VERSION);
4149 out_printf(out, "/* Generated by GOB (v%s)"
4150 " (do not edit directly) */\n\n", VERSION);
4152 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4156 print_includes(void)
4158 gboolean found_header;
4161 /* We may need string.h for memset */
4162 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4163 out_printf(out, "#include <string.h> /* memset() */\n\n");
4166 p = g_strconcat(filebase, ".h", NULL);
4167 found_header = TRUE;
4168 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4169 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4170 found_header = FALSE;
4174 /* if we are creating a private header see if it was included */
4176 char sep[2] = {0,0};
4179 p = g_strconcat(filebase, sep, "private.h", NULL);
4180 if( ! g_list_find_custom(include_files, p,
4181 (GCompareFunc)strcmp)) {
4182 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4186 error_printf(GOB_WARN, 0,
4187 "Implicit private header include "
4189 "\tsource file, while public "
4190 "header is at a custom location, "
4192 "\texplicitly include "
4193 "the private header below the "
4201 print_header_prefixes(void)
4205 p = replace_sep(((Class *)class)->otype, '_');
4207 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4209 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4210 "#define __%s_PRIVATE_H__\n\n"
4211 "#include \"%s.h\"\n\n", p, p, filebase);
4214 if( ! no_extern_c) {
4215 out_printf(outh, "#ifdef __cplusplus\n"
4217 "#endif /* __cplusplus */\n\n");
4219 out_printf(outph, "#ifdef __cplusplus\n"
4221 "#endif /* __cplusplus */\n\n");
4226 print_header_postfixes(void)
4229 out_printf(outh, "\n#ifdef __cplusplus\n"
4231 "#endif /* __cplusplus */\n");
4232 out_printf(outh, "\n#endif\n");
4235 out_printf(outph, "\n#ifdef __cplusplus\n"
4237 "#endif /* __cplusplus */\n");
4238 out_printf(outph, "\n#endif\n");
4247 /* print the AT_CCODE and CT_CCODE blocks */
4248 for(li = nodes; li != NULL; li = li->next) {
4249 Node *node = li->data;
4250 if(node->type == CCODE_NODE) {
4251 CCode *cc = (CCode *)node;
4252 if (cc->cctype == AT_CCODE ||
4253 cc->cctype == CT_CCODE)
4254 print_ccode_block((CCode *)node);
4260 print_header_top(void)
4264 /* mandatory includes */
4265 out_printf (outh, "#include <glib.h>\n");
4266 out_printf (outh, "#include <glib-object.h>\n");
4268 /* print the HT_CCODE blocks */
4269 for (li = nodes; li != NULL; li = li->next) {
4270 Node *node = li->data;
4271 if (node->type == CCODE_NODE) {
4272 CCode *cc = (CCode *)node;
4273 if (cc->cctype == HT_CCODE)
4274 print_ccode_block ((CCode *)node);
4280 print_enum (EnumDef *enode)
4287 funcprefix = replace_sep (enode->etype, '_');
4288 gob_strdown (funcprefix);
4289 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4291 type = remove_sep (enode->etype);
4293 out_printf (outh, "\ntypedef enum {\n");
4295 for (li = enode->values; li != NULL; li = li->next) {
4296 EnumValue *value = li->data;
4298 char *sname = gob_strdown (g_strdup (value->name));
4300 while ((p = strchr (sname, '_')) != NULL)
4303 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4304 if (value->value != NULL)
4305 out_printf (outh, " = %s", value->value);
4306 if (li->next != NULL)
4307 out_printf (outh, ",\n");
4309 out_printf (outh, "\n");
4311 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4312 enode->prefix, value->name,
4313 enode->prefix, value->name,
4319 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4321 out_printf (outh, "} %s;\n", type);
4323 str = make_pre_macro (enode->etype, "TYPE");
4324 out_printf (outh, "#define %s ", str);
4327 out_printf (outh, "%s_get_type()\n", funcprefix);
4328 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4329 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4332 "GType\n%s_get_type (void)\n"
4334 "\tstatic GType type = 0;\n"
4335 "\tif ___GOB_UNLIKELY(type == 0)\n"
4336 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4339 funcprefix, type, funcprefix);
4341 g_free (funcprefix);
4346 print_flags (Flags *fnode)
4354 funcprefix = replace_sep (fnode->ftype, '_');
4355 gob_strdown (funcprefix);
4356 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4358 type = remove_sep (fnode->ftype);
4360 out_printf (outh, "\ntypedef enum {\n");
4362 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4363 const char *name = li->data;
4365 char *sname = gob_strdown (g_strdup (name));
4367 while ((p = strchr (sname, '_')) != NULL)
4370 out_printf (outh, "\t%s_%s = 1<<%d",
4371 fnode->prefix, name, i);
4372 if (li->next != NULL)
4373 out_printf (outh, ",\n");
4375 out_printf (outh, "\n");
4377 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4378 fnode->prefix, name,
4379 fnode->prefix, name,
4385 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4387 out_printf (outh, "} %s;\n", type);
4389 str = make_pre_macro (fnode->ftype, "TYPE");
4390 out_printf (outh, "#define %s ", str);
4393 out_printf (outh, "%s_get_type()\n", funcprefix);
4394 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4395 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4398 "GType\n%s_get_type (void)\n"
4400 "\tstatic GType type = 0;\n"
4401 "\tif ___GOB_UNLIKELY(type == 0)\n"
4402 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4405 funcprefix, type, funcprefix);
4407 g_free (funcprefix);
4412 print_error (Error *enode)
4419 funcprefix = replace_sep (enode->etype, '_');
4420 gob_strdown (funcprefix);
4421 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4423 type = remove_sep (enode->etype);
4425 out_printf (outh, "\ntypedef enum {\n");
4427 for (li = enode->values; li != NULL; li = li->next) {
4428 const char *name = li->data;
4430 char *sname = gob_strdown (g_strdup (name));
4432 while ((p = strchr (sname, '_')) != NULL)
4435 out_printf (outh, "\t%s_%s", enode->prefix, name);
4436 if (li->next != NULL)
4437 out_printf (outh, ",\n");
4439 out_printf (outh, "\n");
4441 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4442 enode->prefix, name,
4443 enode->prefix, name,
4449 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4451 out_printf (outh, "} %s;\n", type);
4453 str = make_pre_macro (enode->etype, "TYPE");
4454 out_printf (outh, "#define %s ", str);
4457 out_printf (outh, "%s_get_type ()\n", funcprefix);
4458 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4459 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4462 "GType\n%s_get_type (void)\n"
4464 "\tstatic GType type = 0;\n"
4465 "\tif ___GOB_UNLIKELY(type == 0)\n"
4466 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4469 funcprefix, type, funcprefix);
4471 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4472 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4474 str = replace_sep (enode->etype, '-');
4478 "GQuark\n%s_quark (void)\n"
4480 "\tstatic GQuark q = 0;\n"
4482 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4489 g_free (funcprefix);
4494 generate_outfiles(void)
4498 print_file_comments();
4504 print_header_prefixes();
4506 print_useful_macros();
4510 print_more_useful_macros ();
4512 for (li = nodes; li != NULL; li = li->next) {
4513 Node *node = li->data;
4514 if (node->type == CCODE_NODE) {
4515 CCode *cc = (CCode *)node;
4516 if (cc->cctype != HT_CCODE &&
4517 cc->cctype != AT_CCODE &&
4518 cc->cctype != AD_CCODE)
4519 print_ccode_block ((CCode *)node);
4520 } else if (node->type == CLASS_NODE) {
4521 print_class_block ((Class *)node);
4522 } else if (node->type == ENUMDEF_NODE) {
4523 print_enum ((EnumDef *)node);
4524 } else if (node->type == FLAGS_NODE) {
4525 print_flags ((Flags *)node);
4526 } else if (node->type == ERROR_NODE) {
4527 print_error ((Error *)node);
4529 g_assert_not_reached();
4533 print_header_postfixes();
4536 static void print_version(void)
4538 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) 2022 Nick Bowler");
4541 puts("License GPLv2+: GNU GPL version 2 or any later version");
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.");
4546 static void print_usage(FILE *f)
4548 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4550 fprintf(f, "Try '%s --help' for more information.\n",
4555 static void print_help(void)
4557 const struct option *opt;
4559 print_usage(stdout);
4561 puts("This is \"GObject Builder\": a simple preprocessor to help with\n"
4562 "implementing GObject types in C.");
4565 for (opt = lopts; opt->name; opt++) {
4566 struct lopt_help help;
4568 /* Don't display obsolete options that don't do anything */
4569 if (!opt->flag && !opt->val)
4572 if (!lopt_get_help(opt, &help))
4575 help_print_option(opt, help.arg, help.desc, 20);
4579 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4583 * Called after getopt_long receives an --m4 argument. Immediately stop
4584 * processing options. Then all non-option arguments seen so far together
4585 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4586 * is false, then M4_FLAGS is inserted before the first non-option argument,
4589 * The resulting string is returned, which should be freed by the caller.
4591 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4593 char **nonopt = NULL, *save_argv0, *ret;
4596 /* First, conclude getopt run and reset with remaining args */
4597 getopt_long(optind, argv, sopts, lopts, NULL);
4602 save_argv0 = argv[0];
4603 argv[0] = M4_COMMANDLINE;
4606 ret = g_strjoinv(" ", argv);
4607 argv[0] = save_argv0;
4611 /* Locate first non-option argument, if any. */
4612 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4614 nonopt = &argv[optind-2];
4619 /* If there is a non-option but the above didn't see it, must be "--" */
4620 if (!nonopt && argv[optind])
4621 nonopt = &argv[optind-2];
4624 /* Found non-option, insert M4_FLAGS just before it. */
4625 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4627 nonopt[1] = M4_FLAGS;
4629 nonopt[0] = g_strjoinv(" ", argv);
4631 nonopt[1] = save_argv[1];
4632 nonopt[2] = save_argv[2];
4633 ret = g_strjoinv(" ", nonopt);
4636 nonopt[0] = save_argv[0];
4638 /* Only options, not inserting M4_FLAGS. */
4639 ret = g_strjoinv(" ", argv);
4642 argv[0] = save_argv0;
4646 static int parse_options(int argc, char **argv)
4648 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4649 char *raw_file_sep = "-";
4653 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4659 output_dir = optarg;
4662 exit_on_warn = TRUE;
4665 raw_file_sep = optarg ? optarg : "";
4671 no_touch = no_touch_headers = TRUE;
4677 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4683 if (optopt == '?') {
4689 /* Rewind getopt to get internal error messages. */
4690 optind = 0, opterr = 1;
4691 while (getopt_long(argc, argv, sopts, lopts, NULL)
4694 case 0: /* no-op or option set by flag */;
4698 filename = argv[optind];
4699 if (argc > optind+1) {
4700 char *s = g_strjoinv(" ", argv+optind+1);
4701 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4702 g_get_prgname(), s);
4708 file_sep = raw_file_sep[0];
4709 if (raw_file_sep[0] && raw_file_sep[1]) {
4710 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4717 printf("%s\n", M4_INCLUDE_DIR);
4725 compare_and_move (const char *old_filename)
4727 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4729 gboolean equal = FALSE;
4731 old_f = fopen (old_filename, "r");
4734 gboolean error = FALSE;
4736 new_f = fopen (new_filename, "r");
4745 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4746 if (ferror (new_f)) {
4748 error_printf (GOB_ERROR, 0,
4749 "Can't read %s: %s",
4751 g_strerror (errno));
4755 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4757 || feof (new_f) != feof (old_f)
4759 || memcmp (new_buf, old_buf, new_n) != 0)
4768 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4769 new_filename, g_strerror (errno));
4777 if (! equal && unlink (old_filename) != 0) {
4778 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4779 old_filename, g_strerror (errno));
4785 if (unlink (new_filename) != 0)
4786 error_printf (GOB_ERROR, 0, "Can't remove %s: %s",
4787 new_filename, g_strerror (errno));
4789 if (rename (new_filename, old_filename) != 0)
4790 error_printf (GOB_ERROR, 0, "Can't rename %s to %s: %s",
4791 new_filename, old_filename,
4792 g_strerror (errno));
4796 g_free (new_filename);
4800 main(int argc, char *argv[])
4804 g_set_prgname(argc > 0 ? argv[0] : "gob2");
4806 rc = parse_options(argc, argv);
4808 print_usage(stderr);
4809 return EXIT_FAILURE;
4810 } else if (rc > 0) {
4811 return EXIT_SUCCESS;
4815 yyin = popen(m4_commandline, "r");
4817 fprintf(stderr, "Error: can't open pipe from '%s'\n",
4821 } else if(filename) {
4822 yyin = fopen(filename, "r");
4824 fprintf(stderr, "Error: can't open file '%s'\n",
4833 /* This is where parsing is done */
4836 error_print (GOB_ERROR, 0, "Parsing errors, quitting");
4838 /* close input file */
4839 if(use_m4) pclose(yyin);
4844 error_print (GOB_ERROR, 0, "no class defined");
4847 exit_on_error = FALSE;
4849 signals = count_signals ((Class *)class);
4850 set_properties = count_set_properties ((Class *)class) +
4851 count_set_arguments ((Class *)class);
4852 get_properties = count_get_properties ((Class *)class) +
4853 count_get_arguments ((Class *)class);
4854 overrides = count_overrides ((Class *)class);
4855 privates = count_privates ((Class *)class);
4856 protecteds = count_protecteds ((Class *)class);
4857 unreftors = count_unreftors ((Class *)class);
4858 destructors = count_destructors ((Class *)class);
4859 initializers = count_initializers ((Class *)class);
4860 glade_widgets = count_glade_widgets ((Class *)class);
4861 overrode_get_type = find_get_type ((Class *)class);
4864 make_inits ((Class *)class);
4866 find_constructor ((Class *)class);
4867 if (user_constructor != NULL)
4868 need_constructor = TRUE;
4870 find_dispose ((Class *)class);
4871 if (unreftors > 0 ||
4872 dispose_handler != NULL ||
4873 user_dispose_method != NULL)
4874 need_dispose = TRUE;
4876 find_finalize ((Class *)class);
4877 if (destructors > 0 ||
4879 user_finalize_method != NULL) {
4880 need_finalize = TRUE;
4883 check_bad_symbols ((Class *)class);
4884 check_duplicate_symbols ((Class *)class);
4885 check_duplicate_overrides ((Class *)class);
4886 check_duplicate_signals_args ((Class *)class);
4887 check_public_new ((Class *)class);
4888 check_vararg ((Class *)class);
4889 check_firstarg ((Class *)class);
4890 check_nonvoidempty ((Class *)class);
4891 check_signal_args ((Class *)class);
4892 check_property_types ((Class *)class);
4893 check_argument_types ((Class *)class);
4894 check_func_arg_checks ((Class *)class);
4895 check_func_attrs ((Class *)class);
4896 check_for_class_destructors ((Class *)class);
4898 exit_on_error = TRUE;
4903 any_special = setup_special_array ((Class *)class, special_array);
4907 generate_outfiles ();
4918 compare_and_move(outfilebase);
4920 if (no_touch_headers) {
4921 compare_and_move(outfilehbase);
4923 compare_and_move(outfilephbase);