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,
35 #include "treefuncs.h"
46 static const char sopts[] = SOPT_STRING;
47 static const struct option lopts[] = {
52 char *filename = NULL;
62 extern GList *include_files;
64 extern GHashTable *gtk_doc_hash;
68 static char *outfilebase;
69 static char *outfilehbase;
70 static char *outfilephbase;
71 static char *funcbase;
72 static char *pfuncbase;
73 static char *macrobase;
75 static char *pmacrois;
76 static char *macrotype;
77 static char *pmacrotype;
78 static char *typebase;
79 static char *ptypebase;
81 char *output_dir = NULL;
85 static int signals = 0; /* number of signals */
86 static int set_properties = 0; /* number of named (set) properties */
87 static int get_properties = 0; /* number of named (get) properties */
88 static int overrides = 0; /* number of override methods */
89 static int privates = 0; /* number of private data members */
90 static int protecteds = 0; /* number of protected methods */
91 static int unreftors = 0; /* number of variable unreffing destructors */
92 static int destructors = 0; /* number of variable non-unreffing destructors */
93 static int initializers = 0; /* number of variable initializers */
94 static int glade_widgets = 0; /* number of glade widgets */
95 static gboolean overrode_get_type = FALSE; /* provided your won _get_type */
97 static gboolean made_aliases = FALSE; /* if we made any shorthand aliases
98 and need the REALLY UGLY HACK to
101 /* the special variable types we need to define */
102 static gboolean special_array[SPECIAL_LAST] = {0};
103 static gboolean any_special = FALSE;
105 static gboolean need_constructor = FALSE;
106 static Method * user_constructor = NULL;
108 static gboolean need_dispose = FALSE;
109 static Method * dispose_handler = NULL;
110 static Method * user_dispose_method = NULL;
112 static gboolean need_finalize = FALSE;
113 static Method * finalize_handler = NULL;
114 static Method * user_finalize_method = NULL;
120 gboolean no_touch = FALSE;
121 gboolean no_touch_headers = FALSE;
122 gboolean for_cpp = FALSE;
123 gboolean no_gnu = FALSE;
124 gboolean exit_on_warn = FALSE;
125 gboolean exit_on_error = TRUE;
126 gboolean got_error = FALSE;
127 gint private_header = PRIVATE_HEADER_ONDEMAND;
128 gboolean no_extern_c = FALSE;
129 gboolean no_write = FALSE;
130 gboolean no_lines = FALSE;
131 gboolean no_self_alias = FALSE;
132 gboolean always_private_struct = FALSE;
133 gboolean gtk3_ok = FALSE;
135 gboolean use_m4 = FALSE; /* preprocess sources with m4 */
136 char *m4_commandline = NULL;
137 #define M4_INCLUDE_DIR PKGDATADIR "/m4"
138 #define M4_BASE_FILENAME "gobm4.m4"
139 #define M4_FLAGS "-P -s -I" M4_INCLUDE_DIR " -DGOBM4_GOB_VERSION=" VERSION " " M4_BASE_FILENAME
140 #define M4_COMMANDLINE "m4"
142 int method_unique_id = 1;
147 filebase = replace_sep (((Class *)class)->otype, file_sep);
148 gob_strdown (filebase);
150 if (output_dir != NULL && output_dir[0] != '\0') {
151 fullfilebase = g_strdup_printf("%s%c%s", output_dir,
152 G_DIR_SEPARATOR, filebase);
154 fullfilebase = g_strdup (filebase);
157 funcbase = replace_sep (((Class *)class)->otype, '_');
158 gob_strdown (funcbase);
160 pfuncbase = replace_sep (((Class *)class)->ptype, '_');
161 gob_strdown (pfuncbase);
163 macrobase = replace_sep (((Class *)class)->otype, '_');
164 gob_strup (macrobase);
166 macrois = make_pre_macro (((Class *)class)->otype, "IS");
167 pmacrois = make_pre_macro (((Class *)class)->ptype, "IS");
169 macrotype = make_pre_macro (((Class *)class)->otype, "TYPE");
170 pmacrotype = make_pre_macro (((Class *)class)->ptype, "TYPE");
172 typebase = remove_sep (((Class *)class)->otype);
174 ptypebase = remove_sep (((Class *)class)->ptype);
178 get_gtk_doc (const char *id)
185 val = g_hash_table_lookup(gtk_doc_hash, id);
187 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
189 val = g_hash_table_lookup(gtk_doc_hash, id);
191 return g_strdup_printf("/**\n * %s_%s:\n%s **/\n",
197 print_type(FILE *fp, const Type *t, gboolean postfix_to_stars)
201 s = get_type(t, postfix_to_stars);
202 out_printf(fp, "%s", s);
208 print_method (FILE *fp,
209 const char *typeprefix,
210 const char *nameprefix,
211 const char *subnameprefix,
212 const char *namepostfix,
213 const char *afterargs,
216 gboolean print_funcattrs,
217 gboolean one_arg_per_line,
218 gboolean no_funcbase,
219 gboolean kill_underscore,
220 gboolean first_unused,
226 out_printf(fp, "%s", typeprefix);
227 print_type(fp, m->mtype, TRUE);
232 out_printf(fp, "%s%s%s%s(",
233 nameprefix, subnameprefix, id, namepostfix);
235 out_printf(fp, "%s%s_%s%s%s(",
236 nameprefix, funcbase, subnameprefix, id,
240 for(li=m->args; li; li=g_list_next(li)) {
241 FuncArg *arg = li->data;
242 const char *unused = "";
245 ! for_cpp && /* g++ has a cow with this */
248 unused = " G_GNUC_UNUSED";
251 print_type(fp, arg->atype, FALSE);
253 out_printf (fp, "___fake___");
255 out_printf(fp, "%s%s%s,%s", arg->name,
256 arg->atype->postfix ?
257 arg->atype->postfix : "",
259 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
261 out_printf(fp, "%s%s%s", arg->name,
262 arg->atype->postfix ?
263 arg->atype->postfix : "",
267 out_printf(fp, ",%s...",
268 one_arg_per_line ? "\n\t\t\t\t\t" : " ");
270 out_printf(fp, "void");
272 /* Slightly icky: sometimes we are called st m->funcattrs
273 hasn't been set, but if so it should be NULL since its been
275 if(print_funcattrs && m->funcattrs != NULL
276 && strlen(m->funcattrs) > 0) {
277 /* To keep the output neat, we trim off the trailing '\n'
278 from the end of funcattrs for a moment. */
279 size_t funcattrs_len = strlen(m->funcattrs);
280 gboolean funcattrs_chomped = FALSE;
281 if((m->funcattrs)[funcattrs_len - 1] == '\n') {
282 m->funcattrs[funcattrs_len - 1] = '\0';
283 funcattrs_chomped = TRUE;
285 out_printf(fp, "%s)\n%s%s", afterargs, m->funcattrs, postfix);
286 /* Put it back like it was (though it shouldn't matter). */
287 if (funcattrs_chomped) {
288 (m->funcattrs)[funcattrs_len - 1] = '\n';
292 out_printf(fp, "%s)%s", afterargs, postfix);
297 any_method_to_alias(Class *c)
301 for(li=c->nodes;li;li=g_list_next(li)) {
302 Node *node = li->data;
303 if(node->type == METHOD_NODE) {
304 Method *m = (Method *)node;
306 if(m->method == INIT_METHOD ||
307 m->method == CLASS_INIT_METHOD ||
308 m->method == CONSTRUCTOR_METHOD ||
309 m->method == DISPOSE_METHOD ||
310 m->method == FINALIZE_METHOD ||
311 m->method == OVERRIDE_METHOD)
322 make_method_aliases (Class *c)
326 for(li = c->nodes; li != NULL; li = li->next) {
327 Node *node = li->data;
328 if(node->type == METHOD_NODE) {
329 Method *m = (Method *)node;
331 if(m->method == INIT_METHOD ||
332 m->method == CLASS_INIT_METHOD ||
333 m->method == CONSTRUCTOR_METHOD ||
334 m->method == DISPOSE_METHOD ||
335 m->method == FINALIZE_METHOD ||
336 m->method == OVERRIDE_METHOD)
339 out_printf (out, "#define self_%s %s_%s\n",
348 add_bad_hack_to_avoid_unused_warnings(const Class *c)
352 /* if we haven't had any methods, just return */
357 out_printf(out, "\n\n#if (!defined __GNUC__) || (defined __GNUC__ && defined __STRICT_ANSI__)\n");
359 "/*REALLY BAD HACK\n"
360 " This is to avoid unused warnings if you don't call\n"
361 " some method. I need to find a better way to do\n"
362 " this, not needed in GCC since we use some gcc\n"
363 " extentions to make saner, faster code */\n"
365 "___%s_really_bad_hack_to_avoid_warnings(void)\n"
367 out_printf(out, "\t((void (*)(void))GET_NEW_VARG)();\n");
368 for(li=c->nodes;li;li=g_list_next(li)) {
369 Node *node = li->data;
370 if(node->type == METHOD_NODE) {
371 Method *m = (Method *)node;
373 if(m->method == INIT_METHOD ||
374 m->method == CLASS_INIT_METHOD ||
375 m->method == CONSTRUCTOR_METHOD ||
376 m->method == DISPOSE_METHOD ||
377 m->method == FINALIZE_METHOD ||
378 m->method == OVERRIDE_METHOD)
381 /* in C++ mode we don't alias new */
382 if(for_cpp && strcmp(m->id, "new")==0)
385 out_printf(out, "\t((void (*)(void))self_%s)();\n", m->id);
388 out_printf(out, "\t___%s_really_bad_hack_to_avoid_warnings();\n",
391 out_printf(out, "}\n#endif /* !__GNUC__ || (__GNUC__ && __STRICT_ANSI__) */\n\n");
393 out_printf(out, "}\n\n");
397 put_variable(const Variable *v, FILE *fp)
399 out_printf(fp, "\t");
400 print_type(fp, v->vtype, FALSE);
401 out_printf(fp, "%s%s;", v->id,
403 v->vtype->postfix:"");
404 if(v->scope == PROTECTED_SCOPE)
405 out_printf(fp, " /* protected */");
406 out_printf(fp, "\n");
410 put_vs_method(const Method *m)
412 if(m->method != SIGNAL_LAST_METHOD &&
413 m->method != SIGNAL_FIRST_METHOD &&
414 m->method != VIRTUAL_METHOD)
417 /* if a signal mark it as such */
418 if(m->method != VIRTUAL_METHOD)
419 print_method(outh, "\t/*signal*/", "(* ", "", ") ", "", ";\n",
420 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
422 print_method(outh, "\t", "(* ", "", ") ", "", ";\n",
423 m, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE);
428 put_pub_method(const Method *m)
430 if(m->scope != PUBLIC_SCOPE)
433 out_addline_infile(outh, m->line_no);
434 print_method(outh, "", "\t", "", "\t", "", ";\n", m,
435 TRUE, TRUE, FALSE, TRUE, FALSE, FALSE);
436 out_addline_outfile(outh);
440 put_signal_macro (const Method *m, gboolean gnu)
442 if(m->method != SIGNAL_LAST_METHOD &&
443 m->method != SIGNAL_FIRST_METHOD)
448 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
449 "g_signal_connect(%s(object),\"%s\","
450 "(GCallback)(func),(data))\n",
451 funcbase, m->id, macrobase, m->id);
454 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
455 "g_signal_connect_after(%s(object),\"%s\","
456 "(GCallback)(func),(data))\n",
457 funcbase, m->id, macrobase, m->id);
460 out_printf (outh, "#define %s_connect_data__%s"
461 "(object,func,data,destroy_data,flags)\t"
462 "g_signal_connect_data(%s(object),\"%s\","
463 "(GCallback)(func),(data),(destroy_data),(GConnectFlags)(flags))\n",
464 funcbase, m->id, macrobase, m->id);
467 out_printf (outh, "#define %s_connect__%s(object,func,data)\t"
469 "%s(__extension__ ({%s *___object = (object); ___object; })),"
471 "(GCallback) __extension__ ({",
472 funcbase, m->id, macrobase, typebase, m->id);
473 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
474 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
475 out_printf (outh, "___%s; }), (data))\n", m->id);
478 out_printf (outh, "#define %s_connect_after__%s(object,func,data)\t"
479 "g_signal_connect_after("
480 "%s(__extension__ ({%s *___object = (object); ___object; })),"
482 "(GCallback) __extension__ ({",
483 funcbase, m->id, macrobase, typebase, m->id);
484 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
485 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
486 out_printf (outh, "___%s; }), (data))\n", m->id);
489 out_printf (outh, "#define %s_connect_data__%s"
490 "(object,func,data,destroy_data,flags)\t"
491 "g_signal_connect_data("
492 "%s(__extension__ ({%s *___object = (object); ___object; })),"
494 "(GCallback) __extension__ ({",
495 funcbase, m->id, macrobase, typebase, m->id);
496 print_method (outh, "", "(* ___", "", ") ", ", gpointer ___data ",
497 " = (func); ", m, FALSE, FALSE, TRUE, TRUE, FALSE, TRUE);
498 out_printf (outh, "___%s; }), (data), (destroy_data), (GConnectFlags)(flags))\n", m->id);
503 put_signal_macros (const Class *c, gboolean gnu)
510 for (li = c->nodes; li != NULL; li = li->next) {
511 const Node *n = li->data;
512 if (n->type == METHOD_NODE)
513 put_signal_macro ((Method *)n, gnu);
518 put_local_signal_macro (const Method *m)
520 if(m->method != SIGNAL_LAST_METHOD &&
521 m->method != SIGNAL_FIRST_METHOD)
525 out_printf (out, "#define self_connect__%s(object,func,data)\t"
526 "%s_connect__%s((object),(func),(data))\n",
527 m->id, funcbase, m->id);
530 out_printf (out, "#define self_connect_after__%s(object,func,data)\t"
531 "%s_connect_after__%s((object),(func),(data))\n",
532 m->id, funcbase, m->id);
535 out_printf (out, "#define self_connect_data__%s(object,func,data,destroy_data,flags)\t"
536 "%s_connect_data__%s((object),(func),(data),(destroy_data),(flags))\n",
537 m->id, funcbase, m->id);
541 put_local_signal_macros (const Class *c)
548 for (li = c->nodes; li != NULL; li = li->next) {
549 const Node *n = li->data;
550 if (n->type == METHOD_NODE)
551 put_local_signal_macro ((Method *)n);
557 put_prot_method(const Method *m)
561 if(m->scope != PROTECTED_SCOPE)
564 f = outph ? outph : out;
566 out_addline_infile(f, m->line_no);
567 print_method(f, "", "\t", "", "\t", "", ";\n",
568 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
569 out_addline_outfile(f);
573 put_priv_method_prot(const Method *m)
575 if(m->method == SIGNAL_LAST_METHOD ||
576 m->method == SIGNAL_FIRST_METHOD ||
577 m->method == VIRTUAL_METHOD) {
580 "static ", "___real_", "", " ", "", ";\n",
581 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
583 /* no else, here, it might still have a private prototype, it's not
586 if((m->method == OVERRIDE_METHOD &&
589 char *s = g_strdup_printf("___%x_", (guint)m->unique_id);
591 out_addline_infile(out, m->line_no);
592 print_method(out, "static ", s, "", " ", "",
593 no_gnu?";\n":" G_GNUC_UNUSED;\n",
594 m, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE);
596 out_addline_outfile(out);
598 } else if(m->scope == PRIVATE_SCOPE ||
599 m->method == INIT_METHOD ||
600 m->method == CLASS_INIT_METHOD ||
601 m->method == CONSTRUCTOR_METHOD ||
602 m->method == DISPOSE_METHOD ||
603 m->method == FINALIZE_METHOD) {
605 out_addline_infile(out, m->line_no);
606 print_method(out, "static ", "", "", " ", "",
607 no_gnu?";\n":" G_GNUC_UNUSED;\n",
608 m, TRUE, FALSE, FALSE, TRUE, FALSE, FALSE);
610 out_addline_outfile(out);
615 make_func_arg (const char *typename, gboolean is_class, const char *name)
622 tn = g_strconcat (typename, ":Class", NULL);
624 tn = g_strdup (typename);
626 type = node_new (TYPE_NODE,
630 node = node_new (FUNCARG_NODE,
631 "atype:steal", (Type *)type,
634 return g_list_prepend (NULL, node);
638 make_inits(Class *cl)
640 int got_class_init = FALSE;
641 int got_init = FALSE;
644 for(li=cl->nodes;li;li=g_list_next(li)) {
646 if(n->type == METHOD_NODE) {
647 Method *m = (Method *)n;
648 if(m->method == INIT_METHOD) {
650 error_print(GOB_ERROR, m->line_no, "init defined more then once");
652 } else if(m->method == CLASS_INIT_METHOD) {
654 error_print(GOB_ERROR, m->line_no, "class_init defined more then once");
655 got_class_init = TRUE;
659 if(!got_class_init) {
660 Type *type = (Type *)node_new (TYPE_NODE,
663 node = node_new (METHOD_NODE,
665 "method", CLASS_INIT_METHOD,
668 "args:steal", make_func_arg (cl->otype,
671 "unique_id", method_unique_id++,
673 cl->nodes = g_list_prepend(cl->nodes, node);
676 Type *type = (Type *)node_new (TYPE_NODE,
679 node = node_new (METHOD_NODE,
681 "method", INIT_METHOD,
684 "args:steal", make_func_arg (cl->otype,
685 FALSE /* is_class */,
687 "unique_id", method_unique_id++,
689 cl->nodes = g_list_prepend(cl->nodes, node);
694 find_method(const Class *cl, int method, const char *id)
698 for(li=cl->nodes;li;li=g_list_next(li)) {
700 if(n->type == METHOD_NODE) {
701 Method *m = (Method *)n;
702 if (m->method == method
703 && (id == NULL || strcmp(m->id, id)==0))
712 find_constructor(const Class *cl)
714 user_constructor = find_method(cl, CONSTRUCTOR_METHOD, NULL);
718 find_dispose(const Class *cl)
720 dispose_handler = find_method(cl, OVERRIDE_METHOD, "dispose");
721 if (dispose_handler != NULL) {
722 if(strcmp(dispose_handler->otype, "G:Object") != 0)
723 error_print(GOB_ERROR, dispose_handler->line_no,
724 "dispose method override "
725 "of class other then "
727 if(g_list_length(dispose_handler->args) != 1)
728 error_print(GOB_ERROR, dispose_handler->line_no,
729 "dispose method override "
730 "with more then one "
734 user_dispose_method = find_method(cl, DISPOSE_METHOD, NULL);
738 find_finalize(const Class *cl)
740 finalize_handler = find_method(cl, OVERRIDE_METHOD, "finalize");
741 if (finalize_handler != NULL) {
742 if(strcmp(finalize_handler->otype, "G:Object") != 0)
743 error_print(GOB_ERROR, finalize_handler->line_no,
744 "finalize method override "
745 "of class other then "
747 if(g_list_length(finalize_handler->args) != 1)
748 error_print(GOB_ERROR, finalize_handler->line_no,
749 "finalize method override "
750 "with more then one "
754 user_finalize_method = find_method(cl, FINALIZE_METHOD, NULL);
758 /* hash of method -> name of signal prototype */
759 static GHashTable *marsh = NULL;
761 /* list of methods with different signal prototypes,
762 we check this list if we can use a signal prototype of a
763 previous signal method, there are only uniques here */
764 static GList *eq_signal_methods = NULL;
766 /* compare a list of strings */
768 is_list_equal(const GList *a, const GList *b)
770 for(;a && b; a=a->next, b=b->next) {
771 if(strcmp(a->data, b->data)!=0) {
775 /* the the lists were different length */
782 find_same_type_signal(const Method *m)
785 for(li=eq_signal_methods;li;li=li->next) {
786 Method *mm = li->data;
787 if(is_list_equal(mm->gtktypes, m->gtktypes))
794 print_signal_marsal_args (const Method *m)
796 if (strcmp (m->gtktypes->next->data, "NONE") != 0) {
799 for (i = 0, li = m->gtktypes->next;
801 i++, li = li->next) {
804 if (strcmp (li->data, "UNICHAR") == 0)
805 /* hack because glib is braindamaged */
806 get_func = g_strdup ("g_value_get_uint");
807 else if (strncmp(li->data, "BOXED_", 6) == 0)
808 get_func = g_strdup ("g_value_get_boxed");
810 get_func = g_strdup_printf
811 ("g_value_get_%s", (char *)li->data);
813 gob_strdown (get_func);
814 out_printf (out, ",\n\t\t(%s) "
815 "%s (param_values + %d)",
816 get_cast (li->data, FALSE),
821 out_printf (out, ",\n\t\tdata2);\n");
826 add_signal_prots(Method *m)
832 gboolean ret_none = FALSE;
833 gboolean arglist_none = FALSE;
835 const char *unused = "";
837 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
838 unused = " G_GNUC_UNUSED";
841 if (m->method != SIGNAL_LAST_METHOD &&
842 m->method != SIGNAL_FIRST_METHOD)
846 marsh = g_hash_table_new(NULL, NULL);
848 g_assert (m->gtktypes->next != NULL);
850 ret_none = strcmp(m->gtktypes->data, "NONE") == 0;
851 arglist_none = strcmp(m->gtktypes->next->data, "NONE") == 0;
853 if (ret_none && arglist_none)
856 /* if we already did a signal prototype just use that */
857 mm = find_same_type_signal (m);
859 s = g_hash_table_lookup (marsh, mm);
860 g_hash_table_insert (marsh, m, s);
867 retcast = get_cast (m->gtktypes->data, FALSE);
869 s = g_strdup_printf("Sig%d", sig++);
871 g_hash_table_insert(marsh, m, s);
872 eq_signal_methods = g_list_prepend(eq_signal_methods, m);
874 /* we know that we'll know all the gtktypes (so get_cast can't fail) */
875 out_printf(out, "\ntypedef %s (*___%s) (%s *, ",
876 get_cast(m->gtktypes->data, FALSE), s, typebase);
878 if ( ! arglist_none) {
879 for (li = m->gtktypes->next; li != NULL; li = li->next)
880 out_printf (out, "%s, ", get_cast (li->data, FALSE));
882 out_printf (out, "gpointer);\n");
884 out_printf (out, "\nstatic void\n"
885 "___marshal_%s (GClosure *closure,\n"
886 "\tGValue *return_value%s,\n"
887 "\tguint n_param_values,\n"
888 "\tconst GValue *param_values,\n"
889 "\tgpointer invocation_hint%s,\n"
890 "\tgpointer marshal_data)\n"
897 out_printf (out, "\t%s v_return;\n", retcast);
899 out_printf (out, "\tregister ___%s callback;\n"
900 "\tregister GCClosure *cc = (GCClosure*) closure;\n"
901 "\tregister gpointer data1, data2;\n\n",
904 out_printf (out, "\tg_return_if_fail (n_param_values == %d);\n\n",
905 arglist_none ? 1 : g_list_length (m->gtktypes));
908 "\tif (G_CCLOSURE_SWAP_DATA (closure)) {\n"
909 "\t\tdata1 = closure->data;\n"
910 "\t\tdata2 = g_value_peek_pointer (param_values + 0);\n"
912 "\t\tdata1 = g_value_peek_pointer (param_values + 0);\n"
913 "\t\tdata2 = closure->data;\n"
916 out_printf (out, "\tcallback = (___%s) "
917 "(marshal_data != NULL ? marshal_data : cc->callback);"
921 out_printf (out, "\tcallback ((%s *)data1", typebase);
923 out_printf (out, "\tv_return = callback ((%s *)data1",
927 print_signal_marsal_args (m);
930 /* FIXME: This code is so fucking ugly it hurts */
931 gboolean take_ownership =
932 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
933 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
937 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
938 /* hack because glib is braindamaged */
939 set_func = g_strdup ("g_value_set_uint");
941 set_func = g_strdup_printf ("g_value_%s_%s",
944 (char *)m->gtktypes->data);
945 gob_strdown (set_func);
947 out_printf (out, "\n\t%s (return_value, v_return);\n",
952 if (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */) {
954 out_printf (out, "\n\treturn_value = NULL;\n");
955 out_printf (out, "\tinvocation_hint = NULL;\n");
958 out_printf (out, "}\n\n");
962 interface_type(const char *if_name)
964 char *rawtype = remove_sep(if_name);
965 char *end = "", *typename;
969 * EEEK! evil, we should have some sort of option
970 * to force this for arbitrary interfaces, since
971 * some are Class and some are Iface. Glib is shite
975 if (strcmp (rawtype, "GtkEditable") == 0
976 || strcmp (rawtype, "GTypePlugin") == 0)
980 /* We'll assume Iface is the standard ending */
984 /* GTK3 doesn't need Iface end */
988 typename = g_strconcat(rawtype, end, (char *)NULL);
995 define_parent_interface_refs(Class *c)
1002 out_printf(out, "\n/* parent class interface implementations */\n");
1003 for (li = c->interfaces; li != NULL; li = li->next) {
1004 char *name = replace_sep(li->data, '_');
1005 char *type = interface_type(li->data);
1007 out_printf (out, "static %s *%s_parent_iface;\n", type, name);
1018 out_printf(out, "\n");
1020 out_printf(out, "enum {\n");
1021 for(li=c->nodes;li;li=g_list_next(li)) {
1023 if(n->type == METHOD_NODE) {
1024 Method *m = (Method *)n;
1025 if(m->method == SIGNAL_LAST_METHOD ||
1026 m->method == SIGNAL_FIRST_METHOD) {
1027 char *s = g_strdup(m->id);
1029 out_printf(out, "\t%s_SIGNAL,\n", s);
1034 out_printf(out, "\tLAST_SIGNAL\n};\n\n");
1036 if (set_properties > 0 ||
1037 get_properties > 0) {
1038 out_printf(out, "enum {\n\tPROP_0");
1039 for(li=c->nodes;li;li=g_list_next(li)) {
1041 if (n->type == PROPERTY_NODE) {
1042 Property *p = (Property *)n;
1043 char *s = g_strdup (p->name);
1045 out_printf (out, ",\n\tPROP_%s", s);
1047 } else if (n->type == ARGUMENT_NODE) {
1048 Argument *a = (Argument *)n;
1049 char *s = g_strdup(a->name);
1051 out_printf(out, ",\n\tPROP_%s", s);
1055 out_printf(out, "\n};\n\n");
1060 "static guint object_signals[LAST_SIGNAL] = {0};\n\n");
1062 out_printf(out, "/* pointer to the class of our parent */\n");
1063 out_printf(out, "static %sClass *parent_class = NULL;\n", ptypebase);
1064 define_parent_interface_refs(c);
1065 out_printf(out, "\n");
1069 add_interface_methods (Class *c, const char *interface)
1072 gboolean added_line = FALSE;
1074 for (li = c->nodes; li != NULL; li = li->next) {
1076 Method *m = (Method *)n;
1077 if (n->type != METHOD_NODE ||
1078 m->method == OVERRIDE_METHOD ||
1079 m->interface == NULL ||
1080 strcmp (m->interface, interface) != 0)
1083 if (m->line_no > 0) {
1084 out_addline_infile (out, m->line_no);
1086 } else if (m->line_no == 0 &&
1088 out_addline_outfile (out);
1091 out_printf (out, "\tiface->%s = self_%s;\n",
1095 out_addline_outfile (out);
1099 add_interface_inits(Class *c)
1103 if (c->interfaces == NULL)
1106 out_printf(out, "\n");
1108 for (li = c->interfaces; li != NULL; li = li->next) {
1109 char *name = replace_sep(li->data, '_');
1110 char *type = interface_type(li->data);
1112 out_printf(out, "static void\n"
1113 "___%s_init (%s *iface)\n"
1116 add_interface_methods(c, li->data);
1118 out_printf(out, "\t%s_parent_iface\n", name);
1119 out_printf(out, for_cpp ? "\t\t= (%s *)" : "\t\t= ", type);
1120 out_printf(out, "g_type_interface_peek_parent(iface);\n"
1129 add_interface_infos(Class *c, gboolean static_storage)
1133 for (li = c->interfaces; li; li = li->next) {
1134 char *name = replace_sep(li->data, '_');
1135 out_printf(out, "\t%sconst GInterfaceInfo %s_info = {\n"
1136 "\t\t(GInterfaceInitFunc) ___%s_init,\n"
1140 static_storage ? "static " : "",
1145 out_printf(out, "\n");
1149 define_add_interfaces(Class *c)
1156 out_printf(out, "static void ___add_interfaces(GType type)\n{\n");
1157 add_interface_infos(c, TRUE);
1159 for (li = c->interfaces; li; li = li->next) {
1160 char *type = make_pre_macro(li->data, "TYPE");
1161 char *name = replace_sep(li->data, '_');
1163 out_printf(out, "\tg_type_add_interface_static\n"
1174 out_printf(out, "}\n\n");
1178 define_dynamic_add_interfaces(Class *c)
1185 out_printf(out, "static void ___add_interfaces"
1186 "(GTypeModule *type_module, GType type)\n"
1188 add_interface_infos(c, FALSE);
1191 * Hack to work around bug in g_type_module_add_interface,
1192 * which will fail to add an interface to types that derive
1193 * from something that also implements the same interface.
1195 * The actual GType system does not have any such problem,
1196 * and the GTypeModule implementation details relied upon
1197 * here have not changed once since the feature was first
1198 * implemented almost 20 years ago.
1200 out_printf(out, "\tstruct _ModuleInterfaceInfo {\n"
1201 "\t\tgboolean loaded;\n"
1202 "\t\tGType instance_type;\n"
1203 "\t\tGType interface_type;\n"
1204 "\t\tGInterfaceInfo info;\n"
1207 for (li = c->interfaces; li; li = li->next) {
1208 char *type = make_pre_macro(li->data, "TYPE");
1209 char *name = replace_sep(li->data, '_');
1211 out_printf(out, "\n"
1212 "\tmodinfo = g_malloc(sizeof *modinfo);\n"
1213 "\tmodinfo->loaded = TRUE;\n"
1214 "\tmodinfo->instance_type = type;\n"
1215 "\tmodinfo->interface_type = %s;\n"
1216 "\tmodinfo->info = %s_info;\n"
1217 "\tg_type_add_interface_dynamic\n"
1218 "\t\t( modinfo->instance_type\n"
1219 "\t\t, modinfo->interface_type\n"
1220 "\t\t, G_TYPE_PLUGIN(type_module)\n"
1222 "\ttype_module->interface_infos = g_slist_prepend\n"
1223 "\t\t( type_module->interface_infos\n"
1232 out_printf(out, "}\n\n");
1235 static void define_add_privates(Class *c)
1237 const char *addprivate = c->dynamic
1238 ? "G_ADD_PRIVATE_DYNAMIC"
1244 out_printf(out, "#ifdef %s\n"
1245 "#define ___add_privates() %s(%s)\n"
1247 "#define ___add_privates()\n"
1249 addprivate, addprivate, typebase);
1252 static void add_type_info(void)
1254 out_printf(out, "\tstatic const GTypeInfo info = {\n"
1255 "\t\tsizeof (%sClass),\n"
1256 "\t\t(GBaseInitFunc) NULL,\n"
1257 "\t\t(GBaseFinalizeFunc) NULL,\n"
1258 "\t\t(GClassInitFunc) %s_class_init,\n"
1259 "\t\t(GClassFinalizeFunc) NULL,\n"
1260 "\t\tNULL /* class_data */,\n"
1261 "\t\tsizeof (%s),\n"
1262 "\t\t%d /* n_preallocs */,\n"
1263 "\t\t(GInstanceInitFunc) %s_init,\n"
1266 typebase, funcbase, typebase, npreallocs, funcbase);
1272 Class *c = (Class *)class;
1274 define_add_interfaces(c);
1275 define_add_privates(c);
1277 out_printf(out, "#ifdef G_DEFINE_TYPE_EXTENDED\n\n"
1278 "G_DEFINE_TYPE_EXTENDED(%s, %s, %s,\n"
1279 "\t(GTypeFlags)%s,\n",
1280 typebase, funcbase, pmacrotype,
1281 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1284 out_printf(out, "\t___add_privates();\n");
1287 out_printf(out, "\t___add_interfaces(g_define_type_id);\n");
1289 /* Fallback for GLib < 2.4 */
1290 out_printf(out, ");\n\n"
1292 "GType %s_get_type(void)\n"
1294 "\tstatic GType type = 0;\n",
1299 out_printf(out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1300 "\t\ttype = g_type_register_static\n"
1304 "\t\t\t, (GTypeFlags)%s\n"
1306 pmacrotype, typebase,
1307 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1310 out_printf(out, "\t\t___add_interfaces(type);\n");
1312 out_printf(out, "\t}\n\n"
1319 add_dynamic_get_type(void)
1321 Class *c = (Class *)class;
1323 define_dynamic_add_interfaces(c);
1324 define_add_privates(c);
1327 * G_DEFINE_DYNAMIC_TYPE_EXTENDED is usable if available, except for
1328 * some reason it defines an xxx_register_type function with internal
1329 * linkage. This is kind of weird so we have to work around that.
1331 out_printf(out, "#ifdef G_DEFINE_DYNAMIC_TYPE_EXTENDED\n\n"
1332 "static void %s_class_finalize(%sClass *c) { }\n\n"
1333 "#define %s_register_type ___register_type\n",
1334 funcbase, typebase, funcbase);
1336 out_printf(out, "G_DEFINE_DYNAMIC_TYPE_EXTENDED(%s, %s, %s,\n"
1337 "\t(GTypeFlags)%s,\n",
1338 typebase, funcbase, pmacrotype,
1339 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1342 out_printf(out, "\t___add_privates();\n");
1344 if (c->interfaces) {
1345 out_printf(out, "\t___add_interfaces"
1346 "(type_module, %s_type_id);\n", funcbase);
1349 out_printf(out, ");\n"
1350 "#undef %s_register_type\n\n"
1351 "void %s_register_type(GTypeModule *type_module)\n"
1353 "\t___register_type(type_module);\n"
1355 funcbase, funcbase);
1357 /* Fallback for GLib < 2.14 */
1358 out_printf(out, "#else\n\n"
1359 "static GType %s_type_id;\n\n"
1360 "GType %s_get_type(void)\n"
1362 "\treturn %s_type_id;\n"
1364 funcbase, funcbase, funcbase);
1366 out_printf(out, "void %s_register_type(GTypeModule *type_module)\n"
1372 out_printf(out, "\t%s_type_id = g_type_module_register_type\n"
1373 "\t\t( type_module\n"
1377 "\t\t, (GTypeFlags)%s\n"
1379 funcbase, pmacrotype, typebase,
1380 c->abstract ? "G_TYPE_FLAG_ABSTRACT" : "0");
1382 if (c->interfaces) {
1383 out_printf(out, "\t___add_interfaces"
1384 "(type_module, %s_type_id);\n",
1388 out_printf(out, "}\n\n"
1393 add_bonobo_object_get_type(void)
1395 Class *c = (Class *)class;
1397 define_add_interfaces(c);
1399 out_printf (out, "GType %s_get_type(void)\n"
1401 "\tstatic GType type = 0;\n",
1406 out_printf (out, "\tif ___GOB_UNLIKELY(type == 0) {\n"
1407 "\t\ttype = bonobo_type_unique\n"
1408 "\t\t\t( BONOBO_OBJECT_TYPE\n"
1409 "\t\t\t, POA_%s__init, NULL\n"
1410 "\t\t\t, G_STRUCT_OFFSET (%sClass, _epv)\n"
1414 c->bonobo_object_class, typebase, typebase);
1416 if (((Class *)class)->interfaces)
1417 out_printf(out, "\t\t___add_interfaces(type);\n");
1419 out_printf(out, "\t}\n\n"
1425 add_overrides(Class *c, const char *oname,
1426 gboolean did_base_obj)
1432 done = g_hash_table_new (g_str_hash, g_str_equal);
1434 s = g_strdup ("GObject");
1435 g_hash_table_insert (done, s, s);
1437 for (li = c->nodes; li != NULL; li = li->next) {
1440 Method *m = (Method *)n;
1441 if(n->type != METHOD_NODE ||
1442 m->method != OVERRIDE_METHOD)
1445 s = remove_sep(m->otype);
1447 if(g_hash_table_lookup(done, s)) {
1451 g_hash_table_insert(done, s, s);
1453 f = replace_sep(m->otype, '_');
1456 out_printf(out, "\t%sClass *%s_class = (%sClass *)%s;\n",
1461 g_hash_table_foreach (done, (GHFunc)g_free, NULL);
1462 g_hash_table_destroy (done);
1466 make_run_signal_flags(Method *m, gboolean last)
1481 gs = g_string_new(NULL);
1484 g_string_assign(gs, "G_SIGNAL_RUN_LAST");
1486 g_string_assign(gs, "G_SIGNAL_RUN_FIRST");
1488 if(m->scope == PUBLIC_SCOPE)
1489 g_string_append(gs, " | G_SIGNAL_ACTION");
1491 for(li = m->flags; li; li = li->next) {
1492 char *flag = li->data;
1494 for(i=0;flags[i];i++) {
1495 if(strcmp(flags[i], flag)==0)
1498 /* if we haven't found it in our list */
1500 error_printf(GOB_WARN, m->line_no,
1501 "Unknown flag '%s' used, "
1502 "perhaps it was misspelled",
1505 g_string_append_printf(gs, " | G_SIGNAL_%s", flag);
1509 char *ret = gs->str;
1510 g_string_free(gs, FALSE);
1517 add_signals(Class *c)
1521 out_printf(out, "\n");
1522 for(li=c->nodes;li;li=g_list_next(li)) {
1524 char *mar, *sig, *flags;
1525 gboolean is_none, last = FALSE;
1526 Method *m = (Method *)n;
1528 if(n->type != METHOD_NODE ||
1529 (m->method != SIGNAL_FIRST_METHOD &&
1530 m->method != SIGNAL_LAST_METHOD))
1533 if(m->method == SIGNAL_FIRST_METHOD)
1538 if(g_hash_table_lookup(marsh, m))
1539 mar = g_strconcat("___marshal_",
1540 (char *)g_hash_table_lookup(marsh, m),
1543 mar = g_strdup("g_cclosure_marshal_VOID__VOID");
1545 is_none = (strcmp(m->gtktypes->next->data, "NONE")==0);
1547 sig = g_strdup (m->id);
1549 flags = make_run_signal_flags (m, last);
1550 out_printf (out, "\tobject_signals[%s_SIGNAL] =\n"
1551 "\t\tg_signal_new (%s,\n"
1552 "\t\t\tG_TYPE_FROM_CLASS (g_object_class),\n"
1553 "\t\t\t(GSignalFlags)(%s),\n"
1554 "\t\t\tG_STRUCT_OFFSET (%sClass, %s),\n"
1555 "\t\t\tNULL, NULL,\n"
1557 "\t\t\tG_TYPE_%s, %d",
1558 sig, m->signal_name /*m->id* if not given signal_name*/,
1560 typebase, m->id, mar,
1561 (char *)m->gtktypes->data,
1562 is_none ? 0 : g_list_length(m->gtktypes->next));
1570 for(l = m->gtktypes->next; l != NULL; l = l->next) {
1571 char *str = l->data;
1572 if (strncmp (str, "BOXED_", 6) == 0)
1573 t = g_strdup (&(str[6]));
1575 t = g_strconcat ("G_TYPE_", str, NULL);
1576 out_printf (out, ",\n\t\t\t%s", t);
1581 out_printf(out, ");\n");
1583 if(strcmp(m->gtktypes->data, "NONE") != 0 ||
1586 out_printf(out, "\tif ___GOB_UNLIKELY(");
1587 if(strcmp(m->gtktypes->data, "NONE") != 0) {
1588 out_printf(out, "sizeof(");
1589 print_type(out, m->mtype, FALSE);
1590 out_printf(out, "%s",
1592 m->mtype->postfix : "");
1593 out_printf(out, ") != sizeof(%s) || ",
1594 get_cast(m->gtktypes->data, FALSE));
1597 for(al = m->args->next, gl = m->gtktypes->next;
1598 al != NULL && gl != NULL;
1599 al = al->next, gl = gl->next) {
1600 FuncArg *arg = al->data;
1601 char *gtkarg = gl->data;
1603 out_printf(out, "sizeof(");
1604 print_type(out, arg->atype, FALSE);
1605 out_printf(out, "%s",
1606 arg->atype->postfix ?
1607 arg->atype->postfix : "");
1608 out_printf(out, ") != sizeof(%s) || ",
1609 get_cast(gtkarg, FALSE));
1613 "parent_class == NULL /* avoid warning */");
1615 out_printf(out, ") {\n"
1616 "\t\tg_error(\"%s line %d: Type mismatch "
1617 "of \\\"%s\\\" signal signature\");\n"
1619 filename, m->line_no, m->id);
1626 set_def_handlers(Class *c, const char *oname)
1629 gboolean set_line = FALSE;
1631 out_printf(out, "\n");
1632 for(li = c->nodes; li; li = g_list_next(li)) {
1634 Method *m = (Method *)n;
1636 if(n->type != METHOD_NODE ||
1637 (m->method != SIGNAL_FIRST_METHOD &&
1638 m->method != SIGNAL_LAST_METHOD &&
1639 m->method != VIRTUAL_METHOD &&
1640 m->method != OVERRIDE_METHOD))
1643 if(m->line_no > 0 && m->cbuf) {
1644 out_addline_infile(out, m->line_no);
1646 } else if(set_line) {
1647 out_addline_outfile(out);
1652 if (m->method == OVERRIDE_METHOD) {
1654 s = replace_sep (m->otype, '_');
1658 dispose_handler != NULL &&
1659 strcmp (m->id, "dispose") == 0)
1660 out_printf (out, "\tg_object_class->dispose "
1662 else if (need_finalize &&
1664 strcmp(m->id, "finalize") == 0)
1666 "\tg_object_class->finalize = ___finalize;\n");
1667 else if (m->cbuf != NULL)
1669 "\t%s_class->%s = ___%x_%s_%s;\n",
1670 s, m->id, (guint)m->unique_id,
1673 out_printf(out, "\t%s_class->%s = NULL;\n",
1677 out_printf(out, "\t%s->%s = ___real_%s_%s;\n",
1681 out_printf(out, "\t%s->%s = NULL;\n",
1686 out_addline_outfile(out);
1690 make_argument (Argument *a)
1695 char *argflags[] = {
1703 flags = g_string_new ("(GParamFlags)(");
1705 if(a->get && a->set)
1706 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1708 g_string_append (flags, "G_PARAM_READABLE");
1710 g_string_append (flags, "G_PARAM_WRITABLE");
1712 g_assert(a->get || a->set);
1714 for (l = a->flags; l != NULL; l = l->next) {
1715 char *flag = l->data;
1717 if(strcmp (flag, "READABLE") == 0 ||
1718 strcmp (flag, "WRITABLE") == 0) {
1719 error_print(GOB_WARN, a->line_no,
1721 "WRITABLE argument flags are "
1722 "set automatically");
1725 for(i = 0; argflags[i]; i++) {
1726 if(strcmp(argflags[i], flag)==0)
1729 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1732 g_string_append (flags, ")");
1734 s = g_strdup(a->name);
1736 if (!strcmp (a->gtktype, "ENUM"))
1737 out_printf(out, "\tparam_spec = g_param_spec_enum (\"%s\", NULL, NULL,\n"
1738 "\t\tG_TYPE_ENUM, 0,\n"
1740 a->name, flags->str);
1741 if (!strcmp (a->gtktype, "FLAGS"))
1742 out_printf(out, "\tparam_spec = g_param_spec_flags (\"%s\", NULL, NULL,\n"
1743 "\t\tG_TYPE_FLAGS, 0,\n"
1745 a->name, flags->str);
1746 else if (!strcmp (a->gtktype, "OBJECT"))
1747 out_printf(out, "\tparam_spec = g_param_spec_object (\"%s\", NULL, NULL,\n"
1748 "\t\tG_TYPE_OBJECT,\n"
1750 a->name, flags->str);
1751 else if (!strcmp (a->gtktype, "STRING"))
1752 out_printf(out, "\tparam_spec = g_param_spec_string (\"%s\", NULL, NULL,\n"
1755 a->name, flags->str);
1756 else if (!strcmp (a->gtktype, "INT"))
1757 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1758 "\t\tG_MININT, G_MAXINT,\n"
1761 a->name, flags->str);
1762 else if (!strcmp (a->gtktype, "UINT"))
1763 out_printf(out, "\tparam_spec = g_param_spec_uint (\"%s\", NULL, NULL,\n"
1764 "\t\t0, G_MAXUINT,\n"
1767 a->name, flags->str);
1768 else if (!strcmp (a->gtktype, "INT"))
1769 out_printf(out, "\tparam_spec = g_param_spec_int (\"%s\", NULL, NULL,\n"
1770 "\t\tG_MININT, G_MAXINT,\n"
1773 a->name, flags->str);
1774 else if (!strcmp (a->gtktype, "CHAR"))
1775 out_printf(out, "\tparam_spec = g_param_spec_char (\"%s\", NULL, NULL,\n"
1779 a->name, flags->str);
1780 else if (!strcmp (a->gtktype, "UCHAR"))
1781 out_printf(out, "\tparam_spec = g_param_spec_uchar (\"%s\", NULL, NULL,\n"
1785 a->name, flags->str);
1786 else if (!strcmp (a->gtktype, "BOOL") ||
1787 !strcmp (a->gtktype, "BOOLEAN"))
1788 out_printf(out, "\tparam_spec = g_param_spec_boolean (\"%s\", NULL, NULL,\n"
1791 a->name, flags->str);
1792 else if (!strcmp (a->gtktype, "LONG"))
1793 out_printf(out, "\tparam_spec = g_param_spec_long (\"%s\", NULL, NULL,\n"
1794 "\t\tG_MINLONG, G_MAXLONG,\n"
1797 a->name, flags->str);
1798 else if (!strcmp (a->gtktype, "ULONG"))
1799 out_printf(out, "\tparam_spec = g_param_spec_ulong (\"%s\", NULL, NULL,\n"
1800 "\t\t0, G_MAXULONG,\n"
1803 a->name, flags->str);
1804 else if (!strcmp (a->gtktype, "INT64"))
1805 out_printf(out, "\tparam_spec = g_param_spec_int64 (\"%s\", NULL, NULL,\n"
1806 "\t\tG_MININT64, G_MAXINT64,\n"
1809 a->name, flags->str);
1810 else if (!strcmp (a->gtktype, "UINT64"))
1811 out_printf(out, "\tparam_spec = g_param_spec_uint64 (\"%s\", NULL, NULL,\n"
1812 "\t\t0, G_MAXUINT64,\n"
1815 a->name, flags->str);
1816 else if (!strcmp (a->gtktype, "FLOAT"))
1817 out_printf(out, "\tparam_spec = g_param_spec_float (\"%s\", NULL, NULL,\n"
1818 "\t\t-G_MAXFLOAT, G_MAXFLOAT,\n"
1821 a->name, flags->str);
1822 else if (!strcmp (a->gtktype, "DOUBLE"))
1823 out_printf(out, "\tparam_spec = g_param_spec_double (\"%s\", NULL, NULL,\n"
1824 "\t\t-G_MAXDOUBLE, G_MAXDOUBLE,\n"
1827 a->name, flags->str);
1828 else if (!strcmp (a->gtktype, "POINTER"))
1829 out_printf(out, "\tparam_spec = g_param_spec_pointer (\"%s\", NULL, NULL,\n"
1831 a->name, flags->str);
1833 error_printf (GOB_ERROR, a->line_no,
1834 "%s type is not supported for arguments, try using properties",
1837 out_printf(out, "\tg_object_class_install_property (g_object_class,\n"
1838 "\t\tPROP_%s, param_spec);\n", s);
1842 g_string_free(flags, TRUE);
1845 #define value_for_print(str, alt) (str != NULL ? str : alt)
1848 make_property (Property *p)
1852 if (p->get == NULL && p->set == NULL) {
1853 error_print (GOB_ERROR, p->line_no,
1854 "Property has no getter nor setter");
1858 if (p->flags != NULL)
1859 error_print (GOB_WARN, p->line_no,
1860 "Overridden property, flags ignored");
1861 if (p->nick != NULL)
1862 error_print (GOB_WARN, p->line_no,
1863 "Overridden property, nick ignored");
1864 if (p->blurb != NULL)
1865 error_print (GOB_WARN, p->line_no,
1866 "Overridden property, blurb ignored");
1867 if (p->minimum != NULL)
1868 error_print (GOB_WARN, p->line_no,
1869 "Overridden property, minimum ignored");
1870 if (p->maximum != NULL)
1871 error_print (GOB_WARN, p->line_no,
1872 "Overridden property, maximum ignored");
1873 if (p->default_value != NULL)
1874 error_print (GOB_WARN, p->line_no,
1875 "Overridden property, default_value ignored");
1877 s = g_strdup (p->name);
1879 out_printf (out, "\tg_object_class_override_property (g_object_class,\n"
1881 "\t\t\"%s\");\n", s, value_for_print (p->canonical_name, p->name) );
1886 char *argflags[] = {
1894 flags = g_string_new ("(GParamFlags)(");
1896 if (p->get != NULL && p->set != NULL)
1897 g_string_append (flags, "G_PARAM_READABLE | G_PARAM_WRITABLE");
1898 else if (p->get != NULL)
1899 g_string_append (flags, "G_PARAM_READABLE");
1901 g_string_append (flags, "G_PARAM_WRITABLE");
1904 for (l = p->flags; l != NULL; l = l->next) {
1905 char *flag = l->data;
1907 if(strcmp (flag, "READABLE") == 0 ||
1908 strcmp (flag, "WRITABLE") == 0) {
1909 error_print(GOB_WARN, p->line_no,
1911 "WRITABLE argument flags are "
1912 "set automatically");
1915 for(i = 0; argflags[i]; i++) {
1916 if(strcmp(argflags[i], flag)==0)
1919 g_string_append_printf(flags, " | %s%s", argflags[i] ? "G_PARAM_" : "", flag);
1922 g_string_append (flags, ")");
1924 if (strcmp (p->gtktype, "CHAR") == 0) {
1925 out_printf (out, "\tparam_spec = g_param_spec_char\n"
1926 "\t\t(\"%s\" /* name */,\n"
1927 "\t\t %s /* nick */,\n"
1928 "\t\t %s /* blurb */,\n"
1929 "\t\t %s /* minimum */,\n"
1930 "\t\t %s /* maximum */,\n"
1931 "\t\t %s /* default_value */,\n"
1933 value_for_print (p->canonical_name, p->name),
1934 value_for_print (p->nick, "NULL"),
1935 value_for_print (p->blurb, "NULL"),
1936 value_for_print (p->minimum, "-128"),
1937 value_for_print (p->maximum, "127"),
1938 value_for_print (p->default_value, "0"),
1940 } else if (strcmp (p->gtktype, "UCHAR") == 0) {
1941 out_printf (out, "\tparam_spec = g_param_spec_uchar\n"
1942 "\t\t(\"%s\" /* name */,\n"
1943 "\t\t %s /* nick */,\n"
1944 "\t\t %s /* blurb */,\n"
1945 "\t\t %s /* minimum */,\n"
1946 "\t\t %s /* maximum */,\n"
1947 "\t\t %s /* default_value */,\n"
1949 value_for_print (p->canonical_name, p->name),
1950 value_for_print (p->nick, "NULL"),
1951 value_for_print (p->blurb, "NULL"),
1952 value_for_print (p->minimum, "0"),
1953 value_for_print (p->maximum, "0xFF"),
1954 value_for_print (p->default_value, "0"),
1956 } else if (strcmp (p->gtktype, "BOOLEAN") == 0) {
1957 out_printf (out, "\tparam_spec = g_param_spec_boolean\n"
1958 "\t\t(\"%s\" /* name */,\n"
1959 "\t\t %s /* nick */,\n"
1960 "\t\t %s /* blurb */,\n"
1961 "\t\t %s /* default_value */,\n"
1963 value_for_print (p->canonical_name, p->name),
1964 value_for_print (p->nick, "NULL"),
1965 value_for_print (p->blurb, "NULL"),
1966 value_for_print (p->default_value, "FALSE"),
1968 } else if (strcmp (p->gtktype, "INT") == 0) {
1969 out_printf (out, "\tparam_spec = g_param_spec_int\n"
1970 "\t\t(\"%s\" /* name */,\n"
1971 "\t\t %s /* nick */,\n"
1972 "\t\t %s /* blurb */,\n"
1973 "\t\t %s /* minimum */,\n"
1974 "\t\t %s /* maximum */,\n"
1975 "\t\t %s /* default_value */,\n"
1977 value_for_print (p->canonical_name, p->name),
1978 value_for_print (p->nick, "NULL"),
1979 value_for_print (p->blurb, "NULL"),
1980 value_for_print (p->minimum, "G_MININT"),
1981 value_for_print (p->maximum, "G_MAXINT"),
1982 value_for_print (p->default_value, "0"),
1984 } else if (strcmp (p->gtktype, "UINT") == 0) {
1985 out_printf (out, "\tparam_spec = g_param_spec_uint\n"
1986 "\t\t(\"%s\" /* name */,\n"
1987 "\t\t %s /* nick */,\n"
1988 "\t\t %s /* blurb */,\n"
1989 "\t\t %s /* minimum */,\n"
1990 "\t\t %s /* maximum */,\n"
1991 "\t\t %s /* default_value */,\n"
1993 value_for_print (p->canonical_name, p->name),
1994 value_for_print (p->nick, "NULL"),
1995 value_for_print (p->blurb, "NULL"),
1996 value_for_print (p->minimum, "0"),
1997 value_for_print (p->maximum, "G_MAXUINT"),
1998 value_for_print (p->default_value, "0"),
2000 } else if (strcmp (p->gtktype, "LONG") == 0) {
2001 out_printf (out, "\tparam_spec = g_param_spec_long\n"
2002 "\t\t(\"%s\" /* name */,\n"
2003 "\t\t %s /* nick */,\n"
2004 "\t\t %s /* blurb */,\n"
2005 "\t\t %s /* minimum */,\n"
2006 "\t\t %s /* maximum */,\n"
2007 "\t\t %s /* default_value */,\n"
2009 value_for_print (p->canonical_name, p->name),
2010 value_for_print (p->nick, "NULL"),
2011 value_for_print (p->blurb, "NULL"),
2012 value_for_print (p->minimum, "G_MINLONG"),
2013 value_for_print (p->maximum, "G_MAXLONG"),
2014 value_for_print (p->default_value, "0"),
2016 } else if (strcmp (p->gtktype, "ULONG") == 0) {
2017 out_printf (out, "\tparam_spec = g_param_spec_ulong\n"
2018 "\t\t(\"%s\" /* name */,\n"
2019 "\t\t %s /* nick */,\n"
2020 "\t\t %s /* blurb */,\n"
2021 "\t\t %s /* minimum */,\n"
2022 "\t\t %s /* maximum */,\n"
2023 "\t\t %s /* default_value */,\n"
2025 value_for_print (p->canonical_name, p->name),
2026 value_for_print (p->nick, "NULL"),
2027 value_for_print (p->blurb, "NULL"),
2028 value_for_print (p->minimum, "0"),
2029 value_for_print (p->maximum, "G_MAXULONG"),
2030 value_for_print (p->default_value, "0"),
2032 } else if (strcmp (p->gtktype, "INT64") == 0) {
2033 out_printf (out, "\tparam_spec = g_param_spec_int64\n"
2034 "\t\t(\"%s\" /* name */,\n"
2035 "\t\t %s /* nick */,\n"
2036 "\t\t %s /* blurb */,\n"
2037 "\t\t %s /* minimum */,\n"
2038 "\t\t %s /* maximum */,\n"
2039 "\t\t %s /* default_value */,\n"
2041 value_for_print (p->canonical_name, p->name),
2042 value_for_print (p->nick, "NULL"),
2043 value_for_print (p->blurb, "NULL"),
2044 value_for_print (p->minimum, "G_MININT64"),
2045 value_for_print (p->maximum, "G_MAXINT64"),
2046 value_for_print (p->default_value, "0"),
2048 } else if (strcmp (p->gtktype, "UINT64") == 0) {
2049 out_printf (out, "\tparam_spec = g_param_spec_uint64\n"
2050 "\t\t(\"%s\" /* name */,\n"
2051 "\t\t %s /* nick */,\n"
2052 "\t\t %s /* blurb */,\n"
2053 "\t\t %s /* minimum */,\n"
2054 "\t\t %s /* maximum */,\n"
2055 "\t\t %s /* default_value */,\n"
2057 value_for_print (p->canonical_name, p->name),
2058 value_for_print (p->nick, "NULL"),
2059 value_for_print (p->blurb, "NULL"),
2060 value_for_print (p->minimum, "0"),
2061 value_for_print (p->maximum, "G_MAXUINT64"),
2062 value_for_print (p->default_value, "0"),
2064 } else if (strcmp (p->gtktype, "UNICHAR") == 0) {
2065 out_printf (out, "\tparam_spec = g_param_spec_unichar\n"
2066 "\t\t(\"%s\" /* name */,\n"
2067 "\t\t %s /* nick */,\n"
2068 "\t\t %s /* blurb */,\n"
2069 "\t\t %s /* default_value */,\n"
2071 value_for_print (p->canonical_name, p->name),
2072 value_for_print (p->nick, "NULL"),
2073 value_for_print (p->blurb, "NULL"),
2074 value_for_print (p->default_value, "0"),
2076 } else if (strcmp (p->gtktype, "ENUM") == 0) {
2077 char *type = make_me_type (p->extra_gtktype,
2079 out_printf (out, "\tparam_spec = g_param_spec_enum\n"
2080 "\t\t(\"%s\" /* name */,\n"
2081 "\t\t %s /* nick */,\n"
2082 "\t\t %s /* blurb */,\n"
2083 "\t\t %s /* enum_type */,\n"
2084 "\t\t %s /* default_value */,\n"
2086 value_for_print (p->canonical_name, p->name),
2087 value_for_print (p->nick, "NULL"),
2088 value_for_print (p->blurb, "NULL"),
2090 value_for_print (p->default_value, "0"),
2093 } else if (strcmp (p->gtktype, "FLAGS") == 0) {
2094 char *type = make_me_type (p->extra_gtktype,
2096 out_printf (out, "\tparam_spec = g_param_spec_flags\n"
2097 "\t\t(\"%s\" /* name */,\n"
2098 "\t\t %s /* nick */,\n"
2099 "\t\t %s /* blurb */,\n"
2100 "\t\t %s /* flags_type */,\n"
2101 "\t\t %s /* default_value */,\n"
2103 value_for_print (p->canonical_name, p->name),
2104 value_for_print (p->nick, "NULL"),
2105 value_for_print (p->blurb, "NULL"),
2107 value_for_print (p->default_value, "0"),
2110 } else if (strcmp (p->gtktype, "FLOAT") == 0) {
2111 out_printf (out, "\tparam_spec = g_param_spec_float\n"
2112 "\t\t(\"%s\" /* name */,\n"
2113 "\t\t %s /* nick */,\n"
2114 "\t\t %s /* blurb */,\n"
2115 "\t\t %s /* minimum */,\n"
2116 "\t\t %s /* maximum */,\n"
2117 "\t\t %s /* default_value */,\n"
2119 value_for_print (p->canonical_name, p->name),
2120 value_for_print (p->nick, "NULL"),
2121 value_for_print (p->blurb, "NULL"),
2122 value_for_print (p->minimum, "-G_MAXFLOAT"),
2123 value_for_print (p->maximum, "G_MAXFLOAT"),
2124 value_for_print (p->default_value, "0.0"),
2126 } else if (strcmp (p->gtktype, "DOUBLE") == 0) {
2127 out_printf (out, "\tparam_spec = g_param_spec_double\n"
2128 "\t\t(\"%s\" /* name */,\n"
2129 "\t\t %s /* nick */,\n"
2130 "\t\t %s /* blurb */,\n"
2131 "\t\t %s /* minimum */,\n"
2132 "\t\t %s /* maximum */,\n"
2133 "\t\t %s /* default_value */,\n"
2135 value_for_print (p->canonical_name, p->name),
2136 value_for_print (p->nick, "NULL"),
2137 value_for_print (p->blurb, "NULL"),
2138 value_for_print (p->minimum, "-G_MAXDOUBLE"),
2139 value_for_print (p->maximum, "G_MAXDOUBLE"),
2140 value_for_print (p->default_value, "0.0"),
2142 } else if (strcmp (p->gtktype, "STRING") == 0) {
2143 out_printf (out, "\tparam_spec = g_param_spec_string\n"
2144 "\t\t(\"%s\" /* name */,\n"
2145 "\t\t %s /* nick */,\n"
2146 "\t\t %s /* blurb */,\n"
2147 "\t\t %s /* default_value */,\n"
2149 value_for_print (p->canonical_name, p->name),
2150 value_for_print (p->nick, "NULL"),
2151 value_for_print (p->blurb, "NULL"),
2152 value_for_print (p->default_value, "NULL"),
2154 } else if (strcmp (p->gtktype, "PARAM") == 0) {
2155 char *type = make_me_type (p->extra_gtktype,
2157 out_printf (out, "\tparam_spec = g_param_spec_param\n"
2158 "\t\t(\"%s\" /* name */,\n"
2159 "\t\t %s /* nick */,\n"
2160 "\t\t %s /* blurb */,\n"
2161 "\t\t %s /* param_type */,\n"
2163 value_for_print (p->canonical_name, p->name),
2164 value_for_print (p->nick, "NULL"),
2165 value_for_print (p->blurb, "NULL"),
2169 } else if (strcmp (p->gtktype, "BOXED") == 0) {
2170 char *type = make_me_type (p->extra_gtktype,
2172 out_printf (out, "\tparam_spec = g_param_spec_boxed\n"
2173 "\t\t(\"%s\" /* name */,\n"
2174 "\t\t %s /* nick */,\n"
2175 "\t\t %s /* blurb */,\n"
2176 "\t\t %s /* boxed_type */,\n"
2178 value_for_print (p->canonical_name, p->name),
2179 value_for_print (p->nick, "NULL"),
2180 value_for_print (p->blurb, "NULL"),
2184 } else if (strcmp (p->gtktype, "POINTER") == 0) {
2185 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2186 "\t\t(\"%s\" /* name */,\n"
2187 "\t\t %s /* nick */,\n"
2188 "\t\t %s /* blurb */,\n"
2190 value_for_print (p->canonical_name, p->name),
2191 value_for_print (p->nick, "NULL"),
2192 value_for_print (p->blurb, "NULL"),
2194 /* FIXME: VALUE_ARRAY */
2195 } else if (strcmp (p->gtktype, "CLOSURE") == 0) {
2196 out_printf (out, "\tparam_spec = g_param_spec_pointer\n"
2197 "\t\t(\"%s\" /* name */,\n"
2198 "\t\t %s /* nick */,\n"
2199 "\t\t %s /* blurb */,\n"
2201 value_for_print (p->canonical_name, p->name),
2202 value_for_print (p->nick, "NULL"),
2203 value_for_print (p->blurb, "NULL"),
2205 } else if (strcmp (p->gtktype, "OBJECT") == 0) {
2206 char *type = make_me_type (p->extra_gtktype,
2208 out_printf (out, "\tparam_spec = g_param_spec_object\n"
2209 "\t\t(\"%s\" /* name */,\n"
2210 "\t\t %s /* nick */,\n"
2211 "\t\t %s /* blurb */,\n"
2212 "\t\t %s /* object_type */,\n"
2214 value_for_print (p->canonical_name, p->name),
2215 value_for_print (p->nick, "NULL"),
2216 value_for_print (p->blurb, "NULL"),
2221 error_printf (GOB_ERROR, p->line_no,
2222 "%s type is not supported by properties",
2226 s = g_strdup (p->name);
2228 out_printf (out, "\tg_object_class_install_property (g_object_class,\n"
2230 "\t\tparam_spec);\n", s);
2233 g_string_free (flags, TRUE);
2238 make_arguments(Class *c)
2241 if (get_properties > 0)
2242 out_printf(out, "\tg_object_class->get_property = ___object_get_property;\n");
2243 if (set_properties > 0)
2244 out_printf(out, "\tg_object_class->set_property = ___object_set_property;\n");
2245 out_printf (out, " {\n");
2246 for (li = c->nodes; li != NULL; li = li->next) {
2248 if ((n->type == PROPERTY_NODE && ! ((Property *) n)->override)
2249 || n->type == ARGUMENT_NODE) {
2250 out_printf(out, "\tGParamSpec *param_spec;\n\n");
2255 for (li = c->nodes; li != NULL; li = li->next) {
2257 if (n->type == PROPERTY_NODE)
2258 make_property ((Property *)n);
2259 else if (n->type == ARGUMENT_NODE)
2260 make_argument ((Argument *)n);
2262 out_printf(out, " }\n");
2266 print_initializer(Method *m, Variable *v)
2273 if(v->initializer == NULL)
2276 if(v->scope == PRIVATE_SCOPE)
2277 root = g_strconcat(((FuncArg *)m->args->data)->name,
2280 root = g_strdup(((FuncArg *)m->args->data)->name);
2282 if(v->initializer_line > 0)
2283 out_addline_infile(out, v->initializer_line);
2285 if (v->initializer_simple)
2286 out_printf(out, "\t%s->%s = %s;\n",
2287 root, v->id, v->initializer);
2288 else if (strcmp(v->id, "_glade_xml") == 0)
2289 /* This is OK, this v->initializer string is set internally
2290 and it will eat exactly one string! */
2291 out_printf(out,v->initializer, ((FuncArg *)m->args->data)->name);
2293 out_printf(out, "%s", v->initializer);
2295 if(v->initializer_line > 0)
2296 out_addline_outfile(out);
2302 print_glade_widget(Method *m, Variable *v)
2307 if(!v->glade_widget)
2310 if(v->scope == PRIVATE_SCOPE)
2311 root = g_strconcat(((FuncArg *)m->args->data)->name,
2314 root = g_strdup(((FuncArg *)m->args->data)->name);
2316 cast = get_type(v->vtype, FALSE);
2317 out_printf(out, "\t%s->%s = (%s)glade_xml_get_widget(%s->_glade_xml, \"%s\");\n",
2318 root, v->id, cast, root, v->id);
2324 print_destructor (Variable *v)
2328 if(v->destructor == NULL)
2331 if(v->scope == PRIVATE_SCOPE)
2332 root = "self->_priv";
2336 if(v->destructor_simple) {
2337 if(v->destructor_line > 0)
2338 out_addline_infile(out, v->destructor_line);
2341 out_printf(out, "\tif(%s->%s) { "
2342 "(reinterpret_cast<void (*)(void *)>(%s)) ((gpointer)%s->%s); "
2343 "%s->%s = NULL; }\n",
2344 root, v->id, v->destructor, root, v->id,
2347 out_printf(out, "\tif(%s->%s) { "
2348 "%s ((gpointer) %s->%s); "
2349 "%s->%s = NULL; }\n",
2350 root, v->id, v->destructor, root, v->id,
2354 if(v->destructor_line > 0)
2355 out_addline_outfile(out);
2357 out_printf(out, "#define %s (%s->%s)\n", v->id, root, v->id);
2358 out_printf(out, "#define VAR %s\n", v->id);
2359 out_printf(out, "\t{\n");
2360 if(v->destructor_line > 0)
2361 out_addline_infile(out, v->destructor_line);
2363 out_printf(out, "\t%s}\n", v->destructor);
2365 if(v->destructor_line > 0)
2366 out_addline_outfile(out);
2367 out_printf(out, "\tmemset(&(%s), 0, sizeof(%s));\n",
2369 out_printf(out, "#undef VAR\n");
2370 out_printf(out, "#undef %s\n", v->id);
2375 add_constructor (Class *c)
2377 out_printf(out, "\nstatic GObject *\n"
2378 "___constructor (GType type, guint n_construct_properties, GObjectConstructParam *construct_properties)\n"
2381 "#define __GOB_FUNCTION__ \"%s::constructor\"\n",
2384 out_printf(out, "\tGObject *obj_self;\n");
2385 out_printf(out, "\t%s *self;\n", typebase);
2387 out_printf(out, "\tobj_self = G_OBJECT_CLASS (parent_class)->constructor (type, n_construct_properties, construct_properties);\n");
2388 out_printf(out, "\tself = %s (obj_self);\n", macrobase);
2390 if (user_constructor->line_no > 0)
2391 out_addline_infile (out, user_constructor->line_no);
2392 out_printf (out, "\t%s_constructor (self);\n", funcbase);
2393 if (user_constructor->line_no > 0)
2394 out_addline_outfile (out);
2396 out_printf(out, "\treturn obj_self;\n");
2397 out_printf(out, "}\n"
2398 "#undef __GOB_FUNCTION__\n\n");
2402 print_unreftors (Class *c)
2405 for(li = ((Class *)class)->nodes;
2409 Variable *v = (Variable *)n;
2410 if (n->type == VARIABLE_NODE &&
2411 v->scope != CLASS_SCOPE &&
2412 v->destructor_unref)
2413 print_destructor (v);
2418 add_dispose (Class *c)
2420 out_printf(out, "\nstatic void\n"
2421 "___dispose (GObject *obj_self)\n"
2424 "#define __GOB_FUNCTION__ \"%s::dispose\"\n",
2427 if (unreftors > 0 || user_dispose_method != NULL) {
2428 out_printf (out, "\t%s *self%s = %s (obj_self);\n",
2430 ! no_gnu ? " G_GNUC_UNUSED" : "",
2434 if (dispose_handler != NULL) {
2435 if (unreftors > 0) {
2436 print_unreftors (c);
2439 /* so we get possible bad argument warning */
2440 if (dispose_handler->line_no > 0)
2441 out_addline_infile (out, dispose_handler->line_no);
2442 out_printf (out, "\t___%x_%s_dispose(obj_self);\n",
2443 (guint)dispose_handler->unique_id, funcbase);
2444 if (dispose_handler->line_no > 0)
2445 out_addline_outfile (out);
2447 if (user_dispose_method != NULL) {
2448 if (user_dispose_method->line_no > 0)
2449 out_addline_infile (out, user_dispose_method->line_no);
2450 out_printf (out, "\t%s_dispose (self);\n", funcbase);
2451 if (user_dispose_method->line_no > 0)
2452 out_addline_outfile (out);
2455 if (unreftors > 0) {
2456 print_unreftors (c);
2460 "\tif (G_OBJECT_CLASS (parent_class)->dispose) \\\n"
2461 "\t\t(* G_OBJECT_CLASS (parent_class)->dispose) (obj_self);\n");
2464 out_printf(out, "}\n"
2465 "#undef __GOB_FUNCTION__\n\n");
2469 print_destructors (Class *c)
2472 for (li = ((Class *)class)->nodes;
2476 Variable *v = (Variable *)n;
2477 if (n->type == VARIABLE_NODE &&
2478 v->scope != CLASS_SCOPE &&
2479 ! v->destructor_unref)
2480 print_destructor (v);
2485 add_finalize (Class *c)
2489 "___finalize(GObject *obj_self)\n"
2492 "#define __GOB_FUNCTION__ \"%s::finalize\"\n",
2497 user_finalize_method != NULL) {
2498 const char *unused = "";
2500 unused = " G_GNUC_UNUSED";
2501 out_printf(out, "\t%s *self%s = %s (obj_self);\n",
2502 typebase, unused, macrobase);
2505 const char *unused = "";
2507 unused = " G_GNUC_UNUSED";
2508 out_printf(out, "\tgpointer priv%s = self->_priv;\n",
2512 if(finalize_handler) {
2513 if (destructors > 0) {
2514 print_destructors (c);
2517 /* so we get possible bad argument warning */
2518 if(finalize_handler->line_no > 0)
2519 out_addline_infile(out, finalize_handler->line_no);
2520 out_printf(out, "\t___%x_%s_finalize(obj_self);\n",
2521 (guint)finalize_handler->unique_id, funcbase);
2522 if(finalize_handler->line_no > 0)
2523 out_addline_outfile(out);
2525 if (user_finalize_method != NULL) {
2526 if (user_finalize_method->line_no > 0)
2527 out_addline_infile (out, user_finalize_method->line_no);
2528 out_printf (out, "\t%s_finalize (self);\n", funcbase);
2529 if (user_finalize_method->line_no > 0)
2530 out_addline_outfile (out);
2533 if (destructors > 0) {
2534 print_destructors (c);
2538 "\tif(G_OBJECT_CLASS(parent_class)->finalize) \\\n"
2539 "\t\t(* G_OBJECT_CLASS(parent_class)->finalize)(obj_self);\n");
2542 out_printf(out, "}\n"
2543 "#undef __GOB_FUNCTION__\n\n");
2547 make_bonobo_object_epv (Class *c, const char *classname)
2550 gboolean added_line = FALSE;
2552 for (li = c->nodes; li != NULL; li = li->next) {
2554 Method *m = (Method *)n;
2555 if(n->type != METHOD_NODE ||
2556 m->method == OVERRIDE_METHOD)
2559 if (m->bonobo_object_func) {
2560 if(m->line_no > 0) {
2561 out_addline_infile(out, m->line_no);
2563 } else if (m->line_no == 0 &&
2565 out_addline_outfile(out);
2568 out_printf (out, "\t%s->_epv.%s = self_%s;\n",
2569 classname, m->id, m->id);
2573 out_addline_outfile(out);
2576 static void add_class_private(Class *c, Method *m)
2578 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2583 out_printf(out, "\n#if !defined(G_DEFINE%s_TYPE_EXTENDED)"
2584 " || !defined(G_ADD_PRIVATE%s)\n"
2585 "\tg_type_class_add_private(%s, sizeof(%sPrivate));\n"
2588 ((FuncArg *)m->args->data)->name, typebase);
2591 static void get_instance_private(Class *c, Method *m)
2593 const char *self = ((FuncArg *)m->args->data)->name;
2594 const char *dynamic = c->dynamic ? "_DYNAMIC" : "";
2597 if (always_private_struct) {
2598 out_printf(out, "\t%s->_priv = NULL;\n", self);
2604 out_printf(out, "\t%s->_priv = (%sPrivate *)\n"
2605 "#if defined(G_DEFINE%s_TYPE_EXTENDED)"
2606 " && defined(G_ADD_PRIVATE%s)\n"
2607 "\t\t%s_get_instance_private(%s);\n"
2609 "\t\tG_TYPE_INSTANCE_GET_PRIVATE\n"
2612 "\t\t\t, %sPrivate\n"
2618 self, macrotype, typebase);
2624 const char *unused = "";
2628 unused = " G_GNUC_UNUSED";
2630 for(li=c->nodes;li;li=g_list_next(li)) {
2634 if(n->type != METHOD_NODE)
2637 if(m->method == INIT_METHOD) {
2639 out_addline_infile(out, m->line_no);
2640 print_method(out, "static ", "\n", "", " ", "", "\n",
2641 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2643 out_printf(out, "{\n");
2645 out_addline_outfile(out);
2647 "#define __GOB_FUNCTION__ \"%s::init\"\n",
2650 get_instance_private(c, m);
2652 if(initializers > 0) {
2654 for(li = ((Class *)class)->nodes;
2658 Variable *v = (Variable *)n;
2659 if(n->type != VARIABLE_NODE ||
2660 v->scope == CLASS_SCOPE)
2662 print_initializer(m, v);
2665 if(glade_widgets > 0) {
2667 for(li = ((Class *)class)->nodes;
2671 Variable *v = (Variable *)n;
2672 if(n->type != VARIABLE_NODE ||
2673 v->scope == CLASS_SCOPE)
2675 print_glade_widget(m, v);
2678 } else if(m->method == CLASS_INIT_METHOD) {
2679 gboolean did_base_obj = FALSE;
2682 out_addline_infile(out, m->line_no);
2683 print_method(out, "static ", "\n", "", " ", "", "\n",
2684 m, FALSE, FALSE, FALSE, TRUE, TRUE,
2686 out_printf(out, "{\n");
2688 out_addline_outfile(out);
2690 "#define __GOB_FUNCTION__ \"%s::class_init\"\n",
2692 if (set_properties > 0 ||
2693 get_properties > 0 ||
2700 "g_object_class%s = "
2701 "(GObjectClass*) %s;\n",
2703 ((FuncArg *)m->args->data)->name);
2704 did_base_obj = TRUE;
2709 ((FuncArg *)m->args->data)->name,
2712 add_class_private(c, m);
2714 if (initializers > 0) {
2716 for(li = ((Class *)class)->nodes;
2720 Variable *v = (Variable *)n;
2721 if(n->type == VARIABLE_NODE &&
2722 v->scope == CLASS_SCOPE)
2723 print_initializer(m, v);
2727 out_printf(out, "\n\tparent_class = ");
2729 out_printf(out, "(%sClass *)", ptypebase);
2730 out_printf(out, "g_type_class_ref (%s);\n",
2736 set_def_handlers(c, ((FuncArg *)m->args->data)->name);
2738 /* if there are no handlers for these things, we
2739 * need to set them up here */
2740 if(need_constructor)
2741 out_printf(out, "\tg_object_class->constructor "
2742 "= ___constructor;\n");
2743 if(need_dispose && !dispose_handler)
2744 out_printf(out, "\tg_object_class->dispose "
2746 if(need_finalize && !finalize_handler)
2747 out_printf(out, "\tg_object_class->finalize = "
2750 if(get_properties > 0 || set_properties > 0)
2753 if (c->bonobo_object_class != NULL) {
2754 make_bonobo_object_epv (c, ((FuncArg *)m->args->data)->name);
2760 out_printf(out, " {\n");
2761 out_addline_infile(out, m->ccode_line);
2762 out_printf(out, "%s\n", m->cbuf);
2763 out_addline_outfile(out);
2764 out_printf(out, " }\n");
2766 out_printf(out, "}\n"
2767 "#undef __GOB_FUNCTION__\n");
2772 add_argument (Argument *a, gboolean is_set)
2776 char *the_type_lower;
2781 line_no = a->set_line;
2784 line_no = a->get_line;
2788 s = g_strdup(a->name);
2790 out_printf(out, "\tcase PROP_%s:\n\t{", s);
2792 the_type_lower = g_strdup (a->gtktype);
2793 gob_strdown (the_type_lower);
2795 /* HACK because there is no g_value_set/get for unichar */
2796 if (strcmp (the_type_lower, "unichar") == 0) {
2797 g_free (the_type_lower);
2798 the_type_lower = g_strdup ("uint");
2803 const char *unused = "";
2805 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2806 unused = " G_GNUC_UNUSED";
2809 if (a->atype != NULL &&
2810 /* gcc -Wbad-function-cast is wanking stupid, moronic
2811 and otherwise evil so we should just use a (gint)
2812 or (guint) cast, not the specific type cast */
2814 (strcmp (a->gtktype, "ENUM") != 0 &&
2815 strcmp (a->gtktype, "FLAGS") != 0)))
2816 cast = get_type (a->atype, TRUE);
2818 cast = g_strdup (get_cast (a->gtktype, FALSE));
2820 out_printf (out, "\t%s ARG%s = (%s) g_value_get_%s (VAL);\n",
2821 cast, unused, cast, the_type_lower);
2824 } else if ( ! is_set) {
2827 if (a->atype != NULL)
2828 cast = get_type (a->atype, TRUE);
2830 cast = g_strdup (get_cast (a->gtktype, FALSE));
2831 out_printf (out, "\t%s ARG;\n"
2832 "\tmemset (&ARG, 0, sizeof (%s));\n",
2838 out_printf(out, "\t\t{\n");
2840 out_addline_infile (out, line_no);
2841 out_printf (out, "%s\n", cbuf);
2843 out_addline_outfile (out);
2844 out_printf (out, "\t\t}\n");
2846 if (strcmp (a->gtktype, "OBJECT") == 0)
2847 out_printf (out, "\t\tg_value_set_%s (VAL, G_OBJECT (ARG));\n",
2850 out_printf (out, "\t\t"
2851 "g_value_set_%s (VAL, ARG);\n",
2854 g_free (the_type_lower);
2857 (no_gnu || for_cpp /* g++ has a cow with G_GNUC_UNUSED */)) {
2858 out_printf (out, "\t\tif (&ARG) break;\n");
2861 out_printf (out, "\t\tbreak;\n");
2863 out_printf (out, "\t}\n");
2867 add_property (Property *p, gboolean is_set)
2870 char *the_type_lower;
2876 line_no = p->set_line;
2879 line_no = p->get_line;
2884 name_upper = g_strdup (p->name);
2885 gob_strup (name_upper);
2886 the_type_lower = g_strdup (p->gtktype);
2887 gob_strdown (the_type_lower);
2889 out_printf (out, "\tcase PROP_%s:\n", name_upper);
2891 out_printf(out, "\t\t{\n");
2893 out_addline_infile (out, line_no);
2894 out_printf (out, "%s\n", cbuf);
2896 out_addline_outfile (out);
2897 out_printf (out, "\t\t}\n");
2899 g_free (name_upper);
2900 g_free (the_type_lower);
2902 out_printf (out, "\t\tbreak;\n");
2906 add_getset_arg(Class *c, gboolean is_set)
2909 const char *unused = "";
2910 const char *hack_unused = "";
2912 if ( ! no_gnu && ! for_cpp /* g++ has a cow with this */) {
2913 unused = " G_GNUC_UNUSED";
2915 hack_unused = "if (&VAL || &pspec) break;\n\t\t";
2918 out_printf(out, "\nstatic void\n"
2919 "___object_%s_property (GObject *object,\n"
2920 "\tguint property_id,\n"
2921 "\t%sGValue *VAL%s,\n"
2922 "\tGParamSpec *pspec%s)\n"
2923 "#define __GOB_FUNCTION__ \"%s::%s_property\"\n"
2926 "\tself = %s (object);\n\n"
2927 "\tswitch (property_id) {\n",
2928 is_set ? "set" : "get",
2929 is_set ? "const " : "",
2933 is_set ? "set" : "get",
2938 for (li = c->nodes; li != NULL; li = li->next) {
2940 if (n->type == PROPERTY_NODE)
2941 add_property ((Property *)n, is_set);
2942 else if (n->type == ARGUMENT_NODE)
2943 add_argument ((Argument *)n, is_set);
2945 out_printf (out, "\tdefault:\n"
2946 "/* Apparently in g++ this is needed, glib is b0rk */\n"
2947 "#ifndef __PRETTY_FUNCTION__\n"
2948 "# undef G_STRLOC\n"
2949 "# define G_STRLOC __FILE__ \":\" G_STRINGIFY (__LINE__)\n"
2951 "\t\tG_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);\n"
2952 "\t\t%sbreak;\n\t}\n"
2954 "#undef __GOB_FUNCTION__\n", hack_unused);
2958 print_checks (Method *m, FuncArg *fa)
2962 gboolean checked_null = FALSE;
2963 is_void = (strcmp(m->mtype->name, "void")==0 &&
2964 m->mtype->pointer == NULL);
2966 for(li = fa->checks; li != NULL; li = li->next) {
2967 Check *ch = li->data;
2969 /* point to the method prot in .gob for failed checks */
2971 out_addline_infile(out, m->line_no);
2973 out_printf(out, "\tg_return_if_fail (");
2975 out_printf(out, "\tg_return_val_if_fail (");
2976 switch(ch->chtype) {
2978 out_printf(out, "%s != NULL", fa->name);
2979 checked_null = TRUE;
2982 s = make_pre_macro(fa->atype->name, "IS");
2984 out_printf(out, "%s (%s)", s, fa->name);
2986 /* if not check null, null may be valid */
2987 out_printf(out, "!(%s) || %s (%s)", fa->name,
2992 out_printf(out, "%s < %s", fa->name, ch->number);
2995 out_printf(out, "%s > %s", fa->name, ch->number);
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);
3011 out_printf(out, ");\n");
3013 out_printf(out, ", (");
3014 print_type(out, m->mtype, TRUE);
3015 out_printf(out, ")%s);\n",
3016 m->onerror?m->onerror:"0");
3022 print_preconditions(Method *m)
3026 for(li=m->args;li;li=g_list_next(li)) {
3027 FuncArg *fa = li->data;
3029 print_checks(m, fa);
3032 out_addline_outfile(out);
3036 print_method_body (Method *m, gboolean pre, gboolean unused_self)
3038 out_printf(out, "{\n");
3040 out_addline_outfile(out);
3041 out_printf(out, "#define __GOB_FUNCTION__ \"%s::%s\"\n",
3042 ((Class *)class)->otype,
3045 print_preconditions(m);
3049 (no_gnu || for_cpp) &&
3051 ((FuncArg *)(m->args->data))->name != NULL &&
3052 strcmp (((FuncArg *)(m->args->data))->name, "self") == 0) {
3053 out_printf (out, "\tif (&self) { ; }\n");
3056 /* Note: the trailing }'s are on one line, this is so
3057 that we get the no return warning correctly and point to
3058 the correct line in the .gob file, yes this is slightly
3059 ugly in the .c file, but that is not supposed to be
3060 human readable anyway. */
3062 out_printf(out, "{\n");
3064 out_addline_infile(out, m->ccode_line);
3065 out_printf(out, "\t%s}", m->cbuf);
3068 /* Note, there is no \n between the last } and this } so that
3069 * errors/warnings reported on the end of the body get pointed to the
3070 * right line in the .gob source */
3071 out_printf(out, "}\n");
3074 out_addline_outfile(out);
3075 out_printf(out, "#undef __GOB_FUNCTION__\n");
3079 put_signal_args (Method *m)
3085 if (m->args->next == NULL)
3088 for (ali = m->gtktypes->next, li = m->args->next, i = 1;
3089 li != NULL && ali != NULL;
3090 li = li->next, ali = ali->next, i++) {
3091 FuncArg *fa = li->data;
3092 char *str = ali->data;
3093 char *cast = g_strdup (get_cast (str, FALSE));
3094 /* FIXME: This code is so fucking ugly it hurts */
3095 gboolean do_static =
3096 (strcmp (str, "STRING") == 0 ||
3097 strcmp (str, "BOXED") == 0 ||
3098 strncmp (str, "BOXED_", 6) == 0);
3103 cast = get_type (fa->atype, TRUE);
3105 /* we should have already proved before that
3106 the we know all the types */
3107 g_assert (cast != NULL);
3109 if (strncmp (str, "BOXED_", 6) == 0)
3110 t = g_strdup (&(str[6]));
3112 t = g_strconcat ("G_TYPE_", str, NULL);
3115 "\t___param_values[%d].g_type = 0;\n"
3116 "\tg_value_init (&___param_values[%d], %s);\n",
3120 if (strcmp (str, "UNICHAR") == 0)
3121 /* hack because glib is braindamaged */
3122 set_func = g_strdup ("g_value_set_uint");
3123 else if (strncmp (str, "BOXED_", 6) == 0)
3124 set_func = g_strdup ("g_value_set_static_boxed");
3126 set_func = g_strdup_printf ("g_value_set%s_%s",
3127 do_static ? "_static" : "",
3129 gob_strdown (set_func);
3131 out_printf (out, "\t%s (&___param_values[%d], (%s) %s);\n\n",
3132 set_func, i, cast, fa->name);
3140 clear_signal_args (Method *m)
3145 out_printf (out, "\n\tg_value_unset (&___param_values[0]);\n");
3147 if (m->args->next == NULL)
3150 for (li = m->args->next, i = 1;
3152 li = li->next, i++) {
3154 "\tg_value_unset (&___param_values[%d]);\n", i);
3159 get_arg_names_for_macro (Method *m)
3164 GString *gs = g_string_new(NULL);
3166 for(li=m->args;li;li=g_list_next(li)) {
3167 FuncArg *arg = li->data;
3168 g_string_append_printf(gs, "%s___%s", sep, arg->name);
3173 g_string_free(gs, FALSE);
3177 static gboolean method_is_void(Method *m)
3179 return !strcmp(m->mtype->name, "void") && !m->mtype->pointer;
3182 static const char *method_err_retval(Method *m)
3184 if (method_is_void(m))
3192 put_interface_parent_handler(Method *m)
3194 const char *errval = method_err_retval(m);
3195 char *name = replace_sep(m->interface, '_');
3196 char *args = get_arg_names_for_macro(m);
3198 out_printf(out, "#define PARENT_HANDLER(%s) (%s_parent_iface \\\n"
3199 "\t? %s_parent_iface->%s(%s) \\\n"
3200 "\t: %s)\n", args, name, name, m->id, args, errval);
3207 put_method(Method *m)
3209 char *s, *args, *doc;
3211 is_void = (strcmp(m->mtype->name, "void")==0 &&
3212 m->mtype->pointer == NULL);
3213 out_printf(out, "\n");
3214 if(m->method != OVERRIDE_METHOD) {
3215 doc = get_gtk_doc(m->id);
3217 out_printf(out, "%s", doc);
3223 case REGULAR_METHOD:
3225 out_addline_infile(out, m->line_no);
3226 if(m->scope == PRIVATE_SCOPE)
3227 print_method(out, "static ", "\n", "", " ", "", "\n",
3228 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3229 else /* PUBLIC, PROTECTED */
3230 print_method(out, "", "\n", "", " ", "", "\n",
3231 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3234 out_addline_outfile(out);
3235 put_interface_parent_handler(m);
3238 print_method_body(m, TRUE, TRUE);
3241 out_printf(out, "#undef PARENT_HANDLER\n");
3244 /* the outfile line was added above */
3246 case SIGNAL_FIRST_METHOD:
3247 case SIGNAL_LAST_METHOD:
3249 out_addline_infile(out, m->line_no);
3250 if(m->scope == PRIVATE_SCOPE)
3251 print_method(out, "static ", "\n", "", " ", "", "\n",
3252 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3253 else /* PUBLIC, PROTECTED */
3254 print_method(out, "", "\n", "", " ", "", "\n",
3255 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3256 out_printf (out, "{\n");
3258 out_addline_outfile (out);
3261 "\tGValue ___param_values[%d];\n"
3262 "\tGValue ___return_val;\n\n"
3263 "memset (&___return_val, 0, "
3264 "sizeof (___return_val));\n"
3265 "memset (&___param_values, 0, "
3266 "sizeof (___param_values));\n\n",
3267 g_list_length (m->args));
3269 print_preconditions (m);
3272 "\n\t___param_values[0].g_type = 0;\n"
3273 "\tg_value_init (&___param_values[0], G_TYPE_FROM_INSTANCE (%s));\n"
3274 "\tg_value_set_instance (&___param_values[0], (gpointer) %s);\n\n",
3275 ((FuncArg *)m->args->data)->name,
3276 ((FuncArg *)m->args->data)->name);
3278 put_signal_args (m);
3280 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3281 const char *defret = NULL;
3283 out_printf (out, "\tg_value_init (&___return_val, G_TYPE_%s);\n",
3284 (char *)m->gtktypes->data);
3286 if (m->defreturn != NULL)
3287 defret = m->defreturn;
3288 else if (m->onerror != NULL)
3289 defret = m->onerror;
3291 if (defret != NULL) {
3293 /* FIXME: This code is so fucking ugly it hurts */
3294 gboolean do_static =
3295 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3296 strcmp ((char *)m->gtktypes->data, "BOXED") == 0);
3297 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3299 cast = get_type (m->mtype, TRUE);
3301 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3302 /* hack because glib is braindamaged */
3303 set_func = g_strdup ("g_value_set_uint");
3305 set_func = g_strdup_printf ("g_value_set%s_%s",
3306 do_static ? "_static" : "",
3307 (char *)m->gtktypes->data);
3308 gob_strdown (set_func);
3310 out_printf (out, "\t%s (&___return_val, (%s) (%s));\n",
3311 set_func, cast, defret);
3316 out_printf (out, "\n");
3319 s = g_strdup (m->id);
3322 out_printf(out, "\tg_signal_emitv (___param_values,\n"
3323 "\t\tobject_signals[%s_SIGNAL],\n"
3324 "\t\t0 /* detail */,\n"
3325 "\t\t&___return_val);\n", s);
3329 clear_signal_args (m);
3331 if (strcmp (m->gtktypes->data, "NONE") != 0) {
3332 char *cast = g_strdup (get_cast (m->gtktypes->data, FALSE));
3334 /* Hack because glib is very very braindead */
3336 (strcmp ((char *)m->gtktypes->data, "STRING") == 0 ||
3337 strcmp ((char *)m->gtktypes->data, "BOXED") == 0 ||
3338 strcmp ((char *)m->gtktypes->data, "OBJECT") == 0 ||
3339 strcmp ((char *)m->gtktypes->data, "PARAM") == 0);
3341 if (strcmp (m->gtktypes->data, "UNICHAR") == 0)
3342 /* hack because glib is braindamaged */
3343 getfunc = g_strdup ("g_value_get_uint");
3345 getfunc = g_strdup_printf ("g_value_%s_%s",
3346 do_dup ? "dup" : "get",
3347 (char *)m->gtktypes->data);
3348 gob_strdown (getfunc);
3351 cast = get_type (m->mtype, TRUE);
3356 print_type (out, m->mtype, TRUE);
3358 " ___ret = (%s) %s (&___return_val);\n"
3359 "\t\tg_value_unset (&___return_val);\n"
3360 "\t\treturn ___ret;\n"
3367 out_printf(out, "}\n");
3372 out_addline_infile(out, m->line_no);
3373 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3374 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3375 print_method_body(m, FALSE, TRUE);
3376 /* the outfile line was added above */
3378 case VIRTUAL_METHOD:
3380 out_addline_infile(out, m->line_no);
3381 if(m->scope==PRIVATE_SCOPE)
3382 print_method(out, "static ", "\n", "", " ", "", "\n",
3383 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3384 else /* PUBLIC, PROTECTED */
3385 print_method(out, "", "\n", "", " ", "", "\n",
3386 m, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE);
3387 out_printf(out, "{\n");
3388 out_addline_outfile(out);
3389 out_printf(out, "\t%sClass *klass;\n", typebase);
3390 print_preconditions(m);
3391 out_printf(out, "\tklass = %s_GET_CLASS(%s);\n\n"
3392 "\tif(klass->%s)\n",
3393 macrobase, ((FuncArg *)m->args->data)->name,
3395 if(strcmp(m->mtype->name, "void") == 0 &&
3396 m->mtype->pointer == NULL) {
3398 out_printf(out, "\t\t(*klass->%s)(%s",
3400 ((FuncArg *)m->args->data)->name);
3401 for(li=m->args->next;li;li=g_list_next(li)) {
3402 FuncArg *fa = li->data;
3403 out_printf(out, ",%s", fa->name);
3405 out_printf(out, ");\n}\n");
3408 out_printf(out, "\t\treturn (*klass->%s)(%s",
3410 ((FuncArg *)m->args->data)->name);
3411 for(li=m->args->next;li;li=g_list_next(li)) {
3412 FuncArg *fa = li->data;
3413 out_printf(out, ",%s", fa->name);
3415 out_printf(out, ");\n"
3418 print_type(out, m->mtype, TRUE);
3420 out_printf(out, ")(%s);\n}\n", m->defreturn);
3422 out_printf(out, ")(%s);\n}\n", m->onerror);
3424 out_printf(out, ")(0);\n}\n");
3430 out_addline_infile(out, m->line_no);
3431 print_method(out, "static ", "\n___real_", "", " ", "", "\n",
3432 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3433 print_method_body(m, FALSE, TRUE);
3434 /* the outfile line was added above */
3436 case OVERRIDE_METHOD:
3440 out_addline_infile(out, m->line_no);
3441 s = g_strdup_printf("\n___%x_", (guint)m->unique_id);
3442 print_method(out, "static ", s, "", " ", "", "\n",
3443 m, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE);
3445 out_addline_outfile(out);
3446 s = replace_sep(m->otype, '_');
3448 args = get_arg_names_for_macro(m);
3450 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3451 "\t{ if(%s_CLASS(parent_class)->%s) \\\n"
3452 "\t\t(* %s_CLASS(parent_class)->%s)(%s); }\n",
3453 args, s, m->id, s, m->id, args);
3455 out_printf(out, "#define PARENT_HANDLER(%s) \\\n"
3456 "\t((%s_CLASS(parent_class)->%s)? \\\n"
3457 "\t\t(* %s_CLASS(parent_class)->%s)(%s): \\\n"
3459 args, s, m->id, s, m->id, args);
3460 out_printf(out, "(");
3461 print_type(out, m->mtype, TRUE);
3462 out_printf(out, ")%s))\n",
3463 m->onerror?m->onerror:"0");
3467 print_method_body(m, TRUE, TRUE);
3468 /* the outfile line was added above */
3469 out_printf(out, "#undef PARENT_HANDLER\n");
3471 case CONSTRUCTOR_METHOD:
3472 case DISPOSE_METHOD:
3473 case FINALIZE_METHOD:
3475 out_addline_infile(out, m->line_no);
3476 print_method(out, "static ", "\n", "", " ", "", "\n",
3477 m, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE);
3478 print_method_body(m, TRUE, TRUE);
3479 /* the outfile line was added above */
3488 char *outfile, *outfileh, *outfileph;
3490 outfilebase = g_strconcat (fullfilebase, for_cpp ? ".cc" : ".c", NULL);
3491 outfile = g_strconcat(outfilebase, no_touch ? "#gob#" : "", NULL);
3493 outfilehbase = g_strconcat (fullfilebase, ".h", NULL);
3494 outfileh = g_strconcat(outfilehbase, no_touch_headers ? "#gob#" : "", NULL);
3496 if ((privates > 0 || protecteds > 0 ||
3497 private_header == PRIVATE_HEADER_ALWAYS) &&
3498 private_header != PRIVATE_HEADER_NEVER) {
3499 char sep[2] = {0,0};
3502 outfilephbase = g_strconcat (fullfilebase, sep, "private.h", NULL);
3503 outfileph = g_strconcat (outfilephbase, no_touch_headers ? "#gob#" : "", NULL);
3505 outfilephbase = NULL;
3511 out = fopen (outfile, "w");
3513 error_printf (GOB_ERROR, 0,
3514 "Cannot open outfile: %s", outfile);
3516 outh = fopen (outfileh, "w");
3518 error_printf (GOB_ERROR, 0,
3519 "Cannot open outfile: %s", outfileh);
3521 if (outfileph != NULL) {
3522 outph = fopen (outfileph, "w");
3523 if (outph == NULL) {
3524 error_printf (GOB_ERROR, 0,
3525 "Cannot open outfile: %s",
3533 put_argument_nongnu_wrappers (Class *c)
3537 if (get_properties < 0 && set_properties < 0)
3540 for (li = c->nodes; li != NULL; li = li->next) {
3542 const char *name, *gtktype;
3548 if (n->type == ARGUMENT_NODE) {
3549 Argument *a = (Argument *)n;
3551 gtktype = a->gtktype;
3553 get = a->get != NULL;
3554 set = a->set != NULL;
3555 } else if (n->type == PROPERTY_NODE) {
3556 Property *p = (Property *)n;
3558 gtktype = p->gtktype;
3560 get = p->get != NULL;
3561 set = p->set != NULL;
3566 aname = g_strdup (name);
3570 cast = get_type (atype, TRUE);
3572 cast = g_strdup (get_cast (gtktype, TRUE));
3576 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3577 "\"%s\",(%s)(arg)\n",
3578 macrobase, aname, name, cast);
3580 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3581 "\"%s\",(%s*)(arg)\n",
3582 macrobase, aname, name, cast);
3585 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3587 macrobase, aname, name);
3589 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3591 macrobase, aname, name);
3599 put_argument_gnu_wrappers(Class *c)
3603 if(get_properties < 0 && set_properties < 0)
3606 for (li = c->nodes; li != NULL; li = li->next) {
3608 const char *name, *gtktype;
3614 if (n->type == ARGUMENT_NODE) {
3615 Argument *a = (Argument *)n;
3617 gtktype = a->gtktype;
3619 get = a->get != NULL;
3620 set = a->set != NULL;
3621 } else if (n->type == PROPERTY_NODE) {
3622 Property *p = (Property *)n;
3624 gtktype = p->gtktype;
3626 get = p->get != NULL;
3627 set = p->set != NULL;
3632 aname = g_strdup (name);
3636 cast = get_type (atype, TRUE);
3638 cast = g_strdup (get_cast (gtktype, TRUE));
3642 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3643 "\"%s\", __extension__ ({%sz = (arg); z;})\n",
3644 macrobase, aname, name, cast);
3646 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3647 "\"%s\", __extension__ ({%s*z = (arg); z;})\n",
3648 macrobase, aname, name, cast);
3651 out_printf (outh, "#define %s_PROP_%s(arg) \t"
3653 macrobase, aname, name);
3655 out_printf (outh, "#define %s_GET_PROP_%s(arg)\t"
3657 macrobase, aname, name);
3665 print_ccode_block(CCode *cc)
3668 switch(cc->cctype) {
3670 /* HT code is printed exactly like normal header
3671 code but is printed before */
3674 out_printf(fp, "\n");
3677 /* AT code is printed exactly like normal 'all'
3678 code but is printed before */
3681 out_printf(outph, "\n");
3682 out_printf(outph, "%s\n", cc->cbuf);
3683 out_addline_infile(outph, cc->line_no);
3684 out_addline_outfile(outph);
3686 out_printf(outh, "\n");
3687 out_printf(outh, "%s\n", cc->cbuf);
3689 out_printf(fp, "\n");
3690 out_addline_infile(fp, cc->line_no);
3696 out_printf(fp, "\n");
3697 out_addline_infile(fp, cc->line_no);
3704 out_printf(fp, "\n");
3705 out_addline_infile(fp, cc->line_no);
3708 out_printf(fp, "%s\n", cc->cbuf);
3709 if(cc->cctype == C_CCODE ||
3710 cc->cctype == AD_CCODE ||
3711 cc->cctype == A_CCODE ||
3712 cc->cctype == AT_CCODE ||
3713 cc->cctype == PH_CCODE)
3714 out_addline_outfile(fp);
3718 print_class_block(Class *c)
3722 gboolean printed_private = FALSE;
3726 out_printf(outph ? outph : outh, "#include <gtk/gtk.h>\n");
3727 out_printf(outph ? outph : outh, "#include <glade/glade-xml.h>\n\n");
3731 out_printf(out, "/* utility types we may need */\n");
3732 if(special_array[SPECIAL_2POINTER])
3733 out_printf(out, "typedef struct { "
3734 "gpointer a; gpointer b; "
3735 "} ___twopointertype;\n");
3736 if(special_array[SPECIAL_3POINTER])
3737 out_printf(out, "typedef struct { "
3738 "gpointer a; gpointer b; "
3740 "} ___threepointertype;\n");
3741 if(special_array[SPECIAL_INT_POINTER])
3742 out_printf(out, "typedef struct { "
3743 "gint a; gpointer b; "
3744 "} ___intpointertype;\n");
3745 out_printf(out, "\n");
3748 out_printf(outh, "\n/*\n"
3749 " * Type checking and casting macros\n"
3751 out_printf(outh, "#define %s\t"
3752 "(%s_get_type())\n",
3753 macrotype, funcbase);
3754 out_printf(outh, "#define %s(obj)\t"
3755 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s)\n",
3756 macrobase, funcbase, typebase);
3757 out_printf(outh, "#define %s_CONST(obj)\t"
3758 "G_TYPE_CHECK_INSTANCE_CAST((obj), %s_get_type(), %s const)\n",
3759 macrobase, funcbase, typebase);
3760 out_printf(outh, "#define %s_CLASS(klass)\t"
3761 "G_TYPE_CHECK_CLASS_CAST((klass), %s_get_type(), %sClass)\n",
3762 macrobase, funcbase, typebase);
3763 out_printf(outh, "#define %s(obj)\t"
3764 "G_TYPE_CHECK_INSTANCE_TYPE((obj), %s_get_type ())\n\n",
3767 "#define %s_GET_CLASS(obj)\t"
3768 "G_TYPE_INSTANCE_GET_CLASS((obj), %s_get_type(), %sClass)\n",
3769 macrobase, funcbase, typebase);
3771 if ( ! no_self_alias) {
3772 out_printf(out, "/* self casting macros */\n");
3773 out_printf(out, "#define SELF(x) %s(x)\n", macrobase);
3774 out_printf(out, "#define SELF_CONST(x) %s_CONST(x)\n", macrobase);
3775 out_printf(out, "#define IS_SELF(x) %s(x)\n", macrois);
3776 out_printf(out, "#define TYPE_SELF %s\n", macrotype);
3777 out_printf(out, "#define SELF_CLASS(x) %s_CLASS(x)\n\n",
3779 out_printf(out, "#define SELF_GET_CLASS(x) %s_GET_CLASS(x)\n\n",
3782 out_printf(out, "/* self typedefs */\n");
3783 out_printf(out, "typedef %s Self;\n", typebase);
3784 out_printf(out, "typedef %sClass SelfClass;\n\n", typebase);
3788 always_private_struct) {
3789 out_printf (outh, "\n/* Private structure type */\n");
3790 out_printf (outh, "typedef struct _%sPrivate %sPrivate;\n",
3791 typebase, typebase);
3793 out_printf (outh, "/* There are no privates, this "
3794 "structure is thus never defined */\n");
3797 out_printf (outh, "\n/*\n"
3798 " * Main object structure\n"
3800 s = replace_sep (c->otype, '_');
3802 out_printf (outh, "#ifndef __TYPEDEF_%s__\n"
3803 "#define __TYPEDEF_%s__\n", s, s);
3805 out_printf (outh, "typedef struct _%s %s;\n"
3806 "#endif\n", typebase, typebase);
3807 out_printf (outh, "struct _%s {\n\t%s __parent__;\n",
3808 typebase, ptypebase);
3809 for (li = c->nodes; li; li=li->next) {
3810 static gboolean printed_public = FALSE;
3812 Variable *v = (Variable *)n;
3813 if(n->type == VARIABLE_NODE &&
3814 v->scope == PUBLIC_SCOPE) {
3815 if( ! printed_public) {
3816 out_printf(outh, "\t/*< public >*/\n");
3817 printed_public = TRUE;
3819 put_variable((Variable *)n, outh);
3822 /* put protecteds always AFTER publics */
3823 for (li = c->nodes; li != NULL; li = li->next) {
3825 Variable *v = (Variable *)n;
3826 if (n->type == VARIABLE_NODE &&
3827 v->scope == PROTECTED_SCOPE) {
3828 if ( ! printed_private) {
3829 out_printf (outh, "\t/*< private >*/\n");
3830 printed_private = TRUE;
3832 put_variable ((Variable *)n, outh);
3836 always_private_struct) {
3837 if ( ! printed_private)
3838 out_printf (outh, "\t/*< private >*/\n");
3839 out_printf (outh, "\t%sPrivate *_priv;\n", typebase);
3841 out_printf (outh, "};\n");
3846 /* if we are to stick this into the private
3847 header, if not stick it directly into the
3854 out_printf (outfp, "struct _%sPrivate {\n",
3858 for(li=c->nodes; li; li=li->next) {
3860 Variable *v = (Variable *)n;
3861 if(n->type == VARIABLE_NODE &&
3862 v->scope == PRIVATE_SCOPE) {
3863 out_addline_infile(outfp, v->line_no);
3864 put_variable(v, outfp);
3867 out_addline_outfile(outfp);
3869 out_printf(outfp, "};\n");
3872 out_printf(outh, "\n/*\n"
3873 " * Class definition\n"
3875 out_printf(outh, "typedef struct _%sClass %sClass;\n",
3876 typebase, typebase);
3878 "struct _%sClass {\n\t%sClass __parent__;\n",
3879 typebase, ptypebase);
3880 for(li = c->nodes; li != NULL; li = li->next) {
3882 if(n->type == METHOD_NODE)
3883 put_vs_method((Method *)n);
3885 /* If BonoboX type class put down the epv */
3886 if (c->bonobo_object_class != NULL) {
3888 "\t/* Bonobo object epv */\n"
3889 "\tPOA_%s__epv _epv;\n",
3890 c->bonobo_object_class);
3892 /* put class scope variables */
3893 for (li = c->nodes; li != NULL; li = li->next) {
3895 Variable *v = (Variable *)n;
3896 if (n->type == VARIABLE_NODE &&
3897 v->scope == CLASS_SCOPE)
3898 put_variable ((Variable *)n, outh);
3900 out_printf (outh, "};\n\n");
3902 out_printf (out, "/* here are local prototypes */\n");
3903 if (set_properties > 0) {
3904 out_printf (out, "static void ___object_set_property "
3905 "(GObject *object, guint property_id, "
3906 "const GValue *value, GParamSpec *pspec);\n");
3908 if (get_properties > 0) {
3909 out_printf (out, "static void ___object_get_property "
3910 "(GObject *object, guint property_id, "
3911 "GValue *value, GParamSpec *pspec);\n");
3914 out_printf (outh, "\n/*\n"
3915 " * Public methods\n"
3918 if (!overrode_get_type && !no_gnu) {
3920 * For ordinary "static" types it should be safe to mark the
3921 * get_type implementation as const, since the get_type
3922 * function return really is constant at the call boundary
3923 * (even though there is an initial setup on the first call).
3924 * But for dynamic types, since the registration is explicitly
3925 * separated, we need to settle for "pure" as the results of
3926 * get_type differ before and after type registration.
3928 out_printf(outh, "GType\t%s_get_type\t(void) %s;\n", funcbase,
3929 c->dynamic ? "G_GNUC_PURE" : "G_GNUC_CONST");
3933 out_printf(outh, "void\t%s_register_type\t(GTypeModule *);\n",
3937 for(li = c->nodes; li != NULL; li = li->next) {
3939 if(n->type == METHOD_NODE) {
3940 put_pub_method((Method *)n);
3941 put_prot_method((Method *)n);
3942 put_priv_method_prot((Method *)n);
3946 /* this idea is less and less apealing to me */
3948 out_printf (outh, "\n/*\n"
3949 " * Signal connection wrapper macros\n"
3952 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3953 put_signal_macros (c, TRUE);
3954 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3955 put_signal_macros (c, FALSE);
3956 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n");
3958 put_signal_macros (c, FALSE);
3959 out_printf(outh, "\n");
3962 out_printf (out, "\n/*\n"
3963 " * Signal connection wrapper macro shortcuts\n"
3965 put_local_signal_macros (c);
3966 out_printf(outh, "\n");
3969 /* argument wrapping macros */
3970 if(get_properties > 0 || set_properties > 0) {
3971 out_printf(outh, "\n/*\n"
3972 " * Argument wrapping macros\n"
3975 out_printf(outh, "#if defined(__GNUC__) && !defined(__STRICT_ANSI__)\n");
3976 put_argument_gnu_wrappers(c);
3977 out_printf(outh, "#else /* __GNUC__ && !__STRICT_ANSI__ */\n");
3978 put_argument_nongnu_wrappers(c);
3979 out_printf(outh, "#endif /* __GNUC__ && !__STRICT_ANSI__ */\n\n");
3981 put_argument_nongnu_wrappers(c);
3986 for(li = c->nodes; li != NULL; li = li->next) {
3988 if(n->type == METHOD_NODE)
3989 add_signal_prots((Method *)n);
3995 if(any_method_to_alias(c)) {
3996 out_printf (out, "/* Short form macros */\n");
3997 make_method_aliases (c);
4000 add_interface_inits (c);
4002 if (!overrode_get_type) {
4003 if (c->bonobo_object_class != NULL)
4004 add_bonobo_object_get_type();
4005 else if (c->dynamic)
4006 add_dynamic_get_type();
4011 out_printf (out, "/* a macro for creating a new object of our type */\n");
4013 "#define GET_NEW ((%s *)g_object_new(%s_get_type(), NULL))\n\n",
4014 typebase, funcbase);
4016 out_printf (out, "/* a function for creating a new object of our type */\n");
4017 out_printf (out, "#include <stdarg.h>\n");
4019 "static %s * GET_NEW_VARG (const char *first, ...)%s;\n"
4020 "static %s *\nGET_NEW_VARG (const char *first, ...)\n"
4021 "{\n\t%s *ret;\n\tva_list ap;\n"
4022 "\tva_start (ap, first);\n"
4023 "\tret = (%s *)g_object_new_valist (%s_get_type (), "
4026 "\treturn ret;\n}\n\n",
4028 no_gnu ? "" : " G_GNUC_UNUSED",
4029 typebase, typebase, typebase, funcbase);
4033 out_printf (out, "/* a function to connect glade callback */\n");
4034 out_printf (out,"static void\n"
4035 "___glade_xml_connect_foreach(const gchar *handler_name,\n"
4036 "GObject *object,\n"
4037 "const gchar *signal_name,\n"
4038 "const gchar *signal_data,\n"
4039 "GObject *connect_object,\n"
4041 "gpointer user_data)\n"
4043 "\tstatic GModule * allsymbols = NULL;\n"
4045 "\tif (!allsymbols) allsymbols = g_module_open(NULL, 0);\n"
4046 "\tif (allsymbols) {\n"
4047 "\t\tgchar * func_name = g_strdup_printf(\"%s_%%s\", handler_name);\n"
4048 "\t\tGCallback func;\n"
4050 "\t\tif (!g_module_symbol(allsymbols, func_name, (gpointer)&func)){\n"
4051 "\t\t\tif (!g_module_symbol(allsymbols, handler_name, (gpointer)&func)) {\n"
4052 "\t\t\t\tg_warning(\"could not find signal handler '%%s'.\", func_name);\n"
4053 "\t\t\t\tg_free(func_name);\n"
4058 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_AFTER | G_CONNECT_SWAPPED);\n"
4060 "\t\t\tg_signal_connect_data(object, signal_name, func, user_data, NULL, G_CONNECT_SWAPPED);\n"
4061 "\t\tg_free(func_name);\n"
4068 for (li = nodes; li != NULL; li = li->next) {
4069 Node *node = li->data;
4070 if (node->type == CCODE_NODE) {
4071 CCode *cc = (CCode *)node;
4072 if (cc->cctype == AD_CCODE)
4073 print_ccode_block (cc);
4077 if (need_constructor)
4078 add_constructor (c);
4088 if(set_properties > 0) {
4089 add_getset_arg(c, TRUE);
4092 if(get_properties > 0) {
4093 add_getset_arg(c, FALSE);
4096 for(li = c->nodes; li != NULL; li = li->next) {
4098 if(n->type == METHOD_NODE)
4099 put_method((Method *)n);
4102 add_bad_hack_to_avoid_unused_warnings(c);
4106 print_useful_macros(void)
4108 int major = 0, minor = 0, pl = 0;
4111 sscanf (VERSION, "%d.%d.%d", &major, &minor, &pl);
4112 out_printf (out, "#define GOB_VERSION_MAJOR %d\n", major);
4113 out_printf (out, "#define GOB_VERSION_MINOR %d\n", minor);
4114 out_printf (out, "#define GOB_VERSION_PATCHLEVEL %d\n\n", pl);
4116 /* Useful priv macro thingie */
4117 /* FIXME: this should be done the same way that priv is, as a var,
4119 out_printf (out, "#define selfp (self->_priv)\n\n");
4123 print_more_useful_macros (void)
4126 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4127 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4129 out_printf (out, "#ifdef G_LIKELY\n");
4130 out_printf (out, "#define ___GOB_LIKELY(expr) G_LIKELY(expr)\n");
4131 out_printf (out, "#define ___GOB_UNLIKELY(expr) G_UNLIKELY(expr)\n");
4132 out_printf (out, "#else /* ! G_LIKELY */\n");
4133 out_printf (out, "#define ___GOB_LIKELY(expr) (expr)\n");
4134 out_printf (out, "#define ___GOB_UNLIKELY(expr) (expr)\n");
4135 out_printf (out, "#endif /* G_LIKELY */\n");
4140 print_file_comments(void)
4142 out_printf(outh, "/* Generated by GOB (v%s)"
4143 " (do not edit directly) */\n\n", VERSION);
4145 out_printf(outph, "/* Generated by GOB (v%s)"
4146 " (do not edit directly) */\n\n", VERSION);
4147 out_printf(out, "/* Generated by GOB (v%s)"
4148 " (do not edit directly) */\n\n", VERSION);
4150 out_printf(out, "/* End world hunger, donate to the World Food Programme, http://www.wfp.org */\n\n");
4154 print_includes(void)
4156 gboolean found_header;
4159 /* We may need string.h for memset */
4160 if ( ! g_list_find_custom(include_files, "string.h", (GCompareFunc)strcmp)) {
4161 out_printf(out, "#include <string.h> /* memset() */\n\n");
4164 p = g_strconcat(filebase, ".h", NULL);
4165 found_header = TRUE;
4166 if( ! g_list_find_custom(include_files, p, (GCompareFunc)strcmp)) {
4167 out_printf(out, "#include \"%s.h\"\n\n", filebase);
4168 found_header = FALSE;
4172 /* if we are creating a private header see if it was included */
4174 char sep[2] = {0,0};
4177 p = g_strconcat(filebase, sep, "private.h", NULL);
4178 if( ! g_list_find_custom(include_files, p,
4179 (GCompareFunc)strcmp)) {
4180 out_printf(out, "#include \"%s%sprivate.h\"\n\n",
4184 error_printf(GOB_WARN, 0,
4185 "Implicit private header include "
4187 "\tsource file, while public "
4188 "header is at a custom location, "
4190 "\texplicitly include "
4191 "the private header below the "
4199 print_header_prefixes(void)
4203 p = replace_sep(((Class *)class)->otype, '_');
4205 out_printf(outh, "#ifndef __%s_H__\n#define __%s_H__\n\n", p, p);
4207 out_printf(outph, "#ifndef __%s_PRIVATE_H__\n"
4208 "#define __%s_PRIVATE_H__\n\n"
4209 "#include \"%s.h\"\n\n", p, p, filebase);
4212 if( ! no_extern_c) {
4213 out_printf(outh, "#ifdef __cplusplus\n"
4215 "#endif /* __cplusplus */\n\n");
4217 out_printf(outph, "#ifdef __cplusplus\n"
4219 "#endif /* __cplusplus */\n\n");
4224 print_header_postfixes(void)
4227 out_printf(outh, "\n#ifdef __cplusplus\n"
4229 "#endif /* __cplusplus */\n");
4230 out_printf(outh, "\n#endif\n");
4233 out_printf(outph, "\n#ifdef __cplusplus\n"
4235 "#endif /* __cplusplus */\n");
4236 out_printf(outph, "\n#endif\n");
4245 /* print the AT_CCODE and CT_CCODE blocks */
4246 for(li = nodes; li != NULL; li = li->next) {
4247 Node *node = li->data;
4248 if(node->type == CCODE_NODE) {
4249 CCode *cc = (CCode *)node;
4250 if (cc->cctype == AT_CCODE ||
4251 cc->cctype == CT_CCODE)
4252 print_ccode_block((CCode *)node);
4258 print_header_top(void)
4262 /* mandatory includes */
4263 out_printf (outh, "#include <glib.h>\n");
4264 out_printf (outh, "#include <glib-object.h>\n");
4266 /* print the HT_CCODE blocks */
4267 for (li = nodes; li != NULL; li = li->next) {
4268 Node *node = li->data;
4269 if (node->type == CCODE_NODE) {
4270 CCode *cc = (CCode *)node;
4271 if (cc->cctype == HT_CCODE)
4272 print_ccode_block ((CCode *)node);
4278 print_enum (EnumDef *enode)
4285 funcprefix = replace_sep (enode->etype, '_');
4286 gob_strdown (funcprefix);
4287 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4289 type = remove_sep (enode->etype);
4291 out_printf (outh, "\ntypedef enum {\n");
4293 for (li = enode->values; li != NULL; li = li->next) {
4294 EnumValue *value = li->data;
4296 char *sname = gob_strdown (g_strdup (value->name));
4298 while ((p = strchr (sname, '_')) != NULL)
4301 out_printf (outh, "\t%s_%s", enode->prefix, value->name);
4302 if (value->value != NULL)
4303 out_printf (outh, " = %s", value->value);
4304 if (li->next != NULL)
4305 out_printf (outh, ",\n");
4307 out_printf (outh, "\n");
4309 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4310 enode->prefix, value->name,
4311 enode->prefix, value->name,
4317 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4319 out_printf (outh, "} %s;\n", type);
4321 str = make_pre_macro (enode->etype, "TYPE");
4322 out_printf (outh, "#define %s ", str);
4325 out_printf (outh, "%s_get_type()\n", funcprefix);
4326 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4327 funcprefix, no_gnu ? "": " G_GNUC_CONST");
4330 "GType\n%s_get_type (void)\n"
4332 "\tstatic GType type = 0;\n"
4333 "\tif ___GOB_UNLIKELY(type == 0)\n"
4334 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4337 funcprefix, type, funcprefix);
4339 g_free (funcprefix);
4344 print_flags (Flags *fnode)
4352 funcprefix = replace_sep (fnode->ftype, '_');
4353 gob_strdown (funcprefix);
4354 out_printf (out, "static const GFlagsValue _%s_values[] = {\n",
4356 type = remove_sep (fnode->ftype);
4358 out_printf (outh, "\ntypedef enum {\n");
4360 for (i = 0, li = fnode->values; li != NULL; i++, li = li->next) {
4361 const char *name = li->data;
4363 char *sname = gob_strdown (g_strdup (name));
4365 while ((p = strchr (sname, '_')) != NULL)
4368 out_printf (outh, "\t%s_%s = 1<<%d",
4369 fnode->prefix, name, i);
4370 if (li->next != NULL)
4371 out_printf (outh, ",\n");
4373 out_printf (outh, "\n");
4375 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4376 fnode->prefix, name,
4377 fnode->prefix, name,
4383 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4385 out_printf (outh, "} %s;\n", type);
4387 str = make_pre_macro (fnode->ftype, "TYPE");
4388 out_printf (outh, "#define %s ", str);
4391 out_printf (outh, "%s_get_type()\n", funcprefix);
4392 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4393 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4396 "GType\n%s_get_type (void)\n"
4398 "\tstatic GType type = 0;\n"
4399 "\tif ___GOB_UNLIKELY(type == 0)\n"
4400 "\t\ttype = g_flags_register_static (\"%s\", _%s_values);\n"
4403 funcprefix, type, funcprefix);
4405 g_free (funcprefix);
4410 print_error (Error *enode)
4417 funcprefix = replace_sep (enode->etype, '_');
4418 gob_strdown (funcprefix);
4419 out_printf (out, "static const GEnumValue _%s_values[] = {\n",
4421 type = remove_sep (enode->etype);
4423 out_printf (outh, "\ntypedef enum {\n");
4425 for (li = enode->values; li != NULL; li = li->next) {
4426 const char *name = li->data;
4428 char *sname = gob_strdown (g_strdup (name));
4430 while ((p = strchr (sname, '_')) != NULL)
4433 out_printf (outh, "\t%s_%s", enode->prefix, name);
4434 if (li->next != NULL)
4435 out_printf (outh, ",\n");
4437 out_printf (outh, "\n");
4439 out_printf (out, "\t{ %s_%s, (char *)\"%s_%s\", (char *)\"%s\" },\n",
4440 enode->prefix, name,
4441 enode->prefix, name,
4447 out_printf (out, "\t{ 0, NULL, NULL }\n};\n\n");
4449 out_printf (outh, "} %s;\n", type);
4451 str = make_pre_macro (enode->etype, "TYPE");
4452 out_printf (outh, "#define %s ", str);
4455 out_printf (outh, "%s_get_type ()\n", funcprefix);
4456 out_printf (outh, "GType %s_get_type (void)%s;\n\n",
4457 funcprefix, no_gnu ? "" : " G_GNUC_CONST");
4460 "GType\n%s_get_type (void)\n"
4462 "\tstatic GType type = 0;\n"
4463 "\tif ___GOB_UNLIKELY(type == 0)\n"
4464 "\t\ttype = g_enum_register_static (\"%s\", _%s_values);\n"
4467 funcprefix, type, funcprefix);
4469 out_printf (outh, "#define %s %s_quark ()\n", enode->prefix, funcprefix);
4470 out_printf (outh, "GQuark %s_quark (void);\n\n", funcprefix);
4472 str = replace_sep (enode->etype, '-');
4476 "GQuark\n%s_quark (void)\n"
4478 "\tstatic GQuark q = 0;\n"
4480 "\t\tq = g_quark_from_static_string (\"%s\");\n"
4487 g_free (funcprefix);
4492 generate_outfiles(void)
4496 print_file_comments();
4502 print_header_prefixes();
4504 print_useful_macros();
4508 print_more_useful_macros ();
4510 for (li = nodes; li != NULL; li = li->next) {
4511 Node *node = li->data;
4512 if (node->type == CCODE_NODE) {
4513 CCode *cc = (CCode *)node;
4514 if (cc->cctype != HT_CCODE &&
4515 cc->cctype != AT_CCODE &&
4516 cc->cctype != AD_CCODE)
4517 print_ccode_block ((CCode *)node);
4518 } else if (node->type == CLASS_NODE) {
4519 print_class_block ((Class *)node);
4520 } else if (node->type == ENUMDEF_NODE) {
4521 print_enum ((EnumDef *)node);
4522 } else if (node->type == FLAGS_NODE) {
4523 print_flags ((Flags *)node);
4524 } else if (node->type == ERROR_NODE) {
4525 print_error ((Error *)node);
4527 g_assert_not_reached();
4531 print_header_postfixes();
4534 static void print_version(void)
4536 printf("%s (%s) %s\n", PACKAGE_NAME, PACKAGE_TARNAME, PACKAGE_VERSION);
4537 puts("Copyright (C) 2013 George (Jiri) Lebl et al.");
4538 puts("Copyright (C) 2022 Nick Bowler");
4539 puts("License GPLv2+: GNU GPL version 2 or any later version");
4540 puts("This is free software: you are free to change and redistribute it.");
4541 puts("There is NO WARRANTY, to the extent permitted by law.");
4544 static void print_usage(FILE *f)
4546 fprintf(f, "Usage: %s [options] file.gob\n", g_get_prgname());
4548 fprintf(f, "Try '%s --help' for more information.\n",
4553 static void print_help(void)
4555 const struct option *opt;
4557 print_usage(stdout);
4559 puts("This is \"GObject Builder\": a simple preprocessor to help with\n"
4560 "implementing GObject types in C.");
4563 for (opt = lopts; opt->name; opt++) {
4564 struct lopt_help help;
4566 /* Don't display obsolete options that don't do anything */
4567 if (!opt->flag && !opt->val)
4570 if (!lopt_get_help(opt, &help))
4573 help_print_option(opt, help.arg, help.desc, 20);
4577 puts("End world hunger, donate to the World Food Programme: https://www.wfp.org/");
4581 * Called after getopt_long receives an --m4 argument. Immediately stop
4582 * processing options. Then all non-option arguments seen so far together
4583 * with all remaining arguments are appended to M4_COMMANDLINE. If m4_clean
4584 * is false, then M4_FLAGS is inserted before the first non-option argument,
4587 * The resulting string is returned, which should be freed by the caller.
4589 static char *parse_m4_options(int argc, char **argv, gboolean m4_clean)
4591 char **nonopt = NULL, *save_argv0, *ret;
4594 /* First, conclude getopt run and reset with remaining args */
4595 getopt_long(optind, argv, sopts, lopts, NULL);
4600 save_argv0 = argv[0];
4601 argv[0] = M4_COMMANDLINE;
4604 ret = g_strjoinv(" ", argv);
4605 argv[0] = save_argv0;
4609 /* Locate first non-option argument, if any. */
4610 while ((opt = getopt_long(argc, argv, "-", NULL, NULL)) != -1) {
4612 nonopt = &argv[optind-2];
4617 /* If there is a non-option but the above didn't see it, must be "--" */
4618 if (!nonopt && argv[optind])
4619 nonopt = &argv[optind-2];
4622 /* Found non-option, insert M4_FLAGS just before it. */
4623 char *save_argv[3] = { nonopt[0], nonopt[1], nonopt[2] };
4625 nonopt[1] = M4_FLAGS;
4627 nonopt[0] = g_strjoinv(" ", argv);
4629 nonopt[1] = save_argv[1];
4630 nonopt[2] = save_argv[2];
4631 ret = g_strjoinv(" ", nonopt);
4634 nonopt[0] = save_argv[0];
4636 /* Only options, not inserting M4_FLAGS. */
4637 ret = g_strjoinv(" ", argv);
4640 argv[0] = save_argv0;
4644 static int parse_options(int argc, char **argv)
4646 gboolean show_m4_dir = FALSE, m4_clean = FALSE;
4647 char *raw_file_sep = "-";
4651 while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) {
4657 output_dir = optarg;
4660 exit_on_warn = TRUE;
4663 raw_file_sep = optarg ? optarg : "";
4669 no_touch = no_touch_headers = TRUE;
4675 m4_commandline = parse_m4_options(argc, argv, m4_clean);
4681 if (optopt == '?') {
4687 /* Rewind getopt to get internal error messages. */
4688 optind = 0, opterr = 1;
4689 while (getopt_long(argc, argv, sopts, lopts, NULL)
4692 case 0: /* no-op or option set by flag */;
4696 filename = argv[optind];
4697 if (argc > optind+1) {
4698 char *s = g_strjoinv(" ", argv+optind+1);
4699 fprintf(stderr, "%s: Warning: excess arguments ignored: %s\n",
4700 g_get_prgname(), s);
4706 file_sep = raw_file_sep[0];
4707 if (raw_file_sep[0] && raw_file_sep[1]) {
4708 fprintf(stderr, "%s: Warning: --file-sep characters beyond the first are ignored\n",
4715 printf("%s\n", M4_INCLUDE_DIR);
4723 compare_and_move (const char *old_filename)
4725 char *new_filename = g_strconcat (old_filename, "#gob#", NULL);
4727 gboolean equal = FALSE;
4729 old_f = fopen (old_filename, "r");
4732 gboolean error = FALSE;
4734 new_f = fopen (new_filename, "r");
4743 new_n = fread (new_buf, 1, sizeof (new_buf), new_f);
4744 if (ferror (new_f)) {
4746 error_printf (GOB_ERROR, 0,
4747 "Can't read %s: %s",
4749 g_strerror (errno));
4753 old_n = fread (old_buf, 1, sizeof (old_buf), old_f);
4755 || feof (new_f) != feof (old_f)
4757 || memcmp (new_buf, old_buf, new_n) != 0)
4766 error_printf (GOB_ERROR, 0, "Can't open %s: %s",
4767 new_filename, g_strerror (errno));
4775 if (!equal && remove(old_filename) != 0) {
4776 error_printf(GOB_ERROR, 0, "Can't remove %s: %s",
4777 old_filename, g_strerror (errno));
4783 if (remove(new_filename) != 0) {
4784 error_printf(GOB_ERROR, 0, "Can't remove %s: %s",
4785 new_filename, g_strerror(errno));
4788 if (rename(new_filename, old_filename) != 0) {
4789 error_printf(GOB_ERROR, 0, "Can't rename %s to %s: %s",
4790 new_filename, old_filename,
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);